예제 #1
0
//====================================================================== 
// 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; 
}
예제 #2
0
//====================================================================== 
// 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;
    }