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 
void write_output_db(Ioss::Region &io_region, const stk_classic::mesh::BulkData &bulk, const stk_classic::mesh::Selector *anded_selector)
FEMMetaData is a class that implements a Finite Element Method skin on top of the Sierra Tool Kit Met...
Definition: FEMMetaData.hpp:54
Field base class with an anonymous data type and anonymous multi-dimension.
Definition: FieldBase.hpp:53
The manager of an integrated collection of parts and fields.
Definition: MetaData.hpp:56
void declare_part_subset(Part &superset, Part &subset)
Declare a superset-subset relationship between parts.
Definition: MetaData.cpp:240
Class BroadcastArg creates a copy of argc and argv after broadcasting them from processor 0...
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
EntityRank side_rank() const
Returns the side rank which changes depending on spatial dimension.
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
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)
EntityRank element_rank() const
Returns the element rank which is always equal to spatial dimension.
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
unsigned primary_entity_rank() const
The primary entity type for this part.
Definition: Part.hpp:64
const FieldVector & get_fields() const
Get all defined fields.
Definition: MetaData.hpp:218
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.
bool include_entity(const Ioss::GroupingEntity *entity)
void process_input_request(Ioss::Region &region, stk_classic::mesh::BulkData &bulk, int step)
Definition: io_example.cpp:780
Entity * get_entity(EntityRank entity_rank, EntityId entity_id) const
Get entity with a given key.
Definition: BulkData.hpp:211
void process_elementblocks(Ioss::Region &region, stk_classic::mesh::MetaData &meta)
Definition: io_example.cpp:393
Field with defined data type and multi-dimensions (if any)
Definition: Field.hpp:118
void process_nodeblocks(Ioss::Region &region, stk_classic::mesh::MetaData &meta)
Definition: io_example.cpp:368
An application-defined subset of a problem domain.
Definition: Part.hpp:49
void process_sidesets(Ioss::Region &region, stk_classic::mesh::MetaData &meta)
Definition: io_example.cpp:532
void default_part_processing(const std::vector< T *> &entities, stk_classic::mesh::fem::FEMMetaData &fem_meta)
Definition: IossBridge.hpp:93
void change_entity_parts(Entity &entity, const PartVector &add_parts, const PartVector &remove_parts=PartVector())
Change the parallel-locally-owned entity&#39;s part membership by adding and/or removing parts...
Definition: BulkData.hpp:249
Part & universal_part() const
Universal subset for the problem domain. All other parts are a subset of the universal part...
Definition: MetaData.hpp:88
boost::program_options::options_description & get_options_description()
Function get_options_description is a singleton used to store the command line option descriptions fo...
bool modification_end()
Parallel synchronization of modifications and transition to the guaranteed parallel consistent state...
bool modification_begin()
Begin a modification phase during which the mesh bulk data could become parallel inconsistent. This is a parallel synchronous call. The first time this method is called the mesh meta data is verified to be committed and parallel consistent. An exception is thrown if this verification fails.
Definition: BulkData.cpp:172
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
bool is_part_io_part(stk_classic::mesh::Part &part)
const std::string & name() const
Application-defined text name of this part.
Definition: Part.hpp:67
void process_output_request(Ioss::Region &region, stk_classic::mesh::BulkData &bulk, int step)
Definition: io_example.cpp:853
const stk_classic::mesh::Field< double, stk_classic::mesh::ElementNode > * get_distribution_factor_field(const stk_classic::mesh::Part &p)
Manager for an integrated collection of entities, entity relations, and buckets of field data...
Definition: BulkData.hpp:49
const std::string & name() const
Application-defined text name of this field.
Definition: FieldBase.hpp:66
static MetaData & get_meta_data(FEMMetaData &fem_meta)
Getter for MetaData off of a FEMMetaData object.
void process_surface_entity(Ioss::SideSet *sset, stk_classic::mesh::MetaData &meta, stk_classic::mesh::EntityRank sset_rank)
Definition: io_example.cpp:479
void parallel_machine_finalize()
parallel_machine_finalize calls MPI_Finalize.
Definition: Parallel.hpp:64
A fundamental unit within the discretization of a problem domain, including but not limited to nodes...
Definition: Entity.hpp:120
const PartVector & get_parts() const
Query all parts of the mesh ordered by the parts&#39; ordinal.
Definition: MetaData.hpp:120
MPI_Comm ParallelMachine
Definition: Parallel.hpp:32
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
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
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...
ParallelMachine parallel_machine_init(int *argc, char ***argv)
parallel_machine_init calls MPI_Init.
Definition: Parallel.hpp:54
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
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.
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
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
std::vector< Part *> PartVector
Collections of parts are frequently maintained as a vector of Part pointers.
Definition: Types.hpp:31
static FEMMetaData & get(const MetaData &meta)
Getter for FEMMetaData off of a MetaData object.
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
void process_nodesets(Ioss::Region &region, stk_classic::mesh::MetaData &meta)
Definition: io_example.cpp:439
field_type * get_field(const std::string &name) const
Get a field, return NULL if it does not exist.
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
void remove_io_part_attribute(mesh::Part &part)
Definition: IossBridge.cpp:589
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
void set_distribution_factor_field(stk_classic::mesh::Part &p, const stk_classic::mesh::Field< double, stk_classic::mesh::ElementNode > &df_field)
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...