Sierra Toolkit  Version of the Day
IO_Fixture.cpp
1 #include <stk_io/util/IO_Fixture.hpp>
2 #include <stk_io/MeshReadWriteUtils.hpp>
3 
4 #include <init/Ionit_Initializer.h>
5 #include <Ioss_SubSystem.h>
6 
7 namespace stk_classic {
8 namespace io {
9 namespace util {
10 
11 IO_Fixture::IO_Fixture(stk_classic::ParallelMachine comm)
12  : m_comm(comm)
13  , m_fem_meta_data(NULL)
14  , m_bulk_data(NULL)
15  , m_ioss_input_region(NULL)
16  , m_ioss_output_region(NULL)
17  , m_mesh_type()
18  , m_mesh_data()
19 {}
20 
21 IO_Fixture::~IO_Fixture()
22 {
23  // There are duplicate pointers in the IO_Fixture class
24  // If both try to delete, bad things happen...
25  m_mesh_data.m_input_region = NULL;
26  m_mesh_data.m_output_region = NULL;
27 }
28 
29 void IO_Fixture::output_ioss_region(Teuchos::RCP<Ioss::Region> ioss_output_region) {
30  m_ioss_output_region = ioss_output_region;
31  m_mesh_data.m_output_region = m_ioss_output_region.get();
32 }
33 
34 void IO_Fixture::create_output_mesh(
35  const std::string & base_exodus_filename,
36  bool add_transient,
37  bool add_all_fields
38  )
39 {
40  // TODO: Check that the meta-data has a coordinates field and IO parts defined.
41 
42  Ioss::DatabaseIO *dbo = Ioss::IOFactory::create(
43  "exodusII",
44  base_exodus_filename,
45  Ioss::WRITE_RESULTS,
46  bulk_data().parallel()
47  );
48 
49  ThrowErrorMsgIf(dbo == NULL || !dbo->ok(),
50  "ERROR: Could not open results database '" << base_exodus_filename <<
51  "' of type 'exodusII'");
52 
53  // If the m_ioss_input_region exists for this fixture,
54  // check the integer size it is using and replicate that
55  // on the output mesh...
56  if (!Teuchos::is_null(m_ioss_input_region)) {
57  if (m_ioss_input_region->get_database()->int_byte_size_api() == 8)
58  dbo->set_int_byte_size_api(Ioss::USE_INT64_API);
59  }
60 
61  // NOTE: 'm_ioss_output_region' owns 'dbo' pointer at this time
62  const std::string name = std::string("results_output_")+base_exodus_filename;
63  m_ioss_output_region = Teuchos::rcp(new Ioss::Region(dbo, name));
64  m_mesh_data.m_output_region = m_ioss_output_region.get();
65 
66  /* Given the newly created Ioss::Region 'm_ioss_output_region', define the
67  * model corresponding to the stk_classic::mesh 'bulk_data'. If the
68  * optional 'input_region' is passed as an argument, then
69  * synchronize all names and ids found on 'input_region' to the
70  * output region 'm_ioss_output_region'. The routine will query all parts
71  * in 'bulk_data' and if they are io_parts (define by the existance
72  * of the IOPartAttribute attribute on the part), then a
73  * corresponding Ioss entity will be defined. This routine only
74  * deals with the non-transient portion of the model; no transient
75  * fields are defined at this point.
76  */
77  stk_classic::io::define_output_db( *m_ioss_output_region, bulk_data(), m_ioss_input_region.get(),
78  m_mesh_data.m_anded_selector);
79 
80  /* Given an Ioss::Region 'm_ioss_output_region' which has already had its
81  * metadata defined via 'define_output_db()' call; transfer all bulk
82  * data (node coordinates, element connectivity, ...) to the
83  * output database that corresponds to this Ioss::Region. At
84  * return, all non-transient portions of the output database will
85  * have been output.
86  */
87  stk_classic::io::write_output_db( *m_ioss_output_region, bulk_data(),
88  m_mesh_data.m_anded_selector);
89 
90  if (add_transient) {
91  m_ioss_output_region->begin_mode(Ioss::STATE_DEFINE_TRANSIENT);
92 
93  // Special processing for nodeblock (all nodes in model)...
95  meta_data().universal_part(),
96  meta_data().node_rank(),
97  m_ioss_output_region->get_node_blocks()[0],
98  Ioss::Field::TRANSIENT,
99  add_all_fields
100  );
101 
102  const stk_classic::mesh::PartVector & all_parts = meta_data().get_parts();
103  for ( stk_classic::mesh::PartVector::const_iterator ip = all_parts.begin();
104  ip != all_parts.end();
105  ++ip
106  )
107  {
108  stk_classic::mesh::Part & part = **ip;
109 
110  // Check whether this part should be output to results database.
112  // Get Ioss::GroupingEntity corresponding to this part...
113  Ioss::GroupingEntity *entity = m_ioss_output_region->get_entity(part.name());
114  if (entity != NULL && entity->type() == Ioss::ELEMENTBLOCK) {
116  part,
117  part.primary_entity_rank(),
118  entity,
119  Ioss::Field::TRANSIENT,
120  add_all_fields
121  );
122  }
123  }
124  }
125  m_ioss_output_region->end_mode(Ioss::STATE_DEFINE_TRANSIENT);
126  }
127 }
128 
129 void IO_Fixture::add_timestep_to_output_mesh( double time )
130 {
131  ThrowErrorMsgIf( Teuchos::is_null(m_ioss_output_region),
132  "Please call create_output_mesh before add_timestep_to_output_mesh" );
133  stk_classic::io::process_output_request(m_mesh_data, bulk_data(), time);
134 }
135 
136 void IO_Fixture::set_meta_data( Teuchos::RCP<stk_classic::mesh::fem::FEMMetaData> arg_meta_data )
137 {
138  ThrowErrorMsgIf( !Teuchos::is_null(m_fem_meta_data),
139  "Meta data already initialized" );
140  m_fem_meta_data = arg_meta_data;
141 }
142 
143 void IO_Fixture::set_bulk_data( Teuchos::RCP<stk_classic::mesh::BulkData> arg_bulk_data )
144 {
145  ThrowErrorMsgIf( !Teuchos::is_null(m_bulk_data),
146  "Bulk data already initialized" );
147  m_bulk_data = arg_bulk_data;
148 }
149 
150 void IO_Fixture::initialize_meta_data( const std::string & base_filename, const std::string & mesh_type)
151 {
152  ThrowErrorMsgIf( !Teuchos::is_null(m_fem_meta_data),
153  "Meta data already initialized" );
154  ThrowErrorMsgIf( !Teuchos::is_null(m_ioss_input_region),
155  "Input region was already initialized");
156 
157  m_fem_meta_data = Teuchos::rcp( new stk_classic::mesh::fem::FEMMetaData());
158  m_mesh_type = mesh_type;
159 
160  Ioss::Init::Initializer init_db;
161 
163  m_mesh_type,
164  base_filename,
165  m_comm,
166  meta_data(),
167  m_mesh_data
168  );
169 
170  // TODO: Restore this once m_mesh_data is fixed
171  m_ioss_input_region = Teuchos::rcp( m_mesh_data.m_input_region );
172 }
173 
174 void IO_Fixture::initialize_bulk_data()
175 {
176  ThrowErrorMsgIf( !Teuchos::is_null(m_bulk_data),
177  "Bulk data already initialized" );
178 
179  // TODO: Probable better to check m_ioss_input_region once that's fixed
180  ThrowErrorMsgIf( m_mesh_type == "",
181  "Can only use this method if meta-data was initialized with initialize_meta_data");
182 
183  m_bulk_data = Teuchos::rcp( new stk_classic::mesh::BulkData(stk_classic::mesh::fem::FEMMetaData::get_meta_data(meta_data()), m_comm));
184 
186  bulk_data(),
187  m_mesh_data
188  );
189 }
190 
191 void IO_Fixture::set_input_ioss_region( Teuchos::RCP<Ioss::Region> input_region )
192 {
193  ThrowErrorMsgIf( !Teuchos::is_null(m_ioss_input_region),
194  "Input region was already initialized");
195 
196  m_ioss_input_region = input_region;
197 }
198 
199 } // namespace util
200 } // namespace io
201 } // namespace stk_classic
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
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)
void populate_bulk_data(stk_classic::mesh::BulkData &bulk_data, MeshData &mesh_data)
unsigned primary_entity_rank() const
The primary entity type for this part.
Definition: Part.hpp:64
An application-defined subset of a problem domain.
Definition: Part.hpp:49
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
Manager for an integrated collection of entities, entity relations, and buckets of field data...
Definition: BulkData.hpp:49
void create_input_mesh(const std::string &mesh_type, const std::string &mesh_filename, stk_classic::ParallelMachine comm, stk_classic::mesh::fem::FEMMetaData &fem_meta, stk_classic::io::MeshData &mesh_data, bool lower_case_variable_names)
static MetaData & get_meta_data(FEMMetaData &fem_meta)
Getter for MetaData off of a FEMMetaData object.
Sierra Toolkit.
MPI_Comm ParallelMachine
Definition: Parallel.hpp:32
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
int process_output_request(MeshData &mesh_data, stk_classic::mesh::BulkData &bulk, double time, const std::set< const stk_classic::mesh::Part *> &exclude)