Panzer Version of the Day
Loading...
Searching...
No Matches
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
15using Teuchos::RCP;
16using Teuchos::rcp;
17
18namespace panzer_stk {
19
24
29
31 Teuchos::RCP<STK_Interface>
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
48 Teuchos::RCP<STK_Interface>
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();
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
97 CustomMeshFactory::setParameterList(const Teuchos::RCP<Teuchos::ParameterList> &paramList)
98 {
99 paramList->validateParametersAndSetDefaults(*getValidParameters(),0);
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
128 Teuchos::RCP<const Teuchos::ParameterList>
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
167 RCP<Teuchos::ParameterList> validParams = rcp(new Teuchos::ParameterList(*getValidParameters()));
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
void buildMetaData(STK_Interface &mesh) const
void addSideSets(STK_Interface &mesh) const
void fillSolutionFieldData(STK_Interface &mesh) const
void setParameterList(const Teuchos::RCP< Teuchos::ParameterList > &paramList)
From ParameterListAcceptor.
virtual void completeMeshConstruction(STK_Interface &mesh, stk::ParallelMachine parallelMach) const
Teuchos::RCP< const Teuchos::ParameterList > getValidParameters() const
From ParameterListAcceptor.
virtual Teuchos::RCP< STK_Interface > buildUncommitedMesh(stk::ParallelMachine parallelMach) const
void buildElements(STK_Interface &mesh) const
Teuchos::RCP< STK_Interface > buildMesh(stk::ParallelMachine parallelMach) const
Build the mesh object.
void initialize(stk::ParallelMachine parallelMach, bool setupIO=true, const bool buildRefinementSupport=false)
stk::mesh::Part * getElementBlockPart(const std::string &name) const
get the block part
stk::mesh::EntityId elementGlobalId(std::size_t lid) const
bool isInitialized() const
Has initialize been called on this mesh object?
std::string containingBlockId(stk::mesh::Entity elmt) const
void buildSubcells()
force the mesh to build subcells: edges and faces
void addElement(const Teuchos::RCP< ElementDescriptor > &ed, stk::mesh::Part *block)
void addNode(stk::mesh::EntityId gid, const std::vector< double > &coord)
void setSolutionFieldData(const std::string &fieldName, const std::string &blockId, const std::vector< std::size_t > &localElementIds, const ArrayT &solutionValues, double scaleValue=1.0)
std::size_t elementLocalId(stk::mesh::Entity elmt) const
void getElementBlockNames(std::vector< std::string > &names) const
void addSideset(const std::string &name, const CellTopologyData *ctData)
unsigned getDimension() const
get the dimension
void endModification(const bool find_and_set_shared_nodes_in_stk=true)
unsigned entityOwnerRank(stk::mesh::Entity entity) const
void addSolutionField(const std::string &fieldName, const std::string &blockId)
void addEntityToSideset(stk::mesh::Entity entity, stk::mesh::Part *sideset)
stk::mesh::EntityRank getSideRank() const
void getMyElements(std::vector< stk::mesh::Entity > &elements) const
void addElementBlock(const std::string &name, const CellTopologyData *ctData)
Teuchos::RCP< stk::mesh::BulkData > getBulkData() const
stk::mesh::Part * getSideset(const std::string &name) const
static void parsePeriodicBCList(const Teuchos::RCP< Teuchos::ParameterList > &pl, std::vector< Teuchos::RCP< const PeriodicBC_MatcherBase > > &periodicBC, bool &useBBoxSearch)
std::vector< Teuchos::RCP< const PeriodicBC_MatcherBase > > periodicBCVec_