Beispiel #1
0
static Element * mesh_find_large_element( const Mesh *mesh, gdouble max_element_area )
{
    GList *elements_iter;
    
    for ( elements_iter = mesh->elements; elements_iter != NULL; elements_iter = g_list_next( elements_iter ) )
    {
        if ( element_area( ELEMENT( elements_iter->data ) ) > max_element_area )
            return ELEMENT( elements_iter->data );
    }

    return NULL;
}
Beispiel #2
0
/* This function evaluates the quality of an element, based on the 2D quality
 * functional proposed by Lipnikov et. al.. The description for the functional
 * is taken from: Yu. V. Vasileskii and K. N. Lipnikov, An Adaptive Algorithm
 * for Quasioptimal Mesh Generation, Computational Mathematics and Mathematical
 * Physics, Vol. 39, No. 9, 1999, pp. 1468 - 1486.
 */
double Mesh::element_quality(size_t eid) const{
  const size_t *n = &ENList[3*eid];

  // Pointers to the coordinates of each vertex
  const double *c0 = &coords[2*n[0]];
  const double *c1 = &coords[2*n[1]];
  const double *c2 = &coords[2*n[2]];

  // Pointers to the metric tensor at each vertex
  const double *m0 = &metric[3*n[0]]; //const
  const double *m1 = &metric[3*n[1]]; //const
  const double *m2 = &metric[3*n[2]]; //const

  // Metric tensor averaged over the element
  const double m00 = (m0[0] + m1[0] + m2[0])/3; //const
  const double m01 = (m0[1] + m1[1] + m2[1])/3; //const
  const double m11 = (m0[2] + m1[2] + m2[2])/3; //const

  // l is the length of the perimeter, measured in metric space
  
  const double c0010 = c0[0] - c1[0];
  const double c0111 = c0[1] - c1[1];
  
  const double c0020 = c0[0] - c2[0];
  const double c0121 = c0[1] - c2[1];

  const double c2010 = c2[0] - c1[0];
  const double c2111 = c2[1] - c1[1];

  const double l =
    sqrt(c0111*(c0111*m11 + 2*c0010*m01) +
         c0010*c0010*m00)+
    sqrt(c0121*(c0121*m11 + 2*c0020*m01) +
         c0020*c0020*m00)+
    sqrt(c2111*(c2111*m11 + 2*c2010*m01) +
         c2010*c2010*m00);

  // Area in physical space
  const double a = element_area(eid);

  // Area in metric space
  const double a_m = a * sqrt(m00*m11 - m01*m01); //const

  // Function
  const double f = std::min(l/3.0, 3.0/l);
  const double F = pow(f * (2.0 - f), 3.0);

  // This is the 2D Lipnikov functional.
  double quality = 12.0 * sqrt(3.0) * a_m * F / (l*l);

  return quality;
}
Beispiel #3
0
/* This function evaluates the quality of an element, based on the 2D quality
 * functional proposed by Lipnikov et. al.. The description for the functional
 * is taken from: Yu. V. Vasileskii and K. N. Lipnikov, An Adaptive Algorithm
 * for Quasioptimal Mesh Generation, Computational Mathematics and Mathematical
 * Physics, Vol. 39, No. 9, 1999, pp. 1468 - 1486.
 */
