diff --git a/Geo/MQuadrangle.h b/Geo/MQuadrangle.h index 19591a4342706ac1ea08aaf10ab96633389dc4ab..14e3bf691e6e20196ff77ee97c4e513d0f4a0479 100644 --- a/Geo/MQuadrangle.h +++ b/Geo/MQuadrangle.h @@ -343,7 +343,7 @@ class MQuadrangle9 : public MQuadrangle { * | | N = total number of vertices * 4+3E 3+2E * | | Interior vertex numbers - * ... 4+4e to N-1 ... for edge 0 <= i <= 3: 4+i*E to 3+(i+1)*E + * ... 4+4E to N-1 ... for edge 0 <= i <= 3: 4+i*E to 3+(i+1)*E * | | in volume : 4+4*E to N-1 * 3+4E 4+E * | | diff --git a/Geo/MTetrahedron.h b/Geo/MTetrahedron.h index 5c6a7b15db716b99277f9b68a107499355380f8f..920a88bc2fcb1851e908e3a3417a3a3b9fc70a6f 100644 --- a/Geo/MTetrahedron.h +++ b/Geo/MTetrahedron.h @@ -275,37 +275,19 @@ class MTetrahedron10 : public MTetrahedron { } }; -/* - * MTetrahedronN FIXME: check the plot - * - * 2 - * ,/|`\ - * ,/ | `\ E = order - 1 - * ,/ '. `\ C = 4 + 6*E - * ,/ | `\ F = ((order - 1)*(order - 2))/2 - * ,/ | `\ N = total number of vertices - * 0-----------'.--------1 - * `\. | ,/ Interior vertex numbers - * `\. | ,/ for edge 0 <= i <= 5: 4+i*E to 3+(i+1)*E - * `\. '. ,/ for face 0 <= j <= 3: C+j*F to C-1+(j+1)*F - * `\. |/ in volume : C+4*F to N-1 - * `3 +/* tet order 3 FIXME: check the plot * - */ - -/* tet order 3 - * 2 * ,/|`\ - * ,5 | `6 E = order - 1 - * ,/ 12 `\ C = 4 + 6*E - * ,4 | `7 F = ((order - 1)*(order - 2))/2 + * ,8 | `7 E = order - 1 + * ,/ 13 `\ C = 4 + 6*E + * ,9 | `6 F = ((order - 1)*(order - 2))/2 * ,/ | `\ N = total number of vertices - * 0-----9-----'.--8-----1 + * 0-----4-----'.--5-----1 * `\. | ,/ Interior vertex numbers - * 10. 13 ,14 for edge 0 <= i <= 5: 4+i*E to 3+(i+1)*E - * `\. '. 15 for face 0 <= j <= 3: C+j*F to C-1+(j+1)*F - * 11\.|/ in volume : C+4*F to N-1 + * 11. 12 ,15 for edge 0 <= i <= 5: 4+i*E to 4+(i+1)*E-1 + * `\. '. 14 for face 0 <= j <= 3: C+j*F to C+(j+1)*F-1 + * 10\.|/ in volume : C+4*F to N-1 * `3 * */ diff --git a/Numeric/nodalBasis.cpp b/Numeric/nodalBasis.cpp index 38126f89c91b09b77e0e73ac68f6c7a2cbcdb7ea..8a2c1b3c656c8b7f56a0a8fae2f03e87612410fb 100644 --- a/Numeric/nodalBasis.cpp +++ b/Numeric/nodalBasis.cpp @@ -1372,9 +1372,8 @@ static void generateClosureOrder0(nodalBasis::clCont &closure, int nb) nodalBasis::nodalBasis(int tag) { - type = tag; - + switch (tag) { case MSH_PNT : parentType = TYPE_PNT; order = 0; serendip = false; break; case MSH_LIN_1 : parentType = TYPE_LIN; order = 0; serendip = false; break; diff --git a/Numeric/nodalBasis.h b/Numeric/nodalBasis.h index 5bc687fdcb205a9705b7f630336b79c03ba57c4f..eb545bbeaa496e7dca3ea473fafd8ac791a57265 100644 --- a/Numeric/nodalBasis.h +++ b/Numeric/nodalBasis.h @@ -10,33 +10,26 @@ #include "GmshDefines.h" class nodalBasis { - public: int type, parentType, order, dimension, numFaces; bool serendip; fullMatrix<double> points; - + nodalBasis(int tag); virtual ~nodalBasis() {} - - // Basis functions evaluation - virtual void f(double u, double v, double w, double *sf) const {Msg::Fatal("Not implemented");}; - virtual void f(const fullMatrix<double> &coord, fullMatrix<double> &sf) const {Msg::Fatal("Not implemented");}; - - // Basis functions gradients evaluation - virtual void df(double u, double v, double w, double grads[][3]) const {Msg::Fatal("Not implemented");}; - virtual void df(const fullMatrix<double> &coord, fullMatrix<double> &dfm) const {Msg::Fatal("Not implemented");}; + virtual int getNumShapeFunctions() const = 0; + + // Basis functions & gradients evaluation + virtual void f(double u, double v, double w, double *sf) const = 0; + virtual void f(const fullMatrix<double> &coord, fullMatrix<double> &sf) const = 0; + virtual void df(double u, double v, double w, double grads[][3]) const = 0; + virtual void df(const fullMatrix<double> &coord, fullMatrix<double> &dfm) const = 0; virtual void ddf(double u, double v, double w, double grads[][3][3]) const {Msg::Fatal("Not implemented");}; virtual void dddf(double u, double v, double w, double grads[][3][3][3]) const {Msg::Fatal("Not implemented");}; - - virtual int getNumShapeFunctions() const {Msg::Fatal("Not implemented"); return -1;} - - class closure : public std::vector<int> { - public: - int type; - }; - typedef std::vector<closure> clCont; + + + // closures is the list of the nodes of each face, in the order of // the polynomialBasis of the face; fullClosures is mapping of the // nodes of the element that rotates the element so that the @@ -45,9 +38,14 @@ class nodalBasis { // fullCLosure[i] rotates the element so that the considered face // becomes the closureRef[i]-th face (the first tringle or the first // quad face) + class closure : public std::vector<int> { + public: + int type; + }; + typedef std::vector<closure> clCont; clCont closures, fullClosures; std::vector<int> closureRef; - + // for a given face/edge, with both a sign and a rotation, give an // ordered list of nodes on this face/edge virtual int getClosureType(int id) const { return closures[id].type; } @@ -55,9 +53,8 @@ class nodalBasis { virtual const std::vector<int> &getFullClosure(int id) const { return fullClosures[id]; } inline int getClosureId(int iFace, int iSign=1, int iRot=0) const; inline void breakClosureId(int i, int &iFace, int &iSign, int &iRot) const; - + static inline int getTag(int parentTag, int order, bool serendip = false); - }; diff --git a/Numeric/pointsGenerators.cpp b/Numeric/pointsGenerators.cpp index 6c3db2a1a7be8300fbde5c54a65230da324fdd82..5b4e4221ac253acd5cd71f06281aafe99efc5efb 100644 --- a/Numeric/pointsGenerators.cpp +++ b/Numeric/pointsGenerators.cpp @@ -4,6 +4,10 @@ // bugs and problems to the public mailing list <gmsh@geuz.org>. #include "pointsGenerators.h" +#include "MTriangle.h" +#include "MQuadrangle.h" +#include "MTetrahedron.h" +#include "MHexahedron.h" /* --- Lines --- */ @@ -779,3 +783,309 @@ fullMatrix<double> gmshGeneratePointsPyramid(int order, bool serendip) } return points; } + + + + +fullMatrix<int> gmshGenerateMonomialsLine(int order) +{ + fullMatrix<int> monomials(order + 1, 1); + monomials(0,0) = 0; + if (order > 0) { + monomials(1, 0) = order; + for (int i = 2; i < order + 1; i++) monomials(i, 0) = i-1; + } + return monomials; +} +fullMatrix<int> gmshGenerateMonomialsTriangle(int order, bool serendip) +{ + int nbMonomials = serendip ? 3 * order : (order + 1) * (order + 2) / 2; + fullMatrix<int> monomials(nbMonomials, 2); + + monomials(0, 0) = 0; + monomials(0, 1) = 0; + + if (order > 0) { + monomials(1, 0) = order; + monomials(1, 1) = 0; + + monomials(2, 0) = 0; + monomials(2, 1) = order; + + if (order > 1) { + int index = 3; + for (int iedge = 0; iedge < 3; ++iedge) { + int i0 = MTriangle::edges_tri(iedge, 0); + int i1 = MTriangle::edges_tri(iedge, 1); + + int u_0 = (monomials(i1,0)-monomials(i0,0)) / order; + int u_1 = (monomials(i1,1)-monomials(i0,1)) / order; + + for (int i = 1; i < order; ++i, ++index) { + monomials(index, 0) = monomials(i0, 0) + u_0 * i; + monomials(index, 1) = monomials(i0, 1) + u_1 * i; + } + } + fullMatrix<int> inner = gmshGenerateMonomialsQuadrangle(order-2); + inner.add(1); + monomials.copy(inner, 0, nbMonomials - index, 0, 2, index, 0); + } + } + return monomials; +} +fullMatrix<int> gmshGenerateMonomialsQuadrangle(int order) +{ + int nbMonomials = (order+1)*(order+1); + fullMatrix<int> monomials(nbMonomials, 2); + + monomials(0, 0) = 0; + monomials(0, 1) = 0; + + if (order > 0) { + monomials(1, 0) = order; + monomials(1, 1) = 0; + + monomials(2, 0) = order; + monomials(2, 1) = order; + + monomials(3, 0) = 0; + monomials(3, 1) = order; + + if (order > 1) { + int index = 4; + for (int iedge = 0; iedge < 4; ++iedge) { + int i0 = MQuadrangle::edges_quad(iedge, 0); + int i1 = MQuadrangle::edges_quad(iedge, 1); + + int u_0 = (monomials(i1,0)-monomials(i0,0)) / order; + int u_1 = (monomials(i1,1)-monomials(i0,1)) / order; + + for (int i = 1; i < order; ++i, ++index) { + monomials(index, 0) = monomials(i0, 0) + u_0 * i; + monomials(index, 1) = monomials(i0, 1) + u_1 * i; + } + } + fullMatrix<int> inner = gmshGenerateMonomialsQuadrangle(order-2); + inner.add(1); + monomials.copy(inner, 0, nbMonomials - index, 0, 2, index, 0); + } + } + return monomials; +} +//KH : caveat : node coordinates are not yet coherent with node numbering associated +// to numbering of principal vertices of face !!!! +fullMatrix<int> gmshGenerateMonomialsTetrahedron(int order, bool serendip) +{ + int nbMonomials = + (serendip ? + 4 + 6 * std::max(0, order - 1) + 4 * std::max(0, (order - 2) * (order - 1) / 2) : + (order + 1) * (order + 2) * (order + 3) / 6); + + fullMatrix<int> monomials(nbMonomials, 3); + + monomials(0, 0) = 0; + monomials(0, 1) = 0; + monomials(0, 2) = 0; + + if (order > 0) { + monomials(1, 0) = order; + monomials(1, 1) = 0; + monomials(1, 2) = 0; + + monomials(2, 0) = 0; + monomials(2, 1) = order; + monomials(2, 2) = 0; + + monomials(3, 0) = 0; + monomials(3, 1) = 0; + monomials(3, 2) = order; + + // the template has been defined in table edges_tetra and faces_tetra (MElement.h) + + if (order > 1) { + int index = 4; + for (int iedge = 0; iedge < 6; ++iedge) { + int i0 = MTetrahedron::edges_tetra(iedge, 0); + int i1 = MTetrahedron::edges_tetra(iedge, 1); + + int u[3]; + u[0] = (monomials(i1,0)-monomials(i0,0)) / order; + u[1] = (monomials(i1,1)-monomials(i0,1)) / order; + u[2] = (monomials(i1,2)-monomials(i0,2)) / order; + + for (int i = 1; i < order; ++i, ++index) { + monomials(index, 0) = monomials(i0, 0) + u[0] * i; + monomials(index, 1) = monomials(i0, 1) + u[1] * i; + monomials(index, 2) = monomials(i0, 2) + u[2] * i; + } + } + + if (order > 2) { + fullMatrix<int> dudv = gmshGenerateMonomialsTriangle(order - 3); + + for (int iface = 0; iface < 4; ++iface) { + int i0 = MTetrahedron::faces_tetra(iface, 0); + int i1 = MTetrahedron::faces_tetra(iface, 1); + int i2 = MTetrahedron::faces_tetra(iface, 2); + + int u[3]; + u[0] = (monomials(i1, 0) - monomials(i0, 0)) / order; + u[1] = (monomials(i1, 1) - monomials(i0, 1)) / order; + u[2] = (monomials(i1, 2) - monomials(i0, 2)) / order; + int v[3]; + v[0] = (monomials(i2, 0) - monomials(i0, 0)) / order; + v[1] = (monomials(i2, 1) - monomials(i0, 1)) / order; + v[2] = (monomials(i2, 2) - monomials(i0, 2)) / order; + + for (int i = 0; i < dudv.size1(); ++i, ++index) { + monomials(index, 0) = monomials(i0, 0) + u[0] * dudv(i, 0) + v[0] * dudv(i, 1); + monomials(index, 1) = monomials(i0, 1) + u[1] * dudv(i, 0) + v[1] * dudv(i, 1); + monomials(index, 2) = monomials(i0, 2) + u[2] * dudv(i, 0) + v[2] * dudv(i, 1); + } + } + + if (!serendip && order > 3) { + fullMatrix<int> inner = gmshGenerateMonomialsTetrahedron(order - 4); + inner.add(1); + monomials.copy(inner, 0, nbMonomials - index, 0, 3, index, 0); + } + } + } + } + return monomials; +} +/* +fullMatrix<int> gmshGenerateMonomialsPrism(int order) +{ + const int prism18Pts[18][3] = { + {0, 0, 0}, // 0 + {2, 0, 0}, // 1 + {0, 2, 0}, // 2 + {0, 0, 2}, // 3 + {2, 0, 2}, // 4 + {0, 2, 2}, // 5 + {1, 0, 0}, // 6 + {0, 1, 0}, // 7 + {0, 0, 1}, // 8 + {1, 1, 0}, // 9 + {2, 0, 1}, // 10 + {0, 2, 1}, // 11 + {1, 0, 2}, // 12 + {0, 1, 2}, // 13 + {1, 1, 2}, // 14 + {1, 0, 1}, // 15 + {0, 1, 1}, // 16 + {1, 1, 1}, // 17 + }; + + int nbMonomials = (order + 1)*(order + 1)*(order + 2)/2; + fullMatrix<int> monomials(nbMonomials, 3); + + int index = 0; + fullMatrix<int> triMonomials = gmshGenerateMonomialsTriangle(order,false); + fullMatrix<int> lineMonomials = gmshGenerateMonomialsLine(order); + + if (order == 2) + for (int i =0; i<18; i++) + for (int j=0; j<3;j++) + monomials(i,j) = prism18Pts[i][j]; + else + for (int j = 0; j <lineMonomials.size1() ; j++) { + for (int i = 0; i < triMonomials.size1(); i++) { + monomials(index,0) = triMonomials(i,0); + monomials(index,1) = triMonomials(i,1); + monomials(index,2) = lineMonomials(j,0); + index++; + } + } + + return monomials; + +} +*/ +fullMatrix<int> gmshGenerateMonomialsHexahedron(int order) +{ + int nbMonomials = (order+1)*(order+1)*(order+1); + fullMatrix<int> monomials(nbMonomials, 3); + + monomials(0, 0) = 0; + monomials(0, 1) = 0; + monomials(0, 2) = 0; + + if (order > 0) { + monomials(1, 0) = order; + monomials(1, 1) = 0; + monomials(1, 2) = 0; + + monomials(2, 0) = order; + monomials(2, 1) = order; + monomials(2, 2) = 0; + + monomials(3, 0) = 0; + monomials(3, 1) = order; + monomials(3, 2) = 0; + + monomials(4, 0) = 0; + monomials(4, 1) = 0; + monomials(4, 2) = order; + + monomials(5, 0) = order; + monomials(5, 1) = 0; + monomials(5, 2) = order; + + monomials(6, 0) = order; + monomials(6, 1) = order; + monomials(6, 2) = order; + + monomials(7, 0) = 0; + monomials(7, 1) = order; + monomials(7, 2) = order; + + if (order > 1) { + int index = 8; + for (int iedge = 0; iedge < 12; ++iedge) { + int i0 = MHexahedron::edges_hexa(iedge, 0); + int i1 = MHexahedron::edges_hexa(iedge, 1); + + int u_1 = (monomials(i1,0)-monomials(i0,0)) / order; + int u_2 = (monomials(i1,1)-monomials(i0,1)) / order; + int u_3 = (monomials(i1,2)-monomials(i0,2)) / order; + + for (int i = 1; i < order; ++i, ++index) { + monomials(index, 0) = monomials(i0, 0) + i * u_1; + monomials(index, 1) = monomials(i0, 1) + i * u_2; + monomials(index, 2) = monomials(i0, 2) + i * u_3; + } + } + + fullMatrix<int> dudv = gmshGenerateMonomialsQuadrangle(order - 3); + + for (int iface = 0; iface < 6; ++iface) { + int i0 = MHexahedron::faces_hexa(iface, 0); + int i1 = MHexahedron::faces_hexa(iface, 1); + int i3 = MHexahedron::faces_hexa(iface, 3); + + int u[3]; + u[0] = (monomials(i1, 0) - monomials(i0, 0)) / order; + u[1] = (monomials(i1, 1) - monomials(i0, 1)) / order; + u[2] = (monomials(i1, 2) - monomials(i0, 2)) / order; + int v[3]; + v[0] = (monomials(i3, 0) - monomials(i0, 0)) / order; + v[1] = (monomials(i3, 1) - monomials(i0, 1)) / order; + v[2] = (monomials(i3, 2) - monomials(i0, 2)) / order; + + for (int i = 0; i < dudv.size1(); ++i, ++index) { + monomials(index, 0) = monomials(i0, 0) + u[0] * dudv(i, 0) + v[0] * dudv(i, 1); + monomials(index, 1) = monomials(i0, 1) + u[1] * dudv(i, 0) + v[1] * dudv(i, 1); + monomials(index, 2) = monomials(i0, 2) + u[2] * dudv(i, 0) + v[2] * dudv(i, 1); + } + } + + fullMatrix<int> inner = gmshGenerateMonomialsHexahedron(order - 2); + inner.add(1); + monomials.copy(inner, 0, nbMonomials - index, 0, 3, index, 0); + } + } + return monomials; +} + diff --git a/Numeric/pointsGenerators.h b/Numeric/pointsGenerators.h index 583b874d153963621979010cc8493117b9d6d5f3..5aa57b2c7f2376b74c01a81e2fa91acbb14a1652 100644 --- a/Numeric/pointsGenerators.h +++ b/Numeric/pointsGenerators.h @@ -11,34 +11,36 @@ /* * Functions to generate point distributions on * the references elements, for all orders. + * & + * Functions generating exponents of Pascal monomials + * in the same order than Gmsh Points. */ -/* --- Lines --- */ - +// Points fullMatrix<double> gmshGeneratePointsLine(int order); -/* --- Triangles --- */ - fullMatrix<double> gmshGeneratePointsTriangle(int order, bool serendip); - -/* --- Quadrangles --- */ - fullMatrix<double> gmshGeneratePointsQuadrangle(int order, bool serendip); -/* --- Tetahedra --- */ - fullMatrix<double> gmshGeneratePointsTetrahedron(int order, bool serendip); +fullMatrix<double> gmshGeneratePointsHexahedron(int order, bool serendip); +fullMatrix<double> gmshGeneratePointsPrism(int order, bool serendip); -/* --- Hexahedra --- */ +fullMatrix<double> gmshGeneratePointsPyramid(int order, bool serendip); -fullMatrix<double> gmshGeneratePointsHexahedron(int order, bool serendip); +// Monomial exponents +fullMatrix<int> gmshGenerateMonomialsLine(int order); -/* --- Prisms --- */ +fullMatrix<int> gmshGenerateMonomialsTriangle(int order, bool serendip = false); +fullMatrix<int> gmshGenerateMonomialsQuadrangle(int order); +//fullMatrix<int> gmshGenerateMonomialsQuadSerendipity(int order); -fullMatrix<double> gmshGeneratePointsPrism(int order, bool serendip); +fullMatrix<int> gmshGenerateMonomialsTetrahedron(int order, bool serendip = false); +fullMatrix<int> gmshGenerateMonomialsHexahedron(int order); +//fullMatrix<int> gmshGenerateMonomialsPrism(int order); + +//fullMatrix<int> gmshGenerateMonomialsPyramid(int order, bool serendip); -/* --- Pyramids --- */ -fullMatrix<double> gmshGeneratePointsPyramid(int order, bool serendip); #endif diff --git a/Numeric/polynomialBasis.h b/Numeric/polynomialBasis.h index 0c09ef633c896f699efc23abe42a2f98e5fc49e6..395f55ada3c8e5c73a61594d3cea35f7611c721c 100644 --- a/Numeric/polynomialBasis.h +++ b/Numeric/polynomialBasis.h @@ -64,52 +64,33 @@ inline double pow_int(const double &a, const int &n) } } -fullMatrix<double> generate1DMonomials(int order); - - - - class polynomialBasis : public nodalBasis { - // integrationOrder, closureId => df/dXi -// mutable std::map<int,std::vector<fullMatrix<double> > > _dfAtFace; public: // for now the only implemented polynomial basis are nodal poly // basis, we use the type of the corresponding gmsh element as type - //int type, parentType, order, dimension; - //bool serendip; - - //fullMatrix<double> points; fullMatrix<double> monomials; fullMatrix<double> coefficients; - + polynomialBasis(int tag); ~polynomialBasis(); - + + virtual int getNumShapeFunctions() const; + virtual void f(double u, double v, double w, double *sf) const; virtual void f(const fullMatrix<double> &coord, fullMatrix<double> &sf) const; virtual void df(const fullMatrix<double> &coord, fullMatrix<double> &dfm) const; virtual void df(double u, double v, double w, double grads[][3]) const; virtual void ddf(double u, double v, double w, double hess[][3][3]) const; virtual void dddf(double u, double v, double w, double third[][3][3][3]) const; - - virtual int getNumShapeFunctions() const; - - inline void evaluateMonomials(double u, double v, double w, double p[]) const; - -}; - - - -inline void polynomialBasis::evaluateMonomials(double u, double v, double w, double p[]) const -{ - for (int j = 0; j < monomials.size1(); j++) { - p[j] = pow_int(u, (int)monomials(j, 0)); - if (monomials.size2() > 1) p[j] *= pow_int(v, (int)monomials(j, 1)); - if (monomials.size2() > 2) p[j] *= pow_int(w, (int)monomials(j, 2)); + + inline void evaluateMonomials(double u, double v, double w, double p[]) const { + for (int j = 0; j < monomials.size1(); j++) { + p[j] = pow_int(u, (int)monomials(j, 0)); + if (monomials.size2() > 1) p[j] *= pow_int(v, (int)monomials(j, 1)); + if (monomials.size2() > 2) p[j] *= pow_int(w, (int)monomials(j, 2)); + } } -} - - +}; #endif diff --git a/contrib/voro++/examples/degenerate/degenerate2.cc b/contrib/voro++/examples/degenerate/degenerate2.cc index 6165d605d14516390afd4ca3aaf698e75669809b..7ffe17a875e9ee01f12013e16f7b9b372502e392 100644 --- a/contrib/voro++/examples/degenerate/degenerate2.cc +++ b/contrib/voro++/examples/degenerate/degenerate2.cc @@ -10,7 +10,7 @@ using namespace voro; const double pi=3.1415926535897932384626433832795; // The total number of points to create as degenerate vertices -const int points=100; +const int voro_points=100; // The number of planes that will be cut around each point const int n=64; @@ -32,7 +32,7 @@ int main() { v.init(-1,1,-1,1,-1,1); // Plane cutting - while(n<points) { + while(n<voro_points) { // Choose a random point x=2*rnd()-1;