From c36677f3feb0b6f2fce150f87a137e7219f9b444 Mon Sep 17 00:00:00 2001 From: Jean-Francois Remacle <jean-francois.remacle@uclouvain.be> Date: Fri, 26 Nov 2004 10:31:54 +0000 Subject: [PATCH] *** empty log message *** --- Plugin/Gradient.cpp | 336 +++++++++++++++++++++++++++++++++++++++++ Plugin/Gradient.h | 45 ++++++ Plugin/Integrate.cpp | 347 +++++++++++++++++++++++-------------------- Plugin/Lambda2.cpp | 212 ++++++++++++++++++++++++++ Plugin/Lambda2.h | 52 +++++++ 5 files changed, 835 insertions(+), 157 deletions(-) create mode 100644 Plugin/Gradient.cpp create mode 100644 Plugin/Gradient.h create mode 100644 Plugin/Lambda2.cpp create mode 100644 Plugin/Lambda2.h diff --git a/Plugin/Gradient.cpp b/Plugin/Gradient.cpp new file mode 100644 index 0000000000..75655036dd --- /dev/null +++ b/Plugin/Gradient.cpp @@ -0,0 +1,336 @@ +// $Id: Gradient.cpp,v 1.1 2004-11-26 10:31:54 remacle 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 "Gradient.h" +#include "List.h" +#include "Views.h" +#include "Context.h" +#include "Numeric.h" +#include <algorithm> +#include <functional> +#include <math.h> +#include <stdio.h> + +#if defined(HAVE_MATH_EVAL) +#include "matheval.h" +#endif + +extern Context_T CTX; + +StringXNumber GradientOptions_Number[] = { + {GMSH_FULLRC, "iView", NULL, -1.} +}; + +extern "C" +{ + GMSH_Plugin *GMSH_RegisterGradientPlugin() + { + return new GMSH_GradientPlugin(); + } +} + +int GMSH_GradientPlugin::getNbOptionsStr() const +{ + return 0; +} + +int GMSH_GradientPlugin::getNbOptions() const +{ + return sizeof(GradientOptions_Number) / sizeof(StringXNumber); +} + +StringXNumber *GMSH_GradientPlugin::getOption(int iopt) +{ + return &GradientOptions_Number[iopt]; +} + +StringXString *GMSH_GradientPlugin::getOptionStr(int iopt) +{ + throw; +} + + + +GMSH_GradientPlugin::GMSH_GradientPlugin() +{ + ; +} + +void GMSH_GradientPlugin::getName(char *name) const +{ + strcpy(name, "Gradient"); +} + +void GMSH_GradientPlugin::getInfos(char *author, char *copyright, + char *help_text) const +{ + strcpy(author, "E. Marchandise"); + strcpy(copyright, "DGR (www.multiphysics.com)"); + strcpy(help_text, + "Plugin(Gradient) computes\n" + "the eigenvalues Lambda (1,2,3)\n" + "of the tensor S_ik S_kj + Om_ik Om_kj,\n" + "where S_ij = 0.5 (ui,j + uj,i)) and\n" + "Om_ij = 0.5 (ui,j - uj,i) are respectively\n" + "the symmetric and antisymmetric parts\n" + "of the velocity gradient tensor.\n" + "Vortices are well-represented by regions\n" + "where Lambda (2) is negative.\n" + "If `iView' < 0, the plugin is run\n" + "on the current view.\n" + "\n" + "Plugin(Lambda2) is executed in-place.\n"); +} + + +void GMSH_GradientPlugin::catchErrorMessage(char *errorMessage) const +{ + strcpy(errorMessage, "Gradient failed..."); +} + +//----------------------------------------------------------------------------- +static void computeGradient( List_T *inList, int inNb, + List_T *outListVector, int *outNbVector, + int nbTime, int nbNod, int nbComp) +{ + + if(!inNb) + return; + + int outNbComp, *outNb; + List_T *outList; + + outNbComp = 1; + outNb = outNbVector; + outList = outListVector; + + int MAX_NOD = 4; + int MAX_COMP= 3; + + int nb = List_Nbr(inList) / inNb; + + //on parcourt les elements + //------------------------ + //------------------------ + for(int i = 0; i < List_Nbr(inList); i += nb) { + + double *yy = (double *)List_Pointer_Fast(inList, i + nbNod); + + if (yy[0] > 0) + { + for(int j = 0; j < 3 * nbNod; j++) + List_Add(outList, List_Pointer_Fast(inList, i + j)); + + for(int t = 0; t < nbTime; t++){ + + //on lit vecteurs positions et vitesses + //------------------------------------- + double *x = (double *)List_Pointer_Fast(inList, i); + double *y = (double *)List_Pointer_Fast(inList, i + nbNod); + double *z = (double *)List_Pointer_Fast(inList, i + 2 * nbNod); + double val[MAX_COMP][MAX_NOD]; + for(int k = 0; k < nbNod; k++){ + double *v = (double *)List_Pointer_Fast(inList, i + 3 * nbNod + nbNod * nbComp * t + nbComp * k); + for(int l = 0; l < nbComp; l++){ + val[l][k] = v[l]; + } + } + + + //on calcule le gradient des fonctions de forme + //--------------------------------------------- + double GradPhi_x[4][3]; + double GradPhi_ksi[4][3]; + double dx_dksi[3][3]; + double dksi_dx[3][3]; + double det; + + //triangles + //+++++++++ + if (nbNod == 3){ + double a[3], b[3], cross[3]; + a[0]= x[1]-x[0]; a[1]= y[1]-y[0]; a[2]= z[1]-z[0]; + b[0]= x[2]-x[0]; b[1]= y[2]-y[0]; b[2]= z[2]-z[0]; + prodve(a, b, cross); + dx_dksi[0][0] = x[1] - x[0]; dx_dksi[0][1] = x[2]-x[0]; dx_dksi[0][2] = cross[0]; + dx_dksi[1][0] = y[1] - y[0]; dx_dksi[1][1] = y[2]-y[0]; dx_dksi[1][2] = cross[1]; + dx_dksi[2][0] = z[1] - z[0]; dx_dksi[2][1] = z[2]-z[0]; dx_dksi[2][2] = cross[2]; + inv3x3(dx_dksi, dksi_dx, &det); + + GradPhi_ksi[0][0]= -1; GradPhi_ksi[0][1]= -1; GradPhi_ksi[0][2]= 0; + GradPhi_ksi[1][0]= 1; GradPhi_ksi[1][1]= 0; GradPhi_ksi[1][2]= 0; + GradPhi_ksi[2][0]= 0; GradPhi_ksi[2][1]= 1; GradPhi_ksi[2][2]= 0; + } + + //tetraedre + //++++++++++ + if (nbNod == 4){ + dx_dksi[0][0] = x[1] - x[0]; dx_dksi[0][1] = x[2]-x[0]; dx_dksi[0][2] = x[3]-x[0]; + dx_dksi[1][0] = y[1] - y[0]; dx_dksi[1][1] = y[2]-y[0]; dx_dksi[1][2] = y[3]-y[0]; + dx_dksi[2][0] = z[1] - z[0]; dx_dksi[2][1] = z[2]-z[0]; dx_dksi[2][2] = z[3]-z[0]; + inv3x3(dx_dksi, dksi_dx, &det); + GradPhi_ksi[0][0]= -1; GradPhi_ksi[0][1]= -1; GradPhi_ksi[0][2]= -1; + GradPhi_ksi[1][0]= 1; GradPhi_ksi[1][1]= 0; GradPhi_ksi[1][2]= 0; + GradPhi_ksi[2][0]= 0; GradPhi_ksi[2][1]= 1; GradPhi_ksi[2][2]= 0; + GradPhi_ksi[3][0]= 0; GradPhi_ksi[3][1]= 0; GradPhi_ksi[3][2]= 1; + } + + for(int k = 0; k < nbNod ; k++){ + for(int l = 0; l < 3; l++){ + GradPhi_x[k][l] = 0.0; + for(int m = 0; m < 3; m++){ + GradPhi_x[k][l] += GradPhi_ksi[k][m] * dksi_dx[l][m]; + } + } + } + + //on calcule le gradient des vitesses + //---------------------------------- + + //par noeud on a max 9 composantes + double res, grad[3][3], sym[3][3], asym[3][3]; +// for(int l = outNbComp; l < 9; l++) +// d[l] = 0.0; + for(int k = 0; k < nbComp; k++){ + for(int l = 0; l < 3; l++){ + grad[k][l] = 0.0; + for(int m = 0; m < nbNod; m++){ + grad[k][l] += val[k][m]* GradPhi_x[m][l]; + } + } + } + + for(int k=0; k<nbComp; k++){ + for(int l=0; l<3; l++){ + sym[k][l] = 0.5*(grad[k][l]+grad[l][k]); + asym[k][l] = 0.5*(grad[k][l]-grad[l][k]); + } + } + + double a[3][3]; + for(int i=0; i<3; i++) + for(int j=0; j<3; j++){ + a[i][j] = 0.0; + for(int k=0; k<3; k++) + a[i][j] += sym[i][k]*sym[k][j] + asym[i][k]*asym[k][j]; + } + + //calcul de lambda avec tri + double lambda[3]; + eigenvalue(a, lambda); + + for(int k = 0; k < nbNod; k++){ + for(int l = 0; l < outNbComp; l++){ + res = lambda[1]; + List_Add(outList, &res); + } + } + } + (*outNb)++; + } + } +} + +//----------------------------------------------------------------------------- +Post_View *GMSH_GradientPlugin::execute(Post_View * v) +{ + + int iView = (int)GradientOptions_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); + +// points +//-------- +// computeGradient( v1->SP, v1->NbSP, v2->VP, &v2->NbVP, v1->NbTimeStep, 1, 1); +// computeGradient( v1->VP, v1->NbVP, v2->TP, &v2->NbTP, v1->NbTimeStep, 1, 3); + +// lines +//------- + // computeGradient( v1->SL, v1->NbSL, v2->VL, &v2->NbVL, v1->NbTimeStep, 2, 1); + // computeGradient( v1->VL, v1->NbVL, v2->TL, &v2->NbTL, v1->NbTimeStep, 2, 3); + + +// triangles +//------------ +// computeGradient( v1->ST, v1->NbST, v2->VT, &v2->NbVT, v1->NbTimeStep, 3, 1); +// computeGradient( v1->VT, v1->NbVT, v2->TT, &v2->NbTT, v1->NbTimeStep, 3, 3); + + +// tets +//------ +// computeGradient( v1->SS, v1->NbSS, v2->VS, &v2->NbVS, v1->NbTimeStep, 4, 1); + computeGradient( v1->VS, v1->NbVS, v2->SS, &v2->NbSS, v1->NbTimeStep, 4, 3); + + +/* +// quadrangles +//----------- +computeGradient( v1->SQ, v1->NbSQ, v2->VQ, &v2->NbVQ, v1->NbTimeStep, 4, 1); +computeGradient( v1->VQ, v1->NbVQ, v2->VQ, &v2->NbVQ, v1->NbTimeStep, 4, 3); +computeGradient( v1->TQ, v1->NbTQ, v2->VQ, &v2->NbVQ, v1->NbTimeStep, 4, 9); +// hexas +//-------- +computeGradient( v1->SH, v1->NbSH, v2->VH, &v2->NbVH, v1->NbTimeStep, 8, 1); +computeGradient( v1->VH, v1->NbVH, v2->VH, &v2->NbVH, v1->NbTimeStep, 8, 3); +computeGradient( v1->TH, v1->NbTH, v2->VH, &v2->NbVH, v1->NbTimeStep, 8, 9); +// prisms +//-------- +computeGradient( v1->SI, v1->NbSI, v2->VI, &v2->NbVI, v1->NbTimeStep, 6, 1); +computeGradient( v1->VI, v1->NbVI, v2->VI, &v2->NbVI, v1->NbTimeStep, 6, 3); +computeGradient( v1->TI, v1->NbTI, v2->VI, &v2->NbVI, v1->NbTimeStep, 6, 9); +// pyramids +//---------- +computeGradient( v1->SY, v1->NbSY, v2->VY, &v2->NbVY, v1->NbTimeStep, 5, 1); +computeGradient( v1->VY, v1->NbVY, v2->VY, &v2->NbVY, v1->NbTimeStep, 5, 3); +computeGradient( v1->TY, v1->NbTY, v2->VY, &v2->NbVY, v1->NbTimeStep, 5, 9); +*/ + + if(v2->empty()) { + RemoveViewByNumber(v2->Num); + return v1; + } + else{ + // 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_Gradient", v1->Name); + sprintf(filename, "%s_Gradient.pos", v1->Name); + EndView(v2, 1, filename, name); + return v2; + } +} + + + +//---------------------------------------------------------------------- diff --git a/Plugin/Gradient.h b/Plugin/Gradient.h new file mode 100644 index 0000000000..19ec8b91d7 --- /dev/null +++ b/Plugin/Gradient.h @@ -0,0 +1,45 @@ +#ifndef _GRADIENT_H_ +#define _GRADIENT_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" +#include "Numeric.h" + +extern "C" +{ + GMSH_Plugin *GMSH_RegisterGradientPlugin(); +} + +class GMSH_GradientPlugin : public GMSH_Post_Plugin +{ +public: + GMSH_GradientPlugin(); + void getName(char *name) const; + void getInfos(char *author, char *copyright, char *helpText) const; + void catchErrorMessage(char *errorMessage) const; + int getNbOptions() const; + StringXNumber* getOption(int iopt); + int getNbOptionsStr() const; + StringXString* getOptionStr(int iopt); + Post_View *execute(Post_View *); +}; + +#endif diff --git a/Plugin/Integrate.cpp b/Plugin/Integrate.cpp index 2784c9258d..8601528c2b 100644 --- a/Plugin/Integrate.cpp +++ b/Plugin/Integrate.cpp @@ -1,4 +1,4 @@ -// $Id: Integrate.cpp,v 1.6 2004-11-25 22:07:53 geuzaine Exp $ +// $Id: Integrate.cpp,v 1.7 2004-11-26 10:29:20 remacle Exp $ // // Copyright (C) 1997-2004 C. Geuzaine, J.-F. Remacle // @@ -30,203 +30,236 @@ extern Context_T CTX; StringXNumber IntegrateOptions_Number[] = { - {GMSH_FULLRC, "iView", NULL, -1.}, - {GMSH_FULLRC, "computeLevelsetPositive", NULL, 0.} + {GMSH_FULLRC, "iView", NULL, -1.}, + {GMSH_FULLRC, "computeLevelsetPositive", NULL, 0.} }; extern "C" { - GMSH_Plugin *GMSH_RegisterIntegratePlugin() - { - return new GMSH_IntegratePlugin(); - } + GMSH_Plugin *GMSH_RegisterIntegratePlugin() + { + return new GMSH_IntegratePlugin(); + } } GMSH_IntegratePlugin::GMSH_IntegratePlugin() { - ; + ; } void GMSH_IntegratePlugin::getName(char *name) const { - strcpy(name, "Integrate"); + strcpy(name, "Integrate"); } void GMSH_IntegratePlugin::getInfos(char *author, char *copyright, - char *help_text) const + 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\n" - "as the circulation/flux of vector fields over\n" - "line/surface elements. If `iView' < 0, the\n" - "plugin is run on the current view. If\n" - "`computeLevelsetPositive' is set, the plugin\n" - "computes the positive area (volume) of the map\n" - "(for triangle/tetrahedron maps only).\n" - "\n" - "Plugin(Integrate) creates one new view.\n"); + 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\n" + "as the circulation/flux of vector fields over\n" + "line/surface elements. If `iView' < 0, the\n" + "plugin is run on the current view. If\n" + "`computeLevelsetPositive' is set, the plugin\n" + "computes the positive area (volume) of the map\n" + "(for triangle/tetrahedron maps only).\n" + "\n" + "Plugin(Integrate) creates one new view.\n"); } int GMSH_IntegratePlugin::getNbOptions() const { - return sizeof(IntegrateOptions_Number) / sizeof(StringXNumber); + return sizeof(IntegrateOptions_Number) / sizeof(StringXNumber); } StringXNumber *GMSH_IntegratePlugin::getOption(int iopt) { - return &IntegrateOptions_Number[iopt]; + return &IntegrateOptions_Number[iopt]; } void GMSH_IntegratePlugin::catchErrorMessage(char *errorMessage) const { - strcpy(errorMessage, "Integrate failed..."); + strcpy(errorMessage, "Integrate failed..."); } static double integrate(int nbList, List_T *list, int dim, int nbNod, int nbComp, int step) { - if(!nbList) return 0.; + if(!nbList) return 0.; - const int levelsetPositive = (int)IntegrateOptions_Number[1].def; + const int levelsetPositive = (int)IntegrateOptions_Number[1].def; - double res = 0.; - double res2 = 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){ - if(!levelsetPositive) - res += t.integrate(v); - else{ - double ONES[] = { 1.0 , 1.0 , 1.0 }; - const double area = t.integrate(ONES); - const double SUM = v[0] + v[1] + v[2]; - const double SUMABS = fabs(v[0]) + fabs(v[1]) + fabs (v[2]); - if(SUMABS){ - const double XI = SUM / SUMABS; - res += area * (1 - XI) * 0.5 ; + 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(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){ - if(!levelsetPositive) - res += t.integrate(v); - else{ - double ONES[] = { 1.0 , 1.0 , 1.0, 1.0 }; - const double area = fabs(t.integrate (ONES)); - const double SUM = v[0] + v[1] + v[2] + v[3]; - const double SUMABS = fabs(v[0]) + fabs(v[1]) + fabs (v[2]) + fabs (v[3]); - if(SUMABS){ - const double XI = SUM / SUMABS; - res += area * (1 - XI) * 0.5 ; - res2 += area * (1 + XI) * 0.5 ; + 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(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); - } + else if(dim == 2){ + if(nbNod == 3){ + triangle t(x, y, z); + if(nbComp == 1){ + if(!levelsetPositive) + res += t.integrate(v); + else{ + double ONES[] = { 1.0 , 1.0 , 1.0 }; + const double area = t.integrate(ONES); + const double SUM = v[0] + v[1] + v[2]; + const double SUMABS = fabs(v[0]) + fabs(v[1]) + fabs (v[2]); + if(SUMABS){ + const double XI = SUM / SUMABS; + res += area * (1 - XI) * 0.5 ; + } + } + } + else if(nbComp == 3) res += t.integrateFlux(v); + } + else if(nbNod == 4){ + quadrangle q(x, y, z); + if(nbComp == 1) { + if(!levelsetPositive) + { + res += q.integrate(v); + } + else + { + double ONES[] = { 1.0 , 1.0 , 1.0 , 1.0}; + const double area = q.integrate(ONES); + const double SUM = v[0] + v[1] + v[2] + v[3]; + const double SUMABS = fabs(v[0]) + fabs(v[1]) + fabs (v[2]) + fabs (v[3]); + if(SUMABS){ + const double XI = SUM / SUMABS; + res += area * (1 - XI) * 0.5 ; + } + } + } + else if(nbComp == 3) res += q.integrateFlux(v); + } + } + else if(dim == 3) + { + if(nbNod == 4) + { + tetrahedron t(x, y, z); + if(nbComp == 1) + { + if ( ! levelsetPositive ) + res += t.integrate(v); + else + { + double ONES[] = { 1.0 , 1.0 , 1.0, 1.0 }; + const double area = fabs(t.integrate (ONES)); + const double SUM = v[0] + v[1] + v[2] + v[3]; + const double SUMABS = fabs(v[0]) + fabs(v[1]) + fabs (v[2]) + fabs (v[3]); + const double XI = SUM / SUMABS; + res += area * (1 - XI) * 0.5 ; + } + } + } + else if(nbNod == 8){ + hexahedron h(x, y, z); + if(nbComp == 1) + { + if ( ! levelsetPositive ) + res += h.integrate(v); + else + { + double ONES[] = { 1.0 , 1.0 , 1.0, 1.0 ,1,1,1,1}; + const double area = fabs(h.integrate (ONES)); + const double SUM = v[0] + v[1] + v[2] + v[3]+v[4] + v[5] + v[6] + v[7]; + const double SUMABS = fabs(v[0]) + fabs(v[1]) + fabs (v[2]) + fabs (v[3]) + + fabs(v[4]) + fabs(v[5]) + fabs (v[6]) + fabs (v[7]); + if (SUMABS) + { + const double XI = SUM / SUMABS; + res += area * (1 - XI) * 0.5 ; + } + } + } + } + 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); + } + } + +// printf("integration res = %22.15E\n",res); + return res; } - } - // printf("integration res = %22.15E\n",res); - 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 *v1 = *(Post_View **)List_Pointer(CTX.post.list, iView); - Post_View *v2 = BeginView(1); - - 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; + 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 *v1 = *(Post_View **)List_Pointer(CTX.post.list, iView); + Post_View *v2 = BeginView(1); + + 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/Lambda2.cpp b/Plugin/Lambda2.cpp new file mode 100644 index 0000000000..2be8210166 --- /dev/null +++ b/Plugin/Lambda2.cpp @@ -0,0 +1,212 @@ +// $Id: Lambda2.cpp,v 1.1 2004-11-26 10:31:54 remacle 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 "Lambda2.h" +#include "List.h" +#include "Views.h" +#include "Context.h" +#include "Numeric.h" +#include <algorithm> +#include <functional> +#include <math.h> +#include <stdio.h> + +#if defined(HAVE_MATH_EVAL) +#include "matheval.h" +#endif + +extern Context_T CTX; + +StringXNumber Lambda2Options_Number[] = { + {GMSH_FULLRC, "Eigenvalue", NULL, 2.}, + {GMSH_FULLRC, "iView", NULL, -1.} +}; + + +extern "C" +{ + GMSH_Plugin *GMSH_RegisterLambda2Plugin() + { + return new GMSH_Lambda2Plugin(); + } +} + + +GMSH_Lambda2Plugin::GMSH_Lambda2Plugin() +{ + ; +} + +void GMSH_Lambda2Plugin::getName(char *name) const +{ + strcpy(name, "Lambda2"); +} + +void GMSH_Lambda2Plugin::getInfos(char *author, char *copyright, + char *help_text) const +{ + strcpy(author, "E. Marchandise"); + strcpy(copyright, "DGR (www.multiphysics.com)"); + strcpy(help_text, + "Plugin(Lambda2) computes\n" + "the eigenvalues Lambda (1,2,3)\n" + "of the tensor S_ik S_kj + Om_ik Om_kj,\n" + "where S_ij = 0.5 (ui,j + uj,i)) and\n" + "Om_ij = 0.5 (ui,j - uj,i) are respectively\n" + "the symmetric and antisymmetric parts\n" + "of the velocity gradient tensor.\n" + "Vortices are well-represented by regions\n" + "where Lambda (2) is negative.\n" + "If `iView' < 0, the plugin is run\n" + "on the current view.\n" + "\n" + "Plugin(Lambda2) is executed in-place.\n"); +} + +int GMSH_Lambda2Plugin::getNbOptions() const +{ + return sizeof(Lambda2Options_Number) / sizeof(StringXNumber); +} + +StringXNumber *GMSH_Lambda2Plugin::getOption(int iopt) +{ + return &Lambda2Options_Number[iopt]; +} + +void GMSH_Lambda2Plugin::catchErrorMessage(char *errorMessage) const +{ + strcpy(errorMessage, "Lambda2 failed..."); +} + +//----------------------------------------------------------------------------- +static void eigen(List_T *inList, int inNb, + List_T *outListScalar, int *outNbScalar, + int nbTime, int nbNod, int nbComp, int lam) +{ + + if(!inNb) + return; + + int outNbComp, *outNb; + List_T *outList; + + outNbComp = 1; + outNb = outNbScalar; + outList = outListScalar; + + int nb = List_Nbr(inList) / inNb; + + //boucle sur les elements + //----------------------- + for(int i = 0; i < List_Nbr(inList); i += nb) { + + for(int j = 0; j < 3 * nbNod; j++) + List_Add(outList, List_Pointer_Fast(inList, i + j)); + + for(int j = 0; j < nbTime; j++){ + + double *x = (double *)List_Pointer_Fast(inList, i); + double *y = (double *)List_Pointer_Fast(inList, i + nbNod); + double *z = (double *)List_Pointer_Fast(inList, i + 2 * nbNod); + double GradVel[3][3]; + double *v = (double *)List_Pointer_Fast(inList, i + 3 * nbNod + nbNod * nbComp * j + nbComp * 0); + GradVel[0][0] = v[0]; GradVel[0][1] = v[1]; GradVel[0][2] = v[2]; + GradVel[1][0] = v[3]; GradVel[1][1] = v[4]; GradVel[1][2] = v[5]; + GradVel[2][0] = v[6]; GradVel[2][1] = v[7]; GradVel[2][2] = v[8]; + + //par element + //------------ + + //calcul partie sym et antisymetrique + double sym[3][3]; + double asym[3][3]; + for(int i=0; i<3; i++){ + for(int j=0; j<3; j++){ + sym[i][j] = 0.5*(GradVel[i][j]+GradVel[j][i]); + asym[i][j] = 0.5*(GradVel[i][j]-GradVel[j][i]); + } + } + double a[3][3]; + for(int i=0; i<3; i++) + for(int j=0; j<3; j++){ + a[i][j] = 0.0; + for(int k=0; k<3; k++) + a[i][j] += sym[i][k]*sym[k][j] + asym[i][k]*asym[k][j]; + } + + //calcul de lambda avec tri + double lambda[3]; + eigenvalue(a, lambda); + + double res; + for(int k = 0; k < nbNod; k++){ + for(int l = 0; l < outNbComp; l++){ + res = lambda[lam-1]; + List_Add(outList, &res); + } + } + } + (*outNb)++; + } + +} + +//----------------------------------------------------------------------------- +Post_View *GMSH_Lambda2Plugin::execute(Post_View * v) +{ + int ev = (int)Lambda2Options_Number[0].def; + int iView = (int)Lambda2Options_Number[1].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); + + eigen(v1->TT, v1->NbTT, v2->ST, &v2->NbSS, v1->NbTimeStep, 3, 9, ev); + + eigen(v1->TS, v1->NbTS, v2->SS, &v2->NbSS, v1->NbTimeStep, 4, 9, ev); + + if(v2->empty()) { + RemoveViewByNumber(v2->Num); + return v1; + } + else{ + // 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_Extract", v1->Name); + sprintf(filename, "%s_Extract.pos", v1->Name); + EndView(v2, 1, filename, name); + return v2; + + } +} +//------------------------------------------------------------------ diff --git a/Plugin/Lambda2.h b/Plugin/Lambda2.h new file mode 100644 index 0000000000..f7d9f93174 --- /dev/null +++ b/Plugin/Lambda2.h @@ -0,0 +1,52 @@ +#ifndef _LAMBDA2_H_ +#define _LAMBDA2_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" +#include "List.h" +#include "Numeric.h" +#include <algorithm> +#include <functional> +#include <math.h> +#include <stdio.h> + +extern "C" +{ + GMSH_Plugin *GMSH_RegisterLambda2Plugin(); +} + +class GMSH_Lambda2Plugin : public GMSH_Post_Plugin +{ +public: + GMSH_Lambda2Plugin(); + void getName(char *name) const; + void getInfos(char *author, char *copyright, char *helpText) const; + void catchErrorMessage(char *errorMessage) const; + int getNbOptions() const; + StringXNumber* getOption(int iopt); + + Post_View *execute(Post_View *); + + + +//--------------------------------------------------------- +}; +#endif -- GitLab