Sierra Toolkit Version of the Day
IO_Fixture.cpp
00001 #include <stk_io/util/IO_Fixture.hpp>
00002 #include <stk_io/MeshReadWriteUtils.hpp>
00003 
00004 #include <init/Ionit_Initializer.h>
00005 #include <Ioss_SubSystem.h>
00006 
00007 namespace stk {
00008 namespace io {
00009 namespace util {
00010 
00011 IO_Fixture::IO_Fixture(stk::ParallelMachine comm)
00012   : m_comm(comm)
00013   , m_fem_meta_data(NULL)
00014   , m_bulk_data(NULL)
00015   , m_ioss_input_region(NULL)
00016   , m_ioss_output_region(NULL)
00017   , m_mesh_type()
00018   , m_mesh_data()
00019 {}
00020 
00021 IO_Fixture::~IO_Fixture()
00022 {
00023   // There are duplicate pointers in the IO_Fixture class
00024   // If both try to delete, bad things happen...
00025   m_mesh_data.m_input_region = NULL;
00026   m_mesh_data.m_output_region = NULL;
00027 }
00028 
00029 void IO_Fixture::output_ioss_region(Teuchos::RCP<Ioss::Region> ioss_output_region) {
00030   m_ioss_output_region = ioss_output_region;
00031   m_mesh_data.m_output_region = m_ioss_output_region.get();
00032 }
00033 
00034 void IO_Fixture::create_output_mesh(
00035                                     const std::string & base_exodus_filename,
00036                                     bool  add_transient,
00037                                     bool  add_all_fields
00038                                    )
00039 {
00040   // TODO: Check that the meta-data has a coordinates field and IO parts defined.
00041 
00042   Ioss::DatabaseIO *dbo = Ioss::IOFactory::create(
00043       "exodusII",
00044       base_exodus_filename,
00045       Ioss::WRITE_RESULTS,
00046       bulk_data().parallel()
00047       );
00048 
00049   ThrowErrorMsgIf(dbo == NULL || !dbo->ok(),
00050       "ERROR: Could not open results database '" << base_exodus_filename <<
00051       "' of type 'exodusII'");
00052 
00053   // If the m_ioss_input_region exists for this fixture,
00054   // check the integer size it is using and replicate that
00055   // on the output mesh...
00056   if (!Teuchos::is_null(m_ioss_input_region)) {
00057     if (m_ioss_input_region->get_database()->int_byte_size_api() == 8)
00058       dbo->set_int_byte_size_api(Ioss::USE_INT64_API);
00059   }
00060 
00061   // NOTE: 'm_ioss_output_region' owns 'dbo' pointer at this time
00062   const std::string name = std::string("results_output_")+base_exodus_filename;
00063   m_ioss_output_region = Teuchos::rcp(new Ioss::Region(dbo, name));
00064   m_mesh_data.m_output_region = m_ioss_output_region.get();
00065 
00066   /* Given the newly created Ioss::Region 'm_ioss_output_region', define the
00067    * model corresponding to the stk::mesh 'bulk_data'.  If the
00068    * optional 'input_region' is passed as an argument, then
00069    * synchronize all names and ids found on 'input_region' to the
00070    * output region 'm_ioss_output_region'.  The routine will query all parts
00071    * in 'bulk_data' and if they are io_parts (define by the existance
00072    * of the IOPartAttribute attribute on the part), then a
00073    * corresponding Ioss entity will be defined.  This routine only
00074    * deals with the non-transient portion of the model; no transient
00075    * fields are defined at this point.
00076    */
00077   stk::io::define_output_db( *m_ioss_output_region, bulk_data(), m_ioss_input_region.get(),
00078            m_mesh_data.m_anded_selector);
00079 
00080   /* Given an Ioss::Region 'm_ioss_output_region' which has already had its
00081    * metadata defined via 'define_output_db()' call; transfer all bulk
00082    * data (node coordinates, element connectivity, ...) to the
00083    * output database that corresponds to this Ioss::Region. At
00084    * return, all non-transient portions of the output database will
00085    * have been output.
00086    */
00087   stk::io::write_output_db( *m_ioss_output_region, bulk_data(),
00088           m_mesh_data.m_anded_selector);
00089 
00090   if (add_transient) {
00091     m_ioss_output_region->begin_mode(Ioss::STATE_DEFINE_TRANSIENT);
00092 
00093     // Special processing for nodeblock (all nodes in model)...
00094     stk::io::ioss_add_fields(
00095                               meta_data().universal_part(),
00096                               meta_data().node_rank(),
00097                               m_ioss_output_region->get_node_blocks()[0],
00098                               Ioss::Field::TRANSIENT,
00099                               add_all_fields
00100                             );
00101 
00102     const stk::mesh::PartVector & all_parts = meta_data().get_parts();
00103     for ( stk::mesh::PartVector::const_iterator ip = all_parts.begin();
00104           ip != all_parts.end();
00105           ++ip
00106         )
00107     {
00108       stk::mesh::Part & part = **ip;
00109 
00110       // Check whether this part should be output to results database.
00111       if (stk::io::is_part_io_part(part)) {
00112         // Get Ioss::GroupingEntity corresponding to this part...
00113         Ioss::GroupingEntity *entity = m_ioss_output_region->get_entity(part.name());
00114         if (entity != NULL && entity->type() == Ioss::ELEMENTBLOCK) {
00115           stk::io::ioss_add_fields(
00116                                     part,
00117                                     part.primary_entity_rank(),
00118                                     entity,
00119                                     Ioss::Field::TRANSIENT,
00120                                     add_all_fields
00121                                   );
00122         }
00123       }
00124     }
00125     m_ioss_output_region->end_mode(Ioss::STATE_DEFINE_TRANSIENT);
00126   }
00127 }
00128 
00129 void IO_Fixture::add_timestep_to_output_mesh( double time )
00130 {
00131   ThrowErrorMsgIf( Teuchos::is_null(m_ioss_output_region),
00132                    "Please call create_output_mesh before add_timestep_to_output_mesh" );
00133   stk::io::process_output_request(m_mesh_data, bulk_data(), time);
00134 }
00135 
00136 void IO_Fixture::set_meta_data( Teuchos::RCP<stk::mesh::fem::FEMMetaData> arg_meta_data )
00137 {
00138   ThrowErrorMsgIf( !Teuchos::is_null(m_fem_meta_data),
00139                    "Meta data already initialized" );
00140   m_fem_meta_data = arg_meta_data;
00141 }
00142 
00143 void IO_Fixture::set_bulk_data( Teuchos::RCP<stk::mesh::BulkData> arg_bulk_data )
00144 {
00145   ThrowErrorMsgIf( !Teuchos::is_null(m_bulk_data),
00146                    "Bulk data already initialized" );
00147   m_bulk_data = arg_bulk_data;
00148 }
00149 
00150 void IO_Fixture::initialize_meta_data( const std::string & base_filename, const std::string & mesh_type)
00151 {
00152   ThrowErrorMsgIf( !Teuchos::is_null(m_fem_meta_data),
00153                    "Meta data already initialized" );
00154   ThrowErrorMsgIf( !Teuchos::is_null(m_ioss_input_region),
00155                    "Input region was already initialized");
00156 
00157   m_fem_meta_data = Teuchos::rcp( new stk::mesh::fem::FEMMetaData());
00158   m_mesh_type = mesh_type;
00159 
00160   Ioss::Init::Initializer init_db;
00161 
00162   stk::io::create_input_mesh(
00163            m_mesh_type,
00164            base_filename,
00165            m_comm,
00166            meta_data(),
00167            m_mesh_data
00168            );
00169 
00170   // TODO: Restore this once m_mesh_data is fixed
00171   m_ioss_input_region = Teuchos::rcp( m_mesh_data.m_input_region );
00172 }
00173 
00174 void IO_Fixture::initialize_bulk_data()
00175 {
00176   ThrowErrorMsgIf( !Teuchos::is_null(m_bulk_data),
00177                    "Bulk data already initialized" );
00178 
00179   // TODO: Probable better to check m_ioss_input_region once that's fixed
00180   ThrowErrorMsgIf( m_mesh_type == "",
00181     "Can only use this method if meta-data was initialized with initialize_meta_data");
00182 
00183   m_bulk_data = Teuchos::rcp( new stk::mesh::BulkData(stk::mesh::fem::FEMMetaData::get_meta_data(meta_data()), m_comm));
00184 
00185   stk::io::populate_bulk_data(
00186             bulk_data(),
00187             m_mesh_data
00188             );
00189 }
00190 
00191 void IO_Fixture::set_input_ioss_region( Teuchos::RCP<Ioss::Region> input_region )
00192 {
00193   ThrowErrorMsgIf( !Teuchos::is_null(m_ioss_input_region),
00194                    "Input region was already initialized");
00195 
00196   m_ioss_input_region = input_region;
00197 }
00198 
00199 } // namespace util
00200 } // namespace io
00201 } // namespace stk
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines