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; }
void test_write_invalid_elem() { Core mbcore; Interface& moab = mbcore; ReadUtilIface* readtool = 0; ErrorCode rval; rval = moab.query_interface( readtool ); CHECK_ERR(rval); CHECK( readtool != 0 ); // create two nodes EntityHandle first_node; std::vector<double*> coords; rval = readtool->get_node_coords( 3, 2, 1, first_node, coords ); CHECK_ERR(rval); coords[0][0] = coords[0][1] = 0.0; coords[1][0] = coords[1][1] = 0.0; coords[2][0] = coords[2][1] = 0.0; // create a triangle with an invalid node handle for its // third vertex EntityHandle tri; EntityHandle* conn = 0; rval = readtool->get_element_connect( 1, 3, MBTRI, 1, tri, conn ); CHECK_ERR(rval); conn[0] = first_node; // valid conn[1] = first_node+1; // valid conn[2] = first_node+2; // invalid // try to write the file (should fail) WriteHDF5 writer( &moab ); FileOptions opts(0); rval = writer.write_file( filename, true, opts, 0, 0, std::vector<std::string>() ); CHECK(MB_SUCCESS != rval); }