Real InfHex::quality (const ElemQuality q) const { switch (q) { /** * Compue the min/max diagonal ratio. * Source: CUBIT User's Manual. * * For infinite elements, we just only compute * the diagonal in the face... * Don't know whether this makes sense, * but should be a feasible way. */ case DIAGONAL: { // Diagonal between node 0 and node 2 const Real d02 = this->length(0,2); // Diagonal between node 1 and node 3 const Real d13 = this->length(1,3); // Find the biggest and smallest diagonals const Real min = std::min(d02, d13); const Real max = std::max(d02, d13); libmesh_assert_not_equal_to (max, 0.0); return min / max; break; } /** * Minimum ratio of lengths derived from opposite edges. * Source: CUBIT User's Manual. * * For IFEMs, do this only for the base face... * Does this make sense? */ case TAPER: { /** * Compute the side lengths. */ const Real d01 = this->length(0,1); const Real d12 = this->length(1,2); const Real d23 = this->length(2,3); const Real d03 = this->length(0,3); std::vector<Real> edge_ratios(2); // Bottom edge_ratios[8] = std::min(d01, d23) / std::max(d01, d23); edge_ratios[9] = std::min(d03, d12) / std::max(d03, d12); return *(std::min_element(edge_ratios.begin(), edge_ratios.end())) ; break; } /** * Minimum edge length divided by max diagonal length. * Source: CUBIT User's Manual. * * And again, we mess around a bit, for the IFEMs... * Do this only for the base. */ case STRETCH: { /** * Should this be a sqrt2, when we do this for the base only? */ const Real sqrt3 = 1.73205080756888; /** * Compute the maximum diagonal in the base. */ const Real d02 = this->length(0,2); const Real d13 = this->length(1,3); const Real max_diag = std::max(d02, d13); libmesh_assert_not_equal_to ( max_diag, 0.0 ); /** * Compute the minimum edge length in the base. */ std::vector<Real> edges(4); edges[0] = this->length(0,1); edges[1] = this->length(1,2); edges[2] = this->length(2,3); edges[3] = this->length(0,3); const Real min_edge = *(std::min_element(edges.begin(), edges.end())); return sqrt3 * min_edge / max_diag ; break; } /** * I don't know what to do for this metric. * Maybe the base class knows... */ default: { return Elem::quality(q); } } // Will never get here... libmesh_error(); return 0.; }
Real Hex::quality (const ElemQuality q) const { switch (q) { /** * Compue the min/max diagonal ratio. * Source: CUBIT User's Manual. */ case DIAGONAL: { // Diagonal between node 0 and node 6 const Real d06 = this->length(0,6); // Diagonal between node 3 and node 5 const Real d35 = this->length(3,5); // Diagonal between node 1 and node 7 const Real d17 = this->length(1,7); // Diagonal between node 2 and node 4 const Real d24 = this->length(2,4); // Find the biggest and smallest diagonals const Real min = std::min(d06, std::min(d35, std::min(d17, d24))); const Real max = std::max(d06, std::max(d35, std::max(d17, d24))); libmesh_assert_not_equal_to (max, 0.0); return min / max; break; } /** * Minimum ratio of lengths derived from opposite edges. * Source: CUBIT User's Manual. */ case TAPER: { /** * Compute the side lengths. */ const Real d01 = this->length(0,1); const Real d12 = this->length(1,2); const Real d23 = this->length(2,3); const Real d03 = this->length(0,3); const Real d45 = this->length(4,5); const Real d56 = this->length(5,6); const Real d67 = this->length(6,7); const Real d47 = this->length(4,7); const Real d04 = this->length(0,4); const Real d15 = this->length(1,5); const Real d37 = this->length(3,7); const Real d26 = this->length(2,6); std::vector<Real> edge_ratios(12); // Front edge_ratios[0] = std::min(d01, d45) / std::max(d01, d45); edge_ratios[1] = std::min(d04, d15) / std::max(d04, d15); // Right edge_ratios[2] = std::min(d15, d26) / std::max(d15, d26); edge_ratios[3] = std::min(d12, d56) / std::max(d12, d56); // Back edge_ratios[4] = std::min(d67, d23) / std::max(d67, d23); edge_ratios[5] = std::min(d26, d37) / std::max(d26, d37); // Left edge_ratios[6] = std::min(d04, d37) / std::max(d04, d37); edge_ratios[7] = std::min(d03, d47) / std::max(d03, d47); // Bottom edge_ratios[8] = std::min(d01, d23) / std::max(d01, d23); edge_ratios[9] = std::min(d03, d12) / std::max(d03, d12); // Top edge_ratios[10] = std::min(d45, d67) / std::max(d45, d67); edge_ratios[11] = std::min(d56, d47) / std::max(d56, d47); return *(std::min_element(edge_ratios.begin(), edge_ratios.end())) ; break; } /** * Minimum edge length divided by max diagonal length. * Source: CUBIT User's Manual. */ case STRETCH: { const Real sqrt3 = 1.73205080756888; /** * Compute the maximum diagonal. */ const Real d06 = this->length(0,6); const Real d17 = this->length(1,7); const Real d35 = this->length(3,5); const Real d24 = this->length(2,4); const Real max_diag = std::max(d06, std::max(d17, std::max(d35, d24))); libmesh_assert_not_equal_to ( max_diag, 0.0 ); /** * Compute the minimum edge length. */ std::vector<Real> edges(12); edges[0] = this->length(0,1); edges[1] = this->length(1,2); edges[2] = this->length(2,3); edges[3] = this->length(0,3); edges[4] = this->length(4,5); edges[5] = this->length(5,6); edges[6] = this->length(6,7); edges[7] = this->length(4,7); edges[8] = this->length(0,4); edges[9] = this->length(1,5); edges[10] = this->length(2,6); edges[11] = this->length(3,7); const Real min_edge = *(std::min_element(edges.begin(), edges.end())); return sqrt3 * min_edge / max_diag ; } /** * I don't know what to do for this metric. * Maybe the base class knows... */ default: return Elem::quality(q); } libmesh_error_msg("We'll never get here!"); return 0.; }