void DebugOutput::list_range_real( const char* pfx, const Range& range ) { if (pfx) { lineBuffer.insert( lineBuffer.end(), pfx, pfx+strlen(pfx) ); lineBuffer.push_back(' '); } if (range.empty()) { print_real("<empty>\n"); return; } char numbuf[48]; // unsigned 64 bit integer can't have more than 20 decimal digits Range::const_pair_iterator i; EntityType type = MBMAXTYPE; for (i = range.const_pair_begin(); i != range.const_pair_end(); ++i) { if (TYPE_FROM_HANDLE(i->first) != type) { type = TYPE_FROM_HANDLE(i->first); const char* name = CN::EntityTypeName(type); lineBuffer.insert( lineBuffer.end(), name, name+strlen(name) ); } if (i->first == i->second) sprintf(numbuf, " %lu,", (unsigned long)(ID_FROM_HANDLE(i->first))); else print_range(numbuf, ID_FROM_HANDLE(i->first), ID_FROM_HANDLE(i->second) ); lineBuffer.insert( lineBuffer.end(), numbuf, numbuf+strlen(numbuf) ); } lineBuffer.push_back('\n'); process_line_buffer(); }
ErrorCode WriteTemplate::get_neuset_elems(EntityHandle neuset, int current_sense, Range &forward_elems, Range &reverse_elems) { Range neuset_elems, neuset_meshsets; // get the sense tag; don't need to check return, might be an error if the tag // hasn't been created yet Tag sense_tag = 0; mbImpl->tag_get_handle("SENSE", 1, MB_TYPE_INTEGER, sense_tag); // get the entities in this set ErrorCode result = mbImpl->get_entities_by_handle(neuset, neuset_elems, true); if (MB_FAILURE == result) return result; // now remove the meshsets into the neuset_meshsets; first find the first meshset, Range::iterator range_iter = neuset_elems.begin(); while (TYPE_FROM_HANDLE(*range_iter) != MBENTITYSET && range_iter != neuset_elems.end()) range_iter++; // then, if there are some, copy them into neuset_meshsets and erase from neuset_elems if (range_iter != neuset_elems.end()) { std::copy(range_iter, neuset_elems.end(), range_inserter(neuset_meshsets)); neuset_elems.erase(range_iter, neuset_elems.end()); } // ok, for the elements, check the sense of this set and copy into the right range // (if the sense is 0, copy into both ranges) // need to step forward on list until we reach the right dimension Range::iterator dum_it = neuset_elems.end(); dum_it--; int target_dim = CN::Dimension(TYPE_FROM_HANDLE(*dum_it)); dum_it = neuset_elems.begin(); while (target_dim != CN::Dimension(TYPE_FROM_HANDLE(*dum_it)) && dum_it != neuset_elems.end()) dum_it++; if (current_sense == 1 || current_sense == 0) std::copy(dum_it, neuset_elems.end(), range_inserter(forward_elems)); if (current_sense == -1 || current_sense == 0) std::copy(dum_it, neuset_elems.end(), range_inserter(reverse_elems)); // now loop over the contained meshsets, getting the sense of those and calling this // function recursively for (range_iter = neuset_meshsets.begin(); range_iter != neuset_meshsets.end(); range_iter++) { // first get the sense; if it's not there, by convention it's forward int this_sense; if (0 == sense_tag || MB_FAILURE == mbImpl->tag_get_data(sense_tag, &(*range_iter), 1, &this_sense)) this_sense = 1; // now get all the entities on this meshset, with the proper (possibly reversed) sense get_neuset_elems(*range_iter, this_sense*current_sense, forward_elems, reverse_elems); } return result; }
/** \brief Convert representation from fine to coarse * Each element in set, or in interface if set is not input, is converted to coarse elements, with * fine vertices put into SPECTRAL_VERTICES tagged array. NOTE: This function assumes that each * order^d (fine) elements comprise each coarse element, and are in order of fine elements in each * coarse element. If order is input as 0, looks for a SPECTRAL_ORDER tag on the mesh. * \param order Order of the spectral mesh * \param spectral_set Set containing spectral elements */ ErrorCode SpectralMeshTool::convert_to_coarse(int order, EntityHandle spectral_set) { if (order) spectralOrder = order; if (!spectralOrder) { MB_SET_ERR(MB_FAILURE, "Spectral order must be set or input before converting to spectral mesh"); } Range tmp_ents, ents; ErrorCode rval = mbImpl->get_entities_by_handle(spectral_set, tmp_ents); if (MB_SUCCESS != rval || ents.empty()) return rval; // get the max-dimensional elements from it ents = tmp_ents.subset_by_dimension(3); if (ents.empty()) ents = tmp_ents.subset_by_dimension(2); if (ents.empty()) ents = tmp_ents.subset_by_dimension(1); if (ents.empty()) { MB_SET_ERR(MB_FAILURE, "Can't find any entities for conversion"); } // get a ptr to connectivity if (ents.psize() != 1) { MB_SET_ERR(MB_FAILURE, "Entities must be in one chunk for conversion"); } EntityHandle *conn; int count, verts_per_e; rval = mbImpl->connect_iterate(ents.begin(), ents.end(), conn, verts_per_e, count); if (MB_SUCCESS != rval || count != (int)ents.size()) return rval; Range tmp_range; return create_spectral_elems(conn, ents.size(), CN::Dimension(TYPE_FROM_HANDLE(*ents.begin())), tmp_range); }
template <class Container> inline void BitTag::get_tagged( Range::const_iterator begin, Range::const_iterator end, Container& entities ) const { EntityType type; EntityID count; size_t page; int offset, per_page = ents_per_page(); typename Container::iterator hint = entities.begin(); EntityHandle h; Range::const_iterator i = begin; while (i != end) { h = *i; unpack( h, type, page, offset ); i = i.end_of_block(); count = *i - h + 1; ++i; while (count > 0) { EntityID pcount = std::min( count, (EntityID)(per_page - offset) ); if (page < pageList[type].size() && pageList[type][page]) hint = entities.insert( hint, h, h+pcount-1 ); count -= pcount; h += pcount; assert(TYPE_FROM_HANDLE(h) == type); offset = 0; ++page; } } }
inline ErrorCode SweptElementData::get_params_connectivity(const int i, const int j, const int k, std::vector<EntityHandle>& connectivity) const { if (contains(HomCoord(i, j, k)) == false) return MB_FAILURE; connectivity.push_back(get_vertex(i, j, k)); connectivity.push_back(get_vertex(i+1, j, k)); if (CN::Dimension(TYPE_FROM_HANDLE(start_handle())) < 2) return MB_SUCCESS; connectivity.push_back(get_vertex(i+1, j+1, k)); connectivity.push_back(get_vertex(i, j+1, k)); if (CN::Dimension(TYPE_FROM_HANDLE(start_handle())) < 3) return MB_SUCCESS; connectivity.push_back(get_vertex(i, j, k+1)); connectivity.push_back(get_vertex(i+1, j, k+1)); connectivity.push_back(get_vertex(i+1, j+1, k+1)); connectivity.push_back(get_vertex(i, j+1, k+1)); return MB_SUCCESS; }
ErrorCode VectorSetIterator::get_next_arr(std::vector<EntityHandle> &arr, bool &atend) { int count; const EntityHandle *ptr; WriteUtilIface *iface; Interface *mbImpl = dynamic_cast<Interface*>(myCore); ErrorCode rval = mbImpl->query_interface(iface); if (MB_SUCCESS != rval) return rval; rval = iface->get_entity_list_pointers( &entSet, 1, &ptr, WriteUtilIface::CONTENTS, &count); if (MB_SUCCESS != rval) return rval; mbImpl->release_interface(iface); if (!count || iterPos >= count) { atend = true; return MB_SUCCESS; } std::vector<EntityHandle> tmp_arr; std::vector<EntityHandle> *tmp_ptr = &arr; if (checkValid) tmp_ptr = &tmp_arr; // just get the next chunkSize entities, or as many as you can int this_ct = 0; while (this_ct < (int)chunkSize && iterPos < count) { if ((MBMAXTYPE == entType || TYPE_FROM_HANDLE(ptr[iterPos]) == entType) && (-1 == entDimension || CN::Dimension(TYPE_FROM_HANDLE(ptr[iterPos])) == entDimension)) { arr.push_back(ptr[iterPos]); this_ct++; } iterPos++; } atend = (iterPos == count); if (checkValid) { for (std::vector<EntityHandle>::iterator vit = tmp_ptr->begin(); vit != tmp_ptr->end(); vit++) { if (myCore->is_valid(*vit)) arr.push_back(*vit); } } // step along list, adding entities return MB_SUCCESS; }
static ErrorCode ent_not_found( Error* error, std::string name, EntityHandle h ) { error->set_last_error( "Invalid entity handle setting tag %s: %s %ld", name.c_str(), CN::EntityTypeName(TYPE_FROM_HANDLE(h)), (unsigned long)ID_FROM_HANDLE(h)); return MB_ENTITY_NOT_FOUND; }
inline ErrorCode ScdElementData::get_params_connectivity(const int i, const int j, const int k, std::vector<EntityHandle>& connectivity) const { if (contains(HomCoord(i, j, k)) == false) return MB_FAILURE; int ip1 = (isPeriodic[0] ? (i+1)%dIJKm1[0] : i+1), jp1 = (isPeriodic[1] ? (j+1)%dIJKm1[1] : j+1); connectivity.push_back(get_vertex(i, j, k)); connectivity.push_back(get_vertex(ip1, j, k)); if (CN::Dimension(TYPE_FROM_HANDLE(start_handle())) < 2) return MB_SUCCESS; connectivity.push_back(get_vertex(ip1, jp1, k)); connectivity.push_back(get_vertex(i, jp1, k)); if (CN::Dimension(TYPE_FROM_HANDLE(start_handle())) < 3) return MB_SUCCESS; connectivity.push_back(get_vertex(i, j, k+1)); connectivity.push_back(get_vertex(ip1, j, k+1)); connectivity.push_back(get_vertex(ip1, jp1, k+1)); connectivity.push_back(get_vertex(i, jp1, k+1)); return MB_SUCCESS; }
ErrorCode BitTag::get_entities_with_bits( const Range &range, EntityType in_type, Range& entities, unsigned char bits ) const { if (MBMAXTYPE == in_type) { ErrorCode rval; for (--in_type; in_type >= MBVERTEX; --in_type) { rval = get_entities_with_bits( range, in_type, entities, bits ); if (MB_SUCCESS != rval) return rval; } return MB_SUCCESS; } EntityType type; EntityID count; size_t page; int offset, per_page = ents_per_page(); Range::const_iterator j, i, end; if (MBMAXTYPE == in_type) { i = range.begin(); end = range.end(); } else { std::pair<Range::iterator,Range::iterator> r = range.equal_range(in_type); i = r.first; end = r.second; } EntityHandle h; while (i != end) { h = *i; unpack( h, type, page, offset ); assert(MBMAXTYPE == in_type || type == in_type); i = i.end_of_block(); count = *i - h + 1; ++i; while (count > 0) { EntityID pcount = std::min( count, (EntityID)(per_page - offset) ); if (page < pageList[type].size() && pageList[type][page]) pageList[type][page]->search( bits, offset, pcount, storedBitsPerEntity, entities, h ); count -= pcount; h += pcount; assert(TYPE_FROM_HANDLE(h) == type); offset = 0; ++page; } } return MB_SUCCESS; }
EntityID SweptElementData::calc_num_entities(EntityHandle start_handle, int irange, int jrange, int krange) { size_t result = 1; switch (CN::Dimension(TYPE_FROM_HANDLE(start_handle))) { default: result = 0; assert( false ); case 3: result *= krange; case 2: result *= jrange; case 1: result *= irange; } return result; }
static ErrorCode not_found( Error* error, std::string name, EntityHandle h ) { if (h) error->set_last_error( "No dense tag %s value for %s %ld", name.c_str(), CN::EntityTypeName(TYPE_FROM_HANDLE(h)), (unsigned long)ID_FROM_HANDLE(h)); else error->set_last_error( "No tag value for root set" ); return MB_TAG_NOT_FOUND; }
inline ErrorCode SweptElementData::get_params(const EntityHandle ehandle, int &i, int &j, int &k) const { if (TYPE_FROM_HANDLE(ehandle) != TYPE_FROM_HANDLE(start_handle())) return MB_FAILURE; int hdiff = ehandle - start_handle(); // use double ?: test below because on some platforms, both sides of the : are // evaluated, and if dIJKm1[1] is zero, that'll generate a divide-by-zero k = (dIJKm1[1] > 0 ? hdiff / (dIJKm1[1] > 0 ? dIJKm1[0]*dIJKm1[1] : 1) : 0); j = (hdiff - (k*dIJKm1[0]*dIJKm1[1])) / dIJKm1[0]; i = hdiff % dIJKm1[0]; k += elementParams[0].k(); j += elementParams[0].j(); i += elementParams[0].i(); return (ehandle >= start_handle() && ehandle < start_handle()+size() && i >= i_min() && i <= i_max() && j >= j_min() && j <= j_max() && k >= k_min() && k <= k_max()) ? MB_SUCCESS : MB_FAILURE; }
EntityID ScdElementData::calc_num_entities(EntityHandle start_handle, int irange, int jrange, int krange, int *is_periodic) { size_t result = 1; switch (CN::Dimension(TYPE_FROM_HANDLE(start_handle))) { default: result = 0; assert( false ); case 3: result *= krange; case 2: result *= (is_periodic && is_periodic[1] ? (jrange+1) : jrange); case 1: result *= (is_periodic && is_periodic[0] ? (irange+1) : irange); } return result; }
inline ErrorCode SweptVertexData::get_params(const EntityHandle vhandle, int &i, int &j, int &k) const { if (TYPE_FROM_HANDLE(vhandle) != MBVERTEX) return MB_FAILURE; int hdiff = vhandle - start_handle(); k = hdiff / (dIJK[0]*dIJK[1]); j = (hdiff - (k*dIJK[0]*dIJK[1])) / dIJK[0]; i = hdiff % dIJK[0]; k += vertexParams[0].k(); j += vertexParams[0].j(); i += vertexParams[0].i(); return (vhandle >= start_handle() && i >= i_min() && i <= i_max() && j >= j_min() && j <= j_max() && k >= k_min() && k <= k_max()) ? MB_SUCCESS : MB_FAILURE; }
ErrorCode RangeSetIterator::get_next_by_dimension(const EntityHandle *&ptr, int count, std::vector<EntityHandle> &arr, bool &atend) { // iterating by dimension - type should be maxtype if (entType != MBMAXTYPE) { MB_SET_ERR(MB_FAILURE, "Both dimension and type should not be set on an iterator"); } unsigned int num_ret = 0; size_t idx = 0; // initialize to first relevant handle while ((int)idx < count && (iterPos > ptr[idx+1] || (!iterPos && entDimension > CN::Dimension(TYPE_FROM_HANDLE(ptr[idx+1]))))) idx += 2; if ((int)idx == count || CN::Dimension(TYPE_FROM_HANDLE(ptr[idx])) > entDimension) { atend = true; return MB_SUCCESS; } if (!iterPos) iterPos = ptr[idx]; else if (CN::Dimension(TYPE_FROM_HANDLE(ptr[idx])) < entDimension) iterPos = CREATE_HANDLE(CN::TypeDimensionMap[entDimension].first,1); // idx points to start of subrange, iterPos in that subrange do { EntityHandle next = ptr[idx+1]; if (CN::Dimension(TYPE_FROM_HANDLE(next)) != entDimension) next = LAST_HANDLE(CN::TypeDimensionMap[entDimension].second); unsigned int this_ret = chunkSize-num_ret; unsigned int to_end = next - iterPos + 1; if (to_end < this_ret) this_ret = to_end; std::copy(MeshSet::hdl_iter(iterPos), MeshSet::hdl_iter(iterPos + this_ret), std::back_inserter(arr)); if (this_ret == to_end) { idx += 2; iterPos = ((int)idx < count ? ptr[idx] : 0); } else iterPos += this_ret; num_ret += this_ret; } while ((int)idx < count && num_ret < chunkSize && iterPos && CN::Dimension(TYPE_FROM_HANDLE(iterPos)) == entDimension); if (!iterPos || CN::Dimension(TYPE_FROM_HANDLE(iterPos)) != entDimension) atend = true; return MB_SUCCESS; }
ErrorCode BitTag::clear_data( SequenceManager* seqman, Error* error, const Range& handles, const void* value_ptr, int value_len ) { if (value_len) return MB_INVALID_SIZE; ErrorCode rval = seqman->check_valid_entities( error, handles ); if (MB_SUCCESS != rval) return rval; EntityType type; EntityID count; size_t page; int offset, per_page = ents_per_page(); const unsigned char value = *reinterpret_cast<const unsigned char*>(value_ptr); Range::const_pair_iterator i; for (i = handles.const_pair_begin(); i != handles.const_pair_end(); ++i) { unpack( i->first, type, page, offset ); assert(TYPE_FROM_HANDLE(i->second) == type); // should be true because id of zero is never used count = i->second - i->first + 1; while (count) { if (page >= pageList[type].size()) pageList[type].resize( page+1, 0 ); if (!pageList[type][page]) pageList[type][page] = new BitPage( storedBitsPerEntity, default_val() ); size_t pcount = std::min( (EntityID)(per_page - offset), count ); pageList[type][page]->set_bits( offset, pcount, storedBitsPerEntity, value ); count -= pcount; offset = 0; ++page; } } return MB_SUCCESS; }
ErrorCode RangeSetIterator::get_next_by_type(const EntityHandle *&ptr, int count, std::vector<EntityHandle> &arr, bool &atend) { unsigned int num_ret = 0; bool max_type = (entType == MBMAXTYPE); size_t idx = 0; // initialize to first relevant handle while ((int)idx < count && (iterPos > ptr[idx+1] || (!max_type && !iterPos && CREATE_HANDLE(entType, ID_FROM_HANDLE(iterPos)) > ptr[idx+1]))) idx += 2; if ((int)idx == count || TYPE_FROM_HANDLE(ptr[idx]) > entType) { atend = true; return MB_SUCCESS; } if (!iterPos && max_type) iterPos = ptr[idx]; else if (!iterPos && TYPE_FROM_HANDLE(ptr[idx]) <= entType && TYPE_FROM_HANDLE(ptr[idx+1]) >= entType) { iterPos = std::max(CREATE_HANDLE(entType,1), ptr[idx]); } // idx points to start of subrange, iterPos in that subrange do { EntityHandle next = ptr[idx+1]; if (TYPE_FROM_HANDLE(next) != entType && !max_type) next = LAST_HANDLE(entType); unsigned int this_ret = chunkSize-num_ret; unsigned int to_end = next - iterPos + 1; if (to_end < this_ret) this_ret = to_end; std::copy(MeshSet::hdl_iter(iterPos), MeshSet::hdl_iter(iterPos + this_ret), std::back_inserter(arr)); if (this_ret == to_end) { idx += 2; iterPos = ((int)idx < count ? ptr[idx] : 0); } else iterPos += this_ret; num_ret += this_ret; } while ((int)idx < count && num_ret < chunkSize && iterPos && (max_type || TYPE_FROM_HANDLE(iterPos) == entType)); if (!iterPos || (!max_type && TYPE_FROM_HANDLE(iterPos) != entType)) atend = true; return MB_SUCCESS; }
ErrorCode BitTag::get_data( const SequenceManager*, Error*, const Range& handles, void* gen_data ) const { EntityType type; EntityID count; size_t page; int offset, per_page = ents_per_page(); unsigned char def = default_val(); unsigned char* data = reinterpret_cast<unsigned char*>(gen_data); Range::const_pair_iterator i; for (i = handles.const_pair_begin(); i != handles.const_pair_end(); ++i) { unpack( i->first, type, page, offset ); assert(TYPE_FROM_HANDLE(i->second) == type); // should be true because id of zero is never used count = i->second - i->first + 1; if (page >= pageList[type].size()) { memset( data, def, count ); data += count; continue; } while (count) { size_t pcount = std::min( (EntityID)(per_page - offset), count ); if (pageList[type][page]) pageList[type][page]->get_bits( offset, pcount, storedBitsPerEntity, data ); else memset( data, def, pcount ); data += pcount; count -= pcount; offset = 0; ++page; } } return MB_SUCCESS; }
ErrorCode BitTag::remove_data( SequenceManager*, Error*, const Range& handles ) { EntityType type; EntityID count; size_t page; int offset, per_page = ents_per_page(); unsigned char val = default_val(); Range::const_pair_iterator i; for (i = handles.const_pair_begin(); i != handles.const_pair_end(); ++i) { unpack( i->first, type, page, offset ); assert(TYPE_FROM_HANDLE(i->second) == type); // should be true because id of zero is never used count = i->second - i->first + 1; while (count) { size_t pcount = std::min( (EntityID)(per_page - offset), count ); if (page < pageList[type].size() && pageList[type][page]) pageList[type][page]->set_bits( offset, pcount, storedBitsPerEntity, val ); count -= pcount; offset = 0; ++page; } } return MB_SUCCESS; }
/** Find entity sequence containing specified handle. *\return MB_SUCCESS or MB_ENTITY_NOT_FOUND */ ErrorCode find( EntityHandle handle, const EntitySequence*& sequence_out ) const { return typeData[TYPE_FROM_HANDLE(handle)].find( handle, sequence_out ); }
ErrorCode WriteVtk::write_elems(std::ostream& stream, const Range& nodes, const Range& elems) { ErrorCode rval; Range connected_nodes; rval = mbImpl->get_connectivity(elems, connected_nodes); if (MB_SUCCESS != rval) return rval; Range free_nodes = subtract(nodes, connected_nodes); // Get and write counts unsigned long num_elems, num_uses; num_elems = num_uses = elems.size(); for (Range::const_iterator i = elems.begin(); i != elems.end(); ++i) { EntityType type = mbImpl->type_from_handle(*i); if (!VtkUtil::get_vtk_type(type, CN::VerticesPerEntity(type))) continue; std::vector<EntityHandle> connect; rval = mbImpl->get_connectivity(&(*i), 1, connect); if (MB_SUCCESS != rval) return rval; num_uses += connect.size(); } stream << "CELLS " << num_elems + free_nodes.size()<< ' ' << num_uses + 2*free_nodes.size() << std::endl; // Write element connectivity std::vector<int> conn_data; std::vector<unsigned> vtk_types(elems.size() + free_nodes.size() ); std::vector<unsigned>::iterator t = vtk_types.begin(); for (Range::const_iterator i = elems.begin(); i != elems.end(); ++i) { // Get type information for element EntityType type = TYPE_FROM_HANDLE(*i); // Get element connectivity std::vector<EntityHandle> connect; rval = mbImpl->get_connectivity(&(*i), 1, connect); int conn_len = connect.size(); if (MB_SUCCESS != rval) return rval; // Get VTK type const VtkElemType* vtk_type = VtkUtil::get_vtk_type(type, conn_len); if (!vtk_type) { // Try connectivity with 1 fewer node vtk_type = VtkUtil::get_vtk_type(type, conn_len - 1); if (vtk_type) conn_len--; else { MB_SET_ERR(MB_FAILURE, "Vtk file format does not support elements of type " << CN::EntityTypeName(type) << " (" << (int)type << ") with " << conn_len << " nodes"); } } // Get IDs from vertex handles assert(conn_len > 0); conn_data.resize(conn_len); for (int j = 0; j < conn_len; ++j) conn_data[j] = nodes.index(connect[j]); // Save VTK type index for later *t = vtk_type->vtk_type; ++t; // Write connectivity list stream << conn_len; if (vtk_type->node_order) for (int k = 0; k < conn_len; ++k) stream << ' ' << conn_data[vtk_type->node_order[k]]; else for (int k = 0; k < conn_len; ++k) stream << ' ' << conn_data[k]; stream << std::endl; } for (Range::const_iterator v=free_nodes.begin(); v!= free_nodes.end(); ++v, ++t) { EntityHandle node=*v; stream << "1 " << nodes.index(node) << std::endl; *t = 1; } // Write element types stream << "CELL_TYPES " << vtk_types.size() << std::endl; for (std::vector<unsigned>::const_iterator i = vtk_types.begin(); i != vtk_types.end(); ++i) stream << *i << std::endl; return MB_SUCCESS; }
ErrorCode DenseTag::find_entities_with_value( const SequenceManager* seqman, Error* error, Range& output_entities, const void* value, int value_bytes, EntityType type, const Range* intersect_entities ) const { if (value_bytes && value_bytes != get_size()) { error->set_last_error( "Cannot compare data of size %d with tag of size %d", value_bytes, get_size() ); return MB_INVALID_SIZE; } if (!intersect_entities) { std::pair<EntityType,EntityType> range = type_range(type); TypeSequenceManager::const_iterator i; for (EntityType t = range.first; t != range.second; ++i) { const TypeSequenceManager& map = seqman->entity_map(t); for (i = map.begin(); i != map.end(); ++i) { const void* data = (*i)->data()->get_tag_data( mySequenceArray ); if (data) { ByteArrayIterator start( (*i)->data()->start_handle(), data, *this ); ByteArrayIterator end( (*i)->end_handle() + 1, 0, 0 ); start += (*i)->start_handle() - (*i)->data()->start_handle(); find_tag_values_equal( *this, value, get_size(), start, end, output_entities ); } } } } else { const unsigned char* array = NULL; // initialize to get rid of warning size_t count; ErrorCode rval; Range::const_pair_iterator p = intersect_entities->begin(); if (type != MBMAXTYPE) { p = intersect_entities->lower_bound(type); assert(TYPE_FROM_HANDLE(p->first) == type); } for (; p != intersect_entities->const_pair_end() && (MBMAXTYPE == type || TYPE_FROM_HANDLE(p->first) == type); ++p) { EntityHandle start = p->first; while (start <= p->second) { rval = get_array( seqman, error, start, array, count ); if (MB_SUCCESS != rval) return rval; if (p->second - start < count-1) count = p->second - start + 1; if (array) { ByteArrayIterator istart( start, array, *this ); ByteArrayIterator iend( start+count, 0, 0 ); find_tag_values_equal( *this, value, get_size(), istart, iend, output_entities ); } start += count; } } } return MB_SUCCESS; }
EntityType type() const { return TYPE_FROM_HANDLE(start_handle()); }
static ErrorCode not_root_set(const std::string& name, EntityHandle h) { MB_SET_ERR(MB_VARIABLE_DATA_LENGTH, "Cannot get/set mesh/global tag " << name << " on non-root-set " << CN::EntityTypeName(TYPE_FROM_HANDLE(h)) << " " << (unsigned long)ID_FROM_HANDLE(h)); }
ErrorCode WriteTemplate::gather_mesh_information(MeshInfo &mesh_info, std::vector<WriteTemplate::MaterialSetData> &matset_info, std::vector<WriteTemplate::NeumannSetData> &neuset_info, std::vector<WriteTemplate::DirichletSetData> &dirset_info, std::vector<EntityHandle> &matsets, std::vector<EntityHandle> &neusets, std::vector<EntityHandle> &dirsets) { std::vector<EntityHandle>::iterator vector_iter, end_vector_iter; mesh_info.num_nodes = 0; mesh_info.num_elements = 0; mesh_info.num_matsets = 0; int id = 0; vector_iter= matsets.begin(); end_vector_iter = matsets.end(); mesh_info.num_matsets = matsets.size(); std::vector<EntityHandle> parent_meshsets; // clean out the bits for the element mark mbImpl->tag_delete(mEntityMark); mbImpl->tag_get_handle("WriteTemplate element mark", 1, MB_TYPE_BIT, mEntityMark, MB_TAG_CREAT); int highest_dimension_of_element_matsets = 0; for(vector_iter = matsets.begin(); vector_iter != matsets.end(); vector_iter++) { WriteTemplate::MaterialSetData matset_data; matset_data.elements = new Range; //for the purpose of qa records, get the parents of these matsets if( mbImpl->get_parent_meshsets( *vector_iter, parent_meshsets ) != MB_SUCCESS ) return MB_FAILURE; // get all Entity Handles in the mesh set Range dummy_range; mbImpl->get_entities_by_handle(*vector_iter, dummy_range, true ); // find the dimension of the last entity in this range Range::iterator entity_iter = dummy_range.end(); entity_iter = dummy_range.end(); entity_iter--; int this_dim = CN::Dimension(TYPE_FROM_HANDLE(*entity_iter)); entity_iter = dummy_range.begin(); while (entity_iter != dummy_range.end() && CN::Dimension(TYPE_FROM_HANDLE(*entity_iter)) != this_dim) entity_iter++; if (entity_iter != dummy_range.end()) std::copy(entity_iter, dummy_range.end(), range_inserter(*(matset_data.elements))); assert(matset_data.elements->begin() == matset_data.elements->end() || CN::Dimension(TYPE_FROM_HANDLE(*(matset_data.elements->begin()))) == this_dim); // get the matset's id if(mbImpl->tag_get_data(mMaterialSetTag, &(*vector_iter), 1, &id) != MB_SUCCESS ) { mWriteIface->report_error("Couldn't get matset id from a tag for an element matset."); return MB_FAILURE; } matset_data.id = id; matset_data.number_attributes = 0; // iterate through all the elements in the meshset Range::iterator elem_range_iter, end_elem_range_iter; elem_range_iter = matset_data.elements->begin(); end_elem_range_iter = matset_data.elements->end(); // get the entity type for this matset, verifying that it's the same for all elements // THIS ASSUMES HANDLES SORT BY TYPE!!! EntityType entity_type = TYPE_FROM_HANDLE(*elem_range_iter); end_elem_range_iter--; if (entity_type != TYPE_FROM_HANDLE(*(end_elem_range_iter++))) { mWriteIface->report_error("Entities in matset %i not of common type", id); return MB_FAILURE; } int dimension = CN::Dimension(entity_type); if( dimension > highest_dimension_of_element_matsets ) highest_dimension_of_element_matsets = dimension; matset_data.moab_type = mbImpl->type_from_handle(*(matset_data.elements->begin())); if (MBMAXTYPE == matset_data.moab_type) return MB_FAILURE; std::vector<EntityHandle> tmp_conn; mbImpl->get_connectivity(&(*(matset_data.elements->begin())), 1, tmp_conn); matset_data.element_type = ExoIIUtil::get_element_type_from_num_verts(tmp_conn.size(), entity_type, dimension); if (matset_data.element_type == EXOII_MAX_ELEM_TYPE) { mWriteIface->report_error("Element type in matset %i didn't get set correctly", id); return MB_FAILURE; } matset_data.number_nodes_per_element = ExoIIUtil::VerticesPerElement[matset_data.element_type]; // number of nodes for this matset matset_data.number_elements = matset_data.elements->size(); // total number of elements mesh_info.num_elements += matset_data.number_elements; // get the nodes for the elements mWriteIface->gather_nodes_from_elements(*matset_data.elements, mEntityMark, mesh_info.nodes); if(!neusets.empty()) { // if there are neusets, keep track of which elements are being written out for(Range::iterator iter = matset_data.elements->begin(); iter != matset_data.elements->end(); ++iter) { unsigned char bit = 0x1; mbImpl->tag_set_data(mEntityMark, &(*iter), 1, &bit); } } matset_info.push_back( matset_data ); } //if user hasn't entered dimension, we figure it out if( mesh_info.num_dim == 0 ) { //never want 1 or zero dimensions if( highest_dimension_of_element_matsets < 2 ) mesh_info.num_dim = 3; else mesh_info.num_dim = highest_dimension_of_element_matsets; } Range::iterator range_iter, end_range_iter; range_iter = mesh_info.nodes.begin(); end_range_iter = mesh_info.nodes.end(); mesh_info.num_nodes = mesh_info.nodes.size(); //------dirsets-------- vector_iter= dirsets.begin(); end_vector_iter = dirsets.end(); for(; vector_iter != end_vector_iter; vector_iter++) { WriteTemplate::DirichletSetData dirset_data; dirset_data.id = 0; dirset_data.number_nodes = 0; // get the dirset's id if(mbImpl->tag_get_data(mDirichletSetTag,&(*vector_iter), 1,&id) != MB_SUCCESS) { mWriteIface->report_error("Couldn't get id tag for dirset %i", id); return MB_FAILURE; } dirset_data.id = id; std::vector<EntityHandle> node_vector; //get the nodes of the dirset that are in mesh_info.nodes if( mbImpl->get_entities_by_handle(*vector_iter, node_vector, true) != MB_SUCCESS ) { mWriteIface->report_error("Couldn't get nodes in dirset %i", id); return MB_FAILURE; } std::vector<EntityHandle>::iterator iter, end_iter; iter = node_vector.begin(); end_iter= node_vector.end(); int j=0; unsigned char node_marked = 0; ErrorCode result; for(; iter != end_iter; iter++) { if (TYPE_FROM_HANDLE(*iter) != MBVERTEX) continue; result = mbImpl->tag_get_data(mEntityMark, &(*iter), 1, &node_marked); if (MB_SUCCESS != result) { mWriteIface->report_error("Couldn't get mark data."); return result; } if(node_marked == 0x1) dirset_data.nodes.push_back( *iter ); j++; } dirset_data.number_nodes = dirset_data.nodes.size(); dirset_info.push_back( dirset_data ); } //------neusets-------- vector_iter= neusets.begin(); end_vector_iter = neusets.end(); for(; vector_iter != end_vector_iter; vector_iter++) { WriteTemplate::NeumannSetData neuset_data; // get the neuset's id if(mbImpl->tag_get_data(mNeumannSetTag,&(*vector_iter), 1,&id) != MB_SUCCESS) return MB_FAILURE; neuset_data.id = id; neuset_data.mesh_set_handle = *vector_iter; //get the sides in two lists, one forward the other reverse; starts with forward sense // by convention Range forward_elems, reverse_elems; if(get_neuset_elems(*vector_iter, 0, forward_elems, reverse_elems) == MB_FAILURE) return MB_FAILURE; ErrorCode result = get_valid_sides(forward_elems, 1, neuset_data); if (MB_SUCCESS != result) { mWriteIface->report_error("Couldn't get valid sides data."); return result; } result = get_valid_sides(reverse_elems, -1, neuset_data); if (MB_SUCCESS != result) { mWriteIface->report_error("Couldn't get valid sides data."); return result; } neuset_data.number_elements = neuset_data.elements.size(); neuset_info.push_back( neuset_data ); } return MB_SUCCESS; }
ErrorCode WriteTemplate::get_valid_sides(Range &elems, const int sense, WriteTemplate::NeumannSetData &neuset_data) { // this is where we see if underlying element of side set element is included in output unsigned char element_marked = 0; ErrorCode result; for(Range::iterator iter = elems.begin(); iter != elems.end(); iter++) { // should insert here if "side" is a quad/tri on a quad/tri mesh result = mbImpl->tag_get_data(mEntityMark, &(*iter), 1, &element_marked); if (MB_SUCCESS != result) { mWriteIface->report_error("Couldn't get mark data."); return result; } if(element_marked == 0x1) { neuset_data.elements.push_back( *iter ); // TJT TODO: the sense should really be # edges + 1or2 neuset_data.side_numbers.push_back((sense == 1 ? 1 : 2)); } else //then "side" is probably a quad/tri on a hex/tet mesh { std::vector<EntityHandle> parents; int dimension = CN::Dimension( TYPE_FROM_HANDLE(*iter)); //get the adjacent parent element of "side" if( mbImpl->get_adjacencies( &(*iter), 1, dimension+1, false, parents) != MB_SUCCESS ) { mWriteIface->report_error("Couldn't get adjacencies for neuset."); return MB_FAILURE; } if(!parents.empty()) { //make sure the adjacent parent element will be output for(unsigned int k=0; k<parents.size(); k++) { result = mbImpl->tag_get_data(mEntityMark, &(parents[k]), 1, &element_marked); if (MB_SUCCESS != result) { mWriteIface->report_error("Couldn't get mark data."); return result; } int side_no, this_sense, this_offset; if(element_marked == 0x1 && mbImpl->side_number(parents[k], *iter, side_no, this_sense, this_offset) == MB_SUCCESS && this_sense == sense) { neuset_data.elements.push_back(parents[k]); neuset_data.side_numbers.push_back(side_no+1); break; } } } else { mWriteIface->report_error("No parent element exists for element in neuset %i", neuset_data.id); return MB_FAILURE; } } } return MB_SUCCESS; }
ErrorCode VerdictWrapper::all_quality_measures(EntityHandle eh, std::map<QualityType, double> & qualities) { EntityType etype = TYPE_FROM_HANDLE(eh); if (etype == MBPOLYHEDRON || etype == MBVERTEX || etype == MBENTITYSET) return MB_SUCCESS; // no quality for polyhedron or vertex or set double coordinates[27][3]; // at most 27 nodes per element // get coordinates of points, if not passed already const EntityHandle * conn = NULL; int num_nodes; ErrorCode rval = mbImpl->get_connectivity(eh, conn, num_nodes); if (rval != MB_SUCCESS) return rval; rval = mbImpl->get_coords(conn, num_nodes, &(coordinates[0][0])); if (rval != MB_SUCCESS) return rval; switch (etype) { case MBEDGE: { double leng = v_edge_length(2, coordinates); qualities[MB_LENGTH] = leng; break; } case MBHEX: { num_nodes = 8; HexMetricVals hexMetric; v_hex_quality(num_nodes, coordinates, V_HEX_ALL, &hexMetric); qualities[MB_EDGE_RATIO] = hexMetric.edge_ratio; qualities[MB_MAX_EDGE_RATIO] = hexMetric.max_edge_ratio; qualities[MB_SKEW] = hexMetric.skew; qualities[MB_TAPER] = hexMetric.taper; qualities[MB_VOLUME] = hexMetric.volume; qualities[MB_STRETCH] = hexMetric.stretch; qualities[MB_DIAGONAL] = hexMetric.diagonal; qualities[MB_DIMENSION] = hexMetric.dimension; qualities[MB_ODDY] = hexMetric.oddy; qualities[MB_MED_ASPECT_FROBENIUS] = hexMetric.med_aspect_frobenius; // MB_CONDITION is the same as MB_MAX_ASPECT_FROBENIUS qualities[MB_MAX_ASPECT_FROBENIUS] = hexMetric.condition; qualities[MB_CONDITION] = hexMetric.condition; qualities[MB_JACOBIAN] = hexMetric.jacobian; qualities[MB_SCALED_JACOBIAN] = hexMetric.scaled_jacobian; qualities[MB_SHEAR] = hexMetric.shear; qualities[MB_SHAPE] = hexMetric.shape; qualities[MB_RELATIVE_SIZE_SQUARED] = hexMetric.relative_size_squared; qualities[MB_SHAPE_AND_SIZE] = hexMetric.shape_and_size; qualities[MB_SHEAR_AND_SIZE] = hexMetric.shear_and_size; qualities[MB_DISTORTION] = hexMetric.distortion; break; } case MBTET: { num_nodes = 4; TetMetricVals tetMetrics; v_tet_quality(num_nodes, coordinates, V_TET_ALL, &tetMetrics); qualities[MB_EDGE_RATIO]=tetMetrics.edge_ratio; qualities[MB_RADIUS_RATIO] = tetMetrics.radius_ratio; qualities[MB_ASPECT_BETA] = tetMetrics.aspect_beta; qualities[MB_ASPECT_RATIO] = tetMetrics.aspect_ratio; qualities[MB_ASPECT_GAMMA] = tetMetrics.aspect_gamma; qualities[MB_MAX_ASPECT_FROBENIUS] = tetMetrics.aspect_frobenius; qualities[MB_MINIMUM_ANGLE] = tetMetrics.minimum_angle; qualities[MB_COLLAPSE_RATIO] = tetMetrics.collapse_ratio; qualities[MB_VOLUME] = tetMetrics.volume; qualities[MB_CONDITION] = tetMetrics.condition; qualities[MB_JACOBIAN] = tetMetrics.jacobian; qualities[MB_SCALED_JACOBIAN] = tetMetrics.scaled_jacobian; qualities[MB_SHAPE] = tetMetrics.shape; qualities[MB_RELATIVE_SIZE_SQUARED] = tetMetrics.relative_size_squared; qualities[MB_SHAPE_AND_SIZE] = tetMetrics.shape_and_size; qualities[MB_DISTORTION] = tetMetrics.distortion; break; } case MBPRISM: { num_nodes = 6; double volu = v_wedge_volume(num_nodes, coordinates); qualities[MB_VOLUME] = volu; break; } case MBKNIFE: { num_nodes = 7; double volu = v_knife_volume(num_nodes, coordinates); qualities[MB_VOLUME] = volu; break; } case MBQUAD: { num_nodes = 4; QuadMetricVals quadMetrics; v_quad_quality(num_nodes, coordinates, V_QUAD_ALL, &quadMetrics); qualities[MB_EDGE_RATIO] = quadMetrics.edge_ratio; qualities[MB_MAX_EDGE_RATIO] = quadMetrics.max_edge_ratio; qualities[MB_ASPECT_RATIO] = quadMetrics.aspect_ratio; // 23 qualities[MB_RADIUS_RATIO] = quadMetrics.radius_ratio; // 21 qualities[MB_MED_ASPECT_FROBENIUS] = quadMetrics.med_aspect_frobenius; // 9 qualities[MB_MAX_ASPECT_FROBENIUS] = quadMetrics.max_aspect_frobenius; //10 qualities[MB_SKEW] = quadMetrics.skew; // 2 qualities[MB_TAPER] = quadMetrics.taper; // 3 qualities[MB_WARPAGE] = quadMetrics.warpage; // 27 qualities[MB_AREA] = quadMetrics.area; // 28 qualities[MB_STRETCH] = quadMetrics.stretch; // 5 qualities[MB_MINIMUM_ANGLE] = quadMetrics.minimum_angle; // 25 qualities[MB_MAXIMUM_ANGLE] = quadMetrics.maximum_angle; // 29 qualities[MB_ODDY] = quadMetrics.oddy; // 8 qualities[MB_CONDITION] = quadMetrics.condition; // 11 qualities[MB_JACOBIAN] = quadMetrics.jacobian; // 12 qualities[MB_SCALED_JACOBIAN] = quadMetrics.scaled_jacobian; // 13 qualities[MB_SHEAR] = quadMetrics.shear; // 14 qualities[MB_SHAPE] = quadMetrics.shape; // 15 qualities[MB_RELATIVE_SIZE_SQUARED] = quadMetrics.relative_size_squared; // 16 qualities[MB_SHAPE_AND_SIZE] = quadMetrics.shape_and_size; // 17 qualities[MB_SHEAR_AND_SIZE] = quadMetrics.shear_and_size; // 18 qualities[MB_DISTORTION] = quadMetrics.distortion; // 19 break; } case MBTRI: { num_nodes = 3; TriMetricVals triMetrics; v_tri_quality(num_nodes, coordinates, V_TRI_ALL, &triMetrics); qualities[MB_EDGE_RATIO] = triMetrics.edge_ratio; // 0 qualities[MB_ASPECT_RATIO] = triMetrics.aspect_ratio; // 23 qualities[MB_RADIUS_RATIO] = triMetrics.radius_ratio; // 21 qualities[MB_MAX_ASPECT_FROBENIUS] = triMetrics.aspect_frobenius; // 10 qualities[MB_AREA] = triMetrics.area; // 28 qualities[MB_MINIMUM_ANGLE] = triMetrics.minimum_angle; // 25 qualities[MB_MAXIMUM_ANGLE] = triMetrics.maximum_angle; // 29 qualities[MB_CONDITION] = triMetrics.condition; // 11 qualities[MB_SCALED_JACOBIAN] = triMetrics.scaled_jacobian; // 13 // does not exist, even though it was defined in verdict.h; remove it from there too // case MB_SHEAR: func = v_tri_shear; break; // 14 qualities[MB_RELATIVE_SIZE_SQUARED] = triMetrics.relative_size_squared; // 16 qualities[MB_SHAPE] = triMetrics.shape; // 15 qualities[MB_SHAPE_AND_SIZE] = triMetrics.shape_and_size; // 17 qualities[MB_DISTORTION] = triMetrics.distortion; // 19 break; } default: return MB_NOT_IMPLEMENTED; } return MB_SUCCESS; }
ErrorCode VerdictWrapper::quality_measure(EntityHandle eh, QualityType q, double & quality, int num_nodes, EntityType etype, double * coords) { double coordinates[27][3]; // at most 27 nodes per element if (0==num_nodes && NULL==coords) { etype= TYPE_FROM_HANDLE(eh); if (possibleQuality[etype][q]==0) return MB_NOT_IMPLEMENTED; // get coordinates of points, if not passed already const EntityHandle * conn = NULL; //int num_nodes; ErrorCode rval = mbImpl->get_connectivity(eh, conn, num_nodes); if (rval!=MB_SUCCESS) return rval; if (etype!=MBPOLYHEDRON) { rval = mbImpl->get_coords(conn, num_nodes, &(coordinates[0][0])); if (rval!=MB_SUCCESS) return rval; } } else { if (num_nodes > 27) return MB_FAILURE; for (int i=0; i<num_nodes; i++) { for (int j=0; j<3; j++) coordinates[i][j]=coords[3*i+j]; } } VerdictFunction func=0; switch(etype) { case MBHEX: { num_nodes = 8; switch(q) { case MB_EDGE_RATIO: func = v_hex_edge_ratio; break; // 0 case MB_MAX_EDGE_RATIO: func = v_hex_max_edge_ratio; break; // 1 case MB_SKEW: func = v_hex_skew; break; // 2 case MB_TAPER: func = v_hex_taper; break; // 3 case MB_VOLUME: func = v_hex_volume; break; // 4 case MB_STRETCH: func = v_hex_stretch; break; // 5 case MB_DIAGONAL: func = v_hex_diagonal; break; // 6 case MB_DIMENSION: func = v_hex_dimension; break; // 7 case MB_ODDY: func = v_hex_oddy; break; // 8 case MB_MED_ASPECT_FROBENIUS: func = v_hex_med_aspect_frobenius; break;// 9 case MB_MAX_ASPECT_FROBENIUS: func = v_hex_max_aspect_frobenius; break;// 10 case MB_CONDITION: func = v_hex_condition; break; // 11 case MB_JACOBIAN: func = v_hex_jacobian; break; // 12 case MB_SCALED_JACOBIAN: func = v_hex_scaled_jacobian; break; // 13 case MB_SHEAR: func = v_hex_shear; break; // 14 case MB_SHAPE: func = v_hex_shape; break; // 15 case MB_RELATIVE_SIZE_SQUARED: func = v_hex_relative_size_squared; break; // 16 case MB_SHAPE_AND_SIZE: func = v_hex_shape_and_size; break ; // 17 case MB_SHEAR_AND_SIZE: func = v_hex_shear_and_size; break; // 18 case MB_DISTORTION: func = v_hex_distortion; break; // 19 default : return MB_FAILURE; } break; } case MBEDGE: { num_nodes = 2; switch (q) { case MB_LENGTH: func = v_edge_length; break; // 20 default : return MB_FAILURE; } break; } case MBTET: { num_nodes = 4; switch (q) { case MB_EDGE_RATIO: func = v_tet_edge_ratio; break; // 0 //! Calculates tet edge ratio metric. case MB_RADIUS_RATIO: func = v_tet_radius_ratio; break; // 21 case MB_ASPECT_BETA: func = v_tet_aspect_beta; break; // 22 case MB_ASPECT_RATIO: func = v_tet_aspect_ratio; break; // 23 case MB_ASPECT_GAMMA: func = v_tet_aspect_gamma; break; // 24 case MB_MAX_ASPECT_FROBENIUS: func = v_tet_aspect_frobenius; break; // 10 case MB_MINIMUM_ANGLE: func = v_tet_minimum_angle; break; // 25 case MB_COLLAPSE_RATIO: func = v_tet_collapse_ratio; break; // 26 case MB_VOLUME: func = v_tet_volume; break; // 4 case MB_CONDITION: func = v_tet_condition; break; // 11 case MB_JACOBIAN: func = v_tet_jacobian; break; // 12 case MB_SCALED_JACOBIAN: func = v_tet_scaled_jacobian; break; // 13 case MB_SHAPE: func = v_tet_shape; break; // 15 case MB_RELATIVE_SIZE_SQUARED: func = v_tet_relative_size_squared; break;// 16 case MB_SHAPE_AND_SIZE: func = v_tet_shape_and_size; break; // 17 case MB_DISTORTION: func = v_tet_distortion; break; // 19 default : return MB_FAILURE; } break; } case MBPRISM: { num_nodes = 6; switch (q) { case MB_VOLUME: func = v_wedge_volume; break; // 4 default : return MB_FAILURE; } break; } case MBKNIFE: { num_nodes = 7; switch (q) { case MB_VOLUME: func = v_knife_volume; break; // 4 default : return MB_FAILURE; } break; } case MBQUAD: { num_nodes = 4; switch (q) { case MB_EDGE_RATIO: func = v_quad_edge_ratio; break; // 0 case MB_MAX_EDGE_RATIO: func = v_quad_max_edge_ratio; break; // 1 case MB_ASPECT_RATIO: func = v_quad_aspect_ratio; break; // 23 case MB_RADIUS_RATIO: func = v_quad_radius_ratio; break; // 21 case MB_MED_ASPECT_FROBENIUS: func = v_quad_med_aspect_frobenius; break;// 9 case MB_MAX_ASPECT_FROBENIUS: func = v_quad_max_aspect_frobenius; break;//10 case MB_SKEW: func = v_quad_skew; break; // 2 case MB_TAPER: func = v_quad_taper; break; // 3 case MB_WARPAGE: func = v_quad_warpage; break; // 27 case MB_AREA: func = v_quad_area; break; // 28 case MB_STRETCH: func = v_quad_stretch; break; // 5 case MB_MINIMUM_ANGLE: func = v_quad_minimum_angle; break; // 25 case MB_MAXIMUM_ANGLE: func = v_quad_maximum_angle; break; // 29 case MB_ODDY: func = v_quad_oddy; break; // 8 case MB_CONDITION: func = v_quad_condition; break; // 11 case MB_JACOBIAN: func = v_quad_jacobian; break; // 12 case MB_SCALED_JACOBIAN: func = v_quad_scaled_jacobian; break; // 13 case MB_SHEAR: func = v_quad_shear; break; // 14 case MB_SHAPE: func = v_quad_shape; break; // 15 case MB_RELATIVE_SIZE_SQUARED: func = v_quad_relative_size_squared; break; // 16 case MB_SHAPE_AND_SIZE: func = v_quad_shape_and_size; break ; // 17 case MB_SHEAR_AND_SIZE: func = v_quad_shear_and_size; break; // 18 case MB_DISTORTION: func = v_quad_distortion; break; // 19 default : return MB_FAILURE; } break; } case MBTRI: { num_nodes = 3; switch(q) { case MB_EDGE_RATIO: func = v_tri_edge_ratio; break; // 0 case MB_ASPECT_RATIO: func = v_tri_aspect_ratio; break; // 23 case MB_RADIUS_RATIO: func = v_tri_radius_ratio; break; // 21 case MB_MAX_ASPECT_FROBENIUS: func = v_tri_aspect_frobenius; break; // 10 case MB_AREA: func = v_tri_area; break; // 28 case MB_MINIMUM_ANGLE: func = v_tri_minimum_angle; break; // 25 case MB_MAXIMUM_ANGLE: func = v_tri_maximum_angle; break; // 29 case MB_CONDITION: func = v_tri_condition; break; // 11 case MB_SCALED_JACOBIAN: func = v_tri_scaled_jacobian; break; // 13 // does not exist, even though it was defined in verdict.h; remove it from there too // case MB_SHEAR: func = v_tri_shear; break; // 14 case MB_RELATIVE_SIZE_SQUARED: func = v_tri_relative_size_squared; break; // 16 case MB_SHAPE: func = v_tri_shape; break; // 15 case MB_SHAPE_AND_SIZE: func = v_tri_shape_and_size; break ; // 17 case MB_DISTORTION: func = v_tri_distortion; break; // 19 default : return MB_FAILURE; } break; } default : break; // some have no measures } if (!func) return MB_NOT_IMPLEMENTED; // actual computation happens here quality = (*func)(num_nodes, coordinates); return MB_SUCCESS; }
bool operator()( EntityHandle h ) { return TYPE_FROM_HANDLE(h) == type; }