template <typename INT> std::string ExoII_Read<INT>::Close_File() { SMART_ASSERT(Check_State()); if (file_id < 0) return "ERROR: File is not open!"; int err = ex_close(file_id); if (err < 0) { std::cout << "ExoII_Read::Close_File(): ERROR " << err << ": Unable to close file! Aborting..." << '\n'; exit(1); } if (err > 0) { std::ostringstream oss; oss << "WARNING: " << err << " issued upon close"; return oss.str(); } file_id = -1; return ""; }
std::string Exo_Entity::Load_Attributes(int attr_index) { SMART_ASSERT(Check_State()); if (fileId < 0) return "exodiff: ERROR: Invalid file id!"; if (id_ == EX_INVALID_ID) return "exodiff: ERROR: Must initialize block parameters first!"; SMART_ASSERT(attr_index >= 0 && attr_index < numAttr); if (!attributes_[attr_index] && numEntity) { attributes_[attr_index] = new double[numEntity]; SMART_ASSERT(attributes_[attr_index] != nullptr); } if (numEntity) { int err = 0; err = ex_get_one_attr(fileId, exodus_type(), id_, attr_index + 1, attributes_[attr_index]); if (err < 0) { ERROR("Exo_Entity::Load_Attributes(): Call to exodus routine" << " returned error value! " << label() << " id = " << id_ << '\n' << "Aborting...\n"); exit(1); } else if (err > 0) { std::ostringstream oss; oss << "WARNING: Number " << err << " returned from call to exodus get attribute routine."; return oss.str(); } } else return std::string("WARNING: No items in this ") + label(); return ""; }
template <typename INT> void Exo_Block<INT>::Display(std::ostream &s) const { SMART_ASSERT(Check_State()); s << "Exo_Block<INT>::Display() block id = " << id_ << '\n' << " element type = " << elmt_type << '\n' << " number of elmts = " << numEntity << '\n' << " number of nodes per elmt = " << num_nodes_per_elmt << '\n' << " number of attributes = " << attr_count() << '\n' << " number of variables = " << var_count() << '\n'; if (conn) { size_t index = 0; s << " connectivity = "; for (size_t e = 0; e < numEntity; ++e) { if (e != 0) s << " "; s << "(" << (e + 1) << ") "; for (int n = 0; n < num_nodes_per_elmt; ++n) s << conn[index++] << " "; s << '\n'; } } }
std::string ExoII_Read<INT>::Global_to_Block_Local(size_t global_elmt_num, int &block_index, size_t &local_elmt_index) const { SMART_ASSERT(Check_State()); if (!Open()) return "ERROR: File not open!"; if (global_elmt_num < 1 || global_elmt_num > num_elmts) { std::ostringstream oss; oss << "ERROR: global_elmt_num = " << global_elmt_num << " is out of bounds [1, " << num_elmts << "]!"; return oss.str(); } block_index = 0; size_t total = 0; while (total + eblocks[block_index].Size() < global_elmt_num) total += eblocks[block_index++].Size(); local_elmt_index = global_elmt_num - total - 1; return ""; }
const double *Exo_Entity::Get_Attributes(int attr_index) const { SMART_ASSERT(Check_State()); SMART_ASSERT(attr_index >= 0 && attr_index < numAttr); return attributes_[attr_index]; }
std::string Exo_Entity::Load_Results(int t1, int t2, double proportion, int var_index) { static std::vector<double> results2; SMART_ASSERT(Check_State()); if (fileId < 0) return "exodiff: ERROR: Invalid file id!"; if (id_ == EX_INVALID_ID) return "exodiff: ERROR: Must initialize block parameters first!"; SMART_ASSERT(var_index >= 0 && var_index < numVars); SMART_ASSERT(t1 >= 1 && t1 <= (int)get_num_timesteps(fileId)); SMART_ASSERT(t2 >= 1 && t2 <= (int)get_num_timesteps(fileId)); if (t1 != currentStep) { Free_Results(); currentStep = t1; } if (truth_ == nullptr) { get_truth_table(); } if (truth_[var_index]) { if (!results_[var_index] && numEntity) { results_[var_index] = new double[numEntity]; SMART_ASSERT(results_[var_index] != nullptr); } if (numEntity) { int err = ex_get_var(fileId, t1, exodus_type(), var_index + 1, id_, numEntity, results_[var_index]); if (err < 0) { ERROR("Exo_Entity::Load_Results(): Call to exodus routine" << " returned error value! " << label() << " id = " << id_ << '\n' << "Aborting...\n"); exit(1); } else if (err > 0) { std::ostringstream oss; oss << "WARNING: Number " << err << " returned from call to exodus get variable routine."; return oss.str(); } if (t1 != t2) { results2.resize(numEntity); err = ex_get_var(fileId, t2, exodus_type(), var_index + 1, id_, numEntity, &results2[0]); if (err < 0) { ERROR("Exo_Entity::Load_Results(): Call to exodus routine" << " returned error value! " << label() << " id = " << id_ << '\n' << "Aborting...\n"); exit(1); } double *results1 = results_[var_index]; for (size_t i = 0; i < numEntity; i++) { results1[i] = (1.0 - proportion) * results1[i] + proportion * results2[i]; } } } else return std::string("WARNING: No items in this ") + label(); } else { return std::string("WARNING: Variable not stored in this ") + label(); } return ""; }
template <typename INT> void ExoII_Read<INT>::Display(std::ostream &s) const { SMART_ASSERT(Check_State()); const char *separator = " --------------------------------------------------"; s << "ExoII_Read::Display(): file name = " << file_name << '\n'; if (title != "") s << " title = " << title << '\n'; s << " file id = "; if (file_id >= 0) s << file_id << '\n'; else s << "(not open)" << '\n'; s << " dimension = " << dimension << '\n' << " number of nodes = " << num_nodes << '\n' << " number of elements = " << num_elmts << '\n'; if (dimension >= 1) { if (coord_names.size() >= 1) s << " first coordinate name = " << coord_names[0] << '\n'; else s << " first coordinate name = " << '\n'; } if (dimension >= 2) { if (coord_names.size() >= 2) s << " second coordinate name = " << coord_names[1] << '\n'; else s << " second coordinate name = " << '\n'; } if (dimension >= 3) { if (coord_names.size() >= 3) s << " third coordinate name = " << coord_names[2] << '\n'; else s << " third coordinate name = " << '\n'; } s << separator << '\n'; s << " number of element blocks = " << num_elmt_blocks << '\n' << " number of nodes sets = " << num_node_sets << '\n' << " number of side sets = " << num_side_sets << '\n'; if (num_elmt_blocks) { s << separator << '\n'; s << " ELEMENT BLOCKS" << '\n'; s << "\tIndex \tId num elmts nodes/elmt num attr type" << '\n'; for (size_t b = 0; b < num_elmt_blocks; ++b) { s << "\t" << b << " \t" << eblocks[b].Id() << " \t" << eblocks[b].Size() << " \t\t" << eblocks[b].num_nodes_per_elmt << " \t " << eblocks[b].attr_count() << " \t " << eblocks[b].elmt_type << '\n'; } } if (num_node_sets) { s << separator << '\n'; s << " NODE SETS " << '\n' << "\tIndex \tId length \tdistribution factors length" << '\n'; for (size_t nset = 0; nset < num_node_sets; ++nset) { s << "\t" << nset << " \t" << nsets[nset].Id() << " \t" << nsets[nset].Size() << " \t" << nsets[nset].num_dist_factors << '\n'; } } if (num_side_sets) { s << separator << '\n'; s << " SIDE SETS " << '\n' << "\tIndex \tId length \tdistribution factors length" << '\n'; for (size_t sset = 0; sset < num_side_sets; ++sset) { s << "\t" << sset << " \t" << ssets[sset].Id() << " \t" << ssets[sset].Size() << " \t" << ssets[sset].num_dist_factors << '\n'; } } if (io_word_size || db_version > 0.0 || api_version > 0.0) s << separator << '\n'; if (io_word_size) s << " file's data size = " << io_word_size << " bytes" << '\n'; if (db_version > 0.0) s << " Exodus database version = " << db_version << '\n'; if (api_version > 0.0) s << " Exodus library version = " << api_version << '\n'; s << separator << '\n'; if (nodes) { s << "\tNodal Coordinates:" << '\n'; for (size_t n = 0; n < num_nodes; ++n) { s << "\t" << (n + 1) << "\t" << nodes[n]; if (dimension > 1) s << "\t" << nodes[num_nodes + n]; if (dimension > 2) s << "\t" << nodes[num_nodes * 2 + n]; s << '\n'; } s << separator << '\n'; } if (!elmt_atts.empty()) { s << " number element attributes = " << elmt_atts.size() << '\n'; } if (num_times) { // Use this to indicate whether results data exists. s << "\t\tRESULTS INFO" << '\n' << separator << '\n'; s << " number global variables = " << global_vars.size() << '\n' << " number nodal variables = " << nodal_vars.size() << '\n' << " number element variables = " << elmt_vars.size() << '\n'; unsigned max = global_vars.size() > nodal_vars.size() ? global_vars.size() : nodal_vars.size(); max = elmt_vars.size() > max ? elmt_vars.size() : max; if (max) s << "\t GLOBAL \t NODAL \t ELEMENT" << '\n'; for (unsigned i = 0; i < max; ++i) { if (i < global_vars.size()) s << "\t " << global_vars[i]; else s << "\t "; if (i < nodal_vars.size()) s << "\t " << nodal_vars[i]; else s << "\t "; if (i < elmt_vars.size()) s << "\t " << elmt_vars[i] << '\n'; else s << '\n'; } s << separator << '\n'; s << " number of times = " << num_times << '\n'; for (int t = 0; t < num_times; ++t) s << "\t\t(" << (t + 1) << ") " << times[t] << '\n'; } }
template <typename INT> void ExoII_Read<INT>::Free_Nodal_Coordinates() { SMART_ASSERT(Check_State()); delete[] nodes; nodes = nullptr; }
template <typename INT> size_t ExoII_Read<INT>::Block_Id(size_t block_index) const { SMART_ASSERT(Check_State()); SMART_ASSERT(block_index >= 0 && block_index < num_elmt_blocks); return eblocks[block_index].Id(); }
Exo_Block<INT> *ExoII_Read<INT>::Get_Elmt_Block_by_Index(size_t block_index) const { SMART_ASSERT(Check_State()); SMART_ASSERT(block_index < num_elmt_blocks); return &eblocks[block_index]; }
template <typename INT> const std::string &ExoII_Read<INT>::SS_Var_Name(int index) const { SMART_ASSERT(Check_State()); SMART_ASSERT(index >= 0 && (unsigned)index < ss_vars.size()); return ss_vars[index]; }
template <typename INT> const std::string &ExoII_Read<INT>::Elmt_Att_Name(int index) const { SMART_ASSERT(Check_State()); SMART_ASSERT(index >= 0 && (unsigned)index < elmt_atts.size()); return elmt_atts[index]; }
template <typename INT> double ExoII_Read<INT>::Time(int time_num) const { SMART_ASSERT(Check_State()); SMART_ASSERT(time_num > 0 && time_num <= num_times)(time_num)(num_times); return times[time_num - 1]; }
template <typename INT> void ExoII_Read<INT>::Get_Init_Data() { SMART_ASSERT(Check_State()); SMART_ASSERT(file_id >= 0); // Determine max size of entity and variable names on the database int name_length = ex_inquire_int(file_id, EX_INQ_DB_MAX_USED_NAME_LENGTH); ex_set_max_name_length(file_id, name_length); ex_init_params info; info.title[0] = '\0'; int err = ex_get_init_ext(file_id, &info); if (err < 0) { std::cout << "EXODIFF ERROR: Failed to get init data!" << " Error number = " << err << ". Aborting..." << '\n'; exit(1); } dimension = info.num_dim; num_nodes = info.num_nodes; num_elmts = info.num_elem; num_elmt_blocks = info.num_elem_blk; num_node_sets = info.num_node_sets; num_side_sets = info.num_side_sets; title = info.title; if (err > 0 && !interface.quiet_flag) std::cout << "EXODIFF WARNING: was issued, number = " << err << '\n'; if (dimension < 1 || dimension > 3 || num_elmt_blocks < 0 || num_node_sets < 0 || num_side_sets < 0) { std::cout << "EXODIFF ERROR: Init data appears corrupt:" << '\n' << " dimension = " << dimension << '\n' << " num_nodes = " << num_nodes << '\n' << " num_elmts = " << num_elmts << '\n' << " num_elmt_blocks = " << num_elmt_blocks << '\n' << " num_node_sets = " << num_node_sets << '\n' << " num_side_sets = " << num_side_sets << '\n' << " ... Aborting..." << '\n'; exit(1); } int num_qa = ex_inquire_int(file_id, EX_INQ_QA); int num_info = ex_inquire_int(file_id, EX_INQ_INFO); if (num_qa < 0 || num_info < 0) { std::cout << "EXODIFF ERROR: inquire data appears corrupt:" << '\n' << " num_qa = " << num_qa << '\n' << " num_info = " << num_info << '\n' << " ... Aborting..." << '\n'; exit(1); } // Coordinate Names... char **coords = get_name_array(3, name_length); err = ex_get_coord_names(file_id, coords); if (err < 0) { std::cout << "EXODIFF ERROR: Failed to get coordinate" << " names! Aborting..." << '\n'; exit(1); } coord_names.clear(); for (size_t i = 0; i < dimension; ++i) { coord_names.push_back(coords[i]); } free_name_array(coords, 3); // Element Block Data... if (eblocks) delete[] eblocks; eblocks = nullptr; if (num_elmt_blocks > 0) { eblocks = new Exo_Block<INT>[num_elmt_blocks]; SMART_ASSERT(eblocks != nullptr); std::vector<INT> ids(num_elmt_blocks); err = ex_get_ids(file_id, EX_ELEM_BLOCK, TOPTR(ids)); if (err < 0) { std::cout << "EXODIFF ERROR: Failed to get element" << " block ids! Aborting..." << '\n'; exit(1); } size_t e_count = 0; for (size_t b = 0; b < num_elmt_blocks; ++b) { if (ids[b] <= EX_INVALID_ID) { std::cout << "EXODIFF WARNING: Element block Id " << "for block index " << b << " is " << ids[b] << " which is negative. This was returned by call to ex_get_elem_blk_ids()." << '\n'; } eblocks[b].initialize(file_id, ids[b]); e_count += eblocks[b].Size(); } if (e_count != num_elmts && !interface.quiet_flag) { std::cout << "EXODIFF WARNING: Total number of elements " << num_elmts << " does not equal the sum of the number of elements " << "in each block " << e_count << '\n'; } // Gather the attribute names (even though not all attributes are on all blocks) std::set<std::string> names; for (size_t b = 0; b < num_elmt_blocks; ++b) { for (int a = 0; a < eblocks[b].attr_count(); a++) { names.insert(eblocks[b].Get_Attribute_Name(a)); } } elmt_atts.resize(names.size()); std::copy(names.begin(), names.end(), elmt_atts.begin()); } // Node & Side sets... if (nsets) delete[] nsets; nsets = nullptr; if (num_node_sets > 0) { nsets = new Node_Set<INT>[num_node_sets]; SMART_ASSERT(nsets != nullptr); std::vector<INT> ids(num_node_sets); err = ex_get_ids(file_id, EX_NODE_SET, TOPTR(ids)); if (err < 0) { std::cout << "EXODIFF ERROR: Failed to get " << "nodeset ids! Aborting..." << '\n'; exit(1); } for (size_t nset = 0; nset < num_node_sets; ++nset) { if (ids[nset] <= EX_INVALID_ID) { std::cout << "EXODIFF WARNING: Nodeset Id " << "for nodeset index " << nset << " is " << ids[nset] << " which is negative. This was returned by call to ex_get_ids()." << '\n'; } nsets[nset].initialize(file_id, ids[nset]); } } if (ssets) delete[] ssets; ssets = nullptr; if (num_side_sets) { ssets = new Side_Set<INT>[num_side_sets]; SMART_ASSERT(ssets != nullptr); std::vector<INT> ids(num_side_sets); err = ex_get_ids(file_id, EX_SIDE_SET, TOPTR(ids)); if (err < 0) { std::cout << "EXODIFF ERROR: Failed to get " << "sideset ids! Aborting..." << '\n'; exit(1); } for (size_t sset = 0; sset < num_side_sets; ++sset) { if (ids[sset] <= EX_INVALID_ID) { std::cout << "EXODIFF WARNING: Sideset Id " << "for sideset index " << sset << " is " << ids[sset] << " which is negative. This was returned by call to ex_get_ids()." << '\n'; } ssets[sset].initialize(file_id, ids[sset]); } } // ************** RESULTS info *************** // int num_global_vars, num_nodal_vars, num_elmt_vars, num_ns_vars, num_ss_vars; err = ex_get_variable_param(file_id, EX_GLOBAL, &num_global_vars); if (err < 0) { std::cout << "EXODIFF ERROR: Failed to get number of" << " global variables! Aborting..." << '\n'; exit(1); } err = ex_get_variable_param(file_id, EX_NODAL, &num_nodal_vars); if (err < 0) { std::cout << "EXODIFF ERROR: Failed to get number of" << " nodal variables! Aborting..." << '\n'; exit(1); } err = ex_get_variable_param(file_id, EX_ELEM_BLOCK, &num_elmt_vars); if (err < 0) { std::cout << "EXODIFF ERROR: Failed to get number of" << " element variables! Aborting..." << '\n'; exit(1); } err = ex_get_variable_param(file_id, EX_NODE_SET, &num_ns_vars); if (err < 0) { std::cout << "EXODIFF ERROR: Failed to get number of" << " nodeset variables! Aborting..." << '\n'; exit(1); } err = ex_get_variable_param(file_id, EX_SIDE_SET, &num_ss_vars); if (err < 0) { std::cout << "EXODIFF ERROR: Failed to get number of" << " sideset variables! Aborting..." << '\n'; exit(1); } if (num_global_vars < 0 || num_nodal_vars < 0 || num_elmt_vars < 0 || num_ns_vars < 0 || num_ss_vars < 0) { std::cout << "EXODIFF ERROR: Data appears corrupt for" << " number of variables !" << '\n' << "\tnum global vars = " << num_global_vars << '\n' << "\tnum nodal vars = " << num_nodal_vars << '\n' << "\tnum element vars = " << num_elmt_vars << '\n' << " ... Aborting..." << '\n'; exit(1); } read_vars(file_id, EX_GLOBAL, "Global", num_global_vars, global_vars); read_vars(file_id, EX_NODAL, "Nodal", num_nodal_vars, nodal_vars); read_vars(file_id, EX_ELEM_BLOCK, "Element", num_elmt_vars, elmt_vars); read_vars(file_id, EX_NODE_SET, "Nodeset", num_ns_vars, ns_vars); read_vars(file_id, EX_SIDE_SET, "Sideset", num_ss_vars, ss_vars); // Times: num_times = ex_inquire_int(file_id, EX_INQ_TIME); if (num_times < 0) { std::cout << "EXODIFF ERROR: Number of time steps came" << " back negative (" << num_times << ")! Aborting..." << '\n'; exit(1); } if ((num_global_vars > 0 || num_nodal_vars > 0 || num_elmt_vars > 0 || num_ns_vars > 0 || num_ss_vars > 0) && num_times == 0) { std::cout << "EXODIFF Consistency error -- The database contains transient variables, but no " "timesteps!" << '\n'; exit(1); } if (num_times) { times = new double[num_times]; SMART_ASSERT(times != nullptr); err = ex_get_all_times(file_id, times); } if (num_nodal_vars) { if (num_times == 0) { std::cout << "EXODIFF Consistency error--The database contains " << num_nodal_vars << " nodal variables, but there are no time steps defined." << '\n'; } if (num_times) { results = new double *[num_nodal_vars]; for (int i = 0; i < num_nodal_vars; ++i) results[i] = nullptr; } } } // End of EXODIFF