Forked from
gmsh / gmsh
13854 commits behind the upstream repository.
-
Gauthier Becker authored
Fracture can be prescribed by a different law on interface Explicit system is implemented with petsc vector operations
Gauthier Becker authoredFracture can be prescribed by a different law on interface Explicit system is implemented with petsc vector operations
MTriangle.h 11.34 KiB
// Gmsh - Copyright (C) 1997-2010 C. Geuzaine, J.-F. Remacle
//
// See the LICENSE.txt file for license information. Please report all
// bugs and problems to <gmsh@geuz.org>.
#ifndef _MTRIANGLE_H_
#define _MTRIANGLE_H_
#include "MElement.h"
/*
* MTriangle
*
* v
* ^
* |
* 2
* |`\
* | `\
* | `\
* | `\
* | `\
* 0----------1 --> u
*
*/
class MTriangle : public MElement {
protected:
MVertex *_v[3];
void _getEdgeVertices(const int num, std::vector<MVertex*> &v) const
{
v[0] = _v[edges_tri(num, 0)];
v[1] = _v[edges_tri(num, 1)];
}
void _getFaceVertices(std::vector<MVertex*> &v) const
{
v[0] = _v[0];
v[1] = _v[1];
v[2] = _v[2];
}
public :
MTriangle(MVertex *v0, MVertex *v1, MVertex *v2, int num=0, int part=0)
: MElement(num, part)
{
_v[0] = v0; _v[1] = v1; _v[2] = v2;
}
MTriangle(std::vector<MVertex*> &v, int num=0, int part=0)
: MElement(num, part)
{
for(int i = 0; i < 3; i++) _v[i] = v[i];
}
~MTriangle(){}
virtual int getDim() const { return 2; }
virtual double etaShapeMeasure();
virtual double gammaShapeMeasure();
virtual double distoShapeMeasure();
virtual double getInnerRadius();
virtual double angleShapeMeasure();
virtual int getNumVertices() const { return 3; }
virtual MVertex *getVertex(int num){ return _v[num]; }
virtual MVertex *getVertexMED(int num)
{
static const int map[3] = {0, 2, 1};
return getVertex(map[num]);
}
virtual MVertex *getOtherVertex(MVertex *v1, MVertex *v2)
{
if(_v[0] != v1 && _v[0] != v2) return _v[0];
if(_v[1] != v1 && _v[1] != v2) return _v[1];
if(_v[2] != v1 && _v[2] != v2) return _v[2];
return 0;
}
virtual int getNumEdges(){ return 3; }
virtual MEdge getEdge(int num)
{
return MEdge(_v[edges_tri(num, 0)], _v[edges_tri(num, 1)]);
}
virtual void getEdgeInfo (const MEdge & edge, int &ithEdge, int &sign) const
{
for (ithEdge = 0; ithEdge < 3; ithEdge++){
const MVertex *v0 = _v[edges_tri(ithEdge, 0)];
const MVertex *v1 = _v[edges_tri(ithEdge, 1)];
if (v0 == edge.getVertex(0) && v1 == edge.getVertex(1)){
sign = 1; return;
}
if (v1 == edge.getVertex(0) && v0 == edge.getVertex(1)){
sign = -1; return;
}
}
Msg::Error("Could not get edge information for triangle %d", getNum());
}
virtual int getNumEdgesRep(){ return 3; }
virtual void getEdgeRep(int num, double *x, double *y, double *z, SVector3 *n)
{
MEdge e(getEdge(num));
_getEdgeRep(e.getVertex(0), e.getVertex(1), x, y, z, n, 0);
}
virtual void getEdgeVertices(const int num, std::vector<MVertex*> &v) const
{
v.resize(2);
_getEdgeVertices(num, v);
}
virtual int getNumFaces(){ return 1; }
virtual MFace getFace(int num)
{
return MFace(_v[0], _v[1], _v[2]);
}
virtual int getNumFacesRep(){ return 1; }
virtual void getFaceRep(int num, double *x, double *y, double *z, SVector3 *n)
{
_getFaceRep(_v[0], _v[1], _v[2], x, y, z, n);
}
virtual void getFaceVertices(const int num, std::vector<MVertex*> &v) const
{
v.resize(3);
_getFaceVertices(v);
}
virtual int getType() const { return TYPE_TRI; }
virtual int getTypeForMSH() const { return MSH_TRI_3; }
virtual int getTypeForUNV() const { return 91; } // thin shell linear triangle
virtual int getTypeForVTK() const { return 5; }
virtual const char *getStringForPOS() const { return "ST"; }
virtual const char *getStringForBDF() const { return "CTRIA3"; }
virtual const char *getStringForDIFF() const { return "ElmT3n2D"; }
virtual const char *getStringForINP() const { return "C2D3"; }
virtual void revert()
{
MVertex *tmp = _v[1]; _v[1] = _v[2]; _v[2] = tmp;
}
virtual const polynomialBasis* getFunctionSpace(int o=-1) const;
virtual const JacobianBasis* getJacobianFuncSpace(int o=-1) const;
virtual bool isInside(double u, double v, double w)
{
double tol = _isInsideTolerance;
if(u < (-tol) || v < (-tol) || u > ((1. + tol) - v))
return false;
return true;
}
virtual void getIntegrationPoints(int pOrder, int *npts, IntPt **pts);
virtual SPoint3 circumcenter();
private:
int edges_tri(const int edge, const int vert) const
{
static const int e[3][2] = {
{0, 1},
{1, 2},
{2, 0}
};
return e[edge][vert];
}
public:
static void registerBindings(binding *b);
};
/*
* MTriangle6
*
* 2
* |`\
* | `\
* 5 `4
* | `\
* | `\
* 0-----3----1
*
*/
class MTriangle6 : public MTriangle {
protected:
MVertex *_vs[3];
public :
MTriangle6(MVertex *v0, MVertex *v1, MVertex *v2, MVertex *v3, MVertex *v4,
MVertex *v5, int num=0, int part=0)
: MTriangle(v0, v1, v2, num, part)
{
_vs[0] = v3; _vs[1] = v4; _vs[2] = v5;
for(int i = 0; i < 3; i++) _vs[i]->setPolynomialOrder(2);
}
MTriangle6(std::vector<MVertex*> &v, int num=0, int part=0)
: MTriangle(v, num, part)
{
for(int i = 0; i < 3; i++) _vs[i] = v[3 + i];
for(int i = 0; i < 3; i++) _vs[i]->setPolynomialOrder(2);
}
~MTriangle6(){}
virtual int getPolynomialOrder() const { return 2; }
virtual int getNumVertices() const { return 6; }
virtual MVertex *getVertex(int num){ return num < 3 ? _v[num] : _vs[num - 3]; }
virtual MVertex *getVertexUNV(int num)
{
static const int map[6] = {0, 3, 1, 4, 2, 5};
return getVertex(map[num]);
}
virtual MVertex *getVertexMED(int num)
{
static const int map[6] = {0, 2, 1, 5, 4, 3};
return getVertex(map[num]);
}
virtual int getNumEdgeVertices() const { return 3; }
virtual int getNumEdgesRep();
virtual void getEdgeRep(int num, double *x, double *y, double *z, SVector3 *n);
virtual void getEdgeVertices(const int num, std::vector<MVertex*> &v) const
{
v.resize(3);
MTriangle::_getEdgeVertices(num, v);
v[2] = _vs[num];
}
virtual int getNumFacesRep();
virtual void getFaceRep(int num, double *x, double *y, double *z, SVector3 *n);
virtual void getFaceVertices(const int num, std::vector<MVertex*> &v) const
{
v.resize(6);
MTriangle::_getFaceVertices(v);
v[3] = _vs[0];
v[4] = _vs[1];
v[5] = _vs[2];
}
virtual int getTypeForMSH() const { return MSH_TRI_6; }
virtual int getTypeForUNV() const { return 92; } // thin shell parabolic triangle
//virtual int getTypeForVTK() const { return 22; }
virtual const char *getStringForPOS() const { return "ST2"; }
virtual const char *getStringForBDF() const { return "CTRIA6"; }
virtual const char *getStringForDIFF() const { return "ElmT6n2D"; }
virtual const char *getStringForINP() const { return "C2D6"; }
virtual void revert()
{
MVertex *tmp;
tmp = _v[1]; _v[1] = _v[2]; _v[2] = tmp;
tmp = _vs[0]; _vs[0] = _vs[2]; _vs[2] = tmp;
}
};
/*
* MTriangleN FIXME: check the plot
*
* 2
* |`\ E = order - 1;
* | `\ N = total number of vertices
* 3+2E 2+2E
* | `\ Interior vertex numbers
* ... ... for edge 0 <= i <= 2: 3+i*E to 2+(i+1)*E
* | `\ in volume : 3+3*E to N-1
* 2+3E 3+E
* | 3+3E to N-1 `\
* | `\
* 0---3--...---2+E---1
*
*/
class MTriangleN : public MTriangle {
protected:
std::vector<MVertex *> _vs;
const char _order;
public:
MTriangleN(MVertex *v0, MVertex *v1, MVertex *v2,
std::vector<MVertex*> &v, char order, int num=0, int part=0)
: MTriangle(v0, v1, v2, num, part), _vs(v), _order(order)
{
for(unsigned int i = 0; i < _vs.size(); i++) _vs[i]->setPolynomialOrder(_order);
}
MTriangleN(std::vector<MVertex*> &v, char order, int num=0, int part=0)
: MTriangle(v[0], v[1], v[2], num, part), _order(order)
{
for(unsigned int i = 3; i < v.size(); i++) _vs.push_back(v[i]);
for(unsigned int i = 0; i < _vs.size(); i++) _vs[i]->setPolynomialOrder(_order);
}
~MTriangleN(){}
virtual int getPolynomialOrder() const { return _order; }
virtual int getNumVertices() const { return 3 + _vs.size(); }
virtual MVertex *getVertex(int num){ return num < 3 ? _v[num] : _vs[num - 3]; }
virtual int getNumFaceVertices() const
{
if(_order == 3 && _vs.size() == 6) return 0;
if(_order == 3 && _vs.size() == 7) return 1;
if(_order == 4 && _vs.size() == 9) return 0;
if(_order == 4 && _vs.size() == 12) return 3;
if(_order == 5 && _vs.size() == 12) return 0;
if(_order == 5 && _vs.size() == 18) return 6;
if(_order == 6 && _vs.size() == 25) return 10;
if(_order == 7 && _vs.size() == 33) return 12;
if(_order == 8 && _vs.size() == 42) return 15;
if(_order == 9 && _vs.size() == 52) return 21;
if(_order == 10 && _vs.size() == 63) return 28;
if(_order == 6 && _vs.size() == 15) return 0;
if(_order == 7 && _vs.size() == 18) return 0;
if(_order == 8 && _vs.size() == 21) return 0;
if(_order == 9 && _vs.size() == 24) return 0;
if(_order == 10 && _vs.size() == 27) return 0;
return 0;
}
virtual int getNumEdgeVertices() const { return 3 * (_order - 1); }
virtual int getNumEdgesRep();
virtual int getNumFacesRep();
virtual void getEdgeRep(int num, double *x, double *y, double *z, SVector3 *n);
virtual void getEdgeVertices(const int num, std::vector<MVertex*> &v) const
{
v.resize(_order + 1);
MTriangle::_getEdgeVertices(num, v);
int j = 2;
const int ie = (num + 1) * (_order - 1);
for(int i = num * (_order-1); i != ie; ++i) v[j++] = _vs[i];
}
virtual void getFaceRep(int num, double *x, double *y, double *z, SVector3 *n);
virtual void getFaceVertices(const int num, std::vector<MVertex*> &v) const
{
v.resize(3 + _vs.size());
MTriangle::_getFaceVertices(v);
for(unsigned int i = 0; i != _vs.size(); ++i) v[i + 3] = _vs[i];
}
virtual int getTypeForMSH() const
{
if(_order == 2 && _vs.size() == 3) return MSH_TRI_6;
if(_order == 3 && _vs.size() == 6) return MSH_TRI_9;
if(_order == 3 && _vs.size() == 7) return MSH_TRI_10;
if(_order == 4 && _vs.size() == 9) return MSH_TRI_12;
if(_order == 4 && _vs.size() == 12) return MSH_TRI_15;
if(_order == 5 && _vs.size() == 12) return MSH_TRI_15I;
if(_order == 5 && _vs.size() == 18) return MSH_TRI_21;
if(_order == 6 && _vs.size() == 25) return MSH_TRI_28;
if(_order == 7 && _vs.size() == 33) return MSH_TRI_36;
if(_order == 8 && _vs.size() == 42) return MSH_TRI_45;
if(_order == 9 && _vs.size() == 52) return MSH_TRI_55;
if(_order ==10 && _vs.size() == 63) return MSH_TRI_66;
return 0;
}
virtual void revert()
{
MVertex *tmp;
tmp = _v[1]; _v[1] = _v[2]; _v[2] = tmp;
std::vector<MVertex*> inv;
inv.insert(inv.begin(), _vs.rbegin(), _vs.rend());
_vs = inv;
}
};
template <class T>
void sort3(T *t[3])
{
T *temp;
if(t[0] > t[1]){
temp = t[1];
t[1] = t[0];
t[0] = temp;
}
if(t[1] > t[2]){
temp = t[2];
t[2] = t[1];
t[1] = temp;
}
if(t[0] > t[1]){
temp = t[1];
t[1] = t[0];
t[0] = temp;
}
}
struct compareMTriangleLexicographic
{
bool operator () (MTriangle *t1, MTriangle *t2) const
{
MVertex *_v1[3] = {t1->getVertex(0), t1->getVertex(1), t1->getVertex(2)};
MVertex *_v2[3] = {t2->getVertex(0), t2->getVertex(1), t2->getVertex(2)};
sort3(_v1);
sort3(_v2);
if(_v1[0] < _v2[0]) return true;
if(_v1[0] > _v2[0]) return false;
if(_v1[1] < _v2[1]) return true;
if(_v1[1] > _v2[1]) return false;
if(_v1[2] < _v2[2]) return true;
return false;
}
};
#endif