Panzer  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Panzer_STK_CustomMeshFactory.cpp
Go to the documentation of this file.
1 // @HEADER
2 // *****************************************************************************
3 // Panzer: A partial differential equation assembly
4 // engine for strongly coupled complex multiphysics systems
5 //
6 // Copyright 2011 NTESS and the Panzer contributors.
7 // SPDX-License-Identifier: BSD-3-Clause
8 // *****************************************************************************
9 // @HEADER
10 
12 #include <Teuchos_TimeMonitor.hpp>
13 #include <PanzerAdaptersSTK_config.hpp>
14 
15 using Teuchos::RCP;
16 using Teuchos::rcp;
17 
18 namespace panzer_stk {
19 
21  {
23  }
24 
27  {
28  }
29 
32  CustomMeshFactory::buildMesh(stk::ParallelMachine parallelMach) const
33  {
34  PANZER_FUNC_TIME_MONITOR("panzer::CustomMeshFactory::buildMesh()");
35 
36  // build all meta data
37  RCP<STK_Interface> mesh = buildUncommitedMesh(parallelMach);
38 
39  // commit meta data; allocate field variables
40  mesh->initialize(parallelMach);
41 
42  // build bulk data
43  completeMeshConstruction(*mesh,parallelMach);
44 
45  return mesh;
46  }
47 
49  CustomMeshFactory::buildUncommitedMesh(stk::ParallelMachine parallelMach) const
50  {
51  PANZER_FUNC_TIME_MONITOR("panzer::CustomMeshFactory::buildUncomittedMesh()");
52 
53  RCP<STK_Interface> mesh = rcp(new STK_Interface(3));
54 
55  machRank_ = stk::parallel_machine_rank(parallelMach);
56  machSize_ = stk::parallel_machine_size(parallelMach);
57 
58  // add blocks and side sets (global geometry setup)
59  buildMetaData(*mesh);
60 
61  mesh->addPeriodicBCs(periodicBCVec_);
62  mesh->setBoundingBoxSearchFlag(useBBoxSearch_);
63 
64  return mesh;
65  }
66 
67  void
69  stk::ParallelMachine parallelMach) const
70  {
71  PANZER_FUNC_TIME_MONITOR("panzer::CustomMeshFactory::completeMeshConstruction()");
72 
73  if (not mesh.isInitialized())
74  mesh.initialize(parallelMach);
75 
76  // add node and element information
77  buildElements(mesh);
78 
79  // build edges and faces; fyi: addSides(mesh) builds only edges
80  mesh.buildSubcells();
81  mesh.buildLocalElementIDs();
82 
83 
84 
85  // now that edges are built, side and node sets can be added
86  addSideSets(mesh);
87 
88  // set solution fields
90 
91  // calls Stk_MeshFactory::rebalance
92  //this->rebalance(mesh);
93  }
94 
96  void
98  {
100 
101  setMyParamList(paramList);
102 
103  Dimension_ = paramList->get<int>("Dimension");
104 
105  NumBlocks_ = paramList->get<int>("NumBlocks");
106 
107  NumNodesPerProc_ = paramList->get<int>("NumNodesPerProc");
108  Nodes_ = paramList->get<int*>("Nodes");
109 
110  Coords_ = paramList->get<double*>("Coords");
111 
112  NumElementsPerProc_ = paramList->get<int>("NumElementsPerProc");
113 
114  BlockIDs_ = paramList->get<int*>("BlockIDs");
115  Element2Nodes_ = paramList->get<int*>("Element2Nodes");
116 
117  OffsetToGlobalElementIDs_ = paramList->get<int>("OffsetToGlobalElementIDs");
118 
119  // solution fields from tramonto
120  ChargeDensity_ = paramList->get<double*>("ChargeDensity");
121  ElectricPotential_ = paramList->get<double*>("ElectricPotential");
122 
123  // read in periodic boundary conditions
124  parsePeriodicBCList(Teuchos::rcpFromRef(paramList->sublist("Periodic BCs")),periodicBCVec_,useBBoxSearch_);
125  }
126 
130  {
131  static RCP<Teuchos::ParameterList> defaultParams;
132 
133  // fill with default values
134  if(defaultParams == Teuchos::null) {
135  defaultParams = rcp(new Teuchos::ParameterList);
136 
137  defaultParams->set<int>("Dimension",3);
138 
139  defaultParams->set<int>("NumBlocks",0);
140 
141  defaultParams->set<int>("NumNodesPerProc",0);
142  defaultParams->set<int*>("Nodes",NULL);
143 
144  defaultParams->set<double*>("Coords",NULL);
145 
146  defaultParams->set<int>("NumElementsPerProc",0);
147 
148  defaultParams->set<int*>("BlockIDs",NULL);
149  defaultParams->set<int*>("Element2Nodes",NULL);
150 
151  defaultParams->set<int>("OffsetToGlobalElementIDs", 0);
152 
153  defaultParams->set<double*>("ChargeDensity",NULL);
154  defaultParams->set<double*>("ElectricPotential",NULL);
155 
156  Teuchos::ParameterList &bcs = defaultParams->sublist("Periodic BCs");
157  bcs.set<int>("Count",0); // no default periodic boundary conditions
158  }
159 
160  return defaultParams;
161  }
162 
163  void
165  {
166  // get valid parameters
168 
169  // set that parameter list
170  setParameterList(validParams);
171  }
172 
173  void
175  {
176  typedef shards::Hexahedron<8> HexTopo;
177  const CellTopologyData *ctd = shards::getCellTopologyData<HexTopo>();
178  const CellTopologyData *side_ctd = shards::CellTopology(ctd).getBaseCellTopologyData(2,0);
179 
180  for (int blk=0;blk<NumBlocks_;++blk) {
181  std::stringstream block_id;
182  block_id << "eblock-" << blk;
183 
184  // add element blocks
185  mesh.addElementBlock(block_id.str(),ctd);
186 
187  mesh.addSolutionField("CHARGE_DENSITY",block_id.str());
188  mesh.addSolutionField("ELECTRIC_POTENTIAL",block_id.str());
189  }
190 
191  mesh.addSideset("left", side_ctd);
192  mesh.addSideset("right", side_ctd);
193  mesh.addSideset("top", side_ctd);
194  mesh.addSideset("bottom",side_ctd);
195  mesh.addSideset("front", side_ctd);
196  mesh.addSideset("back", side_ctd);
197 
198  mesh.addSideset("wall", side_ctd);
199  }
200 
201  void
203  {
204  mesh.beginModification();
205 
206  const int dim = mesh.getDimension();
207 
208  // build the nodes
209  std::vector<double> coords(dim,0.0);
210  for (int i=0;i<NumNodesPerProc_;++i) {
211  for (int k=0;k<dim;++k)
212  coords[k] = Coords_[i*dim+k];
213  mesh.addNode(Nodes_[i], coords);
214  }
215 
216  // build the elements
217  std::vector<std::string> block_ids;
218  mesh.getElementBlockNames(block_ids);
219 
220  for (int i=0;i<NumElementsPerProc_;++i) {
221 
222  // get block by its name
223  std::stringstream block_id;
224  block_id << "eblock-" << BlockIDs_[i];
225 
226  stk::mesh::Part *block = mesh.getElementBlockPart(block_id.str());
227 
228  // construct element and its nodal connectivity
229  stk::mesh::EntityId elt = i + OffsetToGlobalElementIDs_;
230  std::vector<stk::mesh::EntityId> elt2nodes(8);
231 
232  for (int k=0;k<8;++k)
233  elt2nodes[k] = Element2Nodes_[i*8+k];
234 
235  RCP<ElementDescriptor> ed = rcp(new ElementDescriptor(elt,elt2nodes));
236  mesh.addElement(ed,block);
237  }
238 
239  mesh.endModification();
240  }
241 
242  void
244  {
245  mesh.beginModification();
246  stk::mesh::BulkData& bulkData = *mesh.getBulkData();
247  const stk::mesh::EntityRank sideRank = mesh.getSideRank();
248 
249  // get all part vectors
250  stk::mesh::Part *box[6];
251  box[0] = mesh.getSideset("front");
252  box[1] = mesh.getSideset("right");
253  box[2] = mesh.getSideset("back");
254  box[3] = mesh.getSideset("left");
255  box[4] = mesh.getSideset("bottom");
256  box[5] = mesh.getSideset("top");
257 
258  stk::mesh::Part *wall = mesh.getSideset("wall");
259 
260  std::vector<stk::mesh::Entity> elements;
261  mesh.getMyElements(elements);
262 
263  // loop over elements adding sides to sidesets
264  for (std::vector<stk::mesh::Entity>::const_iterator
265  itr=elements.begin();itr!=elements.end();++itr) {
266  stk::mesh::Entity element = (*itr);
267  const size_t numSides = bulkData.num_connectivity(element, sideRank);
268  stk::mesh::Entity const* relations = bulkData.begin(element, sideRank);
269 
270  // loop over side id checking element neighbors
271  for (std::size_t i=0;i<numSides;++i) {
272  stk::mesh::Entity side = relations[i];
273  const size_t numNeighbors = bulkData.num_elements(side);
274  stk::mesh::Entity const* neighbors = bulkData.begin_elements(side);
275 
276  if (numNeighbors == 1) {
277  if (mesh.entityOwnerRank(side) == machRank_)
278  mesh.addEntityToSideset(side, box[i]);
279  }
280  else if (numNeighbors == 2) {
281  std::string neig_block_id_0 = mesh.containingBlockId(neighbors[0]);
282  std::string neig_block_id_1 = mesh.containingBlockId(neighbors[1]);
283  if (neig_block_id_0 != neig_block_id_1 && mesh.entityOwnerRank(side) == machRank_)
284  mesh.addEntityToSideset(side, wall);
285  }
286  else {
287  // runtime exception
288  }
289  }
290  }
291 
292  mesh.endModification();
293  }
294 
295  void
297  {
298  constexpr std::size_t dim_1 = 8;
299 
300  for (int blk=0;blk<NumBlocks_;++blk) {
301 
302  std::stringstream block_id;
303  block_id << "eblock-" << blk;
304 
305  // elements in this processor for this block
306  std::vector<stk::mesh::Entity> elements;
307  mesh.getMyElements(block_id.str(), elements);
308 
309  // size of elements in the current block
310  const auto n_elements = elements.size();
311 
312  // build local element index
313  std::vector<std::size_t> local_ids;
314 
315  Kokkos::View<double**, Kokkos::HostSpace> charge_density_by_local_ids("charge_density_by_local_ids", n_elements, dim_1);
316  Kokkos::View<double**, Kokkos::HostSpace> electric_potential_by_local_ids("electric_potential_by_local_ids", n_elements, dim_1);
317 
318  for (const auto& elem : elements){
319  local_ids.push_back(mesh.elementLocalId(elem));
320  const auto q = mesh.elementGlobalId(elem) - OffsetToGlobalElementIDs_;
321 
322  for (std::size_t k=0;k<dim_1;++k) {
323  const auto loc = q*dim_1 + k;
324  charge_density_by_local_ids(q,k) = ChargeDensity_[loc];
325  electric_potential_by_local_ids(q,k) = ElectricPotential_[loc];
326  }
327  }
328 
329  // write out to stk mesh
330  mesh.setSolutionFieldData("CHARGE_DENSITY",
331  block_id.str(),
332  local_ids,
333  charge_density_by_local_ids, 1.0);
334 
335  mesh.setSolutionFieldData("ELECTRIC_POTENTIAL",
336  block_id.str(),
337  local_ids,
338  electric_potential_by_local_ids, 1.0);
339  }
340  }
341 } // end panzer_stk
unsigned entityOwnerRank(stk::mesh::Entity entity) const
void setSolutionFieldData(const std::string &fieldName, const std::string &blockId, const std::vector< std::size_t > &localElementIds, const ArrayT &solutionValues, double scaleValue=1.0)
void setParameterList(const Teuchos::RCP< Teuchos::ParameterList > &paramList)
From ParameterListAcceptor.
static void parsePeriodicBCList(const Teuchos::RCP< Teuchos::ParameterList > &pl, std::vector< Teuchos::RCP< const PeriodicBC_MatcherBase > > &periodicBC, bool &useBBoxSearch)
void getElementBlockNames(std::vector< std::string > &names) const
T & get(const std::string &name, T def_value)
stk::mesh::Part * getElementBlockPart(const std::string &name) const
get the block part
void addEntityToSideset(stk::mesh::Entity entity, stk::mesh::Part *sideset)
void addSolutionField(const std::string &fieldName, const std::string &blockId)
ParameterList & set(std::string const &name, T &&value, std::string const &docString="", RCP< const ParameterEntryValidator > const &validator=null)
stk::mesh::Part * getSideset(const std::string &name) const
Teuchos::RCP< const Teuchos::ParameterList > getValidParameters() const
From ParameterListAcceptor.
Teuchos::RCP< STK_Interface > buildMesh(stk::ParallelMachine parallelMach) const
Build the mesh object.
std::size_t elementLocalId(stk::mesh::Entity elmt) const
void addSideSets(STK_Interface &mesh) const
unsigned getDimension() const
get the dimension
void addElement(const Teuchos::RCP< ElementDescriptor > &ed, stk::mesh::Part *block)
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
stk::mesh::EntityRank getSideRank() const
void initialize(stk::ParallelMachine parallelMach, bool setupIO=true, const bool buildRefinementSupport=false)
virtual void completeMeshConstruction(STK_Interface &mesh, stk::ParallelMachine parallelMach) const
Teuchos::RCP< stk::mesh::BulkData > getBulkData() const
stk::mesh::EntityId elementGlobalId(std::size_t lid) const
void setMyParamList(const RCP< ParameterList > &paramList)
void validateParametersAndSetDefaults(ParameterList const &validParamList, int const depth=1000)
std::string containingBlockId(stk::mesh::Entity elmt) const
void addNode(stk::mesh::EntityId gid, const std::vector< double > &coord)
void buildSubcells()
force the mesh to build subcells: edges and faces
bool isInitialized() const
Has initialize been called on this mesh object?
void fillSolutionFieldData(STK_Interface &mesh) const
void buildElements(STK_Interface &mesh) const
void addSideset(const std::string &name, const CellTopologyData *ctData)
std::vector< Teuchos::RCP< const PeriodicBC_MatcherBase > > periodicBCVec_
ParameterList & sublist(const std::string &name, bool mustAlreadyExist=false, const std::string &docString="")
void getMyElements(std::vector< stk::mesh::Entity > &elements) const
virtual Teuchos::RCP< STK_Interface > buildUncommitedMesh(stk::ParallelMachine parallelMach) const
void buildMetaData(STK_Interface &mesh) const
void addElementBlock(const std::string &name, const CellTopologyData *ctData)