From 8e8be2a5f37db74596204c37da6f2adf416e82da Mon Sep 17 00:00:00 2001 From: Bastien Gorissen <bastien.gorissen@cenaero.be> Date: Fri, 26 Oct 2012 10:24:07 +0000 Subject: [PATCH] Grouped points generation methods for elements into a single file. --- Numeric/CMakeLists.txt | 1 + Numeric/pointsGenerators.cpp | 786 +++++++++++++++++++++++++++++++++++ Numeric/pointsGenerators.h | 44 ++ 3 files changed, 831 insertions(+) create mode 100644 Numeric/pointsGenerators.cpp create mode 100644 Numeric/pointsGenerators.h diff --git a/Numeric/CMakeLists.txt b/Numeric/CMakeLists.txt index 8a69629800..62bab4da4f 100644 --- a/Numeric/CMakeLists.txt +++ b/Numeric/CMakeLists.txt @@ -11,6 +11,7 @@ set(SRC BergotBasis.cpp jacobiPolynomials.cpp legendrePolynomials.cpp + pointsGenerators.cpp GaussIntegration.cpp GaussQuadratureLin.cpp GaussQuadratureTri.cpp diff --git a/Numeric/pointsGenerators.cpp b/Numeric/pointsGenerators.cpp new file mode 100644 index 0000000000..c340ca51d6 --- /dev/null +++ b/Numeric/pointsGenerators.cpp @@ -0,0 +1,786 @@ +// Gmsh - Copyright (C) 1997-2012 C. Geuzaine, J.-F. Remacle +// +// See the LICENSE.txt file for license information. Please report all +// bugs and problems to <gmsh@geuz.org>. + +#include "pointsGenerators.h" + +/* --- Lines --- */ + +fullMatrix<double> gmshGeneratePointsLine(int order) +{ + fullMatrix<double> points(order + 1, 1); + points(0,0) = 0; + if (order > 0) { + points(0, 0) = -1.; + points(1, 0) = 1.; + double dd = 2. / order; + for (int i = 2; i < order + 1; i++) points(i, 0) = -1. + dd * (i - 1); + } + return points; +} + +/* --- Triangles --- */ + +fullMatrix<double> gmshGeneratePointsTriangle(int order, bool serendip) +{ + int nbPoints = serendip ? 3 * order : (order + 1) * (order + 2) / 2; + fullMatrix<double> points(nbPoints, 2); + + points(0, 0) = 0; + points(0, 1) = 0; + + if (order > 0) { + double dd = 1. / order; + + points(1, 0) = 1; + points(1, 1) = 0; + points(2, 0) = 0; + points(2, 1) = 1; + + int index = 3; + + if (order > 1) { + + double ksi = 0; + double eta = 0; + + for (int i = 0; i < order - 1; i++, index++) { + ksi += dd; + points(index, 0) = ksi; + points(index, 1) = eta; + } + + ksi = 1.; + + for (int i = 0; i < order - 1; i++, index++) { + ksi -= dd; + eta += dd; + points(index, 0) = ksi; + points(index, 1) = eta; + } + + eta = 1.; + ksi = 0.; + + for (int i = 0; i < order - 1; i++, index++) { + eta -= dd; + points(index, 0) = ksi; + points(index, 1) = eta; + } + + if (order > 2 && !serendip) { + fullMatrix<double> inner = gmshGeneratePointsTriangle(order - 3, serendip); + inner.scale(1. - 3. * dd); + inner.add(dd); + points.copy(inner, 0, nbPoints - index, 0, 2, index, 0); + } + } + } + return points; +} + +/* --- Quadrangles --- */ + +fullMatrix<double> gmshGeneratePointsQuadrangle(int order, bool serendip) +{ + int nbPoints = serendip ? order*4 : (order+1)*(order+1); + fullMatrix<double> points(nbPoints, 2); + + if (order > 0) { + points(0, 0) = -1; + points(0, 1) = -1; + points(1, 0) = 1; + points(1, 1) = -1; + points(2, 0) = 1; + points(2, 1) = 1; + points(3, 0) = -1; + points(3, 1) = 1; + + if (order > 1) { + int index = 4; + const static int edges[4][2]={{0,1},{1,2},{2,3},{3,0}}; + for (int iedge=0; iedge<4; iedge++) { + int p0 = edges[iedge][0]; + int p1 = edges[iedge][1]; + for (int i = 1; i < order; i++, index++) { + points(index, 0) = points(p0, 0) + i*(points(p1,0)-points(p0,0))/order; + points(index, 1) = points(p0, 1) + i*(points(p1,1)-points(p0,1))/order; + } + } + if (order >= 2 && !serendip) { + fullMatrix<double> inner = gmshGeneratePointsQuadrangle(order-2, false); + inner.scale(1. - 2./order); + points.copy(inner, 0, nbPoints - index, 0, 2, index, 0); + } + } + } + else { + points(0, 0) = 0; + points(0, 1) = 0; + } + return points; + + +} + +/* --- Tetahedra --- */ + +static int nbdoftriangle(int order) { return (order + 1) * (order + 2) / 2; } + +//KH : caveat : node coordinates are not yet coherent with node numbering associated +// to numbering of principal vertices of face !!!! + +// uv surface - orientation v0-v2-v1 +static void nodepositionface0(int order, double *u, double *v, double *w) +{ + int ndofT = nbdoftriangle(order); + if (order == 0) { u[0] = 0.; v[0] = 0.; w[0] = 0.; return; } + + u[0]= 0.; v[0]= 0.; w[0] = 0.; + u[1]= 0.; v[1]= order; w[1] = 0.; + u[2]= order; v[2]= 0.; w[2] = 0.; + + // edges + for (int k = 0; k < (order - 1); k++){ + u[3 + k] = 0.; + v[3 + k] = k + 1; + w[3 + k] = 0.; + + u[3 + order - 1 + k] = k + 1; + v[3 + order - 1 + k] = order - 1 - k ; + w[3 + order - 1 + k] = 0.; + + u[3 + 2 * (order - 1) + k] = order - 1 - k; + v[3 + 2 * (order - 1) + k] = 0.; + w[3 + 2 * (order - 1) + k] = 0.; + } + + if (order > 2){ + int nbdoftemp = nbdoftriangle(order - 3); + nodepositionface0(order - 3, &u[3 + 3 * (order - 1)], &v[3 + 3 * (order - 1)], + &w[3 + 3* (order - 1)]); + for (int k = 0; k < nbdoftemp; k++){ + u[3 + k + 3 * (order - 1)] = u[3 + k + 3 * (order - 1)] * (order - 3) + 1.; + v[3 + k + 3 * (order - 1)] = v[3 + k + 3 * (order - 1)] * (order - 3) + 1.; + w[3 + k + 3 * (order - 1)] = w[3 + k + 3 * (order - 1)] * (order - 3); + } + } + for (int k = 0; k < ndofT; k++){ + u[k] = u[k] / order; + v[k] = v[k] / order; + w[k] = w[k] / order; + } +} + +// uw surface - orientation v0-v1-v3 +static void nodepositionface1(int order, double *u, double *v, double *w) +{ + int ndofT = nbdoftriangle(order); + if (order == 0) { u[0] = 0.; v[0] = 0.; w[0] = 0.; return; } + + u[0] = 0.; v[0]= 0.; w[0] = 0.; + u[1] = order; v[1]= 0.; w[1] = 0.; + u[2] = 0.; v[2]= 0.; w[2] = order; + // edges + for (int k = 0; k < (order - 1); k++){ + u[3 + k] = k + 1; + v[3 + k] = 0.; + w[3 + k] = 0.; + + u[3 + order - 1 + k] = order - 1 - k; + v[3 + order - 1 + k] = 0.; + w[3 + order - 1+ k ] = k + 1; + + u[3 + 2 * (order - 1) + k] = 0. ; + v[3 + 2 * (order - 1) + k] = 0.; + w[3 + 2 * (order - 1) + k] = order - 1 - k; + } + if (order > 2){ + int nbdoftemp = nbdoftriangle(order - 3); + nodepositionface1(order - 3, &u[3 + 3 * (order - 1)], &v[3 + 3 * (order -1 )], + &w[3 + 3 * (order - 1)]); + for (int k = 0; k < nbdoftemp; k++){ + u[3 + k + 3 * (order - 1)] = u[3 + k + 3 * (order - 1)] * (order - 3) + 1.; + v[3 + k + 3 * (order - 1)] = v[3 + k + 3 * (order - 1)] * (order - 3); + w[3 + k + 3 * (order - 1)] = w[3 + k + 3 * (order - 1)] * (order - 3) + 1.; + } + } + for (int k = 0; k < ndofT; k++){ + u[k] = u[k] / order; + v[k] = v[k] / order; + w[k] = w[k] / order; + } +} + +// vw surface - orientation v0-v3-v2 +static void nodepositionface2(int order, double *u, double *v, double *w) +{ + int ndofT = nbdoftriangle(order); + if (order == 0) { u[0] = 0.; v[0] = 0.; return; } + + u[0]= 0.; v[0]= 0.; w[0] = 0.; + u[1]= 0.; v[1]= 0.; w[1] = order; + u[2]= 0.; v[2]= order; w[2] = 0.; + // edges + for (int k = 0; k < (order - 1); k++){ + + u[3 + k] = 0.; + v[3 + k] = 0.; + w[3 + k] = k + 1; + + u[3 + order - 1 + k] = 0.; + v[3 + order - 1 + k] = k + 1; + w[3 + order - 1 + k] = order - 1 - k; + + u[3 + 2 * (order - 1) + k] = 0.; + v[3 + 2 * (order - 1) + k] = order - 1 - k; + w[3 + 2 * (order - 1) + k] = 0.; + } + if (order > 2){ + int nbdoftemp = nbdoftriangle(order - 3); + nodepositionface2(order - 3, &u[3 + 3 * (order - 1)], &v[3 + 3 * (order - 1)], + &w[3 + 3 * (order - 1)]); + for (int k = 0; k < nbdoftemp; k++){ + u[3 + k + 3 * (order - 1)] = u[3 + k + 3 * (order - 1)] * (order - 3); + v[3 + k + 3 * (order - 1)] = v[3 + k + 3 * (order - 1)] * (order - 3) + 1.; + w[3 + k + 3 * (order - 1)] = w[3 + k + 3 * (order - 1)] * (order - 3) + 1.; + } + } + for (int k = 0; k < ndofT; k++){ + u[k] = u[k] / order; + v[k] = v[k] / order; + w[k] = w[k] / order; + } +} + +// uvw surface - orientation v3-v1-v2 +static void nodepositionface3(int order, double *u, double *v, double *w) +{ + int ndofT = nbdoftriangle(order); + if (order == 0) { u[0] = 0.; v[0] = 0.; w[0] = 0.; return; } + + u[0]= 0.; v[0]= 0.; w[0] = order; + u[1]= order; v[1]= 0.; w[1] = 0.; + u[2]= 0.; v[2]= order; w[2] = 0.; + // edges + for (int k = 0; k < (order - 1); k++){ + + u[3 + k] = k + 1; + v[3 + k] = 0.; + w[3 + k] = order - 1 - k; + + u[3 + order - 1 + k] = order - 1 - k; + v[3 + order - 1 + k] = k + 1; + w[3 + order - 1 + k] = 0.; + + u[3 + 2 * (order - 1) + k] = 0.; + v[3 + 2 * (order - 1) + k] = order - 1 - k; + w[3 + 2 * (order - 1) + k] = k + 1; + } + if (order > 2){ + int nbdoftemp = nbdoftriangle(order - 3); + nodepositionface3(order - 3, &u[3 + 3 * (order - 1)], &v[3 + 3 * (order - 1)], + &w[3 + 3 * (order - 1)]); + for (int k = 0; k < nbdoftemp; k++){ + u[3 + k + 3 * (order - 1)] = u[3 + k + 3 * (order - 1)] * (order - 3) + 1.; + v[3 + k + 3 * (order - 1)] = v[3 + k + 3 * (order - 1)] * (order - 3) + 1.; + w[3 + k + 3 * (order - 1)] = w[3 + k + 3 * (order - 1)] * (order - 3) + 1.; + } + } + for (int k = 0; k < ndofT; k++){ + u[k] = u[k] / order; + v[k] = v[k] / order; + w[k] = w[k] / order; + } +} + + +fullMatrix<double> gmshGeneratePointsTetrahedron(int order, bool serendip) +{ + + int nbPoints = + (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<double> points(nbPoints, 3); + + double overOrder = (order == 0 ? 1. : 1. / order); + + points(0, 0) = 0.; + points(0, 1) = 0.; + points(0, 2) = 0.; + + if (order > 0) { + points(1, 0) = order; + points(1, 1) = 0; + points(1, 2) = 0; + + points(2, 0) = 0.; + points(2, 1) = order; + points(2, 2) = 0.; + + points(3, 0) = 0.; + points(3, 1) = 0.; + points(3, 2) = order; + + // edges e5 and e6 switched in original version, opposite direction + // the template has been defined in table edges_tetra and faces_tetra (MElement.h) + + if (order > 1) { + for (int k = 0; k < (order - 1); k++) { + points(4 + k, 0) = k + 1; + points(4 + order - 1 + k, 0) = order - 1 - k; + points(4 + 2 * (order - 1) + k, 0) = 0.; + points(4 + 3 * (order - 1) + k, 0) = 0.; + // points(4 + 4 * (order - 1) + k, 0) = order - 1 - k; + // points(4 + 5 * (order - 1) + k, 0) = 0.; + points(4 + 4 * (order - 1) + k, 0) = 0.; + points(4 + 5 * (order - 1) + k, 0) = k+1; + + points(4 + k, 1) = 0.; + points(4 + order - 1 + k, 1) = k + 1; + points(4 + 2 * (order - 1) + k, 1) = order - 1 - k; + points(4 + 3 * (order - 1) + k, 1) = 0.; + // points(4 + 4 * (order - 1) + k, 1) = 0.; + // points(4 + 5 * (order - 1) + k, 1) = order - 1 - k; + points(4 + 4 * (order - 1) + k, 1) = k+1; + points(4 + 5 * (order - 1) + k, 1) = 0.; + + points(4 + k, 2) = 0.; + points(4 + order - 1 + k, 2) = 0.; + points(4 + 2 * (order - 1) + k, 2) = 0.; + points(4 + 3 * (order - 1) + k, 2) = order - 1 - k; + points(4 + 4 * (order - 1) + k, 2) = order - 1 - k; + points(4 + 5 * (order - 1) + k, 2) = order - 1 - k; + } + + if (order > 2) { + int ns = 4 + 6 * (order - 1); + int nbdofface = nbdoftriangle(order - 3); + + double *u = new double[nbdofface]; + double *v = new double[nbdofface]; + double *w = new double[nbdofface]; + + nodepositionface0(order - 3, u, v, w); + + // u-v plane + + for (int i = 0; i < nbdofface; i++){ + points(ns + i, 0) = u[i] * (order - 3) + 1.; + points(ns + i, 1) = v[i] * (order - 3) + 1.; + points(ns + i, 2) = w[i] * (order - 3); + } + + ns = ns + nbdofface; + + // u-w plane + + nodepositionface1(order - 3, u, v, w); + + for (int i=0; i < nbdofface; i++){ + points(ns + i, 0) = u[i] * (order - 3) + 1.; + points(ns + i, 1) = v[i] * (order - 3) ; + points(ns + i, 2) = w[i] * (order - 3) + 1.; + } + + // v-w plane + + ns = ns + nbdofface; + + nodepositionface2(order - 3, u, v, w); + + for (int i = 0; i < nbdofface; i++){ + points(ns + i, 0) = u[i] * (order - 3); + points(ns + i, 1) = v[i] * (order - 3) + 1.; + points(ns + i, 2) = w[i] * (order - 3) + 1.; + } + + // u-v-w plane + + ns = ns + nbdofface; + + nodepositionface3(order - 3, u, v, w); + + for (int i = 0; i < nbdofface; i++){ + points(ns + i, 0) = u[i] * (order - 3) + 1.; + points(ns + i, 1) = v[i] * (order - 3) + 1.; + points(ns + i, 2) = w[i] * (order - 3) + 1.; + } + + ns = ns + nbdofface; + + delete [] u; + delete [] v; + delete [] w; + + if (!serendip && order > 3) { + + fullMatrix<double> interior = gmshGeneratePointsTetrahedron(order - 4, false); + for (int k = 0; k < interior.size1(); k++) { + points(ns + k, 0) = 1. + interior(k, 0) * (order - 4); + points(ns + k, 1) = 1. + interior(k, 1) * (order - 4); + points(ns + k, 2) = 1. + interior(k, 2) * (order - 4); + } + } + } + } + } + + points.scale(overOrder); + points.print(); + return points; + +} + + + +/* --- Hexahedra --- */ + +fullMatrix<double> gmshGeneratePointsHexahedron(int order, bool serendip) +{ + int nbPoints = (order+1)*(order+1)*(order+1); + if (serendip) nbPoints -= (order-1)*(order-1)*(order-1); + fullMatrix<double> points(nbPoints, 3); + + // should be a public member of MHexahedron, just copied + static const int edges[12][2] = { + {0, 1}, + {0, 3}, + {0, 4}, + {1, 2}, + {1, 5}, + {2, 3}, + {2, 6}, + {3, 7}, + {4, 5}, + {4, 7}, + {5, 6}, + {6, 7} + }; + static const int faces[6][4] = { + {0, 3, 2, 1}, + {0, 1, 5, 4}, + {0, 4, 7, 3}, + {1, 2, 6, 5}, + {2, 3, 7, 6}, + {4, 5, 6, 7} + }; + + if (order > 0) { + points(0, 0) = -1; + points(0, 1) = -1; + points(0, 2) = -1; + points(1, 0) = 1; + points(1, 1) = -1; + points(1, 2) = -1; + points(2, 0) = 1; + points(2, 1) = 1; + points(2, 2) = -1; + points(3, 0) = -1; + points(3, 1) = 1; + points(3, 2) = -1; + + points(4, 0) = -1; + points(4, 1) = -1; + points(4, 2) = 1; + points(5, 0) = 1; + points(5, 1) = -1; + points(5, 2) = 1; + points(6, 0) = 1; + points(6, 1) = 1; + points(6, 2) = 1; + points(7, 0) = -1; + points(7, 1) = 1; + points(7, 2) = 1; + + if (order > 1) { + int index = 8; + for (int iedge=0; iedge<12; iedge++) { + int p0 = edges[iedge][0]; + int p1 = edges[iedge][1]; + for (int i = 1; i < order; i++, index++) { + points(index, 0) = points(p0, 0) + i*(points(p1,0)-points(p0,0))/order; + points(index, 1) = points(p0, 1) + i*(points(p1,1)-points(p0,1))/order; + points(index, 2) = points(p0, 2) + i*(points(p1,2)-points(p0,2))/order; + } + } + + fullMatrix<double> fp = gmshGeneratePointsQuadrangle(order - 2, false); + fp.scale(1. - 2./order); + for (int iface=0; iface<6; iface++) { + int p0 = faces[iface][0]; + int p1 = faces[iface][1]; + int p2 = faces[iface][2]; + int p3 = faces[iface][3]; + for (int i=0;i<fp.size1();i++, index++){ + const double u = fp(i,0); + const double v = fp(i,1); + const double newU = + 0.25*(1.-u)*(1.-v)*points(p0,0) + + 0.25*(1.+u)*(1.-v)*points(p1,0) + + 0.25*(1.+u)*(1.+v)*points(p2,0) + + 0.25*(1.-u)*(1.+v)*points(p3,0) ; + const double newV = + 0.25*(1.-u)*(1.-v)*points(p0,1) + + 0.25*(1.+u)*(1.-v)*points(p1,1) + + 0.25*(1.+u)*(1.+v)*points(p2,1) + + 0.25*(1.-u)*(1.+v)*points(p3,1) ; + const double newW = + 0.25*(1.-u)*(1.-v)*points(p0,2) + + 0.25*(1.+u)*(1.-v)*points(p1,2) + + 0.25*(1.+u)*(1.+v)*points(p2,2) + + 0.25*(1.-u)*(1.+v)*points(p3,2) ; + points(index, 0) = newU; + points(index, 1) = newV; + points(index, 2) = newW; + } + } + if (!serendip) { + fullMatrix<double> inner = gmshGeneratePointsHexahedron(order - 2, false); + inner.scale(1. - 2./order); + points.copy(inner, 0, nbPoints - index, 0, 3, index, 0); + } + } + } + else if (order == 0){ + points(0, 0) = 0; + points(0, 1) = 0; + points(0, 2) = 0; + } + return points; +} + +/* --- Prisms --- */ + +fullMatrix<double> gmshGeneratePointsPrism(int order, bool serendip) +{ + const double prism18Pts[18][3] = { + {0, 0, -1}, // 0 + {1, 0, -1}, // 1 + {0, 1, -1}, // 2 + {0, 0, 1}, // 3 + {1, 0, 1}, // 4 + {0, 1, 1}, // 5 + {0.5, 0, -1}, // 6 + {0, 0.5, -1}, // 7 + {0, 0, 0}, // 8 + {0.5, 0.5, -1}, // 9 + {1, 0, 0}, // 10 + {0, 1, 0}, // 11 + {0.5, 0, 1}, // 12 + {0, 0.5, 1}, // 13 + {0.5, 0.5, 1}, // 14 + {0.5, 0, 0}, // 15 + {0, 0.5, 0}, // 16 + {0.5, 0.5, 0}, // 17 + }; + + int nbPoints = (order + 1)*(order + 1)*(order + 2)/2; + fullMatrix<double> points(nbPoints, 3); + + int index = 0; + fullMatrix<double> triPoints = gmshGeneratePointsTriangle(order,false); + fullMatrix<double> linePoints = gmshGeneratePointsLine(order); + + if (order == 2) + for (int i =0; i<18; i++) + for (int j=0; j<3;j++) + points(i,j) = prism18Pts[i][j]; + else + for (int j = 0; j <linePoints.size1() ; j++) { + for (int i = 0; i < triPoints.size1(); i++) { + points(index,0) = triPoints(i,0); + points(index,1) = triPoints(i,1); + points(index,2) = linePoints(j,0); + index ++; + } + } + + return points; + +} + +/* --- Pyramids --- */ + +fullMatrix<double> gmshGeneratePointsPyramid(int order, bool serendip) +{ + int nbPoints = (order+1)*((order+1)+1)*(2*(order+1)+1)/6; + + // Remove volume points if incomplete basis + if (serendip && order > 2) nbPoints -= (order-2)*((order-2)+1)*(2*(order-2)+1)/6; + + fullMatrix<double> points(nbPoints, 3); + + static const int edges[8][2] = { + {0, 1}, + {0, 3}, + {0, 4}, + {1, 2}, + {1, 4}, + {2, 3}, + {2, 4}, + {3, 4}, + }; + static const int faces[5][4] = { + {0, 1, 4, -1}, + {3, 0, 4, -1}, + {1, 2, 4, -1}, + {2, 3, 4, -1}, + {0, 3, 2, 1} + }; + + if (order == 0) { + points(0,0) = 0.0; + points(0,1) = 0.0; + points(0,2) = 0.0; + return points; + } + + // Principal vertices of the pyramid + points(0,0) = -1.0; points(0,1) = -1.0; points(0,2) = 0.0; + points(1,0) = 1.0; points(1,1) = -1.0; points(1,2) = 0.0; + points(2,0) = 1.0; points(2,1) = 1.0; points(2,2) = 0.0; + points(3,0) = -1.0; points(3,1) = 1.0; points(3,2) = 0.0; + points(4,0) = 0.0; points(4,1) = 0.0; points(4,2) = 1.0; + + if (order > 1) { + int p = 5; + + // Edges + for (int e = 0; e < 8; e++) { + double vec[3]; + vec[0] = points(edges[e][1],0) - points(edges[e][0],0); + vec[1] = points(edges[e][1],1) - points(edges[e][0],1); + vec[2] = points(edges[e][1],2) - points(edges[e][0],2); + for (int i = 0; i < order - 1; i++) { + points(p,0) = points(edges[e][0],0) + vec[0]/order * (i+1); + points(p,1) = points(edges[e][0],1) + vec[1]/order * (i+1); + points(p,2) = points(edges[e][0],2) + vec[2]/order * (i+1); + p++; + } + } + + // Faces + for (int f = 0; f < 4; f++) { + fullMatrix<double> fp = gmshGeneratePointsTriangle(order, false); + + fullVector<double> u(4); + fullVector<double> v(4); + fullVector<double> w(4); + fullVector<double> y(4); + + fullVector<double> up(4); + fullVector<double> vp(4); + fullVector<double> wp(4); + fullVector<double> yp(4); + + for (int c = 0; c < 3; c++) { + u(c) = fp(0,c); + v(c) = fp(1,c); + w(c) = fp(2,c); + up(c) = points(faces[f][0],c); + vp(c) = points(faces[f][1],c); + wp(c) = points(faces[f][2],c); + } + + u(2) = 0.0; + v(2) = 0.0; + w(2) = 0.0; + u(3) = 1.0; + v(3) = 1.0; + w(3) = 1.0; + + y(0) = u(0) + ((v(1)-u(1))*(w(2)-u(2)) - (v(2)-u(2))*(w(1)-u(1))); + y(1) = u(1) + ((v(2)-u(2))*(w(0)-u(0)) - (v(0)-u(0))*(w(2)-u(2))); + y(2) = u(2) + ((v(0)-u(0))*(w(1)-u(1)) - (v(1)-u(1))*(w(0)-u(0))); + y(3) = 1.0; + + up(3) = 1.0; + vp(3) = 1.0; + wp(3) = 1.0; + + yp(0) = up(0) + ((vp(1)-up(1))*(wp(2)-up(2)) - (vp(2)-up(2))*(wp(1)-up(1))); + yp(1) = up(1) + ((vp(2)-up(2))*(wp(0)-up(0)) - (vp(0)-up(0))*(wp(2)-up(2))); + yp(2) = up(2) + ((vp(0)-up(0))*(wp(1)-up(1)) - (vp(1)-up(1))*(wp(0)-up(0))); + yp(3) = 1.0; + + fullMatrix<double> M(4,4); + fullMatrix<double> Mp(4,4); + + M(0,0) = u(0); M(0,1) = v(0); M(0,2) = w(0); M(0,3) = y(0); + M(1,0) = u(1); M(1,1) = v(1); M(1,2) = w(1); M(1,3) = y(1); + M(2,0) = u(2); M(2,1) = v(2); M(2,2) = w(2); M(2,3) = y(2); + M(3,0) = u(3); M(3,1) = v(3); M(3,2) = w(3); M(3,3) = y(3); + + Mp(0,0) = up(0); Mp(0,1) = vp(0); Mp(0,2) = wp(0); Mp(0,3) = yp(0); + Mp(1,0) = up(1); Mp(1,1) = vp(1); Mp(1,2) = wp(1); Mp(1,3) = yp(1); + Mp(2,0) = up(2); Mp(2,1) = vp(2); Mp(2,2) = wp(2); Mp(2,3) = yp(2); + Mp(3,0) = up(3); Mp(3,1) = vp(3); Mp(3,2) = wp(3); Mp(3,3) = yp(3); + + + M.invertInPlace(); + fullMatrix<double> T(4,4); + Mp.mult(M, T); + + for(int k = 3*order; k < fp.size1(); k++) { + fullVector<double> pnt(4); + pnt(0) = fp(k,0); + pnt(1) = fp(k,1); + pnt(2) = 0.0; + pnt(3) = 1.0; + + fullVector<double> res(4); + T.mult(pnt, res); + + points(p, 0) = res(0); + points(p, 1) = res(1); + points(p, 2) = res(2); + + p++; + + } + } + + fullMatrix<double> fpq = gmshGeneratePointsQuadrangle(order-2, false); + fullMatrix<double> transform(2,2); + fullMatrix<double> scaled(fpq.size1(), fpq.size2()); + transform(0,0) = (order-2)/(double)order; transform(0,1) = 0.0; + transform(1,0) = 0.0; transform(1,1) = (order-2)/(double)order; + fpq.mult(transform, scaled); + + for (int i = 0; i < scaled.size1(); i++) { + points(p, 0) = scaled(i, 1); + points(p, 1) = scaled(i, 0); + points(p, 2) = 0.0; + p++; + } + + // Volume + if (!serendip and order > 2) { + fullMatrix<double> volume_points = gmshGeneratePointsPyramid(order - 3, false); + // scale to order-3/order + fullMatrix<double> T(3,3); + T(0,0) = (order - 3.0) / order; T(0,1) = 0.0; T(0,2) = 0.0; + T(1,0) = 0.0; T(1,1) = (order - 3.0) / order; T(1,2) = 0.0; + T(2,0) = 0.0; T(2,1) = 0.0; T(2,2) = (order - 3.0) / order; + fullMatrix<double> scaled(volume_points.size1(), volume_points.size2()); + volume_points.mult(T, scaled); + + // translate 1/order + for (int i = 0; i < scaled.size1(); i++) { + points(p, 0) = scaled(i,0); + points(p, 1) = scaled(i,1); + points(p, 2) = scaled(i,2) + 1.0/order; + p++; + } + } + } + for (int i = 0; i < points.size1(); i++) { + printf("Point(%d) %g, %g, %g\n", i, points(i,0),points(i,1),points(i,2)); + } + printf("number of points : %d\n\n", nbPoints); + return points; +} diff --git a/Numeric/pointsGenerators.h b/Numeric/pointsGenerators.h new file mode 100644 index 0000000000..fca7e09048 --- /dev/null +++ b/Numeric/pointsGenerators.h @@ -0,0 +1,44 @@ +// Gmsh - Copyright (C) 1997-2012 C. Geuzaine, J.-F. Remacle +// +// See the LICENSE.txt file for license information. Please report all +// bugs and problems to <gmsh@geuz.org>. + +#ifndef POINTSGENERATORS_H +#define POINTSGENERATORS_H + +#include "fullMatrix.h" + + /* + * Functions to generate point distributions on + * the references elements, for all orders. + */ + +/* --- Lines --- */ + +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); + +/* --- Hexahedra --- */ + +fullMatrix<double> gmshGeneratePointsHexahedron(int order, bool serendip); + +/* --- Prisms --- */ + +fullMatrix<double> gmshGeneratePointsPrism(int order, bool serendip); + +/* --- Pyramids --- */ + +fullMatrix<double> gmshGeneratePointsPyramid(int order, bool serendip); + +#endif \ No newline at end of file -- GitLab