Skip to content
Snippets Groups Projects
MElement.cpp 37.1 KiB
Newer Older
Christophe Geuzaine's avatar
Christophe Geuzaine committed
// Gmsh - Copyright (C) 1997-2009 C. Geuzaine, J.-F. Remacle
Christophe Geuzaine's avatar
Christophe Geuzaine committed
// See the LICENSE.txt file for license information. Please report all
// bugs and problems to <gmsh@geuz.org>.
Claudine Bon's avatar
Claudine Bon committed
#include <stdlib.h>
#include <math.h>
#include "MElement.h"
#include "GEntity.h"
#include "GFace.h"
Christophe Geuzaine's avatar
Christophe Geuzaine committed
#include "StringUtils.h"
Christophe Geuzaine's avatar
 
Christophe Geuzaine committed

#if defined(HAVE_GMSH_EMBEDDED)
#include "GmshEmbedded.h"
Christophe Geuzaine's avatar
 
Christophe Geuzaine committed
#else
#include "Numeric.h"
#include "GaussLegendre1D.h"
#include "Context.h"
#include "qualityMeasures.h"
#include "meshGFaceDelaunayInsertion.h"
#include "meshGRegionDelaunayInsertion.h"
Christophe Geuzaine's avatar
 
Christophe Geuzaine committed
#endif
Christophe Geuzaine's avatar
 
Christophe Geuzaine committed

Christophe Geuzaine's avatar
Christophe Geuzaine committed
#define SQU(a)      ((a)*(a))

Christophe Geuzaine's avatar
 
Christophe Geuzaine committed
extern Context_T CTX;

int MElement::_globalNum = 0;
Christophe Geuzaine's avatar
 
Christophe Geuzaine committed
double MElementLessThanLexicographic::tolerance = 1.e-6;
Christophe Geuzaine's avatar
 
Christophe Geuzaine committed
void MElement::_getEdgeRep(MVertex *v0, MVertex *v1, 
Christophe Geuzaine's avatar
 
Christophe Geuzaine committed
                           double *x, double *y, double *z, SVector3 *n, 
                           int faceIndex)
Christophe Geuzaine's avatar
 
Christophe Geuzaine committed
{
  x[0] = v0->x(); y[0] = v0->y(); z[0] = v0->z();
  x[1] = v1->x(); y[1] = v1->y(); z[1] = v1->z();
  if(faceIndex >= 0){
    n[0] = n[1] = getFace(faceIndex).normal();
  }
  else{
    MEdge e(v0, v1);
    n[0] = n[1] = e.normal();
  }
}

void MElement::_getFaceRep(MVertex *v0, MVertex *v1, MVertex *v2, 
Christophe Geuzaine's avatar
 
Christophe Geuzaine committed
                           double *x, double *y, double *z, SVector3 *n)
Christophe Geuzaine's avatar
 
Christophe Geuzaine committed
{
  x[0] = v0->x(); x[1] = v1->x(); x[2] = v2->x(); 
  y[0] = v0->y(); y[1] = v1->y(); y[2] = v2->y();
  z[0] = v0->z(); z[1] = v1->z(); z[2] = v2->z();
  SVector3 t1(x[1] - x[0], y[1] - y[0], z[1] - z[0]);
  SVector3 t2(x[2] - x[0], y[2] - y[0], z[2] - z[0]);
  SVector3 normal = crossprod(t1, t2);
  normal.normalize();
  for(int i = 0; i < 3; i++) n[i] = normal;
}

Christophe Geuzaine's avatar
 
Christophe Geuzaine committed
char MElement::getVisibility()
{
  if(CTX.hide_unselected && _visible < 2) return false;
  return _visible; 
}

double MElement::minEdge()
{
  double m = 1.e25;
  for(int i = 0; i < getNumEdges(); i++){
    MEdge e = getEdge(i);
Christophe Geuzaine's avatar
 
Christophe Geuzaine committed
    m = std::min(m, e.getVertex(0)->distance(e.getVertex(1)));
  }
  return m;
}

double MElement::maxEdge()
{
  double m = 0.;
  for(int i = 0; i < getNumEdges(); i++){
    MEdge e = getEdge(i);
Christophe Geuzaine's avatar
 
Christophe Geuzaine committed
    m = std::max(m, e.getVertex(0)->distance(e.getVertex(1)));
  }
  return m;
}

double MElement::rhoShapeMeasure()
{
  double min = minEdge();
  double max = maxEdge();
  if(max)
    return min / max;
  else
    return 0.;
}

Christophe Geuzaine's avatar
 
Christophe Geuzaine committed
void MElement::getShapeFunctions(double u, double v, double w, double s[], int o)
#if !defined(HAVE_GMSH_EMBEDDED)
Christophe Geuzaine's avatar
 
