diff --git a/Geo/GModelIO_MED.cpp b/Geo/GModelIO_MED.cpp index 120139515a62d9f3f43a3550101ab87d037e1433..18fae9b130ad7f6377af0da250c9dcf85f5f38ee 100644 --- a/Geo/GModelIO_MED.cpp +++ b/Geo/GModelIO_MED.cpp @@ -1,4 +1,4 @@ -// $Id: GModelIO_MED.cpp,v 1.25 2008-04-02 20:00:38 geuzaine Exp $ +// $Id: GModelIO_MED.cpp,v 1.26 2008-04-05 09:21:37 geuzaine Exp $ // // Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle // @@ -273,7 +273,7 @@ int GModel::readMED(const std::string &name, int meshIndex) _associateEntityWithMeshVertices(); for(unsigned int i = 0; i < verts.size(); i++){ GEntity *ge = verts[i]->onWhat(); - // store vertices (except for points, which ok already) + // store vertices (except for points, which are already ok) if(ge && ge->dim() > 0) ge->mesh_vertices.push_back(verts[i]); // delete unused vertices if(!ge) delete verts[i]; diff --git a/Graphics/Post.cpp b/Graphics/Post.cpp index 14a37d448e177a3eadfa3318d260884edffe3c22..cf2256f8517c98c216d6fdb9c0fde48f11396442 100644 --- a/Graphics/Post.cpp +++ b/Graphics/Post.cpp @@ -1,4 +1,4 @@ -// $Id: Post.cpp,v 1.162 2008-04-01 12:47:10 geuzaine Exp $ +// $Id: Post.cpp,v 1.163 2008-04-05 09:21:37 geuzaine Exp $ // // Copyright (C) 1997-2008 C. Geuzaine, J.-F. Remacle // @@ -895,7 +895,7 @@ void addElementsInArrays(PView *p, bool preprocessNormalsOnly) for(int ent = 0; ent < data->getNumEntities(opt->TimeStep); ent++){ if(data->skipEntity(opt->TimeStep, ent)) continue; for(int i = 0; i < data->getNumElements(opt->TimeStep, ent); i++){ - if(data->skipElement(opt->TimeStep, ent, i)) continue; + if(data->skipElement(opt->TimeStep, ent, i, true)) continue; int numEdges = data->getNumEdges(opt->TimeStep, ent, i); if(opt->skipElement(numEdges)) continue; int numComp = data->getNumComponents(opt->TimeStep, ent, i); @@ -1150,7 +1150,7 @@ void drawGlyphs(PView *p) for(int ent = 0; ent < data->getNumEntities(opt->TimeStep); ent++){ if(data->skipEntity(opt->TimeStep, ent)) continue; for(int i = 0; i < data->getNumElements(opt->TimeStep, ent); i++){ - if(data->skipElement(opt->TimeStep, ent, i)) continue; + if(data->skipElement(opt->TimeStep, ent, i, true)) continue; int numEdges = data->getNumEdges(opt->TimeStep, ent, i); if(opt->skipElement(numEdges)) continue; int dim = data->getDimension(opt->TimeStep, ent, i); diff --git a/Plugin/Curl.cpp b/Plugin/Curl.cpp index 860f3dc4166cab254788f984227c98fca49f740b..51fcd685219fc5751c6055af7a25d5d5bc390a06 100644 --- a/Plugin/Curl.cpp +++ b/Plugin/Curl.cpp @@ -1,4 +1,4 @@ -// $Id: Curl.cpp,v 1.7 2008-03-20 11:44:12 geuzaine Exp $ +// $Id: Curl.cpp,v 1.8 2008-04-05 09:21:37 geuzaine Exp $ // // Copyright (C) 1997-2008 C. Geuzaine, J.-F. Remacle // @@ -72,34 +72,18 @@ void GMSH_CurlPlugin::catchErrorMessage(char *errorMessage) const strcpy(errorMessage, "Curl failed..."); } -static void curl(int inNb, List_T *inList, int *outNb, List_T *outList, - int dim, int nbNod, int nbTime) +static List_T *incrementList(PViewDataList *data2, int numEdges) { - if(!inNb) return; - - int nb = List_Nbr(inList) / inNb; - for(int i = 0; i < List_Nbr(inList); i += nb) { - 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); - elementFactory factory; - element *element = factory.create(nbNod, dim, x, y, z); - if(!element) return; - for(int j = 0; j < 3 * nbNod; j++) - List_Add(outList, &x[j]); - for(int j = 0; j < nbTime; j++){ - double *val = (double *)List_Pointer(inList, i + 3 * nbNod + nbNod * 3 * j); - for(int k = 0; k < nbNod; k++){ - double u, v, w, f[3]; - element->getNode(k, u, v, w); - element->interpolateCurl(val, u, v, w, f, 3); - List_Add(outList, &f[0]); - List_Add(outList, &f[1]); - List_Add(outList, &f[2]); - } - } - delete element; - (*outNb)++; + switch(numEdges){ + case 0: data2->NbVP++; return data2->VP; + case 1: data2->NbVL++; return data2->VL; + case 3: data2->NbVT++; return data2->VT; + case 4: data2->NbVQ++; return data2->VQ; + case 6: data2->NbVS++; return data2->VS; + case 12: data2->NbVH++; return data2->VH; + case 9: data2->NbVI++; return data2->VI; + case 8: data2->NbVY++; return data2->VY; + default: return 0; } } @@ -110,25 +94,55 @@ PView *GMSH_CurlPlugin::execute(PView *v) PView *v1 = getView(iView, v); if(!v1) return v; - PViewDataList *data1 = getDataList(v1); - if(!data1) return v; + PViewData *data1 = v1->getData(); + if(data1->hasMultipleMeshes()){ + Msg(GERROR, "Curl plugin cannot be run on multi-mesh views"); + return v; + } PView *v2 = new PView(true); - PViewDataList *data2 = getDataList(v2); - if(!data2) return v; - int nts = data1->getNumTimeSteps(); - curl(data1->NbVL, data1->VL, &data2->NbVL, data2->VL, 1, 2, nts); - curl(data1->NbVT, data1->VT, &data2->NbVT, data2->VT, 2, 3, nts); - curl(data1->NbVQ, data1->VQ, &data2->NbVQ, data2->VQ, 2, 4, nts); - curl(data1->NbVS, data1->VS, &data2->NbVS, data2->VS, 3, 4, nts); - curl(data1->NbVH, data1->VH, &data2->NbVH, data2->VH, 3, 8, nts); - curl(data1->NbVI, data1->VI, &data2->NbVI, data2->VI, 3, 6, nts); - curl(data1->NbVY, data1->VY, &data2->NbVY, data2->VY, 3, 5, nts); + for(int ent = 0; ent < data1->getNumEntities(0); ent++){ + for(int ele = 0; ele < data1->getNumElements(0, ent); ele++){ + if(data1->skipElement(0, ent, ele)) continue; + int numComp = data1->getNumComponents(0, ent, ele); + if(numComp != 3) continue; + int numEdges = data1->getNumEdges(0, ent, ele); + List_T *out = incrementList(data2, numEdges); + if(!out) continue; + int numNodes = data1->getNumNodes(0, ent, ele); + double x[8], y[8], z[8], val[8 * 3]; + for(int nod = 0; nod < numNodes; nod++) + data1->getNode(0, ent, ele, nod, x[nod], y[nod], z[nod]); + int dim = data1->getDimension(0, ent, ele); + elementFactory factory; + element *element = factory.create(numNodes, dim, x, y, z); + if(!element) continue; + for(int nod = 0; nod < numNodes; nod++) List_Add(out, &x[nod]); + for(int nod = 0; nod < numNodes; nod++) List_Add(out, &y[nod]); + for(int nod = 0; nod < numNodes; nod++) List_Add(out, &z[nod]); + for(int step = 0; step < data1->getNumTimeSteps(); step++){ + for(int nod = 0; nod < numNodes; nod++) + for(int comp = 0; comp < numComp; comp++) + data1->getValue(step, ent, ele, nod, comp, val[numComp * nod + comp]); + for(int nod = 0; nod < numNodes; nod++){ + double u, v, w, f[3]; + element->getNode(nod, u, v, w); + element->interpolateCurl(val, u, v, w, f, 3); + List_Add(out, &f[0]); + List_Add(out, &f[1]); + List_Add(out, &f[2]); + } + } + delete element; + } + } - for(int i = 0; i < List_Nbr(data1->Time); i++) - List_Add(data2->Time, List_Pointer(data1->Time, i)); + for(int i = 0; i < data1->getNumTimeSteps(); i++){ + double time = data1->getTime(i); + List_Add(data2->Time, &time); + } data2->setName(data1->getName() + "_Curl"); data2->setFileName(data1->getName() + "_Curl.pos"); data2->finalize(); diff --git a/Plugin/Divergence.cpp b/Plugin/Divergence.cpp index aaa1501c4b85c845ba022c9d1e03fa32a1408bb6..3c36f8429227de27edf6b3f681638a76c20e2460 100644 --- a/Plugin/Divergence.cpp +++ b/Plugin/Divergence.cpp @@ -1,4 +1,4 @@ -// $Id: Divergence.cpp,v 1.7 2008-03-20 11:44:13 geuzaine Exp $ +// $Id: Divergence.cpp,v 1.8 2008-04-05 09:21:37 geuzaine Exp $ // // Copyright (C) 1997-2008 C. Geuzaine, J.-F. Remacle // @@ -72,32 +72,18 @@ void GMSH_DivergencePlugin::catchErrorMessage(char *errorMessage) const strcpy(errorMessage, "Divergence failed..."); } -static void divergence(int inNb, List_T *inList, int *outNb, List_T *outList, - int dim, int nbNod, int nbTime) +static List_T *incrementList(PViewDataList *data2, int numEdges) { - if(!inNb) return; - - int nb = List_Nbr(inList) / inNb; - for(int i = 0; i < List_Nbr(inList); i += nb) { - 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); - elementFactory factory; - element *element = factory.create(nbNod, dim, x, y, z); - if(!element) return; - for(int j = 0; j < 3 * nbNod; j++) - List_Add(outList, &x[j]); - for(int j = 0; j < nbTime; j++){ - double *val = (double *)List_Pointer(inList, i + 3 * nbNod + nbNod * 3 * j); - for(int k = 0; k < nbNod; k++){ - double u, v, w; - element->getNode(k, u, v, w); - double f = element->interpolateDiv(val, u, v, w, 3); - List_Add(outList, &f); - } - } - delete element; - (*outNb)++; + switch(numEdges){ + case 0: data2->NbSP++; return data2->SP; + case 1: data2->NbSL++; return data2->SL; + case 3: data2->NbST++; return data2->ST; + case 4: data2->NbSQ++; return data2->SQ; + case 6: data2->NbSS++; return data2->SS; + case 12: data2->NbSH++; return data2->SH; + case 9: data2->NbSI++; return data2->SI; + case 8: data2->NbSY++; return data2->SY; + default: return 0; } } @@ -108,25 +94,53 @@ PView *GMSH_DivergencePlugin::execute(PView *v) PView *v1 = getView(iView, v); if(!v1) return v; - PViewDataList *data1 = getDataList(v1); - if(!data1) return v; + PViewData *data1 = v1->getData(); + if(data1->hasMultipleMeshes()){ + Msg(GERROR, "Divergence plugin cannot be run on multi-mesh views"); + return v; + } PView *v2 = new PView(true); - PViewDataList *data2 = getDataList(v2); - if(!data2) return v; - - int nts = data1->getNumTimeSteps(); - divergence(data1->NbVL, data1->VL, &data2->NbSL, data2->SL, 1, 2, nts); - divergence(data1->NbVT, data1->VT, &data2->NbST, data2->ST, 2, 3, nts); - divergence(data1->NbVQ, data1->VQ, &data2->NbSQ, data2->SQ, 2, 4, nts); - divergence(data1->NbVS, data1->VS, &data2->NbSS, data2->SS, 3, 4, nts); - divergence(data1->NbVH, data1->VH, &data2->NbSH, data2->SH, 3, 8, nts); - divergence(data1->NbVI, data1->VI, &data2->NbSI, data2->SI, 3, 6, nts); - divergence(data1->NbVY, data1->VY, &data2->NbSY, data2->SY, 3, 5, nts); - - for(int i = 0; i < List_Nbr(data1->Time); i++) - List_Add(data2->Time, List_Pointer(data1->Time, i)); + + for(int ent = 0; ent < data1->getNumEntities(0); ent++){ + for(int ele = 0; ele < data1->getNumElements(0, ent); ele++){ + if(data1->skipElement(0, ent, ele)) continue; + int numComp = data1->getNumComponents(0, ent, ele); + if(numComp != 3) continue; + int numEdges = data1->getNumEdges(0, ent, ele); + List_T *out = incrementList(data2, numEdges); + if(!out) continue; + int numNodes = data1->getNumNodes(0, ent, ele); + double x[8], y[8], z[8], val[8 * 3]; + for(int nod = 0; nod < numNodes; nod++) + data1->getNode(0, ent, ele, nod, x[nod], y[nod], z[nod]); + int dim = data1->getDimension(0, ent, ele); + elementFactory factory; + element *element = factory.create(numNodes, dim, x, y, z); + if(!element) continue; + for(int nod = 0; nod < numNodes; nod++) List_Add(out, &x[nod]); + for(int nod = 0; nod < numNodes; nod++) List_Add(out, &y[nod]); + for(int nod = 0; nod < numNodes; nod++) List_Add(out, &z[nod]); + for(int step = 0; step < data1->getNumTimeSteps(); step++){ + for(int nod = 0; nod < numNodes; nod++) + for(int comp = 0; comp < numComp; comp++) + data1->getValue(step, ent, ele, nod, comp, val[numComp * nod + comp]); + for(int nod = 0; nod < numNodes; nod++){ + double u, v, w; + element->getNode(nod, u, v, w); + double f = element->interpolateDiv(val, u, v, w, 3); + List_Add(out, &f); + } + } + delete element; + } + } + + for(int i = 0; i < data1->getNumTimeSteps(); i++){ + double time = data1->getTime(i); + List_Add(data2->Time, &time); + } data2->setName(data1->getName() + "_Divergence"); data2->setFileName(data1->getName() + "_Divergence.pos"); data2->finalize(); diff --git a/Plugin/Gradient.cpp b/Plugin/Gradient.cpp index 9ec9bf4205cd4098fbffb91990a7b0842845494a..b96daa4d7a4f4eb10ad6d832e238727c4ebc6e6c 100644 --- a/Plugin/Gradient.cpp +++ b/Plugin/Gradient.cpp @@ -1,4 +1,4 @@ -// $Id: Gradient.cpp,v 1.12 2008-03-20 11:44:14 geuzaine Exp $ +// $Id: Gradient.cpp,v 1.13 2008-04-05 09:21:37 geuzaine Exp $ // // Copyright (C) 1997-2008 C. Geuzaine, J.-F. Remacle // @@ -72,36 +72,18 @@ void GMSH_GradientPlugin::catchErrorMessage(char *errorMessage) const strcpy(errorMessage, "Gradient failed..."); } -static void gradient(int inNb, List_T *inList, int *outNb, List_T *outList, - int dim, int nbNod, int nbComp, int nbTime) +static List_T *incrementList(PViewDataList *data2, int numEdges) { - if(!inNb) return; - - int nb = List_Nbr(inList) / inNb; - for(int i = 0; i < List_Nbr(inList); i += nb) { - 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); - elementFactory factory; - element *element = factory.create(nbNod, dim, x, y, z); - if(!element) return; - for(int j = 0; j < 3 * nbNod; j++) - List_Add(outList, &x[j]); - for(int j = 0; j < nbTime; j++){ - double *val = (double *)List_Pointer(inList, i + 3 * nbNod + nbNod * nbComp * j); - for(int k = 0; k < nbNod; k++){ - double u, v, w, f[3]; - element->getNode(k, u, v, w); - for(int l = 0; l < nbComp; l++){ - element->interpolateGrad(val+l, u, v, w, f, nbComp); - List_Add(outList, &f[0]); - List_Add(outList, &f[1]); - List_Add(outList, &f[2]); - } - } - } - delete element; - (*outNb)++; + switch(numEdges){ + case 0: data2->NbVP++; return data2->VP; + case 1: data2->NbVL++; return data2->VL; + case 3: data2->NbVT++; return data2->VT; + case 4: data2->NbVQ++; return data2->VQ; + case 6: data2->NbVS++; return data2->VS; + case 12: data2->NbVH++; return data2->VH; + case 9: data2->NbVI++; return data2->VI; + case 8: data2->NbVY++; return data2->VY; + default: return 0; } } @@ -112,33 +94,54 @@ PView *GMSH_GradientPlugin::execute(PView *v) PView *v1 = getView(iView, v); if(!v1) return v; - PViewDataList *data1 = getDataList(v1); - if(!data1) return v; + PViewData *data1 = v1->getData(); + if(data1->hasMultipleMeshes()){ + Msg(GERROR, "Gradient plugin cannot be run on multi-mesh views"); + return v; + } PView *v2 = new PView(true); - PViewDataList *data2 = getDataList(v2); - if(!data2) return v; - int nts = data1->getNumTimeSteps(); - gradient(data1->NbSL, data1->SL, &data2->NbVL, data2->VL, 1, 2, 1, nts); - gradient(data1->NbST, data1->ST, &data2->NbVT, data2->VT, 2, 3, 1, nts); - gradient(data1->NbSQ, data1->SQ, &data2->NbVQ, data2->VQ, 2, 4, 1, nts); - gradient(data1->NbSS, data1->SS, &data2->NbVS, data2->VS, 3, 4, 1, nts); - gradient(data1->NbSH, data1->SH, &data2->NbVH, data2->VH, 3, 8, 1, nts); - gradient(data1->NbSI, data1->SI, &data2->NbVI, data2->VI, 3, 6, 1, nts); - gradient(data1->NbSY, data1->SY, &data2->NbVY, data2->VY, 3, 5, 1, nts); - - gradient(data1->NbVL, data1->VL, &data2->NbTL, data2->TL, 1, 2, 3, nts); - gradient(data1->NbVT, data1->VT, &data2->NbTT, data2->TT, 2, 3, 3, nts); - gradient(data1->NbVQ, data1->VQ, &data2->NbTQ, data2->TQ, 2, 4, 3, nts); - gradient(data1->NbVS, data1->VS, &data2->NbTS, data2->TS, 3, 4, 3, nts); - gradient(data1->NbVH, data1->VH, &data2->NbTH, data2->TH, 3, 8, 3, nts); - gradient(data1->NbVI, data1->VI, &data2->NbTI, data2->TI, 3, 6, 3, nts); - gradient(data1->NbVY, data1->VY, &data2->NbTY, data2->TY, 3, 5, 3, nts); + for(int ent = 0; ent < data1->getNumEntities(0); ent++){ + for(int ele = 0; ele < data1->getNumElements(0, ent); ele++){ + if(data1->skipElement(0, ent, ele)) continue; + int numComp = data1->getNumComponents(0, ent, ele); + if(numComp != 1) continue; + int numEdges = data1->getNumEdges(0, ent, ele); + List_T *out = incrementList(data2, numEdges); + if(!out) continue; + int numNodes = data1->getNumNodes(0, ent, ele); + double x[8], y[8], z[8], val[8 * 3]; + for(int nod = 0; nod < numNodes; nod++) + data1->getNode(0, ent, ele, nod, x[nod], y[nod], z[nod]); + int dim = data1->getDimension(0, ent, ele); + elementFactory factory; + element *element = factory.create(numNodes, dim, x, y, z); + if(!element) continue; + for(int nod = 0; nod < numNodes; nod++) List_Add(out, &x[nod]); + for(int nod = 0; nod < numNodes; nod++) List_Add(out, &y[nod]); + for(int nod = 0; nod < numNodes; nod++) List_Add(out, &z[nod]); + for(int step = 0; step < data1->getNumTimeSteps(); step++){ + for(int nod = 0; nod < numNodes; nod++) + data1->getValue(step, ent, ele, nod, 0, val[nod]); + for(int nod = 0; nod < numNodes; nod++){ + double u, v, w, f[3]; + element->getNode(nod, u, v, w); + element->interpolateGrad(val, u, v, w, f, 1); + List_Add(out, &f[0]); + List_Add(out, &f[1]); + List_Add(out, &f[2]); + } + } + delete element; + } + } - for(int i = 0; i < List_Nbr(data1->Time); i++) - List_Add(data2->Time, List_Pointer(data1->Time, i)); + for(int i = 0; i < data1->getNumTimeSteps(); i++){ + double time = data1->getTime(i); + List_Add(data2->Time, &time); + } data2->setName(data1->getName() + "_Gradient"); data2->setFileName(data1->getName() + "_Gradient.pos"); data2->finalize(); diff --git a/Plugin/Integrate.cpp b/Plugin/Integrate.cpp index 7a7ead93be12f775513ef7b2fadd03a4fea84f3c..4bd71a2ac872dc94421061926dfa3cb1c3382dce 100644 --- a/Plugin/Integrate.cpp +++ b/Plugin/Integrate.cpp @@ -1,4 +1,4 @@ -// $Id: Integrate.cpp,v 1.24 2008-03-20 11:44:14 geuzaine Exp $ +// $Id: Integrate.cpp,v 1.25 2008-04-05 09:21:37 geuzaine Exp $ // // Copyright (C) 1997-2008 C. Geuzaine, J.-F. Remacle // @@ -74,36 +74,6 @@ 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); - elementFactory factory; - element *element = factory.create(nbNod, dim, x, y, z); - if(!element) return 0.; - if(nbComp == 1){ - res += element->integrate(v); - } - else if(nbComp == 3){ - if(dim == 1) - res += element->integrateCirculation(v); - else if(dim == 2) - res += element->integrateFlux(v); - } - delete element; - } - return res; -} - PView *GMSH_IntegratePlugin::execute(PView * v) { int iView = (int)IntegrateOptions_Number[1].def; @@ -111,13 +81,10 @@ PView *GMSH_IntegratePlugin::execute(PView * v) PView *v1 = getView(iView, v); if(!v1) return v; - PViewDataList *data1 = getDataList(v1); - if(!data1) return v; + PViewData *data1 = v1->getData(); PView *v2 = new PView(true); - PViewDataList *data2 = getDataList(v2); - if(!data2) return v; double x = data1->getBoundingBox().center().x(); double y = data1->getBoundingBox().center().y(); @@ -125,30 +92,47 @@ PView *GMSH_IntegratePlugin::execute(PView * v) List_Add(data2->SP, &x); List_Add(data2->SP, &y); List_Add(data2->SP, &z); - for(int ts = 0; ts < data1->getNumTimeSteps(); ts++){ - double val = 0; - // scalar fields - val += integrate(data1->NbSP, data1->SP, 0, 1, 1, ts); - val += integrate(data1->NbSL, data1->SL, 1, 2, 1, ts); - val += integrate(data1->NbST, data1->ST, 2, 3, 1, ts); - val += integrate(data1->NbSQ, data1->SQ, 2, 4, 1, ts); - val += integrate(data1->NbSS, data1->SS, 3, 4, 1, ts); - val += integrate(data1->NbSH, data1->SH, 3, 8, 1, ts); - val += integrate(data1->NbSI, data1->SI, 3, 6, 1, ts); - val += integrate(data1->NbSY, data1->SY, 3, 5, 1, ts); - // circulations - val += integrate(data1->NbVL, data1->VL, 1, 2, 3, ts); - // fluxes - val += integrate(data1->NbVT, data1->VT, 2, 3, 3, ts); - val += integrate(data1->NbVQ, data1->VQ, 2, 4, 3, ts); - Msg(INFO, "Step %d: integral = %.16g", ts, val); - List_Add(data2->SP, &val); + for(int step = 0; step < data1->getNumTimeSteps(); step++){ + double res = 0; + for(int ent = 0; ent < data1->getNumEntities(step); ent++){ + for(int ele = 0; ele < data1->getNumElements(step, ent); ele++){ + if(data1->skipElement(step, ent, ele)) continue; + int numComp = data1->getNumComponents(step, ent, ele); + int numEdges = data1->getNumEdges(step, ent, ele); + bool scalar = (numComp == 1); + bool circulation = (numComp == 3 && numEdges == 1); + bool flux = (numComp == 3 && (numEdges == 3 || numEdges == 4)); + if(!scalar && !circulation && !flux) continue; + int numNodes = data1->getNumNodes(step, ent, ele); + int dim = data1->getDimension(step, ent, ele); + double x[8], y[8], z[8], val[8 * 3]; + for(int nod = 0; nod < numNodes; nod++){ + data1->getNode(step, ent, ele, nod, x[nod], y[nod], z[nod]); + for(int comp = 0; comp < numComp; comp++) + data1->getValue(step, ent, ele, nod, comp, val[numComp * nod + comp]); + } + elementFactory factory; + element *element = factory.create(numNodes, dim, x, y, z); + if(!element) continue; + if(scalar) + res += element->integrate(val); + else if(circulation) + res += element->integrateCirculation(val); + else if(flux) + res += element->integrateFlux(val); + delete element; + } + } + Msg(INFO, "Step %d: integral = %.16g", step, res); + List_Add(data2->SP, &res); } data2->NbSP = 1; v2->getOptions()->IntervalsType = PViewOptions::Numeric; - for(int i = 0; i < List_Nbr(data1->Time); i++) - List_Add(data2->Time, List_Pointer(data1->Time, i)); + for(int i = 0; i < data1->getNumTimeSteps(); i++){ + double time = data1->getTime(i); + List_Add(data2->Time, &time); + } data2->setName(data1->getName() + "_Integrate"); data2->setFileName(data1->getName() + "_Integrate.pos"); data2->finalize(); diff --git a/Plugin/Levelset.cpp b/Plugin/Levelset.cpp index d9e0671256d2846c9f6a269cd28276a4ea82c28e..c9e5199e464d33d5612c62e315e5970df720a310 100644 --- a/Plugin/Levelset.cpp +++ b/Plugin/Levelset.cpp @@ -1,4 +1,4 @@ -// $Id: Levelset.cpp,v 1.43 2008-03-20 11:44:14 geuzaine Exp $ +// $Id: Levelset.cpp,v 1.44 2008-04-05 09:21:37 geuzaine Exp $ // // Copyright (C) 1997-2008 C. Geuzaine, J.-F. Remacle // @@ -454,6 +454,7 @@ PView *GMSH_LevelsetPlugin::execute(PView *v) PViewDataList *out = getDataList(new PView(true)); for(int ent = 0; ent < vdata->getNumEntities(0); ent++){ for(int ele = 0; ele < vdata->getNumElements(0, ent); ele++){ + if(vdata->skipElement(0, ent, ele)) continue; for(int nod = 0; nod < vdata->getNumNodes(0, ent, ele); nod++){ vdata->getNode(0, ent, ele, nod, x[nod], y[nod], z[nod]); levels[nod] = levelset(x[nod], y[nod], z[nod], 0.); @@ -475,8 +476,9 @@ PView *GMSH_LevelsetPlugin::execute(PView *v) PViewDataList *out = getDataList(new PView(true)); for(int ent = 0; ent < vdata->getNumEntities(step); ent++){ for(int ele = 0; ele < vdata->getNumElements(step, ent); ele++){ + if(vdata->skipElement(step, ent, ele)) continue; for(int nod = 0; nod < vdata->getNumNodes(step, ent, ele); nod++){ - vdata->getNode(0, ent, ele, nod, x[nod], y[nod], z[nod]); + vdata->getNode(step, ent, ele, nod, x[nod], y[nod], z[nod]); vdata->getScalarValue(step, ent, ele, nod, scalarValues[nod]); levels[nod] = levelset(x[nod], y[nod], z[nod], scalarValues[nod]); } diff --git a/Plugin/Transform.cpp b/Plugin/Transform.cpp index b2f4ae86b8bf9c3b774642516100deda2281df16..ba3ec4375319ff9a236e1e84f7ecc17c734b9d44 100644 --- a/Plugin/Transform.cpp +++ b/Plugin/Transform.cpp @@ -1,4 +1,4 @@ -// $Id: Transform.cpp,v 1.38 2008-03-20 11:44:14 geuzaine Exp $ +// $Id: Transform.cpp,v 1.39 2008-04-05 09:21:37 geuzaine Exp $ // // Copyright (C) 1997-2008 C. Geuzaine, J.-F. Remacle // @@ -90,64 +90,6 @@ void GMSH_TransformPlugin::catchErrorMessage(char *errorMessage) const strcpy(errorMessage, "Transform failed..."); } -// Transformation - -static void transform(double mat[3][4], double v[3], - double *x, double *y, double *z) -{ - *x = mat[0][0] * v[0] + mat[0][1] * v[1] + mat[0][2] * v[2] + mat[0][3]; - *y = mat[1][0] * v[0] + mat[1][1] * v[1] + mat[1][2] * v[2] + mat[1][3]; - *z = mat[2][0] * v[0] + mat[2][1] * v[1] + mat[2][2] * v[2] + mat[2][3]; -} - -static void transform_list(PViewDataList *data, List_T *list, int nbList, - int nbVert, int nbComp, double mat[3][4], int swap) -{ - if(!nbList) return; - - int nb = List_Nbr(list) / nbList; - double *copy = NULL; - if(swap) copy = new double[nb]; - - 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 + nbVert); - double *z = (double *)List_Pointer_Fast(list, i + 2 * nbVert); - for(int j = 0; j < nbVert; j++) { - double v[3] = { x[j], y[j], z[j] }; -#if 1 - transform(mat, v, &x[j], &y[j], &z[j]); -#else - // for saku - double alpha = mat[0][0]; - double d = sqrt(v[0] * v[0] + v[1] * v[1]); - x[j] = cos(2 * M_PI / alpha * atan2(v[1], v[0])) * alpha / (2 * M_PI) * d; - y[j] = sin(2 * M_PI / alpha * atan2(v[1], v[0])) * alpha / (2 * M_PI) * d; - z[j] = cos(asin(alpha / (2 * M_PI))) * d; -#endif - } - if(copy){ - for(int j = 0; j < nb; j++) - copy[j] = x[j]; - for(int j = 0; j < nbVert; j++){ - x[j] = copy[nbVert - j - 1]; - x[nbVert + j] = copy[2 * nbVert - j - 1]; - x[2 * nbVert + j] = copy[3 * nbVert - j - 1]; - } - for(int ts = 0; ts < data->getNumTimeSteps(); ts++){ - for(int j = 0; j < nbVert; j++){ - for(int k = 0; k < nbComp; k++){ - x[3 * nbVert + nbComp * nbVert * ts + nbComp * j + k] = - copy[3 * nbVert + nbComp * nbVert * ts + nbComp * (nbVert - j - 1) + k]; - } - } - } - } - } - - if(copy) delete [] copy; -} - PView *GMSH_TransformPlugin::execute(PView *v) { double mat[3][4]; @@ -172,35 +114,44 @@ PView *GMSH_TransformPlugin::execute(PView *v) PView *v1 = getView(iView, v); if(!v1) return v; - PViewDataList *data1 = getDataList(v1); - if(!data1) return v; - - transform_list(data1, data1->SP, data1->NbSP, 1, 1, mat, swap); - transform_list(data1, data1->SL, data1->NbSL, 2, 1, mat, swap); - transform_list(data1, data1->ST, data1->NbST, 3, 1, mat, swap); - transform_list(data1, data1->SQ, data1->NbSQ, 4, 1, mat, swap); - transform_list(data1, data1->SS, data1->NbSS, 4, 1, mat, swap); - transform_list(data1, data1->SH, data1->NbSH, 8, 1, mat, swap); - transform_list(data1, data1->SI, data1->NbSI, 6, 1, mat, swap); - transform_list(data1, data1->SY, data1->NbSY, 5, 1, mat, swap); - - transform_list(data1, data1->VP, data1->NbVP, 1, 3, mat, swap); - transform_list(data1, data1->VL, data1->NbVL, 2, 3, mat, swap); - transform_list(data1, data1->VT, data1->NbVT, 3, 3, mat, swap); - transform_list(data1, data1->VQ, data1->NbVQ, 4, 3, mat, swap); - transform_list(data1, data1->VS, data1->NbVS, 4, 3, mat, swap); - transform_list(data1, data1->VH, data1->NbVH, 8, 3, mat, swap); - transform_list(data1, data1->VI, data1->NbVI, 6, 3, mat, swap); - transform_list(data1, data1->VY, data1->NbVY, 5, 3, mat, swap); - - transform_list(data1, data1->TP, data1->NbTP, 1, 9, mat, swap); - transform_list(data1, data1->TL, data1->NbTL, 2, 9, mat, swap); - transform_list(data1, data1->TT, data1->NbTT, 3, 9, mat, swap); - transform_list(data1, data1->TQ, data1->NbTQ, 4, 9, mat, swap); - transform_list(data1, data1->TS, data1->NbTS, 4, 9, mat, swap); - transform_list(data1, data1->TH, data1->NbTH, 8, 9, mat, swap); - transform_list(data1, data1->TI, data1->NbTI, 6, 9, mat, swap); - transform_list(data1, data1->TY, data1->NbTY, 5, 9, mat, swap); + PViewData *data1 = v1->getData(); + + // tag all the nodes with "0" (the default tag) + for(int step = 0; step < data1->getNumTimeSteps(); step++){ + for(int ent = 0; ent < data1->getNumEntities(step); ent++){ + for(int ele = 0; ele < data1->getNumElements(step, ent); ele++){ + if(data1->skipElement(step, ent, ele)) continue; + if(swap) data1->revertElement(step, ent, ele); + int numNodes = data1->getNumNodes(step, ent, ele); + for(int nod = 0; nod < numNodes; nod++){ + double x, y, z; + data1->getNode(step, ent, ele, nod, x, y, z); + data1->setNode(step, ent, ele, nod, x, y, z, 0); + } + } + } + } + + // transform all "0" nodes + for(int step = 0; step < data1->getNumTimeSteps(); step++){ + for(int ent = 0; ent < data1->getNumEntities(step); ent++){ + for(int ele = 0; ele < data1->getNumElements(step, ent); ele++){ + if(data1->skipElement(step, ent, ele)) continue; + int numNodes = data1->getNumNodes(step, ent, ele); + for(int nod = 0; nod < numNodes; nod++){ + double x, y, z; + int tag = data1->getNode(step, ent, ele, nod, x, y, z); + if(!tag){ + double x2, y2, z2; + x2 = mat[0][0] * x + mat[0][1] * y + mat[0][2] * z + mat[0][3]; + y2 = mat[1][0] * x + mat[1][1] * y + mat[1][2] * z + mat[1][3]; + z2 = mat[2][0] * x + mat[2][1] * y + mat[2][2] * z + mat[2][3]; + data1->setNode(step, ent, ele, nod, x2, y2, z2, 1); + } + } + } + } + } data1->finalize(); diff --git a/Post/PViewData.cpp b/Post/PViewData.cpp index 4732808e13a2616c96bbf29500513715e31dc3f4..628ef6cbd16b4a2f6ba7222eafc066cee79db5d5 100644 --- a/Post/PViewData.cpp +++ b/Post/PViewData.cpp @@ -1,4 +1,4 @@ -// $Id: PViewData.cpp,v 1.15 2008-03-19 17:33:54 geuzaine Exp $ +// $Id: PViewData.cpp,v 1.16 2008-04-05 09:21:37 geuzaine Exp $ // // Copyright (C) 1997-2008 C. Geuzaine, J.-F. Remacle // @@ -24,6 +24,7 @@ #include "PViewData.h" #include "Numeric.h" +#include "Message.h" PViewData::PViewData() : _dirty(true), _fileIndex(0) @@ -44,3 +45,13 @@ void PViewData::getScalarValue(int step, int ent, int ele, int nod, double &val) val = ComputeScalarRep(numComp, d); } +void PViewData::setNode(int step, int ent, int ele, int nod, double x, double y, double z, + int tag) +{ + Msg(GERROR, "Cannot change node coordinates in this view"); +} + +void PViewData::setValue(int step, int ent, int ele, int nod, int comp, double val) +{ + Msg(GERROR, "Cannot change field value in this view"); +} diff --git a/Post/PViewData.h b/Post/PViewData.h index 982802bd8cbb307999d279f87acf39fcbbbf44a8..ad656676133e19f5a7eadab28d227395ef93149f 100644 --- a/Post/PViewData.h +++ b/Post/PViewData.h @@ -78,17 +78,20 @@ class PViewData { // Returns the number of nodes of the ele-th element in the ent-th // entity virtual int getNumNodes(int step, int ent, int ele) = 0; - // Returns the coordinates of the nod-th node from the ele-th element - // in the ent-th entity - virtual void getNode(int step, int ent, int ele, int nod, - double &x, double &y, double &z) = 0; + // Gets/Sets the coordinates of the nod-th node from the ele-th element + // in the ent-th entity (if the node has a tag, getNode returns it) + virtual int getNode(int step, int ent, int ele, int nod, + double &x, double &y, double &z) = 0; + virtual void setNode(int step, int ent, int ele, int nod, + double x, double y, double z, int tag=0); // Returns the number of componts available for the ele-th element // in the ent-th entity virtual int getNumComponents(int step, int ent, int ele) = 0; - // Returns the comp-th component (at the step-th time step) + // Gets/sets the comp-th component (at the step-th time step) // associated with the node-th node from the ele-th element in the // ent-th entity virtual void getValue(int step, int ent, int ele, int nod, int comp, double &val) = 0; + virtual void setValue(int step, int ent, int ele, int nod, int comp, double val); // Returns a scalar value (same as value for scalars, norm for // vectors, etc.) associated with the node-th node from the ele-th // element in the ent-th entity @@ -102,13 +105,15 @@ class PViewData { double &x, double &y, double &style){} virtual void getString3D(int i, int step, std::string &str, double &x, double &y, double &z, double &style){} + virtual void revertElement(int step, int ent, int ele){} virtual bool empty(); virtual void smooth(){} virtual bool combineTime(nameData &nd){ return false; } virtual bool combineSpace(nameData &nd){ return false; } virtual bool isAdaptive(){ return false; } virtual bool skipEntity(int step, int ent){ return false; } - virtual bool skipElement(int step, int ent, int ele){ return false; } + virtual bool skipElement(int step, int ent, int ele, + bool checkVisibility=false){ return false; } virtual bool hasTimeStep(int step){ return step < getNumTimeSteps(); } virtual bool hasPartition(int part){ return false; } virtual bool hasMultipleMeshes(){ return false; } diff --git a/Post/PViewDataGModel.cpp b/Post/PViewDataGModel.cpp index b4def5cb32a60ab180c0d3504f0e8188e9c44c15..7550ca42312d53222c13fc929b3d707e5ff7621a 100644 --- a/Post/PViewDataGModel.cpp +++ b/Post/PViewDataGModel.cpp @@ -1,4 +1,4 @@ -// $Id: PViewDataGModel.cpp,v 1.47 2008-04-03 07:48:54 geuzaine Exp $ +// $Id: PViewDataGModel.cpp,v 1.48 2008-04-05 09:21:37 geuzaine Exp $ // // Copyright (C) 1997-2008 C. Geuzaine, J.-F. Remacle // @@ -150,8 +150,8 @@ int PViewDataGModel::getNumNodes(int step, int ent, int ele) } } -void PViewDataGModel::getNode(int step, int ent, int ele, int nod, - double &x, double &y, double &z) +int PViewDataGModel::getNode(int step, int ent, int ele, int nod, + double &x, double &y, double &z) { // no sanity checks (assumed to be guarded by skipElement) MElement *e = _steps[step]->getEntity(ent)->getMeshElement(ele); @@ -174,15 +174,28 @@ void PViewDataGModel::getNode(int step, int ent, int ele, int nod, y = e->interpolate(vy, p[3 * nod], p[3 * nod + 1], p[3 * nod + 2]); z = e->interpolate(vz, p[3 * nod], p[3 * nod + 1], p[3 * nod + 2]); } + return 0; } else{ MVertex *v = e->getVertex(nod); x = v->x(); y = v->y(); z = v->z(); + return v->getIndex(); } } +void PViewDataGModel::setNode(int step, int ent, int ele, int nod, + double x, double y, double z, int tag) +{ + // no sanity checks (assumed to be guarded by skipElement) + MVertex *v = _steps[step]->getEntity(ent)->getMeshElement(ele)->getVertex(nod); + v->x() = x; + v->y() = y; + v->z() = z; + v->setIndex(tag); +} + int PViewDataGModel::getNumComponents(int step, int ent, int ele) { // no sanity checks (assumed to be guarded by skipElement) @@ -209,12 +222,38 @@ void PViewDataGModel::getValue(int step, int ent, int ele, int nod, int comp, do } } +void PViewDataGModel::setValue(int step, int ent, int ele, int nod, int comp, double val) +{ + // no sanity checks (assumed to be guarded by skipElement) + stepData<double> *sd = _steps[step]; + MElement *e = sd->getEntity(ent)->getMeshElement(ele); + switch(_type){ + case NodeData: + sd->getData(e->getVertex(nod)->getNum())[comp] = val; + break; + case ElementNodeData: + case GaussPointData: + sd->getData(e->getNum())[sd->getNumComponents() * nod + comp] = val; + break; + case ElementData: + default: + sd->getData(e->getNum())[comp] = val; + break; + } +} + int PViewDataGModel::getNumEdges(int step, int ent, int ele) { // no sanity checks (assumed to be guarded by skipElement) return _steps[step]->getEntity(ent)->getMeshElement(ele)->getNumEdges(); } +void PViewDataGModel::revertElement(int step, int ent, int ele) +{ + // no sanity checks (assumed to be guarded by skipElement) + if(!step) _steps[step]->getEntity(ent)->getMeshElement(ele)->revert(); +} + void PViewDataGModel::smooth() { if(_type == NodeData || _type == GaussPointData) return; @@ -264,13 +303,13 @@ bool PViewDataGModel::skipEntity(int step, int ent) return !_steps[step]->getEntity(ent)->getVisibility(); } -bool PViewDataGModel::skipElement(int step, int ent, int ele) +bool PViewDataGModel::skipElement(int step, int ent, int ele, bool checkVisibility) { if(step >= getNumTimeSteps()) return true; stepData<double> *sd = _steps[step]; if(!_steps[step]->getNumData()) return true; MElement *e = sd->getEntity(ent)->getMeshElement(ele); - if(!e->getVisibility()) return true; + if(checkVisibility && !e->getVisibility()) return true; if(_type == NodeData){ for(int i = 0; i < e->getNumVertices(); i++) if(!sd->getData(e->getVertex(i)->getNum())) return true; diff --git a/Post/PViewDataGModel.h b/Post/PViewDataGModel.h index 0ae11911c656f57df397b197d122b6911b78d44f..e7b8d5fcbedc4a26faffb073090d897254f526d6 100644 --- a/Post/PViewDataGModel.h +++ b/Post/PViewDataGModel.h @@ -158,13 +158,17 @@ class PViewDataGModel : public PViewData { int getNumElements(int step=-1, int ent=-1); int getDimension(int step, int ent, int ele); int getNumNodes(int step, int ent, int ele); - void getNode(int step, int ent, int ele, int nod, double &x, double &y, double &z); + int getNode(int step, int ent, int ele, int nod, double &x, double &y, double &z); + void setNode(int step, int ent, int ele, int nod, double x, double y, double z, + int tag=0); int getNumComponents(int step, int ent, int ele); void getValue(int step, int ent, int ele, int node, int comp, double &val); + void setValue(int step, int ent, int ele, int node, int comp, double val); int getNumEdges(int step, int ent, int ele); + void revertElement(int step, int ent, int ele); void smooth(); bool skipEntity(int step, int ent); - bool skipElement(int step, int ent, int ele); + bool skipElement(int step, int ent, int ele, bool checkVisibility=false); bool hasTimeStep(int step); bool hasPartition(int part); bool hasMultipleMeshes(); diff --git a/Post/PViewDataGModelIO.cpp b/Post/PViewDataGModelIO.cpp index 6dc741cff988e6b394dddf51d3df412cb0f6f115..6082f8fb0726c201f407b0325a8eb2c2545be1ea 100644 --- a/Post/PViewDataGModelIO.cpp +++ b/Post/PViewDataGModelIO.cpp @@ -1,4 +1,4 @@ -// $Id: PViewDataGModelIO.cpp,v 1.37 2008-04-03 07:48:54 geuzaine Exp $ +// $Id: PViewDataGModelIO.cpp,v 1.38 2008-04-05 09:21:37 geuzaine Exp $ // // Copyright (C) 1997-2008 C. Geuzaine, J.-F. Remacle // @@ -165,7 +165,6 @@ extern "C" { #include <med.h> } -extern med_geometrie_element msh2medElementType(int msh); extern int med2mshElementType(med_geometrie_element med); extern int med2mshNodeIndex(med_geometrie_element med, int k); diff --git a/Post/PViewDataList.cpp b/Post/PViewDataList.cpp index 6f0fe6e9091bcdf38bcc23856388b988e508bb86..83cc55ea319b1bed50a930638e7b77fcaae3669f 100644 --- a/Post/PViewDataList.cpp +++ b/Post/PViewDataList.cpp @@ -1,4 +1,4 @@ -// $Id: PViewDataList.cpp,v 1.19 2008-03-20 11:44:15 geuzaine Exp $ +// $Id: PViewDataList.cpp,v 1.20 2008-04-05 09:21:37 geuzaine Exp $ // // Copyright (C) 1997-2008 C. Geuzaine, J.-F. Remacle // @@ -333,13 +333,24 @@ int PViewDataList::getNumNodes(int step, int ent, int ele) return _lastNumNodes; } -void PViewDataList::getNode(int step, int ent, int ele, int nod, - double &x, double &y, double &z) +int PViewDataList::getNode(int step, int ent, int ele, int nod, + double &x, double &y, double &z) { if(ele != _lastElement) _setLast(ele); x = _lastXYZ[nod]; y = _lastXYZ[_lastNumNodes + nod]; z = _lastXYZ[2 * _lastNumNodes + nod]; + return 0; +} + +void PViewDataList::setNode(int step, int ent, int ele, int nod, + double x, double y, double z, int tag) +{ + if(step) return; + if(ele != _lastElement) _setLast(ele); + _lastXYZ[nod] = x; + _lastXYZ[_lastNumNodes + nod] = y; + _lastXYZ[2 * _lastNumNodes + nod] = z; } int PViewDataList::getNumComponents(int step, int ent, int ele) @@ -356,6 +367,14 @@ void PViewDataList::getValue(int step, int ent, int ele, int nod, int comp, doub comp]; } +void PViewDataList::setValue(int step, int ent, int ele, int nod, int comp, double val) +{ + if(ele != _lastElement) _setLast(ele); + _lastVal[step * _lastNumNodes * _lastNumComponents + + nod * _lastNumComponents + + comp] = val; +} + int PViewDataList::getNumEdges(int step, int ent, int ele) { if(ele != _lastElement) _setLast(ele); @@ -427,6 +446,36 @@ void PViewDataList::getString3D(int i, int step, std::string &str, _getString(3, i, step, str, x, y, z, style); } +void PViewDataList::revertElement(int step, int ent, int ele) +{ + if(step) return; + if(ele != _lastElement) _setLast(ele); + + // copy data + std::vector<double> XYZ(3 * _lastNumNodes); + for(int i = 0; i < XYZ.size(); i++) + XYZ[i] = _lastXYZ[i]; + + std::vector<double> V(_lastNumNodes * _lastNumComponents * getNumTimeSteps()); + for(int i = 0; i < V.size(); i++) + V[i] = _lastVal[i]; + + // reverse node order + for(int i = 0; i < _lastNumNodes; i++){ + _lastXYZ[i] = XYZ[_lastNumNodes - i - 1]; + _lastXYZ[_lastNumNodes + i] = XYZ[2 * _lastNumNodes - i - 1]; + _lastXYZ[2 * _lastNumNodes + i] = XYZ[3 * _lastNumNodes - i - 1]; + } + + for(int step = 0; step < getNumTimeSteps(); step++) + for(int i = 0; i < _lastNumNodes; i++) + for(int k = 0; k < _lastNumComponents; k++) + _lastVal[_lastNumComponents * _lastNumNodes * step + + _lastNumComponents * i + k] = + V[_lastNumComponents * _lastNumNodes * step + + _lastNumComponents * (_lastNumNodes - i - 1) + k]; +} + static void splitCurvedElement(List_T **in, int *nbin, List_T *out, int *nbout, int nodin, int nodout, int nbcomp, int nbsplit, int split[][8], int remove=1) diff --git a/Post/PViewDataList.h b/Post/PViewDataList.h index da16f8e14b0bbcd3d01f5560203bff90e895bb85..227080d05628a139d5d6cfbd130937994327567f 100644 --- a/Post/PViewDataList.h +++ b/Post/PViewDataList.h @@ -94,9 +94,12 @@ class PViewDataList : public PViewData { int getNumElements(int step=-1, int ent=-1); int getDimension(int step, int ent, int ele); int getNumNodes(int step, int ent, int ele); - void getNode(int step, int ent, int ele, int nod, double &x, double &y, double &z); + int getNode(int step, int ent, int ele, int nod, double &x, double &y, double &z); + void setNode(int step, int ent, int ele, int nod, double x, double y, double z, + int tag=0); int getNumComponents(int step, int ent, int ele); void getValue(int step, int ent, int ele, int nod, int comp, double &val); + void setValue(int step, int ent, int ele, int nod, int comp, double val); int getNumEdges(int step, int ent, int ele); int getNumStrings2D(){ return NbT2; } int getNumStrings3D(){ return NbT3; } @@ -104,6 +107,7 @@ class PViewDataList : public PViewData { double &x, double &y, double &style); void getString3D(int i, int step, std::string &str, double &x, double &y, double &z, double &style); + void revertElement(int step, int ent, int ele); void smooth(); bool combineTime(nameData &nd); bool combineSpace(nameData &nd); diff --git a/doc/texinfo/gmsh.texi b/doc/texinfo/gmsh.texi index d1604677c5e6eb044be6362776052d24ced314cf..039073d149594e0747c882d0ecfb0034294a3e4c 100644 --- a/doc/texinfo/gmsh.texi +++ b/doc/texinfo/gmsh.texi @@ -1,5 +1,5 @@ \input texinfo.tex @c -*-texinfo-*- -@c $Id: gmsh.texi,v 1.241 2008-03-21 09:39:43 geuzaine Exp $ +@c $Id: gmsh.texi,v 1.242 2008-04-05 09:21:37 geuzaine Exp $ @c @c Copyright (C) 1997-2008 C. Geuzaine, J.-F. Remacle @c @@ -230,21 +230,16 @@ Running Gmsh File formats -* Gmsh mesh file formats:: -* Gmsh post-processing file formats:: -* Gmsh node ordering:: +* MSH ASCII file format:: +* MSH binary file format:: +* Node ordering:: +* Legacy formats:: -Gmsh mesh file formats +Legacy formats -* Version 1.0:: -* Version 2.0 ASCII:: -* Version 2.0 Binary:: - -Gmsh post-processing file formats - -* Parsed post-processing file format:: -* ASCII post-processing file format:: -* Binary post-processing file format:: +* MSH file format version 1.0:: +* POS ASCII file format:: +* POS binary file format:: Programming notes @@ -1873,7 +1868,7 @@ number of the elementary entities they discretize as their elementary region number (and 0 as their physical region number@footnote{This behaviour was introduced in Gmsh 2.0. In older versions, both the elementary and the physical region numbers would be set to the -identification number of the elementary region.}; @ref{Gmsh mesh file +identification number of the elementary region.}; @ref{File formats}). This can sometimes be inconvenient: @itemize @bullet @@ -1898,11 +1893,10 @@ physical entities in large models usually greatly facilitates the manipulation of the model (e.g., using `Tools->Visibility' in the GUI) and the interfacing with external solvers. -In the @file{.msh} file format (@pxref{Gmsh mesh file formats}), if -physical entities are defined, the output mesh only contains those -elements that belong to physical entities. Other file formats each treat -physical entities in slightly different ways, depending on their -capability to define groups. +In the MSH file format (@pxref{File formats}), if physical entities are +defined, the output mesh only contains those elements that belong to +physical entities. Other file formats each treat physical entities in +slightly different ways, depending on their capability to define groups. @c ------------------------------------------------------------------------- @c Mesh commands @@ -1988,7 +1982,7 @@ mathematical function. A @code{Min} field specifies the size as the minimum of the sizes computed using other fields @item -@dots +@dots{} @end itemize All target element sizes specified by fields can also be constrained by the characteristic lengths defined in the geometrical model if the @@ -2309,9 +2303,9 @@ peculiar to 3D (lightning, element selection, etc.) or 2D plots (abscissa labels, etc.). Note that 2D plots can be positioned explicitly inside the graphical window, or be automatically positioned in order to avoid overlaps. -Sample post-processing files in human-readable ``parsed'' format -(@pxref{Parsed post-processing file format}) are available in the -@file{tutorial} directory of Gmsh's distribution (@file{.pos} files). +Sample post-processing files in human-readable ``parsed'' format are +available in the @file{tutorial} directory of Gmsh's distribution +(@file{.pos} files). @menu * Post-processing commands:: @@ -2402,16 +2396,149 @@ Saves the the @var{expression}-th post-processing view in a file named @var{char-expression}. If the path in @var{char-expression} is not absolute, @var{char-expression} is appended to the path of the current file. -@item View "@var{string}" @{ @var{string} ( @var{expression-list} ) @{ @var{expression-list} @}; @dots{} @}; -Creates a new post-processing view, named @code{"@var{string}"}. This is the -easiest way to create a post-processing view, but also the least efficient -(the view is read through Gmsh's script parser, which can become a bit slow -if the view is very large---e.g., with one million elements). Nevertheless, -this ``parsed'' post-processing format (explained in detail in @ref{Parsed -post-processing file format}) is very powerful, since all the values are -@var{expressions}. Two other formats, better suited for very large data -sets, are described in @ref{ASCII post-processing file format}, and -@ref{Binary post-processing file format}. +@item View "@var{string}" @{ @var{string} < ( @var{expression-list} ) > @{ @var{expression-list} @}; @dots{} @}; +Creates a new post-processing view, named @code{"@var{string}"}. This +is an easy and quite powerful way to import post-processing data: all +the values are @var{expressions}, you can embed datasets directly into +your geometrical descriptions (see, e.g., @ref{t4.geo}), the data can be +easily generated ``on-the-fly'' (there is no header containing @emph{a +priori} information on the size of the dataset). The syntax is also very +permissive, which makes it ideal for testing purposes. + +However this ``parsed format'' is read by Gmsh's script parser, which +makes it inefficient if there are many elements in the dataset. Also, +there is no connectivity information in parsed views and all the +elements are independent (all fields can be discontinuous), so a lot of +information can be duplicated. For large datasets, you should thus use +the mesh-based post-processing file format described in @ref{File +formats}, or use one of the standard formats like MED. + +More explicitly, the syntax for a parsed @code{View} is the following + +@example +@group +View "@var{string}" @{ + < TIME @{ @var{expression-list} @}; > + @var{type} ( @var{list-of-coords} ) @{ @var{list-of-values} @}; + @dots{} +@}; +@end group +@end example + +where the 47 object @w{@var{type}s} that can be displayed are: + +@smallexample + @var{type} #@var{list-of-coords} #@var{list-of-values} +-------------------------------------------------------------------- +Scalar point SP 3 1 * @var{nb-time-steps} +Vector point VP 3 3 * @var{nb-time-steps} +Tensor point TP 3 9 * @var{nb-time-steps} +Scalar line SL 6 2 * @var{nb-time-steps} +Vector line VL 6 6 * @var{nb-time-steps} +Tensor line TL 6 18 * @var{nb-time-steps} +Scalar triangle ST 9 3 * @var{nb-time-steps} +Vector triangle VT 9 9 * @var{nb-time-steps} +Tensor triangle TT 9 27 * @var{nb-time-steps} +Scalar quadrangle SQ 12 4 * @var{nb-time-steps} +Vector quadrangle VQ 12 12 * @var{nb-time-steps} +Tensor quadrangle TQ 12 36 * @var{nb-time-steps} +Scalar tetrahedron SS 12 4 * @var{nb-time-steps} +Vector tetrahedron VS 12 12 * @var{nb-time-steps} +Tensor tetrahedron TS 12 36 * @var{nb-time-steps} +Scalar hexahedron SH 24 8 * @var{nb-time-steps} +Vector hexahedron VH 24 24 * @var{nb-time-steps} +Tensor hexahedron TH 24 72 * @var{nb-time-steps} +Scalar prism SI 18 6 * @var{nb-time-steps} +Vector prism VI 18 18 * @var{nb-time-steps} +Tensor prism TI 18 54 * @var{nb-time-steps} +Scalar pyramid SY 15 5 * @var{nb-time-steps} +Vector pyramid VY 15 15 * @var{nb-time-steps} +Tensor pyramid TY 15 45 * @var{nb-time-steps} +2nd order scalar line SL2 9 3 * @var{nb-time-steps} +2nd order vector line VL2 9 9 * @var{nb-time-steps} +2nd order tensor line TL2 9 27 * @var{nb-time-steps} +2nd order scalar triangle ST2 18 6 * @var{nb-time-steps} +2nd order vector triangle VT2 18 18 * @var{nb-time-steps} +2nd order tensor triangle TT2 18 54 * @var{nb-time-steps} +2nd order scalar quadrangle SQ2 27 9 * @var{nb-time-steps} +2nd order vector quadrangle VQ2 27 27 * @var{nb-time-steps} +2nd order tensor quadrangle TQ2 27 81 * @var{nb-time-steps} +2nd order scalar tetrahedron SS2 30 10 * @var{nb-time-steps} +2nd order vector tetrahedron VS2 30 30 * @var{nb-time-steps} +2nd order tensor tetrahedron TS2 30 90 * @var{nb-time-steps} +2nd order scalar hexahedron SH2 81 27 * @var{nb-time-steps} +2nd order vector hexahedron VH2 81 81 * @var{nb-time-steps} +2nd order tensor hexahedron TH2 81 243* @var{nb-time-steps} +2nd order scalar prism SI2 54 18 * @var{nb-time-steps} +2nd order vector prism VI2 54 54 * @var{nb-time-steps} +2nd order tensor prism TI2 54 162* @var{nb-time-steps} +2nd order scalar pyramid SY2 42 14 * @var{nb-time-steps} +2nd order vector pyramid VY2 42 42 * @var{nb-time-steps} +2nd order tensor pyramid TY2 42 126* @var{nb-time-steps} +2D text T2 3 arbitrary +3D text T3 4 arbitrary +@end smallexample + +The coordinates are given `by node', i.e., + +@itemize @bullet +@item +@code{(@var{coord1}, @var{coord2}, @var{coord3})} for a point, +@item +@code{(@var{coord1-node1}, @var{coord2-node1}, @var{coord3-node1},}@* +@code{ @var{coord1-node2}, @var{coord2-node2}, @var{coord3-node2})} for a line, +@item +@code{(@var{coord1-node1}, @var{coord2-node1}, @var{coord3-node1},}@* +@code{ @var{coord1-node2}, @var{coord2-node2}, @var{coord3-node2},}@* +@code{ @var{coord1-node3}, @var{coord2-node3}, @var{coord3-node3})} for a triangle, +@item +etc. +@end itemize + +The ordering of the nodes is given in @ref{Node ordering}. For second +order elements, the first order nodes are given first, followed by the nodes +associated with the edges, followed by the nodes associated with the +quadrangular faces (if any), followed by the nodes associated with the +volume (if any). The ordering of these additional nodes follows the ordering +of the edges and quadrangular faces given in @ref{Node ordering}. + +The values are given by time step, by node and by component, i.e.: +@example +@var{comp1-node1-time1}, @var{comp2-node1-time1}, @var{comp3-node1-time1}, +@var{comp1-node2-time1}, @var{comp2-node2-time1}, @var{comp3-node2-time1}, +@var{comp1-node3-time1}, @var{comp2-node3-time1}, @var{comp3-node3-time1}, +@var{comp1-node1-time2}, @var{comp2-node1-time2}, @var{comp3-node1-time2}, +@var{comp1-node2-time2}, @var{comp2-node2-time2}, @var{comp3-node2-time2}, +@var{comp1-node3-time2}, @var{comp2-node3-time2}, @var{comp3-node3-time2}, +@dots{} +@end example + +For the 2D text objects, the two first @w{@var{expression}s} in +@var{list-of-coords} give the X-Y position of the string in screen +coordinates, measured from the top-left corner of the window. If the first +(respectively second) @var{expression} is negative, the position is measured +from the right (respectively bottom) edge of the window. If the value of the +first (respectively second) @var{expression} is larger than 99999, the +string is centered horizontally (respectively vertically). If the third +@var{expression} is equal to zero, the text is aligned bottom-left and +displayed using the default font and size. Otherwise, the third +@var{expression} is converted into an integer whose eight lower bits give +the font size, whose eight next bits select the font (the index corresponds +to the position in the font menu in the GUI), and whose eight next bits +define the text alignment (0=bottom-left, 1=bottom-center, 2=bottom-right, +3=top-left, 4=top-center, 5=top-right, 6=center-left, 7=center-center, +8=center-right). + +For the 3D text objects, the three first @w{@var{expression}s} in +@var{list-of-coords} give the XYZ position of the string in model (real +world) coordinates. The fourth @var{expression} has the same meaning as the +third @var{expression} in 2D text objects. + +For both 2D and 3D text objects, the @var{list-of-values} can contain an +arbitrary number of @w{@var{char-expression}s}. + +The optional @code{TIME} list can contain a list of expressions giving the +value of the time (or any other variable) for which an evolution was saved. @end ftable @c ------------------------------------------------------------------------- @@ -2828,193 +2955,43 @@ below.) @cindex File formats -This chapter describes Gmsh's native mesh and post-processing file -formats. (These formats have version numbers that are independent of Gmsh's -main version number.) - -All non-parsed file formats have sections enclosed between @code{$Key} and -@code{$EndKey} tags. +This chapter describes Gmsh's native ``MSH'' file format, used to allows +store meshes and associated post-processing datasets. The MSH format +exists in two flavor: ASCII and binary. The format has a version number +(currently 2.0) that is independent of Gmsh's main version number. @menu -* Gmsh mesh file formats:: -* Gmsh post-processing file formats:: -* Gmsh node ordering:: +* MSH ASCII file format:: +* MSH binary file format:: +* Node ordering:: +* Legacy formats:: @end menu @c ------------------------------------------------------------------------- -@c Gmsh mesh file formats +@c MSH ASCII file format @c ------------------------------------------------------------------------- -@node Gmsh mesh file formats, Gmsh post-processing file formats, File formats, File formats -@section Gmsh mesh file formats +@node MSH ASCII file format, MSH binary file format, File formats, File formats +@section MSH ASCII file format @cindex Mesh, file format @cindex File format, mesh -@cindex @file{.msh} file - -Please note that the list of nodes and elements in Gmsh's mesh files do -not have to be dense or ordered (i.e., the node and element numbers do -not have to be given in a consecutive or even an ordered way). - -@menu -* Version 1.0:: -* Version 2.0 ASCII:: -* Version 2.0 Binary:: -@end menu - -@c ......................................................................... -@c Version 1.0 -@c ......................................................................... - -@node Version 1.0, Version 2.0 ASCII, Gmsh mesh file formats, Gmsh mesh file formats -@subsection Version 1.0 - -The @file{.msh} file format, version 1.0, is Gmsh's old native mesh file -format, now superseded by the format described in @ref{Version 2.0 ASCII}. - -In the @file{.msh} file format, version 1.0, the file is divided in two -sections, defining the nodes (@code{$NOD}-@code{$ENDNOD}) and the elements -(@code{$ELM}-@code{$ENDELM}) in the mesh: - -@example -$NOD -@var{number-of-nodes} -@var{node-number} @var{x-coord} @var{y-coord} @var{z-coord} -@dots{} -$ENDNOD -$ELM -@var{number-of-elements} -@var{elm-number} @var{elm-type} @var{reg-phys} @var{reg-elem} @var{number-of-nodes} @var{node-number-list} -@dots{} -$ENDELM -@end example - -@noindent -where -@table @code -@item @var{number-of-nodes} -is the number of nodes in the mesh. - -@item @var{node-number} -is the number (index) of the @var{n}-th node in the mesh; -@var{node-number} must be a postive (non-zero) integer. Note that the -@w{@var{node-number}s} do not necessarily have to form a dense nor an -ordered sequence. - -@item @var{x-coord} @var{y-coord} @var{z-coord} -are the floating point values giving the X, Y and Z coordinates of the -@var{n}-th node. - -@item @var{number-of-elements} -is the number of elements in the mesh. - -@item @var{elm-number} -is the number (index) of the @var{n}-th element in the mesh; -@var{elm-number} must be a postive (non-zero) integer. Note that the -@w{@var{elm-number}s} do not necessarily have to form a dense nor an -ordered sequence. - -@item @var{elm-type} -defines the geometrical type of the @var{n}-th element: -@table @code -@item 1 -2-node line. -@item 2 -3-node triangle. -@item 3 -4-node quadrangle. -@item 4 -4-node tetrahedron. -@item 5 -8-node hexahedron. -@item 6 -6-node prism. -@item 7 -5-node pyramid. -@item 8 -3-node second order line (2 nodes associated with the vertices and 1 -with the edge). -@item 9 -6-node second order triangle (3 nodes associated with the vertices and 3 -with the edges). -@item 10 -9-node second order quadrangle (4 nodes associated with the vertices, 4 -with the edges and 1 with the face). -@item 11 -10-node second order tetrahedron (4 nodes associated with the vertices -and 6 with the edges). -@item 12 -27-node second order hexahedron (8 nodes associated with the vertices, -12 with the edges, 6 with the faces and 1 with the volume). -@item 13 -18-node second order prism (6 nodes associated with the vertices, 9 with -the edges and 3 with the quadrangular faces). -@item 14 -14-node second order pyramid (5 nodes associated with the vertices, 8 -with the edges and 1 with the quadrangular face). -@item 15 -1-node point. -@item 16 -8-node second order quadrangle (4 nodes associated with the vertices and -4 with the edges). -@item 17 -20-node second order hexahedron (8 nodes associated with the vertices -and 12 with the edges). -@item 18 -15-node second order prism (6 nodes associated with the vertices and 9 -with the edges). -@item 19 -13-node second order pyramid (5 nodes associated with the vertices and 8 -with the edges). -@end table -See below for the ordering of the nodes. - -@item @var{reg-phys} -is the number of the physical entity to which the element belongs; -@var{reg-phys} must be a postive integer, or zero. If @var{reg-phys} is -equal to zero, the element is considered not to belong to any physical -entity. - -@item @var{reg-elem} -is the number of the elementary entity to which the element belongs; -@var{reg-elem} must be a postive (non-zero) integer. - -@item @var{number-of-nodes} -is the number of nodes for the @var{n}-th element. This is redundant, but -kept for backward compatibility. +@cindex MSH file -@item @var{node-number-list} -is the list of the @var{number-of-nodes} node numbers of the @var{n}-th -element. The ordering of the nodes is given in @ref{Gmsh node ordering}; for -second order elements, the first order nodes are given first, followed by -the nodes associated with the edges, followed by the nodes associated with -the quadrangular faces (if any), followed by the nodes associated with the -volume (if any). The ordering of these additional nodes follows the ordering -of the edges and quadrangular faces given in @ref{Gmsh node ordering}. -@end table - -@c ......................................................................... -@c Version 2.0 ASCII -@c ......................................................................... - -@node Version 2.0 ASCII, Version 2.0 Binary, Version 1.0, Gmsh mesh file formats -@subsection Version 2.0 ASCII +The MSH ASCII file format contains one mandatory section giving +information about the file (@code{$MeshFormat}), followed by several +optional sections defining the nodes (@code{$Nodes}), elements +(@code{$Elements}), region names (@code{$PhysicalName}) or +post-processing datasets (@code{$NodeData}, @code{$ElementData}, +@code{$ElememtNodeData}). Sections can be repeated in the same file, and +post-processing sections can be put into separate files (e.g. one file +per time step). -The version 2.0 of the @file{.msh} file format is Gmsh's new native mesh -file format. It is very similar to the old one (@pxref{Version 1.0}), -but is more general: it contains information about itself and allows to -associate an arbitrary number of integer tags with each element. Ialso -exists in both ASCII and binary form. - -The @file{.msh} file format, version 2.0, is divided in three main -sections, defining the file format -(@code{$MeshFormat}-@code{$EndMeshFormat}), the nodes -(@code{$Nodes}-@code{$EndNodes}) and the elements -(@code{$Elements}-@code{$EndElements}) in the mesh: +The format is defined as follows: @example $MeshFormat -2.0 @var{file-type} @var{data-size} +@var{version-number} @var{file-type} @var{data-size} $EndMeshFormat $Nodes @var{number-of-nodes} @@ -3026,11 +3003,35 @@ $Elements @var{elm-number} @var{elm-type} @var{number-of-tags} < @var{tag} > @dots{} @var{node-number-list} @dots{} $EndElements +$PhysicalNames +@var{number-of-names} +@var{phyical-number} "@var{physical-name}" +@dots{} +$EndPhysicalNames +$NodeData +"@var{view-name}" +@var{step} @var{time} @var{partition} @var{interpolation-id} @var{number-of-components} @var{number-of-nodes} +@var{node-number} @var{value} @dots{} +@dots{} +$EndNodeData +$ElementData +@var{step} @var{time} @var{partition} @var{interpolation-id} @var{number-of-components} @var{number-of-elements} +@var{elm-number} @var{value} @dots{} +@dots{} +$EndElementData +$ElementNodeData +@var{step} @var{time} @var{partition} @var{interpolation-id} @var{number-of-components} @var{number-of-elements} +@var{elm-number} @var{number-of-nodes-per-element} @var{value} @dots{} +@dots{} +$ElementEndNodeData @end example @noindent where @table @code +@item @var{version-number} +is a real number equal to 2.0 + @item @var{file-type} is an integer equal to 0 in the ASCII file format. @@ -3130,38 +3131,63 @@ integers, or zero. A zero tag is equivalent to no tag. @item @var{node-number-list} is the list of the node numbers of the @var{n}-th element. The ordering of -the nodes is given in @ref{Gmsh node ordering}; for second order elements, +the nodes is given in @ref{Node ordering}; for second order elements, the first order nodes are given first, followed by the nodes associated with the edges, followed by the nodes associated with the quadrangular faces (if any), followed by the nodes associated with the volume (if any). The ordering of these additional nodes follows the ordering of the edges and -quadrangular faces given in @ref{Gmsh node ordering}. -@end table +quadrangular faces given in @ref{Node ordering}. -Additional sections can be present in the file, which an external parser -can simply ignore. One such additional section -(@code{$PhysicalNames}-@code{$EndPhysicalNames}) associates names with -physical entity identification numbers: -@example -$PhysicalNames -@var{number-of-names} -@var{phyical-number} "@var{physical-name}" -$EndPhysicalNames -@end example +@item @var{view-name} +gives the name of the post-processing dataset -@c ......................................................................... -@c Version 2.0 BINARY -@c ......................................................................... +@item @var{step} +is an integer giving an index for the view (e.g. a time step number) + +@item @var{time} +is a real number associating some floating point to the step value + +@item @var{partition} +is an integer giving a partition index for the view data. If another +view is loaded with the same name, but a different partition index, then +their contents will be merged. + +@item @var{interpolation-id} +index of an interpolation scheme used to interpret the view values + +@item @var{number-of-components} +gives the number of components of the data in the view -@node Version 2.0 Binary, , Version 2.0 ASCII, Gmsh mesh file formats -@subsection Version 2.0 Binary +@item @var{number-of-nodes} +gives the number of nodes in a node-based view + +@item @var{number-of-elements} +gives the number of elements in an element-based view + +@item @var{number-of-nodes-per-elements} +gives the number of node values for an element in an element-based view + +@item @var{value} +is a real number giving the value associated with a node or an +element. For @code{NodeData} (respectively @code{ElementData}) views, +there are @var{number-of-components} values per node (resp. per +element). For @code{ElementNodeData} views, there are +@var{number-of-components} times @var{number-of-nodes-per-elements} +values per element. +@end table + +@c ------------------------------------------------------------------------- +@c MSH binary file format +@c ------------------------------------------------------------------------- + +@node MSH binary file format, Node ordering, MSH ASCII file format, File formats +@section MSH binary file format -The binary file format is similar to the ASCII format described in -@ref{Version 2.0 ASCII}: +The binary file format is similar to the ASCII format described above: @example $MeshFormat -2.0 @var{file-type} @var{data-size} +@var{version-number} @var{file-type} @var{data-size} @var{one-binary} $EndMeshFormat $Nodes @@ -3176,11 +3202,17 @@ $Elements @var{elements-binary} @dots{} $EndElements + +[ all other sections are identical to ASCII, except that @var{node-number}, + @var{elm-number}, @var{number-of-nodes} and @var{values} are written in binary ] @end example @noindent where @table @code +@item @var{version-number} +is a real number equal to 2.0. + @item @var{file-type} is an integer equal to 1. @@ -3254,204 +3286,311 @@ for(i = 0; i < number_of_triangles; i++)@{ @end example @end table -The same additional sections as in the ASCII format can be present in -the file. - @c ------------------------------------------------------------------------- -@c Gmsh post-processing file formats +@c Node ordering @c ------------------------------------------------------------------------- -@node Gmsh post-processing file formats, Gmsh node ordering, Gmsh mesh file formats, File formats -@section Gmsh post-processing file formats - -@cindex @file{.pos} file - -Gmsh can read and write data sets in three different file formats: the -``parsed'', ``ASCII'' and ``binary'' file formats. The parsed format is the -oldest and most flexible, but also the slowest to read/write. The ASCII and -binary formats are less flexible but allow for faster read/write operations, -which is useful for (very) large data sets. - -Gmsh can convert any format to any other, either in a script (cf. @code{Save -View} and @code{PostProcessing.Format} in @ref{Post-processing commands}, -and @ref{Post-processing options}, respectively) or in the graphical user -interface (using the `View->Save As' menu). - -@menu -* Parsed post-processing file format:: -* ASCII post-processing file format:: -* Binary post-processing file format:: -@end menu - -@c ......................................................................... -@c Parsed post-processing file format -@c ......................................................................... - -@node Parsed post-processing file format, ASCII post-processing file format, Gmsh post-processing file formats, Gmsh post-processing file formats -@subsection Parsed post-processing file format +@node Node ordering, Legacy formats, MSH binary file format, File formats +@section Node ordering -@cindex Post-processing, parsed file format -@cindex File format, post-processing, parsed -@cindex @file{.pos} file - -Gmsh's oldest post-processing format (``parsed'') is read by Gmsh's script -parser (see also @ref{Post-processing commands}). You can thus, for example, -embed parsed post-processing views directly into your geometrical -descriptions (see, e.g., @ref{t4.geo}). +@cindex Nodes, ordering +@cindex Edges, ordering +@cindex Faces, ordering -The parsed format is very powerful, since all the values are -@var{expressions}, and it can be easily generated ``on-the-fly'', as there -is no header containing @emph{a priori} information on the size of the data -set. Its syntax is also very permissive, which makes it ideal for testing -purposes. Its main disadvantage resides in the overhead introduced by the -parser, which makes loading a view in parsed format slower than loading a -view in ASCII or binary format. This is only a disadvantage for very large -data sets, though. +For all mesh and post-processing file formats, the reference elements +are defined as follows. For high-order elements, the ordering of the +edges/quad faces defines the ordering of high-order vertices associated +with edges/faces. -A post-processing view in parsed format is defined as follows (there can be -one or more views in the same file): +@c FIXME: changer la doc des faces pour les definir de maniere sensee +@c sans butterflies. @example @group -View "@var{string}" @{ - < TIME @{ @var{expression-list} @}; > - @var{type} ( @var{list-of-coords} ) @{ @var{list-of-values} @}; - @dots{} -@}; +Point: + v + | + | + -----1-----u + | + | @end group @end example -where the 47 object @w{@var{type}s} that can be displayed are: +@example +@group +Line: + edge 1: nodes 1 2 + v + | + | + --1-----2--u + | + | +@end group +@end example @example - @var{type} #@var{list-of-coords} #@var{list-of-values} --------------------------------------------------------------------- -Scalar point SP 3 1 * @var{nb-time-steps} -Vector point VP 3 3 * @var{nb-time-steps} -Tensor point TP 3 9 * @var{nb-time-steps} -Scalar line SL 6 2 * @var{nb-time-steps} -Vector line VL 6 6 * @var{nb-time-steps} -Tensor line TL 6 18 * @var{nb-time-steps} -Scalar triangle ST 9 3 * @var{nb-time-steps} -Vector triangle VT 9 9 * @var{nb-time-steps} -Tensor triangle TT 9 27 * @var{nb-time-steps} -Scalar quadrangle SQ 12 4 * @var{nb-time-steps} -Vector quadrangle VQ 12 12 * @var{nb-time-steps} -Tensor quadrangle TQ 12 36 * @var{nb-time-steps} -Scalar tetrahedron SS 12 4 * @var{nb-time-steps} -Vector tetrahedron VS 12 12 * @var{nb-time-steps} -Tensor tetrahedron TS 12 36 * @var{nb-time-steps} -Scalar hexahedron SH 24 8 * @var{nb-time-steps} -Vector hexahedron VH 24 24 * @var{nb-time-steps} -Tensor hexahedron TH 24 72 * @var{nb-time-steps} -Scalar prism SI 18 6 * @var{nb-time-steps} -Vector prism VI 18 18 * @var{nb-time-steps} -Tensor prism TI 18 54 * @var{nb-time-steps} -Scalar pyramid SY 15 5 * @var{nb-time-steps} -Vector pyramid VY 15 15 * @var{nb-time-steps} -Tensor pyramid TY 15 45 * @var{nb-time-steps} -Second order scalar line SL2 9 3 * @var{nb-time-steps} -Second order vector line VL2 9 9 * @var{nb-time-steps} -Second order tensor line TL2 9 27 * @var{nb-time-steps} -Second order scalar triangle ST2 18 6 * @var{nb-time-steps} -Second order vector triangle VT2 18 18 * @var{nb-time-steps} -Second order tensor triangle TT2 18 54 * @var{nb-time-steps} -Second order scalar quadrangle SQ2 27 9 * @var{nb-time-steps} -Second order vector quadrangle VQ2 27 27 * @var{nb-time-steps} -Second order tensor quadrangle TQ2 27 81 * @var{nb-time-steps} -Second order scalar tetrahedron SS2 30 10 * @var{nb-time-steps} -Second order vector tetrahedron VS2 30 30 * @var{nb-time-steps} -Second order tensor tetrahedron TS2 30 90 * @var{nb-time-steps} -Second order scalar hexahedron SH2 81 27 * @var{nb-time-steps} -Second order vector hexahedron VH2 81 81 * @var{nb-time-steps} -Second order tensor hexahedron TH2 81 243* @var{nb-time-steps} -Second order scalar prism SI2 54 18 * @var{nb-time-steps} -Second order vector prism VI2 54 54 * @var{nb-time-steps} -Second order tensor prism TI2 54 162* @var{nb-time-steps} -Second order scalar pyramid SY2 42 14 * @var{nb-time-steps} -Second order vector pyramid VY2 42 42 * @var{nb-time-steps} -Second order tensor pyramid TY2 42 126* @var{nb-time-steps} -2D text T2 3 arbitrary -3D text T3 4 arbitrary +@group +Triangle: + edge 1: nodes 1 2 + v 2: 2 3 + | 3: 3 1 + | + 3 + |\ + | \ + |__\___u + 1 2 +@end group @end example -The coordinates are given `by node'@footnote{Beware that this is different -from the ordering of the node coordinates in the ASCII and binary -post-processing file formats.}, i.e., +@example +@group +Quadrangle: + edge 1: nodes 1 2 quad. face 1: nodes 1 2 3 4 + v 2: 2 3 + | 3: 3 4 + 4--|--3 4: 4 1 + | | | + -----------u + | | | + 1--|--2 + | +@end group +@end example -@itemize @bullet -@item -@code{(@var{coord1}, @var{coord2}, @var{coord3})} for a point, -@item -@code{(@var{coord1-node1}, @var{coord2-node1}, @var{coord3-node1},}@* -@code{ @var{coord1-node2}, @var{coord2-node2}, @var{coord3-node2})} for a line, -@item -@code{(@var{coord1-node1}, @var{coord2-node1}, @var{coord3-node1},}@* -@code{ @var{coord1-node2}, @var{coord2-node2}, @var{coord3-node2},}@* -@code{ @var{coord1-node3}, @var{coord2-node3}, @var{coord3-node3})} for a triangle, -@item -etc. -@end itemize +@example +@group +Tetrahedron: + edge 1: nodes 1 2 + v 2: 2 3 + | 3: 3 1 + | 4: 4 1 + | 5: 4 3 + 3 6: 4 2 + |\ + | \ + |__\2_____u + 1\ / + \4 + \ + w +@end group +@end example -The ordering of the nodes is given in @ref{Gmsh node ordering}. For second -order elements, the first order nodes are given first, followed by the nodes -associated with the edges, followed by the nodes associated with the -quadrangular faces (if any), followed by the nodes associated with the -volume (if any). The ordering of these additional nodes follows the ordering -of the edges and quadrangular faces given in @ref{Gmsh node ordering}. +@example +@group +Hexahedron: + edge 1: nodes 1 2 quad. face 1: nodes 1 2 3 4 + v 2: 1 4 2: 1 2 5 6 + | 3: 1 5 3: 1 4 5 8 + | 4: 2 3 4: 2 3 6 7 + 4----|--3 5: 2 6 5: 3 4 7 8 + |\ | |\ 6: 3 4 6: 5 6 7 8 + | 8-------7 7: 3 7 + | | ----|---u 8: 4 8 + 1-|---\-2 | 9: 5 6 + \| \ \| 10: 5 8 + 5-----\-6 11: 6 7 + \ 12: 7 8 + w +@end group +@end example -The values are given by time step, by node and by component, i.e.: @example -@var{comp1-node1-time1}, @var{comp2-node1-time1}, @var{comp3-node1-time1}, -@var{comp1-node2-time1}, @var{comp2-node2-time1}, @var{comp3-node2-time1}, -@var{comp1-node3-time1}, @var{comp2-node3-time1}, @var{comp3-node3-time1}, -@var{comp1-node1-time2}, @var{comp2-node1-time2}, @var{comp3-node1-time2}, -@var{comp1-node2-time2}, @var{comp2-node2-time2}, @var{comp3-node2-time2}, -@var{comp1-node3-time2}, @var{comp2-node3-time2}, @var{comp3-node3-time2}, -@dots{} +@group +Prism: + edge 1: nodes 1 2 quad. face 1: nodes 1 2 4 5 + v 2: 1 3 2: 1 3 4 6 + 3 | 3: 1 4 3: 2 3 5 6 + |\| 4: 2 3 + | | 5: 2 5 + 1_|2 6: 3 6 + \| 6 7: 4 5 + |_|_\___u 8: 4 6 + \| \ 9: 5 6 + 4 __5 + \ + \ + w +@end group @end example -For the 2D text objects, the two first @w{@var{expression}s} in -@var{list-of-coords} give the X-Y position of the string in screen -coordinates, measured from the top-left corner of the window. If the first -(respectively second) @var{expression} is negative, the position is measured -from the right (respectively bottom) edge of the window. If the value of the -first (respectively second) @var{expression} is larger than 99999, the -string is centered horizontally (respectively vertically). If the third -@var{expression} is equal to zero, the text is aligned bottom-left and -displayed using the default font and size. Otherwise, the third -@var{expression} is converted into an integer whose eight lower bits give -the font size, whose eight next bits select the font (the index corresponds -to the position in the font menu in the GUI), and whose eight next bits -define the text alignment (0=bottom-left, 1=bottom-center, 2=bottom-right, -3=top-left, 4=top-center, 5=top-right, 6=center-left, 7=center-center, -8=center-right). +@example +@group +Pyramid: + edge 1: nodes 1 2 quad. face 1: nodes 1 2 3 4 + v 2 1 4 + | 3 1 5 + | 4 2 3 + 4---|---3 5 2 5 + | \ | /| 6 3 4 + | \ -/-|---u 7 3 5 + | / 5\ | 8 4 5 + 1/----\-2 + \ + \ + w +@end group +@end example -For the 3D text objects, the three first @w{@var{expression}s} in -@var{list-of-coords} give the XYZ position of the string in model (real -world) coordinates. The fourth @var{expression} has the same meaning as the -third @var{expression} in 2D text objects. +@c ------------------------------------------------------------------------- +@c Legacy formats +@c ------------------------------------------------------------------------- -For both 2D and 3D text objects, the @var{list-of-values} can contain an -arbitrary number of @w{@var{char-expression}s}. +@node Legacy formats, , Node ordering, File formats +@section Legacy formats -The optional @code{TIME} list can contain a list of expressions giving the -value of the time (or any other variable) for which an evolution was saved. +This section describes Gmsh's older native file formats. Future versions +of Gmsh will continue to support these formats, but we recommend that +you do not use them in new aplications. @c ......................................................................... -@c ASCII post-processing file format +@c MSH file format version 1.0 @c ......................................................................... -@node ASCII post-processing file format, Binary post-processing file format, Parsed post-processing file format, Gmsh post-processing file formats -@subsection ASCII post-processing file format +@menu +* MSH file format version 1.0:: +* POS ASCII file format:: +* POS binary file format:: +@end menu + +@node MSH file format version 1.0, POS ASCII file format, Legacy formats, Legacy formats +@subsection MSH file format version 1.0 + +The MSH file format version 1.0 is Gmsh's old native mesh file format, +now superseded by the format described in @ref{MSH ASCII file +format}. It is defined as follows: + +@example +$NOD +@var{number-of-nodes} +@var{node-number} @var{x-coord} @var{y-coord} @var{z-coord} +@dots{} +$ENDNOD +$ELM +@var{number-of-elements} +@var{elm-number} @var{elm-type} @var{reg-phys} @var{reg-elem} @var{number-of-nodes} @var{node-number-list} +@dots{} +$ENDELM +@end example + +@noindent +where +@table @code +@item @var{number-of-nodes} +is the number of nodes in the mesh. + +@item @var{node-number} +is the number (index) of the @var{n}-th node in the mesh; +@var{node-number} must be a postive (non-zero) integer. Note that the +@w{@var{node-number}s} do not necessarily have to form a dense nor an +ordered sequence. + +@item @var{x-coord} @var{y-coord} @var{z-coord} +are the floating point values giving the X, Y and Z coordinates of the +@var{n}-th node. + +@item @var{number-of-elements} +is the number of elements in the mesh. + +@item @var{elm-number} +is the number (index) of the @var{n}-th element in the mesh; +@var{elm-number} must be a postive (non-zero) integer. Note that the +@w{@var{elm-number}s} do not necessarily have to form a dense nor an +ordered sequence. + +@item @var{elm-type} +defines the geometrical type of the @var{n}-th element: +@table @code +@item 1 +2-node line. +@item 2 +3-node triangle. +@item 3 +4-node quadrangle. +@item 4 +4-node tetrahedron. +@item 5 +8-node hexahedron. +@item 6 +6-node prism. +@item 7 +5-node pyramid. +@item 8 +3-node second order line (2 nodes associated with the vertices and 1 +with the edge). +@item 9 +6-node second order triangle (3 nodes associated with the vertices and 3 +with the edges). +@item 10 +9-node second order quadrangle (4 nodes associated with the vertices, 4 +with the edges and 1 with the face). +@item 11 +10-node second order tetrahedron (4 nodes associated with the vertices +and 6 with the edges). +@item 12 +27-node second order hexahedron (8 nodes associated with the vertices, +12 with the edges, 6 with the faces and 1 with the volume). +@item 13 +18-node second order prism (6 nodes associated with the vertices, 9 with +the edges and 3 with the quadrangular faces). +@item 14 +14-node second order pyramid (5 nodes associated with the vertices, 8 +with the edges and 1 with the quadrangular face). +@item 15 +1-node point. +@item 16 +8-node second order quadrangle (4 nodes associated with the vertices and +4 with the edges). +@item 17 +20-node second order hexahedron (8 nodes associated with the vertices +and 12 with the edges). +@item 18 +15-node second order prism (6 nodes associated with the vertices and 9 +with the edges). +@item 19 +13-node second order pyramid (5 nodes associated with the vertices and 8 +with the edges). +@end table +See below for the ordering of the nodes. + +@item @var{reg-phys} +is the number of the physical entity to which the element belongs; +@var{reg-phys} must be a postive integer, or zero. If @var{reg-phys} is +equal to zero, the element is considered not to belong to any physical +entity. -@cindex Post-processing, ASCII file format -@cindex File format, post-processing, ASCII +@item @var{reg-elem} +is the number of the elementary entity to which the element belongs; +@var{reg-elem} must be a postive (non-zero) integer. + +@item @var{number-of-nodes} +is the number of nodes for the @var{n}-th element. This is redundant, but +kept for backward compatibility. + +@item @var{node-number-list} +is the list of the @var{number-of-nodes} node numbers of the @var{n}-th +element. The ordering of the nodes is given in @ref{Node ordering}; for +second order elements, the first order nodes are given first, followed +by the nodes associated with the edges, followed by the nodes associated +with the quadrangular faces (if any), followed by the nodes associated +with the volume (if any). The ordering of these additional nodes follows +the ordering of the edges and quadrangular faces given in @ref{Node +ordering}. +@end table -The ASCII post-processing file is divided in several sections: one format -section, enclosed between @code{$PostFormat}-@code{$EndPostFormat} tags, and -one or more post-processing views, enclosed between -@code{$View}-@code{$EndView} tags: +@c ......................................................................... +@c POS ASCII file format +@c ......................................................................... + +@node POS ASCII file format, POS binary file format, MSH file format version 1.0, Legacy formats +@subsection POS ASCII file format + +The POS ASCII file is Gmsh's old native pot-processing format, now +superseded by the format described in @ref{MSH ASCII file format}. It is +defined as follows: @example $PostFormat @@ -3568,12 +3707,13 @@ For example, @var{vector-triangle-value} is defined as: @dots{} @end example -The ordering of the nodes is given in @ref{Gmsh node ordering}. For second -order elements, the first order nodes are given first, followed by the nodes -associated with the edges, followed by the nodes associated with the -quadrangular faces (if any), followed by the nodes associated with the -volume (if any). The ordering of these additional nodes follows the ordering -of the edges and quadrangular faces given in @ref{Gmsh node ordering}. +The ordering of the nodes is given in @ref{Node ordering}. For second +order elements, the first order nodes are given first, followed by the +nodes associated with the edges, followed by the nodes associated with +the quadrangular faces (if any), followed by the nodes associated with +the volume (if any). The ordering of these additional nodes follows the +ordering of the edges and quadrangular faces given in @ref{Node +ordering}. @item @var{text2d} is a list of 4 double precision numbers: @@ -3615,17 +3755,14 @@ null `@code{\0}' character. @end table @c ......................................................................... -@c Binary post-processing file format +@c POS binary file format @c ......................................................................... -@node Binary post-processing file format, , ASCII post-processing file format, Gmsh post-processing file formats -@subsection Binary post-processing file format +@node POS binary file format, , POS ASCII file format, Legacy formats +@subsection POS binary file format -@cindex Post-processing, binary file format -@cindex File format, post-processing, binary - -The binary post-processing file format is the same as the ASCII file format -described in @ref{ASCII post-processing file format}, except that: +The POS binary file format is the same as the POS ASCII file format +described in @ref{POS ASCII file format}, except that: @enumerate @item @@ -3684,153 +3821,6 @@ precision numbers containing all the @var{scalar-point-value} lists, put one after each other in order to form a long array of doubles. The principle is the same for all other kinds of values. -@c ------------------------------------------------------------------------- -@c Gmsh node ordering -@c ------------------------------------------------------------------------- - -@node Gmsh node ordering, , Gmsh post-processing file formats, File formats -@section Gmsh node ordering - -@cindex Nodes, ordering -@cindex Edges, ordering -@cindex Faces, ordering - -For all mesh and post-processing file formats, the reference elements are -defined as follows: - -@c FIXME: changer la doc des faces pour les definir de maniere sensee -@c sans butterflies. - -@example -@group -Point: - v - | - | - -----1-----u - | - | -@end group -@end example - -@example -@group -Line: - edge 1: nodes 1 2 - v - | - | - --1-----2--u - | - | -@end group -@end example - -@example -@group -Triangle: - edge 1: nodes 1 2 - v 2: 2 3 - | 3: 3 1 - | - 3 - |\ - | \ - |__\___u - 1 2 -@end group -@end example - -@example -@group -Quadrangle: - edge 1: nodes 1 2 quad. face 1: nodes 1 2 3 4 - v 2: 2 3 - | 3: 3 4 - 4--|--3 4: 4 1 - | | | - -----------u - | | | - 1--|--2 - | -@end group -@end example - -@example -@group -Tetrahedron: - edge 1: nodes 1 2 - v 2: 2 3 - | 3: 3 1 - | 4: 4 1 - | 5: 4 3 - 3 6: 4 2 - |\ - | \ - |__\2_____u - 1\ / - \4 - \ - w -@end group -@end example - -@example -@group -Hexahedron: - edge 1: nodes 1 2 quad. face 1: nodes 1 2 3 4 - v 2: 1 4 2: 1 2 5 6 - | 3: 1 5 3: 1 4 5 8 - | 4: 2 3 4: 2 3 6 7 - 4----|--3 5: 2 6 5: 3 4 7 8 - |\ | |\ 6: 3 4 6: 5 6 7 8 - | 8-------7 7: 3 7 - | | ----|---u 8: 4 8 - 1-|---\-2 | 9: 5 6 - \| \ \| 10: 5 8 - 5-----\-6 11: 6 7 - \ 12: 7 8 - w -@end group -@end example - -@example -@group -Prism: - edge 1: nodes 1 2 quad. face 1: nodes 1 2 4 5 - v 2: 1 3 2: 1 3 4 6 - 3 | 3: 1 4 3: 2 3 5 6 - |\| 4: 2 3 - | | 5: 2 5 - 1_|2 6: 3 6 - \| 6 7: 4 5 - |_|_\___u 8: 4 6 - \| \ 9: 5 6 - 4 __5 - \ - \ - w -@end group -@end example - -@example -@group -Pyramid: - edge 1: nodes 1 2 quad. face 1: nodes 1 2 3 4 - v 2 1 4 - | 3 1 5 - | 4 2 3 - 4---|---3 5 2 5 - | \ | /| 6 3 4 - | \ -/-|---u 7 3 5 - | / 5\ | 8 4 5 - 1/----\-2 - \ - \ - w -@end group -@end example - @c ========================================================================= @c Programming notes @c ========================================================================= @@ -3922,7 +3912,7 @@ option panel (in @file{Fltk/Callbacks.cpp}). @c todo: @c Tools to check memory leaks @c * on mac: use GMALLOC - (gdb) set env DYLD_INSERT_LIBRARIES /usr/lib/libgmalloc.dylib +@c (gdb) set env DYLD_INSERT_LIBRARIES /usr/lib/libgmalloc.dylib @c * LIBNJAMD @c export LD_PRELOAD=libnjamd.so @c kill -USR1