Skip to content
Snippets Groups Projects
MElement.cpp 34.5 KiB
Newer Older
// $Id: MElement.cpp,v 1.80 2008-07-11 10:54:24 remacle Exp $
// Copyright (C) 1997-2008 C. Geuzaine, J.-F. Remacle
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
// USA.
// 
// 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

#if defined(HAVE_GMSH_EMBEDDED)
#  include "GmshEmbedded.h"
Christophe Geuzaine's avatar
 
Christophe Geuzaine committed
#else
#  include "Numeric.h"
Christophe Geuzaine's avatar
Christophe Geuzaine committed
#  include "FunctionSpace.h"
#  include "GaussLegendre1D.h"
#  include "Message.h"
#  include "Context.h"
#  include "qualityMeasures.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.;
}

void MElement::getIntegrationPoints(int pOrder, int *npts, IntPt **pts) const
{
  Msg::Error("No integration points defined for this type of element");
}

double MTriangle::gammaShapeMeasure()
{
Christophe Geuzaine's avatar
 
Christophe Geuzaine committed
#if defined(HAVE_GMSH_EMBEDDED)
  return 0.;
#else
  return qmTriangle(this, QMTRI_RHO);
Christophe Geuzaine's avatar
 
Christophe Geuzaine committed
#endif
double MTetrahedron::gammaShapeMeasure()
{
Christophe Geuzaine's avatar
 
Christophe Geuzaine committed
#if defined(HAVE_GMSH_EMBEDDED)
  return 0.;
#else
  double vol;
  return qmTet(this, QMTET_2, &vol);
Christophe Geuzaine's avatar
 
Christophe Geuzaine committed
#endif
}

double MTetrahedron::etaShapeMeasure()
{
Christophe Geuzaine's avatar
 
Christophe Geuzaine committed
#if defined(HAVE_GMSH_EMBEDDED)
  return 0.;
#else
  double vol;
  return qmTet(this, QMTET_3, &vol);
Christophe Geuzaine's avatar
 
Christophe Geuzaine committed
#endif
Christophe Geuzaine's avatar
 
Christophe Geuzaine committed
double MTetrahedron::getVolume()
Christophe Geuzaine's avatar
 
Christophe Geuzaine committed
{
Christophe Geuzaine's avatar
 
Christophe Geuzaine committed
  double mat[3][3];
  getMat(mat);
  return det3x3(mat) / 6.;
}

Christophe Geuzaine's avatar
 
Christophe Geuzaine committed
void MTetrahedron::xyz2uvw(double xyz[3], double uvw[3])
Christophe Geuzaine's avatar
 
Christophe Geuzaine committed
{
Christophe Geuzaine's avatar
 
Christophe Geuzaine committed
  double mat[3][3], b[3], det;
Christophe Geuzaine's avatar
 
Christophe Geuzaine committed
  getMat(mat);
Christophe Geuzaine's avatar
 
Christophe Geuzaine committed
  b[0] = xyz[0] - getVertex(0)->x();
  b[1] = xyz[1] - getVertex(0)->y();
  b[2] = xyz[2] - getVertex(0)->z();
  sys3x3(mat, b, uvw, &det);
Christophe Geuzaine's avatar
 
Christophe Geuzaine committed
}

int MHexahedron::getVolumeSign()
{ 
  double mat[3][3];
  mat[0][0] = _v[1]->x() - _v[0]->x();
  mat[0][1] = _v[3]->x() - _v[0]->x();
  mat[0][2] = _v[4]->x() - _v[0]->x();
  mat[1][0] = _v[1]->y() - _v[0]->y();
  mat[1][1] = _v[3]->y() - _v[0]->y();
  mat[1][2] = _v[4]->y() - _v[0]->y();
  mat[2][0] = _v[1]->z() - _v[0]->z();
  mat[2][1] = _v[3]->z() - _v[0]->z();
  mat[2][2] = _v[4]->z() - _v[0]->z();
  return sign(det3x3(mat));
}

int MPrism::getVolumeSign()
{ 
  double mat[3][3];
  mat[0][0] = _v[1]->x() - _v[0]->x();
  mat[0][1] = _v[2]->x() - _v[0]->x();
  mat[0][2] = _v[3]->x() - _v[0]->x();
  mat[1][0] = _v[1]->y() - _v[0]->y();
  mat[1][1] = _v[2]->y() - _v[0]->y();
  mat[1][2] = _v[3]->y() - _v[0]->y();
  mat[2][0] = _v[1]->z() - _v[0]->z();
  mat[2][1] = _v[2]->z() - _v[0]->z();
  mat[2][2] = _v[3]->z() - _v[0]->z();
  return sign(det3x3(mat));
}

int MPyramid::getVolumeSign()
{ 
  double mat[3][3];
  mat[0][0] = _v[1]->x() - _v[0]->x();
  mat[0][1] = _v[3]->x() - _v[0]->x();
  mat[0][2] = _v[4]->x() - _v[0]->x();
  mat[1][0] = _v[1]->y() - _v[0]->y();
  mat[1][1] = _v[3]->y() - _v[0]->y();
  mat[1][2] = _v[4]->y() - _v[0]->y();
  mat[2][0] = _v[1]->z() - _v[0]->z();
Loading
Loading full blame...