Christophe Geuzaine committed
  const gmshFunctionSpace* fs = getFunctionSpace(o);
  if(fs) fs->f(u, v, w, s);
Christophe Geuzaine's avatar
Christophe Geuzaine committed
  else Msg::Error("Function space not implemented for this type of element");
Christophe Geuzaine's avatar
 
Christophe Geuzaine committed
void MElement::getGradShapeFunctions(double u, double v, double w, double s[][3], int o)
Christophe Geuzaine's avatar
 
Christophe Geuzaine committed
#if !defined(HAVE_GMSH_EMBEDDED)
  const gmshFunctionSpace* fs = getFunctionSpace(o);
  if(fs) fs->df(u, v, w, s);
Christophe Geuzaine's avatar
Christophe Geuzaine committed
  else Msg::Error("Function space not implemented for this type of element");
Christophe Geuzaine's avatar
 
Christophe Geuzaine committed
#endif
SPoint3 MElement::barycenter()
  SPoint3 p(0., 0., 0.);
  int n = getNumVertices();
  for(int i = 0; i < n; i++) {
    MVertex *v = getVertex(i);
    p[0] += v->x();
    p[1] += v->y();
    p[2] += v->z();
  p[0] /= (double)n;
  p[1] /= (double)n;
  p[2] /= (double)n;
  return p;
Christophe Geuzaine's avatar
 
Christophe Geuzaine committed
std::string MElement::getInfoString()
{
  char tmp[256];
  sprintf(tmp, "Element %d", getNum());
  return std::string(tmp);
}

static double _computeDeterminantAndRegularize(MElement *ele, double jac[3][3])
Christophe Geuzaine's avatar
 
Christophe Geuzaine committed
{
  switch (ele->getDim()) {
      dJ = sqrt(SQU(jac[0][0]) + SQU(jac[0][1]) + SQU(jac[0][2]));

      // regularize matrix
      double a[3], b[3], c[3];
      a[0] = ele->getVertex(1)->x() - ele->getVertex(0)->x(); 
      a[1] = ele->getVertex(1)->y() - ele->getVertex(0)->y();
      a[2] = ele->getVertex(1)->z() - ele->getVertex(0)->z();     
      if((fabs(a[0]) >= fabs(a[1]) && fabs(a[0]) >= fabs(a[2])) ||
         (fabs(a[1]) >= fabs(a[0]) && fabs(a[1]) >= fabs(a[2]))) {
        b[0] = a[1]; b[1] = -a[0]; b[2] = 0.;
      }
      else {
        b[0] = 0.; b[1] = a[2]; b[2] = -a[1];
      }
      prodve(a, b, c);
      jac[1][0] = b[0]; jac[1][1] = b[1]; jac[1][2] = b[2]; 
      jac[2][0] = c[0]; jac[2][1] = c[1]; jac[2][2] = c[2]; 
      break;
    }
  case 2:
    {
      dJ = sqrt(SQU(jac[0][0] * jac[1][1] - jac[0][1] * jac[1][0]) +
                SQU(jac[0][2] * jac[1][0] - jac[0][0] * jac[1][2]) +
                SQU(jac[0][1] * jac[1][2] - jac[0][2] * jac[1][1]));

      // regularize matrix
      double a[3], b[3], c[3];
      a[0] = jac[0][0];
      a[1] = jac[0][1];
      a[2] = jac[0][2];
      b[0] = jac[1][0];
      b[1] = jac[1][1];
      b[2] = jac[1][2];
      prodve(a, b, c);
      norme(c);
      jac[2][0] = c[0]; jac[2][1] = c[1]; jac[2][2] = c[2];
Christophe Geuzaine's avatar
 
Christophe Geuzaine committed
    }
  case 3:
    {
      dJ = fabs(jac[0][0] * jac[1][1] * jac[2][2] + jac[0][2] * jac[1][0] * jac[2][1] +
Christophe Geuzaine's avatar
 
Christophe Geuzaine committed
                jac[0][1] * jac[1][2] * jac[2][0] - jac[0][2] * jac[1][1] * jac[2][0] -
                jac[0][0] * jac[1][2] * jac[2][1] - jac[0][1] * jac[1][0] * jac[2][2]);
Christophe Geuzaine's avatar
 
Christophe Geuzaine committed
    }
double MElement::getJacobian(double u, double v, double w, double jac[3][3])
{
  jac[0][0] = jac[0][1] = jac[0][2] = 0.;
  jac[1][0] = jac[1][1] = jac[1][2] = 0.;
  jac[2][0] = jac[2][1] = jac[2][2] = 0.;

  double gsf[256][3];
Loading
Loading full blame...