/usr/include/gmsh/MElement.h is in libgmsh-dev 2.8.3+dfsg-4ubuntu2.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 | // Gmsh - Copyright (C) 1997-2013 C. Geuzaine, J.-F. Remacle
//
// See the LICENSE.txt file for license information. Please report all
// bugs and problems to the public mailing list <gmsh@geuz.org>.
#ifndef _MELEMENT_H_
#define _MELEMENT_H_
#include <stdio.h>
#include <algorithm>
#include <string>
#include "GmshDefines.h"
#include "GmshMessage.h"
#include "MVertex.h"
#include "MEdge.h"
#include "MFace.h"
#include "nodalBasis.h"
#include "polynomialBasis.h"
#include "JacobianBasis.h"
#include "GaussIntegration.h"
class GModel;
// A mesh element.
class MElement
{
private:
// the id number of the element (this number is unique and is
// guaranteed never to change once a mesh has been generated)
int _num;
// the number of the mesh partition the element belongs to
short _partition;
// a visibility flag
char _visible;
protected:
// the tolerance used to determine if a point is inside an element,
// in parametric coordinates
static double _isInsideTolerance;
void _getEdgeRep(MVertex *v0, MVertex *v1,
double *x, double *y, double *z, SVector3 *n,
int faceIndex=-1);
void _getFaceRep(MVertex *v0, MVertex *v1, MVertex *v2,
double *x, double *y, double *z, SVector3 *n);
public :
MElement(int num=0, int part=0);
virtual ~MElement(){}
// set/get the tolerance for isInside() test
static void setTolerance(const double tol){ _isInsideTolerance = tol; }
static double getTolerance() { return _isInsideTolerance; }
// return the tag of the element
virtual int getNum() const { return _num; }
// return the geometrical dimension of the element
virtual int getDim() const = 0;
// return the polynomial order the element
virtual int getPolynomialOrder() const { return 1; }
// get/set the partition to which the element belongs
virtual int getPartition() const { return _partition; }
virtual void setPartition(int num){ _partition = (short)num; }
// get/set the visibility flag
virtual char getVisibility() const;
virtual void setVisibility(char val){ _visible = val; }
// get & set the vertices
virtual int getNumVertices() const = 0;
virtual const MVertex *getVertex(int num) const= 0;
virtual MVertex *getVertex(int num) = 0;
void getVertices(std::vector<MVertex*> &verts)
{
int N = getNumVertices();
verts.resize(N);
for(int i = 0; i < N; i++) verts[i] = getVertex(i);
}
virtual void setVertex(int num, MVertex *v)
{
Msg::Error("Vertex set not supported for this element");
}
// give an MVertex as input and get its local number
virtual void getVertexInfo(const MVertex *vertex, int &ithVertex) const
{
Msg::Error("Vertex information not available for this element");
}
// get the vertex using the I-deas UNV ordering
virtual MVertex *getVertexUNV(int num){ return getVertex(num); }
// get the vertex using the VTK ordering
virtual MVertex *getVertexVTK(int num){ return getVertex(num); }
// get the vertex using the Nastran BDF ordering
virtual MVertex *getVertexBDF(int num){ return getVertex(num); }
// get the vertex using DIFF ordering
virtual MVertex *getVertexDIFF(int num){ return getVertex(num); }
// get the vertex using INP ordering
virtual MVertex *getVertexINP(int num){ return getVertex(num); }
// get the number of vertices associated with edges, faces and
// volumes (nonzero only for higher order elements, polygons or
// polyhedra)
virtual int getNumEdgeVertices() const { return 0; }
virtual int getNumFaceVertices() const { return 0; }
virtual int getNumVolumeVertices() const { return 0; }
// get the number of primary vertices (first-order element)
int getNumPrimaryVertices() const
{
return getNumVertices() - getNumEdgeVertices() - getNumFaceVertices() -
getNumVolumeVertices();
}
// get the edges
virtual int getNumEdges() = 0;
virtual MEdge getEdge(int num) const= 0;
// give an MEdge as input and get its local number and sign
virtual void getEdgeInfo(const MEdge & edge, int &ithEdge, int &sign) const
{
Msg::Error("Edge information not available for this element");
}
// get an edge representation for drawing
virtual int getNumEdgesRep() = 0;
virtual void getEdgeRep(int num, double *x, double *y, double *z, SVector3 *n) = 0;
// get all the vertices on an edge
virtual void getEdgeVertices(const int num, std::vector<MVertex*> &v) const
{
v.resize(0);
}
// get the faces
virtual int getNumFaces() = 0;
virtual MFace getFace(int num) = 0;
// give an MFace as input and get its local number, sign and rotation
virtual void getFaceInfo(const MFace & face, int &ithFace, int &sign, int &rot) const
{
Msg::Error("Face information not available for this element");
}
// get a face representation for drawing
virtual int getNumFacesRep() = 0;
virtual void getFaceRep(int num, double *x, double *y, double *z, SVector3 *n) = 0;
// get all the vertices on a face
virtual void getFaceVertices(const int num, std::vector<MVertex*> &v) const
{
v.resize(0);
}
// get and set parent and children for hierarchial grids
virtual MElement *getParent() const { return NULL; }
virtual void setParent(MElement *p, bool owner = false) {}
virtual int getNumChildren() const { return 0; }
virtual MElement *getChild(int i) const { return NULL; }
virtual bool ownsParent() const { return false; }
// get base element in case of MSubElement
virtual const MElement *getBaseElement() const { return this; }
virtual MElement *getBaseElement() { return this; }
// get and set domain for borders
virtual MElement *getDomain(int i) const { return NULL; }
virtual void setDomain (MElement *e, int i) { }
// get the type of the element
virtual int getType() const = 0;
// get the max/min edge length
virtual double maxEdge();
virtual double minEdge();
// get the quality measures
virtual double rhoShapeMeasure();
virtual double gammaShapeMeasure(){ return 0.; }
virtual double etaShapeMeasure(){ return 0.; }
virtual double distoShapeMeasure()
{
double jmin, jmax;
scaledJacRange(jmin, jmax);
return jmin;
}
virtual double angleShapeMeasure() { return 1.0; }
virtual void scaledJacRange(double &jmin, double &jmax);
// get the radius of the inscribed circle/sphere if it exists,
// otherwise get the minimum radius of all the circles/spheres
// tangent to the most boundaries of the element.
virtual double getInnerRadius(){ return 0.; }
// get the radius of the circumscribed circle/sphere if it exists,
// otherwise get the maximum radius of all the circles/spheres
// tangent to the most boundaries of the element.
virtual double getOuterRadius(){ return 0.; }
// compute the barycenter
virtual SPoint3 barycenter(bool primary = false) const;
virtual SPoint3 barycenterUVW() const;
// compute the barycenter in infinity norm
virtual SPoint3 barycenter_infty() const;
// reverse the orientation of the element
virtual void reverse(){}
// get volume of element
virtual double getVolume();
// return sign of volume (+1 or -1) for 3D elements (or 0 if element
// has zero volume)
virtual int getVolumeSign();
// compute and change the orientation of 3D elements to get positive
// volume (return false if element has zero volume)
virtual bool setVolumePositive();
// return an information string for the element
virtual std::string getInfoString();
// get the function space for the element
virtual const nodalBasis* getFunctionSpace(int order=-1) const { return 0; }
// get the function space for the jacobian of the element
virtual const JacobianBasis* getJacobianFuncSpace(int order=-1) const { return 0; }
// return parametric coordinates (u,v,w) of a vertex
virtual void getNode(int num, double &u, double &v, double &w) const;
// return the interpolating nodal shape functions evaluated at point
// (u,v,w) in parametric coordinates (if order == -1, use the
// polynomial order of the element)
virtual void getShapeFunctions(double u, double v, double w, double s[],
int order=-1) const;
// return the gradient of the nodal shape functions evaluated at
// point (u,v,w) in parametric coordinates (if order == -1, use the
// polynomial order of the element)
virtual void getGradShapeFunctions(double u, double v, double w, double s[][3],
int order=-1) const;
virtual void getHessShapeFunctions(double u, double v, double w, double s[][3][3],
int order=-1) const;
virtual void getThirdDerivativeShapeFunctions(double u, double v, double w,
double s[][3][3][3], int order=-1) const;
// return the Jacobian of the element evaluated at point (u,v,w) in
// parametric coordinates
virtual double getJacobian(const fullMatrix<double> &gsf, double jac[3][3]) const;
// To be compatible with _vgrads of functionSpace without having to put under
// fullMatrix form
virtual double getJacobian(const std::vector<SVector3> &gsf, double jac[3][3])const ;
virtual double getJacobian(double u, double v, double w, double jac[3][3]) const;
inline double getJacobian(double u, double v, double w, fullMatrix<double> &j) const{
double JAC[3][3];
const double detJ = getJacobian (u,v,w,JAC);
for (int i=0;i<3;i++){
j(i,0) = JAC[i][0];
j(i,1) = JAC[i][1];
j(i,2) = JAC[i][2];
}
return detJ;
}
virtual double getPrimaryJacobian(double u, double v, double w, double jac[3][3]);
double getJacobianDeterminant(double u, double v, double w)
{
double jac[3][3]; return getJacobian(u, v, w, jac);
}
void getSignedJacobian(fullVector<double> &jacobian, int o = -1);
void getNodesCoord(fullMatrix<double> &nodesXYZ);
virtual int getNumShapeFunctions() const{ return getNumVertices(); }
virtual int getNumPrimaryShapeFunctions() { return getNumPrimaryVertices(); }
virtual const MVertex *getShapeFunctionNode(int i) const{ return getVertex(i); }
virtual MVertex *getShapeFunctionNode(int i) { return getVertex(i); }
// get the point in cartesian coordinates corresponding to the point
// (u,v,w) in parametric coordinates
virtual void pnt(double u, double v, double w, SPoint3 &p) const;
// To be compatible with functionSpace without changing form
virtual void pnt(const std::vector<double> &sf,SPoint3 &p) const;
virtual void primaryPnt(double u, double v, double w, SPoint3 &p);
// invert the parametrisation
virtual void xyz2uvw(double xyz[3], double uvw[3]) const;
void xyzTouvw(fullMatrix<double> *xu) const;
// move point between parent and element parametric spaces
virtual void movePointFromParentSpaceToElementSpace(double &u, double &v,
double &w) const;
virtual void movePointFromElementSpaceToParentSpace(double &u, double &v,
double &w) const;
// test if a point, given in parametric coordinates, belongs to the
// element
virtual bool isInside(double u, double v, double w) const = 0;
// interpolate the given nodal data (resp. its gradient, curl and
// divergence) at point (u,v,w) in parametric coordinates
double interpolate(double val[], double u, double v, double w, int stride=1,
int order=-1);
void interpolateGrad(double val[], double u, double v, double w, double f[],
int stride=1, double invjac[3][3]=0, int order=-1);
void interpolateCurl(double val[], double u, double v, double w, double f[],
int stride=3, int order=-1);
double interpolateDiv(double val[], double u, double v, double w, int stride=3,
int order=-1);
// integration routines
virtual void getIntegrationPoints(int pOrder, int *npts, IntPt **pts)
{
Msg::Error("No integration points defined for this type of element: %d",
this->getType());
}
double integrate(double val[], int pOrder, int stride=1, int order=-1);
// val[] must contain interpolation data for face/edge vertices of given edge/face
double integrateCirc(double val[], int edge, int pOrder, int order=-1);
double integrateFlux(double val[], int face, int pOrder, int order=-1);
// IO routines
virtual void writeMSH(FILE *fp, bool binary=false, int elementary=1,
std::vector<short> *ghosts=0);
virtual void writeMSH2(FILE *fp, double version=1.0, bool binary=false,
int num=0, int elementary=1, int physical=1,
int parentNum=0, int dom1Num = 0, int dom2Num = 0,
std::vector<short> *ghosts=0);
virtual void writePOS(FILE *fp, bool printElementary, bool printElementNumber,
bool printGamma, bool printEta, bool printRho,
bool printDisto,double scalingFactor=1.0, int elementary=1);
virtual void writeSTL(FILE *fp, bool binary=false, double scalingFactor=1.0);
virtual void writeVRML(FILE *fp);
virtual void writePLY2(FILE *fp);
virtual void writeUNV(FILE *fp, int num=0, int elementary=1, int physical=1);
virtual void writeVTK(FILE *fp, bool binary=false, bool bigEndian=false);
virtual void writeMESH(FILE *fp, int elementTagType=1, int elementary=1,
int physical=0);
virtual void writeIR3(FILE *fp, int elementTagType, int num, int elementary,
int physical);
virtual void writeBDF(FILE *fp, int format=0, int elementTagType=1,
int elementary=1, int physical=0);
virtual void writeDIFF(FILE *fp, int num, bool binary=false,
int physical_property=1);
virtual void writeINP(FILE *fp, int num);
virtual void writeSU2(FILE *fp, int num);
// info for specific IO formats (returning 0 means that the element
// is not implemented in that format)
virtual int getTypeForMSH() const { return 0; }
virtual int getTypeForUNV() const { return 0; }
virtual int getTypeForVTK() const { return 0; }
virtual const char *getStringForPOS() const { return 0; }
virtual const char *getStringForBDF() const { return 0; }
virtual const char *getStringForDIFF() const { return 0; }
virtual const char *getStringForINP() const { return 0; }
// return the number of vertices, as well as the element name if
// 'name' != 0
static int getInfoMSH(const int typeMSH, const char **const name=0);
virtual int getNumVerticesForMSH() { return getNumVertices(); }
virtual void getVerticesIdForMSH(std::vector<int> &verts);
// copy element and parent if any, vertexMap contains the new vertices
virtual MElement *copy(std::map<int, MVertex*> &vertexMap,
std::map<MElement*, MElement*> &newParents,
std::map<MElement*, MElement*> &newDomains);
};
class MElementFactory{
public:
MElement *create(int type, std::vector<MVertex*> &v, int num=0, int part=0,
bool owner=false, MElement *parent=0, MElement *d1=0, MElement *d2=0);
MElement *create(int num, int type, const std::vector<int> &data, GModel *model);
};
// Traits of various elements based on the dimension. These generally define
// the faces of 2-D elements as MEdge and 3-D elements as MFace.
template <unsigned DIM> struct DimTr;
template <> struct DimTr<2>
{
typedef MEdge FaceT;
static int getNumFace(MElement *const element)
{
return element->getNumEdges();
}
static MEdge getFace(MElement *const element, const int iFace)
{
return element->getEdge(iFace);
}
static void getAllFaceVertices(MElement *const element, const int iFace,
std::vector<MVertex*> &v)
{
element->getEdgeVertices(iFace, v);
}
};
template <> struct DimTr<3>
{
typedef MFace FaceT;
static int getNumFace(MElement *const element)
{
return element->getNumFaces();
}
static MFace getFace(MElement *const element, const int iFace)
{
return element->getFace(iFace);
}
static void getAllFaceVertices(MElement *const element, const int iFace,
std::vector<MVertex*> &v)
{
element->getFaceVertices(iFace, v);
}
};
#endif
|