00001
00002
00003
00004
00005
00006 #ifdef ALBANY_SEACAS
00007
00008 #include <iostream>
00009
00010 #include "Albany_IossSTKMeshStruct.hpp"
00011 #include "Teuchos_VerboseObject.hpp"
00012
00013 #include <Shards_BasicTopologies.hpp>
00014
00015 #include <stk_mesh/base/Entity.hpp>
00016 #include <stk_mesh/base/GetEntities.hpp>
00017 #include <stk_mesh/base/GetBuckets.hpp>
00018 #include <stk_mesh/base/FieldData.hpp>
00019 #include <stk_mesh/base/Selector.hpp>
00020 #include <stk_io/IossBridge.hpp>
00021 #include <Ioss_SubSystem.h>
00022
00023
00024 #include <boost/algorithm/string/predicate.hpp>
00025
00026 #include "Albany_Utils.hpp"
00027
00028 Albany::IossSTKMeshStruct::IossSTKMeshStruct(
00029 const Teuchos::RCP<Teuchos::ParameterList>& params,
00030 const Teuchos::RCP<Teuchos::ParameterList>& adaptParams_,
00031 const Teuchos::RCP<const Epetra_Comm>& comm) :
00032 GenericSTKMeshStruct(params, adaptParams_),
00033 out(Teuchos::VerboseObjectBase::getDefaultOStream()),
00034 useSerialMesh(false),
00035 periodic(params->get("Periodic BC", false)),
00036 m_hasRestartSolution(false),
00037 m_restartDataTime(-1.0),
00038 m_solutionFieldHistoryDepth(0)
00039 {
00040 params->validateParameters(*getValidDiscretizationParameters(),0);
00041
00042 mesh_data = new stk::io::MeshData();
00043
00044 usePamgen = (params->get("Method","Exodus") == "Pamgen");
00045
00046 std::vector<std::string> entity_rank_names;
00047
00048
00049 if(buildEMesh)
00050 entity_rank_names.push_back("FAMILY_TREE");
00051
00052 #ifdef ALBANY_ZOLTAN // rebalance requires Zoltan
00053
00054 if (params->get<bool>("Use Serial Mesh", false) && comm->NumProc() > 1){
00055
00056
00057 useSerialMesh = true;
00058
00059 readSerialMesh(comm, entity_rank_names);
00060
00061 }
00062 else
00063 #endif
00064 if (!usePamgen) {
00065 *out << "Albany_IOSS: Loading STKMesh from Exodus file "
00066 << params->get<std::string>("Exodus Input File Name") << std::endl;
00067
00068 stk::io::create_input_mesh("exodusII",
00069
00070 params->get<std::string>("Exodus Input File Name"),
00071 Albany::getMpiCommFromEpetraComm(*comm),
00072 *metaData, *mesh_data,
00073 entity_rank_names);
00074 }
00075 else {
00076 *out << "Albany_IOSS: Loading STKMesh from Pamgen file "
00077 << params->get<std::string>("Pamgen Input File Name") << std::endl;
00078
00079 stk::io::create_input_mesh("pamgen",
00080
00081 params->get<std::string>("Pamgen Input File Name"),
00082 Albany::getMpiCommFromEpetraComm(*comm),
00083 *metaData, *mesh_data,
00084 entity_rank_names);
00085
00086 }
00087
00088 typedef Teuchos::Array<std::string> StringArray;
00089 const StringArray additionalNodeSets = params->get("Additional Node Sets", StringArray());
00090 for (StringArray::const_iterator it = additionalNodeSets.begin(), it_end = additionalNodeSets.end(); it != it_end; ++it) {
00091 stk::mesh::Part &newNodeSet = metaData->declare_part(*it, metaData->node_rank());
00092 if (!stk::io::is_part_io_part(newNodeSet)) {
00093 stk::mesh::Field<double> * const distrFactorfield = metaData->get_field<stk::mesh::Field<double> >("distribution_factors");
00094 stk::mesh::put_field(*distrFactorfield, metaData->node_rank(), newNodeSet);
00095 stk::io::put_io_part_attribute(newNodeSet);
00096 }
00097 }
00098
00099 numDim = metaData->spatial_dimension();
00100
00101 stk::io::put_io_part_attribute(metaData->universal_part());
00102
00103
00104 const stk::mesh::PartVector & all_parts = metaData->get_parts();
00105 std::vector<std::string> ssNames;
00106 std::vector<std::string> nsNames;
00107 int numEB = 0;
00108
00109 for (stk::mesh::PartVector::const_iterator i = all_parts.begin();
00110 i != all_parts.end(); ++i) {
00111
00112 stk::mesh::Part * const part = *i ;
00113
00114 if ( part->primary_entity_rank() == metaData->element_rank()) {
00115 if (part->name()[0] != '{') {
00116
00117 partVec[numEB] = part;
00118 numEB++;
00119 }
00120 }
00121 else if ( part->primary_entity_rank() == metaData->node_rank()) {
00122 if (part->name()[0] != '{') {
00123
00124 nsPartVec[part->name()]=part;
00125 nsNames.push_back(part->name());
00126 }
00127 }
00128 else if ( part->primary_entity_rank() == metaData->side_rank()) {
00129 if (part->name()[0] != '{') {
00130
00131 ssPartVec[part->name()]=part;
00132 }
00133 }
00134 }
00135
00136 cullSubsetParts(ssNames, ssPartVec);
00137
00138 #if 0
00139
00140 std::map<std::string, stk::mesh::Part*>::iterator it;
00141
00142 for(it = ssPartVec.begin(); it != ssPartVec.end(); ++it){
00143
00144
00145
00146 print(*out, "Found \n", *it->second);
00147 }
00148
00149 #endif
00150
00151 const int cub = params->get("Cubature Degree",3);
00152 const int default_cub_rule = static_cast<int>(Intrepid::PL_GAUSS);
00153 const Intrepid::EIntrepidPLPoly cub_rule = static_cast<Intrepid::EIntrepidPLPoly>(params->get("Cubature Rule",default_cub_rule));
00154 int worksetSizeMax = params->get("Workset Size",50);
00155
00156
00157
00158 std::vector<int> el_blocks;
00159 stk::io::get_element_block_sizes(*mesh_data, el_blocks);
00160 TEUCHOS_TEST_FOR_EXCEPT(el_blocks.size() != partVec.size());
00161
00162 int ebSizeMax = *std::max_element(el_blocks.begin(), el_blocks.end());
00163 int worksetSize = this->computeWorksetSize(worksetSizeMax, ebSizeMax);
00164
00165
00166
00167 for (int eb=0; eb<numEB; eb++)
00168
00169 this->ebNameToIndex[partVec[eb]->name()] = eb;
00170
00171
00172 if (!params->get("Separate Evaluators by Element Block",false)) {
00173
00174 const CellTopologyData& ctd = *metaData->get_cell_topology(*partVec[0]).getCellTopologyData();
00175 this->meshSpecs[0] = Teuchos::rcp(new Albany::MeshSpecsStruct(ctd, numDim, cub,
00176 nsNames, ssNames, worksetSize, partVec[0]->name(),
00177 this->ebNameToIndex, this->interleavedOrdering,cub_rule));
00178
00179 }
00180 else {
00181
00182 *out << "MULTIPLE Elem Block in Ioss: DO worksetSize[eb] max?? " << std::endl;
00183 this->allElementBlocksHaveSamePhysics=false;
00184 this->meshSpecs.resize(numEB);
00185 for (int eb=0; eb<numEB; eb++) {
00186 const CellTopologyData& ctd = *metaData->get_cell_topology(*partVec[eb]).getCellTopologyData();
00187 this->meshSpecs[eb] = Teuchos::rcp(new Albany::MeshSpecsStruct(ctd, numDim, cub,
00188 nsNames, ssNames, worksetSize, partVec[eb]->name(),
00189 this->ebNameToIndex, this->interleavedOrdering,cub_rule));
00190 std::cout << "el_block_size[" << eb << "] = " << el_blocks[eb] << " name " << partVec[eb]->name() << std::endl;
00191 }
00192
00193 }
00194
00195 {
00196 const Ioss::Region *inputRegion = mesh_data->m_input_region;
00197 m_solutionFieldHistoryDepth = inputRegion->get_property("state_count").get_int();
00198 }
00199 }
00200
00201 Albany::IossSTKMeshStruct::~IossSTKMeshStruct()
00202 {
00203 delete mesh_data;
00204 }
00205
00206 void
00207 Albany::IossSTKMeshStruct::readSerialMesh(const Teuchos::RCP<const Epetra_Comm>& comm,
00208 std::vector<std::string>& entity_rank_names){
00209
00210 #ifdef ALBANY_ZOLTAN // rebalance needs Zoltan
00211
00212 MPI_Group group_world;
00213 MPI_Group peZero;
00214 MPI_Comm peZeroComm;
00215
00216
00217
00218 MPI_Comm theComm = Albany::getMpiCommFromEpetraComm(*comm);
00219
00220 int process_rank[1];
00221
00222 process_rank[0] = 0;
00223 int my_rank = comm->MyPID();
00224
00225
00226 MPI_Comm_group(theComm, &group_world);
00227
00228 MPI_Group_incl(group_world, 1, process_rank, &peZero);
00229
00230 MPI_Comm_create(theComm, peZero, &peZeroComm);
00231
00232
00233
00234 if(my_rank == 0){
00235
00236 *out << "Albany_IOSS: Loading serial STKMesh from Exodus file "
00237 << params->get<std::string>("Exodus Input File Name") << std::endl;
00238
00239 }
00240
00241
00242
00243
00244
00245
00246 stk::io::create_input_mesh("exodusII",
00247
00248 params->get<std::string>("Exodus Input File Name"),
00249 peZeroComm,
00250 *metaData, *mesh_data,
00251 entity_rank_names);
00252
00253
00254
00255 #endif
00256
00257 }
00258
00259 void
00260 Albany::IossSTKMeshStruct::setFieldAndBulkData(
00261 const Teuchos::RCP<const Epetra_Comm>& comm,
00262 const Teuchos::RCP<Teuchos::ParameterList>& params,
00263 const unsigned int neq_,
00264 const AbstractFieldContainer::FieldContainerRequirements& req,
00265 const Teuchos::RCP<Albany::StateInfoStruct>& sis,
00266 const unsigned int worksetSize)
00267 {
00268 this->SetupFieldData(comm, neq_, req, sis, worksetSize);
00269
00270 *out << "IOSS-STK: number of node sets = " << nsPartVec.size() << std::endl;
00271 *out << "IOSS-STK: number of side sets = " << ssPartVec.size() << std::endl;
00272
00273 metaData->commit();
00274
00275
00276 int index = params->get("Restart Index",-1);
00277 double res_time = params->get<double>("Restart Time",-1.0);
00278 Ioss::Region *region = mesh_data->m_input_region;
00279
00280
00281
00282
00283
00284
00285
00286
00287 #ifdef ALBANY_ZOLTAN // rebalance needs Zoltan
00288
00289 if(useSerialMesh){
00290
00291 bulkData->modification_begin();
00292
00293 if(comm->MyPID() == 0){
00294
00295 stk::io::process_mesh_bulk_data(region, *bulkData);
00296
00297
00298 if (index >= 0) {
00299 *out << "Restart Index set, reading solution index : " << index << std::endl;
00300 stk::io::input_mesh_fields(region, *bulkData, index);
00301 m_restartDataTime = region->get_state_time(index);
00302 m_hasRestartSolution = true;
00303 }
00304 else if (res_time >= 0) {
00305 *out << "Restart solution time set, reading solution time : " << res_time << std::endl;
00306 stk::io::input_mesh_fields(region, *bulkData, res_time);
00307 m_restartDataTime = res_time;
00308 m_hasRestartSolution = true;
00309 }
00310 else {
00311
00312 *out << "Neither restart index or time are set. Not reading solution data from exodus file"<< std::endl;
00313
00314 }
00315 }
00316
00317 bulkData->modification_end();
00318
00319 }
00320
00321 else
00322 #endif
00323
00324
00325
00326
00327
00328
00329
00330 {
00331
00332 stk::io::populate_bulk_data(*bulkData, *mesh_data);
00333
00334 if (!usePamgen) {
00335
00336
00337 if (index >= 0) {
00338 *out << "Restart Index set, reading solution index : " << index << std::endl;
00339 stk::io::process_input_request(*mesh_data, *bulkData, index);
00340 m_restartDataTime = region->get_state_time(index);
00341 m_hasRestartSolution = true;
00342 }
00343 else if (res_time >= 0) {
00344 *out << "Restart solution time set, reading solution time : " << res_time << std::endl;
00345 stk::io::process_input_request(*mesh_data, *bulkData, res_time);
00346 m_restartDataTime = res_time;
00347 m_hasRestartSolution = true;
00348 }
00349 else {
00350 *out << "Restart Index not set. Not reading solution from exodus ("
00351 << index << ")"<< std::endl;
00352
00353 }
00354 }
00355
00356 bulkData->modification_end();
00357
00358 }
00359
00360 if(m_hasRestartSolution){
00361
00362 Teuchos::Array<std::string> default_field;
00363 default_field.push_back("solution");
00364 Teuchos::Array<std::string> restart_fields =
00365 params->get<Teuchos::Array<std::string> >("Restart Fields", default_field);
00366
00367
00368
00369
00370
00371 const Ioss::ElementBlockContainer& elem_blocks = region->get_element_blocks();
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382 for (std::size_t i=0; i<sis->size(); i++) {
00383 Albany::StateStruct& st = *((*sis)[i]);
00384
00385 if(elem_blocks[0]->field_exists(st.name))
00386
00387 for(std::size_t j = 0; j < restart_fields.size(); j++)
00388
00389 if(boost::iequals(st.name, restart_fields[j])){
00390
00391 *out << "Restarting from field \"" << st.name << "\" found in exodus file." << std::endl;
00392 st.restartDataAvailable = true;
00393 break;
00394
00395 }
00396 }
00397 }
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440 uniformRefineMesh(comm);
00441
00442
00443 rebalanceInitialMesh(comm);
00444
00445
00446 computeAddlConnectivity();
00447
00448 }
00449
00450 double
00451 Albany::IossSTKMeshStruct::getSolutionFieldHistoryStamp(int step) const
00452 {
00453 TEUCHOS_ASSERT(step >= 0 && step < m_solutionFieldHistoryDepth);
00454
00455 const int index = step + 1;
00456 const Ioss::Region * const inputRegion = mesh_data->m_input_region;
00457 return inputRegion->get_state_time(index);
00458 }
00459
00460 void
00461 Albany::IossSTKMeshStruct::loadSolutionFieldHistory(int step)
00462 {
00463 TEUCHOS_ASSERT(step >= 0 && step < m_solutionFieldHistoryDepth);
00464
00465 const int index = step + 1;
00466 stk::io::process_input_request(*mesh_data, *bulkData, index);
00467 }
00468
00469 Teuchos::RCP<const Teuchos::ParameterList>
00470 Albany::IossSTKMeshStruct::getValidDiscretizationParameters() const
00471 {
00472 Teuchos::RCP<Teuchos::ParameterList> validPL =
00473 this->getValidGenericSTKParameters("Valid IOSS_DiscParams");
00474 validPL->set<bool>("Periodic BC", false, "Flag to indicate periodic a mesh");
00475 validPL->set<std::string>("Exodus Input File Name", "", "File Name For Exodus Mesh Input");
00476 validPL->set<std::string>("Pamgen Input File Name", "", "File Name For Pamgen Mesh Input");
00477 validPL->set<int>("Restart Index", 1, "Exodus time index to read for inital guess/condition.");
00478 validPL->set<double>("Restart Time", 1.0, "Exodus solution time to read for inital guess/condition.");
00479
00480 Teuchos::Array<std::string> emptyStringArray;
00481 validPL->set<Teuchos::Array<std::string> >("Additional Node Sets", emptyStringArray, "Declare additional node sets not present in the input file");
00482
00483 return validPL;
00484 }
00485 #endif