Panzer  Version of the Day
Panzer_STK_LineMeshFactory.cpp
Go to the documentation of this file.
1 // @HEADER
2 // ***********************************************************************
3 //
4 // Panzer: A partial differential equation assembly
5 // engine for strongly coupled complex multiphysics systems
6 // Copyright (2011) Sandia Corporation
7 //
8 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
9 // the U.S. Government retains certain rights in this software.
10 //
11 // Redistribution and use in source and binary forms, with or without
12 // modification, are permitted provided that the following conditions are
13 // met:
14 //
15 // 1. Redistributions of source code must retain the above copyright
16 // notice, this list of conditions and the following disclaimer.
17 //
18 // 2. Redistributions in binary form must reproduce the above copyright
19 // notice, this list of conditions and the following disclaimer in the
20 // documentation and/or other materials provided with the distribution.
21 //
22 // 3. Neither the name of the Corporation nor the names of the
23 // contributors may be used to endorse or promote products derived from
24 // this software without specific prior written permission.
25 //
26 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
27 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
30 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
31 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
32 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
33 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
34 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
35 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
36 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37 //
38 // Questions? Contact Roger P. Pawlowski (rppawlo@sandia.gov) and
39 // Eric C. Cyr (eccyr@sandia.gov)
40 // ***********************************************************************
41 // @HEADER
42 
44 #include <Teuchos_TimeMonitor.hpp>
45 #include <PanzerAdaptersSTK_config.hpp>
46 
47 using Teuchos::RCP;
48 using Teuchos::rcp;
49 
50 namespace panzer_stk {
51 
53 {
55 }
56 
59 {
60 }
61 
63 Teuchos::RCP<STK_Interface> LineMeshFactory::buildMesh(stk::ParallelMachine parallelMach) const
64 {
65  PANZER_FUNC_TIME_MONITOR("panzer::LineMeshFactory::buildMesh()");
66 
67  // build all meta data
68  RCP<STK_Interface> mesh = buildUncommitedMesh(parallelMach);
69 
70  // commit meta data
71  mesh->initialize(parallelMach);
72 
73  // build bulk data
74  completeMeshConstruction(*mesh,parallelMach);
75 
76  return mesh;
77 }
78 
79 Teuchos::RCP<STK_Interface> LineMeshFactory::buildUncommitedMesh(stk::ParallelMachine parallelMach) const
80 {
81  PANZER_FUNC_TIME_MONITOR("panzer::LineMeshFactory::buildUncomittedMesh()");
82 
83  RCP<STK_Interface> mesh = rcp(new STK_Interface(1));
84 
85  machRank_ = stk::parallel_machine_rank(parallelMach);
86  machSize_ = stk::parallel_machine_size(parallelMach);
87 
89 
90  // build meta information: blocks and side set setups
91  buildMetaData(parallelMach,*mesh);
92 
93  mesh->addPeriodicBCs(periodicBCVec_);
94  mesh->setBoundingBoxSearchFlag(useBBoxSearch_);
95 
96  return mesh;
97 }
98 
99 void LineMeshFactory::completeMeshConstruction(STK_Interface & mesh,stk::ParallelMachine parallelMach) const
100 {
101  PANZER_FUNC_TIME_MONITOR("panzer::LineMeshFactory::completeMeshConstruction()");
102 
103  if(not mesh.isInitialized())
104  mesh.initialize(parallelMach);
105 
106  // add node and element information
107  buildElements(parallelMach,mesh);
108 
109  // finish up the edges
110  mesh.buildSubcells();
111  mesh.buildLocalElementIDs();
112 
113  // now that edges are built, sidets can be added
114  addSideSets(mesh);
115 
116  // calls Stk_MeshFactory::rebalance
117  this->rebalance(mesh);
118 }
119 
121 void LineMeshFactory::setParameterList(const Teuchos::RCP<Teuchos::ParameterList> & paramList)
122 {
123  paramList->validateParametersAndSetDefaults(*getValidParameters(),0);
124 
125  setMyParamList(paramList);
126 
127  x0_ = paramList->get<double>("X0");
128  xf_ = paramList->get<double>("Xf");
129  xBlocks_ = paramList->get<int>("X Blocks");
130  nXElems_ = paramList->get<int>("X Elements");
131 
132  // read in periodic boundary conditions
133  parsePeriodicBCList(Teuchos::rcpFromRef(paramList->sublist("Periodic BCs")),periodicBCVec_,useBBoxSearch_);
134 }
135 
137 Teuchos::RCP<const Teuchos::ParameterList> LineMeshFactory::getValidParameters() const
138 {
139  static RCP<Teuchos::ParameterList> defaultParams;
140 
141  // fill with default values
142  if(defaultParams == Teuchos::null) {
143  defaultParams = rcp(new Teuchos::ParameterList);
144 
145  defaultParams->set<double>("X0",0.0);
146  defaultParams->set<double>("Xf",1.0);
147  defaultParams->set<int>("X Blocks",1);
148  defaultParams->set<int>("X Elements",5);
149 
150  Teuchos::ParameterList & bcs = defaultParams->sublist("Periodic BCs");
151  bcs.set<int>("Count",0); // no default periodic boundary conditions
152  }
153 
154  return defaultParams;
155 }
156 
158 {
159  // get valid parameters
160  RCP<Teuchos::ParameterList> validParams = rcp(new Teuchos::ParameterList(*getValidParameters()));
161 
162  // set that parameter list
163  setParameterList(validParams);
164 }
165 
166 void LineMeshFactory::buildMetaData(stk::ParallelMachine /* parallelMach */, STK_Interface & mesh) const
167 {
168  typedef shards::Line<2> LineTopo;
169  const CellTopologyData * ctd = shards::getCellTopologyData<LineTopo>();
170  const CellTopologyData * side_ctd = shards::CellTopology(ctd).getBaseCellTopologyData(0,0);
171 
172  // build meta data
173  //mesh.setDimension(2);
174  for(int bx=0;bx<xBlocks_;bx++) {
175  // add this element block
176  {
177  std::stringstream ebPostfix;
178  ebPostfix << "-" << bx;
179 
180  // add element blocks
181  mesh.addElementBlock("eblock"+ebPostfix.str(),ctd);
182  }
183  }
184 
185  // add sidesets
186  mesh.addSideset("left",side_ctd);
187  mesh.addSideset("right",side_ctd);
188 }
189 
190 void LineMeshFactory::buildElements(stk::ParallelMachine parallelMach,STK_Interface & mesh) const
191 {
192  mesh.beginModification();
193  // build each block
194  for(int xBlock=0;xBlock<xBlocks_;xBlock++) {
195  buildBlock(parallelMach,xBlock,mesh);
196  }
197  mesh.endModification();
198 }
199 
200 void LineMeshFactory::buildBlock(stk::ParallelMachine /* parallelMach */, int xBlock, STK_Interface& mesh) const
201 {
202  // grab this processors rank and machine size
203  std::pair<int,int> sizeAndStartX = determineXElemSizeAndStart(xBlock,machSize_,machRank_);
204 
205  int myXElems_start = sizeAndStartX.first;
206  int myXElems_end = myXElems_start+sizeAndStartX.second;
207  int totalXElems = nXElems_*xBlocks_;
208 
209  double deltaX = (xf_-x0_)/static_cast<double>(totalXElems);
210 
211  // build the nodes
212  std::vector<double> coord(1,0.0);
213  for(int nx=myXElems_start;nx<myXElems_end+1;++nx) {
214  coord[0] = this->getMeshCoord(nx, deltaX, x0_);
215  mesh.addNode(nx+1,coord);
216  }
217 
218  std::stringstream blockName;
219  blockName << "eblock-" << xBlock;
220  stk::mesh::Part * block = mesh.getElementBlockPart(blockName.str());
221 
222  // build the elements
223  for(int nx=myXElems_start;nx<myXElems_end;++nx) {
224  stk::mesh::EntityId gid = nx+1;
225  std::vector<stk::mesh::EntityId> nodes(2);
226  nodes[0] = nx+1;
227  nodes[1] = nodes[0]+1;
228 
229  RCP<ElementDescriptor> ed = rcp(new ElementDescriptor(gid,nodes));
230  mesh.addElement(ed,block);
231  }
232 }
233 
234 std::pair<int,int> LineMeshFactory::determineXElemSizeAndStart(int xBlock,unsigned int size,unsigned int /* rank */) const
235 {
236  std::size_t xProcLoc = procTuple_[0];
237  unsigned int minElements = nXElems_/size;
238  unsigned int extra = nXElems_ - minElements*size;
239 
240  TEUCHOS_ASSERT(minElements>0);
241 
242  // first "extra" elements get an extra column of elements
243  // this determines the starting X index and number of elements
244  int nume=0, start=0;
245  if(xProcLoc<extra) {
246  nume = minElements+1;
247  start = xProcLoc*(minElements+1);
248  }
249  else {
250  nume = minElements;
251  start = extra*(minElements+1)+(xProcLoc-extra)*minElements;
252  }
253 
254  return std::make_pair(start+nXElems_*xBlock,nume);
255 }
256 
258 {
259  mesh.beginModification();
260  const stk::mesh::EntityRank sideRank = mesh.getSideRank();
261 
262  std::size_t totalXElems = nXElems_*xBlocks_;
263 
264  // get all part vectors
265  stk::mesh::Part * left = mesh.getSideset("left");
266  stk::mesh::Part * right = mesh.getSideset("right");
267 
268  std::vector<stk::mesh::Entity> localElmts;
269  mesh.getMyElements(localElmts);
270 
271  // loop over elements adding edges to sidesets
272  std::vector<stk::mesh::Entity>::const_iterator itr;
273  for(itr=localElmts.begin();itr!=localElmts.end();++itr) {
274  stk::mesh::Entity element = (*itr);
275  stk::mesh::EntityId gid = mesh.elementGlobalId(element);
276 
277  std::size_t nx = gid-1;
278 
279  // vertical boundaries
281 
282  if(nx+1==totalXElems) {
283  stk::mesh::Entity edge = mesh.findConnectivityById(element, sideRank, 1);
284 
285  // on the right
286  if(mesh.entityOwnerRank(edge)==machRank_)
287  mesh.addEntityToSideset(edge,right);
288  }
289 
290  if(nx==0) {
291  stk::mesh::Entity edge = mesh.findConnectivityById(element, sideRank, 0);
292 
293  // on the left
294  if(mesh.entityOwnerRank(edge)==machRank_)
295  mesh.addEntityToSideset(edge,left);
296  }
297  }
298 
299  mesh.endModification();
300 }
301 
303 Teuchos::Tuple<std::size_t,2> LineMeshFactory::procRankToProcTuple(std::size_t procRank) const
304 {
305  std::size_t i=0,j=0;
306 
307  j = procRank/machSize_;
308  procRank = procRank % machSize_;
309  i = procRank;
310 
311  return Teuchos::tuple(i,j);
312 }
313 
314 } // end panzer_stk
Teuchos::RCP< const Teuchos::ParameterList > getValidParameters() const
From ParameterListAcceptor.
stk::mesh::Part * getElementBlockPart(const std::string &name) const
get the block part
static void parsePeriodicBCList(const Teuchos::RCP< Teuchos::ParameterList > &pl, std::vector< Teuchos::RCP< const PeriodicBC_MatcherBase > > &periodicBC, bool &useBBoxSearch)
void buildBlock(stk::ParallelMachine machRank, int xBlock, STK_Interface &mesh) const
void buildElements(stk::ParallelMachine parallelMach, STK_Interface &mesh) const
void getMyElements(std::vector< stk::mesh::Entity > &elements) const
void addEntityToSideset(stk::mesh::Entity entity, stk::mesh::Part *sideset)
Teuchos::Tuple< std::size_t, 2 > procTuple_
stk::mesh::EntityRank getSideRank() const
stk::mesh::Entity findConnectivityById(stk::mesh::Entity src, stk::mesh::EntityRank tgt_rank, unsigned rel_id) const
Teuchos::Tuple< std::size_t, 2 > procRankToProcTuple(std::size_t procRank) const
what is the 2D tuple describe this processor distribution
void addSideSets(STK_Interface &mesh) const
virtual void completeMeshConstruction(STK_Interface &mesh, stk::ParallelMachine parallelMach) const
stk::mesh::Part * getSideset(const std::string &name) const
void addElement(const Teuchos::RCP< ElementDescriptor > &ed, stk::mesh::Part *block)
stk::mesh::EntityId elementGlobalId(std::size_t lid) const
void initialize(stk::ParallelMachine parallelMach, bool setupIO=true, const bool buildRefinementSupport=false)
std::pair< int, int > determineXElemSizeAndStart(int xBlock, unsigned int size, unsigned int rank) const
double getMeshCoord(const int nx, const double deltaX, const double x0) const
bool isInitialized() const
Has initialize been called on this mesh object?
void buildMetaData(stk::ParallelMachine parallelMach, STK_Interface &mesh) const
virtual Teuchos::RCP< STK_Interface > buildUncommitedMesh(stk::ParallelMachine parallelMach) const
void addNode(stk::mesh::EntityId gid, const std::vector< double > &coord)
void buildSubcells()
force the mesh to build subcells: edges and faces
void addSideset(const std::string &name, const CellTopologyData *ctData)
std::vector< Teuchos::RCP< const PeriodicBC_MatcherBase > > periodicBCVec_
unsigned entityOwnerRank(stk::mesh::Entity entity) const
void rebalance(STK_Interface &mesh) const
void addElementBlock(const std::string &name, const CellTopologyData *ctData)
void setParameterList(const Teuchos::RCP< Teuchos::ParameterList > &paramList)
From ParameterListAcceptor.
Teuchos::RCP< STK_Interface > buildMesh(stk::ParallelMachine parallelMach) const
Build the mesh object.