Sierra Toolkit  Version of the Day
io_example.cpp
1 /*------------------------------------------------------------------------*/
2 /* Copyright 2010, 2011 Sandia Corporation. */
3 /* Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive */
4 /* license for use of this work by or on behalf of the U.S. Government. */
5 /* Export of this program may require a license from the */
6 /* United States Government. */
7 /*------------------------------------------------------------------------*/
8 
9 #include <iostream>
10 #include <assert.h>
11 
12 #include <stk_util/parallel/Parallel.hpp>
13 #include <init/Ionit_Initializer.h>
14 #include <Ioss_SubSystem.h>
15 
16 #include <stk_mesh/base/Field.hpp>
17 #include <stk_mesh/base/FieldData.hpp>
18 #include <stk_mesh/base/BulkData.hpp>
19 
20 #include <stk_mesh/fem/FEMMetaData.hpp>
21 #include <stk_mesh/fem/TopologyDimensions.hpp>
22 
23 #include <stk_io/IossBridge.hpp>
24 
41 namespace stk_example_io {
42 
46  void process_nodeblocks (Ioss::Region &region, stk_classic::mesh::MetaData &meta);
47 
53  void process_elementblocks (Ioss::Region &region, stk_classic::mesh::MetaData &meta);
54 
61  void process_nodesets (Ioss::Region &region, stk_classic::mesh::MetaData &meta);
62 
76  void process_sidesets (Ioss::Region &region, stk_classic::mesh::MetaData &meta);
77 
84  void process_nodeblocks (Ioss::Region &region, stk_classic::mesh::BulkData &bulk);
85 
97  void process_elementblocks (Ioss::Region &region, stk_classic::mesh::BulkData &bulk);
98 
105  void process_nodesets (Ioss::Region &region, stk_classic::mesh::BulkData &bulk);
106 
112  void process_sidesets (Ioss::Region &region, stk_classic::mesh::BulkData &bulk);
113 
120  void process_input_request (Ioss::Region &region, stk_classic::mesh::BulkData &bulk, int step);
121 
134  void process_output_request(Ioss::Region &region, stk_classic::mesh::BulkData &bulk, int step);
135 
163  const std::string& in_filename,
164  const std::string& out_filename,
165  const std::string& decomp_method)
166  {
167  // Initialize IO system. Registers all element types and storage
168  // types and the exodusII default database type.
169  Ioss::Init::Initializer init_db;
170 
171  std::cout << "========================================================================\n"
172  << " Copy input mesh to output mesh. \n"
173  << "========================================================================\n";
174 
175  std::string dbtype("exodusII");
176  Ioss::PropertyManager properties;
177  if (!decomp_method.empty()) {
178  properties.add(Ioss::Property("DECOMPOSITION_METHOD", Ioss::Utils::uppercase(decomp_method)));
179  }
180  Ioss::DatabaseIO *dbi = Ioss::IOFactory::create(dbtype, in_filename, Ioss::READ_MODEL,
181  comm, properties);
182  if (dbi == NULL || !dbi->ok()) {
183  std::cerr << "ERROR: Could not open database '" << in_filename
184  << "' of type '" << dbtype << "'\n";
185  std::exit(EXIT_FAILURE);
186  }
187 
188  std::cout << "Reading input file: " << in_filename << "\n";
189  // NOTE: 'in_region' owns 'dbi' pointer at this time...
190  Ioss::Region in_region(dbi, "input_model");
191 
192  // SUBSETTING PARSING/PREPROCESSING...
193  // Just an example of how application could control whether an
194  // entity is subsetted or not...
195 
196 
197 #if 0
198  // Example command line in current code corresponding to behavior below:
199  std::cout << "\nWhen processing file multi-block.g for use case 2, the blocks below will be omitted:\n";
200  std::cout << "\tOMIT BLOCK Cblock Eblock I1 I2\n\n";
201  Ioss::ElementBlock *eb = in_region.get_element_block("cblock");
202  if (eb != NULL)
203  eb->property_add(Ioss::Property(std::string("omitted"), 1));
204 
205  eb = in_region.get_element_block("eblock");
206  if (eb != NULL)
207  eb->property_add(Ioss::Property(std::string("omitted"), 1));
208 
209  eb = in_region.get_element_block("i1");
210  if (eb != NULL)
211  eb->property_add(Ioss::Property(std::string("omitted"), 1));
212 
213  eb = in_region.get_element_block("i2");
214  if (eb != NULL)
215  eb->property_add(Ioss::Property(std::string("omitted"), 1));
216 #endif
217 
218 #if 0
219  // Example for subsetting -- omit "odd" blocks
220  if (entity->type() == Ioss::ELEMENTBLOCK) {
221  int id = entity->get_property("id").get_int();
222  if (id % 2) {
223  entity->property_add(Ioss::Property(std::string("omitted"), 1));
224  std::cout << "Skipping " << entity->type_string() << ": " << entity->name() << "\n";
225  }
226  }
227 #endif
228 
229  //----------------------------------
230  // Process Entity Types. Subsetting is possible.
231 
232  static size_t spatial_dimension = in_region.get_property("spatial_dimension").get_int();
233 
234  stk_classic::mesh::fem::FEMMetaData fem_meta_data( spatial_dimension );
235  stk_classic::mesh::MetaData &meta_data = fem_meta_data.get_meta_data(fem_meta_data);
236  process_elementblocks(in_region, meta_data);
237  process_nodeblocks(in_region, meta_data);
238  process_sidesets(in_region, meta_data);
239  process_nodesets(in_region, meta_data);
240 
241  //----------------------------------
242  // Done populating meta data, commit and create bulk data
243  meta_data.commit();
244 
245  //----------------------------------
246  // Process Bulkdata for all Entity Types. Subsetting is possible.
247  stk_classic::mesh::BulkData bulk_data(meta_data, comm);
248 
249  bulk_data.modification_begin();
250  process_elementblocks(in_region, bulk_data);
251  process_nodeblocks(in_region, bulk_data);
252  process_sidesets(in_region, bulk_data);
253  process_nodesets(in_region, bulk_data);
254  bulk_data.modification_end();
255 
256  //----------------------------------
257  // OUTPUT...Create the output "mesh" portion
258 
259  std::cout << "Creating output file: " << out_filename << "\n";
260  Ioss::DatabaseIO *dbo = Ioss::IOFactory::create(dbtype, out_filename,
261  Ioss::WRITE_RESULTS,
262  comm);
263  if (dbo == NULL || !dbo->ok()) {
264  std::cerr << "ERROR: Could not open results database '" << out_filename
265  << "' of type '" << dbtype << "'\n";
266  std::exit(EXIT_FAILURE);
267  }
268 
269 #if 0
270  {
271  // Code to test the remove_io_part_attribute functionality.
272  // Hook this up to a command line option at some point to test nightly...
273  const stk_classic::mesh::PartVector & all_parts = meta_data.get_parts();
274  for ( stk_classic::mesh::PartVector::const_iterator ip = all_parts.begin(); ip != all_parts.end(); ++ip ) {
275  stk_classic::mesh::Part * const part = *ip;
276  const stk_classic::mesh::EntityRank part_rank = part->primary_entity_rank();
277 
278  if (stk_classic::io::is_part_io_part(*part) && part_rank == 2) {
279  std::cout << "Removing part attribute from " << part->name() << "\n";
281  }
282  }
283  }
284 #endif
285 
286  // NOTE: 'out_region' owns 'dbo' pointer at this time...
287  Ioss::Region out_region(dbo, "results_output");
288 
289  stk_classic::io::define_output_db(out_region, bulk_data, &in_region);
290  stk_classic::io::write_output_db(out_region, bulk_data);
291 
292  // ------------------------------------------------------------------------
307  out_region.begin_mode(Ioss::STATE_DEFINE_TRANSIENT);
308 
309  // Special processing for nodeblock (all nodes in model)...
310  stk_classic::io::ioss_add_fields(meta_data.universal_part(), stk_classic::mesh::fem::FEMMetaData::NODE_RANK,
311  out_region.get_node_blocks()[0],
312  Ioss::Field::TRANSIENT);
313 
314  const stk_classic::mesh::PartVector & all_parts = meta_data.get_parts();
315  for ( stk_classic::mesh::PartVector::const_iterator
316  ip = all_parts.begin(); ip != all_parts.end(); ++ip ) {
317 
318  stk_classic::mesh::Part * const part = *ip;
319 
320  const stk_classic::mesh::EntityRank part_rank = part->primary_entity_rank();
321 
322  // Check whether this part should be output to results database.
324  // Get Ioss::GroupingEntity corresponding to this part...
325  Ioss::GroupingEntity *entity = out_region.get_entity(part->name());
326  if (entity != NULL) {
327  if (entity->type() == Ioss::SIDESET) {
328  Ioss::SideSet *sset = dynamic_cast<Ioss::SideSet*>(entity);
329  assert(sset != NULL);
330  int block_count = sset->block_count();
331  for (int i=0; i < block_count; i++) {
332  Ioss::SideBlock *fb = sset->get_block(i);
333  stk_classic::io::ioss_add_fields(*part, part_rank,
334  fb, Ioss::Field::TRANSIENT);
335  }
336  } else {
337  stk_classic::io::ioss_add_fields(*part, part_rank,
338  entity, Ioss::Field::TRANSIENT);
339  }
340  } else {
343  }
344  }
345  }
346  out_region.end_mode(Ioss::STATE_DEFINE_TRANSIENT);
347  // ------------------------------------------------------------------------
348 
349  // Read and Write transient fields...
350  out_region.begin_mode(Ioss::STATE_TRANSIENT);
351  int timestep_count = in_region.get_property("state_count").get_int();
352  for (int step = 1; step <= timestep_count; step++) {
353  double time = in_region.get_state_time(step);
354 
355  // Read data from the io input mesh database into stk_classic::mesh fields...
356  process_input_request(in_region, bulk_data, step);
357 
358  // execute()
359 
360  // Write data from the stk_classic::mesh fields out to the output database.a
361  int out_step = out_region.add_state(time);
362  process_output_request(out_region, bulk_data, out_step);
363  }
364  out_region.end_mode(Ioss::STATE_TRANSIENT);
365  }
366 
367  // ========================================================================
368  void process_nodeblocks(Ioss::Region &region, stk_classic::mesh::MetaData &meta)
369  {
370  const Ioss::NodeBlockContainer& node_blocks = region.get_node_blocks();
371  assert(node_blocks.size() == 1);
372 
373  Ioss::NodeBlock *nb = node_blocks[0];
374 
375  assert(nb->field_exists("mesh_model_coordinates"));
376  Ioss::Field coordinates = nb->get_field("mesh_model_coordinates");
377  int spatial_dim = coordinates.transformed_storage()->component_count();
378 
381 
382  stk_classic::mesh::put_field( coord_field, stk_classic::mesh::fem::FEMMetaData::NODE_RANK, meta.universal_part(),
383  spatial_dim);
384 
389  stk_classic::io::define_io_fields(nb, Ioss::Field::TRANSIENT, meta.universal_part(),stk_classic::mesh::fem::FEMMetaData::NODE_RANK);
390  }
391 
392  // ========================================================================
393  void process_elementblocks(Ioss::Region &region, stk_classic::mesh::MetaData &meta)
394  {
396  const stk_classic::mesh::EntityRank element_rank = fem_meta_data.element_rank();
397 
398  const Ioss::ElementBlockContainer& elem_blocks = region.get_element_blocks();
399  stk_classic::io::default_part_processing(elem_blocks, meta, element_rank);
400 
401  // Parts were created above, now handle element block specific
402  // information (topology, attributes, ...);
403  for(Ioss::ElementBlockContainer::const_iterator it = elem_blocks.begin();
404  it != elem_blocks.end(); ++it) {
405  Ioss::ElementBlock *entity = *it;
406 
407  if (stk_classic::io::include_entity(entity)) {
408  stk_classic::mesh::Part* const part = meta.get_part(entity->name());
409  assert(part != NULL);
410 
411  const stk_classic::mesh::EntityRank part_rank = part->primary_entity_rank();
412 
413  // Element Block attributes (if any)...
418  stk_classic::io::define_io_fields(entity, Ioss::Field::ATTRIBUTE,
419  *part,
420  part_rank);
421 
426  stk_classic::io::define_io_fields(entity, Ioss::Field::TRANSIENT,
427  *part,
428  part_rank);
429 
430  const CellTopologyData* cell_topo = fem_meta_data.get_cell_topology(*part).getCellTopologyData();
431  std::string cell_topo_name = "UNKNOWN";
432  if (cell_topo != NULL)
433  cell_topo_name = cell_topo->name;
434  }
435  }
436  }
437 
438  // ========================================================================
439  void process_nodesets(Ioss::Region &region, stk_classic::mesh::MetaData &meta)
440  {
441  const Ioss::NodeSetContainer& node_sets = region.get_nodesets();
442  stk_classic::io::default_part_processing(node_sets, meta, stk_classic::mesh::fem::FEMMetaData::NODE_RANK);
443 
448  stk_classic::mesh::Field<double> & distribution_factors_field =
449  meta.declare_field<stk_classic::mesh::Field<double> >("distribution_factors");
450 
456  for(Ioss::NodeSetContainer::const_iterator it = node_sets.begin();
457  it != node_sets.end(); ++it) {
458  Ioss::NodeSet *entity = *it;
459 
460  if (stk_classic::io::include_entity(entity)) {
461  stk_classic::mesh::Part* const part = meta.get_part(entity->name());
462  assert(part != NULL);
463  assert(entity->field_exists("distribution_factors"));
464 
465  stk_classic::mesh::put_field(distribution_factors_field, stk_classic::mesh::fem::FEMMetaData::NODE_RANK, *part);
466 
471  stk_classic::io::define_io_fields(entity, Ioss::Field::TRANSIENT,
472  *part,
473  part->primary_entity_rank() ) ;
474  }
475  }
476  }
477 
478  // ========================================================================
479  void process_surface_entity(Ioss::SideSet *sset, stk_classic::mesh::MetaData &meta,
480  stk_classic::mesh::EntityRank sset_rank)
481  {
482  assert(sset->type() == Ioss::SIDESET);
483  Ioss::SideSet *fs = dynamic_cast<Ioss::SideSet *>(sset);
484  assert(fs != NULL);
485  const Ioss::SideBlockContainer& blocks = fs->get_side_blocks();
486  stk_classic::io::default_part_processing(blocks, meta, sset_rank);
487 
488  stk_classic::mesh::Part* const fs_part = meta.get_part(sset->name());
489  assert(fs_part != NULL);
490 
491  stk_classic::mesh::Field<double, stk_classic::mesh::ElementNode> *distribution_factors_field = NULL;
492  bool surface_df_defined = false; // Has the surface df field been defined yet?
493 
494 
495  int block_count = sset->block_count();
496  for (int i=0; i < block_count; i++) {
497  Ioss::SideBlock *side_block = sset->get_block(i);
498  if (stk_classic::io::include_entity(side_block)) {
499  stk_classic::mesh::Part * const side_block_part = meta.get_part(side_block->name());
500  assert(side_block_part != NULL);
501  meta.declare_part_subset(*fs_part, *side_block_part);
502 
503  const stk_classic::mesh::EntityRank part_rank = side_block_part->primary_entity_rank();
504 
505  if (side_block->field_exists("distribution_factors")) {
506  if (!surface_df_defined) {
507  std::string field_name = sset->name() + "_distribution_factors";
508  distribution_factors_field =
510  stk_classic::io::set_distribution_factor_field(*fs_part, *distribution_factors_field);
511  surface_df_defined = true;
512  }
513  stk_classic::io::set_distribution_factor_field(*side_block_part, *distribution_factors_field);
514  int side_node_count = side_block->topology()->number_nodes();
515  stk_classic::mesh::put_field(*distribution_factors_field,
516  part_rank,
517  *side_block_part, side_node_count);
518  }
519 
524  stk_classic::io::define_io_fields(side_block, Ioss::Field::TRANSIENT,
525  *side_block_part,
526  part_rank);
527  }
528  }
529  }
530 
531  // ========================================================================
532  void process_sidesets(Ioss::Region &region, stk_classic::mesh::MetaData &meta)
533  {
535  const stk_classic::mesh::EntityRank side_rank = fem.side_rank();
536 
537  const Ioss::SideSetContainer& side_sets = region.get_sidesets();
538  stk_classic::io::default_part_processing(side_sets, meta, side_rank);
539 
540  for(Ioss::SideSetContainer::const_iterator it = side_sets.begin();
541  it != side_sets.end(); ++it) {
542  Ioss::SideSet *entity = *it;
543 
544  if (stk_classic::io::include_entity(entity)) {
545  process_surface_entity(entity, meta, side_rank);
546  }
547  }
548  }
549 
550  // ========================================================================
551  // Bulk Data
552  // ========================================================================
553  void process_nodeblocks(Ioss::Region &region, stk_classic::mesh::BulkData &bulk)
554  {
555  // This must be called after the "process_element_blocks" call
556  // since there may be nodes that exist in the database that are
557  // not part of the analysis mesh due to subsetting of the element
558  // blocks.
559 
560  const Ioss::NodeBlockContainer& node_blocks = region.get_node_blocks();
561  assert(node_blocks.size() == 1);
562 
563  Ioss::NodeBlock *nb = node_blocks[0];
564 
565  std::vector<stk_classic::mesh::Entity*> nodes;
566  stk_classic::io::get_entity_list(nb, stk_classic::mesh::fem::FEMMetaData::NODE_RANK, bulk, nodes);
567 
572  const stk_classic::mesh::MetaData& meta = stk_classic::mesh::MetaData::get(bulk);
575 
576  stk_classic::io::field_data_from_ioss(coord_field, nodes, nb, "mesh_model_coordinates");
577  }
578 
579  // ========================================================================
580  void process_elementblocks(Ioss::Region &region, stk_classic::mesh::BulkData &bulk)
581  {
582  const Ioss::ElementBlockContainer& elem_blocks = region.get_element_blocks();
583 
584  for(Ioss::ElementBlockContainer::const_iterator it = elem_blocks.begin();
585  it != elem_blocks.end(); ++it) {
586  Ioss::ElementBlock *entity = *it;
587 
588  if (stk_classic::io::include_entity(entity)) {
589  const std::string &name = entity->name();
590  const stk_classic::mesh::MetaData& meta = stk_classic::mesh::MetaData::get(bulk);
592  stk_classic::mesh::Part* const part = meta.get_part(name);
593  assert(part != NULL);
594 
595  const CellTopologyData* cell_topo = fem_meta_data.get_cell_topology(*part).getCellTopologyData();
596  if (cell_topo == NULL) {
597  std::ostringstream msg ;
598  msg << " INTERNAL_ERROR: Part " << part->name() << " returned NULL from get_cell_topology()";
599  throw std::runtime_error( msg.str() );
600  }
601 
602  std::vector<int> elem_ids ;
603  std::vector<int> connectivity ;
604  std::vector<stk_classic::mesh::EntityId> connectivity2 ;
605 
606  entity->get_field_data("ids", elem_ids);
607  entity->get_field_data("connectivity", connectivity);
608  connectivity2.reserve(connectivity.size());
609  std::copy(connectivity.begin(), connectivity.end(), std::back_inserter(connectivity2));
610 
611  size_t element_count = elem_ids.size();
612  int nodes_per_elem = cell_topo->node_count ;
613 
614  std::vector<stk_classic::mesh::Entity*> elements(element_count);
615  for(size_t i=0; i<element_count; ++i) {
616  stk_classic::mesh::EntityId *conn = &connectivity2[i*nodes_per_elem];
617  elements[i] = &stk_classic::mesh::fem::declare_element(bulk, *part, elem_ids[i], conn);
618  }
619 
620  // For this example, we are just taking all attribute fields
621  // found on the io database and populating fields on the
622  // corresponding mesh part. In practice, would probably be
623  // selective about which attributes to use...
624  Ioss::NameList names;
625  entity->field_describe(Ioss::Field::ATTRIBUTE, &names);
626  for (Ioss::NameList::const_iterator I = names.begin(); I != names.end(); ++I) {
627  if (*I == "attribute" && names.size() > 1)
628  continue;
630  stk_classic::io::field_data_from_ioss(field, elements, entity, *I);
631 
632  }
633  }
634  }
635  }
636 
637  // ========================================================================
638  void process_nodesets(Ioss::Region &region, stk_classic::mesh::BulkData &bulk)
639  {
640  // Should only process nodes that have already been defined via the element
641  // blocks connectivity lists.
642  const Ioss::NodeSetContainer& node_sets = region.get_nodesets();
643 
644  for(Ioss::NodeSetContainer::const_iterator it = node_sets.begin();
645  it != node_sets.end(); ++it) {
646  Ioss::NodeSet *entity = *it;
647 
648  if (stk_classic::io::include_entity(entity)) {
649  const std::string & name = entity->name();
650  const stk_classic::mesh::MetaData& meta = stk_classic::mesh::MetaData::get(bulk);
651  stk_classic::mesh::Part* const part = meta.get_part(name);
652  assert(part != NULL);
653  stk_classic::mesh::PartVector add_parts( 1 , part );
654 
655  std::vector<int> node_ids ;
656  int node_count = entity->get_field_data("ids", node_ids);
657 
658  std::vector<stk_classic::mesh::Entity*> nodes(node_count);
659  for(int i=0; i<node_count; ++i) {
660  nodes[i] = bulk.get_entity( stk_classic::mesh::fem::FEMMetaData::NODE_RANK, node_ids[i] );
661  if (nodes[i] != NULL)
662  bulk.declare_entity(stk_classic::mesh::fem::FEMMetaData::NODE_RANK, node_ids[i], add_parts );
663  }
664 
670  meta.get_field<stk_classic::mesh::Field<double> >("distribution_factors");
671 
672  if (df_field != NULL) {
673  stk_classic::io::field_data_from_ioss(df_field, nodes, entity, "distribution_factors");
674  }
675  }
676  }
677  }
678 
679  // ========================================================================
680  void process_surface_entity(const Ioss::SideSet* sset ,
682  {
683  assert(sset->type() == Ioss::SIDESET);
684 
685  const stk_classic::mesh::MetaData& meta = stk_classic::mesh::MetaData::get(bulk);
687  const stk_classic::mesh::EntityRank element_rank = fem_meta_data.element_rank();
688 
689  int block_count = sset->block_count();
690  for (int i=0; i < block_count; i++) {
691  Ioss::SideBlock *block = sset->get_block(i);
692  if (stk_classic::io::include_entity(block)) {
693  std::vector<int> side_ids ;
694  std::vector<int> elem_side ;
695 
696  stk_classic::mesh::Part * const side_block_part = meta.get_part(block->name());
697  stk_classic::mesh::EntityRank side_rank = side_block_part->primary_entity_rank();
698 
699  block->get_field_data("ids", side_ids);
700  block->get_field_data("element_side", elem_side);
701 
702  assert(side_ids.size() * 2 == elem_side.size());
703  stk_classic::mesh::PartVector add_parts( 1 , side_block_part );
704 
705  size_t side_count = side_ids.size();
706  std::vector<stk_classic::mesh::Entity*> sides(side_count);
707  for(size_t is=0; is<side_count; ++is) {
708 
709  stk_classic::mesh::Entity* const elem = bulk.get_entity(element_rank, elem_side[is*2]);
710 
711  // If NULL, then the element was probably assigned to an
712  // element block that appears in the database, but was
713  // subsetted out of the analysis mesh. Only process if
714  // non-null.
715  if (elem != NULL) {
716  // Ioss uses 1-based side ordinal, stk_classic::mesh uses 0-based.
717  // Hence the '-1' in the following line.
718  int side_ordinal = elem_side[is*2+1] - 1 ;
719 
720  stk_classic::mesh::Entity *side = NULL;
721  if (side_rank == 2) {
722  side = &stk_classic::mesh::fem::declare_element_side(bulk, side_ids[is], *elem, side_ordinal);
723  } else {
724  side = &stk_classic::mesh::fem::declare_element_edge(bulk, side_ids[is], *elem, side_ordinal);
725  }
726  bulk.change_entity_parts( *side, add_parts );
727  sides[is] = side;
728  } else {
729  sides[is] = NULL;
730  }
731  }
732 
735  if (df_field != NULL) {
736  stk_classic::io::field_data_from_ioss(df_field, sides, block, "distribution_factors");
737  }
738  }
739  }
740  }
741 
742  // ========================================================================
743  void process_sidesets(Ioss::Region &region, stk_classic::mesh::BulkData &bulk)
744  {
745  const Ioss::SideSetContainer& side_sets = region.get_sidesets();
746 
747  for(Ioss::SideSetContainer::const_iterator it = side_sets.begin();
748  it != side_sets.end(); ++it) {
749  Ioss::SideSet *entity = *it;
750 
751  if (stk_classic::io::include_entity(entity)) {
752  process_surface_entity(entity, bulk);
753  }
754  }
755  }
756 
757  // ========================================================================
758  // ========================================================================
759  void get_field_data(stk_classic::mesh::BulkData &bulk, stk_classic::mesh::Part &part,
760  stk_classic::mesh::EntityRank part_type,
761  Ioss::GroupingEntity *io_entity,
762  Ioss::Field::RoleType filter_role)
763  {
764  std::vector<stk_classic::mesh::Entity*> entities;
765  stk_classic::io::get_entity_list(io_entity, part_type, bulk, entities);
766 
767  stk_classic::mesh::MetaData& meta = stk_classic::mesh::MetaData::get(part);
768  stk_classic::mesh::Part &universal = meta.universal_part();
769  const std::vector<stk_classic::mesh::FieldBase*> &fields = meta.get_fields();
770 
771  std::vector<stk_classic::mesh::FieldBase *>::const_iterator I = fields.begin();
772  while (I != fields.end()) {
773  const stk_classic::mesh::FieldBase *f = *I; ++I;
774  if (stk_classic::io::is_valid_part_field(f, part_type, part, universal, filter_role)) {
775  stk_classic::io::field_data_from_ioss(f, entities, io_entity, f->name());
776  }
777  }
778  }
779 
780  void process_input_request(Ioss::Region &region,
782  int step)
783  {
784  region.begin_state(step);
785 
786  // Special processing for nodeblock (all nodes in model)...
787  const stk_classic::mesh::MetaData& meta = stk_classic::mesh::MetaData::get(bulk);
788 
789  // ??? Get field data from nodeblock...
790  get_field_data(bulk, meta.universal_part(), stk_classic::mesh::fem::FEMMetaData::NODE_RANK,
791  region.get_node_blocks()[0], Ioss::Field::TRANSIENT);
792 
793  const stk_classic::mesh::PartVector & all_parts = meta.get_parts();
794  for ( stk_classic::mesh::PartVector::const_iterator
795  ip = all_parts.begin(); ip != all_parts.end(); ++ip ) {
796 
797  stk_classic::mesh::Part * const part = *ip;
798 
799  const stk_classic::mesh::EntityRank part_rank = part->primary_entity_rank();
800 
801  // Check whether this part should be output to results database.
803  // Get Ioss::GroupingEntity corresponding to this part...
804  Ioss::GroupingEntity *entity = region.get_entity(part->name());
805  if (entity != NULL) {
806  if (entity->type() == Ioss::SIDESET) {
807  Ioss::SideSet *sset = dynamic_cast<Ioss::SideSet*>(entity);
808  assert(sset != NULL);
809  int block_count = sset->block_count();
810  for (int i=0; i < block_count; i++) {
811  Ioss::SideBlock *side_block = sset->get_block(i);
813  get_field_data(bulk, *part,
814  part_rank,
815  side_block, Ioss::Field::TRANSIENT);
816  }
817  } else {
818  get_field_data(bulk, *part,
819  part_rank,
820  entity, Ioss::Field::TRANSIENT);
821  }
822  } else {
825  }
826  }
827  }
828 
829  region.end_state(step);
830  }
831 
832  void put_field_data(stk_classic::mesh::BulkData &bulk, stk_classic::mesh::Part &part,
833  stk_classic::mesh::EntityRank part_type,
834  Ioss::GroupingEntity *io_entity,
835  Ioss::Field::RoleType filter_role)
836  {
837  std::vector<stk_classic::mesh::Entity*> entities;
838  stk_classic::io::get_entity_list(io_entity, part_type, bulk, entities);
839 
840  stk_classic::mesh::MetaData& meta = stk_classic::mesh::MetaData::get(part);
841  stk_classic::mesh::Part &universal = meta.universal_part();
842  const std::vector<stk_classic::mesh::FieldBase*> &fields = meta.get_fields();
843 
844  std::vector<stk_classic::mesh::FieldBase *>::const_iterator I = fields.begin();
845  while (I != fields.end()) {
846  const stk_classic::mesh::FieldBase *f = *I; ++I;
847  if (stk_classic::io::is_valid_part_field(f, part_type, part, universal, filter_role)) {
848  stk_classic::io::field_data_to_ioss(f, entities, io_entity, f->name(), filter_role);
849  }
850  }
851  }
852 
853  void process_output_request(Ioss::Region &region,
855  int step)
856  {
857  region.begin_state(step);
858  // Special processing for nodeblock (all nodes in model)...
859  const stk_classic::mesh::MetaData& meta = stk_classic::mesh::MetaData::get(bulk);
860 
861  put_field_data(bulk, meta.universal_part(), stk_classic::mesh::fem::FEMMetaData::NODE_RANK,
862  region.get_node_blocks()[0], Ioss::Field::TRANSIENT);
863 
864  const stk_classic::mesh::PartVector & all_parts = meta.get_parts();
865  for ( stk_classic::mesh::PartVector::const_iterator
866  ip = all_parts.begin(); ip != all_parts.end(); ++ip ) {
867 
868  stk_classic::mesh::Part * const part = *ip;
869 
870  const stk_classic::mesh::EntityRank part_rank = part->primary_entity_rank();
871 
872  // Check whether this part should be output to results database.
874 
875  // Get Ioss::GroupingEntity corresponding to this part...
876  Ioss::GroupingEntity *entity = region.get_entity(part->name());
877  if (entity != NULL) {
878 
879  if (entity->type() == Ioss::SIDESET) {
880  Ioss::SideSet *sset = dynamic_cast<Ioss::SideSet*>(entity);
881  assert(sset != NULL);
882  int block_count = sset->block_count();
883 
884  for (int i=0; i < block_count; i++) {
885  Ioss::SideBlock *side_block = sset->get_block(i);
887  put_field_data(bulk, *part, part_rank,
888  side_block, Ioss::Field::TRANSIENT);
889  }
890  } else {
891  put_field_data(bulk, *part, part_rank,
892  entity, Ioss::Field::TRANSIENT);
893  }
894  } else {
897  }
898  }
899  }
900  region.end_state(step);
901  }
902 }
903 
904 // ========================================================================
905 #include <boost/program_options.hpp>
906 
907 #include <stk_util/parallel/BroadcastArg.hpp>
908 #include <stk_util/environment/ProgramOptions.hpp>
909 
910  namespace bopt = boost::program_options;
911  int main(int argc, char** argv)
912  {
913  //----------------------------------
914  // Broadcast argc and argv to all processors.
915 
917 
918  stk_classic::BroadcastArg b_arg(comm, argc, argv);
919 
920  //----------------------------------
921  // Process the broadcast command line arguments
922 
923  bopt::options_description desc("options");
924 
925  desc.add_options()
926  ("help,h", "produce help message")
927  ("mesh", bopt::value<std::string>(), "mesh file" )
928  ("decomposition,D", bopt::value<std::string>(), "decomposition method" )
929  ("directory,d", bopt::value<std::string>(), "working directory" )
930  ("output-log,o", bopt::value<std::string>(), "output log path" )
931  ("runtest,r", bopt::value<std::string>(), "runtest pid file" );
932 
934 
935  bopt::variables_map &vm = stk_classic::get_variables_map();
936  try {
937  bopt::store(bopt::parse_command_line(b_arg.m_argc, b_arg.m_argv, desc), vm);
938  bopt::notify(vm);
939  }
940  catch (std::exception & /* x */) {
941  std::exit(1);
942  }
943 
944  if (vm.count("help")) {
945  std::cout << desc << "\n";
946  std::exit(EXIT_SUCCESS);
947  }
948 
949  //----------------------------------
950 
951  if ( vm.count("mesh") ) {
952  std::string in_filename = boost::any_cast<std::string>(vm["mesh"].value());
953  std::string out_filename = in_filename + ".out";
954  std::string decomp_method;
955  if (vm.count("decomposition")) {
956  decomp_method = boost::any_cast<std::string>(vm["decomposition"].value());
957  }
958  stk_example_io::io_example(comm, in_filename, out_filename, decomp_method );
959  } else {
960  std::cout << "OPTION ERROR: The '--mesh <filename>' option is required!\n";
961  std::exit(EXIT_FAILURE);
962  }
964 
965  return 0;
966  }
967 
stk_classic::mesh::FieldBase
Field base class with an anonymous data type and anonymous multi-dimension.
Definition: FieldBase.hpp:53
stk_classic::mesh::MetaData::get_field
field_type * get_field(const std::string &name) const
Get a field, return NULL if it does not exist.
stk_classic::mesh::fem::declare_element_side
Entity & declare_element_side(Entity &elem, Entity &side, const unsigned local_side_id, Part *part)
Create (or find) an element side.
Definition: FEMHelpers.cpp:104
stk_classic::mesh::MetaData::get_parts
const PartVector & get_parts() const
Query all parts of the mesh ordered by the parts' ordinal.
Definition: MetaData.hpp:120
stk_classic::mesh::put_field
field_type & put_field(field_type &field, EntityRank entity_rank, const Part &part, const void *init_value=NULL)
Declare a field to exist for a given entity type and Part.
stk_example_io
Definition: io_example.cpp:41
stk_classic::mesh::fem::FEMMetaData::get_cell_topology
fem::CellTopology get_cell_topology(const Part &part) const
Return the cell topology associated with the given part. The cell topology is set on a part through p...
Definition: FEMMetaData.cpp:239
stk_classic::mesh::fem::FEMMetaData::get
static FEMMetaData & get(const MetaData &meta)
Getter for FEMMetaData off of a MetaData object.
Definition: FEMMetaData.hpp:200
stk_example_io::process_nodesets
void process_nodesets(Ioss::Region &region, stk_classic::mesh::MetaData &meta)
Definition: io_example.cpp:439
stk_classic::io::set_distribution_factor_field
void set_distribution_factor_field(stk_classic::mesh::Part &p, const stk_classic::mesh::Field< double, stk_classic::mesh::ElementNode > &df_field)
Definition: IossBridge.cpp:1706
stk_classic::mesh::MetaData::get_fields
const FieldVector & get_fields() const
Get all defined fields.
Definition: MetaData.hpp:218
stk_classic::io::include_entity
bool include_entity(const Ioss::GroupingEntity *entity)
Definition: IossBridge.cpp:1035
stk_classic::mesh::Field
Field with defined data type and multi-dimensions (if any)
Definition: Field.hpp:118
stk_classic::mesh::MetaData::get_part
Part * get_part(const std::string &p_name, const char *required_by=NULL) const
Get an existing part by its application-defined text name.
Definition: MetaData.cpp:185
stk_classic::mesh::Part
An application-defined subset of a problem domain.
Definition: Part.hpp:49
stk_classic::mesh::fem::declare_element
Entity & declare_element(BulkData &mesh, Part &part, const EntityId elem_id, const EntityId node_id[])
Declare an element member of a Part with a CellTopology and nodes conformal to that topology.
Definition: FEMHelpers.cpp:72
stk_classic::io::field_data_from_ioss
void field_data_from_ioss(const stk_classic::mesh::FieldBase *field, std::vector< stk_classic::mesh::Entity * > &entities, Ioss::GroupingEntity *io_entity, const std::string &io_fld_name)
Definition: IossBridge.cpp:964
stk_classic::mesh::BulkData::declare_entity
Entity & declare_entity(EntityRank ent_rank, EntityId ent_id, const PartVector &parts)
Create or retrieve a locally owned entity of a given rank and id.
Definition: BulkData.cpp:215
stk_classic::parallel_machine_finalize
void parallel_machine_finalize()
parallel_machine_finalize calls MPI_Finalize.
Definition: Parallel.hpp:64
stk_classic::io::write_output_db
void write_output_db(Ioss::Region &io_region, const stk_classic::mesh::BulkData &bulk, const stk_classic::mesh::Selector *anded_selector)
Definition: IossBridge.cpp:1643
stk_classic::mesh::BulkData::change_entity_parts
void change_entity_parts(Entity &entity, const PartVector &add_parts, const PartVector &remove_parts=PartVector())
Change the parallel-locally-owned entity's part membership by adding and/or removing parts.
Definition: BulkData.hpp:249
stk_classic::mesh::MetaData::commit
void commit()
Commit the part and field declarations so that the meta data manager can be used to create mesh bulk ...
Definition: MetaData.cpp:368
stk_classic::io::default_part_processing
void default_part_processing(const std::vector< T * > &entities, stk_classic::mesh::fem::FEMMetaData &fem_meta)
Definition: IossBridge.hpp:93
stk_classic::ParallelMachine
MPI_Comm ParallelMachine
Definition: Parallel.hpp:32
stk_example_io::process_nodeblocks
void process_nodeblocks(Ioss::Region &region, stk_classic::mesh::MetaData &meta)
Definition: io_example.cpp:368
stk_classic::mesh::BulkData::get_entity
Entity * get_entity(EntityRank entity_rank, EntityId entity_id) const
Get entity with a given key.
Definition: BulkData.hpp:211
stk_classic::mesh::MetaData::declare_field
field_type & declare_field(const std::string &name, unsigned number_of_states=1)
Declare a field of the given field_type, test name, and number of states.
stk_classic::mesh::BulkData::modification_end
bool modification_end()
Parallel synchronization of modifications and transition to the guaranteed parallel consistent state.
Definition: BulkDataEndSync.cpp:729
stk_classic::io::field_data_to_ioss
void field_data_to_ioss(const stk_classic::mesh::FieldBase *field, std::vector< stk_classic::mesh::Entity * > &entities, Ioss::GroupingEntity *io_entity, const std::string &io_fld_name, Ioss::Field::RoleType filter_role)
Definition: IossBridge.cpp:999
stk_example_io::process_output_request
void process_output_request(Ioss::Region &region, stk_classic::mesh::BulkData &bulk, int step)
Definition: io_example.cpp:853
stk_classic::io::is_part_io_part
bool is_part_io_part(stk_classic::mesh::Part &part)
Definition: IossBridge.cpp:1696
stk_example_io::process_elementblocks
void process_elementblocks(Ioss::Region &region, stk_classic::mesh::MetaData &meta)
Definition: io_example.cpp:393
stk_example_io::process_sidesets
void process_sidesets(Ioss::Region &region, stk_classic::mesh::MetaData &meta)
Definition: io_example.cpp:532
stk_classic::mesh::fem::FEMMetaData::get_meta_data
static MetaData & get_meta_data(FEMMetaData &fem_meta)
Getter for MetaData off of a FEMMetaData object.
Definition: FEMMetaData.hpp:113
stk_classic::mesh::Part::primary_entity_rank
unsigned primary_entity_rank() const
The primary entity type for this part.
Definition: Part.hpp:64
stk_classic::parallel_machine_init
ParallelMachine parallel_machine_init(int *argc, char ***argv)
parallel_machine_init calls MPI_Init.
Definition: Parallel.hpp:54
stk_example_io::process_input_request
void process_input_request(Ioss::Region &region, stk_classic::mesh::BulkData &bulk, int step)
Definition: io_example.cpp:780
stk_classic::io::get_distribution_factor_field
const stk_classic::mesh::Field< double, stk_classic::mesh::ElementNode > * get_distribution_factor_field(const stk_classic::mesh::Part &p)
Definition: IossBridge.cpp:1701
stk_classic::get_options_description
boost::program_options::options_description & get_options_description()
Function get_options_description is a singleton used to store the command line option descriptions fo...
Definition: ProgramOptions.cpp:14
stk_example_io::process_surface_entity
void process_surface_entity(Ioss::SideSet *sset, stk_classic::mesh::MetaData &meta, stk_classic::mesh::EntityRank sset_rank)
Definition: io_example.cpp:479
stk_classic::mesh::BulkData::modification_begin
bool modification_begin()
Begin a modification phase during which the mesh bulk data could become parallel inconsistent....
Definition: BulkData.cpp:172
stk_classic::mesh::MetaData
The manager of an integrated collection of parts and fields.
Definition: MetaData.hpp:56
stk_classic::mesh::PartVector
std::vector< Part * > PartVector
Collections of parts are frequently maintained as a vector of Part pointers.
Definition: Types.hpp:31
stk_classic::mesh::fem::declare_element_edge
Entity & declare_element_edge(Entity &elem, Entity &edge, const unsigned local_edge_id, Part *part)
Create (or find) an element edge.
Definition: FEMHelpers.cpp:145
stk_classic::io::define_io_fields
void define_io_fields(Ioss::GroupingEntity *entity, Ioss::Field::RoleType role, stk_classic::mesh::Part &part, stk_classic::mesh::EntityRank part_type)
Definition: IossBridge.cpp:905
stk_classic::mesh::Part::name
const std::string & name() const
Application-defined text name of this part.
Definition: Part.hpp:67
stk_classic::mesh::FieldBase::name
const std::string & name() const
Application-defined text name of this field.
Definition: FieldBase.hpp:66
stk_classic::io::remove_io_part_attribute
void remove_io_part_attribute(mesh::Part &part)
Definition: IossBridge.cpp:589
stk_classic::io::is_valid_part_field
bool is_valid_part_field(const stk_classic::mesh::FieldBase *field, const stk_classic::mesh::EntityRank part_type, const stk_classic::mesh::Part &part, const stk_classic::mesh::Part &universal, const Ioss::Field::RoleType filter_role, bool add_all)
Definition: IossBridge.cpp:620
stk_classic::io::ioss_add_fields
void ioss_add_fields(const stk_classic::mesh::Part &part, const stk_classic::mesh::EntityRank part_type, Ioss::GroupingEntity *entity, const Ioss::Field::RoleType filter_role, const bool add_all)
Definition: IossBridge.cpp:868
stk_classic::io::define_output_db
void define_output_db(Ioss::Region &io_region, const mesh::BulkData &bulk_data, const Ioss::Region *input_region, const stk_classic::mesh::Selector *anded_selector, const bool sort_stk_parts)
Definition: IossBridge.cpp:1276
stk_classic::mesh::fem::FEMMetaData::element_rank
EntityRank element_rank() const
Returns the element rank which is always equal to spatial dimension.
Definition: FEMMetaData.hpp:160
stk_classic::mesh::fem::FEMMetaData
FEMMetaData is a class that implements a Finite Element Method skin on top of the Sierra Tool Kit Met...
Definition: FEMMetaData.hpp:54
stk_classic::mesh::Entity
A fundamental unit within the discretization of a problem domain, including but not limited to nodes,...
Definition: Entity.hpp:120
stk_classic::mesh::MetaData::universal_part
Part & universal_part() const
Universal subset for the problem domain. All other parts are a subset of the universal part.
Definition: MetaData.hpp:88
stk_classic::mesh::BulkData
Manager for an integrated collection of entities, entity relations, and buckets of field data.
Definition: BulkData.hpp:49
stk_classic::mesh::MetaData::declare_part_subset
void declare_part_subset(Part &superset, Part &subset)
Declare a superset-subset relationship between parts.
Definition: MetaData.cpp:240
stk_classic::BroadcastArg
Class BroadcastArg creates a copy of argc and argv after broadcasting them from processor 0.
Definition: BroadcastArg.hpp:21
stk_example_io::io_example
void io_example(stk_classic::ParallelMachine comm, const std::string &in_filename, const std::string &out_filename, const std::string &decomp_method)
Definition: io_example.cpp:162
stk_classic::get_variables_map
boost::program_options::variables_map & get_variables_map()
Function get_variabel_map is a singleton used to store the variables parsed from the line option desc...
Definition: ProgramOptions.cpp:22
stk_classic::mesh::fem::FEMMetaData::side_rank
EntityRank side_rank() const
Returns the side rank which changes depending on spatial dimension.
Definition: FEMMetaData.hpp:153