1 // Gmsh - Copyright (C) 1997-2021 C. Geuzaine, J.-F. Remacle
2 //
3 // See the LICENSE.txt file in the Gmsh root directory for license information.
4 // Please report all issues on https://gitlab.onelab.info/gmsh/gmsh/issues.
5
6 #ifndef NODALBASIS_H
7 #define NODALBASIS_H
8
9 #include "fullMatrix.h"
10 #include "GmshDefines.h"
11
12 class nodalBasis {
13 public:
14 int type, parentType, order, dimension, numFaces;
15 bool serendip;
16 fullMatrix<double> points;
17
nodalBasis()18 nodalBasis() {}
19 nodalBasis(int tag);
~nodalBasis()20 virtual ~nodalBasis() {}
21 virtual int getNumShapeFunctions() const = 0;
22 int getNumBubbleShapeFunctions() const;
getReferenceNodes(fullMatrix<double> & nodes)23 void getReferenceNodes(fullMatrix<double> &nodes) const { nodes = points; }
getReferenceNodes()24 const fullMatrix<double> &getReferenceNodes() const { return points; }
25
26 // compute the matrix that projects the provided points on the current control
27 // points
28 bool forwardTransformation(const fullMatrix<double> &otherPoints,
29 fullMatrix<double> &projection,
30 int elementType = -1) const;
31
32 // compute the renumbering vector to map the provided points on the current
33 // control points
34 bool forwardRenumbering(const fullMatrix<double> &otherPoints, int *renum,
35 int elemenType = -1) const;
36
37 // Basis functions & gradients evaluation
38 virtual void f(double u, double v, double w, double *sf) const = 0;
39 virtual void f(const fullMatrix<double> &coord,
40 fullMatrix<double> &sf) const = 0;
41 virtual void f(double u, double v, double w, int i, double *sf) const = 0;
42 virtual void df(double u, double v, double w, double grads[][3]) const = 0;
43 virtual void df(const fullMatrix<double> &coord,
44 fullMatrix<double> &dfm) const = 0;
45 virtual void df(double u, double v, double w, int i,
46 double grad[3]) const = 0;
ddf(double u,double v,double w,double grads[][3][3])47 virtual void ddf(double u, double v, double w, double grads[][3][3]) const
48 {
49 Msg::Error("ddf not implemented for this basis");
50 }
dddf(double u,double v,double w,double grads[][3][3][3])51 virtual void dddf(double u, double v, double w, double grads[][3][3][3]) const
52 {
53 Msg::Error("dddf not implemented for this basis");
54 }
55
56 // closures is the list of the nodes of each face, in the order of the
57 // polynomialBasis of the face; fullClosures is mapping of the nodes of the
58 // element that rotates the element so that the considered face becomes the
59 // first one in the right orientation; For element, like prisms that have
60 // different kind of faces, fullCLosure[i] rotates the element so that the
61 // considered face becomes the closureRef[i]-th face (the first triangle or
62 // the first quad face)
63 class closure : public std::vector<int> {
64 public:
65 int type;
66 };
67 typedef std::vector<closure> clCont;
68 clCont closures, fullClosures;
69 std::vector<int> closureRef;
70
71 // for a given face/edge, with both a sign and a rotation, give an ordered
72 // list of nodes on this face/edge
getClosureType(int id)73 virtual int getClosureType(int id) const { return closures[id].type; }
getClosure(int id)74 virtual const std::vector<int> &getClosure(int id) const
75 {
76 return closures[id];
77 }
getFullClosure(int id)78 virtual const std::vector<int> &getFullClosure(int id) const
79 {
80 return fullClosures[id];
81 }
82 inline int getClosureId(int iFace, int iSign = 1, int iRot = 0) const;
83 inline void breakClosureId(int i, int &iFace, int &iSign, int &iRot) const;
84 };
85
getClosureId(int iFace,int iSign,int iRot)86 inline int nodalBasis::getClosureId(int iFace, int iSign, int iRot) const
87 {
88 return iFace + numFaces * (iSign == 1 ? 0 : 1) + 2 * numFaces * iRot;
89 }
90
breakClosureId(int i,int & iFace,int & iSign,int & iRot)91 inline void nodalBasis::breakClosureId(int i, int &iFace, int &iSign,
92 int &iRot) const
93 {
94 iFace = i % numFaces;
95 i = (i - iFace) / numFaces;
96 iSign = i % 2;
97 iRot = (i - iSign) / 2;
98 }
99
100 #endif
101