ErrorCode ReadNC::read_header() { dbgOut.tprint(1, "Reading header...\n"); // Get the global attributes int numgatts; int success; success = NCFUNC(inq_natts )(fileId, &numgatts); if (success) MB_SET_ERR(MB_FAILURE, "Couldn't get number of global attributes"); // Read attributes into globalAtts ErrorCode result = get_attributes(NC_GLOBAL, numgatts, globalAtts);MB_CHK_SET_ERR(result, "Trouble getting global attributes"); dbgOut.tprintf(1, "Read %u attributes\n", (unsigned int) globalAtts.size()); // Read in dimensions into dimNames and dimLens result = get_dimensions(fileId, dimNames, dimLens);MB_CHK_SET_ERR(result, "Trouble getting dimensions"); dbgOut.tprintf(1, "Read %u dimensions\n", (unsigned int) dimNames.size()); // Read in variables into varInfo result = get_variables();MB_CHK_SET_ERR(result, "Trouble getting variables"); dbgOut.tprintf(1, "Read %u variables\n", (unsigned int) varInfo.size()); return MB_SUCCESS; }
ErrorCode SpectralMeshTool::create_spectral_elems(const T *conn, int num_fine_elems, int dim, Range &output_range, int start_idx, Range *local_gids) { assert(spectralOrder && num_fine_elems); // now create num_coarse_elems // compute the number of local elems, accounting for coarse or fine representation // spectral_unit is the # fine elems per coarse elem, or spectralOrder^2 int spectral_unit = spectralOrder*spectralOrder; int num_coarse_elems = num_fine_elems / spectral_unit; EntityHandle *new_conn; EntityHandle start_elem; ReadUtilIface *rmi; ErrorCode rval = mbImpl->query_interface(rmi); if (MB_SUCCESS != rval) return rval; int verts_per_felem = spectralOrderp1*spectralOrderp1, verts_per_celem = std::pow((double)2.0, dim); rval = rmi->get_element_connect(num_coarse_elems, verts_per_celem, (2 == dim ? MBQUAD : MBHEX), 0, start_elem, new_conn);MB_CHK_SET_ERR(rval, "Failed to create elems"); output_range.insert(start_elem, start_elem + num_coarse_elems - 1); // read connectivity into that space // permute_array takes a 4*order^2-long vector of integers, representing the connectivity of order^2 // elems (fine elems in a coarse elem), and picks out the ids of the vertices necessary // to get a lexicographically-ordered array of vertices in a spectral element of that order //assert(verts_per_felem == (sizeof(permute_array)/sizeof(unsigned int))); // we're assuming here that elems was empty on input int count; EntityHandle *sv_ptr = NULL; rval = mbImpl->tag_iterate(spectral_vertices_tag(true), output_range.begin(), output_range.end(), count, (void*&)sv_ptr);MB_CHK_SET_ERR(rval, "Failed to get SPECTRAL_VERTICES ptr"); assert(count == num_coarse_elems); int f = start_idx, fs = 0, fl = 0; for (int c = 0; c < num_coarse_elems; c++) { for (int i = 0; i < verts_per_celem; i++) new_conn[fl+i] = conn[f+lin_permute_array[i]]; fl += verts_per_celem; for (int i = 0; i < verts_per_felem; i++) sv_ptr[fs+i] = conn[f+permute_array[i]]; f += verts_per_celem*spectral_unit; fs += verts_per_felem; } if (local_gids) std::copy(sv_ptr, sv_ptr+verts_per_felem*num_coarse_elems, range_inserter(*local_gids)); return MB_SUCCESS; }
moab::ErrorCode test_hv_cube_mesh( double A_f, double valence, double &ray_fire_time, double worst_split_ratio ) { std::cout << "TESTING MESH - Valence: " << valence << " Area Fraction: " << A_f << std::endl; prep_mesh( A_f, valence); ////////////// START OF MOAB STUFF \\\\\\\\\\\\\\\\\\\\\\\ \ moab::OrientedBoxTreeTool::Settings settings; settings.max_leaf_entities = 8; settings.max_depth = 0; settings.worst_cost = worst_split_ratio; settings.best_cost = 0.4; settings.set_options = MESHSET_SET; //now we'll try to load this mesh-file into a dagmc instance moab::DagMC *dag = new moab::DagMC( mbi ); moab::ErrorCode result; //load the mesh data from the moab instance into dag result = dag->load_existing_contents(); if( MB_SUCCESS != result) return MB_FAILURE; result = dag->setup_impl_compl(); MB_CHK_SET_ERR(result, "Could not setup implicit compliment."); moab::Range surfs,vols; result = dag->setup_geometry(surfs,vols); MB_CHK_SET_ERR(result,"Failed to setup the geometry."); // build obbs result = build_obbs(dag,surfs,vols,settings); MB_CHK_SET_ERR(result, "Failed to setup the OBBs"); // setup indices result = dag->setup_indices(); MB_CHK_SET_ERR(result, "Failed to setup problem indices"); //analyze mesh here double avg_fire_time; CartVect source; source[0] = 0; source [1] = 0; source [2] = 0; //call into the new functions for firing random rays and get the avg time fire_rand_rays( dag, vols[0], 100000, avg_fire_time, source); //write time to data file mbi->write_mesh("hvcube.h5m"); std::cout << "The average fire time for this mesh was: " << avg_fire_time << "s" << std::endl; ray_fire_time = avg_fire_time; mbi->delete_mesh(); return MB_SUCCESS; }
ErrorCode ReadCGNS::create_sets(char *sectionName, const Tag *file_id_tag, EntityType /*element_type*/, const Range& elements, const std::vector<int>& set_ids, int /*set_type*/) { ErrorCode result; result = mbImpl->tag_set_data(globalId, elements, &set_ids[0]); if (MB_SUCCESS != result) return result; if (file_id_tag) { result = mbImpl->tag_set_data(*file_id_tag, elements, &set_ids[0]); if (MB_SUCCESS != result) return result; } result = MB_SUCCESS; EntityHandle set_handle; Tag tag_handle; const char* setName = sectionName; mbImpl->tag_get_handle(setName, 1, MB_TYPE_INTEGER, tag_handle, MB_TAG_SPARSE | MB_TAG_CREAT); // Create set result = mbImpl->create_meshset(MESHSET_SET, set_handle);MB_CHK_SET_ERR(result, fileName << ": Trouble creating set"); //// Add dummy values to current set //std::vector<int> tags(set_ids.size(), 1); //result = mbImpl->tag_set_data(tag_handle, elements, &tags[0]); //if (MB_SUCCESS != result) return result; // Add them to the set result = mbImpl->add_entities(set_handle, elements);MB_CHK_SET_ERR(result, fileName << ": Trouble putting entities in set"); return MB_SUCCESS; }
//! Read/create sets ErrorCode ReadTemplate::create_sets(int num_sets, EntityHandle /*start_vertex*/, int /*num_verts*/, EntityHandle /*start_elem*/, int /*num_elems*/, Range &read_ents) { ErrorCode result = MB_SUCCESS; EntityHandle this_set; for (int i = 0; i < num_sets; i++) { // Create set result = mbImpl->create_meshset(MESHSET_SET, this_set);MB_CHK_SET_ERR(result, fileName << ": Trouble creating set"); Range set_ents; // Read/compute what's in this set; REMEMBER TO CONVERT THESE TO MOAB HANDLES // Add them to the set result = mbImpl->add_entities(this_set, set_ents);MB_CHK_SET_ERR(result, fileName << ": Trouble putting entities in set"); // Add the new set to read_ents read_ents.insert(this_set); } return MB_SUCCESS; }
//! Read/create elements ErrorCode ReadTemplate::read_elements(int num_elems, EntityHandle start_vertex, EntityHandle &start_elem, Range &read_ents) { // Get the entity type being read EntityType ent_type = MBHEX; // Get the number of vertices per entity int verts_per_elem = 8; // Create the element sequence; passes back a pointer to the internal storage for connectivity and the // starting entity handle EntityHandle* conn_array; ErrorCode result = readMeshIface->get_element_connect(num_elems, verts_per_elem, ent_type, 1, start_elem, conn_array);MB_CHK_SET_ERR(result, fileName << ": Trouble reading elements"); // Read connectivity into conn_array directly for (long i = 0; i < num_elems; i++) { // Read connectivity } // Convert file-based connectivity indices to vertex handles in-place; be careful, if indices are smaller than handles, // need to do from the end of the list so we don't overwrite data // // Here, we assume indices are smaller than handles, just for demonstration; create an integer-type pointer to connectivity // initialized to same start of connectivity array int *ind_array = reinterpret_cast<int*>(conn_array); // OFFSET is value of first vertex index in file; most files are 1-based, but some might be 0-based int OFFSET = 1; for (long i = num_elems*verts_per_elem - 1; i >= 0; i--) { conn_array[i] = ind_array[i] + start_vertex + OFFSET; // This assert assumes last handle in read_ents is highest vertex handle in this file assert(conn_array[i] >= start_vertex && conn_array[i] <= *read_ents.rbegin()); } // Notify MOAB of the new elements result = readMeshIface->update_adjacencies(start_elem, num_elems, verts_per_elem, conn_array); if (MB_SUCCESS != result) return result; // Add elements to read_ents if (num_elems) read_ents.insert(start_elem, start_elem + num_elems - 1); return MB_SUCCESS; }
ErrorCode ReadCGNS::create_elements(char *sectionName, const Tag *file_id_tag, const EntityType &ent_type, const int& verts_per_elem, long §ion_offset, int elems_count, const std::vector<cgsize_t>& elemsConn) { ErrorCode result; // Create the element sequence; passes back a pointer to the internal storage for connectivity and the // starting entity handle EntityHandle* conn_array; EntityHandle handle = 0; result = readMeshIface->get_element_connect(elems_count, verts_per_elem, ent_type, 1, handle, conn_array);MB_CHK_SET_ERR(result, fileName << ": Trouble reading elements"); memcpy(conn_array, &elemsConn[0], elemsConn.size() * sizeof(EntityHandle)); // Notify MOAB of the new elements result = readMeshIface->update_adjacencies(handle, elems_count, verts_per_elem, conn_array); if (MB_SUCCESS != result) return result; // ////////////////////////////////// // Create sets and tags Range elements(handle, handle + elems_count - 1); // Store element IDs std::vector<int> id_list(elems_count); // Add 1 to offset id to 1-based numbering for (cgsize_t i = 0; i < elems_count; ++i) id_list[i] = i + 1 + section_offset; section_offset += elems_count; create_sets(sectionName, file_id_tag, ent_type, elements, id_list, 0); return MB_SUCCESS; }
ErrorCode ReadTemplate::read_vertices(int num_verts, EntityHandle &start_vertex, Range &read_ents) { // Allocate nodes; these are allocated in one shot, get contiguous handles starting with start_handle, // and the reader is passed back double*'s pointing to MOAB's native storage for vertex coordinates // for those verts std::vector<double*> coord_arrays; ErrorCode result = readMeshIface->get_node_coords(3, num_verts, 1, start_vertex, coord_arrays);MB_CHK_SET_ERR(result, fileName << ": Trouble reading vertices"); // Fill in vertex coordinate arrays double *x = coord_arrays[0], *y = coord_arrays[1], *z = coord_arrays[2]; for (long i = 0; i < num_verts; ++i) { // Read x/y/z; do something with them for now to avoid warning if (x || y || z) {} } if (num_verts) read_ents.insert(start_vertex, start_vertex + num_verts - 1); return result; }
ErrorCode ReadNC::get_variables() { // First cache the number of time steps std::vector<std::string>::iterator vit = std::find(dimNames.begin(), dimNames.end(), "time"); if (vit == dimNames.end()) vit = std::find(dimNames.begin(), dimNames.end(), "t"); int ntimes = 0; if (vit != dimNames.end()) ntimes = dimLens[vit - dimNames.begin()]; if (!ntimes) ntimes = 1; // Get the number of variables int num_vars; int success = NCFUNC(inq_nvars)(fileId, &num_vars); if (success) MB_SET_ERR(MB_FAILURE, "Trouble getting number of variables"); if (num_vars > NC_MAX_VARS) { MB_SET_ERR(MB_FAILURE, "ReadNC: File contains " << num_vars << " vars but NetCDF library supports only " << NC_MAX_VARS); } char var_name[NC_MAX_NAME + 1]; int var_ndims; for (int i = 0; i < num_vars; i++) { // Get the name first, so we can allocate a map iterate for this var success = NCFUNC(inq_varname )(fileId, i, var_name); if (success) MB_SET_ERR(MB_FAILURE, "Trouble getting variable name"); VarData &data = varInfo[std::string(var_name)]; data.varName = std::string(var_name); data.varId = i; data.varTags.resize(ntimes, 0); // Get the data type success = NCFUNC(inq_vartype)(fileId, i, &data.varDataType); if (success) MB_SET_ERR(MB_FAILURE, "Trouble getting data type for variable " << data.varName); // Get the number of dimensions, then the dimensions success = NCFUNC(inq_varndims)(fileId, i, &var_ndims); if (success) MB_SET_ERR(MB_FAILURE, "Trouble getting number of dims for variable " << data.varName); data.varDims.resize(var_ndims); success = NCFUNC(inq_vardimid)(fileId, i, &data.varDims[0]); if (success) MB_SET_ERR(MB_FAILURE, "Trouble getting dimensions for variable " << data.varName); // Finally, get the number of attributes, then the attributes success = NCFUNC(inq_varnatts)(fileId, i, &data.numAtts); if (success) MB_SET_ERR(MB_FAILURE, "Trouble getting number of dims for variable " << data.varName); // Print debug info here so attribute info comes afterwards dbgOut.tprintf(2, "Variable %s: Id=%d, numAtts=%d, datatype=%d, num_dims=%u\n", data.varName.c_str(), data.varId, data.numAtts, data.varDataType, (unsigned int) data.varDims.size()); ErrorCode rval = get_attributes(i, data.numAtts, data.varAtts, " ");MB_CHK_SET_ERR(rval, "Trouble getting attributes for variable " << data.varName); } return MB_SUCCESS; }
ErrorCode ReadNC::load_file(const char* file_name, const EntityHandle* file_set, const FileOptions& opts, const ReaderIface::SubsetList* /*subset_list*/, const Tag* file_id_tag) { // See if opts has variable(s) specified std::vector<std::string> var_names; std::vector<int> tstep_nums; std::vector<double> tstep_vals; // Get and cache predefined tag handles int dum_val = 0; ErrorCode rval = mbImpl->tag_get_handle(GLOBAL_ID_TAG_NAME, 1, MB_TYPE_INTEGER, mGlobalIdTag, MB_TAG_DENSE | MB_TAG_CREAT, &dum_val);MB_CHK_SET_ERR(rval, "Trouble getting global ID tag"); // Store the pointer to the tag; if not null, set when global id tag // is set too, with the same data, duplicated mpFileIdTag = file_id_tag; rval = parse_options(opts, var_names, tstep_nums, tstep_vals);MB_CHK_SET_ERR(rval, "Trouble parsing option string"); // Open the file dbgOut.tprintf(1, "Opening file %s\n", file_name); fileName = std::string(file_name); int success; #ifdef MOAB_HAVE_PNETCDF if (isParallel) success = NCFUNC(open)(myPcomm->proc_config().proc_comm(), file_name, 0, MPI_INFO_NULL, &fileId); else success = NCFUNC(open)(MPI_COMM_SELF, file_name, 0, MPI_INFO_NULL, &fileId); #else success = NCFUNC(open)(file_name, 0, &fileId); #endif if (success) MB_SET_ERR(MB_FAILURE, "Trouble opening file " << file_name); // Read the header (num dimensions, dimensions, num variables, global attribs) rval = read_header();MB_CHK_SET_ERR(rval, "Trouble reading file header"); // Make sure there's a file set to put things in EntityHandle tmp_set; if (noMesh && !file_set) { MB_SET_ERR(MB_FAILURE, "NOMESH option requires non-NULL file set on input"); } else if (!file_set || (file_set && *file_set == 0)) { rval = mbImpl->create_meshset(MESHSET_SET, tmp_set);MB_CHK_SET_ERR(rval, "Trouble creating file set"); } else tmp_set = *file_set; // Get the scd interface scdi = NULL; rval = mbImpl->query_interface(scdi); if (NULL == scdi) return MB_FAILURE; if (NULL != myHelper) delete myHelper; // Get appropriate NC helper instance based on information read from the header myHelper = NCHelper::get_nc_helper(this, fileId, opts, tmp_set); if (NULL == myHelper) { MB_SET_ERR(MB_FAILURE, "Failed to get NCHelper class instance"); } // Initialize mesh values rval = myHelper->init_mesh_vals();MB_CHK_SET_ERR(rval, "Trouble initializing mesh values"); // Check existing mesh from last read if (noMesh && !noVars) { rval = myHelper->check_existing_mesh();MB_CHK_SET_ERR(rval, "Trouble checking mesh from last read"); } // Create some conventional tags, e.g. __NUM_DIMS // For multiple reads to a specified file set, we assume a single file, or a series of // files with separated timesteps. Keep a flag on the file set to prevent conventional // tags from being created again on a second read Tag convTagsCreated = 0; int def_val = 0; rval = mbImpl->tag_get_handle("__CONV_TAGS_CREATED", 1, MB_TYPE_INTEGER, convTagsCreated, MB_TAG_SPARSE | MB_TAG_CREAT, &def_val);MB_CHK_SET_ERR(rval, "Trouble getting _CONV_TAGS_CREATED tag"); int create_conv_tags_flag = 0; rval = mbImpl->tag_get_data(convTagsCreated, &tmp_set, 1, &create_conv_tags_flag); // The first read to the file set if (0 == create_conv_tags_flag) { // Read dimensions (coordinate variables) by default to create tags like __<var_name>_DIMS // This is done only once (assume that all files read to the file set have the same dimensions) rval = myHelper->read_variables(dimNames, tstep_nums);MB_CHK_SET_ERR(rval, "Trouble reading dimensions"); rval = myHelper->create_conventional_tags(tstep_nums);MB_CHK_SET_ERR(rval, "Trouble creating NC conventional tags"); create_conv_tags_flag = 1; rval = mbImpl->tag_set_data(convTagsCreated, &tmp_set, 1, &create_conv_tags_flag);MB_CHK_SET_ERR(rval, "Trouble setting data to _CONV_TAGS_CREATED tag"); } // Another read to the file set else { if (tStepBase > -1) { // If timesteps spread across files, merge time values read // from current file to existing time tag rval = myHelper->update_time_tag_vals();MB_CHK_SET_ERR(rval, "Trouble updating time tag values"); } } // Create mesh vertex/edge/face sequences Range faces; if (!noMesh) { rval = myHelper->create_mesh(faces);MB_CHK_SET_ERR(rval, "Trouble creating mesh"); } // Read specified variables onto grid if (!noVars) { if (var_names.empty()) { // If VARIABLE option is missing, read all variables rval = myHelper->read_variables(var_names, tstep_nums);MB_CHK_SET_ERR(rval, "Trouble reading all variables"); } else { // Exclude dimensions that are read to the file set by default std::vector<std::string> non_dim_var_names; for (unsigned int i = 0; i < var_names.size(); i++) { if (std::find(dimNames.begin(), dimNames.end(), var_names[i]) == dimNames.end()) non_dim_var_names.push_back(var_names[i]); } if (!non_dim_var_names.empty()) { rval = myHelper->read_variables(non_dim_var_names, tstep_nums);MB_CHK_SET_ERR(rval, "Trouble reading specified variables"); } } } #ifdef MOAB_HAVE_MPI // Create partition set, and populate with elements if (isParallel) { EntityHandle partn_set; rval = mbImpl->create_meshset(MESHSET_SET, partn_set);MB_CHK_SET_ERR(rval, "Trouble creating partition set"); rval = mbImpl->add_entities(partn_set, faces);MB_CHK_SET_ERR(rval, "Couldn't add new faces to partition set"); Range verts; rval = mbImpl->get_connectivity(faces, verts);MB_CHK_SET_ERR(rval, "Couldn't get verts of faces"); rval = mbImpl->add_entities(partn_set, verts);MB_CHK_SET_ERR(rval, "Couldn't add new verts to partition set"); myPcomm->partition_sets().insert(partn_set); // Write partition tag name on partition set Tag part_tag = myPcomm->partition_tag(); int dum_rank = myPcomm->proc_config().proc_rank(); rval = mbImpl->tag_set_data(part_tag, &partn_set, 1, &dum_rank);MB_CHK_SET_ERR(rval, "Trouble writing partition tag name on partition set"); } #endif mbImpl->release_interface(scdi); scdi = NULL; // Close the file success = NCFUNC(close)(fileId); if (success) MB_SET_ERR(MB_FAILURE, "Trouble closing file"); return MB_SUCCESS; }
ErrorCode ReadTemplate::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) { // See src/moab/ReaderIface.hpp, definition of SubsetList struct; this basically specifies // an integer tag and tag values for sets to read on this proc, or a part number and total # parts // for reading a trivial partition of entities } // Save filename to member variable so we don't need to pass as an argument // to called functions fileName = filename; // Process options; see src/FileOptions.hpp for API for FileOptions class, and doc/metadata_info.doc for // a description of various options used by some of the readers in MOAB ErrorCode result = process_options(opts);MB_CHK_SET_ERR(result, fileName << ": problem reading options"); // Open file; filePtr is member of ReadTemplate, change to whatever mechanism is used to identify file FILE* filePtr = fopen(fileName, "r"); if (!filePtr) { MB_SET_ERR(MB_FILE_DOES_NOT_EXIST, fileName << ": fopen returned error"); } // Read number of verts, elements, sets long num_verts = 0, num_elems = 0, num_sets = 0; // read_ents keeps a running set of entities read from this file, including vertices, elements, and sets; // these will get added to file_set (if input) at the end of the read Range read_ents; // start_vertex is passed back so we know how to convert indices from the file into vertex handles; most // of the time this is done by adding start_vertex to the (0-based) index; if the index is 1-based, you also // need to subtract one; see read_elements for details EntityHandle start_vertex; result = read_vertices(num_verts, start_vertex, read_ents); if (MB_SUCCESS != result) { fclose(filePtr); return result; } // Create/read elements; this template assumes that all elements are the same type, so can be read in a single // call to read_elements, and kept track of with a single start_elem handle. If there are more entity types, // might have to keep these start handles in an array/vector. start_elem is only really needed if you're reading // sets later, and need to convert some file-based index to an entity handle EntityHandle start_elem; result = read_elements(num_elems, start_vertex, start_elem, read_ents); if (MB_SUCCESS != result) { fclose(filePtr); return result; } // Read/create entity sets; typically these sets have some tag identifying what they're for, see doc/metadata_info.doc // for examples of different kinds of sets and how they're marked result = create_sets(num_sets, start_vertex, num_verts, start_elem, num_elems, read_ents); if (MB_SUCCESS != result) { fclose(filePtr); return result; } // Finally, add all read_ents into the file set, if one was input if (file_set && *file_set) { result = mbImpl->add_entities(*file_set, read_ents); if (MB_SUCCESS != result) { fclose(filePtr); return result; } } fclose(filePtr); return result; }
ErrorCode ReadCGNS::load_file(const char* filename, const EntityHandle * /*file_set*/, const FileOptions& opts, const ReaderIface::SubsetList* subset_list, const Tag* file_id_tag) { int num_material_sets = 0; const int* material_set_list = 0; if (subset_list) { if (subset_list->tag_list_length > 1 && !strcmp(subset_list->tag_list[0].tag_name, MATERIAL_SET_TAG_NAME)) { MB_SET_ERR(MB_UNSUPPORTED_OPERATION, "CGNS supports subset read only by material ID"); } material_set_list = subset_list->tag_list[0].tag_values; num_material_sets = subset_list->tag_list[0].num_tag_values; } ErrorCode result; geomSets.clear(); result = mbImpl->tag_get_handle(GLOBAL_ID_TAG_NAME, 1, MB_TYPE_INTEGER, globalId, MB_TAG_DENSE | MB_TAG_CREAT, 0); if (MB_SUCCESS != result) return result; // Create set for more convienient check for material set ids std::set<int> blocks; for (const int* mat_set_end = material_set_list + num_material_sets; material_set_list != mat_set_end; ++material_set_list) blocks.insert(*material_set_list); // Map of ID->handle for nodes std::map<long, EntityHandle> node_id_map; // Save filename to member variable so we don't need to pass as an argument // to called functions fileName = filename; // Process options; see src/FileOptions.hpp for API for FileOptions class, and doc/metadata_info.doc for // a description of various options used by some of the readers in MOAB result = process_options(opts);MB_CHK_SET_ERR(result, fileName << ": problem reading options"); // Open file int filePtr = 0; cg_open(filename, CG_MODE_READ, &filePtr); if (filePtr <= 0) { MB_SET_ERR(MB_FILE_DOES_NOT_EXIST, fileName << ": fopen returned error"); } // Read number of verts, elements, sets long num_verts = 0, num_elems = 0, num_sets = 0; int num_bases = 0, num_zones = 0, num_sections = 0; char zoneName[128]; cgsize_t size[3]; mesh_dim = 3; // Default to 3D // Read number of bases; cg_nbases(filePtr, &num_bases); if (num_bases > 1) { MB_SET_ERR(MB_NOT_IMPLEMENTED, fileName << ": support for number of bases > 1 not implemented"); } for (int indexBase = 1; indexBase <= num_bases; ++indexBase) { // Get the number of zones/blocks in current base. cg_nzones(filePtr, indexBase, &num_zones); if (num_zones > 1) { MB_SET_ERR(MB_NOT_IMPLEMENTED, fileName << ": support for number of zones > 1 not implemented"); } for (int indexZone = 1; indexZone <= num_zones; ++indexZone) { // Get zone name and size. cg_zone_read(filePtr, indexBase, indexZone, zoneName, size); // Read number of sections/Parts in current zone. cg_nsections(filePtr, indexBase, indexZone, &num_sections); num_verts = size[0]; num_elems = size[1]; num_sets = num_sections; std::cout << "\nnumber of nodes = " << num_verts; std::cout << "\nnumber of elems = " << num_elems; std::cout << "\nnumber of parts = " << num_sets << std::endl; // ////////////////////////////////// // Read Nodes // Allocate nodes; these are allocated in one shot, get contiguous handles starting with start_handle, // and the reader is passed back double*'s pointing to MOAB's native storage for vertex coordinates // for those verts std::vector<double*> coord_arrays; EntityHandle handle = 0; result = readMeshIface->get_node_coords(3, num_verts, MB_START_ID, handle, coord_arrays);MB_CHK_SET_ERR(result, fileName << ": Trouble reading vertices"); // Fill in vertex coordinate arrays cgsize_t beginPos = 1, endPos = num_verts; // Read nodes coordinates. cg_coord_read(filePtr, indexBase, indexZone, "CoordinateX", RealDouble, &beginPos, &endPos, coord_arrays[0]); cg_coord_read(filePtr, indexBase, indexZone, "CoordinateY", RealDouble, &beginPos, &endPos, coord_arrays[1]); cg_coord_read(filePtr, indexBase, indexZone, "CoordinateZ", RealDouble, &beginPos, &endPos, coord_arrays[2]); // CGNS seems to always include the Z component, even if the mesh is 2D. // Check if Z is zero and determine mesh dimension. // Also create the node_id_map data. double sumZcoord = 0.0; double eps = 1.0e-12; for (long i = 0; i < num_verts; ++i, ++handle) { int index = i + 1; node_id_map.insert(std::pair<long, EntityHandle>(index, handle)).second; sumZcoord += *(coord_arrays[2] + i); } if (std::abs(sumZcoord) <= eps) mesh_dim = 2; // Create reverse map from handle to id std::vector<int> ids(num_verts); std::vector<int>::iterator id_iter = ids.begin(); std::vector<EntityHandle> handles(num_verts); std::vector<EntityHandle>::iterator h_iter = handles.begin(); for (std::map<long, EntityHandle>::iterator i = node_id_map.begin(); i != node_id_map.end(); ++i, ++id_iter, ++h_iter) { *id_iter = i->first; * h_iter = i->second; } // Store IDs in tags result = mbImpl->tag_set_data(globalId, &handles[0], num_verts, &ids[0]); if (MB_SUCCESS != result) return result; if (file_id_tag) { result = mbImpl->tag_set_data(*file_id_tag, &handles[0], num_verts, &ids[0]); if (MB_SUCCESS != result) return result; } ids.clear(); handles.clear(); // ////////////////////////////////// // Read elements data EntityType ent_type; long section_offset = 0; // Define which mesh parts are volume families. // Mesh parts with volumeID[X] = 0 are boundary parts. std::vector<int> volumeID(num_sections, 0); for (int section = 0; section < num_sections; ++section) { ElementType_t elemsType; int iparent_flag, nbndry; char sectionName[128]; int verts_per_elem; int cgSection = section + 1; cg_section_read(filePtr, indexBase, indexZone, cgSection, sectionName, &elemsType, &beginPos, &endPos, &nbndry, &iparent_flag); size_t section_size = endPos - beginPos + 1; // Read element description in current section switch (elemsType) { case BAR_2: ent_type = MBEDGE; verts_per_elem = 2; break; case TRI_3: ent_type = MBTRI; verts_per_elem = 3; if (mesh_dim == 2) volumeID[section] = 1; break; case QUAD_4: ent_type = MBQUAD; verts_per_elem = 4; if (mesh_dim == 2) volumeID[section] = 1; break; case TETRA_4: ent_type = MBTET; verts_per_elem = 4; if (mesh_dim == 3) volumeID[section] = 1; break; case PYRA_5: ent_type = MBPYRAMID; verts_per_elem = 5; if (mesh_dim == 3) volumeID[section] = 1; break; case PENTA_6: ent_type = MBPRISM; verts_per_elem = 6; if (mesh_dim == 3) volumeID[section] = 1; break; case HEXA_8: ent_type = MBHEX; verts_per_elem = 8; if (mesh_dim == 3) volumeID[section] = 1; break; case MIXED: ent_type = MBMAXTYPE; verts_per_elem = 0; break; default: MB_SET_ERR(MB_INDEX_OUT_OF_RANGE, fileName << ": Trouble determining element type"); } if (elemsType == TETRA_4 || elemsType == PYRA_5 || elemsType == PENTA_6 || elemsType == HEXA_8 || elemsType == TRI_3 || elemsType == QUAD_4 || ((elemsType == BAR_2) && mesh_dim == 2)) { // Read connectivity into conn_array directly cgsize_t iparentdata; cgsize_t connDataSize; // Get number of entries on the connectivity list for this section cg_ElementDataSize(filePtr, indexBase, indexZone, cgSection, &connDataSize); // Need a temporary vector to later cast to conn_array. std::vector<cgsize_t> elemNodes(connDataSize); cg_elements_read(filePtr, indexBase, indexZone, cgSection, &elemNodes[0], &iparentdata); // ////////////////////////////////// // Create elements, sets and tags create_elements(sectionName, file_id_tag, ent_type, verts_per_elem, section_offset, section_size , elemNodes); } // Homogeneous mesh type else if (elemsType == MIXED) { // We must first sort all elements connectivities into continuous vectors cgsize_t connDataSize; cgsize_t iparentdata; cg_ElementDataSize(filePtr, indexBase, indexZone, cgSection, &connDataSize); std::vector< cgsize_t > elemNodes(connDataSize); cg_elements_read(filePtr, indexBase, indexZone, cgSection, &elemNodes[0], &iparentdata); std::vector<cgsize_t> elemsConn_EDGE; std::vector<cgsize_t> elemsConn_TRI, elemsConn_QUAD; std::vector<cgsize_t> elemsConn_TET, elemsConn_PYRA, elemsConn_PRISM, elemsConn_HEX; cgsize_t count_EDGE, count_TRI, count_QUAD; cgsize_t count_TET, count_PYRA, count_PRISM, count_HEX; // First, get elements count for current section count_EDGE = count_TRI = count_QUAD = 0; count_TET = count_PYRA = count_PRISM = count_HEX = 0; int connIndex = 0; for (int i = beginPos; i <= endPos; i++) { elemsType = ElementType_t(elemNodes[connIndex]); // Get current cell node count. cg_npe(elemsType, &verts_per_elem); switch (elemsType) { case BAR_2: count_EDGE += 1; break; case TRI_3: count_TRI += 1; break; case QUAD_4: count_QUAD += 1; break; case TETRA_4: count_TET += 1; break; case PYRA_5: count_PYRA += 1; break; case PENTA_6: count_PRISM += 1; break; case HEXA_8: count_HEX += 1; break; default: MB_SET_ERR(MB_INDEX_OUT_OF_RANGE, fileName << ": Trouble determining element type"); } connIndex += (verts_per_elem + 1); // Add one to skip next element descriptor } if (count_EDGE > 0) elemsConn_EDGE.resize(count_EDGE * 2); if (count_TRI > 0) elemsConn_TRI.resize(count_TRI * 3); if (count_QUAD > 0) elemsConn_QUAD.resize(count_QUAD * 4); if (count_TET > 0) elemsConn_TET.resize(count_TET * 4); if (count_PYRA > 0) elemsConn_PYRA.resize(count_PYRA * 5); if (count_PRISM > 0) elemsConn_PRISM.resize(count_PRISM * 6); if (count_HEX > 0) elemsConn_HEX.resize(count_HEX * 8); // Grab mixed section elements connectivity int idx_edge, idx_tri, idx_quad; int idx_tet, idx_pyra, idx_prism, idx_hex; idx_edge = idx_tri = idx_quad = 0; idx_tet = idx_pyra = idx_prism = idx_hex = 0; connIndex = 0; for (int i = beginPos; i <= endPos; i++) { elemsType = ElementType_t(elemNodes[connIndex]); // Get current cell node count. cg_npe(elemsType, &verts_per_elem); switch (elemsType) { case BAR_2: for (int j = 0; j < 2; ++j) elemsConn_EDGE[idx_edge + j] = elemNodes[connIndex + j + 1]; idx_edge += 2; break; case TRI_3: for (int j = 0; j < 3; ++j) elemsConn_TRI[idx_tri + j] = elemNodes[connIndex + j + 1]; idx_tri += 3; break; case QUAD_4: for (int j = 0; j < 4; ++j) elemsConn_QUAD[idx_quad + j] = elemNodes[connIndex + j + 1]; idx_quad += 4; break; case TETRA_4: for (int j = 0; j < 4; ++j) elemsConn_TET[idx_tet + j] = elemNodes[connIndex + j + 1]; idx_tet += 4; break; case PYRA_5: for (int j = 0; j < 5; ++j) elemsConn_PYRA[idx_pyra + j] = elemNodes[connIndex + j + 1]; idx_pyra += 5; break; case PENTA_6: for (int j = 0; j < 6; ++j) elemsConn_PRISM[idx_prism + j] = elemNodes[connIndex + j + 1]; idx_prism += 6; break; case HEXA_8: for (int j = 0; j < 8; ++j) elemsConn_HEX[idx_hex + j] = elemNodes[connIndex + j + 1]; idx_hex += 8; break; default: MB_SET_ERR(MB_INDEX_OUT_OF_RANGE, fileName << ": Trouble determining element type"); } connIndex += (verts_per_elem + 1); // Add one to skip next element descriptor } // ////////////////////////////////// // Create elements, sets and tags if (count_EDGE > 0) create_elements(sectionName, file_id_tag, MBEDGE, 2, section_offset, count_EDGE, elemsConn_EDGE); if (count_TRI > 0) create_elements(sectionName, file_id_tag, MBTRI, 3, section_offset, count_TRI, elemsConn_TRI); if (count_QUAD > 0) create_elements(sectionName, file_id_tag, MBQUAD, 4, section_offset, count_QUAD, elemsConn_QUAD); if (count_TET > 0) create_elements(sectionName, file_id_tag, MBTET, 4, section_offset, count_TET, elemsConn_TET); if (count_PYRA > 0) create_elements(sectionName, file_id_tag, MBPYRAMID, 5, section_offset, count_PYRA, elemsConn_PYRA); if (count_PRISM > 0) create_elements(sectionName, file_id_tag, MBPRISM, 6, section_offset, count_PRISM, elemsConn_PRISM); if (count_HEX > 0) create_elements(sectionName, file_id_tag, MBHEX, 8, section_offset, count_HEX, elemsConn_HEX); } // Mixed mesh type } // num_sections cg_close(filePtr); return result; } // indexZone for } // indexBase for return MB_SUCCESS; }