Panzer  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Panzer_STK_Interface.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 #include <PanzerAdaptersSTK_config.hpp>
44 #include <Panzer_STK_Interface.hpp>
45 
46 #include <Teuchos_as.hpp>
47 #include <Teuchos_RCPStdSharedPtrConversions.hpp>
48 
49 #include <limits>
50 
51 #include <stk_mesh/base/FieldBase.hpp>
52 #include <stk_mesh/base/Comm.hpp>
53 #include <stk_mesh/base/Selector.hpp>
54 #include <stk_mesh/base/GetEntities.hpp>
55 #include <stk_mesh/base/GetBuckets.hpp>
56 #include <stk_mesh/base/MeshBuilder.hpp>
57 #include <stk_mesh/base/CreateAdjacentEntities.hpp>
58 
59 // #include <stk_rebalance/Rebalance.hpp>
60 // #include <stk_rebalance/Partition.hpp>
61 // #include <stk_rebalance/ZoltanPartition.hpp>
62 // #include <stk_rebalance_utils/RebalanceUtils.hpp>
63 
64 #include <stk_util/parallel/ParallelReduce.hpp>
65 #include <stk_util/parallel/CommSparse.hpp>
66 
67 #ifdef PANZER_HAVE_IOSS
68 #include <Ionit_Initializer.h>
69 #include <stk_io/IossBridge.hpp>
70 #include <stk_io/WriteMesh.hpp>
71 #endif
72 
73 #ifdef PANZER_HAVE_PERCEPT
74 #include <percept/PerceptMesh.hpp>
75 #include <adapt/UniformRefinerPattern.hpp>
76 #include <adapt/UniformRefiner.hpp>
77 #endif
78 
80 
81 #include <set>
82 
83 using Teuchos::RCP;
84 using Teuchos::rcp;
85 
86 namespace panzer_stk {
87 
89 ElementDescriptor::ElementDescriptor(stk::mesh::EntityId gid,const std::vector<stk::mesh::EntityId> & nodes)
90  : gid_(gid), nodes_(nodes) {}
92 
96 buildElementDescriptor(stk::mesh::EntityId elmtId,std::vector<stk::mesh::EntityId> & nodes)
97 {
98  return Teuchos::rcp(new ElementDescriptor(elmtId,nodes));
99 }
100 
101 const std::string STK_Interface::coordsString = "coordinates";
102 const std::string STK_Interface::nodesString = "nodes";
103 const std::string STK_Interface::edgesString = "edges";
104 const std::string STK_Interface::facesString = "faces";
105 const std::string STK_Interface::edgeBlockString = "edge_block";
106 const std::string STK_Interface::faceBlockString = "face_block";
107 
109  : dimension_(0), initialized_(false), currentLocalId_(0), initialStateTime_(0.0), currentStateTime_(0.0), useFieldCoordinates_(false)
110 {
111  metaData_ = rcp(new stk::mesh::MetaData());
112  metaData_->use_simple_fields();
113 }
114 
116  : dimension_(0), initialized_(false), currentLocalId_(0), initialStateTime_(0.0), currentStateTime_(0.0), useFieldCoordinates_(false)
117 {
118  metaData_ = metaData;
119  metaData_->use_simple_fields();
120 }
121 
123  : dimension_(dim), initialized_(false), currentLocalId_(0), useFieldCoordinates_(false)
124 {
125  std::vector<std::string> entity_rank_names = stk::mesh::entity_rank_names();
126  entity_rank_names.push_back("FAMILY_TREE");
127 
128  metaData_ = rcp(new stk::mesh::MetaData(dimension_,entity_rank_names));
129  metaData_->use_simple_fields();
130 
132 }
133 
134 void STK_Interface::addSideset(const std::string & name,const CellTopologyData * ctData)
135 {
138 
139  stk::mesh::Part * sideset = metaData_->get_part(name);
140  if(sideset==nullptr)
141  sideset = &metaData_->declare_part_with_topology(name,
142  stk::mesh::get_topology(shards::CellTopology(ctData), dimension_));
143  sidesets_.insert(std::make_pair(name,sideset));
144 }
145 
146 void STK_Interface::addNodeset(const std::string & name)
147 {
150 
151  stk::mesh::Part * nodeset = metaData_->get_part(name);
152  if(nodeset==nullptr) {
153  const CellTopologyData * ctData = shards::getCellTopologyData<shards::Node>();
154  nodeset = &metaData_->declare_part_with_topology(name,
155  stk::mesh::get_topology(shards::CellTopology(ctData), dimension_));
156  }
157  nodesets_.insert(std::make_pair(name,nodeset));
158 }
159 
160 void STK_Interface::addSolutionField(const std::string & fieldName,const std::string & blockId)
161 {
163  "Unknown element block \"" << blockId << "\"");
164  std::pair<std::string,std::string> key = std::make_pair(fieldName,blockId);
165 
166  // add & declare field if not already added...currently assuming linears
167  if(fieldNameToSolution_.find(key)==fieldNameToSolution_.end()) {
168  SolutionFieldType * field = metaData_->get_field<double>(stk::topology::NODE_RANK, fieldName);
169  if(field==0)
170  field = &metaData_->declare_field<double>(stk::topology::NODE_RANK, fieldName);
171  if ( initialized_ ) {
172  metaData_->enable_late_fields();
173  stk::mesh::put_field_on_mesh(*field, metaData_->universal_part(), nullptr);
174  }
176  }
177 }
178 
179 void STK_Interface::addCellField(const std::string & fieldName,const std::string & blockId)
180 {
182  "Unknown element block \"" << blockId << "\"");
183  std::pair<std::string,std::string> key = std::make_pair(fieldName,blockId);
184 
185  // add & declare field if not already added...currently assuming linears
186  if(fieldNameToCellField_.find(key)==fieldNameToCellField_.end()) {
187  SolutionFieldType * field = metaData_->get_field<double>(stk::topology::ELEMENT_RANK, fieldName);
188  if(field==0)
189  field = &metaData_->declare_field<double>(stk::topology::ELEMENT_RANK, fieldName);
190 
191  if ( initialized_ ) {
192  metaData_->enable_late_fields();
193  stk::mesh::put_field_on_mesh(*field, metaData_->universal_part(), nullptr);
194  }
196  }
197 }
198 
199 void STK_Interface::addEdgeField(const std::string & fieldName,const std::string & blockId)
200 {
202  "Unknown element block \"" << blockId << "\"");
203  std::pair<std::string,std::string> key = std::make_pair(fieldName,blockId);
204 
205  // add & declare field if not already added...currently assuming linears
206  if(fieldNameToEdgeField_.find(key)==fieldNameToEdgeField_.end()) {
207  SolutionFieldType * field = metaData_->get_field<double>(stk::topology::EDGE_RANK, fieldName);
208  if(field==0) {
209  field = &metaData_->declare_field<double>(stk::topology::EDGE_RANK, fieldName);
210  }
211 
212  if ( initialized_ ) {
213  metaData_->enable_late_fields();
214  stk::mesh::put_field_on_mesh(*field, metaData_->universal_part(), nullptr);
215  }
217  }
218 }
219 
220 void STK_Interface::addFaceField(const std::string & fieldName,const std::string & blockId)
221 {
223  "Unknown element block \"" << blockId << "\"");
224  std::pair<std::string,std::string> key = std::make_pair(fieldName,blockId);
225 
226  // add & declare field if not already added...currently assuming linears
227  if(fieldNameToFaceField_.find(key)==fieldNameToFaceField_.end()) {
228  SolutionFieldType * field = metaData_->get_field<double>(stk::topology::FACE_RANK, fieldName);
229  if(field==0) {
230  field = &metaData_->declare_field<double>(stk::topology::FACE_RANK, fieldName);
231  }
232 
233  if ( initialized_ ) {
234  metaData_->enable_late_fields();
235  stk::mesh::put_field_on_mesh(*field, metaData_->universal_part(), nullptr);
236  }
238  }
239 }
240 
241 void STK_Interface::addMeshCoordFields(const std::string & blockId,
242  const std::vector<std::string> & coordNames,
243  const std::string & dispPrefix)
244 {
246  TEUCHOS_ASSERT(dimension_==coordNames.size());
249  "Unknown element block \"" << blockId << "\"");
250 
251  // we only allow one alternative coordinate field
252  TEUCHOS_TEST_FOR_EXCEPTION(meshCoordFields_.find(blockId)!=meshCoordFields_.end(),std::invalid_argument,
253  "STK_Interface::addMeshCoordFields: Can't set more than one set of coordinate "
254  "fields for element block \""+blockId+"\".");
255 
256  // Note that there is a distinction between the key which is used for lookups
257  // and the field that lives on the mesh, which is used for printing the displacement.
258 
259  // just copy the coordinate names
260  meshCoordFields_[blockId] = coordNames;
261 
262  // must fill in the displacement fields
263  std::vector<std::string> & dispFields = meshDispFields_[blockId];
264  dispFields.resize(dimension_);
265 
266  for(unsigned i=0;i<dimension_;i++) {
267  std::pair<std::string,std::string> key = std::make_pair(coordNames[i],blockId);
268  std::string dispName = dispPrefix+coordNames[i];
269 
270  dispFields[i] = dispName; // record this field as a
271  // displacement field
272 
273  // add & declare field if not already added...currently assuming linears
274  if(fieldNameToSolution_.find(key)==fieldNameToSolution_.end()) {
275 
276  SolutionFieldType * field = metaData_->get_field<double>(stk::topology::NODE_RANK, dispName);
277  if(field==0) {
278  field = &metaData_->declare_field<double>(stk::topology::NODE_RANK, dispName);
279  }
281  }
282  }
283 }
284 
285 void STK_Interface::addInformationRecords(const std::vector<std::string> & info_records)
286 {
287  informationRecords_.insert(info_records.begin(), info_records.end());
288 }
289 
290 void STK_Interface::initialize(stk::ParallelMachine parallelMach,bool setupIO,
291  const bool buildRefinementSupport)
292 {
294  TEUCHOS_ASSERT(dimension_!=0); // no zero dimensional meshes!
295 
296  if(mpiComm_==Teuchos::null)
297  mpiComm_ = getSafeCommunicator(parallelMach);
298 
299  procRank_ = stk::parallel_machine_rank(*mpiComm_->getRawMpiComm());
300 
301  // associating the field with a part: universal part!
302  stk::mesh::put_field_on_mesh( *coordinatesField_ , metaData_->universal_part(), getDimension(), nullptr);
303  stk::mesh::put_field_on_mesh( *edgesField_ , metaData_->universal_part(), getDimension(), nullptr);
304  if (dimension_ > 2)
305  stk::mesh::put_field_on_mesh( *facesField_ , metaData_->universal_part(), getDimension(), nullptr);
306  stk::mesh::put_field_on_mesh( *processorIdField_ , metaData_->universal_part(), nullptr);
307  stk::mesh::put_field_on_mesh( *loadBalField_ , metaData_->universal_part(), nullptr);
308 
313 
314 #ifdef PANZER_HAVE_IOSS
315  if(setupIO) {
316  // setup Exodus file IO
318 
319  // add element blocks
320  {
321  std::map<std::string, stk::mesh::Part*>::iterator itr;
322  for(itr=elementBlocks_.begin();itr!=elementBlocks_.end();++itr)
323  if(!stk::io::is_part_io_part(*itr->second))
324  stk::io::put_io_part_attribute(*itr->second); // this can only be called once per part
325  }
326 
327  // add edge blocks
328  {
329  std::map<std::string, stk::mesh::Part*>::iterator itr;
330  for(itr=edgeBlocks_.begin();itr!=edgeBlocks_.end();++itr)
331  if(!stk::io::is_part_edge_block_io_part(*itr->second))
332  stk::io::put_edge_block_io_part_attribute(*itr->second); // this can only be called once per part
333  }
334 
335  // add face blocks
336  {
337  std::map<std::string, stk::mesh::Part*>::iterator itr;
338  for(itr=faceBlocks_.begin();itr!=faceBlocks_.end();++itr)
339  if(!stk::io::is_part_face_block_io_part(*itr->second))
340  stk::io::put_face_block_io_part_attribute(*itr->second); // this can only be called once per part
341  }
342 
343  // add side sets
344  {
345  std::map<std::string, stk::mesh::Part*>::iterator itr;
346  for(itr=sidesets_.begin();itr!=sidesets_.end();++itr)
347  if(!stk::io::is_part_io_part(*itr->second))
348  stk::io::put_io_part_attribute(*itr->second); // this can only be called once per part
349  }
350 
351  // add node sets
352  {
353  std::map<std::string, stk::mesh::Part*>::iterator itr;
354  for(itr=nodesets_.begin();itr!=nodesets_.end();++itr)
355  if(!stk::io::is_part_io_part(*itr->second))
356  stk::io::put_io_part_attribute(*itr->second); // this can only be called once per part
357  }
358 
359  // add nodes
360  if(!stk::io::is_part_io_part(*nodesPart_))
361  stk::io::put_io_part_attribute(*nodesPart_);
362 
363  stk::io::set_field_role(*coordinatesField_, Ioss::Field::MESH);
364  stk::io::set_field_output_type(*coordinatesField_, stk::io::FieldOutputType::VECTOR_3D);
365  stk::io::set_field_role(*edgesField_, Ioss::Field::MESH);
366  stk::io::set_field_output_type(*edgesField_, stk::io::FieldOutputType::VECTOR_3D);
367  if (dimension_ > 2) {
368  stk::io::set_field_role(*facesField_, Ioss::Field::MESH);
369  stk::io::set_field_output_type(*facesField_, stk::io::FieldOutputType::VECTOR_3D);
370  }
371  stk::io::set_field_role(*processorIdField_, Ioss::Field::TRANSIENT);
372  // stk::io::set_field_role(*loadBalField_, Ioss::Field::TRANSIENT);
373 
374  }
375 #endif
376 
377  if (buildRefinementSupport) {
378 #ifdef PANZER_HAVE_PERCEPT
379  refinedMesh_ = Teuchos::rcp(new percept::PerceptMesh(this->getMetaData().get(),
380  this->getBulkData().get(),
381  true));
382 
383  breakPattern_ = Teuchos::rcp(new percept::URP_Heterogeneous_3D(*refinedMesh_));
384 #else
385  TEUCHOS_TEST_FOR_EXCEPTION(true,std::logic_error,
386  "ERROR: Uniform refinement requested. This requires the Percept package to be enabled in Trilinos!");
387 #endif
388  }
389 
390  if(bulkData_==Teuchos::null)
391  instantiateBulkData(*mpiComm_->getRawMpiComm());
392 
393  metaData_->commit();
394 
395  initialized_ = true;
396 }
397 
398 void STK_Interface::initializeFieldsInSTK(const std::map<std::pair<std::string,std::string>,SolutionFieldType*> & nameToField,
399  bool setupIO)
400 {
401  std::set<SolutionFieldType*> uniqueFields;
402  std::map<std::pair<std::string,std::string>,SolutionFieldType*>::const_iterator fieldIter;
403  for(fieldIter=nameToField.begin();fieldIter!=nameToField.end();++fieldIter)
404  uniqueFields.insert(fieldIter->second); // this makes setting up IO easier!
405 
406  {
407  std::set<SolutionFieldType*>::const_iterator uniqueFieldIter;
408  for(uniqueFieldIter=uniqueFields.begin();uniqueFieldIter!=uniqueFields.end();++uniqueFieldIter)
409  stk::mesh::put_field_on_mesh(*(*uniqueFieldIter),metaData_->universal_part(),nullptr);
410  }
411 
412 #ifdef PANZER_HAVE_IOSS
413  if(setupIO) {
414  // add solution fields
415  std::set<SolutionFieldType*>::const_iterator uniqueFieldIter;
416  for(uniqueFieldIter=uniqueFields.begin();uniqueFieldIter!=uniqueFields.end();++uniqueFieldIter)
417  stk::io::set_field_role(*(*uniqueFieldIter), Ioss::Field::TRANSIENT);
418  }
419 #endif
420 }
421 
422 void STK_Interface::instantiateBulkData(stk::ParallelMachine parallelMach)
423 {
424  TEUCHOS_ASSERT(bulkData_==Teuchos::null);
425  if(mpiComm_==Teuchos::null)
426  mpiComm_ = getSafeCommunicator(parallelMach);
427 
428  std::unique_ptr<stk::mesh::BulkData> bulkUPtr = stk::mesh::MeshBuilder(*mpiComm_->getRawMpiComm()).create(Teuchos::get_shared_ptr(metaData_));
429  bulkData_ = rcp(bulkUPtr.release());
430 }
431 
433 {
434  TEUCHOS_TEST_FOR_EXCEPTION(bulkData_==Teuchos::null,std::logic_error,
435  "STK_Interface: Must call \"initialized\" or \"instantiateBulkData\" before \"beginModification\"");
436 
437  bulkData_->modification_begin();
438 }
439 
441 {
442  TEUCHOS_TEST_FOR_EXCEPTION(bulkData_==Teuchos::null,std::logic_error,
443  "STK_Interface: Must call \"initialized\" or \"instantiateBulkData\" before \"endModification\"");
444 
445  // TODO: Resolving sharing this way comes at a cost in performance. The STK
446  // team has decided that users need to declare their own sharing. We should
447  // find where shared entities are being created in Panzer and declare it.
448  // Once this is done, the extra code below can be deleted.
449 
450  stk::CommSparse comm(bulkData_->parallel());
451 
452  for (int phase=0;phase<2;++phase) {
453  for (int i=0;i<bulkData_->parallel_size();++i) {
454  if ( i != bulkData_->parallel_rank() ) {
455  const stk::mesh::BucketVector& buckets = bulkData_->buckets(stk::topology::NODE_RANK);
456  for (size_t j=0;j<buckets.size();++j) {
457  const stk::mesh::Bucket& bucket = *buckets[j];
458  if ( bucket.owned() ) {
459  for (size_t k=0;k<bucket.size();++k) {
460  stk::mesh::EntityKey key = bulkData_->entity_key(bucket[k]);
461  comm.send_buffer(i).pack<stk::mesh::EntityKey>(key);
462  }
463  }
464  }
465  }
466  }
467 
468  if (phase == 0 ) {
469  comm.allocate_buffers();
470  }
471  else {
472  comm.communicate();
473  }
474  }
475 
476  for (int i=0;i<bulkData_->parallel_size();++i) {
477  if ( i != bulkData_->parallel_rank() ) {
478  while(comm.recv_buffer(i).remaining()) {
479  stk::mesh::EntityKey key;
480  comm.recv_buffer(i).unpack<stk::mesh::EntityKey>(key);
481  stk::mesh::Entity node = bulkData_->get_entity(key);
482  if ( bulkData_->is_valid(node) ) {
483  bulkData_->add_node_sharing(node, i);
484  }
485  }
486  }
487  }
488 
489 
490  bulkData_->modification_end();
491 
494 }
495 
496 void STK_Interface::addNode(stk::mesh::EntityId gid, const std::vector<double> & coord)
497 {
498  TEUCHOS_TEST_FOR_EXCEPTION(not isModifiable(),std::logic_error,
499  "STK_Interface::addNode: STK_Interface must be modifiable to add a node");
500  TEUCHOS_TEST_FOR_EXCEPTION(coord.size()!=getDimension(),std::logic_error,
501  "STK_Interface::addNode: number of coordinates in vector must mation dimension");
502  TEUCHOS_TEST_FOR_EXCEPTION(gid==0,std::logic_error,
503  "STK_Interface::addNode: STK has STUPID restriction of no zero GIDs, pick something else");
504  stk::mesh::EntityRank nodeRank = getNodeRank();
505 
506  stk::mesh::Entity node = bulkData_->declare_entity(nodeRank,gid,nodesPartVec_);
507 
508  // set coordinate vector
509  double * fieldCoords = stk::mesh::field_data(*coordinatesField_,node);
510  for(std::size_t i=0;i<coord.size();++i)
511  fieldCoords[i] = coord[i];
512 }
513 
514 void STK_Interface::addEntityToSideset(stk::mesh::Entity entity,stk::mesh::Part * sideset)
515 {
516  std::vector<stk::mesh::Part*> sidesetV;
517  sidesetV.push_back(sideset);
518 
519  bulkData_->change_entity_parts(entity,sidesetV);
520 }
521 
522 void STK_Interface::addEntityToNodeset(stk::mesh::Entity entity,stk::mesh::Part * nodeset)
523 {
524  std::vector<stk::mesh::Part*> nodesetV;
525  nodesetV.push_back(nodeset);
526 
527  bulkData_->change_entity_parts(entity,nodesetV);
528 }
529 
530 void STK_Interface::addEntityToEdgeBlock(stk::mesh::Entity entity,stk::mesh::Part * edgeblock)
531 {
532  std::vector<stk::mesh::Part*> edgeblockV;
533  edgeblockV.push_back(edgeblock);
534 
535  bulkData_->change_entity_parts(entity,edgeblockV);
536 }
537 void STK_Interface::addEntitiesToEdgeBlock(std::vector<stk::mesh::Entity> entities,stk::mesh::Part * edgeblock)
538 {
539  if (entities.size() > 0) {
540  std::vector<stk::mesh::Part*> edgeblockV;
541  edgeblockV.push_back(edgeblock);
542 
543  bulkData_->change_entity_parts(entities,edgeblockV);
544  }
545 }
546 
547 void STK_Interface::addEntityToFaceBlock(stk::mesh::Entity entity,stk::mesh::Part * faceblock)
548 {
549  std::vector<stk::mesh::Part*> faceblockV;
550  faceblockV.push_back(faceblock);
551 
552  bulkData_->change_entity_parts(entity,faceblockV);
553 }
554 void STK_Interface::addEntitiesToFaceBlock(std::vector<stk::mesh::Entity> entities,stk::mesh::Part * faceblock)
555 {
556  if (entities.size() > 0) {
557  std::vector<stk::mesh::Part*> faceblockV;
558  faceblockV.push_back(faceblock);
559 
560  bulkData_->change_entity_parts(entities,faceblockV);
561  }
562 }
563 
564 void STK_Interface::addElement(const Teuchos::RCP<ElementDescriptor> & ed,stk::mesh::Part * block)
565 {
566  std::vector<stk::mesh::Part*> blockVec;
567  blockVec.push_back(block);
568 
569  stk::mesh::EntityRank elementRank = getElementRank();
570  stk::mesh::EntityRank nodeRank = getNodeRank();
571  stk::mesh::Entity element = bulkData_->declare_entity(elementRank,ed->getGID(),blockVec);
572 
573  // build relations that give the mesh structure
574  const std::vector<stk::mesh::EntityId> & nodes = ed->getNodes();
575  for(std::size_t i=0;i<nodes.size();++i) {
576  // add element->node relation
577  stk::mesh::Entity node = bulkData_->get_entity(nodeRank,nodes[i]);
578  TEUCHOS_ASSERT(bulkData_->is_valid(node));
579  bulkData_->declare_relation(element,node,i);
580  }
581 
582  ProcIdData * procId = stk::mesh::field_data(*processorIdField_,element);
583  procId[0] = Teuchos::as<ProcIdData>(procRank_);
584 }
585 
586 
588 {
589  // loop over elements
590  stk::mesh::EntityRank edgeRank = getEdgeRank();
591  std::vector<stk::mesh::Entity> localElmts;
592  getMyElements(localElmts);
593  std::vector<stk::mesh::Entity>::const_iterator itr;
594  for(itr=localElmts.begin();itr!=localElmts.end();++itr) {
595  stk::mesh::Entity element = (*itr);
596  stk::mesh::EntityId gid = bulkData_->identifier(element);
597  std::vector<stk::mesh::EntityId> subcellIds;
598  getSubcellIndices(edgeRank,gid,subcellIds);
599 
600  for(std::size_t i=0;i<subcellIds.size();++i) {
601  stk::mesh::Entity edge = bulkData_->get_entity(edgeRank,subcellIds[i]);
602  stk::mesh::Entity const* relations = bulkData_->begin_nodes(edge);
603 
604  double * node_coord_1 = stk::mesh::field_data(*coordinatesField_,relations[0]);
605  double * node_coord_2 = stk::mesh::field_data(*coordinatesField_,relations[1]);
606 
607  // set coordinate vector
608  double * edgeCoords = stk::mesh::field_data(*edgesField_,edge);
609  for(std::size_t j=0;j<getDimension();++j)
610  edgeCoords[j] = (node_coord_1[j]+node_coord_2[j])/2.0;
611  }
612  }
613 }
614 
616 {
617  // loop over elements
618  stk::mesh::EntityRank faceRank = getFaceRank();
619  std::vector<stk::mesh::Entity> localElmts;
620  getMyElements(localElmts);
621  std::vector<stk::mesh::Entity>::const_iterator itr;
622  for(itr=localElmts.begin();itr!=localElmts.end();++itr) {
623  stk::mesh::Entity element = (*itr);
624  stk::mesh::EntityId gid = elementGlobalId(element);
625  std::vector<stk::mesh::EntityId> subcellIds;
626  getSubcellIndices(faceRank,gid,subcellIds);
627 
628  for(std::size_t i=0;i<subcellIds.size();++i) {
629  stk::mesh::Entity face = bulkData_->get_entity(faceRank,subcellIds[i]);
630  stk::mesh::Entity const* relations = bulkData_->begin_nodes(face);
631  const size_t num_relations = bulkData_->num_nodes(face);
632 
633  // set coordinate vector
634  double * faceCoords = stk::mesh::field_data(*facesField_,face);
635  for(std::size_t j=0;j<getDimension();++j){
636  faceCoords[j] = 0.0;
637  for(std::size_t k=0;k<num_relations;++k)
638  faceCoords[j] += stk::mesh::field_data(*coordinatesField_,relations[k])[j];
639  faceCoords[j] /= double(num_relations);
640  }
641  }
642  }
643 }
644 
645 stk::mesh::Entity STK_Interface::findConnectivityById(stk::mesh::Entity src, stk::mesh::EntityRank tgt_rank, unsigned rel_id) const
646 {
647  const size_t num_rels = bulkData_->num_connectivity(src, tgt_rank);
648  stk::mesh::Entity const* relations = bulkData_->begin(src, tgt_rank);
649  stk::mesh::ConnectivityOrdinal const* ordinals = bulkData_->begin_ordinals(src, tgt_rank);
650  for (size_t i = 0; i < num_rels; ++i) {
651  if (ordinals[i] == static_cast<stk::mesh::ConnectivityOrdinal>(rel_id)) {
652  return relations[i];
653  }
654  }
655 
656  return stk::mesh::Entity();
657 }
658 
660 //
661 // writeToExodus()
662 //
664 void
666 writeToExodus(const std::string& filename,
667  const bool append)
668 {
669  setupExodusFile(filename,append);
670  writeToExodus(0.0);
671 } // end of writeToExodus()
672 
674 //
675 // setupExodusFile()
676 //
678 void
680 setupExodusFile(const std::string& filename,
681  const bool append,
682  const bool append_after_restart_time,
683  const double restart_time)
684 {
685  using std::runtime_error;
686  using stk::io::StkMeshIoBroker;
687  using stk::mesh::FieldVector;
688  using stk::ParallelMachine;
689  using Teuchos::rcp;
690  PANZER_FUNC_TIME_MONITOR("STK_Interface::setupExodusFile(filename)");
691 #ifdef PANZER_HAVE_IOSS
693 
694  ParallelMachine comm = *mpiComm_->getRawMpiComm();
695  meshData_ = rcp(new StkMeshIoBroker(comm));
696  meshData_->set_bulk_data(Teuchos::get_shared_ptr(bulkData_));
697  Ioss::PropertyManager props;
698  props.add(Ioss::Property("LOWER_CASE_VARIABLE_NAMES", "FALSE"));
699  if (append) {
700  if (append_after_restart_time) {
701  meshIndex_ = meshData_->create_output_mesh(filename, stk::io::APPEND_RESULTS,
702  props, restart_time);
703  }
704  else // Append results to the end of the file
705  meshIndex_ = meshData_->create_output_mesh(filename, stk::io::APPEND_RESULTS, props);
706  }
707  else
708  meshIndex_ = meshData_->create_output_mesh(filename, stk::io::WRITE_RESULTS, props);
709  const FieldVector& fields = metaData_->get_fields();
710  for (size_t i(0); i < fields.size(); ++i) {
711  // Do NOT add MESH type stk fields to exodus io, but do add everything
712  // else. This allows us to avoid having to catch a throw for
713  // re-registering coordinates, sidesets, etc... Note that some
714  // fields like LOAD_BAL don't always have a role assigned, so for
715  // roles that point to null, we need to register them as well.
716  auto role = stk::io::get_field_role(*fields[i]);
717  if (role != nullptr) {
718  if (*role != Ioss::Field::MESH)
719  meshData_->add_field(meshIndex_, *fields[i]);
720  } else {
721  meshData_->add_field(meshIndex_, *fields[i]);
722  }
723  }
724 
725  // convert the set to a vector
726  std::vector<std::string> deduped_info_records(informationRecords_.begin(),informationRecords_.end());
727  meshData_->add_info_records(meshIndex_, deduped_info_records);
728 #else
729  TEUCHOS_ASSERT(false)
730 #endif
731 } // end of setupExodusFile()
732 
734 //
735 // writeToExodus()
736 //
738 void
741  double timestep)
742 {
743  using std::cout;
744  using std::endl;
745  using Teuchos::FancyOStream;
746  using Teuchos::rcpFromRef;
747  PANZER_FUNC_TIME_MONITOR("STK_Interface::writeToExodus(timestep)");
748 #ifdef PANZER_HAVE_IOSS
749  if (not meshData_.is_null())
750  {
751  currentStateTime_ = timestep;
752  globalToExodus(GlobalVariable::ADD);
753  meshData_->begin_output_step(meshIndex_, currentStateTime_);
754  meshData_->write_defined_output_fields(meshIndex_);
755  globalToExodus(GlobalVariable::WRITE);
756  meshData_->end_output_step(meshIndex_);
757  }
758  else // if (meshData_.is_null())
759  {
760  FancyOStream out(rcpFromRef(cout));
761  out.setOutputToRootOnly(0);
762  out << "WARNING: Exodus I/O has been disabled or not setup properly; "
763  << "not writing to Exodus." << endl;
764  } // end if (meshData_.is_null()) or not
765 #else
766  TEUCHOS_ASSERT(false);
767 #endif
768 } // end of writeToExodus()
769 
771 //
772 // globalToExodus()
773 //
775 void
776 STK_Interface::
777 globalToExodus(
778  const GlobalVariable& flag)
779 {
780  using std::invalid_argument;
781  using std::string;
782  using Teuchos::Array;
783 
784  // Loop over all the global variables to be added to the Exodus output file.
785  // For each global variable, we determine the data type, and then add or
786  // write it accordingly, depending on the value of flag.
787  for (auto i = globalData_.begin(); i != globalData_.end(); ++i)
788  {
789  const string& name = globalData_.name(i);
790 
791  // Integers.
792  if (globalData_.isType<int>(name))
793  {
794  const auto& value = globalData_.get<int>(name);
795  if (flag == GlobalVariable::ADD)
796  {
797  try
798  {
799  meshData_->add_global(meshIndex_, name, value,
800  stk::util::ParameterType::INTEGER);
801  }
802  catch (...)
803  {
804  return;
805  }
806  }
807  else // if (flag == GlobalVariable::WRITE)
808  meshData_->write_global(meshIndex_, name, value,
809  stk::util::ParameterType::INTEGER);
810  }
811 
812  // Doubles.
813  else if (globalData_.isType<double>(name))
814  {
815  const auto& value = globalData_.get<double>(name);
816  if (flag == GlobalVariable::ADD)
817  {
818  try
819  {
820  meshData_->add_global(meshIndex_, name, value,
821  stk::util::ParameterType::DOUBLE);
822  }
823  catch (...)
824  {
825  return;
826  }
827  }
828  else // if (flag == GlobalVariable::WRITE)
829  meshData_->write_global(meshIndex_, name, value,
830  stk::util::ParameterType::DOUBLE);
831  }
832 
833  // Vectors of integers.
834  else if (globalData_.isType<Array<int>>(name))
835  {
836  const auto& value = globalData_.get<Array<int>>(name).toVector();
837  if (flag == GlobalVariable::ADD)
838  {
839  try
840  {
841  meshData_->add_global(meshIndex_, name, value,
842  stk::util::ParameterType::INTEGERVECTOR);
843  }
844  catch (...)
845  {
846  return;
847  }
848  }
849  else // if (flag == GlobalVariable::WRITE)
850  meshData_->write_global(meshIndex_, name, value,
851  stk::util::ParameterType::INTEGERVECTOR);
852  }
853 
854  // Vectors of doubles.
855  else if (globalData_.isType<Array<double>>(name))
856  {
857  const auto& value = globalData_.get<Array<double>>(name).toVector();
858  if (flag == GlobalVariable::ADD)
859  {
860  try
861  {
862  meshData_->add_global(meshIndex_, name, value,
863  stk::util::ParameterType::DOUBLEVECTOR);
864  }
865  catch (...)
866  {
867  return;
868  }
869  }
870  else // if (flag == GlobalVariable::WRITE)
871  meshData_->write_global(meshIndex_, name, value,
872  stk::util::ParameterType::DOUBLEVECTOR);
873  }
874 
875  // If the data type is something else, throw an exception.
876  else
877  TEUCHOS_TEST_FOR_EXCEPTION(true, invalid_argument,
878  "STK_Interface::globalToExodus(): The global variable to be added " \
879  "to the Exodus output file is of an invalid type. Valid types are " \
880  "int and double, along with std::vectors of those types.")
881  } // end loop over globalData_
882 } // end of globalToExodus()
883 
885 //
886 // addGlobalToExodus()
887 //
889 void
892  const std::string& key,
893  const int& value)
894 {
895  globalData_.set(key, value);
896 } // end of addGlobalToExodus()
897 
899 //
900 // addGlobalToExodus()
901 //
903 void
906  const std::string& key,
907  const double& value)
908 {
909  globalData_.set(key, value);
910 } // end of addGlobalToExodus()
911 
913 //
914 // addGlobalToExodus()
915 //
917 void
920  const std::string& key,
921  const std::vector<int>& value)
922 {
923  using Teuchos::Array;
924  globalData_.set(key, Array<int>(value));
925 } // end of addGlobalToExodus()
926 
928 //
929 // addGlobalToExodus()
930 //
932 void
935  const std::string& key,
936  const std::vector<double>& value)
937 {
938  using Teuchos::Array;
939  globalData_.set(key, Array<double>(value));
940 } // end of addGlobalToExodus()
941 
943 {
944  #ifdef PANZER_HAVE_IOSS
945  return true;
946  #else
947  return false;
948  #endif
949 }
950 
951 void STK_Interface::getElementsSharingNode(stk::mesh::EntityId nodeId,std::vector<stk::mesh::Entity> & elements) const
952 {
953  stk::mesh::EntityRank nodeRank = getNodeRank();
954 
955  // get all relations for node
956  stk::mesh::Entity node = bulkData_->get_entity(nodeRank,nodeId);
957  const size_t numElements = bulkData_->num_elements(node);
958  stk::mesh::Entity const* relations = bulkData_->begin_elements(node);
959 
960  // extract elements sharing nodes
961  elements.insert(elements.end(), relations, relations + numElements);
962 }
963 
964 void STK_Interface::getOwnedElementsSharingNode(stk::mesh::Entity node,std::vector<stk::mesh::Entity> & elements,
965  std::vector<int> & relIds) const
966 {
967  // get all relations for node
968  const size_t numElements = bulkData_->num_elements(node);
969  stk::mesh::Entity const* relations = bulkData_->begin_elements(node);
970  stk::mesh::ConnectivityOrdinal const* rel_ids = bulkData_->begin_element_ordinals(node);
971 
972  // extract elements sharing nodes
973  for (size_t i = 0; i < numElements; ++i) {
974  stk::mesh::Entity element = relations[i];
975 
976  // if owned by this processor
977  if(bulkData_->parallel_owner_rank(element) == static_cast<int>(procRank_)) {
978  elements.push_back(element);
979  relIds.push_back(rel_ids[i]);
980  }
981  }
982 }
983 
984 void STK_Interface::getOwnedElementsSharingNode(stk::mesh::EntityId nodeId,std::vector<stk::mesh::Entity> & elements,
985  std::vector<int> & relIds, unsigned int matchType) const
986 {
987  stk::mesh::EntityRank rank;
988  if(matchType == 0)
989  rank = getNodeRank();
990  else if(matchType == 1)
991  rank = getEdgeRank();
992  else if(matchType == 2)
993  rank = getFaceRank();
994  else
995  TEUCHOS_ASSERT(false);
996 
997  stk::mesh::Entity node = bulkData_->get_entity(rank,nodeId);
998 
999  getOwnedElementsSharingNode(node,elements,relIds);
1000 }
1001 
1002 void STK_Interface::getElementsSharingNodes(const std::vector<stk::mesh::EntityId> nodeIds,std::vector<stk::mesh::Entity> & elements) const
1003 {
1004  std::vector<stk::mesh::Entity> current;
1005 
1006  getElementsSharingNode(nodeIds[0],current); // fill it with elements touching first node
1007  std::sort(current.begin(),current.end()); // sort for intersection on the pointer
1008 
1009  // find intersection with remaining nodes
1010  for(std::size_t n=1;n<nodeIds.size();++n) {
1011  // get elements associated with next node
1012  std::vector<stk::mesh::Entity> nextNode;
1013  getElementsSharingNode(nodeIds[n],nextNode); // fill it with elements touching first node
1014  std::sort(nextNode.begin(),nextNode.end()); // sort for intersection on the pointer ID
1015 
1016  // intersect next node elements with current element list
1017  std::vector<stk::mesh::Entity> intersection(std::min(nextNode.size(),current.size()));
1018  std::vector<stk::mesh::Entity>::const_iterator endItr
1019  = std::set_intersection(current.begin(),current.end(),
1020  nextNode.begin(),nextNode.end(),
1021  intersection.begin());
1022  std::size_t newLength = endItr-intersection.begin();
1023  intersection.resize(newLength);
1024 
1025  // store intersection
1026  current.clear();
1027  current = intersection;
1028  }
1029 
1030  // return the elements computed
1031  elements = current;
1032 }
1033 
1034 void STK_Interface::getNodeIdsForElement(stk::mesh::Entity element,std::vector<stk::mesh::EntityId> & nodeIds) const
1035 {
1036  stk::mesh::Entity const* nodeRel = getBulkData()->begin_nodes(element);
1037  const size_t numNodes = getBulkData()->num_nodes(element);
1038 
1039  nodeIds.reserve(numNodes);
1040  for(size_t i = 0; i < numNodes; ++i) {
1041  nodeIds.push_back(elementGlobalId(nodeRel[i]));
1042  }
1043 }
1044 
1046 {
1047  entityCounts_.clear();
1048  stk::mesh::comm_mesh_counts(*bulkData_,entityCounts_);
1049 }
1050 
1052 {
1053  // developed to mirror "comm_mesh_counts" in stk_mesh/base/Comm.cpp
1054 
1055  const auto entityRankCount = metaData_->entity_rank_count();
1056  const size_t commCount = 10; // entityRankCount
1057 
1058  TEUCHOS_ASSERT(entityRankCount<10);
1059 
1060  // stk::ParallelMachine mach = bulkData_->parallel();
1061  stk::ParallelMachine mach = *mpiComm_->getRawMpiComm();
1062 
1063  std::vector<stk::mesh::EntityId> local(commCount,0);
1064 
1065  // determine maximum ID for this processor for each entity type
1066  stk::mesh::Selector ownedPart = metaData_->locally_owned_part();
1067  for(stk::mesh::EntityRank i=stk::topology::NODE_RANK;
1068  i < static_cast<stk::mesh::EntityRank>(entityRankCount); ++i) {
1069  std::vector<stk::mesh::Entity> entities;
1070 
1071  stk::mesh::get_selected_entities(ownedPart,bulkData_->buckets(i),entities);
1072 
1073  // determine maximum ID for this processor
1074  std::vector<stk::mesh::Entity>::const_iterator itr;
1075  for(itr=entities.begin();itr!=entities.end();++itr) {
1076  stk::mesh::EntityId id = bulkData_->identifier(*itr);
1077  if(id>local[i])
1078  local[i] = id;
1079  }
1080  }
1081 
1082  // get largest IDs across processors
1083  stk::all_reduce(mach,stk::ReduceMax<10>(&local[0]));
1084  maxEntityId_.assign(local.begin(),local.begin()+entityRankCount+1);
1085 }
1086 
1087 std::size_t STK_Interface::getEntityCounts(unsigned entityRank) const
1088 {
1089  TEUCHOS_TEST_FOR_EXCEPTION(entityRank>=entityCounts_.size(),std::logic_error,
1090  "STK_Interface::getEntityCounts: Entity counts do not include rank: " << entityRank);
1091 
1092  return entityCounts_[entityRank];
1093 }
1094 
1095 stk::mesh::EntityId STK_Interface::getMaxEntityId(unsigned entityRank) const
1096 {
1097  TEUCHOS_TEST_FOR_EXCEPTION(entityRank>=maxEntityId_.size(),std::logic_error,
1098  "STK_Interface::getMaxEntityId: Max entity ids do not include rank: " << entityRank);
1099 
1100  return maxEntityId_[entityRank];
1101 }
1102 
1104 {
1105  stk::mesh::PartVector emptyPartVector;
1106  stk::mesh::create_adjacent_entities(*bulkData_,emptyPartVector);
1107 
1110 
1111  addEdges();
1112  if (dimension_ > 2)
1113  addFaces();
1114 }
1115 
1116 const double * STK_Interface::getNodeCoordinates(stk::mesh::EntityId nodeId) const
1117 {
1118  stk::mesh::Entity node = bulkData_->get_entity(getNodeRank(),nodeId);
1119  return stk::mesh::field_data(*coordinatesField_,node);
1120 }
1121 
1122 const double * STK_Interface::getNodeCoordinates(stk::mesh::Entity node) const
1123 {
1124  return stk::mesh::field_data(*coordinatesField_,node);
1125 }
1126 
1127 void STK_Interface::getSubcellIndices(unsigned entityRank,stk::mesh::EntityId elementId,
1128  std::vector<stk::mesh::EntityId> & subcellIds) const
1129 {
1130  stk::mesh::EntityRank elementRank = getElementRank();
1131  stk::mesh::Entity cell = bulkData_->get_entity(elementRank,elementId);
1132 
1133  TEUCHOS_TEST_FOR_EXCEPTION(!bulkData_->is_valid(cell),std::logic_error,
1134  "STK_Interface::getSubcellIndices: could not find element requested (GID = " << elementId << ")");
1135 
1136  const size_t numSubcells = bulkData_->num_connectivity(cell, static_cast<stk::mesh::EntityRank>(entityRank));
1137  stk::mesh::Entity const* subcells = bulkData_->begin(cell, static_cast<stk::mesh::EntityRank>(entityRank));
1138  subcellIds.clear();
1139  subcellIds.resize(numSubcells,0);
1140 
1141  // loop over relations and fill subcell vector
1142  for(size_t i = 0; i < numSubcells; ++i) {
1143  stk::mesh::Entity subcell = subcells[i];
1144  subcellIds[i] = bulkData_->identifier(subcell);
1145  }
1146 }
1147 
1148 void STK_Interface::getMyElements(std::vector<stk::mesh::Entity> & elements) const
1149 {
1150  // setup local ownership
1151  stk::mesh::Selector ownedPart = metaData_->locally_owned_part();
1152 
1153  // grab elements
1154  stk::mesh::EntityRank elementRank = getElementRank();
1155  stk::mesh::get_selected_entities(ownedPart,bulkData_->buckets(elementRank),elements);
1156 }
1157 
1158 void STK_Interface::getMyElements(const std::string & blockID,std::vector<stk::mesh::Entity> & elements) const
1159 {
1160  stk::mesh::Part * elementBlock = getElementBlockPart(blockID);
1161 
1162  TEUCHOS_TEST_FOR_EXCEPTION(elementBlock==0,std::logic_error,"Could not find element block \"" << blockID << "\"");
1163 
1164  // setup local ownership
1165  // stk::mesh::Selector block = *elementBlock;
1166  stk::mesh::Selector ownedBlock = metaData_->locally_owned_part() & (*elementBlock);
1167 
1168  // grab elements
1169  stk::mesh::EntityRank elementRank = getElementRank();
1170  stk::mesh::get_selected_entities(ownedBlock,bulkData_->buckets(elementRank),elements);
1171 }
1172 
1173 void STK_Interface::getNeighborElements(std::vector<stk::mesh::Entity> & elements) const
1174 {
1175  // setup local ownership
1176  stk::mesh::Selector neighborBlock = (!metaData_->locally_owned_part());
1177 
1178  // grab elements
1179  stk::mesh::EntityRank elementRank = getElementRank();
1180  stk::mesh::get_selected_entities(neighborBlock,bulkData_->buckets(elementRank),elements);
1181 }
1182 
1183 void STK_Interface::getNeighborElements(const std::string & blockID,std::vector<stk::mesh::Entity> & elements) const
1184 {
1185  stk::mesh::Part * elementBlock = getElementBlockPart(blockID);
1186 
1187  TEUCHOS_TEST_FOR_EXCEPTION(elementBlock==0,std::logic_error,"Could not find element block \"" << blockID << "\"");
1188 
1189  // setup local ownership
1190  stk::mesh::Selector neighborBlock = (!metaData_->locally_owned_part()) & (*elementBlock);
1191 
1192  // grab elements
1193  stk::mesh::EntityRank elementRank = getElementRank();
1194  stk::mesh::get_selected_entities(neighborBlock,bulkData_->buckets(elementRank),elements);
1195 }
1196 
1197 void STK_Interface::getMyEdges(std::vector<stk::mesh::Entity> & edges) const
1198 {
1199  // setup local ownership
1200  stk::mesh::Selector ownedPart = metaData_->locally_owned_part();
1201 
1202  // grab elements
1203  stk::mesh::get_selected_entities(ownedPart,bulkData_->buckets(getEdgeRank()),edges);
1204 }
1205 
1206 void STK_Interface::getMyEdges(const std::string & edgeBlockName,std::vector<stk::mesh::Entity> & edges) const
1207 {
1208  stk::mesh::Part * edgeBlockPart = getEdgeBlock(edgeBlockName);
1209  TEUCHOS_TEST_FOR_EXCEPTION(edgeBlockPart==0,std::logic_error,
1210  "Unknown edge block \"" << edgeBlockName << "\"");
1211 
1212  stk::mesh::Selector edge_block = *edgeBlockPart;
1213  stk::mesh::Selector owned_block = metaData_->locally_owned_part() & edge_block;
1214 
1215  // grab elements
1216  stk::mesh::get_selected_entities(owned_block,bulkData_->buckets(getEdgeRank()),edges);
1217 }
1218 
1219 void STK_Interface::getMyEdges(const std::string & edgeBlockName,const std::string & blockName,std::vector<stk::mesh::Entity> & edges) const
1220 {
1221  stk::mesh::Part * edgeBlockPart = getEdgeBlock(edgeBlockName);
1222  stk::mesh::Part * elmtPart = getElementBlockPart(blockName);
1224  "Unknown edge block \"" << edgeBlockName << "\"");
1226  "Unknown element block \"" << blockName << "\"");
1227 
1228  stk::mesh::Selector edge_block = *edgeBlockPart;
1229  stk::mesh::Selector element_block = *elmtPart;
1230  stk::mesh::Selector owned_block = metaData_->locally_owned_part() & element_block & edge_block;
1231 
1232  // grab elements
1233  stk::mesh::get_selected_entities(owned_block,bulkData_->buckets(getEdgeRank()),edges);
1234 }
1235 
1236 void STK_Interface::getAllEdges(const std::string & edgeBlockName,std::vector<stk::mesh::Entity> & edges) const
1237 {
1238  stk::mesh::Part * edgeBlockPart = getEdgeBlock(edgeBlockName);
1239  TEUCHOS_TEST_FOR_EXCEPTION(edgeBlockPart==0,std::logic_error,
1240  "Unknown edge block \"" << edgeBlockName << "\"");
1241 
1242  stk::mesh::Selector edge_block = *edgeBlockPart;
1243 
1244  // grab elements
1245  stk::mesh::get_selected_entities(edge_block,bulkData_->buckets(getEdgeRank()),edges);
1246 }
1247 
1248 void STK_Interface::getAllEdges(const std::string & edgeBlockName,const std::string & blockName,std::vector<stk::mesh::Entity> & edges) const
1249 {
1250  stk::mesh::Part * edgeBlockPart = getEdgeBlock(edgeBlockName);
1251  stk::mesh::Part * elmtPart = getElementBlockPart(blockName);
1253  "Unknown edge block \"" << edgeBlockName << "\"");
1255  "Unknown element block \"" << blockName << "\"");
1256 
1257  stk::mesh::Selector edge_block = *edgeBlockPart;
1258  stk::mesh::Selector element_block = *elmtPart;
1259  stk::mesh::Selector element_edge_block = element_block & edge_block;
1260 
1261  // grab elements
1262  stk::mesh::get_selected_entities(element_edge_block,bulkData_->buckets(getEdgeRank()),edges);
1263 }
1264 
1265 void STK_Interface::getMyFaces(std::vector<stk::mesh::Entity> & faces) const
1266 {
1267  // setup local ownership
1268  stk::mesh::Selector ownedPart = metaData_->locally_owned_part();
1269 
1270  // grab elements
1271  stk::mesh::EntityRank faceRank = getFaceRank();
1272  stk::mesh::get_selected_entities(ownedPart,bulkData_->buckets(faceRank),faces);
1273 }
1274 
1275 void STK_Interface::getMyFaces(const std::string & faceBlockName,std::vector<stk::mesh::Entity> & faces) const
1276 {
1277  stk::mesh::Part * faceBlockPart = getFaceBlock(faceBlockName);
1278  TEUCHOS_TEST_FOR_EXCEPTION(faceBlockPart==0,std::logic_error,
1279  "Unknown face block \"" << faceBlockName << "\"");
1280 
1281  stk::mesh::Selector face_block = *faceBlockPart;
1282  stk::mesh::Selector owned_block = metaData_->locally_owned_part() & face_block;
1283 
1284  // grab elements
1285  stk::mesh::get_selected_entities(owned_block,bulkData_->buckets(getFaceRank()),faces);
1286 }
1287 
1288 void STK_Interface::getMyFaces(const std::string & faceBlockName,const std::string & blockName,std::vector<stk::mesh::Entity> & faces) const
1289 {
1290  stk::mesh::Part * faceBlockPart = getFaceBlock(faceBlockName);
1291  stk::mesh::Part * elmtPart = getElementBlockPart(blockName);
1293  "Unknown face block \"" << faceBlockName << "\"");
1295  "Unknown element block \"" << blockName << "\"");
1296 
1297  stk::mesh::Selector face_block = *faceBlockPart;
1298  stk::mesh::Selector element_block = *elmtPart;
1299  stk::mesh::Selector owned_block = metaData_->locally_owned_part() & element_block & face_block;
1300 
1301  // grab elements
1302  stk::mesh::get_selected_entities(owned_block,bulkData_->buckets(getFaceRank()),faces);
1303 }
1304 
1305 void STK_Interface::getAllFaces(const std::string & faceBlockName,std::vector<stk::mesh::Entity> & faces) const
1306 {
1307  stk::mesh::Part * faceBlockPart = getFaceBlock(faceBlockName);
1308  TEUCHOS_TEST_FOR_EXCEPTION(faceBlockPart==0,std::logic_error,
1309  "Unknown face block \"" << faceBlockName << "\"");
1310 
1311  stk::mesh::Selector face_block = *faceBlockPart;
1312 
1313  // grab elements
1314  stk::mesh::get_selected_entities(face_block,bulkData_->buckets(getFaceRank()),faces);
1315 }
1316 
1317 void STK_Interface::getAllFaces(const std::string & faceBlockName,const std::string & blockName,std::vector<stk::mesh::Entity> & faces) const
1318 {
1319  stk::mesh::Part * faceBlockPart = getFaceBlock(faceBlockName);
1320  stk::mesh::Part * elmtPart = getElementBlockPart(blockName);
1322  "Unknown face block \"" << faceBlockName << "\"");
1324  "Unknown element block \"" << blockName << "\"");
1325 
1326  stk::mesh::Selector face_block = *faceBlockPart;
1327  stk::mesh::Selector element_block = *elmtPart;
1328  stk::mesh::Selector element_face_block = element_block & face_block;
1329 
1330  // grab elements
1331  stk::mesh::get_selected_entities(element_face_block,bulkData_->buckets(getFaceRank()),faces);
1332 }
1333 
1334 void STK_Interface::getMySides(const std::string & sideName,std::vector<stk::mesh::Entity> & sides) const
1335 {
1336  stk::mesh::Part * sidePart = getSideset(sideName);
1337  TEUCHOS_TEST_FOR_EXCEPTION(sidePart==0,std::logic_error,
1338  "Unknown side set \"" << sideName << "\"");
1339 
1340  stk::mesh::Selector side = *sidePart;
1341  stk::mesh::Selector ownedBlock = metaData_->locally_owned_part() & side;
1342 
1343  // grab elements
1344  stk::mesh::get_selected_entities(ownedBlock,bulkData_->buckets(getSideRank()),sides);
1345 }
1346 
1347 void STK_Interface::getMySides(const std::string & sideName,const std::string & blockName,std::vector<stk::mesh::Entity> & sides) const
1348 {
1349  stk::mesh::Part * sidePart = getSideset(sideName);
1350  stk::mesh::Part * elmtPart = getElementBlockPart(blockName);
1352  "Unknown side set \"" << sideName << "\"");
1354  "Unknown element block \"" << blockName << "\"");
1355 
1356  stk::mesh::Selector side = *sidePart;
1357  stk::mesh::Selector block = *elmtPart;
1358  stk::mesh::Selector ownedBlock = metaData_->locally_owned_part() & block & side;
1359 
1360  // grab elements
1361  stk::mesh::get_selected_entities(ownedBlock,bulkData_->buckets(getSideRank()),sides);
1362 }
1363 
1364 void STK_Interface::getAllSides(const std::string & sideName,std::vector<stk::mesh::Entity> & sides) const
1365 {
1366  stk::mesh::Part * sidePart = getSideset(sideName);
1367  TEUCHOS_TEST_FOR_EXCEPTION(sidePart==0,std::logic_error,
1368  "Unknown side set \"" << sideName << "\"");
1369 
1370  stk::mesh::Selector side = *sidePart;
1371 
1372  // grab elements
1373  stk::mesh::get_selected_entities(side,bulkData_->buckets(getSideRank()),sides);
1374 }
1375 
1376 void STK_Interface::getAllSides(const std::string & sideName,const std::string & blockName,std::vector<stk::mesh::Entity> & sides) const
1377 {
1378  stk::mesh::Part * sidePart = getSideset(sideName);
1379  stk::mesh::Part * elmtPart = getElementBlockPart(blockName);
1381  "Unknown side set \"" << sideName << "\"");
1383  "Unknown element block \"" << blockName << "\"");
1384 
1385  stk::mesh::Selector side = *sidePart;
1386  stk::mesh::Selector block = *elmtPart;
1387  stk::mesh::Selector sideBlock = block & side;
1388 
1389  // grab elements
1390  stk::mesh::get_selected_entities(sideBlock,bulkData_->buckets(getSideRank()),sides);
1391 }
1392 
1393 void STK_Interface::getMyNodes(const std::string & nodesetName,const std::string & blockName,std::vector<stk::mesh::Entity> & nodes) const
1394 {
1395  stk::mesh::Part * nodePart = getNodeset(nodesetName);
1396  stk::mesh::Part * elmtPart = getElementBlockPart(blockName);
1398  "Unknown node set \"" << nodesetName << "\"");
1400  "Unknown element block \"" << blockName << "\"");
1401 
1402  stk::mesh::Selector nodeset = *nodePart;
1403  stk::mesh::Selector block = *elmtPart;
1404  stk::mesh::Selector ownedBlock = metaData_->locally_owned_part() & block & nodeset;
1405 
1406  // grab elements
1407  stk::mesh::get_selected_entities(ownedBlock,bulkData_->buckets(getNodeRank()),nodes);
1408 }
1409 
1410 void STK_Interface::getElementBlockNames(std::vector<std::string> & names) const
1411 {
1412  // TEUCHOS_ASSERT(initialized_); // all blocks must have been added
1413 
1414  names.clear();
1415 
1416  // fill vector with automagically ordered string values
1417  std::map<std::string, stk::mesh::Part*>::const_iterator blkItr; // Element blocks
1418  for(blkItr=elementBlocks_.begin();blkItr!=elementBlocks_.end();++blkItr)
1419  names.push_back(blkItr->first);
1420 }
1421 
1422 void STK_Interface::getSidesetNames(std::vector<std::string> & names) const
1423 {
1424  // TEUCHOS_ASSERT(initialized_); // all blocks must have been added
1425 
1426  names.clear();
1427 
1428  // fill vector with automagically ordered string values
1429  std::map<std::string, stk::mesh::Part*>::const_iterator sideItr; // Side sets
1430  for(sideItr=sidesets_.begin();sideItr!=sidesets_.end();++sideItr)
1431  names.push_back(sideItr->first);
1432 }
1433 
1434 void STK_Interface::getNodesetNames(std::vector<std::string> & names) const
1435 {
1436  names.clear();
1437 
1438  // fill vector with automagically ordered string values
1439  std::map<std::string, stk::mesh::Part*>::const_iterator nodeItr; // Node sets
1440  for(nodeItr=nodesets_.begin();nodeItr!=nodesets_.end();++nodeItr)
1441  names.push_back(nodeItr->first);
1442 }
1443 
1444 void STK_Interface::getEdgeBlockNames(std::vector<std::string> & names) const
1445 {
1446  names.clear();
1447 
1448  // fill vector with automagically ordered string values
1449  std::map<std::string, stk::mesh::Part*>::const_iterator edgeBlockItr; // Edge blocks
1450  for(edgeBlockItr=edgeBlocks_.begin();edgeBlockItr!=edgeBlocks_.end();++edgeBlockItr)
1451  names.push_back(edgeBlockItr->first);
1452 }
1453 
1454 void STK_Interface::getFaceBlockNames(std::vector<std::string> & names) const
1455 {
1456  names.clear();
1457 
1458  // fill vector with automagically ordered string values
1459  std::map<std::string, stk::mesh::Part*>::const_iterator faceBlockItr; // Face blocks
1460  for(faceBlockItr=faceBlocks_.begin();faceBlockItr!=faceBlocks_.end();++faceBlockItr)
1461  names.push_back(faceBlockItr->first);
1462 }
1463 
1464 std::size_t STK_Interface::elementLocalId(stk::mesh::Entity elmt) const
1465 {
1466  return elementLocalId(bulkData_->identifier(elmt));
1467  // const std::size_t * fieldCoords = stk::mesh::field_data(*localIdField_,*elmt);
1468  // return fieldCoords[0];
1469 }
1470 
1471 std::size_t STK_Interface::elementLocalId(stk::mesh::EntityId gid) const
1472 {
1473  // stk::mesh::EntityRank elementRank = getElementRank();
1474  // stk::mesh::Entity elmt = bulkData_->get_entity(elementRank,gid);
1475  // TEUCHOS_ASSERT(elmt->owner_rank()==procRank_);
1476  // return elementLocalId(elmt);
1477  std::unordered_map<stk::mesh::EntityId,std::size_t>::const_iterator itr = localIDHash_.find(gid);
1478  TEUCHOS_ASSERT(itr!=localIDHash_.end());
1479  return itr->second;
1480 }
1481 
1482 bool STK_Interface::isEdgeLocal(stk::mesh::Entity edge) const
1483 {
1484  return isEdgeLocal(bulkData_->identifier(edge));
1485 }
1486 
1487 bool STK_Interface::isEdgeLocal(stk::mesh::EntityId gid) const
1488 {
1489  std::unordered_map<stk::mesh::EntityId,std::size_t>::const_iterator itr = localEdgeIDHash_.find(gid);
1490  if (itr==localEdgeIDHash_.end()) {
1491  return false;
1492  }
1493  return true;
1494 }
1495 
1496 std::size_t STK_Interface::edgeLocalId(stk::mesh::Entity edge) const
1497 {
1498  return edgeLocalId(bulkData_->identifier(edge));
1499 }
1500 
1501 std::size_t STK_Interface::edgeLocalId(stk::mesh::EntityId gid) const
1502 {
1503  std::unordered_map<stk::mesh::EntityId,std::size_t>::const_iterator itr = localEdgeIDHash_.find(gid);
1504  TEUCHOS_ASSERT(itr!=localEdgeIDHash_.end());
1505  return itr->second;
1506 }
1507 
1508 bool STK_Interface::isFaceLocal(stk::mesh::Entity face) const
1509 {
1510  return isFaceLocal(bulkData_->identifier(face));
1511 }
1512 
1513 bool STK_Interface::isFaceLocal(stk::mesh::EntityId gid) const
1514 {
1515  std::unordered_map<stk::mesh::EntityId,std::size_t>::const_iterator itr = localFaceIDHash_.find(gid);
1516  if (itr==localFaceIDHash_.end()) {
1517  return false;
1518  }
1519  return true;
1520 }
1521 
1522 std::size_t STK_Interface::faceLocalId(stk::mesh::Entity face) const
1523 {
1524  return faceLocalId(bulkData_->identifier(face));
1525 }
1526 
1527 std::size_t STK_Interface::faceLocalId(stk::mesh::EntityId gid) const
1528 {
1529  std::unordered_map<stk::mesh::EntityId,std::size_t>::const_iterator itr = localFaceIDHash_.find(gid);
1530  TEUCHOS_ASSERT(itr!=localFaceIDHash_.end());
1531  return itr->second;
1532 }
1533 
1534 
1535 std::string STK_Interface::containingBlockId(stk::mesh::Entity elmt) const
1536 {
1537  for(const auto & eb_pair : elementBlocks_)
1538  if(bulkData_->bucket(elmt).member(*(eb_pair.second)))
1539  return eb_pair.first;
1540  return "";
1541 }
1542 
1543 stk::mesh::Field<double> * STK_Interface::getSolutionField(const std::string & fieldName,
1544  const std::string & blockId) const
1545 {
1546  // look up field in map
1547  std::map<std::pair<std::string,std::string>, SolutionFieldType*>::const_iterator
1548  iter = fieldNameToSolution_.find(std::make_pair(fieldName,blockId));
1549 
1550  // check to make sure field was actually found
1551  TEUCHOS_TEST_FOR_EXCEPTION(iter==fieldNameToSolution_.end(),std::runtime_error,
1552  "Solution field name \"" << fieldName << "\" in block ID \"" << blockId << "\" was not found");
1553 
1554  return iter->second;
1555 }
1556 
1557 stk::mesh::Field<double> * STK_Interface::getCellField(const std::string & fieldName,
1558  const std::string & blockId) const
1559 {
1560  // look up field in map
1561  std::map<std::pair<std::string,std::string>, SolutionFieldType*>::const_iterator
1562  iter = fieldNameToCellField_.find(std::make_pair(fieldName,blockId));
1563 
1564  // check to make sure field was actually found
1565  TEUCHOS_TEST_FOR_EXCEPTION(iter==fieldNameToCellField_.end(),std::runtime_error,
1566  "Cell field named \"" << fieldName << "\" in block ID \"" << blockId << "\" was not found");
1567 
1568  return iter->second;
1569 }
1570 
1571 stk::mesh::Field<double> * STK_Interface::getEdgeField(const std::string & fieldName,
1572  const std::string & blockId) const
1573 {
1574  // look up field in map
1575  std::map<std::pair<std::string,std::string>, SolutionFieldType*>::const_iterator
1576  iter = fieldNameToEdgeField_.find(std::make_pair(fieldName,blockId));
1577 
1578  // check to make sure field was actually found
1579  TEUCHOS_TEST_FOR_EXCEPTION(iter==fieldNameToEdgeField_.end(),std::runtime_error,
1580  "Edge field named \"" << fieldName << "\" in block ID \"" << blockId << "\" was not found");
1581 
1582  return iter->second;
1583 }
1584 
1585 stk::mesh::Field<double> * STK_Interface::getFaceField(const std::string & fieldName,
1586  const std::string & blockId) const
1587 {
1588  // look up field in map
1589  std::map<std::pair<std::string,std::string>, SolutionFieldType*>::const_iterator
1590  iter = fieldNameToFaceField_.find(std::make_pair(fieldName,blockId));
1591 
1592  // check to make sure field was actually found
1593  TEUCHOS_TEST_FOR_EXCEPTION(iter==fieldNameToFaceField_.end(),std::runtime_error,
1594  "Face field named \"" << fieldName << "\" in block ID \"" << blockId << "\" was not found");
1595 
1596  return iter->second;
1597 }
1598 
1600 {
1601  using Teuchos::RCP;
1602  using Teuchos::rcp;
1603 
1604  if(orderedElementVector_==Teuchos::null) {
1605  // safe because essentially this is a call to modify a mutable object
1606  const_cast<STK_Interface*>(this)->buildLocalElementIDs();
1607  }
1608 
1610 }
1611 
1612 void STK_Interface::addElementBlock(const std::string & name,const CellTopologyData * ctData)
1613 {
1615 
1616  stk::mesh::Part * block = metaData_->get_part(name);
1617  if(block==0) {
1618  block = &metaData_->declare_part_with_topology(name, stk::mesh::get_topology(shards::CellTopology(ctData), dimension_));
1619  }
1620 
1621  // construct cell topology object for this block
1623  = Teuchos::rcp(new shards::CellTopology(ctData));
1624 
1625  // add element block part and cell topology
1626  elementBlocks_.insert(std::make_pair(name,block));
1627  elementBlockCT_.insert(std::make_pair(name,ct));
1628 }
1629 
1631 {
1632  using Teuchos::RCP;
1633  using Teuchos::rcp;
1634 
1635  if(orderedEdgeVector_==Teuchos::null) {
1636  // safe because essentially this is a call to modify a mutable object
1637  const_cast<STK_Interface*>(this)->buildLocalEdgeIDs();
1638  }
1639 
1640  return orderedEdgeVector_.getConst();
1641 }
1642 
1643 void STK_Interface::addEdgeBlock(const std::string & elemBlockName,
1644  const std::string & edgeBlockName,
1645  const stk::topology & topology)
1646 {
1648 
1649  stk::mesh::Part * edge_block = metaData_->get_part(edgeBlockName);
1650  if(edge_block==0) {
1651  edge_block = &metaData_->declare_part_with_topology(edgeBlockName, topology);
1652  }
1653 
1654  /* There is only one edge block for each edge topology, so declare it
1655  * as a subset of the element block even if it wasn't just created.
1656  */
1657  stk::mesh::Part * elem_block = metaData_->get_part(elemBlockName);
1658  metaData_->declare_part_subset(*elem_block, *edge_block);
1659 
1660  // add edge block part
1661  edgeBlocks_.insert(std::make_pair(edgeBlockName,edge_block));
1662 }
1663 
1664 void STK_Interface::addEdgeBlock(const std::string & elemBlockName,
1665  const std::string & edgeBlockName,
1666  const CellTopologyData * ctData)
1667 {
1669 
1670  addEdgeBlock(elemBlockName,
1671  edgeBlockName,
1672  stk::mesh::get_topology(shards::CellTopology(ctData), dimension_));
1673 }
1674 
1676 {
1677  using Teuchos::RCP;
1678  using Teuchos::rcp;
1679 
1680  if(orderedFaceVector_==Teuchos::null) {
1681  // safe because essentially this is a call to modify a mutable object
1682  const_cast<STK_Interface*>(this)->buildLocalFaceIDs();
1683  }
1684 
1685  return orderedFaceVector_.getConst();
1686 }
1687 
1688 void STK_Interface::addFaceBlock(const std::string & elemBlockName,
1689  const std::string & faceBlockName,
1690  const stk::topology & topology)
1691 {
1693 
1694  stk::mesh::Part * face_block = metaData_->get_part(faceBlockName);
1695  if(face_block==0) {
1696  face_block = &metaData_->declare_part_with_topology(faceBlockName, topology);
1697  }
1698 
1699  /* There is only one face block for each edge topology, so declare it
1700  * as a subset of the element block even if it wasn't just created.
1701  */
1702  stk::mesh::Part * elem_block = metaData_->get_part(elemBlockName);
1703  metaData_->declare_part_subset(*elem_block, *face_block);
1704 
1705  // add face block part
1706  faceBlocks_.insert(std::make_pair(faceBlockName,face_block));
1707 }
1708 
1709 void STK_Interface::addFaceBlock(const std::string & elemBlockName,
1710  const std::string & faceBlockName,
1711  const CellTopologyData * ctData)
1712 {
1714 
1715  addFaceBlock(elemBlockName,
1716  faceBlockName,
1717  stk::mesh::get_topology(shards::CellTopology(ctData), dimension_));
1718 }
1719 
1721 {
1722  dimension_ = metaData_->spatial_dimension();
1723 
1724  // declare coordinates and node parts
1725  coordinatesField_ = &metaData_->declare_field<double>(stk::topology::NODE_RANK, coordsString);
1726  edgesField_ = &metaData_->declare_field<double>(stk::topology::EDGE_RANK, edgesString);
1727  if (dimension_ > 2)
1728  facesField_ = &metaData_->declare_field<double>(stk::topology::FACE_RANK, facesString);
1729  processorIdField_ = &metaData_->declare_field<ProcIdData>(stk::topology::ELEMENT_RANK, "PROC_ID");
1730  loadBalField_ = &metaData_->declare_field<double>(stk::topology::ELEMENT_RANK, "LOAD_BAL");
1731 
1732  // stk::mesh::put_field( *coordinatesField_ , getNodeRank() , metaData_->universal_part() );
1733 
1734  nodesPart_ = &metaData_->declare_part(nodesString,getNodeRank());
1735  nodesPartVec_.push_back(nodesPart_);
1736  edgesPart_ = &metaData_->declare_part(edgesString,getEdgeRank());
1737  edgesPartVec_.push_back(edgesPart_);
1738  if (dimension_ > 2) {
1739  facesPart_ = &metaData_->declare_part(facesString,getFaceRank());
1740  facesPartVec_.push_back(facesPart_);
1741  }
1742 }
1743 
1745 {
1746  currentLocalId_ = 0;
1747 
1748  orderedElementVector_ = Teuchos::null; // forces rebuild of ordered lists
1749 
1750  // might be better (faster) to do this by buckets
1751  std::vector<stk::mesh::Entity> elements;
1752  getMyElements(elements);
1753 
1754  for(std::size_t index=0;index<elements.size();++index) {
1755  stk::mesh::Entity element = elements[index];
1756 
1757  // set processor rank
1758  ProcIdData * procId = stk::mesh::field_data(*processorIdField_,element);
1759  procId[0] = Teuchos::as<ProcIdData>(procRank_);
1760 
1761  localIDHash_[bulkData_->identifier(element)] = currentLocalId_;
1762 
1763  currentLocalId_++;
1764  }
1765 
1766  // copy elements into the ordered element vector
1767  orderedElementVector_ = Teuchos::rcp(new std::vector<stk::mesh::Entity>(elements));
1768 
1769  elements.clear();
1770  getNeighborElements(elements);
1771 
1772  for(std::size_t index=0;index<elements.size();++index) {
1773  stk::mesh::Entity element = elements[index];
1774 
1775  // set processor rank
1776  ProcIdData * procId = stk::mesh::field_data(*processorIdField_,element);
1777  procId[0] = Teuchos::as<ProcIdData>(procRank_);
1778 
1779  localIDHash_[bulkData_->identifier(element)] = currentLocalId_;
1780 
1781  currentLocalId_++;
1782  }
1783 
1784  orderedElementVector_->insert(orderedElementVector_->end(),elements.begin(),elements.end());
1785 }
1786 
1788 {
1789  std::vector<std::string> names;
1790  getElementBlockNames(names);
1791 
1792  for(std::size_t b=0;b<names.size();b++) {
1793  // find user specified block weight, otherwise use 1.0
1794  std::map<std::string,double>::const_iterator bw_itr = blockWeights_.find(names[b]);
1795  double blockWeight = (bw_itr!=blockWeights_.end()) ? bw_itr->second : 1.0;
1796 
1797  std::vector<stk::mesh::Entity> elements;
1798  getMyElements(names[b],elements);
1799 
1800  for(std::size_t index=0;index<elements.size();++index) {
1801  // set local element ID
1802  double * loadBal = stk::mesh::field_data(*loadBalField_,elements[index]);
1803  loadBal[0] = blockWeight;
1804  }
1805  }
1806 }
1807 
1809 {
1810  currentLocalId_ = 0;
1811 
1812  orderedEdgeVector_ = Teuchos::null; // forces rebuild of ordered lists
1813 
1814  // might be better (faster) to do this by buckets
1815  std::vector<stk::mesh::Entity> edges;
1816  getMyEdges(edges);
1817 
1818  for(std::size_t index=0;index<edges.size();++index) {
1819  stk::mesh::Entity edge = edges[index];
1820  localEdgeIDHash_[bulkData_->identifier(edge)] = currentLocalId_;
1821  currentLocalId_++;
1822  }
1823 
1824  // copy edges into the ordered edge vector
1825  orderedEdgeVector_ = Teuchos::rcp(new std::vector<stk::mesh::Entity>(edges));
1826 }
1827 
1829 {
1830  currentLocalId_ = 0;
1831 
1832  orderedFaceVector_ = Teuchos::null; // forces rebuild of ordered lists
1833 
1834  // might be better (faster) to do this by buckets
1835  std::vector<stk::mesh::Entity> faces;
1836  getMyFaces(faces);
1837 
1838  for(std::size_t index=0;index<faces.size();++index) {
1839  stk::mesh::Entity face = faces[index];
1840  localFaceIDHash_[bulkData_->identifier(face)] = currentLocalId_;
1841  currentLocalId_++;
1842  }
1843 
1844  // copy faces into the ordered face vector
1845  orderedFaceVector_ = Teuchos::rcp(new std::vector<stk::mesh::Entity>(faces));
1846 }
1847 
1848 bool
1849 STK_Interface::isMeshCoordField(const std::string & eBlock,
1850  const std::string & fieldName,
1851  int & axis) const
1852 {
1853  std::map<std::string,std::vector<std::string> >::const_iterator blkItr = meshCoordFields_.find(eBlock);
1854  if(blkItr==meshCoordFields_.end()) {
1855  return false;
1856  }
1857 
1858  axis = 0;
1859  for(axis=0;axis<Teuchos::as<int>(blkItr->second.size());axis++) {
1860  if(blkItr->second[axis]==fieldName)
1861  break; // found axis, break
1862  }
1863 
1864  if(axis>=Teuchos::as<int>(blkItr->second.size()))
1865  return false;
1866 
1867  return true;
1868 }
1869 
1870 std::pair<Teuchos::RCP<std::vector<std::pair<std::size_t,std::size_t> > >, Teuchos::RCP<std::vector<unsigned int> > >
1872 {
1874  Teuchos::RCP<std::vector<unsigned int > > type_vec = rcp(new std::vector<unsigned int>);
1875  const std::vector<Teuchos::RCP<const PeriodicBC_MatcherBase> > & matchers = getPeriodicBCVector();
1876  const bool & useBBoxSearch = useBoundingBoxSearch();
1877  std::vector<std::vector<std::string> > matchedSides(3); // (coord,edge,face)
1878 
1879  // build up the vectors by looping over the matched pair
1880  for(std::size_t m=0;m<matchers.size();m++){
1881  unsigned int type;
1882  if(matchers[m]->getType() == "coord")
1883  type = 0;
1884  else if(matchers[m]->getType() == "edge")
1885  type = 1;
1886  else if(matchers[m]->getType() == "face")
1887  type = 2;
1888  else
1889  TEUCHOS_ASSERT(false);
1890 #ifdef PANZER_HAVE_STKSEARCH
1891 
1892  if (useBBoxSearch) {
1893  vec = matchers[m]->getMatchedPair(*this,matchedSides[type],vec);
1894  } else {
1895  vec = matchers[m]->getMatchedPair(*this,vec);
1896  }
1897 #else
1898  TEUCHOS_TEST_FOR_EXCEPTION(useBBoxSearch,std::logic_error,
1899  "panzer::STK_Interface::getPeriodicNodePairing(): Requested bounding box search, but "
1900  "did not compile with STK_SEARCH enabled.");
1901  vec = matchers[m]->getMatchedPair(*this,vec);
1902 #endif
1903  type_vec->insert(type_vec->begin(),vec->size()-type_vec->size(),type);
1904  matchedSides[type].push_back(matchers[m]->getLeftSidesetName());
1905  }
1906 
1907  return std::make_pair(vec,type_vec);
1908 }
1909 
1910 bool STK_Interface::validBlockId(const std::string & blockId) const
1911 {
1912  std::map<std::string, stk::mesh::Part*>::const_iterator blkItr = elementBlocks_.find(blockId);
1913 
1914  return blkItr!=elementBlocks_.end();
1915 }
1916 
1917 void STK_Interface::print(std::ostream & os) const
1918 {
1919  std::vector<std::string> blockNames, sidesetNames, nodesetNames;
1920 
1921  getElementBlockNames(blockNames);
1922  getSidesetNames(sidesetNames);
1923  getNodesetNames(nodesetNames);
1924 
1925  os << "STK Mesh data:\n";
1926  os << " Spatial dim = " << getDimension() << "\n";
1927  if(getDimension()==2)
1928  os << " Entity counts (Nodes, Edges, Cells) = ( "
1929  << getEntityCounts(getNodeRank()) << ", "
1930  << getEntityCounts(getEdgeRank()) << ", "
1931  << getEntityCounts(getElementRank()) << " )\n";
1932  else if(getDimension()==3)
1933  os << " Entity counts (Nodes, Edges, Faces, Cells) = ( "
1934  << getEntityCounts(getNodeRank()) << ", "
1935  << getEntityCounts(getEdgeRank()) << ", "
1936  << getEntityCounts(getSideRank()) << ", "
1937  << getEntityCounts(getElementRank()) << " )\n";
1938  else
1939  os << " Entity counts (Nodes, Cells) = ( "
1940  << getEntityCounts(getNodeRank()) << ", "
1941  << getEntityCounts(getElementRank()) << " )\n";
1942 
1943  os << " Element blocks = ";
1944  for(std::size_t i=0;i<blockNames.size();i++)
1945  os << "\"" << blockNames[i] << "\" ";
1946  os << "\n";
1947  os << " Sidesets = ";
1948  for(std::size_t i=0;i<sidesetNames.size();i++)
1949  os << "\"" << sidesetNames[i] << "\" ";
1950  os << "\n";
1951  os << " Nodesets = ";
1952  for(std::size_t i=0;i<nodesetNames.size();i++)
1953  os << "\"" << nodesetNames[i] << "\" ";
1954  os << std::endl;
1955 
1956  // print out periodic boundary conditions
1957  const std::vector<Teuchos::RCP<const PeriodicBC_MatcherBase> > & bcVector
1958  = getPeriodicBCVector();
1959  if(bcVector.size()!=0) {
1960  os << " Periodic BCs:\n";
1961  for(std::size_t i=0;i<bcVector.size();i++)
1962  os << " " << bcVector[i]->getString() << "\n";
1963  os << std::endl;
1964  }
1965 }
1966 
1967 void STK_Interface::printMetaData(std::ostream & os) const
1968 {
1969  std::vector<std::string> blockNames, sidesetNames, nodesetNames;
1970 
1971  getElementBlockNames(blockNames);
1972  getSidesetNames(sidesetNames);
1973  getNodesetNames(nodesetNames);
1974 
1975  os << "STK Meta data:\n";
1976  os << " Element blocks = ";
1977  for(std::size_t i=0;i<blockNames.size();i++)
1978  os << "\"" << blockNames[i] << "\" ";
1979  os << "\n";
1980  os << " Sidesets = ";
1981  for(std::size_t i=0;i<sidesetNames.size();i++)
1982  os << "\"" << sidesetNames[i] << "\" ";
1983  os << "\n";
1984  os << " Nodesets = ";
1985  for(std::size_t i=0;i<nodesetNames.size();i++)
1986  os << "\"" << nodesetNames[i] << "\" ";
1987  os << std::endl;
1988 
1989  // print out periodic boundary conditions
1990  const std::vector<Teuchos::RCP<const PeriodicBC_MatcherBase> > & bcVector
1991  = getPeriodicBCVector();
1992  if(bcVector.size()!=0) {
1993  os << " Periodic BCs:\n";
1994  for(std::size_t i=0;i<bcVector.size();i++)
1995  os << " " << bcVector[i]->getString() << "\n";
1996  os << std::endl;
1997  }
1998 
1999  // print all available fields in meta data
2000  os << " Fields = ";
2001  const stk::mesh::FieldVector & fv = metaData_->get_fields();
2002  for(std::size_t i=0;i<fv.size();i++)
2003  os << "\"" << fv[i]->name() << "\" ";
2004  os << std::endl;
2005 }
2006 
2008 {
2009  std::map<std::string, Teuchos::RCP<shards::CellTopology> >::const_iterator itr;
2010  itr = elementBlockCT_.find(eBlock);
2011 
2012  if(itr==elementBlockCT_.end()) {
2013  std::stringstream ss;
2014  printMetaData(ss);
2015  TEUCHOS_TEST_FOR_EXCEPTION(itr==elementBlockCT_.end(),std::logic_error,
2016  "STK_Interface::getCellTopology: No such element block \"" +eBlock +"\" available.\n\n"
2017  << "STK Meta Data follows: \n" << ss.str());
2018  }
2019 
2020  return itr->second;
2021 }
2022 
2024 {
2025  MPI_Comm newComm;
2026  const int err = MPI_Comm_dup (parallelMach, &newComm);
2027  TEUCHOS_TEST_FOR_EXCEPTION(err != MPI_SUCCESS, std::runtime_error,
2028  "panzer::STK_Interface: MPI_Comm_dup failed with error \""
2029  << Teuchos::mpiErrorCodeToString (err) << "\".");
2030 
2031  return Teuchos::rcp(new Teuchos::MpiComm<int>(Teuchos::opaqueWrapper (newComm,MPI_Comm_free)));
2032 }
2033 
2035 {
2036  TEUCHOS_TEST_FOR_EXCEPTION(true, std::runtime_error, "Rebalance not currently supported");
2037 #if 0
2038  // make sure weights have been set (a local operation)
2040 
2041  stk::mesh::Selector selector(getMetaData()->universal_part());
2042  stk::mesh::Selector owned_selector(getMetaData()->locally_owned_part());
2043 
2044  Teuchos::FancyOStream out(Teuchos::rcpFromRef(std::cout));
2045  out.setOutputToRootOnly(0);
2046  out << "Load balance before: " << stk::rebalance::check_balance(*getBulkData(), loadBalField_, getElementRank(), &selector) << std::endl;
2047 
2048  // perform reblance
2049  Teuchos::ParameterList graph;
2050  if(params.begin()!=params.end())
2051  graph.sublist(stk::rebalance::Zoltan::default_parameters_name()) = params;
2052  stk::rebalance::Zoltan zoltan_partition(*mpiComm_->getRawMpiComm(), getDimension(), graph);
2053  stk::rebalance::rebalance(*getBulkData(), owned_selector, &getCoordinatesField(), loadBalField_, zoltan_partition);
2054 
2055  out << "Load balance after: " << stk::rebalance::check_balance(*getBulkData(), loadBalField_, getElementRank(), &selector) << std::endl;
2056 
2057  currentLocalId_ = 0;
2058  orderedElementVector_ = Teuchos::null; // forces rebuild of ordered lists
2059 #endif
2060 }
2061 
2064 {
2065  TEUCHOS_ASSERT(this->isInitialized());
2066  return mpiComm_;
2067 }
2068 
2069 void STK_Interface::refineMesh(const int numberOfLevels, const bool deleteParentElements) {
2070 #ifdef PANZER_HAVE_PERCEPT
2071  TEUCHOS_TEST_FOR_EXCEPTION(numberOfLevels < 1,std::runtime_error,
2072  "ERROR: Number of levels for uniform refinement must be greater than 0");
2073  TEUCHOS_ASSERT(nonnull(refinedMesh_));
2074  TEUCHOS_ASSERT(nonnull(breakPattern_));
2075 
2076  refinedMesh_->setCoordinatesField();
2077 
2078  percept::UniformRefiner breaker(*refinedMesh_,*breakPattern_);
2079  breaker.setRemoveOldElements(deleteParentElements);
2080 
2081  for (int i=0; i < numberOfLevels; ++i)
2082  breaker.doBreak();
2083 
2084 #else
2085  TEUCHOS_TEST_FOR_EXCEPTION(true,std::logic_error,
2086  "ERROR: Uniform refinement requested. This requires the Percept package to be enabled in Trilinos!");
2087 #endif
2088 }
2089 
2090 
2091 } // end namespace panzer_stk
Teuchos::RCP< ElementDescriptor > buildElementDescriptor(stk::mesh::EntityId elmtId, std::vector< stk::mesh::EntityId > &nodes)
Teuchos::RCP< Teuchos::MpiComm< int > > getSafeCommunicator(stk::ParallelMachine parallelMach) const
void getSidesetNames(std::vector< std::string > &name) const
RCP< const T > getConst() const
std::pair< Teuchos::RCP< std::vector< std::pair< std::size_t, std::size_t > > >, Teuchos::RCP< std::vector< unsigned int > > > getPeriodicNodePairing() const
const bool & useBoundingBoxSearch() const
Teuchos::RCP< std::vector< stk::mesh::Entity > > orderedEdgeVector_
void addNodeset(const std::string &name)
Teuchos::RCP< stk::mesh::BulkData > bulkData_
void getFaceBlockNames(std::vector< std::string > &names) const
void print(std::ostream &os) const
void getMyEdges(std::vector< stk::mesh::Entity > &edges) const
Teuchos::RCP< const std::vector< stk::mesh::Entity > > getElementsOrderedByLID() const
std::vector< stk::mesh::Part * > facesPartVec_
std::map< std::pair< std::string, std::string >, SolutionFieldType * > fieldNameToSolution_
void addEntityToNodeset(stk::mesh::Entity entity, stk::mesh::Part *nodeset)
void addGlobalToExodus(const std::string &key, const int &value)
Add an int global variable to the information to be written to the Exodus output file.
void getElementBlockNames(std::vector< std::string > &names) const
void getSubcellIndices(unsigned entityRank, stk::mesh::EntityId elementId, std::vector< stk::mesh::EntityId > &subcellIds) const
void getElementsSharingNodes(const std::vector< stk::mesh::EntityId > nodeId, std::vector< stk::mesh::Entity > &elements) const
get a set of elements sharing multiple nodes
stk::mesh::Field< double > SolutionFieldType
stk::mesh::Part * getElementBlockPart(const std::string &name) const
get the block part
std::vector< stk::mesh::Part * > edgesPartVec_
bool isFaceLocal(stk::mesh::Entity face) const
std::map< std::string, double > blockWeights_
Teuchos::RCP< const std::vector< stk::mesh::Entity > > getEdgesOrderedByLID() const
basic_FancyOStream< char > FancyOStream
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
std::size_t getEntityCounts(unsigned entityRank) const
get the global counts for the entity of specified rank
void printMetaData(std::ostream &os) const
void addEntityToSideset(stk::mesh::Entity entity, stk::mesh::Part *sideset)
std::map< std::string, stk::mesh::Part * > faceBlocks_
void addSolutionField(const std::string &fieldName, const std::string &blockId)
std::map< std::string, Teuchos::RCP< shards::CellTopology > > elementBlockCT_
void addEntityToFaceBlock(stk::mesh::Entity entity, stk::mesh::Part *faceblock)
stk::mesh::EntityId getMaxEntityId(unsigned entityRank) const
get max entity ID of type entityRank
std::map< std::pair< std::string, std::string >, SolutionFieldType * > fieldNameToFaceField_
std::map< std::string, stk::mesh::Part * > sidesets_
std::vector< std::size_t > entityCounts_
bool validBlockId(const std::string &blockId) const
stk::mesh::Part * getNodeset(const std::string &name) const
void getEdgeBlockNames(std::vector< std::string > &names) const
stk::mesh::Part * getFaceBlock(const std::string &name) const
get the block part
void addInformationRecords(const std::vector< std::string > &info_records)
void getAllFaces(const std::string &faceBlockName, std::vector< stk::mesh::Entity > &faces) const
stk::mesh::Field< double > * getSolutionField(const std::string &fieldName, const std::string &blockId) const
void addEdgeBlock(const std::string &elemBlockName, const std::string &edgeBlockName, const stk::topology &topology)
const double * getNodeCoordinates(stk::mesh::EntityId nodeId) const
stk::mesh::Part * getSideset(const std::string &name) const
static const std::string nodesString
void instantiateBulkData(stk::ParallelMachine parallelMach)
std::set< std::string > informationRecords_
void getMySides(const std::string &sideName, std::vector< stk::mesh::Entity > &sides) const
stk::mesh::Field< double > * getEdgeField(const std::string &fieldName, const std::string &blockId) const
std::size_t elementLocalId(stk::mesh::Entity elmt) const
unsigned getDimension() const
get the dimension
void addElement(const Teuchos::RCP< ElementDescriptor > &ed, stk::mesh::Part *block)
std::map< std::string, std::vector< std::string > > meshDispFields_
void setupExodusFile(const std::string &filename, const bool append=false, const bool append_after_restart_time=false, const double restart_time=0.0)
Set up an output Exodus file for writing results.
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
stk::mesh::EntityRank getSideRank() const
void getAllEdges(const std::string &edgeBlockName, std::vector< stk::mesh::Entity > &edges) const
void initialize(stk::ParallelMachine parallelMach, bool setupIO=true, const bool buildRefinementSupport=false)
static const std::string coordsString
Teuchos::RCP< stk::mesh::BulkData > getBulkData() const
std::map< std::string, stk::mesh::Part * > edgeBlocks_
stk::mesh::EntityId elementGlobalId(std::size_t lid) const
std::map< std::string, stk::mesh::Part * > elementBlocks_
std::vector< stk::mesh::Part * > nodesPartVec_
static const std::string edgeBlockString
static const std::string edgesString
basic_FancyOStream & setOutputToRootOnly(const int rootRank)
std::string containingBlockId(stk::mesh::Entity elmt) const
stk::mesh::EntityRank getFaceRank() const
std::size_t edgeLocalId(stk::mesh::Entity elmt) const
void getOwnedElementsSharingNode(stk::mesh::Entity node, std::vector< stk::mesh::Entity > &elements, std::vector< int > &relIds) const
void addNode(stk::mesh::EntityId gid, const std::vector< double > &coord)
void addEntitiesToEdgeBlock(std::vector< stk::mesh::Entity > entities, stk::mesh::Part *edgeblock)
void buildSubcells()
force the mesh to build subcells: edges and faces
Teuchos::RCP< Teuchos::MpiComm< int > > mpiComm_
Teuchos::RCP< stk::mesh::MetaData > metaData_
Teuchos::RCP< stk::mesh::MetaData > getMetaData() const
Teuchos::RCP< std::vector< stk::mesh::Entity > > orderedElementVector_
bool isInitialized() const
Has initialize been called on this mesh object?
TransListIter iter
void writeToExodus(const std::string &filename, const bool append=false)
Write this mesh and associated fields to the given output file.
void getMyNodes(const std::string &sideName, const std::string &blockName, std::vector< stk::mesh::Entity > &nodes) const
bool nonnull(const boost::shared_ptr< T > &p)
void addEdgeField(const std::string &fieldName, const std::string &blockId)
void addMeshCoordFields(const std::string &blockId, const std::vector< std::string > &coordField, const std::string &dispPrefix)
stk::mesh::Entity findConnectivityById(stk::mesh::Entity src, stk::mesh::EntityRank tgt_rank, unsigned rel_id) const
bool isMeshCoordField(const std::string &eBlock, const std::string &fieldName, int &axis) const
void getAllSides(const std::string &sideName, std::vector< stk::mesh::Entity > &sides) const
void addSideset(const std::string &name, const CellTopologyData *ctData)
static const std::string faceBlockString
std::unordered_map< stk::mesh::EntityId, std::size_t > localFaceIDHash_
void addEntityToEdgeBlock(stk::mesh::Entity entity, stk::mesh::Part *edgeblock)
std::map< std::pair< std::string, std::string >, SolutionFieldType * > fieldNameToEdgeField_
stk::mesh::Part * getEdgeBlock(const std::string &name) const
get the block part
std::unordered_map< stk::mesh::EntityId, std::size_t > localEdgeIDHash_
PHX::MDField< ScalarT, panzer::Cell, panzer::BASIS > field
A field to which we&#39;ll contribute, or in which we&#39;ll store, the result of computing this integral...
void rebalance(const Teuchos::ParameterList &params)
std::map< std::string, std::vector< std::string > > meshCoordFields_
stk::mesh::EntityRank getEdgeRank() const
static const std::string facesString
void addEntitiesToFaceBlock(std::vector< stk::mesh::Entity > entities, stk::mesh::Part *faceblock)
Teuchos::RCP< const Teuchos::Comm< int > > getComm() const
get the comm associated with this mesh
void initializeFieldsInSTK(const std::map< std::pair< std::string, std::string >, SolutionFieldType * > &nameToField, bool setupIO)
const std::vector< Teuchos::RCP< const PeriodicBC_MatcherBase > > & getPeriodicBCVector() const
void refineMesh(const int numberOfLevels, const bool deleteParentElements)
stk::mesh::Field< double > * getFaceField(const std::string &fieldName, const std::string &blockId) const
std::size_t faceLocalId(stk::mesh::Entity elmt) const
void addFaceBlock(const std::string &elemBlockName, const std::string &faceBlockName, const stk::topology &topology)
Teuchos::RCP< std::vector< stk::mesh::Entity > > orderedFaceVector_
std::unordered_map< stk::mesh::EntityId, std::size_t > localIDHash_
ParameterList & sublist(const std::string &name, bool mustAlreadyExist=false, const std::string &docString="")
std::vector< stk::mesh::EntityId > maxEntityId_
void getElementsSharingNode(stk::mesh::EntityId nodeId, std::vector< stk::mesh::Entity > &elements) const
get a set of elements sharing a single node
void addFaceField(const std::string &fieldName, const std::string &blockId)
void getMyElements(std::vector< stk::mesh::Entity > &elements) const
#define TEUCHOS_ASSERT(assertion_test)
stk::mesh::EntityRank getNodeRank() const
void getMyFaces(std::vector< stk::mesh::Entity > &faces) const
void addCellField(const std::string &fieldName, const std::string &blockId)
void getNodeIdsForElement(stk::mesh::Entity element, std::vector< stk::mesh::EntityId > &nodeIds) const
get a list of node ids for nodes connected to an element
Teuchos::RCP< const std::vector< stk::mesh::Entity > > getFacesOrderedByLID() const
stk::mesh::EntityRank getElementRank() const
void addElementBlock(const std::string &name, const CellTopologyData *ctData)
stk::mesh::Field< double > * getCellField(const std::string &fieldName, const std::string &blockId) const
const VectorFieldType & getCoordinatesField() const
bool isEdgeLocal(stk::mesh::Entity edge) const
void getNeighborElements(std::vector< stk::mesh::Entity > &elements) const
void getNodesetNames(std::vector< std::string > &name) const
Teuchos::RCP< const shards::CellTopology > getCellTopology(const std::string &eBlock) const
std::map< std::pair< std::string, std::string >, SolutionFieldType * > fieldNameToCellField_
std::map< std::string, stk::mesh::Part * > nodesets_
bool is_null() const