Panzer  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Panzer_STK_PamgenReaderFactory.cpp
Go to the documentation of this file.
1 // @HEADER
2 // ***********************************************************************
3 //
4 // Panzer: A partial differential equation assembly
5 // engine for strongly coupled complex multiphysics systems
6 // Copyright (2011) Sandia Corporation
7 //
8 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
9 // the U.S. Government retains certain rights in this software.
10 //
11 // Redistribution and use in source and binary forms, with or without
12 // modification, are permitted provided that the following conditions are
13 // met:
14 //
15 // 1. Redistributions of source code must retain the above copyright
16 // notice, this list of conditions and the following disclaimer.
17 //
18 // 2. Redistributions in binary form must reproduce the above copyright
19 // notice, this list of conditions and the following disclaimer in the
20 // documentation and/or other materials provided with the distribution.
21 //
22 // 3. Neither the name of the Corporation nor the names of the
23 // contributors may be used to endorse or promote products derived from
24 // this software without specific prior written permission.
25 //
26 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
27 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
30 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
31 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
32 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
33 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
34 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
35 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
36 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37 //
38 // Questions? Contact Roger P. Pawlowski (rppawlo@sandia.gov) and
39 // Eric C. Cyr (eccyr@sandia.gov)
40 // ***********************************************************************
41 // @HEADER
42 
43 
44 #include <Teuchos_TimeMonitor.hpp>
45 #include <PanzerAdaptersSTK_config.hpp>
46 
48 #include "Panzer_STK_Interface.hpp"
49 
50 #ifdef PANZER_HAVE_IOSS
51 
52 #include <Ionit_Initializer.h>
53 #include <Ioss_ElementBlock.h>
54 #include <Ioss_Region.h>
55 #include <stk_io/StkMeshIoBroker.hpp>
56 #include <stk_io/IossBridge.hpp>
57 
58 #include "Teuchos_StandardParameterEntryValidators.hpp"
59 
60 namespace panzer_stk {
61 
62 STK_PamgenReaderFactory::STK_PamgenReaderFactory()
63  : fileName_(""), restartIndex_(0)
64 { }
65 
66 STK_PamgenReaderFactory::STK_PamgenReaderFactory(const std::string & fileName,int restartIndex)
67  : fileName_(fileName), restartIndex_(restartIndex)
68 { }
69 
70 Teuchos::RCP<STK_Interface> STK_PamgenReaderFactory::buildMesh(stk::ParallelMachine parallelMach) const
71 {
72  PANZER_FUNC_TIME_MONITOR("panzer::STK_PamgenReaderFactory::buildMesh()");
73 
74  using Teuchos::RCP;
75  using Teuchos::rcp;
76 
77  RCP<STK_Interface> mesh = buildUncommitedMesh(parallelMach);
78 
79  // in here you would add your fields...but it is better to use
80  // the two step construction
81 
82  // this calls commit on meta data
83  mesh->initialize(parallelMach,false);
84 
85  completeMeshConstruction(*mesh,parallelMach);
86 
87  return mesh;
88 }
89 
94 Teuchos::RCP<STK_Interface> STK_PamgenReaderFactory::buildUncommitedMesh(stk::ParallelMachine parallelMach) const
95 {
96  PANZER_FUNC_TIME_MONITOR("panzer::STK_PamgenReaderFactory::buildUncomittedMesh()");
97 
98  using Teuchos::RCP;
99  using Teuchos::rcp;
100 
101  // read in meta data
102  stk::io::StkMeshIoBroker* meshData = new stk::io::StkMeshIoBroker(parallelMach);
103  meshData->property_add(Ioss::Property("LOWER_CASE_VARIABLE_NAMES", false));
104  meshData->add_mesh_database(fileName_, "pamgen", stk::io::READ_MESH);
105  meshData->create_input_mesh();
106  RCP<stk::mesh::MetaData> metaData = meshData->meta_data_rcp();
107 
108  RCP<STK_Interface> mesh = rcp(new STK_Interface(metaData));
109  mesh->initializeFromMetaData();
110  mesh->instantiateBulkData(parallelMach);
111  meshData->set_bulk_data(mesh->getBulkData());
112 
113  // read in other transient fields, these will be useful later when
114  // trying to read other fields for use in solve
115  meshData->add_all_mesh_fields_as_input_fields();
116 
117  // store mesh data pointer for later use in initializing
118  // bulk data
119  mesh->getMetaData()->declare_attribute_with_delete(meshData);
120 
121  // build element blocks
122  registerElementBlocks(*mesh,*meshData);
123  registerSidesets(*mesh);
124  registerNodesets(*mesh);
125 
126  mesh->addPeriodicBCs(periodicBCVec_);
127 
128  return mesh;
129 }
130 
131 void STK_PamgenReaderFactory::completeMeshConstruction(STK_Interface & mesh,stk::ParallelMachine parallelMach) const
132 {
133  PANZER_FUNC_TIME_MONITOR("panzer::STK_PamgenReaderFactory::completeMeshConstruction()");
134 
135  using Teuchos::RCP;
136  using Teuchos::rcp;
137 
138  if(not mesh.isInitialized())
139  mesh.initialize(parallelMach);
140 
141  // grab mesh data pointer to build the bulk data
142  stk::mesh::MetaData & metaData = *mesh.getMetaData();
143  stk::io::StkMeshIoBroker * meshData =
144  const_cast<stk::io::StkMeshIoBroker *>(metaData.get_attribute<stk::io::StkMeshIoBroker>());
145  // if const_cast is wrong ... why does it feel so right?
146  // I believe this is safe since we are basically hiding this object under the covers
147  // until the mesh construction can be completed...below I cleanup the object myself.
148  TEUCHOS_ASSERT(metaData.remove_attribute(meshData));
149  // remove the MeshData attribute
150 
151  // build mesh bulk data
152  meshData->populate_bulk_data();
153 
154  // put in a negative index and (like python) the restart will be from the back
155  // (-1 is the last time step)
156  int restartIndex = restartIndex_;
157  if(restartIndex<0) {
158  std::pair<int,double> lastTimeStep = meshData->get_input_io_region()->get_max_time();
159  restartIndex = 1+restartIndex+lastTimeStep.first;
160  }
161 
162  // populate mesh fields with specific index
163  meshData->read_defined_input_fields(restartIndex);
164 
165  mesh.buildSubcells();
166  mesh.buildLocalElementIDs();
167 
168  if(restartIndex>0) // process_input_request is a no-op if restartIndex<=0 ... thus there would be no inital time
169  mesh.setInitialStateTime(meshData->get_input_io_region()->get_state_time(restartIndex));
170  else
171  mesh.setInitialStateTime(0.0); // no initial time to speak, might as well use 0.0
172 
173  // clean up mesh data object
174  delete meshData;
175 
176  // calls Stk_MeshFactory::rebalance
177  this->rebalance(mesh);
178 }
179 
181 void STK_PamgenReaderFactory::setParameterList(const Teuchos::RCP<Teuchos::ParameterList> & paramList)
182 {
183  TEUCHOS_TEST_FOR_EXCEPTION_PURE_MSG(!paramList->isParameter("File Name")
184 && !paramList->isParameter("Text Input"),
186  "Error, either parameter {name=\"File Name\","
187  "or the parameter {name=\"Text Input\","
188  "type=\"string\""
189  "\nis required in parameter (sub)list \""<< paramList->name() <<"\"."
190  "\n\nThe parsed parameter parameter list is: \n" << paramList->currentParametersString()
191  );
192 
193  paramList->validateParametersAndSetDefaults(*getValidParameters(),0);
194 
195  setMyParamList(paramList);
196 
197  fileName_ = paramList->get<std::string>("File Name");
198 
199  restartIndex_ = paramList->get<int>("Restart Index");
200 
201  // read in periodic boundary conditions
202  parsePeriodicBCList(Teuchos::rcpFromRef(paramList->sublist("Periodic BCs")),periodicBCVec_);
203 }
204 
206 Teuchos::RCP<const Teuchos::ParameterList> STK_PamgenReaderFactory::getValidParameters() const
207 {
208  static Teuchos::RCP<Teuchos::ParameterList> validParams;
209 
210  if(validParams==Teuchos::null) {
211  validParams = Teuchos::rcp(new Teuchos::ParameterList);
212  validParams->set<std::string>("File Name","<file name not set>","Name of pamgen file to be read",
214 
215  validParams->set<int>("Restart Index",-1,"Index of solution to read in",
216  Teuchos::rcp(new Teuchos::AnyNumberParameterEntryValidator(Teuchos::AnyNumberParameterEntryValidator::PREFER_INT,Teuchos::AnyNumberParameterEntryValidator::AcceptedTypes(true))));
217 
218  Teuchos::ParameterList & bcs = validParams->sublist("Periodic BCs");
219  bcs.set<int>("Count",0); // no default periodic boundary conditions
220  }
221 
222  return validParams.getConst();
223 }
224 
225 void STK_PamgenReaderFactory::registerElementBlocks(STK_Interface & mesh,stk::io::StkMeshIoBroker & meshData) const
226 {
227  using Teuchos::RCP;
228 
229  RCP<stk::mesh::MetaData> femMetaData = mesh.getMetaData();
230 
231  // here we use the Ioss interface because they don't add
232  // "bonus" element blocks and its easier to determine
233  // "real" element blocks versus STK-only blocks
234  const Ioss::ElementBlockContainer & elem_blocks = meshData.get_input_io_region()->get_element_blocks();
235  for(Ioss::ElementBlockContainer::const_iterator itr=elem_blocks.begin();itr!=elem_blocks.end();++itr) {
236  Ioss::GroupingEntity * entity = *itr;
237  const std::string & name = entity->name();
238 
239  const stk::mesh::Part * part = femMetaData->get_part(name);
240  const CellTopologyData * ct = femMetaData->get_cell_topology(*part).getCellTopologyData();
241 
242  TEUCHOS_ASSERT(ct!=0);
243  mesh.addElementBlock(part->name(),ct);
244  }
245 }
246 
247 template <typename SetType>
248 void buildSetNames(const SetType & setData,std::vector<std::string> & names)
249 {
250  // pull out all names for this set
251  for(typename SetType::const_iterator itr=setData.begin();itr!=setData.end();++itr) {
252  Ioss::GroupingEntity * entity = *itr;
253  names.push_back(entity->name());
254  }
255 }
256 
257 void STK_PamgenReaderFactory::registerSidesets(STK_Interface & mesh) const
258 {
259  using Teuchos::RCP;
260 
261  RCP<stk::mesh::MetaData> metaData = mesh.getMetaData();
262  const stk::mesh::PartVector & parts = metaData->get_parts();
263 
264  stk::mesh::PartVector::const_iterator partItr;
265  for(partItr=parts.begin();partItr!=parts.end();++partItr) {
266  const stk::mesh::Part * part = *partItr;
267  const stk::mesh::PartVector & subsets = part->subsets();
268  // const CellTopologyData * ct = stk::mesh::get_cell_topology(*part).getCellTopologyData();
269  const CellTopologyData * ct = metaData->get_cell_topology(*part).getCellTopologyData();
270 
271  // if a side part ==> this is a sideset: now storage is recursive
272  // on part contains all sub parts with consistent topology
273  if(part->primary_entity_rank()==mesh.getSideRank() && ct==0 && subsets.size()>0) {
274  TEUCHOS_TEST_FOR_EXCEPTION(subsets.size()!=1,std::runtime_error,
275  "STK_PamgenReaderFactory::registerSidesets error - part \"" << part->name() <<
276  "\" has more than one subset");
277 
278  // grab cell topology and name of subset part
279  const stk::mesh::Part * ss_part = subsets[0];
280  // const CellTopologyData * ss_ct = stk::mesh::get_cell_topology(*ss_part).getCellTopologyData();
281  const CellTopologyData * ss_ct = metaData->get_cell_topology(*ss_part).getCellTopologyData();
282 
283  // only add subset parts that have no topology
284  if(ss_ct!=0)
285  mesh.addSideset(part->name(),ss_ct);
286  }
287  }
288 }
289 
290 void STK_PamgenReaderFactory::registerNodesets(STK_Interface & mesh) const
291 {
292  using Teuchos::RCP;
293 
294  RCP<stk::mesh::MetaData> metaData = mesh.getMetaData();
295  const stk::mesh::PartVector & parts = metaData->get_parts();
296 
297  stk::mesh::PartVector::const_iterator partItr;
298  for(partItr=parts.begin();partItr!=parts.end();++partItr) {
299  const stk::mesh::Part * part = *partItr;
300  const CellTopologyData * ct = metaData->get_cell_topology(*part).getCellTopologyData();
301 
302  // if a side part ==> this is a sideset: now storage is recursive
303  // on part contains all sub parts with consistent topology
304  if(part->primary_entity_rank()==mesh.getNodeRank() && ct==0) {
305 
306  // only add subset parts that have no topology
307  if(part->name()!=STK_Interface::nodesString)
308  mesh.addNodeset(part->name());
309  }
310  }
311 }
312 
313 }
314 
315 #endif
RCP< const T > getConst() const
const std::string & name() const
std::string currentParametersString() const
T & get(const std::string &name, T def_value)
ParameterList & set(std::string const &name, T const &value, std::string const &docString="", RCP< const ParameterEntryValidator > const &validator=null)
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
static const std::string nodesString
bool isParameter(const std::string &name) const
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
void validateParametersAndSetDefaults(ParameterList const &validParamList, int const depth=1000)
ParameterList & sublist(const std::string &name, bool mustAlreadyExist=false, const std::string &docString="")
#define TEUCHOS_ASSERT(assertion_test)
#define TEUCHOS_TEST_FOR_EXCEPTION_PURE_MSG(throw_exception_test, Exception, msg)