|
Sierra Toolkit
Version of the Day
|
00001 /*------------------------------------------------------------------------*/ 00002 /* Copyright 2010, 2011 Sandia Corporation. */ 00003 /* Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive */ 00004 /* license for use of this work by or on behalf of the U.S. Government. */ 00005 /* Export of this program may require a license from the */ 00006 /* United States Government. */ 00007 /*------------------------------------------------------------------------*/ 00008 00009 #include <iostream> 00010 #include <assert.h> 00011 00012 #include <stk_util/parallel/Parallel.hpp> 00013 #include <init/Ionit_Initializer.h> 00014 #include <Ioss_SubSystem.h> 00015 00016 #include <stk_mesh/base/Field.hpp> 00017 #include <stk_mesh/base/FieldData.hpp> 00018 #include <stk_mesh/base/BulkData.hpp> 00019 00020 #include <stk_mesh/fem/FEMMetaData.hpp> 00021 #include <stk_mesh/fem/TopologyDimensions.hpp> 00022 00023 #include <stk_io/IossBridge.hpp> 00024 00041 namespace stk_example_io { 00042 00046 void process_nodeblocks (Ioss::Region ®ion, stk_classic::mesh::MetaData &meta); 00047 00053 void process_elementblocks (Ioss::Region ®ion, stk_classic::mesh::MetaData &meta); 00054 00061 void process_nodesets (Ioss::Region ®ion, stk_classic::mesh::MetaData &meta); 00062 00076 void process_sidesets (Ioss::Region ®ion, stk_classic::mesh::MetaData &meta); 00077 00084 void process_nodeblocks (Ioss::Region ®ion, stk_classic::mesh::BulkData &bulk); 00085 00097 void process_elementblocks (Ioss::Region ®ion, stk_classic::mesh::BulkData &bulk); 00098 00105 void process_nodesets (Ioss::Region ®ion, stk_classic::mesh::BulkData &bulk); 00106 00112 void process_sidesets (Ioss::Region ®ion, stk_classic::mesh::BulkData &bulk); 00113 00120 void process_input_request (Ioss::Region ®ion, stk_classic::mesh::BulkData &bulk, int step); 00121 00134 void process_output_request(Ioss::Region ®ion, stk_classic::mesh::BulkData &bulk, int step); 00135 00162 void io_example( stk_classic::ParallelMachine comm, 00163 const std::string& in_filename, 00164 const std::string& out_filename, 00165 const std::string& decomp_method) 00166 { 00167 // Initialize IO system. Registers all element types and storage 00168 // types and the exodusII default database type. 00169 Ioss::Init::Initializer init_db; 00170 00171 std::cout << "========================================================================\n" 00172 << " Copy input mesh to output mesh. \n" 00173 << "========================================================================\n"; 00174 00175 std::string dbtype("exodusII"); 00176 Ioss::PropertyManager properties; 00177 if (!decomp_method.empty()) { 00178 properties.add(Ioss::Property("DECOMPOSITION_METHOD", Ioss::Utils::uppercase(decomp_method))); 00179 } 00180 Ioss::DatabaseIO *dbi = Ioss::IOFactory::create(dbtype, in_filename, Ioss::READ_MODEL, 00181 comm, properties); 00182 if (dbi == NULL || !dbi->ok()) { 00183 std::cerr << "ERROR: Could not open database '" << in_filename 00184 << "' of type '" << dbtype << "'\n"; 00185 std::exit(EXIT_FAILURE); 00186 } 00187 00188 std::cout << "Reading input file: " << in_filename << "\n"; 00189 // NOTE: 'in_region' owns 'dbi' pointer at this time... 00190 Ioss::Region in_region(dbi, "input_model"); 00191 00192 // SUBSETTING PARSING/PREPROCESSING... 00193 // Just an example of how application could control whether an 00194 // entity is subsetted or not... 00195 00196 00197 #if 0 00198 // Example command line in current code corresponding to behavior below: 00199 std::cout << "\nWhen processing file multi-block.g for use case 2, the blocks below will be omitted:\n"; 00200 std::cout << "\tOMIT BLOCK Cblock Eblock I1 I2\n\n"; 00201 Ioss::ElementBlock *eb = in_region.get_element_block("cblock"); 00202 if (eb != NULL) 00203 eb->property_add(Ioss::Property(std::string("omitted"), 1)); 00204 00205 eb = in_region.get_element_block("eblock"); 00206 if (eb != NULL) 00207 eb->property_add(Ioss::Property(std::string("omitted"), 1)); 00208 00209 eb = in_region.get_element_block("i1"); 00210 if (eb != NULL) 00211 eb->property_add(Ioss::Property(std::string("omitted"), 1)); 00212 00213 eb = in_region.get_element_block("i2"); 00214 if (eb != NULL) 00215 eb->property_add(Ioss::Property(std::string("omitted"), 1)); 00216 #endif 00217 00218 #if 0 00219 // Example for subsetting -- omit "odd" blocks 00220 if (entity->type() == Ioss::ELEMENTBLOCK) { 00221 int id = entity->get_property("id").get_int(); 00222 if (id % 2) { 00223 entity->property_add(Ioss::Property(std::string("omitted"), 1)); 00224 std::cout << "Skipping " << entity->type_string() << ": " << entity->name() << "\n"; 00225 } 00226 } 00227 #endif 00228 00229 //---------------------------------- 00230 // Process Entity Types. Subsetting is possible. 00231 00232 static size_t spatial_dimension = in_region.get_property("spatial_dimension").get_int(); 00233 00234 stk_classic::mesh::fem::FEMMetaData fem_meta_data( spatial_dimension ); 00235 stk_classic::mesh::MetaData &meta_data = fem_meta_data.get_meta_data(fem_meta_data); 00236 process_elementblocks(in_region, meta_data); 00237 process_nodeblocks(in_region, meta_data); 00238 process_sidesets(in_region, meta_data); 00239 process_nodesets(in_region, meta_data); 00240 00241 //---------------------------------- 00242 // Done populating meta data, commit and create bulk data 00243 meta_data.commit(); 00244 00245 //---------------------------------- 00246 // Process Bulkdata for all Entity Types. Subsetting is possible. 00247 stk_classic::mesh::BulkData bulk_data(meta_data, comm); 00248 00249 bulk_data.modification_begin(); 00250 process_elementblocks(in_region, bulk_data); 00251 process_nodeblocks(in_region, bulk_data); 00252 process_sidesets(in_region, bulk_data); 00253 process_nodesets(in_region, bulk_data); 00254 bulk_data.modification_end(); 00255 00256 //---------------------------------- 00257 // OUTPUT...Create the output "mesh" portion 00258 00259 std::cout << "Creating output file: " << out_filename << "\n"; 00260 Ioss::DatabaseIO *dbo = Ioss::IOFactory::create(dbtype, out_filename, 00261 Ioss::WRITE_RESULTS, 00262 comm); 00263 if (dbo == NULL || !dbo->ok()) { 00264 std::cerr << "ERROR: Could not open results database '" << out_filename 00265 << "' of type '" << dbtype << "'\n"; 00266 std::exit(EXIT_FAILURE); 00267 } 00268 00269 #if 0 00270 { 00271 // Code to test the remove_io_part_attribute functionality. 00272 // Hook this up to a command line option at some point to test nightly... 00273 const stk_classic::mesh::PartVector & all_parts = meta_data.get_parts(); 00274 for ( stk_classic::mesh::PartVector::const_iterator ip = all_parts.begin(); ip != all_parts.end(); ++ip ) { 00275 stk_classic::mesh::Part * const part = *ip; 00276 const stk_classic::mesh::EntityRank part_rank = part->primary_entity_rank(); 00277 00278 if (stk_classic::io::is_part_io_part(*part) && part_rank == 2) { 00279 std::cout << "Removing part attribute from " << part->name() << "\n"; 00280 stk_classic::io::remove_io_part_attribute(*part); 00281 } 00282 } 00283 } 00284 #endif 00285 00286 // NOTE: 'out_region' owns 'dbo' pointer at this time... 00287 Ioss::Region out_region(dbo, "results_output"); 00288 00289 stk_classic::io::define_output_db(out_region, bulk_data, &in_region); 00290 stk_classic::io::write_output_db(out_region, bulk_data); 00291 00292 // ------------------------------------------------------------------------ 00307 out_region.begin_mode(Ioss::STATE_DEFINE_TRANSIENT); 00308 00309 // Special processing for nodeblock (all nodes in model)... 00310 stk_classic::io::ioss_add_fields(meta_data.universal_part(), stk_classic::mesh::fem::FEMMetaData::NODE_RANK, 00311 out_region.get_node_blocks()[0], 00312 Ioss::Field::TRANSIENT); 00313 00314 const stk_classic::mesh::PartVector & all_parts = meta_data.get_parts(); 00315 for ( stk_classic::mesh::PartVector::const_iterator 00316 ip = all_parts.begin(); ip != all_parts.end(); ++ip ) { 00317 00318 stk_classic::mesh::Part * const part = *ip; 00319 00320 const stk_classic::mesh::EntityRank part_rank = part->primary_entity_rank(); 00321 00322 // Check whether this part should be output to results database. 00323 if (stk_classic::io::is_part_io_part(*part)) { 00324 // Get Ioss::GroupingEntity corresponding to this part... 00325 Ioss::GroupingEntity *entity = out_region.get_entity(part->name()); 00326 if (entity != NULL) { 00327 if (entity->type() == Ioss::SIDESET) { 00328 Ioss::SideSet *sset = dynamic_cast<Ioss::SideSet*>(entity); 00329 assert(sset != NULL); 00330 int block_count = sset->block_count(); 00331 for (int i=0; i < block_count; i++) { 00332 Ioss::SideBlock *fb = sset->get_block(i); 00333 stk_classic::io::ioss_add_fields(*part, part_rank, 00334 fb, Ioss::Field::TRANSIENT); 00335 } 00336 } else { 00337 stk_classic::io::ioss_add_fields(*part, part_rank, 00338 entity, Ioss::Field::TRANSIENT); 00339 } 00340 } else { 00343 } 00344 } 00345 } 00346 out_region.end_mode(Ioss::STATE_DEFINE_TRANSIENT); 00347 // ------------------------------------------------------------------------ 00348 00349 // Read and Write transient fields... 00350 out_region.begin_mode(Ioss::STATE_TRANSIENT); 00351 int timestep_count = in_region.get_property("state_count").get_int(); 00352 for (int step = 1; step <= timestep_count; step++) { 00353 double time = in_region.get_state_time(step); 00354 00355 // Read data from the io input mesh database into stk_classic::mesh fields... 00356 process_input_request(in_region, bulk_data, step); 00357 00358 // execute() 00359 00360 // Write data from the stk_classic::mesh fields out to the output database.a 00361 int out_step = out_region.add_state(time); 00362 process_output_request(out_region, bulk_data, out_step); 00363 } 00364 out_region.end_mode(Ioss::STATE_TRANSIENT); 00365 } 00366 00367 // ======================================================================== 00368 void process_nodeblocks(Ioss::Region ®ion, stk_classic::mesh::MetaData &meta) 00369 { 00370 const Ioss::NodeBlockContainer& node_blocks = region.get_node_blocks(); 00371 assert(node_blocks.size() == 1); 00372 00373 Ioss::NodeBlock *nb = node_blocks[0]; 00374 00375 assert(nb->field_exists("mesh_model_coordinates")); 00376 Ioss::Field coordinates = nb->get_field("mesh_model_coordinates"); 00377 int spatial_dim = coordinates.transformed_storage()->component_count(); 00378 00379 stk_classic::mesh::Field<double,stk_classic::mesh::Cartesian> & coord_field = 00380 meta.declare_field<stk_classic::mesh::Field<double,stk_classic::mesh::Cartesian> >("coordinates"); 00381 00382 stk_classic::mesh::put_field( coord_field, stk_classic::mesh::fem::FEMMetaData::NODE_RANK, meta.universal_part(), 00383 spatial_dim); 00384 00389 stk_classic::io::define_io_fields(nb, Ioss::Field::TRANSIENT, meta.universal_part(),stk_classic::mesh::fem::FEMMetaData::NODE_RANK); 00390 } 00391 00392 // ======================================================================== 00393 void process_elementblocks(Ioss::Region ®ion, stk_classic::mesh::MetaData &meta) 00394 { 00395 const stk_classic::mesh::fem::FEMMetaData &fem_meta_data = stk_classic::mesh::fem::FEMMetaData::get(meta); 00396 const stk_classic::mesh::EntityRank element_rank = fem_meta_data.element_rank(); 00397 00398 const Ioss::ElementBlockContainer& elem_blocks = region.get_element_blocks(); 00399 stk_classic::io::default_part_processing(elem_blocks, meta, element_rank); 00400 00401 // Parts were created above, now handle element block specific 00402 // information (topology, attributes, ...); 00403 for(Ioss::ElementBlockContainer::const_iterator it = elem_blocks.begin(); 00404 it != elem_blocks.end(); ++it) { 00405 Ioss::ElementBlock *entity = *it; 00406 00407 if (stk_classic::io::include_entity(entity)) { 00408 stk_classic::mesh::Part* const part = meta.get_part(entity->name()); 00409 assert(part != NULL); 00410 00411 const stk_classic::mesh::EntityRank part_rank = part->primary_entity_rank(); 00412 00413 // Element Block attributes (if any)... 00418 stk_classic::io::define_io_fields(entity, Ioss::Field::ATTRIBUTE, 00419 *part, 00420 part_rank); 00421 00426 stk_classic::io::define_io_fields(entity, Ioss::Field::TRANSIENT, 00427 *part, 00428 part_rank); 00429 00430 const CellTopologyData* cell_topo = fem_meta_data.get_cell_topology(*part).getCellTopologyData(); 00431 std::string cell_topo_name = "UNKNOWN"; 00432 if (cell_topo != NULL) 00433 cell_topo_name = cell_topo->name; 00434 } 00435 } 00436 } 00437 00438 // ======================================================================== 00439 void process_nodesets(Ioss::Region ®ion, stk_classic::mesh::MetaData &meta) 00440 { 00441 const Ioss::NodeSetContainer& node_sets = region.get_nodesets(); 00442 stk_classic::io::default_part_processing(node_sets, meta, stk_classic::mesh::fem::FEMMetaData::NODE_RANK); 00443 00448 stk_classic::mesh::Field<double> & distribution_factors_field = 00449 meta.declare_field<stk_classic::mesh::Field<double> >("distribution_factors"); 00450 00456 for(Ioss::NodeSetContainer::const_iterator it = node_sets.begin(); 00457 it != node_sets.end(); ++it) { 00458 Ioss::NodeSet *entity = *it; 00459 00460 if (stk_classic::io::include_entity(entity)) { 00461 stk_classic::mesh::Part* const part = meta.get_part(entity->name()); 00462 assert(part != NULL); 00463 assert(entity->field_exists("distribution_factors")); 00464 00465 stk_classic::mesh::put_field(distribution_factors_field, stk_classic::mesh::fem::FEMMetaData::NODE_RANK, *part); 00466 00471 stk_classic::io::define_io_fields(entity, Ioss::Field::TRANSIENT, 00472 *part, 00473 part->primary_entity_rank() ) ; 00474 } 00475 } 00476 } 00477 00478 // ======================================================================== 00479 void process_surface_entity(Ioss::SideSet *sset, stk_classic::mesh::MetaData &meta, 00480 stk_classic::mesh::EntityRank sset_rank) 00481 { 00482 assert(sset->type() == Ioss::SIDESET); 00483 Ioss::SideSet *fs = dynamic_cast<Ioss::SideSet *>(sset); 00484 assert(fs != NULL); 00485 const Ioss::SideBlockContainer& blocks = fs->get_side_blocks(); 00486 stk_classic::io::default_part_processing(blocks, meta, sset_rank); 00487 00488 stk_classic::mesh::Part* const fs_part = meta.get_part(sset->name()); 00489 assert(fs_part != NULL); 00490 00491 stk_classic::mesh::Field<double, stk_classic::mesh::ElementNode> *distribution_factors_field = NULL; 00492 bool surface_df_defined = false; // Has the surface df field been defined yet? 00493 00494 00495 int block_count = sset->block_count(); 00496 for (int i=0; i < block_count; i++) { 00497 Ioss::SideBlock *side_block = sset->get_block(i); 00498 if (stk_classic::io::include_entity(side_block)) { 00499 stk_classic::mesh::Part * const side_block_part = meta.get_part(side_block->name()); 00500 assert(side_block_part != NULL); 00501 meta.declare_part_subset(*fs_part, *side_block_part); 00502 00503 const stk_classic::mesh::EntityRank part_rank = side_block_part->primary_entity_rank(); 00504 00505 if (side_block->field_exists("distribution_factors")) { 00506 if (!surface_df_defined) { 00507 std::string field_name = sset->name() + "_distribution_factors"; 00508 distribution_factors_field = 00509 &meta.declare_field<stk_classic::mesh::Field<double, stk_classic::mesh::ElementNode> >(field_name); 00510 stk_classic::io::set_distribution_factor_field(*fs_part, *distribution_factors_field); 00511 surface_df_defined = true; 00512 } 00513 stk_classic::io::set_distribution_factor_field(*side_block_part, *distribution_factors_field); 00514 int side_node_count = side_block->topology()->number_nodes(); 00515 stk_classic::mesh::put_field(*distribution_factors_field, 00516 part_rank, 00517 *side_block_part, side_node_count); 00518 } 00519 00524 stk_classic::io::define_io_fields(side_block, Ioss::Field::TRANSIENT, 00525 *side_block_part, 00526 part_rank); 00527 } 00528 } 00529 } 00530 00531 // ======================================================================== 00532 void process_sidesets(Ioss::Region ®ion, stk_classic::mesh::MetaData &meta) 00533 { 00534 stk_classic::mesh::fem::FEMMetaData &fem = stk_classic::mesh::fem::FEMMetaData::get(meta); 00535 const stk_classic::mesh::EntityRank side_rank = fem.side_rank(); 00536 00537 const Ioss::SideSetContainer& side_sets = region.get_sidesets(); 00538 stk_classic::io::default_part_processing(side_sets, meta, side_rank); 00539 00540 for(Ioss::SideSetContainer::const_iterator it = side_sets.begin(); 00541 it != side_sets.end(); ++it) { 00542 Ioss::SideSet *entity = *it; 00543 00544 if (stk_classic::io::include_entity(entity)) { 00545 process_surface_entity(entity, meta, side_rank); 00546 } 00547 } 00548 } 00549 00550 // ======================================================================== 00551 // Bulk Data 00552 // ======================================================================== 00553 void process_nodeblocks(Ioss::Region ®ion, stk_classic::mesh::BulkData &bulk) 00554 { 00555 // This must be called after the "process_element_blocks" call 00556 // since there may be nodes that exist in the database that are 00557 // not part of the analysis mesh due to subsetting of the element 00558 // blocks. 00559 00560 const Ioss::NodeBlockContainer& node_blocks = region.get_node_blocks(); 00561 assert(node_blocks.size() == 1); 00562 00563 Ioss::NodeBlock *nb = node_blocks[0]; 00564 00565 std::vector<stk_classic::mesh::Entity*> nodes; 00566 stk_classic::io::get_entity_list(nb, stk_classic::mesh::fem::FEMMetaData::NODE_RANK, bulk, nodes); 00567 00572 const stk_classic::mesh::MetaData& meta = stk_classic::mesh::MetaData::get(bulk); 00573 stk_classic::mesh::Field<double,stk_classic::mesh::Cartesian> *coord_field = 00574 meta.get_field<stk_classic::mesh::Field<double,stk_classic::mesh::Cartesian> >("coordinates"); 00575 00576 stk_classic::io::field_data_from_ioss(coord_field, nodes, nb, "mesh_model_coordinates"); 00577 } 00578 00579 // ======================================================================== 00580 void process_elementblocks(Ioss::Region ®ion, stk_classic::mesh::BulkData &bulk) 00581 { 00582 const Ioss::ElementBlockContainer& elem_blocks = region.get_element_blocks(); 00583 00584 for(Ioss::ElementBlockContainer::const_iterator it = elem_blocks.begin(); 00585 it != elem_blocks.end(); ++it) { 00586 Ioss::ElementBlock *entity = *it; 00587 00588 if (stk_classic::io::include_entity(entity)) { 00589 const std::string &name = entity->name(); 00590 const stk_classic::mesh::MetaData& meta = stk_classic::mesh::MetaData::get(bulk); 00591 const stk_classic::mesh::fem::FEMMetaData &fem_meta_data = stk_classic::mesh::fem::FEMMetaData::get(meta); 00592 stk_classic::mesh::Part* const part = meta.get_part(name); 00593 assert(part != NULL); 00594 00595 const CellTopologyData* cell_topo = fem_meta_data.get_cell_topology(*part).getCellTopologyData(); 00596 if (cell_topo == NULL) { 00597 std::ostringstream msg ; 00598 msg << " INTERNAL_ERROR: Part " << part->name() << " returned NULL from get_cell_topology()"; 00599 throw std::runtime_error( msg.str() ); 00600 } 00601 00602 std::vector<int> elem_ids ; 00603 std::vector<int> connectivity ; 00604 std::vector<stk_classic::mesh::EntityId> connectivity2 ; 00605 00606 entity->get_field_data("ids", elem_ids); 00607 entity->get_field_data("connectivity", connectivity); 00608 connectivity2.reserve(connectivity.size()); 00609 std::copy(connectivity.begin(), connectivity.end(), std::back_inserter(connectivity2)); 00610 00611 size_t element_count = elem_ids.size(); 00612 int nodes_per_elem = cell_topo->node_count ; 00613 00614 std::vector<stk_classic::mesh::Entity*> elements(element_count); 00615 for(size_t i=0; i<element_count; ++i) { 00616 stk_classic::mesh::EntityId *conn = &connectivity2[i*nodes_per_elem]; 00617 elements[i] = &stk_classic::mesh::fem::declare_element(bulk, *part, elem_ids[i], conn); 00618 } 00619 00620 // For this example, we are just taking all attribute fields 00621 // found on the io database and populating fields on the 00622 // corresponding mesh part. In practice, would probably be 00623 // selective about which attributes to use... 00624 Ioss::NameList names; 00625 entity->field_describe(Ioss::Field::ATTRIBUTE, &names); 00626 for (Ioss::NameList::const_iterator I = names.begin(); I != names.end(); ++I) { 00627 if (*I == "attribute" && names.size() > 1) 00628 continue; 00629 stk_classic::mesh::FieldBase *field = meta.get_field<stk_classic::mesh::FieldBase>(*I); 00630 stk_classic::io::field_data_from_ioss(field, elements, entity, *I); 00631 00632 } 00633 } 00634 } 00635 } 00636 00637 // ======================================================================== 00638 void process_nodesets(Ioss::Region ®ion, stk_classic::mesh::BulkData &bulk) 00639 { 00640 // Should only process nodes that have already been defined via the element 00641 // blocks connectivity lists. 00642 const Ioss::NodeSetContainer& node_sets = region.get_nodesets(); 00643 00644 for(Ioss::NodeSetContainer::const_iterator it = node_sets.begin(); 00645 it != node_sets.end(); ++it) { 00646 Ioss::NodeSet *entity = *it; 00647 00648 if (stk_classic::io::include_entity(entity)) { 00649 const std::string & name = entity->name(); 00650 const stk_classic::mesh::MetaData& meta = stk_classic::mesh::MetaData::get(bulk); 00651 stk_classic::mesh::Part* const part = meta.get_part(name); 00652 assert(part != NULL); 00653 stk_classic::mesh::PartVector add_parts( 1 , part ); 00654 00655 std::vector<int> node_ids ; 00656 int node_count = entity->get_field_data("ids", node_ids); 00657 00658 std::vector<stk_classic::mesh::Entity*> nodes(node_count); 00659 for(int i=0; i<node_count; ++i) { 00660 nodes[i] = bulk.get_entity( stk_classic::mesh::fem::FEMMetaData::NODE_RANK, node_ids[i] ); 00661 if (nodes[i] != NULL) 00662 bulk.declare_entity(stk_classic::mesh::fem::FEMMetaData::NODE_RANK, node_ids[i], add_parts ); 00663 } 00664 00669 stk_classic::mesh::Field<double> *df_field = 00670 meta.get_field<stk_classic::mesh::Field<double> >("distribution_factors"); 00671 00672 if (df_field != NULL) { 00673 stk_classic::io::field_data_from_ioss(df_field, nodes, entity, "distribution_factors"); 00674 } 00675 } 00676 } 00677 } 00678 00679 // ======================================================================== 00680 void process_surface_entity(const Ioss::SideSet* sset , 00681 stk_classic::mesh::BulkData & bulk) 00682 { 00683 assert(sset->type() == Ioss::SIDESET); 00684 00685 const stk_classic::mesh::MetaData& meta = stk_classic::mesh::MetaData::get(bulk); 00686 const stk_classic::mesh::fem::FEMMetaData &fem_meta_data = stk_classic::mesh::fem::FEMMetaData::get(meta); 00687 const stk_classic::mesh::EntityRank element_rank = fem_meta_data.element_rank(); 00688 00689 int block_count = sset->block_count(); 00690 for (int i=0; i < block_count; i++) { 00691 Ioss::SideBlock *block = sset->get_block(i); 00692 if (stk_classic::io::include_entity(block)) { 00693 std::vector<int> side_ids ; 00694 std::vector<int> elem_side ; 00695 00696 stk_classic::mesh::Part * const side_block_part = meta.get_part(block->name()); 00697 stk_classic::mesh::EntityRank side_rank = side_block_part->primary_entity_rank(); 00698 00699 block->get_field_data("ids", side_ids); 00700 block->get_field_data("element_side", elem_side); 00701 00702 assert(side_ids.size() * 2 == elem_side.size()); 00703 stk_classic::mesh::PartVector add_parts( 1 , side_block_part ); 00704 00705 size_t side_count = side_ids.size(); 00706 std::vector<stk_classic::mesh::Entity*> sides(side_count); 00707 for(size_t is=0; is<side_count; ++is) { 00708 00709 stk_classic::mesh::Entity* const elem = bulk.get_entity(element_rank, elem_side[is*2]); 00710 00711 // If NULL, then the element was probably assigned to an 00712 // element block that appears in the database, but was 00713 // subsetted out of the analysis mesh. Only process if 00714 // non-null. 00715 if (elem != NULL) { 00716 // Ioss uses 1-based side ordinal, stk_classic::mesh uses 0-based. 00717 // Hence the '-1' in the following line. 00718 int side_ordinal = elem_side[is*2+1] - 1 ; 00719 00720 stk_classic::mesh::Entity *side = NULL; 00721 if (side_rank == 2) { 00722 side = &stk_classic::mesh::fem::declare_element_side(bulk, side_ids[is], *elem, side_ordinal); 00723 } else { 00724 side = &stk_classic::mesh::fem::declare_element_edge(bulk, side_ids[is], *elem, side_ordinal); 00725 } 00726 bulk.change_entity_parts( *side, add_parts ); 00727 sides[is] = side; 00728 } else { 00729 sides[is] = NULL; 00730 } 00731 } 00732 00733 const stk_classic::mesh::Field<double, stk_classic::mesh::ElementNode> *df_field = 00734 stk_classic::io::get_distribution_factor_field(*side_block_part); 00735 if (df_field != NULL) { 00736 stk_classic::io::field_data_from_ioss(df_field, sides, block, "distribution_factors"); 00737 } 00738 } 00739 } 00740 } 00741 00742 // ======================================================================== 00743 void process_sidesets(Ioss::Region ®ion, stk_classic::mesh::BulkData &bulk) 00744 { 00745 const Ioss::SideSetContainer& side_sets = region.get_sidesets(); 00746 00747 for(Ioss::SideSetContainer::const_iterator it = side_sets.begin(); 00748 it != side_sets.end(); ++it) { 00749 Ioss::SideSet *entity = *it; 00750 00751 if (stk_classic::io::include_entity(entity)) { 00752 process_surface_entity(entity, bulk); 00753 } 00754 } 00755 } 00756 00757 // ======================================================================== 00758 // ======================================================================== 00759 void get_field_data(stk_classic::mesh::BulkData &bulk, stk_classic::mesh::Part &part, 00760 stk_classic::mesh::EntityRank part_type, 00761 Ioss::GroupingEntity *io_entity, 00762 Ioss::Field::RoleType filter_role) 00763 { 00764 std::vector<stk_classic::mesh::Entity*> entities; 00765 stk_classic::io::get_entity_list(io_entity, part_type, bulk, entities); 00766 00767 stk_classic::mesh::MetaData& meta = stk_classic::mesh::MetaData::get(part); 00768 stk_classic::mesh::Part &universal = meta.universal_part(); 00769 const std::vector<stk_classic::mesh::FieldBase*> &fields = meta.get_fields(); 00770 00771 std::vector<stk_classic::mesh::FieldBase *>::const_iterator I = fields.begin(); 00772 while (I != fields.end()) { 00773 const stk_classic::mesh::FieldBase *f = *I; ++I; 00774 if (stk_classic::io::is_valid_part_field(f, part_type, part, universal, filter_role)) { 00775 stk_classic::io::field_data_from_ioss(f, entities, io_entity, f->name()); 00776 } 00777 } 00778 } 00779 00780 void process_input_request(Ioss::Region ®ion, 00781 stk_classic::mesh::BulkData &bulk, 00782 int step) 00783 { 00784 region.begin_state(step); 00785 00786 // Special processing for nodeblock (all nodes in model)... 00787 const stk_classic::mesh::MetaData& meta = stk_classic::mesh::MetaData::get(bulk); 00788 00789 // ??? Get field data from nodeblock... 00790 get_field_data(bulk, meta.universal_part(), stk_classic::mesh::fem::FEMMetaData::NODE_RANK, 00791 region.get_node_blocks()[0], Ioss::Field::TRANSIENT); 00792 00793 const stk_classic::mesh::PartVector & all_parts = meta.get_parts(); 00794 for ( stk_classic::mesh::PartVector::const_iterator 00795 ip = all_parts.begin(); ip != all_parts.end(); ++ip ) { 00796 00797 stk_classic::mesh::Part * const part = *ip; 00798 00799 const stk_classic::mesh::EntityRank part_rank = part->primary_entity_rank(); 00800 00801 // Check whether this part should be output to results database. 00802 if (stk_classic::io::is_part_io_part(*part)) { 00803 // Get Ioss::GroupingEntity corresponding to this part... 00804 Ioss::GroupingEntity *entity = region.get_entity(part->name()); 00805 if (entity != NULL) { 00806 if (entity->type() == Ioss::SIDESET) { 00807 Ioss::SideSet *sset = dynamic_cast<Ioss::SideSet*>(entity); 00808 assert(sset != NULL); 00809 int block_count = sset->block_count(); 00810 for (int i=0; i < block_count; i++) { 00811 Ioss::SideBlock *side_block = sset->get_block(i); 00813 get_field_data(bulk, *part, 00814 part_rank, 00815 side_block, Ioss::Field::TRANSIENT); 00816 } 00817 } else { 00818 get_field_data(bulk, *part, 00819 part_rank, 00820 entity, Ioss::Field::TRANSIENT); 00821 } 00822 } else { 00825 } 00826 } 00827 } 00828 00829 region.end_state(step); 00830 } 00831 00832 void put_field_data(stk_classic::mesh::BulkData &bulk, stk_classic::mesh::Part &part, 00833 stk_classic::mesh::EntityRank part_type, 00834 Ioss::GroupingEntity *io_entity, 00835 Ioss::Field::RoleType filter_role) 00836 { 00837 std::vector<stk_classic::mesh::Entity*> entities; 00838 stk_classic::io::get_entity_list(io_entity, part_type, bulk, entities); 00839 00840 stk_classic::mesh::MetaData& meta = stk_classic::mesh::MetaData::get(part); 00841 stk_classic::mesh::Part &universal = meta.universal_part(); 00842 const std::vector<stk_classic::mesh::FieldBase*> &fields = meta.get_fields(); 00843 00844 std::vector<stk_classic::mesh::FieldBase *>::const_iterator I = fields.begin(); 00845 while (I != fields.end()) { 00846 const stk_classic::mesh::FieldBase *f = *I; ++I; 00847 if (stk_classic::io::is_valid_part_field(f, part_type, part, universal, filter_role)) { 00848 stk_classic::io::field_data_to_ioss(f, entities, io_entity, f->name(), filter_role); 00849 } 00850 } 00851 } 00852 00853 void process_output_request(Ioss::Region ®ion, 00854 stk_classic::mesh::BulkData &bulk, 00855 int step) 00856 { 00857 region.begin_state(step); 00858 // Special processing for nodeblock (all nodes in model)... 00859 const stk_classic::mesh::MetaData& meta = stk_classic::mesh::MetaData::get(bulk); 00860 00861 put_field_data(bulk, meta.universal_part(), stk_classic::mesh::fem::FEMMetaData::NODE_RANK, 00862 region.get_node_blocks()[0], Ioss::Field::TRANSIENT); 00863 00864 const stk_classic::mesh::PartVector & all_parts = meta.get_parts(); 00865 for ( stk_classic::mesh::PartVector::const_iterator 00866 ip = all_parts.begin(); ip != all_parts.end(); ++ip ) { 00867 00868 stk_classic::mesh::Part * const part = *ip; 00869 00870 const stk_classic::mesh::EntityRank part_rank = part->primary_entity_rank(); 00871 00872 // Check whether this part should be output to results database. 00873 if (stk_classic::io::is_part_io_part(*part)) { 00874 00875 // Get Ioss::GroupingEntity corresponding to this part... 00876 Ioss::GroupingEntity *entity = region.get_entity(part->name()); 00877 if (entity != NULL) { 00878 00879 if (entity->type() == Ioss::SIDESET) { 00880 Ioss::SideSet *sset = dynamic_cast<Ioss::SideSet*>(entity); 00881 assert(sset != NULL); 00882 int block_count = sset->block_count(); 00883 00884 for (int i=0; i < block_count; i++) { 00885 Ioss::SideBlock *side_block = sset->get_block(i); 00887 put_field_data(bulk, *part, part_rank, 00888 side_block, Ioss::Field::TRANSIENT); 00889 } 00890 } else { 00891 put_field_data(bulk, *part, part_rank, 00892 entity, Ioss::Field::TRANSIENT); 00893 } 00894 } else { 00897 } 00898 } 00899 } 00900 region.end_state(step); 00901 } 00902 } 00903 00904 // ======================================================================== 00905 #include <boost/program_options.hpp> 00906 00907 #include <stk_util/parallel/BroadcastArg.hpp> 00908 #include <stk_util/environment/ProgramOptions.hpp> 00909 00910 namespace bopt = boost::program_options; 00911 int main(int argc, char** argv) 00912 { 00913 //---------------------------------- 00914 // Broadcast argc and argv to all processors. 00915 00916 stk_classic::ParallelMachine comm = stk_classic::parallel_machine_init(&argc, &argv); 00917 00918 stk_classic::BroadcastArg b_arg(comm, argc, argv); 00919 00920 //---------------------------------- 00921 // Process the broadcast command line arguments 00922 00923 bopt::options_description desc("options"); 00924 00925 desc.add_options() 00926 ("help,h", "produce help message") 00927 ("mesh", bopt::value<std::string>(), "mesh file" ) 00928 ("decomposition,D", bopt::value<std::string>(), "decomposition method" ) 00929 ("directory,d", bopt::value<std::string>(), "working directory" ) 00930 ("output-log,o", bopt::value<std::string>(), "output log path" ) 00931 ("runtest,r", bopt::value<std::string>(), "runtest pid file" ); 00932 00933 stk_classic::get_options_description().add(desc); 00934 00935 bopt::variables_map &vm = stk_classic::get_variables_map(); 00936 try { 00937 bopt::store(bopt::parse_command_line(b_arg.m_argc, b_arg.m_argv, desc), vm); 00938 bopt::notify(vm); 00939 } 00940 catch (std::exception & /* x */) { 00941 std::exit(1); 00942 } 00943 00944 if (vm.count("help")) { 00945 std::cout << desc << "\n"; 00946 std::exit(EXIT_SUCCESS); 00947 } 00948 00949 //---------------------------------- 00950 00951 if ( vm.count("mesh") ) { 00952 std::string in_filename = boost::any_cast<std::string>(vm["mesh"].value()); 00953 std::string out_filename = in_filename + ".out"; 00954 std::string decomp_method; 00955 if (vm.count("decomposition")) { 00956 decomp_method = boost::any_cast<std::string>(vm["decomposition"].value()); 00957 } 00958 stk_example_io::io_example(comm, in_filename, out_filename, decomp_method ); 00959 } else { 00960 std::cout << "OPTION ERROR: The '--mesh <filename>' option is required!\n"; 00961 std::exit(EXIT_FAILURE); 00962 } 00963 stk_classic::parallel_machine_finalize(); 00964 00965 return 0; 00966 } 00967