float Mesh::element_quality(size_t eid) const{
  const size_t *n = &ENList[3*eid];

  // Pointers to the coordinates of each vertex
  const float *c0 = &coords[2*n[0]];
  const float *c1 = &coords[2*n[1]];
  const float *c2 = &coords[2*n[2]];

  // Pointers to the metric tensor at each vertex
  const float *m0 = &metric[3*n[0]];
  const float *m1 = &metric[3*n[1]];
  const float *m2 = &metric[3*n[2]];

  // Metric tensor averaged over the element
  float m00 = (m0[0] + m1[0] + m2[0])/3;
  float m01 = (m0[1] + m1[1] + m2[1])/3;
  float m11 = (m0[2] + m1[2] + m2[2])/3;

  // l is the length of the perimeter, measured in metric space
  float l =
    sqrt((c0[1] - c1[1])*((c0[1] - c1[1])*m11 + (c0[0] - c1[0])*m01) +
         (c0[0] - c1[0])*((c0[1] - c1[1])*m01 + (c0[0] - c1[0])*m00))+
    sqrt((c0[1] - c2[1])*((c0[1] - c2[1])*m11 + (c0[0] - c2[0])*m01) +
         (c0[0] - c2[0])*((c0[1] - c2[1])*m01 + (c0[0] - c2[0])*m00))+
    sqrt((c2[1] - c1[1])*((c2[1] - c1[1])*m11 + (c2[0] - c1[0])*m01) +
         (c2[0] - c1[0])*((c2[1] - c1[1])*m01 + (c2[0] - c1[0])*m00));

  // Area in physical space
  float a = element_area(eid);

  // Area in metric space
  float a_m = a*sqrt(m00*m11 - m01*m01);

  // Function
  float f = std::min(l/3.0, 3.0/l);
  float F = pow(f * (2.0 - f), 3.0);

  // This is the 2D Lipnikov functional.
  float quality = 12.0 * sqrt(3.0) * a_m * F / (l*l);

  return quality;
}
Beispiel #4
0
int test_element( int argc, char *argv[] )
{
    Element *e = element_new();
    g_return_val_if_fail( e->adjacent_halfedge == NULL , 1 );
    element_free( e );

    Point2 p1, p2, p3;
    point2_set( &p1, 0.0, 1.0 );
    point2_set( &p2, 0.0, 0.0 );
    point2_set( &p3, sqrt( 3.0 ), 0.0 );

    gdouble a1, a2, a3;
    triangle_angles( &p1, &p2, &p3, &a1, &a2, &a3 );
    g_return_val_if_fail( fabs( a1 - G_PI/3.0) < SMALL_NUMBER, 1 );
    g_return_val_if_fail( fabs( a2 - G_PI/2.0) < SMALL_NUMBER, 1 );
    g_return_val_if_fail( fabs( a3 - G_PI/6.0) < SMALL_NUMBER, 1 );

    a1 = triangle_circumcircle_radius( &p1, &p2, &p3 );
    g_return_val_if_fail( fabs( a1 - 1.0 ) < SMALL_NUMBER, 1 );

    a1 = triangle_circumcircle_radius_edge_length( 1.0, sqrt( 3.0 ), 2.0 );
    g_return_val_if_fail( fabs( a1 - 1.0 ) < SMALL_NUMBER, 1 );

    Point2 p;
    triangle_circumcenter_coordinates( &p1, &p2, &p3, &p );
    g_return_val_if_fail( fabs( p.x - sqrt( 3.0 )/2.0 ) < SMALL_NUMBER, 1 );
    g_return_val_if_fail( fabs( p.y - 1.0/2.0 ) < SMALL_NUMBER, 1 );

    a1 = triangle_area( &p1, &p2, &p3 );
    g_return_val_if_fail( fabs( a1 - sqrt( 3.0 )/2.0 ) < SMALL_NUMBER, 1 );


    Mesh *mesh = mesh_new();
    Node *n1 = mesh_add_node( mesh, 0.0, 1.0 );
    Node *n2 = mesh_add_node( mesh, 0.0, 0.0 );
    Node *n3 = mesh_add_node( mesh, sqrt(3.0), 0.0 );
    Edge *e1 = mesh_add_edge( mesh, n1, n2 );
    Edge *e2 = mesh_add_edge( mesh, n2, n3 );
    Edge *e3 = mesh_add_edge( mesh, n3, n1 );
    Element *el = mesh_add_element( mesh, &e1->he[0], &e2->he[0], &e3->he[0] );

    gdouble l1, l2, l3;
    element_edge_lengths( el, &l1, &l2, &l3 );
    g_return_val_if_fail( fabs( l1 - 1.0) < SMALL_NUMBER, 1);
    g_return_val_if_fail( fabs( l2 - sqrt(3.0)) < SMALL_NUMBER, 1);
    g_return_val_if_fail( fabs( l3 - 2.0) < SMALL_NUMBER, 1);

    HalfEdge *he = element_min_edge( el, &l1 );
    g_return_val_if_fail( he->edge == e1, 1 );
    g_return_val_if_fail( fabs( l1 - 1.0) < SMALL_NUMBER, 1);

    l1 = element_min_edge_length( el );
    g_return_val_if_fail( fabs( l1 - 1.0) < SMALL_NUMBER, 1);

    he = element_max_edge( el, &l1 );
    g_return_val_if_fail( he->edge == e3, 1 );
    g_return_val_if_fail( fabs( l1 - 2.0) < SMALL_NUMBER, 1);

    l1 = element_max_edge_length( el );
    g_return_val_if_fail( fabs( l1 - 2.0) < SMALL_NUMBER, 1);

    element_angles( el, &a1, &a2, &a3 );
    g_return_val_if_fail( fabs( a1 - G_PI/3.0) < SMALL_NUMBER, 1);
    g_return_val_if_fail( fabs( a2 - G_PI/2.0) < SMALL_NUMBER, 1);
    g_return_val_if_fail( fabs( a3 - G_PI/6.0) < SMALL_NUMBER, 1);

    a1 = element_maximum_angle( el );
    g_return_val_if_fail( fabs( a1 - G_PI/2.0) < SMALL_NUMBER, 1);

    a1 = element_minimum_angle( el );
    g_return_val_if_fail( fabs( a1 - G_PI/6.0) < SMALL_NUMBER, 1);

    element_circumcenter_coordinates( el, &p );
    g_return_val_if_fail( fabs( p.x - sqrt( 3.0 )/2.0 ) < SMALL_NUMBER, 1);
    g_return_val_if_fail( fabs( p.y - 1.0/2.0 ) < SMALL_NUMBER, 1);

    point2_set( NODE_POSITION( n3 ), 3.0, 0.0 );
    a1 = element_area( el );
    g_return_val_if_fail( fabs( a1 - 3.0/2.0) < SMALL_NUMBER, 1);

    return 0;
}