Panzer  Version of the Day
Panzer_STK_ExodusReaderFactory.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 
43 
44 #include <Teuchos_TimeMonitor.hpp>
45 #include <PanzerAdaptersSTK_config.hpp>
46 
48 #include "Panzer_STK_Interface.hpp"
49 
50 #ifdef PANZER_HAVE_IOSS
51 
52 #include <Ionit_Initializer.h>
53 #include <Ioss_ElementBlock.h>
54 #include <Ioss_Region.h>
55 #include <stk_mesh/base/GetBuckets.hpp>
56 #include <stk_io/StkMeshIoBroker.hpp>
57 #include <stk_io/IossBridge.hpp>
58 #include <stk_mesh/base/FieldParallel.hpp>
59 
60 #include "Teuchos_StandardParameterEntryValidators.hpp"
61 
62 namespace panzer_stk {
63 
64 int getMeshDimension(const std::string & meshStr,
65  stk::ParallelMachine parallelMach,
66  const bool isExodus)
67 {
68  stk::io::StkMeshIoBroker meshData(parallelMach);
69  meshData.property_add(Ioss::Property("LOWER_CASE_VARIABLE_NAMES", false));
70  if (isExodus)
71  meshData.add_mesh_database(meshStr, "exodusII", stk::io::READ_MESH);
72  else
73  meshData.add_mesh_database(meshStr, "pamgen", stk::io::READ_MESH);
74  meshData.create_input_mesh();
75  return Teuchos::as<int>(meshData.meta_data_rcp()->spatial_dimension());
76 }
77 
78 STK_ExodusReaderFactory::STK_ExodusReaderFactory()
79  : fileName_(""), restartIndex_(0), isExodus_(true), userMeshScaling_(false), keepPerceptData_(false),
80  keepPerceptParentElements_(false), rebalancing_("default"), meshScaleFactor_(0.0), levelsOfRefinement_(0),
81  createEdgeBlocks_(false), createFaceBlocks_(false)
82 { }
83 
84 STK_ExodusReaderFactory::STK_ExodusReaderFactory(const std::string & fileName,
85  const int restartIndex,
86  const bool isExodus)
87  : fileName_(fileName), restartIndex_(restartIndex), isExodus_(isExodus), userMeshScaling_(false),
88  keepPerceptData_(false), keepPerceptParentElements_(false), rebalancing_("default"),
89  meshScaleFactor_(0.0), levelsOfRefinement_(0), createEdgeBlocks_(false), createFaceBlocks_(false)
90 { }
91 
92 Teuchos::RCP<STK_Interface> STK_ExodusReaderFactory::buildMesh(stk::ParallelMachine parallelMach) const
93 {
94  PANZER_FUNC_TIME_MONITOR("panzer::STK_ExodusReaderFactory::buildMesh()");
95 
96  using Teuchos::RCP;
97  using Teuchos::rcp;
98 
99  RCP<STK_Interface> mesh = buildUncommitedMesh(parallelMach);
100 
101  // in here you would add your fields...but it is better to use
102  // the two step construction
103 
104  // this calls commit on meta data
105  const bool buildRefinementSupport = levelsOfRefinement_ > 0 ? true : false;
106  mesh->initialize(parallelMach,false,buildRefinementSupport);
107 
108  completeMeshConstruction(*mesh,parallelMach);
109 
110  return mesh;
111 }
112 
117 Teuchos::RCP<STK_Interface> STK_ExodusReaderFactory::buildUncommitedMesh(stk::ParallelMachine parallelMach) const
118 {
119  PANZER_FUNC_TIME_MONITOR("panzer::STK_ExodusReaderFactory::buildUncomittedMesh()");
120 
121  using Teuchos::RCP;
122  using Teuchos::rcp;
123 
124  // read in meta data
125  stk::io::StkMeshIoBroker* meshData = new stk::io::StkMeshIoBroker(parallelMach);
126  meshData->property_add(Ioss::Property("LOWER_CASE_VARIABLE_NAMES", false));
127 
128  // add in "FAMILY_TREE" entity for doing refinement
129  std::vector<std::string> entity_rank_names = stk::mesh::entity_rank_names();
130  entity_rank_names.push_back("FAMILY_TREE");
131  meshData->set_rank_name_vector(entity_rank_names);
132 
133  if (isExodus_)
134  meshData->add_mesh_database(fileName_, "exodusII", stk::io::READ_MESH);
135  else
136  meshData->add_mesh_database(fileName_, "pamgen", stk::io::READ_MESH);
137 
138  meshData->create_input_mesh();
139  RCP<stk::mesh::MetaData> metaData = meshData->meta_data_rcp();
140 
141  RCP<STK_Interface> mesh = rcp(new STK_Interface(metaData));
142  mesh->initializeFromMetaData();
143  mesh->instantiateBulkData(parallelMach);
144  meshData->set_bulk_data(mesh->getBulkData());
145 
146  // read in other transient fields, these will be useful later when
147  // trying to read other fields for use in solve
148  meshData->add_all_mesh_fields_as_input_fields();
149 
150  // store mesh data pointer for later use in initializing
151  // bulk data
152  mesh->getMetaData()->declare_attribute_with_delete(meshData);
153 
154  // build element blocks
155  registerElementBlocks(*mesh,*meshData);
156  registerSidesets(*mesh);
157  registerNodesets(*mesh);
158 
159  if (createEdgeBlocks_) {
160  registerEdgeBlocks(*mesh);
161  }
162  if (createFaceBlocks_ && mesh->getMetaData()->spatial_dimension() > 2) {
163  registerFaceBlocks(*mesh);
164  }
165 
166  buildMetaData(parallelMach, *mesh);
167 
168  mesh->addPeriodicBCs(periodicBCVec_);
169 
170  return mesh;
171 }
172 
173 void STK_ExodusReaderFactory::completeMeshConstruction(STK_Interface & mesh,stk::ParallelMachine parallelMach) const
174 {
175  PANZER_FUNC_TIME_MONITOR("panzer::STK_ExodusReaderFactory::completeMeshConstruction()");
176 
177  using Teuchos::RCP;
178  using Teuchos::rcp;
179 
180 
181  if(not mesh.isInitialized()) {
182  const bool buildRefinementSupport = levelsOfRefinement_ > 0 ? true : false;
183  mesh.initialize(parallelMach,true,buildRefinementSupport);
184  }
185 
186  // grab mesh data pointer to build the bulk data
187  stk::mesh::MetaData & metaData = *mesh.getMetaData();
188  stk::mesh::BulkData & bulkData = *mesh.getBulkData();
189  stk::io::StkMeshIoBroker * meshData =
190  const_cast<stk::io::StkMeshIoBroker *>(metaData.get_attribute<stk::io::StkMeshIoBroker>());
191  // if const_cast is wrong ... why does it feel so right?
192  // I believe this is safe since we are basically hiding this object under the covers
193  // until the mesh construction can be completed...below I cleanup the object myself.
194  TEUCHOS_ASSERT(metaData.remove_attribute(meshData));
195  // remove the MeshData attribute
196 
197  // build mesh bulk data
198  meshData->populate_bulk_data();
199 
200  const bool deleteParentElements = !keepPerceptParentElements_;
201  if (levelsOfRefinement_ > 0)
202  mesh.refineMesh(levelsOfRefinement_,deleteParentElements);
203 
204  // The following section of code is applicable if mesh scaling is
205  // turned on from the input file.
206  if (userMeshScaling_)
207  {
208  stk::mesh::Field<double,stk::mesh::Cartesian>* coord_field =
209  metaData.get_field<stk::mesh::Field<double, stk::mesh::Cartesian> >(stk::topology::NODE_RANK, "coordinates");
210 
211  stk::mesh::Selector select_all_local = metaData.locally_owned_part() | metaData.globally_shared_part();
212  stk::mesh::BucketVector const& my_node_buckets = bulkData.get_buckets(stk::topology::NODE_RANK, select_all_local);
213 
214  int mesh_dim = mesh.getDimension();
215 
216  // Scale the mesh
217  const double inv_msf = 1.0/meshScaleFactor_;
218  for (size_t i=0; i < my_node_buckets.size(); ++i)
219  {
220  stk::mesh::Bucket& b = *(my_node_buckets[i]);
221  double* coordinate_data = field_data( *coord_field, b );
222 
223  for (size_t j=0; j < b.size(); ++j) {
224  for (int k=0; k < mesh_dim; ++k) {
225  coordinate_data[mesh_dim*j + k] *= inv_msf;
226  }
227  }
228  }
229  }
230 
231  // put in a negative index and (like python) the restart will be from the back
232  // (-1 is the last time step)
233  int restartIndex = restartIndex_;
234  if(restartIndex<0) {
235  std::pair<int,double> lastTimeStep = meshData->get_input_io_region()->get_max_time();
236  restartIndex = 1+restartIndex+lastTimeStep.first;
237  }
238 
239  // populate mesh fields with specific index
240  meshData->read_defined_input_fields(restartIndex);
241 
242  mesh.buildSubcells();
243  mesh.buildLocalElementIDs();
244  if (createEdgeBlocks_) {
245  mesh.buildLocalEdgeIDs();
246  }
247  if (createFaceBlocks_ && mesh.getMetaData()->spatial_dimension() > 2) {
248  mesh.buildLocalFaceIDs();
249  }
250 
251  mesh.beginModification();
252  if (createEdgeBlocks_) {
253  addEdgeBlocks(mesh);
254  }
255  if (createFaceBlocks_ && mesh.getMetaData()->spatial_dimension() > 2) {
256  addFaceBlocks(mesh);
257  }
258  mesh.endModification();
259 
260  if (userMeshScaling_) {
261  stk::mesh::Field<double,stk::mesh::Cartesian>* coord_field =
262  metaData.get_field<stk::mesh::Field<double, stk::mesh::Cartesian> >(stk::topology::NODE_RANK, "coordinates");
263  std::vector< const stk::mesh::FieldBase *> fields;
264  fields.push_back(coord_field);
265 
266  stk::mesh::communicate_field_data(bulkData, fields);
267  }
268 
269  if(restartIndex>0) // process_input_request is a no-op if restartIndex<=0 ... thus there would be no inital time
270  mesh.setInitialStateTime(meshData->get_input_io_region()->get_state_time(restartIndex));
271  else
272  mesh.setInitialStateTime(0.0); // no initial time to speak, might as well use 0.0
273 
274  // clean up mesh data object
275  delete meshData;
276 
277  if(rebalancing_ == "default")
278  // calls Stk_MeshFactory::rebalance
279  this->rebalance(mesh);
280  else if(rebalancing_ != "none")
281  {
282  TEUCHOS_TEST_FOR_EXCEPTION(true,std::logic_error,
283  "ERROR: Rebalancing was not set to a valid choice");
284  }
285 }
286 
288 void STK_ExodusReaderFactory::setParameterList(const Teuchos::RCP<Teuchos::ParameterList> & paramList)
289 {
290  TEUCHOS_TEST_FOR_EXCEPTION_PURE_MSG(!paramList->isParameter("File Name"),
291  Teuchos::Exceptions::InvalidParameterName,
292  "Error, the parameter {name=\"File Name\","
293  "type=\"string\""
294  "\nis required in parameter (sub)list \""<< paramList->name() <<"\"."
295  "\n\nThe parsed parameter parameter list is: \n" << paramList->currentParametersString()
296  );
297 
298  // Set default values here. Not all the params should be set so this
299  // has to be done manually as opposed to using
300  // validateParametersAndSetDefaults().
301  if(!paramList->isParameter("Restart Index"))
302  paramList->set<int>("Restart Index", -1);
303 
304  if(!paramList->isParameter("File Type"))
305  paramList->set("File Type", "Exodus");
306 
307  if(!paramList->isSublist("Periodic BCs"))
308  paramList->sublist("Periodic BCs");
309 
310  Teuchos::ParameterList& p_bcs = paramList->sublist("Periodic BCs");
311  if (!p_bcs.isParameter("Count"))
312  p_bcs.set<int>("Count", 0);
313 
314  if(!paramList->isParameter("Levels of Uniform Refinement"))
315  paramList->set<int>("Levels of Uniform Refinement", 0);
316 
317  if(!paramList->isParameter("Keep Percept Data"))
318  paramList->set<bool>("Keep Percept Data", false);
319 
320  if(!paramList->isParameter("Keep Percept Parent Elements"))
321  paramList->set<bool>("Keep Percept Parent Elements", false);
322 
323  if(!paramList->isParameter("Rebalancing"))
324  paramList->set<std::string>("Rebalancing", "default");
325 
326  if(!paramList->isParameter("Create Edge Blocks"))
327  // default to false to prevent massive exodiff test failures
328  paramList->set<bool>("Create Edge Blocks", false);
329 
330  if(!paramList->isParameter("Create Face Blocks"))
331  // default to false to prevent massive exodiff test failures
332  paramList->set<bool>("Create Face Blocks", false);
333 
334  paramList->validateParameters(*getValidParameters(),0);
335 
336  setMyParamList(paramList);
337 
338  fileName_ = paramList->get<std::string>("File Name");
339 
340  restartIndex_ = paramList->get<int>("Restart Index");
341 
342  {
343  const auto fileType = paramList->get<std::string>("File Type");
344  isExodus_ = fileType == "Exodus";
345  }
346 
347  // get any mesh scale factor
348  if (paramList->isParameter("Scale Factor"))
349  {
350  meshScaleFactor_ = paramList->get<double>("Scale Factor");
351  userMeshScaling_ = true;
352  }
353 
354  // read in periodic boundary conditions
355  parsePeriodicBCList(Teuchos::rcpFromRef(paramList->sublist("Periodic BCs")),periodicBCVec_);
356 
357  keepPerceptData_ = paramList->get<bool>("Keep Percept Data");
358 
359  keepPerceptParentElements_ = paramList->get<bool>("Keep Percept Parent Elements");
360 
361  rebalancing_ = paramList->get<std::string>("Rebalancing");
362 
363  levelsOfRefinement_ = paramList->get<int>("Levels of Uniform Refinement");
364 
365  createEdgeBlocks_ = paramList->get<bool>("Create Edge Blocks");
366  createFaceBlocks_ = paramList->get<bool>("Create Face Blocks");
367 }
368 
370 Teuchos::RCP<const Teuchos::ParameterList> STK_ExodusReaderFactory::getValidParameters() const
371 {
372  static Teuchos::RCP<Teuchos::ParameterList> validParams;
373 
374  if(validParams==Teuchos::null) {
375  validParams = Teuchos::rcp(new Teuchos::ParameterList);
376  validParams->set<std::string>("File Name","<file name not set>","Name of exodus file to be read",
377  Teuchos::rcp(new Teuchos::FileNameValidator));
378 
379  validParams->set<int>("Restart Index",-1,"Index of solution to read in",
380  Teuchos::rcp(new Teuchos::AnyNumberParameterEntryValidator(Teuchos::AnyNumberParameterEntryValidator::PREFER_INT,Teuchos::AnyNumberParameterEntryValidator::AcceptedTypes(true))));
381 
382  Teuchos::setStringToIntegralParameter<int>("File Type",
383  "Exodus",
384  "Choose input file type - either \"Exodus\" or \"Pamgen\"",
385  Teuchos::tuple<std::string>("Exodus","Pamgen"),
386  validParams.get()
387  );
388 
389  validParams->set<double>("Scale Factor", 1.0, "Scale factor to apply to mesh after read",
390  Teuchos::rcp(new Teuchos::AnyNumberParameterEntryValidator(Teuchos::AnyNumberParameterEntryValidator::PREFER_DOUBLE,Teuchos::AnyNumberParameterEntryValidator::AcceptedTypes(true))));
391 
392  Teuchos::ParameterList & bcs = validParams->sublist("Periodic BCs");
393  bcs.set<int>("Count",0); // no default periodic boundary conditions
394 
395  validParams->set("Levels of Uniform Refinement",0,"Number of levels of inline uniform mesh refinement");
396 
397  validParams->set("Keep Percept Data",false,"Keep the Percept mesh after uniform refinement is applied");
398 
399  validParams->set("Keep Percept Parent Elements",false,"Keep the parent element information in the Percept data");
400 
401  validParams->set("Rebalancing","default","The type of rebalancing to be performed on the mesh after creation (default, none)");
402 
403  // default to false for backward compatibility
404  validParams->set("Create Edge Blocks",false,"Create or copy edge blocks in the mesh");
405  validParams->set("Create Face Blocks",false,"Create or copy face blocks in the mesh");
406  }
407 
408  return validParams.getConst();
409 }
410 
411 void STK_ExodusReaderFactory::registerElementBlocks(STK_Interface & mesh,stk::io::StkMeshIoBroker & meshData) const
412 {
413  using Teuchos::RCP;
414 
415  RCP<stk::mesh::MetaData> femMetaData = mesh.getMetaData();
416 
417  // here we use the Ioss interface because they don't add
418  // "bonus" element blocks and its easier to determine
419  // "real" element blocks versus STK-only blocks
420  const Ioss::ElementBlockContainer & elem_blocks = meshData.get_input_io_region()->get_element_blocks();
421  for(Ioss::ElementBlockContainer::const_iterator itr=elem_blocks.begin();itr!=elem_blocks.end();++itr) {
422  Ioss::GroupingEntity * entity = *itr;
423  const std::string & name = entity->name();
424 
425  const stk::mesh::Part * part = femMetaData->get_part(name);
426  shards::CellTopology cellTopo = stk::mesh::get_cell_topology(femMetaData->get_topology(*part));
427  const CellTopologyData * ct = cellTopo.getCellTopologyData();
428 
429  TEUCHOS_ASSERT(ct!=0);
430  mesh.addElementBlock(part->name(),ct);
431  }
432 }
433 
434 template <typename SetType>
435 void buildSetNames(const SetType & setData,std::vector<std::string> & names)
436 {
437  // pull out all names for this set
438  for(typename SetType::const_iterator itr=setData.begin();itr!=setData.end();++itr) {
439  Ioss::GroupingEntity * entity = *itr;
440  names.push_back(entity->name());
441  }
442 }
443 
444 void STK_ExodusReaderFactory::registerSidesets(STK_Interface & mesh) const
445 {
446  using Teuchos::RCP;
447 
448  RCP<stk::mesh::MetaData> metaData = mesh.getMetaData();
449  const stk::mesh::PartVector & parts = metaData->get_parts();
450 
451  stk::mesh::PartVector::const_iterator partItr;
452  for(partItr=parts.begin();partItr!=parts.end();++partItr) {
453  const stk::mesh::Part * part = *partItr;
454  const stk::mesh::PartVector & subsets = part->subsets();
455  shards::CellTopology cellTopo = stk::mesh::get_cell_topology(metaData->get_topology(*part));
456  const CellTopologyData * ct = cellTopo.getCellTopologyData();
457 
458  // if a side part ==> this is a sideset: now storage is recursive
459  // on part contains all sub parts with consistent topology
460  if(part->primary_entity_rank()==mesh.getSideRank() && ct==0 && subsets.size()>0) {
461  TEUCHOS_TEST_FOR_EXCEPTION(subsets.size()!=1,std::runtime_error,
462  "STK_ExodusReaderFactory::registerSidesets error - part \"" << part->name() <<
463  "\" has more than one subset");
464 
465  // grab cell topology and name of subset part
466  const stk::mesh::Part * ss_part = subsets[0];
467  shards::CellTopology ss_cellTopo = stk::mesh::get_cell_topology(metaData->get_topology(*ss_part));
468  const CellTopologyData * ss_ct = ss_cellTopo.getCellTopologyData();
469 
470  // only add subset parts that have no topology
471  if(ss_ct!=0)
472  mesh.addSideset(part->name(),ss_ct);
473  }
474  }
475 }
476 
477 void STK_ExodusReaderFactory::registerNodesets(STK_Interface & mesh) const
478 {
479  using Teuchos::RCP;
480 
481  RCP<stk::mesh::MetaData> metaData = mesh.getMetaData();
482  const stk::mesh::PartVector & parts = metaData->get_parts();
483 
484  stk::mesh::PartVector::const_iterator partItr;
485  for(partItr=parts.begin();partItr!=parts.end();++partItr) {
486  const stk::mesh::Part * part = *partItr;
487  shards::CellTopology cellTopo = stk::mesh::get_cell_topology(metaData->get_topology(*part));
488  const CellTopologyData * ct = cellTopo.getCellTopologyData();
489 
490  // if a side part ==> this is a sideset: now storage is recursive
491  // on part contains all sub parts with consistent topology
492  if(part->primary_entity_rank()==mesh.getNodeRank() && ct==0) {
493 
494  // only add subset parts that have no topology
495  if(part->name()!=STK_Interface::nodesString)
496  mesh.addNodeset(part->name());
497  }
498  }
499 }
500 
501 void STK_ExodusReaderFactory::registerEdgeBlocks(STK_Interface & mesh) const
502 {
503  using Teuchos::RCP;
504 
505  RCP<stk::mesh::MetaData> metaData = mesh.getMetaData();
506  const stk::mesh::PartVector & parts = metaData->get_parts();
507 
508  stk::mesh::PartVector::const_iterator partItr;
509  for(partItr=parts.begin();partItr!=parts.end();++partItr) {
510  const stk::mesh::Part * part = *partItr;
511  const stk::mesh::PartVector & subsets = part->subsets();
512  shards::CellTopology cellTopo = stk::mesh::get_cell_topology(metaData->get_topology(*part));
513  const CellTopologyData * ct = cellTopo.getCellTopologyData();
514 
515  if(part->primary_entity_rank()==mesh.getEdgeRank() && ct==0 && subsets.size()>0) {
516  TEUCHOS_TEST_FOR_EXCEPTION(subsets.size()!=1,std::runtime_error,
517  "STK_ExodusReaderFactory::registerEdgeBlocks error - part \"" << part->name() <<
518  "\" has more than one subset");
519 
520  if (stk::io::has_edge_block_part_attribute(*part) && stk::io::get_edge_block_part_attribute(*part)) {
521  // grab cell topology and name of subset part
522  const stk::mesh::Part * edge_part = subsets[0];
523  shards::CellTopology edge_cellTopo = stk::mesh::get_cell_topology(metaData->get_topology(*edge_part));
524  const CellTopologyData * edge_ct = edge_cellTopo.getCellTopologyData();
525 
526  // only add subset parts that have no topology
527  if(edge_ct!=0) {
528  mesh.addEdgeBlock(part->name(),edge_ct);
529  }
530  }
531  }
532  }
533 }
534 
535 void STK_ExodusReaderFactory::registerFaceBlocks(STK_Interface & mesh) const
536 {
537  using Teuchos::RCP;
538 
539  RCP<stk::mesh::MetaData> metaData = mesh.getMetaData();
540  const stk::mesh::PartVector & parts = metaData->get_parts();
541 
542  stk::mesh::PartVector::const_iterator partItr;
543  for(partItr=parts.begin();partItr!=parts.end();++partItr) {
544  const stk::mesh::Part * part = *partItr;
545  const stk::mesh::PartVector & subsets = part->subsets();
546  shards::CellTopology cellTopo = stk::mesh::get_cell_topology(metaData->get_topology(*part));
547  const CellTopologyData * ct = cellTopo.getCellTopologyData();
548 
549  if(part->primary_entity_rank()==mesh.getFaceRank() && ct==0 && subsets.size()>0) {
550  TEUCHOS_TEST_FOR_EXCEPTION(subsets.size()!=1,std::runtime_error,
551  "STK_ExodusReaderFactory::registerFaceBlocks error - part \"" << part->name() <<
552  "\" has more than one subset");
553 
554  if (stk::io::has_face_block_part_attribute(*part) && stk::io::get_face_block_part_attribute(*part)) {
555  // grab cell topology and name of subset part
556  const stk::mesh::Part * face_part = subsets[0];
557  shards::CellTopology face_cellTopo = stk::mesh::get_cell_topology(metaData->get_topology(*face_part));
558  const CellTopologyData * face_ct = face_cellTopo.getCellTopologyData();
559 
560  // only add subset parts that have no topology
561  if(face_ct!=0) {
562  mesh.addFaceBlock(part->name(),face_ct);
563  }
564  }
565  }
566  }
567 }
568 
569 // Pre-Condition: call beginModification() before entry
570 // Post-Condition: call endModification() after exit
571 void STK_ExodusReaderFactory::addEdgeBlocks(STK_Interface & mesh) const
572 {
573  stk::mesh::Part * edge_block = mesh.getEdgeBlock(panzer_stk::STK_Interface::edgeBlockString);
574 
575  Teuchos::RCP<stk::mesh::BulkData> bulkData = mesh.getBulkData();
576  Teuchos::RCP<stk::mesh::MetaData> metaData = mesh.getMetaData();
577 
578  std::vector<stk::mesh::Entity> edges;
579  bulkData->get_entities(mesh.getEdgeRank(),metaData->locally_owned_part(),edges);
580  mesh.addEntitiesToEdgeBlock(edges, edge_block);
581 }
582 
583 // Pre-Condition: call beginModification() before entry
584 // Post-Condition: call endModification() after exit
585 void STK_ExodusReaderFactory::addFaceBlocks(STK_Interface & mesh) const
586 {
587  stk::mesh::Part * face_block = mesh.getFaceBlock(panzer_stk::STK_Interface::faceBlockString);
588 
589  Teuchos::RCP<stk::mesh::BulkData> bulkData = mesh.getBulkData();
590  Teuchos::RCP<stk::mesh::MetaData> metaData = mesh.getMetaData();
591 
592  std::vector<stk::mesh::Entity> faces;
593  bulkData->get_entities(mesh.getFaceRank(),metaData->locally_owned_part(),faces);
594  mesh.addEntitiesToFaceBlock(faces, face_block);
595 }
596 
597 void STK_ExodusReaderFactory::buildMetaData(stk::ParallelMachine /* parallelMach */, STK_Interface & mesh) const
598 {
599  std::vector<std::string> block_names;
600  mesh.getElementBlockNames(block_names);
601 
602  const CellTopologyData *ctd = mesh.getCellTopology(block_names[0])->getCellTopologyData();
603 
604  if (createEdgeBlocks_) {
605  auto ep = mesh.getEdgeBlock(panzer_stk::STK_Interface::edgeBlockString);
606  if (ep == 0) {
607  const CellTopologyData * edge_ctd = shards::CellTopology(ctd).getBaseCellTopologyData(1,0);
608  mesh.addEdgeBlock(panzer_stk::STK_Interface::edgeBlockString, edge_ctd);
609  }
610  }
611  if (createFaceBlocks_ && mesh.getMetaData()->spatial_dimension() > 2) {
612  auto fp = mesh.getFaceBlock(panzer_stk::STK_Interface::faceBlockString);
613  if (fp == 0) {
614  const CellTopologyData * face_ctd = shards::CellTopology(ctd).getBaseCellTopologyData(2,0);
615  mesh.addFaceBlock(panzer_stk::STK_Interface::faceBlockString, face_ctd);
616  }
617  }
618 }
619 
620 }
621 
622 #endif
static const std::string nodesString
static const std::string edgeBlockString
static const std::string faceBlockString