ErrorCode WriteVtk::write_file(const char *file_name, const bool overwrite, const FileOptions& opts, const EntityHandle *output_list, const int num_sets, const std::vector<std::string>& /* qa_list */, const Tag* tag_list, int num_tags, int /* export_dimension */) { ErrorCode rval; // Get precision for node coordinates int precision; if (MB_SUCCESS != opts.get_int_option("PRECISION", precision)) precision = DEFAULT_PRECISION; if (MB_SUCCESS == opts.get_null_option("STRICT")) mStrict = true; else if (MB_SUCCESS == opts.get_null_option("RELAXED")) mStrict = false; else mStrict = DEFAULT_STRICT; // Get entities to write Range nodes, elems; rval = gather_mesh(output_list, num_sets, nodes, elems); if (MB_SUCCESS != rval) return rval; // Honor overwrite flag if (!overwrite) { rval = writeTool->check_doesnt_exist(file_name); if (MB_SUCCESS != rval) return rval; } // Create file std::ofstream file(file_name); if (!file) { MB_SET_ERR(MB_FILE_WRITE_ERROR, "Could not open file: " << file_name); } file.precision(precision); // Write file if ((rval = write_header(file )) != MB_SUCCESS || (rval = write_nodes( file, nodes )) != MB_SUCCESS || (rval = write_elems( file, nodes, elems)) != MB_SUCCESS || (rval = write_tags ( file, true, nodes, tag_list, num_tags)) != MB_SUCCESS || (rval = write_tags ( file, false, elems, tag_list, num_tags)) != MB_SUCCESS) { file.close(); remove(file_name); return rval; } return MB_SUCCESS; }
ErrorCode ReadDamsel::parse_options(const FileOptions &opts, bool ¶llel) { // Handle parallel options std::string junk; bool use_mpio = (MB_SUCCESS == opts.get_null_option("USE_MPIO")); ErrorCode rval = opts.match_option("PARALLEL", "READ_PART"); parallel = (rval != MB_ENTITY_NOT_FOUND); nativeParallel = (rval == MB_SUCCESS); if (use_mpio && !parallel) { readMeshIface->report_error( "'USE_MPIO' option specified w/out 'PARALLEL' option" ); return MB_NOT_IMPLEMENTED; } return MB_SUCCESS; }
ErrorCode ReadCGNS::process_options(const FileOptions & opts) { // Mark all options seen, to avoid compile warning on unused variable opts.mark_all_seen(); return MB_SUCCESS; }
ErrorCode Tree::parse_common_options(FileOptions &options) { double tmp_dbl; int tmp_int; // MAX_PER_LEAF: max entities per leaf; default = 6 ErrorCode rval = options.get_int_option("MAX_PER_LEAF", tmp_int); if (MB_SUCCESS == rval) maxPerLeaf = std::max(tmp_int, 1); // MAX_DEPTH: max depth of the tree; default = 30 rval = options.get_int_option("MAX_DEPTH", tmp_int); if (MB_SUCCESS == rval) maxDepth = tmp_int; if (maxDepth < 1) maxDepth = std::numeric_limits<unsigned>::max(); // MIN_WIDTH: minimum width of box, used like a tolerance; default = 1.0e-10 rval = options.get_real_option("MIN_WIDTH", tmp_dbl); if (MB_SUCCESS == rval) minWidth = tmp_dbl; // MESHSET_FLAGS: flags passed into meshset creation for tree nodes; should be a value from // ENTITY_SET_PROPERTY (see Types.hpp); default = MESHSET_SET rval = options.get_int_option("MESHSET_FLAGS", tmp_int); if (MB_SUCCESS == rval && 0 <= tmp_int) meshsetFlags = (unsigned) tmp_int; else if (0 > tmp_int) return MB_FAILURE; // CLEAN_UP: if false, do not delete tree sets upon tree class destruction; default = true bool tmp_bool; rval = options.get_toggle_option("CLEAN_UP", true, tmp_bool); if (MB_SUCCESS == rval && !tmp_bool) cleanUp = false; // TAG_NAME: tag name to store tree information on tree nodes; default = "AKDTree" std::string tmp_str; rval = options.get_str_option("TAG_NAME", tmp_str); if (MB_SUCCESS == rval) boxTagName = tmp_str; return MB_SUCCESS; }
//! Writes out a file ErrorCode WriteGmsh::write_file(const char *file_name, const bool overwrite, const FileOptions& options, const EntityHandle *output_list, const int num_sets, const std::vector<std::string>& /* qa_list */, const Tag* /* tag_list */, int /* num_tags */, int /* export_dimension */) { ErrorCode rval; Tag global_id = 0, block_tag = 0, geom_tag = 0, prtn_tag = 0; if (!overwrite) { rval = mWriteIface->check_doesnt_exist(file_name); if (MB_SUCCESS != rval) return rval; } // Get tags mbImpl->tag_get_handle(GLOBAL_ID_TAG_NAME, 1, MB_TYPE_INTEGER, global_id); mbImpl->tag_get_handle(MATERIAL_SET_TAG_NAME, 1, MB_TYPE_INTEGER, block_tag); if (global_id) mbImpl->tag_get_handle(GEOM_DIMENSION_TAG_NAME, 1, MB_TYPE_INTEGER, geom_tag); mbImpl->tag_get_handle(PARALLEL_PARTITION_TAG_NAME, 1, MB_TYPE_INTEGER, prtn_tag); // Define arrays to hold entity sets of interest Range sets[3]; Tag set_tags[] = {block_tag, geom_tag, prtn_tag}; Tag set_ids[] = {block_tag, 0 /*global_id*/, prtn_tag}; // Get entities to write Range elements, nodes; if (!output_list) { rval = mbImpl->get_entities_by_dimension(0, 0, nodes, false); if (MB_SUCCESS != rval) return rval; for (int d = 1; d < 3; ++d) { Range tmp_range; rval = mbImpl->get_entities_by_dimension(0, d, tmp_range, false); if (MB_SUCCESS != rval) return rval; elements.merge(tmp_range); } for (int s = 0; s < 3; ++s) { if (set_tags[s]) { rval = mbImpl->get_entities_by_type_and_tag(0, MBENTITYSET, set_tags + s, 0, 1, sets[s]); if (MB_SUCCESS != rval) return rval; } } } else { for (int i = 0; i < num_sets; ++i) { EntityHandle set = output_list[i]; for (int d = 1; d < 3; ++d) { Range tmp_range, tmp_nodes; rval = mbImpl->get_entities_by_dimension(set, d, tmp_range, true); if (rval != MB_SUCCESS) return rval; elements.merge(tmp_range); rval = mbImpl->get_adjacencies(tmp_range, set, false, tmp_nodes); if (rval != MB_SUCCESS) return rval; nodes.merge(tmp_nodes); } for (int s = 0; s < 3; ++s) { if (set_tags[s]) { Range tmp_range; rval = mbImpl->get_entities_by_type_and_tag(set, MBENTITYSET, set_tags + s, 0, 1, tmp_range); if (MB_SUCCESS != rval) return rval; sets[s].merge(tmp_range); int junk; rval = mbImpl->tag_get_data(set_tags[s], &set, 1, &junk); if (MB_SUCCESS == rval) sets[s].insert(set); } } } } if (elements.empty()) { MB_SET_ERR(MB_ENTITY_NOT_FOUND, "Nothing to write"); } // Get global IDs for all elements. // First try to get from tag. If tag is not defined or not set // for all elements, use handle value instead. std::vector<int> global_id_array(elements.size()); std::vector<int>::iterator id_iter; if (!global_id || MB_SUCCESS != mbImpl->tag_get_data(global_id, elements, &global_id_array[0])) { id_iter = global_id_array.begin(); for (Range::iterator i = elements.begin(); i != elements.end(); ++i, ++id_iter) *id_iter = mbImpl->id_from_handle(*i); } // Figure out the maximum ID value so we know where to start allocating // new IDs when we encounter ID conflicts. int max_id = 0; for (id_iter = global_id_array.begin(); id_iter != global_id_array.end(); ++id_iter) if (*id_iter > max_id) max_id = *id_iter; // Initialize ElemInfo struct for each element std::map<EntityHandle, ElemInfo> elem_sets; // Per-element info std::set<int> elem_global_ids; // Temporary for finding duplicate IDs id_iter = global_id_array.begin(); // Iterate backwards to give highest-dimension entities first dibs for // a conflicting ID. for (Range::reverse_iterator i = elements.rbegin(); i != elements.rend(); ++i) { int id = *id_iter; ++id_iter; if (!elem_global_ids.insert(id).second) id = max_id++; ElemInfo& ei = elem_sets[*i]; ei.count = 0; ei.id = id; EntityType type = mbImpl->type_from_handle(*i); int num_vtx; const EntityHandle* conn; rval = mbImpl->get_connectivity(*i, conn, num_vtx); if (MB_SUCCESS != rval) return rval; ei.type = GmshUtil::get_gmsh_type(type, num_vtx); if (ei.type < 0) { MB_SET_ERR(MB_FILE_WRITE_ERROR, "Gmem file format does not support element of type " << CN::EntityTypeName(type) << " with " << num_vtx << " vertices"); } } // Don't need these any more, free memory. elem_global_ids.clear(); global_id_array.clear(); // For each material set, geometry set, or partition; store // the ID of the set on each element. for (int s = 0; s < 3; ++s) { if (!set_tags[s]) continue; for (Range::iterator i = sets[s].begin(); i != sets[s].end(); ++i) { int id; if (set_ids[s]) { rval = mbImpl->tag_get_data(set_ids[s], &*i, 1, &id); if (MB_SUCCESS != rval) return rval; } else id = mbImpl->id_from_handle(*i); Range elems; rval = mbImpl->get_entities_by_handle(*i, elems); if (MB_SUCCESS != rval) return rval; elems = intersect(elems, elements); for (Range::iterator j = elems.begin(); j != elems.end(); ++j) elem_sets[*j].set(s, id); } } // Create file std::ofstream out(file_name); if (!out) return MB_FILE_DOES_NOT_EXIST; // Write header out << "$MeshFormat" << std::endl; out << "2.0 0 " << sizeof(double) << std::endl; out << "$EndMeshFormat" << std::endl; // Set precision for node coordinates int precision; if (MB_SUCCESS != options.get_int_option("PRECISION", precision)) precision = DEFAULT_PRECISION; const int old_precision = out.precision(); out.precision(precision); // Write nodes out << "$Nodes" << std::endl; out << nodes.size() << std::endl; std::vector<double> coords(3*nodes.size()); rval = mbImpl->get_coords(nodes, &coords[0]); if (MB_SUCCESS != rval) return rval; std::vector<double>::iterator c = coords.begin(); for (Range::iterator i = nodes.begin(); i != nodes.end(); ++i) { out << mbImpl->id_from_handle(*i); out << " " << *c; ++c; out << " " << *c; ++c; out << " " << *c; ++c; out << std::endl; } out << "$EndNodes" << std::endl; coords.clear(); // Restore stream state out.precision(old_precision); // Write elements out << "$Elements" << std::endl; out << elem_sets.size() << std::endl; for (std::map<EntityHandle, ElemInfo>::iterator i = elem_sets.begin(); i != elem_sets.end(); ++i) { int num_vtx; const EntityHandle* conn; rval = mbImpl->get_connectivity(i->first, conn, num_vtx); if (MB_SUCCESS != rval) return rval; out << i->second.id << ' ' << i->second.type << ' ' << i->second.count; for (int j = 0; j < i->second.count; ++j) out << ' ' << i->second.sets[j]; const int* order = GmshUtil::gmshElemTypes[i->second.type].node_order; // Need to re-order vertices if (order) { for (int j = 0; j < num_vtx; ++j) out << ' ' << mbImpl->id_from_handle(conn[order[j]]); } else { for (int j = 0; j < num_vtx; ++j) out << ' ' << mbImpl->id_from_handle(conn[j]); } out << std::endl; } out << "$EndElements" << std::endl; // Done return MB_SUCCESS; }
ErrorCode ReadNC::parse_options(const FileOptions& opts, std::vector<std::string>& var_names, std::vector<int>& tstep_nums, std::vector<double>& tstep_vals) { int tmpval; if (MB_SUCCESS == opts.get_int_option("DEBUG_IO", 1, tmpval)) { dbgOut.set_verbosity(tmpval); dbgOut.set_prefix("NC "); } ErrorCode rval = opts.get_strs_option("VARIABLE", var_names); if (MB_TYPE_OUT_OF_RANGE == rval) noVars = true; else noVars = false; opts.get_ints_option("TIMESTEP", tstep_nums); opts.get_reals_option("TIMEVAL", tstep_vals); rval = opts.get_null_option("NOMESH"); if (MB_SUCCESS == rval) noMesh = true; rval = opts.get_null_option("SPECTRAL_MESH"); if (MB_SUCCESS == rval) spectralMesh = true; rval = opts.get_null_option("NO_MIXED_ELEMENTS"); if (MB_SUCCESS == rval) noMixedElements = true; rval = opts.get_null_option("NO_EDGES"); if (MB_SUCCESS == rval) noEdges = true; if (2 <= dbgOut.get_verbosity()) { if (!var_names.empty()) { std::cerr << "Variables requested: "; for (unsigned int i = 0; i < var_names.size(); i++) std::cerr << var_names[i]; std::cerr << std::endl; } if (!tstep_nums.empty()) { std::cerr << "Timesteps requested: "; for (unsigned int i = 0; i < tstep_nums.size(); i++) std::cerr << tstep_nums[i]; std::cerr << std::endl; } if (!tstep_vals.empty()) { std::cerr << "Time vals requested: "; for (unsigned int i = 0; i < tstep_vals.size(); i++) std::cerr << tstep_vals[i]; std::cerr << std::endl; } } rval = opts.get_int_option("GATHER_SET", 0, gatherSetRank); if (MB_TYPE_OUT_OF_RANGE == rval) { MB_SET_ERR(rval, "Invalid value for GATHER_SET option"); } rval = opts.get_int_option("TIMESTEPBASE", 0, tStepBase); if (MB_TYPE_OUT_OF_RANGE == rval) { MB_SET_ERR(rval, "Invalid value for TIMESTEPBASE option"); } rval = opts.get_int_option("TRIVIAL_PARTITION_SHIFT", 1, trivialPartitionShift); if (MB_TYPE_OUT_OF_RANGE == rval) { MB_SET_ERR(rval, "Invalid value for TRIVIAL_PARTITION_SHIFT option"); } #ifdef MOAB_HAVE_MPI isParallel = (opts.match_option("PARALLEL", "READ_PART") != MB_ENTITY_NOT_FOUND); if (!isParallel) // Return success here, since rval still has _NOT_FOUND from not finding option // in this case, myPcomm will be NULL, so it can never be used; always check for isParallel // before any use for myPcomm return MB_SUCCESS; int pcomm_no = 0; rval = opts.get_int_option("PARALLEL_COMM", pcomm_no); if (MB_TYPE_OUT_OF_RANGE == rval) { MB_SET_ERR(rval, "Invalid value for PARALLEL_COMM option"); } myPcomm = ParallelComm::get_pcomm(mbImpl, pcomm_no); if (0 == myPcomm) { myPcomm = new ParallelComm(mbImpl, MPI_COMM_WORLD); } const int rank = myPcomm->proc_config().proc_rank(); dbgOut.set_rank(rank); int dum; rval = opts.match_option("PARTITION_METHOD", ScdParData::PartitionMethodNames, dum); if (MB_FAILURE == rval) { MB_SET_ERR(rval, "Unknown partition method specified"); } else if (MB_ENTITY_NOT_FOUND == rval) partMethod = ScdParData::ALLJORKORI; else partMethod = dum; #endif return MB_SUCCESS; }
// Generic load function for both ASCII and binary. Calls // pure-virtual function implemented in subclasses to read // the data from the file. ErrorCode ReadSTL::load_file(const char* filename, const EntityHandle* /* file_set */, const FileOptions& opts, const ReaderIface::SubsetList* subset_list, const Tag* file_id_tag) { if (subset_list) { MB_SET_ERR(MB_UNSUPPORTED_OPERATION, "Reading subset of files not supported for STL"); } ErrorCode result; std::vector<ReadSTL::Triangle> triangles; bool is_ascii = false, is_binary = false; if (MB_SUCCESS == opts.get_null_option("ASCII")) is_ascii = true; if (MB_SUCCESS == opts.get_null_option("BINARY")) is_binary = true; if (is_ascii && is_binary) { MB_SET_ERR(MB_FAILURE, "Conflicting options: BINARY ASCII"); } bool big_endian = false, little_endian = false; if (MB_SUCCESS == opts.get_null_option("BIG_ENDIAN")) big_endian = true; if (MB_SUCCESS == opts.get_null_option("LITTLE_ENDIAN")) little_endian = true; if (big_endian && little_endian) { MB_SET_ERR(MB_FAILURE, "Conflicting options: BIG_ENDIAN LITTLE_ENDIAN"); } ByteOrder byte_order = big_endian ? STL_BIG_ENDIAN : little_endian ? STL_LITTLE_ENDIAN : STL_UNKNOWN_BYTE_ORDER; if (is_ascii) result = ascii_read_triangles(filename, triangles); else if (is_binary) result = binary_read_triangles(filename, byte_order, triangles); else { // Try ASCII first result = ascii_read_triangles(filename, triangles); if (MB_SUCCESS != result) // ASCII failed, try binary result = binary_read_triangles(filename, byte_order, triangles); } if (MB_SUCCESS != result) return result; // Create a std::map from position->handle, and such // that all positions are specified, and handles are zero. std::map<Point, EntityHandle> vertex_map; for (std::vector<Triangle>::iterator i = triangles.begin(); i != triangles.end(); ++i) { vertex_map[i->points[0]] = 0; vertex_map[i->points[1]] = 0; vertex_map[i->points[2]] = 0; } // Create vertices std::vector<double*> coord_arrays; EntityHandle vtx_handle = 0; result = readMeshIface->get_node_coords(3, vertex_map.size(), MB_START_ID, vtx_handle, coord_arrays); if (MB_SUCCESS != result) return result; // Copy vertex coordinates into entity sequence coordinate arrays // and copy handle into vertex_map. double *x = coord_arrays[0], *y = coord_arrays[1], *z = coord_arrays[2]; for (std::map<Point, EntityHandle>::iterator i = vertex_map.begin(); i != vertex_map.end(); ++i) { i->second = vtx_handle; ++vtx_handle; *x = i->first.coords[0]; ++x; *y = i->first.coords[1]; ++y; *z = i->first.coords[2]; ++z; } // Allocate triangles EntityHandle elm_handle = 0; EntityHandle* connectivity; result = readMeshIface->get_element_connect(triangles.size(), 3, MBTRI, MB_START_ID, elm_handle, connectivity); if (MB_SUCCESS != result) return result; // Use vertex_map to recover triangle connectivity from // vertex coordinates. EntityHandle *conn_sav = connectivity; for (std::vector<Triangle>::iterator i = triangles.begin(); i != triangles.end(); ++i) { *connectivity = vertex_map[i->points[0]]; ++connectivity; *connectivity = vertex_map[i->points[1]]; ++connectivity; *connectivity = vertex_map[i->points[2]]; ++connectivity; } // Notify MOAB of the new elements result = readMeshIface->update_adjacencies(elm_handle, triangles.size(), 3, conn_sav); if (MB_SUCCESS != result) return result; if (file_id_tag) { Range vertices(vtx_handle, vtx_handle + vertex_map.size() - 1); Range elements(elm_handle, elm_handle + triangles.size() - 1); readMeshIface->assign_ids(*file_id_tag, vertices); readMeshIface->assign_ids(*file_id_tag, elements); } return MB_SUCCESS; }