From 25514ecbe472cab87cacf2a92d7432c6dccac7a4 Mon Sep 17 00:00:00 2001 From: Christophe Geuzaine <cgeuzaine@ulg.ac.be> Date: Sat, 13 Nov 2004 23:57:28 +0000 Subject: [PATCH] - First draft (pretty much untested!) of new "Integrate" plugin to * integrate scalar fields over all the elements in a view * integrate the circulation of vector fields along line elements * integrate the flux of vector fields across surface elements Used with Plugin(DisplacementRaise) and Plugin(Evaluate) this permits for example to compute the area/volume of deformed configurations; and, with Plugin(CutPlane)+Plugin(Skin), the perimeter of deformed sections. Another interesting application is to use it on a vector field with Plugin(CutPlane), in order to compute fluxes across arbitrary cross-sections. - Added "connectPoints" option to Plugin(CutParametric) so that we can feed its output to Plugin(Integrate) - Added Normals and Tangents options to visualize the orientation of elements in post-processing views - Added "swapOrientation" in Plugin(Transform) to change the orientation of the elements (in place) (+ moved the transformation routines from the view class into the plugin) - fixed #defines in some of the plugin header files --- Plugin/Integrate.cpp | 197 +++++++++++++++ Plugin/Integrate.h | 42 ++++ Plugin/ShapeFunctions.h | 524 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 763 insertions(+) create mode 100644 Plugin/Integrate.cpp create mode 100644 Plugin/Integrate.h create mode 100644 Plugin/ShapeFunctions.h diff --git a/Plugin/Integrate.cpp b/Plugin/Integrate.cpp new file mode 100644 index 0000000000..f9f8112dd4 --- /dev/null +++ b/Plugin/Integrate.cpp @@ -0,0 +1,197 @@ +// $Id: Integrate.cpp,v 1.1 2004-11-13 23:57:28 geuzaine Exp $ +// +// Copyright (C) 1997-2004 C. Geuzaine, J.-F. Remacle +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems to <gmsh@geuz.org>. + +#include "Plugin.h" +#include "Integrate.h" +#include "List.h" +#include "Views.h" +#include "Context.h" +#include "Numeric.h" +#include "ShapeFunctions.h" + +extern Context_T CTX; + +StringXNumber IntegrateOptions_Number[] = { + {GMSH_FULLRC, "iView", NULL, -1.} +}; + +extern "C" +{ + GMSH_Plugin *GMSH_RegisterIntegratePlugin() + { + return new GMSH_IntegratePlugin(); + } +} + +GMSH_IntegratePlugin::GMSH_IntegratePlugin() +{ + ; +} + +void GMSH_IntegratePlugin::getName(char *name) const +{ + strcpy(name, "Integrate"); +} + +void GMSH_IntegratePlugin::getInfos(char *author, char *copyright, + char *help_text) const +{ + strcpy(author, "C. Geuzaine (geuz@geuz.org)"); + strcpy(copyright, "DGR (www.multiphysics.com)"); + strcpy(help_text, + "Plugin(Integrate) integrates scalar fields over\n" + "all the elements in the view `iView', as well as\n" + "the circulation/flux of vector fields over\n" + "line/surface elements. If `iView' < 0, the plugin\n" + "is run on the current view.\n" + "\n" + "Plugin(Integrate) creates one new view.\n"); +} + +int GMSH_IntegratePlugin::getNbOptions() const +{ + return sizeof(IntegrateOptions_Number) / sizeof(StringXNumber); +} + +StringXNumber *GMSH_IntegratePlugin::getOption(int iopt) +{ + return &IntegrateOptions_Number[iopt]; +} + +void GMSH_IntegratePlugin::catchErrorMessage(char *errorMessage) const +{ + strcpy(errorMessage, "Integrate failed..."); +} + +static double integrate(int nbList, List_T *list, int dim, + int nbNod, int nbComp, int step) +{ + if(!nbList) return 0.; + + double res = 0.; + int nb = List_Nbr(list) / nbList; + for(int i = 0; i < List_Nbr(list); i += nb) { + double *x = (double *)List_Pointer_Fast(list, i); + double *y = (double *)List_Pointer_Fast(list, i + nbNod); + double *z = (double *)List_Pointer_Fast(list, i + 2 * nbNod); + double *v = (double *)List_Pointer_Fast(list, i + 3 * nbNod + + nbNod * nbComp * step); + if(dim == 0){ + if(nbNod == 1){ + point p(x, y, z); + if(nbComp == 1) res += p.integrate(v); + } + } + else if(dim == 1){ + if(nbNod == 2){ + line l(x, y, z); + if(nbComp == 1) res += l.integrate(v); + else if(nbComp == 3) res += l.integrateCirculation(v); + } + } + else if(dim == 2){ + if(nbNod == 3){ + triangle t(x, y, z); + if(nbComp == 1) res += t.integrate(v); + else if(nbComp == 3) res += t.integrateFlux(v); + } + else if(nbNod == 4){ + quadrangle q(x, y, z); + if(nbComp == 1) res += q.integrate(v); + else if(nbComp == 3) res += q.integrateFlux(v); + } + } + else if(dim == 3){ + if(nbNod == 4){ + tetrahedron t(x, y, z); + if(nbComp == 1) res += t.integrate(v); + } + else if(nbNod == 8){ + hexahedron h(x, y, z); + if(nbComp == 1) res += h.integrate(v); + } + else if(nbNod == 6){ + prism p(x, y, z); + if(nbComp == 1) res += p.integrate(v); + } + else if(nbNod == 5){ + pyramid p(x, y, z); + if(nbComp == 1) res += p.integrate(v); + } + } + } + return res; +} + +Post_View *GMSH_IntegratePlugin::execute(Post_View * v) +{ + int iView = (int)IntegrateOptions_Number[0].def; + + if(iView < 0) + iView = v ? v->Index : 0; + + if(!List_Pointer_Test(CTX.post.list, iView)) { + Msg(GERROR, "View[%d] does not exist", iView); + return v; + } + + Post_View *v2 = BeginView(1); + Post_View *v1 = (Post_View*)List_Pointer(CTX.post.list, iView); + + double x = (v1->BBox[0]+v1->BBox[1])/2.; + double y = (v1->BBox[2]+v1->BBox[3])/2.; + double z = (v1->BBox[4]+v1->BBox[5])/2.; + List_Add(v2->SP, &x); + List_Add(v2->SP, &y); + List_Add(v2->SP, &z); + for(int ts = 0; ts < v1->NbTimeStep; ts++){ + double val = 0; + // scalar fields + val += integrate(v1->NbSP, v1->SP, 0, 1, 1, ts); + val += integrate(v1->NbSL, v1->SL, 1, 2, 1, ts); + val += integrate(v1->NbST, v1->ST, 2, 3, 1, ts); + val += integrate(v1->NbSQ, v1->SQ, 2, 4, 1, ts); + val += integrate(v1->NbSS, v1->SS, 3, 4, 1, ts); + val += integrate(v1->NbSH, v1->SH, 3, 8, 1, ts); + val += integrate(v1->NbSI, v1->SI, 3, 6, 1, ts); + val += integrate(v1->NbSY, v1->SY, 3, 5, 1, ts); + // circulations + val += integrate(v1->NbVL, v1->VL, 1, 2, 3, ts); + // fluxes + val += integrate(v1->NbVT, v1->VT, 2, 3, 3, ts); + val += integrate(v1->NbVQ, v1->VQ, 2, 4, 3, ts); + Msg(INFO, "Step %d: integral = %.16g", ts, val); + List_Add(v2->SP, &val); + } + v2->NbSP = 1; + v2->IntervalsType = DRAW_POST_NUMERIC; + + // copy time data + for(int i = 0; i < List_Nbr(v1->Time); i++) + List_Add(v2->Time, List_Pointer(v1->Time, i)); + // finalize + char name[1024], filename[1024]; + sprintf(name, "%s_Integrate", v1->Name); + sprintf(filename, "%s_Integrate.pos", v1->Name); + EndView(v2, 1, filename, name); + + return v2; +} diff --git a/Plugin/Integrate.h b/Plugin/Integrate.h new file mode 100644 index 0000000000..09fa2cb18b --- /dev/null +++ b/Plugin/Integrate.h @@ -0,0 +1,42 @@ +#ifndef _INTEGRATE_H_ +#define _INTEGRATE_H_ + +// Copyright (C) 1997-2004 C. Geuzaine, J.-F. Remacle +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems to <gmsh@geuz.org>. + +#include "Plugin.h" + +extern "C" +{ + GMSH_Plugin *GMSH_RegisterIntegratePlugin(); +} + +class GMSH_IntegratePlugin : public GMSH_Post_Plugin +{ + public: + GMSH_IntegratePlugin(); + void getName(char *name) const; + void getInfos(char *author, char *copyright, char *help_text) const; + void catchErrorMessage(char *errorMessage) const; + int getNbOptions() const; + StringXNumber* getOption(int iopt); + Post_View *execute(Post_View *); +}; + +#endif diff --git a/Plugin/ShapeFunctions.h b/Plugin/ShapeFunctions.h new file mode 100644 index 0000000000..c4ebe19e8e --- /dev/null +++ b/Plugin/ShapeFunctions.h @@ -0,0 +1,524 @@ +#ifndef _SHAPE_FUNCTIONS_H_ +#define _SHAPE_FUNCTIONS_H_ + +// Copyright (C) 1997-2004 C. Geuzaine, J.-F. Remacle +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems to <gmsh@geuz.org>. + +#include "Numeric.h" + +class element{ +protected: + double *_x, *_y, *_z; +public: + element(double *x, double *y, double *z) : _x(x), _y(y), _z(z) {} + virtual ~element(){} + virtual int getDimension() = 0; + virtual int getNumNodes() = 0; + virtual int getNumGaussPoints() = 0; + virtual void getGaussPoint(int num, double &u, double &v, double &w, double &weight) = 0; + virtual void getShapeFunction(int num, double u, double v, double w, double &s) = 0; + virtual void getGradShapeFunction(int num, double u, double v, double w, double s[3]) = 0; + double getJacobian(double u, double v, double w, double jac[3][3]) + { + jac[0][0] = jac[0][1] = jac[0][2] = 0.; + jac[1][0] = jac[1][1] = jac[1][2] = 0.; + jac[2][0] = jac[2][1] = jac[2][2] = 0.; + double s[3]; + switch(getDimension()){ + case 3 : + for(int i = 0; i < getNumNodes(); i++) { + getGradShapeFunction(i, u, v, w, s); + jac[0][0] += _x[i] * s[0]; jac[0][1] += _y[i] * s[0]; jac[0][2] += _z[i] * s[0]; + jac[1][0] += _x[i] * s[1]; jac[1][1] += _y[i] * s[1]; jac[1][2] += _z[i] * s[1]; + jac[2][0] += _x[i] * s[2]; jac[2][1] += _y[i] * s[2]; jac[2][2] += _z[i] * s[2]; + } + return + jac[0][0] * jac[1][1] * jac[2][2] + jac[0][2] * jac[1][0] * jac[2][1] + + jac[0][1] * jac[1][2] * jac[2][0] - jac[0][2] * jac[1][1] * jac[2][0] - + jac[0][0] * jac[1][2] * jac[2][1] - jac[0][1] * jac[1][0] * jac[2][2]; + case 2 : + for(int i = 0; i < getNumNodes(); i++) { + getGradShapeFunction(i, u, v, w, s); + jac[0][0] += _x[i] * s[0]; jac[0][1] += _y[i] * s[0]; jac[0][2] += _z[i] * s[0]; + jac[1][0] += _x[i] * s[1]; jac[1][1] += _y[i] * s[1]; jac[1][2] += _z[i] * s[1]; + } + return sqrt(DSQR(jac[0][0] * jac[1][1] - jac[0][1] * jac[1][0]) + + DSQR(jac[0][2] * jac[1][0] - jac[0][0] * jac[1][2]) + + DSQR(jac[0][1] * jac[1][2] - jac[0][2] * jac[1][1])); + case 1: + for(int i = 0; i < getNumNodes(); i++) { + getGradShapeFunction(i, u, v, w, s); + jac[0][0] += _x[i] * s[0]; jac[0][1] += _y[i] * s[0]; jac[0][2] += _z[i] * s[0]; + } + return sqrt(DSQR(jac[0][0])+DSQR(jac[0][1])+DSQR(jac[0][2])); + default: + return 1.; + } + } + double interpolate(double val[], double u, double v, double w) + { + double sum = 0; + for(int i = 0; i < getNumNodes(); i++){ + double s; + getShapeFunction(i, u, v, w, s); + sum += val[i] * s; + } + return sum; + } + double integrate(double val[]) + { + double sum = 0; + for(int i = 0; i < getNumGaussPoints(); i++){ + double u, v, w, weight, jac[3][3]; + getGaussPoint(i, u, v, w, weight); + double det = getJacobian(u, v, w, jac); + double d = interpolate(val, u, v, w); + sum += d * weight * det; + } + return sum; + } +}; + +class point : public element{ +public: + point(double *x, double *y, double *z) : element(x, y, z) {} + inline int getDimension(){ return 0; } + inline int getNumNodes(){ return 1; } + inline int getNumGaussPoints(){ return 1; } + void getGaussPoint(int num, double &u, double &v, double &w, double &weight) + { + u = v = w = 0.; + weight = 1.; + } + void getShapeFunction(int num, double u, double v, double w, double &s) + { + switch(num) { + case 0 : s = 1.; break; + default : s = 0.; break; + } + } + void getGradShapeFunction(int num, double u, double v, double w, double s[3]) + { + s[0] = s[1] = s[2] = 0.; + } +}; + +class line : public element{ +public: + line(double *x, double *y, double *z) : element(x, y, z) {} + inline int getDimension(){ return 1; } + inline int getNumNodes(){ return 2; } + inline int getNumGaussPoints(){ return 1; } + void getGaussPoint(int num, double &u, double &v, double &w, double &weight) + { + if(num < 0 || num > 0) return; + u = v = w = 0.; + weight = 2.; + } + void getShapeFunction(int num, double u, double v, double w, double &s) + { + switch(num) { + case 0 : s = 0.5 * (1.-u); break; + case 1 : s = 0.5 * (1.+u); break; + default : s = 0.; break; + } + } + void getGradShapeFunction(int num, double u, double v, double w, double s[3]) + { + switch(num) { + case 0 : s[0] = -0.5; s[1] = 0.; s[2] = 0.; break; + case 1 : s[0] = 0.5; s[1] = 0.; s[2] = 0.; break; + default : s[0] = s[1] = s[2] = 0.; break; + } + } + double integrateCirculation(double val[]) + { + double t[3] = {_x[1]-_x[0], _y[1]-_y[0], _z[1]-_z[0]}; + norme(t); + double v[3]; + for(int i = 0; i < 3; i++){ + double tmp[2]; + tmp[0] = val[i]; + tmp[1] = val[3+i]; + v[i] = integrate(tmp); + } + double d; + prosca(t, v, &d); + return d; + } +}; + +class triangle : public element{ +public: + triangle(double *x, double *y, double *z) : element(x, y, z) {} + inline int getDimension(){ return 2; } + inline int getNumNodes(){ return 3; } + inline int getNumGaussPoints(){ return 3; } + void getGaussPoint(int num, double &u, double &v, double &w, double &weight) + { + static double u3[3] = {0.16666666666666,0.66666666666666,0.16666666666666}; + static double v3[3] = {0.16666666666666,0.16666666666666,0.66666666666666}; + static double p3[3] = {0.16666666666666,0.16666666666666,0.16666666666666}; + if(num < 0 || num > 2) return; + u = u3[num]; + v = v3[num]; + w = 0.; + weight = p3[num]; + } + void getShapeFunction(int num, double u, double v, double w, double &s) + { + switch(num){ + case 0 : s = 1.-u-v; break; + case 1 : s = u ; break; + case 2 : s = v; break; + default : s = 0.; break; + } + } + void getGradShapeFunction(int num, double u, double v, double w, double s[3]) + { + switch(num) { + case 0 : s[0] = -1.; s[1] = -1.; s[2] = 0.; break; + case 1 : s[0] = 1.; s[1] = 0.; s[2] = 0.; break; + case 2 : s[0] = 0.; s[1] = 1.; s[2] = 0.; break; + default : s[0] = s[1] = s[2] = 0.; break; + } + } + double integrateFlux(double val[]) + { + double t1[3] = {_x[1]-_x[0], _y[1]-_y[0], _z[1]-_z[0]}; + double t2[3] = {_x[2]-_x[0], _y[2]-_y[0], _z[2]-_z[0]}; + double n[3]; + prodve(t1, t2, n); + norme(n); + double v[3]; + for(int i = 0; i < 3; i++){ + double tmp[3]; + tmp[0] = val[i]; + tmp[1] = val[3+i]; + tmp[2] = val[6+i]; + v[i] = integrate(tmp); + } + double d; + prosca(n, v, &d); + return d; + } +}; + +class quadrangle : public element{ +public: + quadrangle(double *x, double *y, double *z) : element(x, y, z) {} + inline int getDimension(){ return 2; } + inline int getNumNodes(){ return 4; } + inline int getNumGaussPoints(){ return 4; } + void getGaussPoint(int num, double &u, double &v, double &w, double &weight) + { + static double u4[4] = {0.577350269189,-0.577350269189,0.577350269189,-0.577350269189}; + static double v4[4] = {0.577350269189,0.577350269189,-0.577350269189,-0.577350269189}; + static double p4[4] = {1.,1.,1.,1.}; + if(num < 0 || num > 3) return; + u = u4[num]; + v = v4[num]; + w = 0.; + weight = p4[num]; + } + void getShapeFunction(int num, double u, double v, double w, double &s) + { + switch(num) { + case 0 : s = 0.25 * (1.-u) * (1.-v); break; + case 1 : s = 0.25 * (1.+u) * (1.-v); break; + case 2 : s = 0.25 * (1.+u) * (1.+v); break; + case 3 : s = 0.25 * (1.-u) * (1.+v); break; + default : s = 0.; break; + } + } + void getGradShapeFunction(int num, double u, double v, double w, double s[3]) + { + switch(num) { + case 0 : s[0] = -0.25 * (1.-v); s[1] = -0.25 * (1.-u); s[2] = 0.; break; + case 1 : s[0] = 0.25 * (1.-v); s[1] = -0.25 * (1.+u); s[2] = 0.; break; + case 2 : s[0] = 0.25 * (1.+v); s[1] = 0.25 * (1.+u); s[2] = 0.; break; + case 3 : s[0] = -0.25 * (1.+v); s[1] = 0.25 * (1.-u); s[2] = 0.; break; + default : s[0] = s[1] = s[2] = 0.; break; + } + } + double integrateFlux(double val[]) + { + double t1[3] = {_x[1]-_x[0], _y[1]-_y[0], _z[1]-_z[0]}; + double t2[3] = {_x[2]-_x[0], _y[2]-_y[0], _z[2]-_z[0]}; + double n[3]; + prodve(t1, t2, n); + norme(n); + double v[3]; + for(int i = 0; i < 3; i++){ + double tmp[4]; + tmp[0] = val[i]; + tmp[1] = val[3+i]; + tmp[2] = val[6+i]; + tmp[3] = val[9+i]; + v[i] = integrate(tmp); + } + double d; + prosca(n, v, &d); + return d; + } +}; + +class tetrahedron : public element{ +public: + tetrahedron(double *x, double *y, double *z) : element(x, y, z) {} + inline int getDimension(){ return 3; } + inline int getNumNodes(){ return 4; } + inline int getNumGaussPoints(){ return 4; } + void getGaussPoint(int num, double &u, double &v, double &w, double &weight) + { + static double u4[4] = {0.138196601125,0.138196601125,0.138196601125,0.585410196625}; + static double v4[4] = {0.138196601125,0.138196601125,0.585410196625,0.138196601125}; + static double w4[4] = {0.138196601125,0.585410196625,0.138196601125,0.138196601125}; + static double p4[4] = {0.0416666666667,0.0416666666667,0.0416666666667,0.0416666666667}; + if(num < 0 || num > 3) return; + u = u4[num]; + v = v4[num]; + w = w4[num]; + weight = p4[num]; + } + void getShapeFunction(int num, double u, double v, double w, double &s) + { + switch(num) { + case 0 : s = 1.-u-v-w; break; + case 1 : s = u ; break; + case 2 : s = v ; break; + case 3 : s = w; break; + default : s = 0.; break; + } + } + void getGradShapeFunction(int num, double u, double v, double w, double s[3]) + { + switch(num) { + case 0 : s[0] = -1.; s[1] = -1.; s[2] = -1.; break; + case 1 : s[0] = 1.; s[1] = 0.; s[2] = 0.; break; + case 2 : s[0] = 0.; s[1] = 1.; s[2] = 0.; break; + case 3 : s[0] = 0.; s[1] = 0.; s[2] = 1.; break; + default : s[0] = s[1] = s[2] = 0.; break; + } + } +}; + +class hexahedron : public element{ +public: + hexahedron(double *x, double *y, double *z) : element(x, y, z) {} + inline int getDimension(){ return 3; } + inline int getNumNodes(){ return 8; } + inline int getNumGaussPoints(){ return 6; } + void getGaussPoint(int num, double &u, double &v, double &w, double &weight) + { + static double u6[6] = { 0.40824826, 0.40824826, -0.40824826, + -0.40824826, -0.81649658, 0.81649658}; + static double v6[6] = { 0.70710678, -0.70710678, 0.70710678, + -0.70710678, 0., 0.}; + static double w6[6] = {-0.57735027, -0.57735027, 0.57735027, + 0.57735027, -0.57735027, 0.57735027}; + static double p6[6] = { 1.3333333333, 1.3333333333, 1.3333333333, + 1.3333333333, 1.3333333333, 1.3333333333}; + if(num < 0 || num > 5) return; + u = u6[num]; + v = v6[num]; + w = w6[num]; + weight = p6[num]; + } + void getShapeFunction(int num, double u, double v, double w, double &s) + { + switch(num) { + case 0 : s = (1.-u) * (1.-v) * (1.-w) * 0.125; break; + case 1 : s = (1.+u) * (1.-v) * (1.-w) * 0.125; break; + case 2 : s = (1.+u) * (1.+v) * (1.-w) * 0.125; break; + case 3 : s = (1.-u) * (1.+v) * (1.-w) * 0.125; break; + case 4 : s = (1.-u) * (1.-v) * (1.+w) * 0.125; break; + case 5 : s = (1.+u) * (1.-v) * (1.+w) * 0.125; break; + case 6 : s = (1.+u) * (1.+v) * (1.+w) * 0.125; break; + case 7 : s = (1.-u) * (1.+v) * (1.+w) * 0.125; break; + default : s = 0.; break; + } + } + void getGradShapeFunction(int num, double u, double v, double w, double s[3]) + { + switch(num) { + case 0 : s[0] = -0.125 * (1.-v) * (1.-w); + s[1] = -0.125 * (1.-u) * (1.-w); + s[2] = -0.125 * (1.-u) * (1.-v); break; + case 1 : s[0] = 0.125 * (1.-v) * (1.-w); + s[1] = -0.125 * (1.+u) * (1.-w); + s[2] = -0.125 * (1.+u) * (1.-v); break; + case 2 : s[0] = 0.125 * (1.+v) * (1.-w); + s[1] = 0.125 * (1.+u) * (1.-w); + s[2] = -0.125 * (1.+u) * (1.+v); break; + case 3 : s[0] = -0.125 * (1.+v) * (1.-w); + s[1] = 0.125 * (1.-u) * (1.-w); + s[2] = -0.125 * (1.-u) * (1.+v); break; + case 4 : s[0] = -0.125 * (1.-v) * (1.+w); + s[1] = -0.125 * (1.-u) * (1.+w); + s[2] = 0.125 * (1.-u) * (1.-v); break; + case 5 : s[0] = 0.125 * (1.-v) * (1.+w); + s[1] = -0.125 * (1.+u) * (1.+w); + s[2] = 0.125 * (1.+u) * (1.-v); break; + case 6 : s[0] = 0.125 * (1.+v) * (1.+w); + s[1] = 0.125 * (1.+u) * (1.+w); + s[2] = 0.125 * (1.+u) * (1.+v); break; + case 7 : s[0] = -0.125 * (1.+v) * (1.+w); + s[1] = 0.125 * (1.-u) * (1.+w); + s[2] = 0.125 * (1.-u) * (1.+v); break; + default : s[0] = s[1] = s[2] = 0.; break; + } + } +}; + +class prism : public element{ +public: + prism(double *x, double *y, double *z) : element(x, y, z) {}; + inline int getDimension(){ return 3; } + inline int getNumNodes(){ return 6; } + inline int getNumGaussPoints(){ return 6; } + void getGaussPoint(int num, double &u, double &v, double &w, double &weight) + { + static double u6[6] = {0.166666666666666, 0.333333333333333, 0.166666666666666, + 0.166666666666666, 0.333333333333333, 0.166666666666666}; + static double v6[6] = {0.166666666666666, 0.166666666666666, 0.333333333333333, + 0.166666666666666, 0.166666666666666, 0.333333333333333}; + static double w6[6] = {-0.577350269189, -0.577350269189, -0.577350269189, + 0.577350269189, 0.577350269189, 0.577350269189}; + static double p6[6] = {0.166666666666666,0.166666666666666,0.166666666666666, + 0.166666666666666,0.166666666666666,0.166666666666666,}; + if(num < 0 || num > 5) return; + u = u6[num]; + v = v6[num]; + w = w6[num]; + weight = p6[num]; + } + void getShapeFunction(int num, double u, double v, double w, double &s) + { + switch(num) { + case 0 : s = (1.-u-v) * (1.-w) * 0.5; break; + case 1 : s = u * (1.-w) * 0.5; break; + case 2 : s = v * (1.-w) * 0.5; break; + case 3 : s = (1.-u-v) * (1.+w) * 0.5; break; + case 4 : s = u * (1.+w) * 0.5; break; + case 5 : s = v * (1.+w) * 0.5; break; + default : s = 0.; break; + } + } + void getGradShapeFunction(int num, double u, double v, double w, double s[3]) + { + switch(num) { + case 0 : s[0] = -0.5 * (1.-w) ; + s[1] = -0.5 * (1.-w) ; + s[2] = -0.5 * (1.-u-v) ; break ; + case 1 : s[0] = 0.5 * (1.-w) ; + s[1] = 0. ; + s[2] = -0.5 * u ; break ; + case 2 : s[0] = 0. ; + s[1] = 0.5 * (1.-w) ; + s[2] = -0.5 * v ; break ; + case 3 : s[0] = -0.5 * (1.+w) ; + s[1] = -0.5 * (1.+w) ; + s[2] = 0.5 * (1.-u-v) ; break ; + case 4 : s[0] = 0.5 * (1.+w) ; + s[1] = 0. ; + s[2] = 0.5 * u ; break ; + case 5 : s[0] = 0. ; + s[1] = 0.5 * (1.+w) ; + s[2] = 0.5 * v ; break ; + default : s[0] = s[1] = s[2] = 0.; break; + } + } +}; + +class pyramid : public element{ +public: + pyramid(double *x, double *y, double *z) : element(x, y, z) {} + inline int getDimension(){ return 3; } + inline int getNumNodes(){ return 5; } + inline int getNumGaussPoints(){ return 8; } + void getGaussPoint(int num, double &u, double &v, double &w, double &weight) + { + static double u8[8] = {0.3595161057791018,0.09633205020967324, + 0.3595161057791018,0.09633205020967324, + 0.6920507403468987,0.1854344369976602, + 0.6920507403468987,0.1854344369976602}; + static double v8[8] = {0.3595161057791018,0.3595161057791018, + 0.09633205020967324,0.09633205020967324, + 0.6920507403468987,0.6920507403468987, + 0.1854344369976602,0.1854344369976602}; + static double w8[8] = {0.544151844011225,0.544151844011225, + 0.544151844011225,0.544151844011225, + 0.122514822655441,0.122514822655441, + 0.122514822655441,0.122514822655441}; + static double p8[8] = {0.02519647051995625,0.02519647051995625, + 0.02519647051995625,0.02519647051995625, + 0.058136862813377,0.058136862813377, + 0.058136862813377,0.058136862813377}; + if(num < 0 || num > 7) return; + u = u8[num]; + v = v8[num]; + w = w8[num]; + weight = p8[num]; + } + void getShapeFunction(int num, double u, double v, double w, double &s) + { + double r; + if(w != 1. && num != 4) r = u*v*w / (1.-w); + else r = 0.; + switch(num) { + case 0 : s = 0.25 * ((1.-u) * (1.-v) - w + r); break; + case 1 : s = 0.25 * ((1.+u) * (1.-v) - w - r); break; + case 2 : s = 0.25 * ((1.+u) * (1.+v) - w + r); break; + case 3 : s = 0.25 * ((1.-u) * (1.+v) - w - r); break; + case 4 : s = w; break; + default : s = 0.; break; + } + } + void getGradShapeFunction(int num, double u, double v, double w, double s[3]) + { + if(w == 1. && num != 4) { + s[0] = 0.25; + s[1] = 0.25; + s[2] = -0.25; + } + else{ + switch(num) { + case 0 : s[0] = 0.25 * ( -(1.-v) + v*w/(1.-w) ) ; + s[1] = 0.25 * ( -(1.-u) + u*w/(1.-w) ) ; + s[2] = 0.25 * ( -1. + u*v/DSQR(1.-w) ) ; break ; + case 1 : s[0] = 0.25 * ( (1.-v) + v*w/(1.-w) ) ; + s[1] = 0.25 * ( -(1.+u) + u*w/(1.-w) ) ; + s[2] = 0.25 * ( -1. + u*v/DSQR(1.-w) ) ; break ; + case 2 : s[0] = 0.25 * ( (1.+v) + v*w/(1.-w) ) ; + s[1] = 0.25 * ( (1.+u) + u*w/(1.-w) ) ; + s[2] = 0.25 * ( -1. + u*v/DSQR(1.-w) ) ; break ; + case 3 : s[0] = 0.25 * ( -(1.+v) + v*w/(1.-w) ) ; + s[1] = 0.25 * ( (1.-u) + u*w/(1.-w) ) ; + s[2] = 0.25 * ( -1. + u*v/DSQR(1.-w) ) ; break ; + case 4 : s[0] = 0. ; + s[1] = 0. ; + s[2] = 1. ; break ; + default : s[0] = s[1] = s[2] = 0.; break; + } + } + } +}; + +#endif -- GitLab