//====================================================================== // Function: dist_to_edge // Description: return the distance from the point to this edge // Author: sjowen // Date: 2/01 // Corrected by JFowler 5/03 //====================================================================== double CubitFacetEdge::dist_to_edge( const CubitVector &this_point, CubitVector &close_point, CubitBoolean &outside_edge ) { double dist = 0.0; CubitVector p0 = point(0)->coordinates(); CubitVector p1 = point(1)->coordinates(); CubitVector edge_vec( p1, p0 ); CubitVector point_vec( this_point, p0 ); double edge_length; edge_length = edge_vec.normalize(); double dist_on_edge = edge_vec % point_vec; if (dist_on_edge < 0.0e0) { close_point = p0; outside_edge = CUBIT_TRUE; } else if (dist_on_edge > edge_length) { close_point = p1; outside_edge = CUBIT_TRUE; } else { close_point = p0 - edge_vec * dist_on_edge; outside_edge = CUBIT_FALSE; } dist = close_point.distance_between( this_point ); return dist; }
//====================================================================== // Function: proj_to_line // Description: project the point to a line defined by the edge // Author: sjowen // Date: 2/01 //====================================================================== CubitStatus CubitFacetEdge::proj_to_line( const CubitVector &this_point, CubitVector &proj_point ) { CubitStatus stat = CUBIT_SUCCESS; CubitVector p0 = point(0)->coordinates(); CubitVector p1 = point(1)->coordinates(); CubitVector edge_vec( p0,p1 ); CubitVector point_vec( p0, this_point ); edge_vec.normalize(); double dist_on_edge = edge_vec % point_vec; proj_point = p0 + (edge_vec * dist_on_edge); return stat; }
int TestLocalRefinerTri_N_3_EdgeBasedAnisotropic::mark( const stk::mesh::Entity& element, unsigned which_edge, stk::mesh::Entity & node0, stk::mesh::Entity & node1, double *coord0, double *coord1, std::vector<int>* existing_edge_marks) { int mark=0; const int spatial_dim = m_eMesh.get_spatial_dim(); std::vector<double> hessian(spatial_dim*spatial_dim, 0.0); // Hessian from midpoint interp of nodal Hessian field const double *hess0 = stk::mesh::field_data( *m_nodal_hessian_field , node0); const double *hess1 = stk::mesh::field_data( *m_nodal_hessian_field , node1); for (int d=0; d<spatial_dim*spatial_dim; d++) { hessian[d] += 0.5*(hess0[d]+hess1[d]); } std::vector<double> edge_vec(spatial_dim, 0.0); double length = 0; for (int d=0; d<spatial_dim; d++) { edge_vec[d] = coord0[d] - coord1[d]; length += edge_vec[d]*edge_vec[d]; } length = sqrt(length); // Test 1: modified eigenvalues of (diag) Hessian /* const double local_error_tol = 0.001; // HACK assuming diag hessian for now std::vector<double> lambda(spatial_dim, 0.0); for (int d=0; d<spatial_dim; d++) { lambda[d] = std::min(std::max(avg_hessian[d]/local_error_tol, 1./(length_max*length_max)), 1./(length_min*length_min)); } // calc metric, length at midpoint double local_metric2 = 0; // HACK assuming diag hessian for (int d=0; d<spatial_dim; d++) { local_metric2 += lambda[d] * edge_vec[d] * edge_vec[d]; } const double metric = sqrt(local_metric2) * length_max; */ // Test 2: scaled, modified metric /* double local_metric = 0; double local_length = 0; for (int d1=0; d1<spatial_dim; d1++) { for (int d2=0; d2<spatial_dim; d2++) { local_metric += avg_hessian[d1+d2*spatial_dim]*edge_vec[d1]*edge_vec[d2]; } local_length += edge_vec[d1]*edge_vec[d1]; } local_metric = sqrt(local_metric); local_length = sqrt(local_length); */ // Test 2.1: metric is ratio of current to optimal mesh size /* double inv_h_opt = local_metric / local_length; // rescale to maintain min/max mesh size // length_min < h_opt < length_max // => 1/length_max < inv_h_opt < 1/length_min // TEST for refinement only replace length_max with local_length //inv_h_opt = std::min(std::max(inv_h_opt, 1./length_max), 1./length_min); inv_h_opt = std::min(std::max(inv_h_opt, 1./local_length), 1./length_min); const double metric = 1. / (local_length * inv_h_opt); */ // Test 2.2: mark if local_metric > 0 /* const double metric = (local_metric > 0) ? 2*m_Rup : 0.5*m_Rup; */ double seminorm = 0; for (int d1=0; d1<spatial_dim; d1++) { for (int d2=0; d2<spatial_dim; d2++) { seminorm += hessian[d1+d2*spatial_dim]*edge_vec[d1]*edge_vec[d2]; } } if ( seminorm < 0 ) { throw std::logic_error("hessian matrix is non SPD!!"); } seminorm = sqrt(seminorm); // ideally the seminorm should = (h / h_opt) // to enforce bounds on h_opt, we bound the seminorm // (h / length_max) <= seminorm <= (h / length_min) double metric = std::min(std::max(seminorm, length / length_max), length / length_min); // TEST simplest case: metric > Rup if (metric > m_upper_bound) { mark |= DO_REFINE; } // else if (metric < m_lower_bound) { // mark |= DO_UNREFINE; // } // else { // mark |= DO_NOTHING; // } return mark; }