Skip to content
Snippets Groups Projects
MElement.cpp 44.3 KiB
Newer Older
Christophe Geuzaine's avatar
Christophe Geuzaine committed
// Gmsh - Copyright (C) 1997-2012 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 "GmshConfig.h"
#include "GmshMessage.h"
#include "MElement.h"
#include "MPoint.h"
#include "MLine.h"
#include "MTriangle.h"
#include "MQuadrangle.h"
#include "MTetrahedron.h"
#include "MHexahedron.h"
#include "MPrism.h"
#include "MPyramid.h"
#include "GEntity.h"
Christophe Geuzaine's avatar
Christophe Geuzaine committed
#include "StringUtils.h"
#include "Numeric.h"
#include "Context.h"
Christophe Geuzaine's avatar
 
Christophe Geuzaine committed

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

int MElement::_globalNum = 0;
double MElement::_isInsideTolerance = 1.e-6;
MElement::MElement(int num, int part) : _visible(1)
Christophe Geuzaine's avatar
 
Christophe Geuzaine committed
{
#pragma omp critical
  {
    if(num){
      _num = num;
      _globalNum = std::max(_globalNum, _num);
    }
    else{
      _num = ++_globalNum;
    }
Christophe Geuzaine's avatar
 
Christophe Geuzaine committed
  }
}

void MElement::_getEdgeRep(MVertex *v0, MVertex *v1,
                           double *x, double *y, double *z, SVector3 *n,
Christophe Geuzaine's avatar
 
Christophe Geuzaine committed
                           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();
Christophe Geuzaine's avatar
 
Christophe Geuzaine committed
  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() const
Christophe Geuzaine's avatar
 
Christophe Geuzaine committed
{
  if(CTX::instance()->hideUnselected && _visible < 2) return false;
Christophe Geuzaine's avatar
 
Christophe Geuzaine committed
}

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.;
}

void MElement::scaledJacRange(double &jmin, double &jmax)
{
  jmin = jmax = 1.0;
#if defined(HAVE_MESH)
  extern double mesh_functional_distorsion(MElement*,double,double);
  if (getPolynomialOrder() == 1) return;
  const bezierBasis *jac = getJacobianFuncSpace()->bezier;
  fullVector<double>Ji(jac->points.size1());
  for (int i=0;i<jac->points.size1();i++){
    double u = jac->points(i,0);
    double v = jac->points(i,1);
    if (getType() == TYPE_QUA){
      u = -1 + 2*u;
      v = -1 + 2*v;
    }
    Ji(i) = mesh_functional_distorsion(this,u,v);
  }
  fullVector<double> Bi( jac->matrixLag2Bez.size1() );
  jac->matrixLag2Bez.mult(Ji,Bi);
  jmin = *std::min_element(Bi.getDataPtr(),Bi.getDataPtr()+Bi.size());
  jmax = *std::max_element(Bi.getDataPtr(),Bi.getDataPtr()+Bi.size());
#endif
}

void MElement::getNode(int num, double &u, double &v, double &w)
{
  // only for MElements that don't have a lookup table for this
  // (currently only 1st order elements have)
  double uvw[3];
  MVertex* ver = getVertex(num);
  double xyz[3] = {ver->x(), ver->y(), ver->z()};
  xyz2uvw(xyz, uvw);
  u = uvw[0];
  v = uvw[1];
  w = uvw[2];
}

Christophe Geuzaine's avatar
 
Christophe Geuzaine committed
void MElement::getShapeFunctions(double u, double v, double w, double s[], int o)
  const polynomialBasis* fs = getFunctionSpace(o);
Christophe Geuzaine's avatar
 
Christophe Geuzaine committed
  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");
void MElement::getGradShapeFunctions(double u, double v, double w, double s[][3],
  const polynomialBasis* fs = getFunctionSpace(o);
Christophe Geuzaine's avatar
 
Christophe Geuzaine committed
  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");
void MElement::getHessShapeFunctions(double u, double v, double w, double s[][3][3],
                                     int o)
{
  const polynomialBasis* fs = getFunctionSpace(o);
  if(fs) fs->ddf(u, v, w, s);
  else Msg::Error("Function space not implemented for this type of element");
}

void MElement::getThirdDerivativeShapeFunctions(double u, double v, double w, double s[][3][3][3],
                                     int o){
  const polynomialBasis* fs = getFunctionSpace(o);
  if(fs) fs->dddf(u, v, w, s);
  else Msg::Error("Function space not implemented for this type of element");
};

SPoint3 MElement::barycenter_infty ()
{
  double xmin =  getVertex(0)->x();
  double xmax = xmin;
  double ymin =  getVertex(0)->y();
  double ymax = ymin;
  double zmin =  getVertex(0)->z();
  double zmax = zmin;
  int n = getNumVertices();
  for(int i = 0; i < n; i++) {
    MVertex *v = getVertex(i);
    xmin = std::min(xmin,v->x());
    xmax = std::max(xmax,v->x());
    ymin = std::min(ymin,v->y());
    ymax = std::max(ymax,v->y());
    zmin = std::min(zmin,v->z());
    zmax = std::max(zmax,v->z());
  }
  return SPoint3(0.5*(xmin+xmax),0.5*(ymin+ymax),0.5*(zmin+zmax));
}

SPoint3 MElement::barycenter()
  SPoint3 p(0., 0., 0.);
Loading
Loading full blame...