Nalu
Nalu: a generalized unstructured massively parallel low Mach flow code designed to support a variety of energy applications of interest (most notably Wind ECP) built on the Sierra Toolkit and Trilinos solver Tpetra/Epetra stack. The open source BSD, clause 3 license model has been chosen for the code base. See LICENSE for more information. http://NaluCFD.org
FromMesh.h
Go to the documentation of this file.
1 /*------------------------------------------------------------------------*/
2 /* Copyright 2014 Sandia Corporation. */
3 /* This software is released under the license detailed */
4 /* in the file, LICENSE, which is located in the top-level Nalu */
5 /* directory structure */
6 /*------------------------------------------------------------------------*/
7 
8 
9 #ifndef FromMesh_h
10 #define FromMesh_h
11 
12 #include <string>
13 #include <vector>
14 #include <utility>
15 
16 #include <Realm.h>
17 #include <stk_util/parallel/Parallel.hpp>
18 #include <stk_util/parallel/ParallelReduce.hpp>
19 
20 #include <stk_mesh/base/Entity.hpp>
21 #include <stk_mesh/base/BulkData.hpp>
22 #include <stk_mesh/base/MetaData.hpp>
23 #include <stk_mesh/base/FieldParallel.hpp>
24 
25 #include <stk_search/IdentProc.hpp>
26 #include <stk_search/BoundingBox.hpp>
27 
28 #include <FieldTypeDef.h>
29 
30 // stk
31 namespace stk {
32 namespace mesh {
33 class Part;
34 typedef std::vector<Part*> PartVector;
35 class MetaData;
36 class BulkData;
37 }
38 }
39 
40 namespace sierra{
41 namespace nalu{
42 
43 class FromMesh {
44 public :
45  typedef stk::mesh:: Entity Entity;
46  typedef std::vector<Entity> EntityVec;
47  typedef stk::mesh:: EntityKey EntityKey;
48  typedef std::set <EntityKey> EntityKeySet;
49  typedef stk::search::IdentProc<EntityKey, unsigned> EntityProc;
50  typedef std::vector<EntityProc> EntityProcVec;
51 
52  typedef stk::search::Point<double> Point;
53  typedef stk::search::Box<double> Box;
54  typedef std::pair<Box,EntityProc> BoundingBox;
55 
56  enum {Dimension = 3};
57 
58  typedef std::vector<std::pair<std::string, std::string> > PairNames;
59 
60 
61  std::vector< const stk::mesh::FieldBase *>
62  get_fields(const stk::mesh::MetaData &fromMetaData, const PairNames &VarPairName) {
63  // will want to check that all is well with field registration
64  bool allFieldsAreFine = true;
65  std::vector< const stk::mesh::FieldBase *> fromFieldVec;
66  // provide field names
67  for(PairNames::const_iterator i=VarPairName.begin(); i!=VarPairName.end(); ++i) {
68  const std::string &fieldName = i->first;
69  const stk::mesh::FieldBase *fromfield = stk::mesh::get_field_by_name(fieldName,fromMetaData);
70  if ( NULL == fromfield ) {
71  allFieldsAreFine = false;
72  NaluEnv::self().naluOutputP0()
73  << "Xfer::FromMesh:Error field: " << fieldName
74  << " has not been registered anywhere within the FromRealm: " << fromRealm_.name() << std::endl;
75  }
76  else {
77  // always push back; check for errors below
78  fromFieldVec.push_back(fromfield);
79 
80  // check that the field is defined on **all** parts
81  stk::mesh::Selector fieldSelector = stk::mesh::selectField(*fromfield);
82  for ( size_t k = 0; k < fromPartVec_.size(); ++k ) {
83 
84  stk::mesh::BucketVector const &partBuckets
85  = fromBulkData_.get_buckets(stk::topology::NODE_RANK, stk::mesh::Selector(*fromPartVec_[k]));
86 
87  bool fieldIsFine = true;
88  for ( stk::mesh::BucketVector::const_iterator ib = partBuckets.begin();
89  ib != partBuckets.end() ; ++ib ) {
90  stk::mesh::Bucket & b = **ib ;
91  fieldIsFine &= fieldSelector(b);
92  }
93 
94  // local check to make sure that the field is somewhere (delay the throw)
95  if ( !fieldIsFine ) {
96  NaluEnv::self().naluOutputP0()
97  << "Xfer::FromMesh:Error field: " << fromfield->name()
98  << " is not registered on part: " << fromPartVec_[k]->name() << std::endl;
99  allFieldsAreFine = false;
100  }
101  }
102  }
103  }
104 
105  // final error check; only return when all is well
106  if ( allFieldsAreFine ) {
107  return fromFieldVec;
108  }
109  else {
110  throw std::runtime_error("Xfer::FromMesh:Error field registration on desired parts of the mesh is not complete");
111  }
112  }
113 
115  const stk::mesh::MetaData &fromMetaData,
116  stk::mesh::BulkData &fromBulkData,
117  Realm &fromRealm,
118  const std::string &coordinates_name,
119  const PairNames &VarPairName,
120  const stk::mesh::PartVector &fromPartVec,
121  const stk::ParallelMachine comm)
122  : fromMetaData_ (fromMetaData),
123  fromBulkData_ (fromBulkData),
124  fromRealm_ (fromRealm),
125  fromcoordinates_(fromMetaData.get_field<VectorFieldType>(stk::topology::NODE_RANK,coordinates_name)),
126  fromPartVec_ (fromPartVec),
127  fromFieldVec_ (get_fields(fromMetaData, VarPairName)),
128  comm_ (comm),
129  mesh_modified_ (false),
130  ghosting_ (0),
131  ghosting_map_ ()
132  {
133  // nothing to do
134  }
135 
136 
138 
140  bool operator()(const BoundingBox &a, const BoundingBox & b) const
141  {
142  return a.second.id() < b.second.id();
143  }
144  };
145 
146 
147  // Needed for STK Transfer
148  stk::ParallelMachine comm() const {return comm_;}
149 
150  void bounding_boxes (std::vector<BoundingBox> &v) const
151  {
152  const unsigned nDim = fromMetaData_.spatial_dimension();
153 
154  Point min_corner, max_corner;
155 
156  stk::mesh::Selector s_locally_owned_union = fromMetaData_.locally_owned_part()
157  & stk::mesh::selectUnion(fromPartVec_);
158 
159  // determine entity rank for the part served up; should be homogeneous
160  stk::mesh::EntityRank partEntityRank = fromPartVec_[0]->primary_entity_rank();
161 
162  stk::mesh::BucketVector const& entity_buckets = fromBulkData_.get_buckets( partEntityRank, s_locally_owned_union );
163  for ( stk::mesh::BucketVector::const_iterator ib = entity_buckets.begin();
164  ib != entity_buckets.end() ; ++ib ) {
165  stk::mesh::Bucket & b = **ib ;
166 
167  const stk::mesh::Bucket::size_type length = b.size();
168 
169  for ( stk::mesh::Bucket::size_type k = 0 ; k < length ; ++k ) {
170 
171  // get entity
172  stk::mesh::Entity theEntity = b[k];
173 
174  // initialize max and min
175  for (unsigned j = 0; j < nDim; ++j ) {
176  min_corner[j] = +1.0e16;
177  max_corner[j] = -1.0e16;
178  }
179 
180  stk::mesh::Entity const * entity_node_rels = fromBulkData_.begin_nodes(theEntity);
181  int num_entity_nodes = fromBulkData_.num_nodes(theEntity);
182  for ( int ni = 0; ni < num_entity_nodes; ++ni ) {
183  stk::mesh::Entity node = entity_node_rels[ni];
184 
185  double * coords = stk::mesh::field_data(*fromcoordinates_, node);
186  for ( unsigned j=0; j < nDim; ++j ) {
187  min_corner[j] = std::min(min_corner[j], coords[j]);
188  max_corner[j] = std::max(max_corner[j], coords[j]);
189  }
190  }
191 
192  // setup ident
193  FromMesh::EntityProc theIdent(fromBulkData_.entity_key(theEntity), fromBulkData_.parallel_rank());
194 
195  v.push_back(BoundingBox(Box(min_corner,max_corner),theIdent));
196  }
197  }
198  std::sort(v.begin(), v.end(), BoundingBoxCompare());
199  }
200 
201  void update_ghosting(const EntityProcVec &entity_keys)
202  {
203  ghosting_map_.resize(entity_keys.size());
204  for (size_t i=0; i<entity_keys.size(); ++i) {
205  //convert from EntityProc based on EntityKey to EntityProc based on raw Entity.
206  const EntityProc& key_proc = entity_keys[i];
207  const stk::mesh::EntityKey key = key_proc.id();
208  const unsigned proc = key_proc.proc();
209  const stk::mesh::Entity e = entity(key);
210  const stk::mesh::EntityProc ep( e, proc);
211  ghosting_map_[i] = ep;
212  }
213 
214  unsigned s = !ghosting_map_.empty();
215  stk::all_reduce( comm_, stk::ReduceSum<1>(&s));
216 
217  if (s) {
218  std::sort(ghosting_map_.begin(), ghosting_map_.end());
219  stk::mesh::EntityProcVec::iterator del = std::unique(ghosting_map_.begin(), ghosting_map_.end());
220  ghosting_map_.resize(std::distance(ghosting_map_.begin(), del));
221 
222  std::string theGhostName = "nalu_transfer_ghosting";
223  for (unsigned i=0; i!=fromFieldVec_.size(); ++i) theGhostName += "_"+fromFieldVec_[i]->name();
224  ghosting_ = &fromBulkData_.create_ghosting( theGhostName );
225  fromBulkData_.change_ghosting( *ghosting_, ghosting_map_);
226  mesh_modified_ = true;
227  }
228  }
229 
231  {
232  if (ghosting_) {
233  std::vector<const stk::mesh::FieldBase *> fields(fromFieldVec_.begin(), fromFieldVec_.end());
234  if (mesh_modified_) {
235  // Copy coordinates to the newly ghosted nodes
236  mesh_modified_ = false;
237  fields.push_back(fromcoordinates_);
238  }
239  stk::mesh::communicate_field_data( *ghosting_ , fields);
240  stk::mesh::copy_owned_to_shared ( fromBulkData_, fields);
241  }
242  }
243 
244  Entity entity(const EntityKey k) const
245  { return fromBulkData_.get_entity(k); }
246 
247  const stk::mesh::MetaData &fromMetaData_;
248  stk::mesh::BulkData &fromBulkData_;
252  const std::vector< const stk::mesh::FieldBase *> fromFieldVec_;
253  const stk::ParallelMachine comm_;
254 
256  stk::mesh::Ghosting *ghosting_;
257  stk::mesh::EntityProcVec ghosting_map_;
258 };
259 
260 
261 } // namespace nalu
262 } // namespace Sierra
263 
264 #endif
std::vector< Part * > PartVector
Definition: Algorithm.h:16
stk::mesh::BulkData & fromBulkData_
Definition: FromMesh.h:248
const std::vector< const stk::mesh::FieldBase * > fromFieldVec_
Definition: FromMesh.h:252
Definition: ABLForcingAlgorithm.C:26
std::pair< Box, EntityProc > BoundingBox
Definition: FromMesh.h:54
stk::search::Box< double > Box
Definition: FromMesh.h:53
void update_ghosting(const EntityProcVec &entity_keys)
Definition: FromMesh.h:201
bool mesh_modified_
Definition: FromMesh.h:255
stk::mesh::EntityProcVec ghosting_map_
Definition: FromMesh.h:257
const VectorFieldType * fromcoordinates_
Definition: FromMesh.h:250
const stk::mesh::MetaData & fromMetaData_
Definition: FromMesh.h:247
const stk::ParallelMachine comm_
Definition: FromMesh.h:253
Entity entity(const EntityKey k) const
Definition: FromMesh.h:244
Definition: Algorithm.h:14
stk::mesh::Entity Entity
Definition: FromMesh.h:45
stk::mesh::Field< double, stk::mesh::Cartesian > VectorFieldType
Definition: FieldTypeDef.h:24
std::vector< EntityProc > EntityProcVec
Definition: FromMesh.h:50
std::vector< std::pair< std::string, std::string > > PairNames
Definition: FromMesh.h:58
stk::search::Point< double > Point
Definition: FromMesh.h:52
std::vector< const stk::mesh::FieldBase * > get_fields(const stk::mesh::MetaData &fromMetaData, const PairNames &VarPairName)
Definition: FromMesh.h:62
stk::mesh::Ghosting * ghosting_
Definition: FromMesh.h:256
const stk::mesh::PartVector fromPartVec_
Definition: FromMesh.h:251
void bounding_boxes(std::vector< BoundingBox > &v) const
Definition: FromMesh.h:150
stk::mesh::EntityKey EntityKey
Definition: FromMesh.h:47
stk::ParallelMachine comm() const
Definition: FromMesh.h:148
FromMesh(const stk::mesh::MetaData &fromMetaData, stk::mesh::BulkData &fromBulkData, Realm &fromRealm, const std::string &coordinates_name, const PairNames &VarPairName, const stk::mesh::PartVector &fromPartVec, const stk::ParallelMachine comm)
Definition: FromMesh.h:114
Realm & fromRealm_
Definition: FromMesh.h:249
std::vector< Bucket * > BucketVector
Definition: PromotedPartHelper.h:21
std::vector< Entity > EntityVec
Definition: FromMesh.h:46
stk::search::IdentProc< EntityKey, unsigned > EntityProc
Definition: FromMesh.h:49
Definition: FromMesh.h:43
std::set< EntityKey > EntityKeySet
Definition: FromMesh.h:48
void update_values()
Definition: FromMesh.h:230
bool operator()(const BoundingBox &a, const BoundingBox &b) const
Definition: FromMesh.h:140
Definition: Realm.h:82
stk::search::Box< double > Box
Definition: OversetManager.h:33
~FromMesh()
Definition: FromMesh.h:137