From 70555699fdeda3f781f0e4d4d938c03eb3b00239 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Mar=C3=A9chal?= Date: Fri, 4 Mar 2022 16:18:53 +0100 Subject: [PATCH 01/38] Fixed a potential memory leak in the block read/write procedures --- sources/libmeshb7.c | 28 ++++++++++++++-------------- todolist.md | 16 +++++++++------- 2 files changed, 23 insertions(+), 21 deletions(-) diff --git a/sources/libmeshb7.c b/sources/libmeshb7.c index a808b4e..ebbb146 100644 --- a/sources/libmeshb7.c +++ b/sources/libmeshb7.c @@ -2,14 +2,14 @@ /*----------------------------------------------------------------------------*/ /* */ -/* LIBMESHB V7.62 */ +/* LIBMESHB V7.63 */ /* */ /*----------------------------------------------------------------------------*/ /* */ /* Description: handles .meshb file format I/O */ /* Author: Loic MARECHAL */ /* Creation date: dec 09 1999 */ -/* Last modification: jan 07 2022 */ +/* Last modification: mar 04 2022 */ /* */ /*----------------------------------------------------------------------------*/ @@ -1520,7 +1520,7 @@ int NAMF77(GmfGetBlock, gmfgetblock)( TYPF77(int64_t) MshIdx, #endif if( (kwd->typ != RegKwd) && (kwd->typ != SolKwd) ) - return(0); + longjmp(msh->err, -36); // Read the first data type to select between list and table mode typ = VALF77(va_arg(VarArg, TYPF77(int))); @@ -1664,10 +1664,10 @@ int NAMF77(GmfGetBlock, gmfgetblock)( TYPF77(int64_t) MshIdx, { // Allocate both front and back buffers if(!(BckBuf = malloc(BufSiz * LinSiz))) - return(0); + longjmp(msh->err, -37); if(!(FrtBuf = malloc(BufSiz * LinSiz))) - return(0); + longjmp(msh->err, -38); // Setup the ansynchonous parameters memset(&aio, 0, sizeof(struct aiocb)); @@ -1696,12 +1696,12 @@ int NAMF77(GmfGetBlock, gmfgetblock)( TYPF77(int64_t) MshIdx, if (err != 0) { printf (" Error at aio_error() : %s\n", strerror (err)); - exit(1); + longjmp(msh->err, -39); } if (ret != aio.aio_nbytes) { printf(" Error at aio_return()\n"); - exit(1); + longjmp(msh->err, -40); } // Increment the reading position @@ -1744,7 +1744,7 @@ int NAMF77(GmfGetBlock, gmfgetblock)( TYPF77(int64_t) MshIdx, printf("aio_offset = " INT64_T_FMT "\n",(int64_t)aio.aio_offset); printf("aio_nbytes = " INT64_T_FMT "\n",(int64_t)aio.aio_nbytes); printf("errno = %d\n",errno); - exit(1); + longjmp(msh->err, -41); } } @@ -1966,7 +1966,7 @@ int NAMF77(GmfSetBlock, gmfsetblock)( TYPF77(int64_t) MshIdx, #endif if( (kwd->typ != RegKwd) && (kwd->typ != SolKwd) ) - return(0); + longjmp(msh->err, -42); // Read the first data type to select between list and table mode typ = VALF77(va_arg(VarArg, TYPF77(int))); @@ -2115,10 +2115,10 @@ int NAMF77(GmfSetBlock, gmfsetblock)( TYPF77(int64_t) MshIdx, { // Allocate the front and back buffers if(!(BckBuf = malloc(BufSiz * LinSiz))) - return(0); + longjmp(msh->err, -43); if(!(FrtBuf = malloc(BufSiz * LinSiz))) - return(0); + longjmp(msh->err, -44); // Setup the asynchronous parameters memset(&aio, 0, sizeof(struct aiocb)); @@ -2152,7 +2152,7 @@ int NAMF77(GmfSetBlock, gmfsetblock)( TYPF77(int64_t) MshIdx, printf("aio_offset = " INT64_T_FMT "\n",(int64_t)aio.aio_offset); printf("aio_nbytes = " INT64_T_FMT "\n",(int64_t)aio.aio_nbytes); printf("errno = %d\n",errno); - exit(1); + longjmp(msh->err, -45); } } @@ -2267,12 +2267,12 @@ int NAMF77(GmfSetBlock, gmfsetblock)( TYPF77(int64_t) MshIdx, if (err != 0) { printf (" Error at aio_error() : %s\n", strerror (err)); - exit(1); + longjmp(msh->err, -46); } if (ret != aio.aio_nbytes) { printf(" Error at aio_return()\n"); - exit(1); + longjmp(msh->err, -47); } // Move the write position diff --git a/todolist.md b/todolist.md index 5a5305f..0a418b1 100644 --- a/todolist.md +++ b/todolist.md @@ -4,8 +4,8 @@ - Read and allocate the required ElementGID, then build the list of elements that do not belong to the local domain and return it to the caller. ### Distributed parallel write -- Open a mesh file in writing mode but only create the skeleton of the mesh structure to enable further concurrent write access. -- Open an existing mesh file in writing mode and enable concurrent block write thanks to the existing structure. +- Open a mesh file in write mode but only create the skeleton of the mesh structure to enable further concurrent write access. +- Open an existing mesh file in write mode and enable concurrent block writes, thanks to the existing file structure. ## STANDARD PRIORITY @@ -29,15 +29,17 @@ An easy one. ### Add IHOSol* + DHOSol* for each element kinds, -for example +For example: + "IHOSolAtVertices", "i", "ii" // ii = degree + index in DSol + "DHOSolAtVertices", "i", "hr" // High Order solution ### Topological operations --Add a helper to build the list of inner or surface triangles from tetrahedra --Add a helper to build the list of unique edges from tetrahedra --Add a helper to get the face neighborhood between tets and triangles --Add a helper to get an edge's shell of triangles or tets +- Add a helper to build the list of inner or surface triangles from tetrahedra +- Add a helper to build the list of unique edges from tetrahedra +- Add a helper to get the face neighborhood between tets and triangles +- Add a helper to get an edge's shell of triangles or tets ### Documentation From 4c44b88d849c761c2fd6f9fdc9149cf3cf0ba0aa Mon Sep 17 00:00:00 2001 From: Matthieu Maunoury Date: Wed, 24 Aug 2022 14:27:40 +0200 Subject: [PATCH 02/38] Add two keywords to handle P0 solutions for boundary polygons and polyhedra --- sources/libmeshb7.c | 2 ++ sources/libmeshb7.h | 2 ++ sources/libmeshb7.ins | 4 ++++ sources/libmeshb7_mod.f90 | 4 ++++ 4 files changed, 12 insertions(+) diff --git a/sources/libmeshb7.c b/sources/libmeshb7.c index a808b4e..53d9365 100644 --- a/sources/libmeshb7.c +++ b/sources/libmeshb7.c @@ -470,6 +470,8 @@ const char *GmfKwdFmt[ GmfMaxKwd + 1 ][3] = {"PyramidsGID", "i", "iii"}, {"PrismsGID", "i", "iii"}, {"HexahedraGID", "i", "iii"}, + {"SolAtBoundaryPolygons", "i", "sr"}, + {"SolAtPolyhedra", "i", "sr"}, }; #ifdef TRANSMESH diff --git a/sources/libmeshb7.h b/sources/libmeshb7.h index bd67928..45a90f5 100644 --- a/sources/libmeshb7.h +++ b/sources/libmeshb7.h @@ -268,6 +268,8 @@ enum GmfKwdCod GmfPyramidsGID, GmfPrismsGID, GmfHexahedraGID, + GmfSolAtBoundaryPolygons, + GmfSolAtPolyhedra, GmfLastKeyword }; diff --git a/sources/libmeshb7.ins b/sources/libmeshb7.ins index 0ee9a64..2497577 100644 --- a/sources/libmeshb7.ins +++ b/sources/libmeshb7.ins @@ -291,6 +291,8 @@ c Keywords list integer gmfreferencestrings integer gmfprisms9 integer gmfhexahedra12 + integer gmfsolatboundarypolygons + integer gmfsolatpolyhedra parameter (gmfmeshversionformatted=1) parameter (gmfdimension=3) @@ -492,3 +494,5 @@ c Keywords list parameter (gmfreferencestrings=199) parameter (gmfprisms9=200) parameter (gmfhexahedra12=201) + parameter (gmfsolatboundarypolygons=202) + parameter (gmfsolatpolyhedra=203) diff --git a/sources/libmeshb7_mod.f90 b/sources/libmeshb7_mod.f90 index 2dd263d..f980f78 100644 --- a/sources/libmeshb7_mod.f90 +++ b/sources/libmeshb7_mod.f90 @@ -296,6 +296,8 @@ module libmeshb7 integer(4) :: gmfreferencestrings integer(4) :: gmfprisms9 integer(4) :: gmfhexahedra12 + integer(4) :: gmfsolatboundarypolygons + integer(4) :: gmfsolatpolyhedra parameter (gmfmeshversionformatted=1) parameter (gmfdimension=3) @@ -497,6 +499,8 @@ module libmeshb7 parameter (gmfreferencestrings=199) parameter (gmfprisms9=200) parameter (gmfhexahedra12=201) + parameter (gmfsolatboundarypolygons=202) + parameter (gmfsolatpolyhedra=203) ! !> interface GmfSetHONodesOrdering_c ! interface From 89134f435de45d14938fb28b91dd95f7d0451300 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Mar=C3=A9chal?= Date: Fri, 30 Sep 2022 15:18:31 +0200 Subject: [PATCH 03/38] Minor corrections to the sample code in the readme.md --- README.md | 5 +++-- legacy_sources/v2/Makefile | 5 +++++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 6f63254..1343597 100644 --- a/README.md +++ b/README.md @@ -37,10 +37,11 @@ It may be used in C, C++, F77 and F90 programs (Fortran 77 and 90 APIs are provi Tested on *Linux*, *macOS*, and *Windows 7->10*. Reading a mesh file is fairly easy: +("triangles.meshb" should be in version 1 with single precision floating points numbers) ```C++ int64_t LibIdx; -int ver, dim, NmbVer, NmbTri, (*Nodes)[4], *Domains; +int i, ver, dim, NmbVer, NmbTri, (*Nodes)[4], *Domains; float (*Coords)[3]; // Open the mesh file for reading @@ -67,7 +68,7 @@ GmfGotoKwd( LibIdx, GmfTriangles ); // Read each line of triangle data into your own data structures for(i=0;i Date: Fri, 27 Jan 2023 15:25:00 +0100 Subject: [PATCH 04/38] Replaced all aio's off_t to size_t as Windows sets off_t size to 32 bits even in 64 bit mode --- README.md | 1 + sources/libmeshb7.c | 30 +++++++++++++++--------------- 2 files changed, 16 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index 1343597..8f9beff 100644 --- a/README.md +++ b/README.md @@ -37,6 +37,7 @@ It may be used in C, C++, F77 and F90 programs (Fortran 77 and 90 APIs are provi Tested on *Linux*, *macOS*, and *Windows 7->10*. Reading a mesh file is fairly easy: + ("triangles.meshb" should be in version 1 with single precision floating points numbers) ```C++ diff --git a/sources/libmeshb7.c b/sources/libmeshb7.c index 6394644..80cb2d2 100644 --- a/sources/libmeshb7.c +++ b/sources/libmeshb7.c @@ -2,14 +2,14 @@ /*----------------------------------------------------------------------------*/ /* */ -/* LIBMESHB V7.63 */ +/* LIBMESHB V7.64 */ /* */ /*----------------------------------------------------------------------------*/ /* */ /* Description: handles .meshb file format I/O */ /* Author: Loic MARECHAL */ /* Creation date: dec 09 1999 */ -/* Last modification: mar 04 2022 */ +/* Last modification: jan 13 2023 */ /* */ /*----------------------------------------------------------------------------*/ @@ -144,7 +144,7 @@ int my_aio_write ( struct aiocb *aiocbp){return(aio_write (aiocbp));} struct aiocb { FILE *aio_fildes; // File descriptor - off_t aio_offset; // File offset + size_t aio_offset; // File offset void *aio_buf; // Location of buffer size_t aio_nbytes; // Length of transfer int aio_lio_opcode; // Operation to be performed @@ -158,7 +158,7 @@ int my_aio_error(const struct aiocb *aiocbp) // Set the file position and read a block of data int my_aio_read(struct aiocb *aiocbp) { - if( (MYFSEEK(aiocbp->aio_fildes, (off_t)aiocbp->aio_offset, SEEK_SET) == 0) + if( (MYFSEEK(aiocbp->aio_fildes, (size_t)aiocbp->aio_offset, SEEK_SET) == 0) && (fread(aiocbp->aio_buf, 1, aiocbp->aio_nbytes, aiocbp->aio_fildes) == aiocbp->aio_nbytes) ) { @@ -180,7 +180,7 @@ size_t my_aio_return(struct aiocb *aiocbp) // Set the file position and write a block of data int my_aio_write(struct aiocb *aiocbp) { - if( (MYFSEEK(aiocbp->aio_fildes, (off_t)aiocbp->aio_offset, SEEK_SET) == 0) + if( (MYFSEEK(aiocbp->aio_fildes, (size_t)aiocbp->aio_offset, SEEK_SET) == 0) && (fwrite(aiocbp->aio_buf, 1, aiocbp->aio_nbytes, aiocbp->aio_fildes) == aiocbp->aio_nbytes) ) { @@ -1680,7 +1680,7 @@ int NAMF77(GmfGetBlock, gmfgetblock)( TYPF77(int64_t) MshIdx, #else aio.aio_fildes = msh->hdl; #endif - aio.aio_offset = (off_t)(GetFilPos(msh) + (FilBegIdx-1) * LinSiz); + aio.aio_offset = (size_t)(GetFilPos(msh) + (FilBegIdx-1) * LinSiz); NmbBlk = UsrNmbLin / BufSiz; @@ -1707,7 +1707,7 @@ int NAMF77(GmfGetBlock, gmfgetblock)( TYPF77(int64_t) MshIdx, } // Increment the reading position - aio.aio_offset += (off_t)aio.aio_nbytes; + aio.aio_offset += (size_t)aio.aio_nbytes; // and swap the buffers if(aio.aio_buf == BckBuf) @@ -2130,7 +2130,7 @@ int NAMF77(GmfSetBlock, gmfsetblock)( TYPF77(int64_t) MshIdx, #else aio.aio_fildes = msh->hdl; #endif - aio.aio_offset = (off_t)GetFilPos(msh); + aio.aio_offset = (size_t)GetFilPos(msh); NmbBlk = UsrNmbLin / BufSiz; @@ -2278,7 +2278,7 @@ int NAMF77(GmfSetBlock, gmfsetblock)( TYPF77(int64_t) MshIdx, } // Move the write position - aio.aio_offset += (off_t)aio.aio_nbytes; + aio.aio_offset += (size_t)aio.aio_nbytes; } // Swap the buffers @@ -2936,11 +2936,11 @@ static int SetFilPos(GmfMshSct *msh, int64_t pos) { #ifdef WITH_GMF_AIO if(msh->typ & Bin) - return((lseek(msh->FilDes, (off_t)pos, 0) != -1)); + return((lseek(msh->FilDes, (size_t)pos, 0) != -1)); else - return((MYFSEEK(msh->hdl, (off_t)pos, SEEK_SET) == 0)); + return((MYFSEEK(msh->hdl, (size_t)pos, SEEK_SET) == 0)); #else - return((MYFSEEK(msh->hdl, (off_t)pos, SEEK_SET) == 0)); + return((MYFSEEK(msh->hdl, (size_t)pos, SEEK_SET) == 0)); #endif } @@ -2975,7 +2975,7 @@ static int64_t GetFilSiz(GmfMshSct *msh) #ifdef WITH_GMF_AIO CurPos = lseek(msh->FilDes, 0, 1); EndPos = lseek(msh->FilDes, 0, 2); - lseek(msh->FilDes, (off_t)CurPos, 0); + lseek(msh->FilDes, (size_t)CurPos, 0); #else CurPos = MYFTELL(msh->hdl); @@ -2984,7 +2984,7 @@ static int64_t GetFilSiz(GmfMshSct *msh) EndPos = MYFTELL(msh->hdl); - if(MYFSEEK(msh->hdl, (off_t)CurPos, SEEK_SET) != 0) + if(MYFSEEK(msh->hdl, (size_t)CurPos, SEEK_SET) != 0) longjmp(msh->err, -33); #endif } @@ -2997,7 +2997,7 @@ static int64_t GetFilSiz(GmfMshSct *msh) EndPos = MYFTELL(msh->hdl); - if(MYFSEEK(msh->hdl, (off_t)CurPos, SEEK_SET) != 0) + if(MYFSEEK(msh->hdl, (size_t)CurPos, SEEK_SET) != 0) longjmp(msh->err, -35); } From 5d855d9a6e29725e4a71d20cded42c902fbcd5ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Mar=C3=A9chal?= Date: Fri, 24 Feb 2023 16:16:04 +0100 Subject: [PATCH 05/38] Debug: the solutions bock reading and writting is working. Changed: made a clearer distinction beetwen file solution kinds (GmfSca, GmfMat, etc.) and description of user's data (GmfFloat, GmfFloatVec + size, etc.) --- examples/test_libmeshb_sol.c | 71 ++++++++++++++++++------ sample_meshes/out.sol | 12 ++-- sources/libmeshb7.c | 104 ++++++++++++++++++++++++++--------- sources/libmeshb7.h | 48 ++++++++-------- 4 files changed, 161 insertions(+), 74 deletions(-) diff --git a/examples/test_libmeshb_sol.c b/examples/test_libmeshb_sol.c index fe69c07..5e85c9f 100644 --- a/examples/test_libmeshb_sol.c +++ b/examples/test_libmeshb_sol.c @@ -1,5 +1,5 @@ -// libMeshb 7.5 basic example: read a general purpose solution file +// libMeshb 7.66 basic example: read a general purpose solution file #include #include @@ -8,37 +8,72 @@ int main() { - int i, j, NmbSol, ver, dim, SolSiz, NmbTyp, TypTab[ GmfMaxTyp ]; - long long InpMsh; - double *SolTab; + int i, j, NmbSolLin, ver, dim, TotSolSiz, NmbSolTyp, SolTypTab[ GmfMaxTyp ]; + int DatTypTab[10], DatSizTab[10]; + int64_t MshIdx; + double *SolTab; + char *DatBegTab[10], *DatEndTab[10]; + char *TypStr[5] = {"", "GmfSca", "GmfVec", "GmfSymMat", "GmfMat"}; // Open the "out.sol" mesh file - if(!(InpMsh = GmfOpenMesh("../sample_meshes/out.sol", GmfRead, &ver, &dim))) + if(!(MshIdx = GmfOpenMesh("../sample_meshes/out.sol", GmfRead, &ver, &dim))) return(1); - printf("InpMsh: idx = %lld, version = %d, dimension = %d\n", InpMsh, ver, dim); + printf("MshIdx: idx = %lld, version = %d, dimension = %d\n", MshIdx, ver, dim); if(ver < 2) return(1); // Read the number vertices and associated solution size for memory allocation - NmbSol = (int)GmfStatKwd(InpMsh, GmfSolAtVertices, &NmbTyp, &SolSiz, TypTab); - printf("NmbSol = %d, NmbTyp = %d, SolSiz = %d\n", NmbSol, NmbTyp, SolSiz); - SolTab = malloc( (NmbSol+1) * SolSiz * sizeof(double)); - printf("SolTab: %p -> %p\n", SolTab, SolTab+(NmbSol+1) * SolSiz * sizeof(double)); + NmbSolLin = GmfStatKwd(MshIdx, GmfSolAtVertices, &NmbSolTyp, &TotSolSiz, SolTypTab); + printf("NmbSol = %d, NmbTyp = %d, SolSiz = %d\n", NmbSolLin, NmbSolTyp, TotSolSiz); + for(i=0;iSolTypSiz[ GmfSca ] = 1; + msh->SolTypSiz[ GmfVec ] = msh->dim; + msh->SolTypSiz[ GmfSymMat ] = msh->dim * (msh->dim - 1); + msh->SolTypSiz[ GmfMat ] = msh->dim * msh->dim; + return(MshIdx); } else if(msh->mod == GmfWrite) @@ -773,6 +779,12 @@ int64_t GmfOpenMesh(const char *FilNam, int mod, ...) RecWrd(msh, (unsigned char *)&msh->dim); } + // Preset solution entities sizes + msh->SolTypSiz[ GmfSca ] = 1; + msh->SolTypSiz[ GmfVec ] = msh->dim; + msh->SolTypSiz[ GmfSymMat ] = msh->dim * (msh->dim - 1); + msh->SolTypSiz[ GmfMat ] = msh->dim * msh->dim; + return(MshIdx); } else @@ -898,7 +910,7 @@ int GmfGotoKwd(int64_t MshIdx, int KwdCod) int GmfSetKwd(int64_t MshIdx, int KwdCod, int64_t NmbLin, ...) { - int i, *TypTab; + int i, typ, *TypTab; int64_t CurPos; va_list VarArg; GmfMshSct *msh = (GmfMshSct *)MshIdx; @@ -971,7 +983,10 @@ int GmfSetKwd(int64_t MshIdx, int KwdCod, int64_t NmbLin, ...) fprintf(msh->hdl, "%d ", kwd->NmbTyp); for(i=0;iNmbTyp;i++) - fprintf(msh->hdl, "%d ", kwd->TypTab[i]); + { + typ = kwd->TypTab[i] > GmfMat ? GmfSca : kwd->TypTab[i]; + fprintf(msh->hdl, "%d ", typ); + } fprintf(msh->hdl, "\n"); } @@ -1002,7 +1017,10 @@ int GmfSetKwd(int64_t MshIdx, int KwdCod, int64_t NmbLin, ...) RecWrd(msh, (unsigned char *)&kwd->NmbTyp); for(i=0;iNmbTyp;i++) - RecWrd(msh, (unsigned char *)&kwd->TypTab[i]); + { + typ = kwd->TypTab[i] > GmfMat ? GmfSca : kwd->TypTab[i]; + RecWrd(msh, (unsigned char *)&typ); + } if(!strcmp("hr", GmfKwdFmt[ KwdCod ][2])) { @@ -1439,10 +1457,10 @@ int NAMF77(GmfGetBlock, gmfgetblock)( TYPF77(int64_t) MshIdx, { char *UsrDat[ GmfMaxTyp ], *UsrBas[ GmfMaxTyp ], *FilPos, *EndUsrDat; char *FilBuf = NULL, *FrtBuf = NULL, *BckBuf = NULL, *BegUsrDat; - char *StrTab[5] = { "", "%f", "%lf", "%d", INT64_T_FMT }; + char *StrTab[4] = { "%f", "%lf", "%d", INT64_T_FMT }; char **BegTab, **EndTab; int i, j, k, *FilPtrI32, *UsrPtrI32, FilTyp[ GmfMaxTyp ]; - int UsrTyp[ GmfMaxTyp ], TypSiz[5] = {0,4,8,4,8}; + int UsrTyp[ GmfMaxTyp ], TypSiz[4] = {4,8,4,8}; int *IntMapTab = NULL, err, TotSiz = 0, IniFlg = 1, mod = GmfArgLst; int *TypTab, *SizTab, typ, VecCnt, ArgCnt = 0; float *FilPtrR32, *UsrPtrR32; @@ -1551,13 +1569,20 @@ int NAMF77(GmfGetBlock, gmfgetblock)( TYPF77(int64_t) MshIdx, else typ = VALF77(va_arg(VarArg, TYPF77(int))); - // In case the type is a vector. get its size and change the type - // for the corresponding scalar type if(typ >= GmfFloatVec && typ <= GmfLongVec) { + // In case the type is a vector, get its size and change + // the type for the corresponding scalar type typ -= 4; VecCnt = VALF77(va_arg(VarArg, TYPF77(int))); } + else if(typ >= GmfSca && typ <= GmfMat) + { + // In case it is a mathematical solution, expand it + // to the right size with the mesh file's own real kind + VecCnt = msh->SolTypSiz[ typ ]; + typ = (msh->ver == 1) ? GmfFloat : GmfDouble; + } else VecCnt = 1; @@ -1575,6 +1600,13 @@ int NAMF77(GmfGetBlock, gmfgetblock)( TYPF77(int64_t) MshIdx, typ -= 4; VecCnt = SizTab[ ArgCnt ]; } + else if(typ >= GmfSca && typ <= GmfMat) + { + // In case it is a mathematical solution, expand it + // to the right size with the mesh file's own real kind + VecCnt = msh->SolTypSiz[ typ ]; + typ = (msh->ver == 1) ? GmfFloat : GmfDouble; + } else VecCnt = 1; @@ -1584,7 +1616,10 @@ int NAMF77(GmfGetBlock, gmfgetblock)( TYPF77(int64_t) MshIdx, } if(UsrNmbLin > 1) - VecLen = (size_t)(EndUsrDat - BegUsrDat) / (UsrNmbLin - 1); + { + VecLen = (size_t)(EndUsrDat - BegUsrDat); + VecLen /= UsrNmbLin - 1; + } else VecLen = 0; @@ -1592,7 +1627,7 @@ int NAMF77(GmfGetBlock, gmfgetblock)( TYPF77(int64_t) MshIdx, for(i=0;ihdl, StrTab[ UsrTyp[j] ], UsrDat[j], msh->err); + safe_fscanf(msh->hdl, StrTab[ UsrTyp[j] - GmfFloat ], UsrDat[j], msh->err); } if(i >= FilBegIdx) @@ -1771,7 +1806,7 @@ int NAMF77(GmfGetBlock, gmfgetblock)( TYPF77(int64_t) MshIdx, for(j=0;jSolSiz;j++) { if(msh->cod != 1) - SwpWrd(FilPos, TypSiz[ FilTyp[j] ]); + SwpWrd(FilPos, TypSiz[ FilTyp[j] - GmfFloat ]); // Reorder HO nodes on the fly if(kwd->OrdTab && (j != kwd->SolSiz-1)) @@ -1847,7 +1882,7 @@ int NAMF77(GmfGetBlock, gmfgetblock)( TYPF77(int64_t) MshIdx, } } - FilPos += TypSiz[ FilTyp[j] ]; + FilPos += TypSiz[ FilTyp[j] - GmfFloat ]; } } @@ -1882,11 +1917,11 @@ int NAMF77(GmfSetBlock, gmfsetblock)( TYPF77(int64_t) MshIdx, void *prc, ... ) { char *UsrDat[ GmfMaxTyp ], *UsrBas[ GmfMaxTyp ]; - char *StrTab[5] = { "", "%.9g", "%.17g", "%d", "%lld" }, *FilPos; + char *StrTab[4] = {"%.9g", "%.17g", "%d", "%lld" }, *FilPos; char *FilBuf = NULL, *FrtBuf = NULL, *BckBuf = NULL; char **BegTab, **EndTab, *BegUsrDat, *EndUsrDat; int i, j, *FilPtrI32, *UsrPtrI32, FilTyp[ GmfMaxTyp ]; - int UsrTyp[ GmfMaxTyp ], TypSiz[5] = {0,4,8,4,8}; + int UsrTyp[ GmfMaxTyp ], TypSiz[4] = {4,8,4,8}; int err, *IntMapTab = NULL, typ, mod = GmfArgLst; int *TypTab, *SizTab, IniFlg = 1, TotSiz = 0, VecCnt, ArgCnt = 0; float *FilPtrR32, *UsrPtrR32; @@ -2004,6 +2039,13 @@ int NAMF77(GmfSetBlock, gmfsetblock)( TYPF77(int64_t) MshIdx, typ -= 4; VecCnt = VALF77(va_arg(VarArg, TYPF77(int))); } + else if(typ >= GmfSca && typ <= GmfMat) + { + // In case it is a mathematical solution, expand it + // to the right size with the mesh file's own real kind + VecCnt = msh->SolTypSiz[ typ ]; + typ = (msh->ver == 1) ? GmfFloat : GmfDouble; + } else VecCnt = 1; @@ -2021,6 +2063,13 @@ int NAMF77(GmfSetBlock, gmfsetblock)( TYPF77(int64_t) MshIdx, typ -= 4; VecCnt = SizTab[ ArgCnt ]; } + else if(typ >= GmfSca && typ <= GmfMat) + { + // In case it is a mathematical solution, expand it + // to the right size with the mesh file's own real kind + VecCnt = msh->SolTypSiz[ typ ]; + typ = (msh->ver == 1) ? GmfFloat : GmfDouble; + } else VecCnt = 1; @@ -2030,7 +2079,10 @@ int NAMF77(GmfSetBlock, gmfsetblock)( TYPF77(int64_t) MshIdx, } if(UsrNmbLin > 1) - VecLen = (size_t)(EndUsrDat - BegUsrDat) / (UsrNmbLin - 1); + { + VecLen = EndUsrDat - BegUsrDat; + VecLen /= UsrNmbLin - 1; + } else VecLen = 0; @@ -2038,7 +2090,7 @@ int NAMF77(GmfSetBlock, gmfsetblock)( TYPF77(int64_t) MshIdx, for(i=0;ihdl, StrTab[ UsrTyp[j] ], (double)*UsrPtrR32); + fprintf(msh->hdl, StrTab[ UsrTyp[j] - GmfFloat ], (double)*UsrPtrR32); } else if(UsrTyp[j] == GmfDouble) { UsrPtrR64 = (double *)UsrDat[j]; - fprintf(msh->hdl, StrTab[ UsrTyp[j] ], *UsrPtrR64); + fprintf(msh->hdl, StrTab[ UsrTyp[j] - GmfFloat ], *UsrPtrR64); } else if(UsrTyp[j] == GmfInt) { UsrPtrI32 = (int *)UsrDat[j]; - fprintf(msh->hdl, StrTab[ UsrTyp[j] ], *UsrPtrI32); + fprintf(msh->hdl, StrTab[ UsrTyp[j] - GmfFloat ], *UsrPtrI32); } else if(UsrTyp[j] == GmfLong) { UsrPtrI64 = (int64_t *)UsrDat[j]; - fprintf(msh->hdl, StrTab[ UsrTyp[j] ], *UsrPtrI64); + fprintf(msh->hdl, StrTab[ UsrTyp[j] - GmfFloat ], *UsrPtrI64); } if(j < kwd->SolSiz -1) @@ -2254,7 +2306,7 @@ int NAMF77(GmfSetBlock, gmfsetblock)( TYPF77(int64_t) MshIdx, } } - FilPos += TypSiz[ FilTyp[j] ]; + FilPos += TypSiz[ FilTyp[j] - GmfFloat ]; } } } diff --git a/sources/libmeshb7.h b/sources/libmeshb7.h index 45a90f5..ac9381a 100644 --- a/sources/libmeshb7.h +++ b/sources/libmeshb7.h @@ -2,14 +2,14 @@ /*----------------------------------------------------------------------------*/ /* */ -/* LIBMESHB V7.61 */ +/* LIBMESHB V7.66 */ /* */ /*----------------------------------------------------------------------------*/ /* */ /* Description: handle .meshb file format I/O */ /* Author: Loic MARECHAL */ /* Creation date: dec 09 1999 */ -/* Last modification: sep 27 2021 */ +/* Last modification: feb 24 2023 */ /* */ /*----------------------------------------------------------------------------*/ @@ -25,28 +25,28 @@ /* Defines */ /*----------------------------------------------------------------------------*/ -#define GmfStrSiz 1024 -#define GmfMaxTyp 1000 -#define GmfMaxKwd GmfLastKeyword - 1 -#define GmfMshVer 1 -#define GmfRead 1 -#define GmfWrite 2 -#define GmfSca 1 -#define GmfVec 2 -#define GmfSymMat 3 -#define GmfMat 4 -#define GmfFloat 1 -#define GmfDouble 2 -#define GmfInt 3 -#define GmfLong 4 -#define GmfFloatVec 5 -#define GmfDoubleVec 6 -#define GmfIntTab 7 -#define GmfIntVec 7 -#define GmfLongTab 8 -#define GmfLongVec 8 -#define GmfArgTab 100 -#define GmfArgLst 101 +#define GmfStrSiz 1024 +#define GmfMaxTyp 1000 +#define GmfMaxKwd GmfLastKeyword - 1 +#define GmfMshVer 1 +#define GmfRead 1 +#define GmfWrite 2 +#define GmfSca 1 +#define GmfVec 2 +#define GmfSymMat 3 +#define GmfMat 4 +#define GmfFloat 8 +#define GmfDouble 9 +#define GmfInt 10 +#define GmfLong 11 +#define GmfFloatVec 12 +#define GmfDoubleVec 13 +#define GmfIntTab 14 +#define GmfIntVec 14 +#define GmfLongTab 15 +#define GmfLongVec 15 +#define GmfArgTab 100 +#define GmfArgLst 101 enum GmfKwdCod { From a39eee209d71586ec804ff673924412bced168cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Mar=C3=A9chal?= Date: Tue, 5 Sep 2023 15:44:54 +0200 Subject: [PATCH 06/38] Restored the unsafe calls to fscanf because of some odd results with the safer fgets --- sources/libmeshb7.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/sources/libmeshb7.c b/sources/libmeshb7.c index 08c41cc..e72c7bf 100644 --- a/sources/libmeshb7.c +++ b/sources/libmeshb7.c @@ -2,14 +2,14 @@ /*----------------------------------------------------------------------------*/ /* */ -/* LIBMESHB V7.66 */ +/* LIBMESHB V7.67 */ /* */ /*----------------------------------------------------------------------------*/ /* */ /* Description: handles .meshb file format I/O */ /* Author: Loic MARECHAL */ /* Creation date: dec 09 1999 */ -/* Last modification: feb 24 2023 */ +/* Last modification: sep 05 2023 */ /* */ /*----------------------------------------------------------------------------*/ @@ -1107,8 +1107,9 @@ int NAMF77(GmfGetLin, gmfgetlin)(TYPF77(int64_t)MshIdx, TYPF77(int)KwdCod, ...) } else if(kwd->fmt[i] == 'c') { - safe_fgets( va_arg(VarArg, char *), - WrdSiz * FilStrSiz, msh->hdl, msh->err); + safe_fscanf(msh->hdl, "%s", va_arg(VarArg, char *), msh->err); + //safe_fgets( va_arg(VarArg, char *), + // WrdSiz * FilStrSiz, msh->hdl, msh->err); } } } @@ -1413,7 +1414,10 @@ int GmfCpyLin(int64_t InpIdx, int64_t OutIdx, int KwdCod) memset(s, 0, FilStrSiz * WrdSiz); if(InpMsh->typ & Asc) - safe_fgets(s, WrdSiz * FilStrSiz, InpMsh->hdl, InpMsh->err); + { + //safe_fgets(s, WrdSiz * FilStrSiz, InpMsh->hdl, InpMsh->err); + safe_fscanf(InpMsh->hdl, "%s", s, InpMsh->err); + } else #ifdef WITH_GMF_AIO read(InpMsh->FilDes, s, WrdSiz * FilStrSiz); From 45b3af90c6fc1bc3dfa8c4a674b1416459dcba5c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Mar=C3=A9chal?= Date: Thu, 16 Nov 2023 16:27:18 +0100 Subject: [PATCH 07/38] Added keywords for hybrid CAD mapping --- sources/libmeshb7.c | 12 ++++++++++-- sources/libmeshb7.h | 12 ++++++++++-- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/sources/libmeshb7.c b/sources/libmeshb7.c index e72c7bf..f914ba7 100644 --- a/sources/libmeshb7.c +++ b/sources/libmeshb7.c @@ -2,14 +2,14 @@ /*----------------------------------------------------------------------------*/ /* */ -/* LIBMESHB V7.67 */ +/* LIBMESHB V7.68 */ /* */ /*----------------------------------------------------------------------------*/ /* */ /* Description: handles .meshb file format I/O */ /* Author: Loic MARECHAL */ /* Creation date: dec 09 1999 */ -/* Last modification: sep 05 2023 */ +/* Last modification: nov 16 2023 */ /* */ /*----------------------------------------------------------------------------*/ @@ -472,6 +472,14 @@ const char *GmfKwdFmt[ GmfMaxKwd + 1 ][3] = {"HexahedraGID", "i", "iii"}, {"SolAtBoundaryPolygons", "i", "sr"}, {"SolAtPolyhedra", "i", "sr"}, + {"VertexOnGeometryNode", "i", "iiiiii"}, + {"VertexOnGeometryEdge", "i", "iiiiirdrii"}, + {"EdgeOnGeometryEdge", "i", "iiiiiii"}, + {"VertexOnGeometryFace", "i", "iiiiirrdrii"}, + {"EdgeOnGeometryFace", "i", "iiiiiii"}, + {"TriangleOnGeometryFace", "i", "iiiiiii"}, + {"QuadrialteralOnGeometryFace", "i", "iiiiiii"}, + {"MeshOnGeometry", "i", "iiiiiidrdrii"} }; #ifdef TRANSMESH diff --git a/sources/libmeshb7.h b/sources/libmeshb7.h index ac9381a..79b8219 100644 --- a/sources/libmeshb7.h +++ b/sources/libmeshb7.h @@ -2,14 +2,14 @@ /*----------------------------------------------------------------------------*/ /* */ -/* LIBMESHB V7.66 */ +/* LIBMESHB V7.68 */ /* */ /*----------------------------------------------------------------------------*/ /* */ /* Description: handle .meshb file format I/O */ /* Author: Loic MARECHAL */ /* Creation date: dec 09 1999 */ -/* Last modification: feb 24 2023 */ +/* Last modification: nov 16 2023 */ /* */ /*----------------------------------------------------------------------------*/ @@ -270,6 +270,14 @@ enum GmfKwdCod GmfHexahedraGID, GmfSolAtBoundaryPolygons, GmfSolAtPolyhedra, + GmfVerticesOnGeometryNodes, + GmfVerticesOnGeometryEdges, + GmfEdgesOnGeometryEdges, + GmfVerticesOnGeometryFaces, + GmfEdgesOnGeometryFaces, + GmfTrianglesOnGeometryFaces, + GmfQuadrialteralsOnGeometryFaces, + GmfMeshOnGeometry, GmfLastKeyword }; From eebf66d0b16c02cefa8ad7b55192cd66b058f61e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Mar=C3=A9chal?= Date: Fri, 5 Jan 2024 10:28:36 +0100 Subject: [PATCH 08/38] Corrected a bug that prevented ASCII files greater than 2GB from working. Minor updates to silent some warnings. There are still lots of warnings related to setjup() and clobbered data that need to be fixed. --- examples/test_libmeshb.f | 19 +++++++++++-------- sources/libmeshb7.c | 17 ++++++++--------- sources/libmeshb7.h | 9 +++++---- 3 files changed, 24 insertions(+), 21 deletions(-) diff --git a/examples/test_libmeshb.f b/examples/test_libmeshb.f index dba0cbf..adddea1 100644 --- a/examples/test_libmeshb.f +++ b/examples/test_libmeshb.f @@ -6,7 +6,7 @@ integer n parameter (n=4000) - integer i,NmbVer,NmbQad,ver,dim,res,RefTab(n),QadTab(5,n) + integer i,NmbVer,NmbQad,ver,dim,res,RefTab(n),QadTab(5,n),kwd integer*8 InpMsh, OutMsh real*8 VerTab(3,n) @@ -30,13 +30,6 @@ if(NmbQad.gt.n) STOP 'Too many quads' print*, 'input mesh : ',NmbVer,' vertices,',NmbQad,'quads' -c Read the vertices - res = gmfgotokwd(InpMsh, GmfVertices) - do i = 1, NmbVer - res = gmfgetlin(InpMsh, GmfVertices - +, VerTab(1,i), VerTab(2,i), VerTab(3,i), RefTab(i)) - end do - c Read the quads res = gmfgotokwd(InpMsh, GmfQuadrilaterals) do i = 1, NmbQad @@ -44,6 +37,16 @@ +, QadTab(1,i),QadTab(2,i),QadTab(3,i),QadTab(4,i),QadTab(5,i)) end do +c Read the vertices + kwd = GmfVertices + print*, 'InpMsh: ', InpMsh, 'kwd: ', kwd + res = gmfgotokwd(InpMsh, kwd) + do i = 1, NmbVer + VerTab(1,i) = -1 + res = gmfgetlin(InpMsh, kwd + +, VerTab(1,i), VerTab(2,i), VerTab(3,i), RefTab(i)) + end do + c Close the quadrilateral mesh res = gmfclosemesh(InpMsh) diff --git a/sources/libmeshb7.c b/sources/libmeshb7.c index f914ba7..5dde963 100644 --- a/sources/libmeshb7.c +++ b/sources/libmeshb7.c @@ -2,14 +2,14 @@ /*----------------------------------------------------------------------------*/ /* */ -/* LIBMESHB V7.68 */ +/* LIBMESHB V7.69 */ /* */ /*----------------------------------------------------------------------------*/ /* */ /* Description: handles .meshb file format I/O */ /* Author: Loic MARECHAL */ /* Creation date: dec 09 1999 */ -/* Last modification: nov 16 2023 */ +/* Last modification: jan 04 2024 */ /* */ /*----------------------------------------------------------------------------*/ @@ -1058,6 +1058,7 @@ int NAMF77(GmfGetLin, gmfgetlin)(TYPF77(int64_t)MshIdx, TYPF77(int)KwdCod, ...) float *FltSolTab, FltVal, *PtrFlt; double *DblSolTab, *PtrDbl; va_list VarArg; + GmfMshSct *msh = (GmfMshSct *) VALF77(MshIdx); KwdSct *kwd = &msh->KwdTab[ VALF77(KwdCod) ]; @@ -1095,8 +1096,8 @@ int NAMF77(GmfGetLin, gmfgetlin)(TYPF77(int64_t)MshIdx, TYPF77(int)KwdCod, ...) } else { - safe_fscanf(msh->hdl, "%lf", - va_arg(VarArg, double *), msh->err); + PtrDbl = va_arg(VarArg, double *); + safe_fscanf(msh->hdl, "%lf",PtrDbl, msh->err); } } else if(kwd->fmt[i] == 'i') @@ -1481,7 +1482,7 @@ int NAMF77(GmfGetBlock, gmfgetblock)( TYPF77(int64_t) MshIdx, int64_t *LngMapTab = NULL, OldIdx = 0, UsrNmbLin, VecLen; size_t FilBegIdx = VALF77(BegIdx), FilEndIdx = VALF77(EndIdx); void (*UsrPrc)(int64_t, int64_t, void *) = NULL; - size_t UsrLen[ GmfMaxTyp ], ret, LinSiz, b, NmbBlk; + size_t UsrLen[ GmfMaxTyp ], ret, LinSiz, b, l, NmbBlk; va_list VarArg; GmfMshSct *msh = (GmfMshSct *) VALF77(MshIdx); KwdSct *kwd = &msh->KwdTab[ VALF77(KwdCod) ]; @@ -1674,7 +1675,7 @@ int NAMF77(GmfGetBlock, gmfgetblock)( TYPF77(int64_t) MshIdx, { OldIdx = 1; - for(i=1;i<=FilEndIdx;i++) + for(l=1;l<=FilEndIdx;l++) { for(j=0;jSolSiz;j++) { @@ -1697,7 +1698,7 @@ int NAMF77(GmfGetBlock, gmfgetblock)( TYPF77(int64_t) MshIdx, safe_fscanf(msh->hdl, StrTab[ UsrTyp[j] - GmfFloat ], UsrDat[j], msh->err); } - if(i >= FilBegIdx) + if(l >= FilBegIdx) OldIdx++; // Call the user's preprocessing procedure @@ -2377,8 +2378,6 @@ int GmfSetHONodesOrdering(int64_t MshIdx, int KwdCod, int *BasTab, int *OrdTab) GmfMshSct *msh = (GmfMshSct *)MshIdx; KwdSct *kwd; - // printf("\n\tGmfSetHONodesOrdering 0\n"); - if( (KwdCod < 1) || (KwdCod > GmfMaxKwd) ) return(0); diff --git a/sources/libmeshb7.h b/sources/libmeshb7.h index 79b8219..9c9dd76 100644 --- a/sources/libmeshb7.h +++ b/sources/libmeshb7.h @@ -2,25 +2,26 @@ /*----------------------------------------------------------------------------*/ /* */ -/* LIBMESHB V7.68 */ +/* LIBMESHB V7.69 */ /* */ /*----------------------------------------------------------------------------*/ /* */ /* Description: handle .meshb file format I/O */ /* Author: Loic MARECHAL */ /* Creation date: dec 09 1999 */ -/* Last modification: nov 16 2023 */ +/* Last modification: jan 04 2024 */ /* */ /*----------------------------------------------------------------------------*/ // [Bruno] get PRINTF_INT64_MODIFIER // #include -#include - #ifndef LIBMESHB7_H #define LIBMESHB7_H +#include + + /*----------------------------------------------------------------------------*/ /* Defines */ /*----------------------------------------------------------------------------*/ From e7e7c4c62fa152210832f61452543448cedb3801 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Mar=C3=A9chal?= Date: Mon, 15 Jan 2024 15:09:37 +0100 Subject: [PATCH 09/38] Added CTests validation with 10 feature tests --- CMakeLists.txt | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 94b6e28..a7af25c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -11,6 +11,7 @@ project(libMeshb VERSION ${libMeshb_VERSION_MAJOR}.${libMeshb_VERSION_MINOR} LAN option(WITH_GMF_AIO "Use Unix low-level and asynchronous I/O for higher speed" OFF) option(WITH_GMF_CPACK "Enable cpack target to generate a zip file containing binaries" OFF) +option(WITH_GMF_CTEST "Enable ctest ti run basic validation tests" OFF) option(WITH_GMF_FORTRAN "Build the Fortran API" ON ) include (CheckLanguage) @@ -19,7 +20,7 @@ if(CMAKE_Fortran_COMPILER AND WITH_GMF_FORTRAN) enable_language(Fortran) set(CMAKE_Fortran_MODULE_DIRECTORY ${CMAKE_BINARY_DIR}/modules) if (CMAKE_Fortran_COMPILER_ID STREQUAL GNU) - set (CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -std=legacy") + set (CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -std=legacy -fno-backtrace") endif () endif() @@ -71,6 +72,12 @@ install (DIRECTORY sample_meshes DESTINATION share/libMeshb) # SET PACKAGE AND DEPLOYMENT VARIABLES ###################################### +if(WITH_GMF_CTEST) + enable_testing() + include_directories(${PROJECT_SOURCE_DIR}/testing) + add_subdirectory(testing) +endif() + if (WITH_GMF_CPACK) include (InstallRequiredSystemLibraries) set (CPACK_GENERATOR TXZ) @@ -112,6 +119,7 @@ install(FILES message("-- Build mode : " ${CMAKE_BUILD_TYPE}) message("-- cpack target enabled : " ${WITH_GMF_CPACK}) +message("-- ctest target enabled : " ${WITH_GMF_CTEST}) message("-- Asynchronous IO : " ${WITH_GMF_AIO}) message("-- Fortran API : " ${WITH_GMF_FORTRAN}) message("-- Install directory : " ${CMAKE_INSTALL_PREFIX}) From c99e564182e8118b9077ca4f8323cceeb7862fe8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Mar=C3=A9chal?= Date: Mon, 15 Jan 2024 16:09:25 +0100 Subject: [PATCH 10/38] Updated the libmeshb7.ins that was older and inconsistant with the C header and caused test_libmeshb_block_f77 to crash --- sources/libmeshb7.ins | 76 +++++++++++++++++++++++++++++++++++-------- 1 file changed, 62 insertions(+), 14 deletions(-) diff --git a/sources/libmeshb7.ins b/sources/libmeshb7.ins index 2497577..1d7a28c 100644 --- a/sources/libmeshb7.ins +++ b/sources/libmeshb7.ins @@ -2,14 +2,14 @@ c---------------------------------------------------------- c -c LIBMESH V 7.56 +c LIBMESH V 7.69 c c---------------------------------------------------------- c c Description: handles .meshb file format I/O c Author: Loic MARECHAL c Creation date: dec 08 2015 -c Last modification: nov 27 2020 +c Last modification: jan 15 2024 c c---------------------------------------------------------- @@ -76,16 +76,16 @@ c Parameters definition parameter (gmfvec=2) parameter (gmfsymmat=3) parameter (gmfmat=4) - parameter (gmffloat=1) - parameter (gmfdouble=2) - parameter (gmfint=3) - parameter (gmflong=4) - parameter (gmfinttab=7) - parameter (gmflongtab=8) - parameter (gmffloatvec=5) - parameter (gmfdoublevec=6) - parameter (gmfintvec=7) - parameter (gmflongvec=8) + parameter (gmffloat=8) + parameter (gmfdouble=9) + parameter (gmfint=10) + parameter (gmflong=11) + parameter (gmfinttab=14) + parameter (gmflongtab=15) + parameter (gmffloatvec=12) + parameter (gmfdoublevec=13) + parameter (gmfintvec=14) + parameter (gmflongvec=15) parameter (gmfargtab=100) parameter (gmfarglst=101) @@ -291,8 +291,32 @@ c Keywords list integer gmfreferencestrings integer gmfprisms9 integer gmfhexahedra12 + integer gmfquadrilaterals6 + integer gmfboundarypolygonheaders + integer gmfboundarypolygonvertices + integer gmfinnerpolygonheaders + integer gmfinnerpolygonvertices + integer gmfpolyhedraheaders + integer gmfpolyhedrafaces + integer gmfdomains + integer gmfverticesgid + integer gmfedgesgid + integer gmftrianglesgid + integer gmfquadrilateralsgid + integer gmftetrahedragid + integer gmfpyramidsgid + integer gmfprismsgid + integer gmfhexahedragid integer gmfsolatboundarypolygons integer gmfsolatpolyhedra + integer gmfverticesongeometrynodes + integer gmfverticesongeometryedges + integer gmfedgesongeometryedges + integer gmfverticesongeometryfaces + integer gmfedgesongeometryfaces + integer gmftrianglesongeometryfaces + integer gmfquadrialteralsongeometryfaces + integer gmfmeshongeometry parameter (gmfmeshversionformatted=1) parameter (gmfdimension=3) @@ -494,5 +518,29 @@ c Keywords list parameter (gmfreferencestrings=199) parameter (gmfprisms9=200) parameter (gmfhexahedra12=201) - parameter (gmfsolatboundarypolygons=202) - parameter (gmfsolatpolyhedra=203) + parameter (gmfquadrilaterals6=202) + parameter (gmfboundarypolygonheaders=203) + parameter (gmfboundarypolygonvertices=204) + parameter (gmfinnerpolygonheaders=205) + parameter (gmfinnerpolygonvertices=206) + parameter (gmfpolyhedraheaders=207) + parameter (gmfpolyhedrafaces=208) + parameter (gmfdomains=209) + parameter (gmfverticesgid=210) + parameter (gmfedgesgid=211) + parameter (gmftrianglesgid=212) + parameter (gmfquadrilateralsgid=213) + parameter (gmftetrahedragid=214) + parameter (gmfpyramidsgid=215) + parameter (gmfprismsgid=216) + parameter (gmfhexahedragid=217) + parameter (gmfsolatboundarypolygons=218) + parameter (gmfsolatpolyhedra=219) + parameter (gmfverticesongeometrynodes=220) + parameter (gmfverticesongeometryedges=221) + parameter (gmfedgesongeometryedges=222) + parameter (gmfverticesongeometryfaces=223) + parameter (gmfedgesongeometryfaces=224) + parameter (gmftrianglesongeometryfaces=225) + parameter (gmfquadrialteralsongeometryfaces=226) + parameter (gmfmeshongeometry=227) From 0b9be55d80b4b4ba57782816d3a054e1116d62da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Mar=C3=A9chal?= Date: Mon, 15 Jan 2024 16:16:36 +0100 Subject: [PATCH 11/38] Updated the F90 module to conform to the C header --- sources/libmeshb7.ins | 2 +- sources/libmeshb7_mod.f90 | 78 +++++++++++++++++++++++++++++++-------- 2 files changed, 64 insertions(+), 16 deletions(-) diff --git a/sources/libmeshb7.ins b/sources/libmeshb7.ins index 1d7a28c..1436fd9 100644 --- a/sources/libmeshb7.ins +++ b/sources/libmeshb7.ins @@ -69,7 +69,7 @@ c Parameters definition integer gmfarglst parameter (gmfmaxtyp=1000) - parameter (gmfmaxkwd=103) + parameter (gmfmaxkwd=227) parameter (gmfread=1) parameter (gmfwrite=2) parameter (gmfsca=1) diff --git a/sources/libmeshb7_mod.f90 b/sources/libmeshb7_mod.f90 index f980f78..2680eec 100644 --- a/sources/libmeshb7_mod.f90 +++ b/sources/libmeshb7_mod.f90 @@ -2,14 +2,14 @@ !---------------------------------------------------------- ! -! LIBMESH V 7.56 +! LIBMESH V 7.69 ! !---------------------------------------------------------- ! ! Description: handles .meshb file format I/O ! Author: Loic MARECHAL ! Creation date: dec 08 2015 -! Last modification: nov 27 2020 +! Last modification: jan 15 2024 ! !---------------------------------------------------------- @@ -74,23 +74,23 @@ module libmeshb7 integer(4) :: gmfarglst parameter (gmfmaxtyp=1000) - parameter (gmfmaxkwd=103) + parameter (gmfmaxkwd=207) parameter (gmfread=1) parameter (gmfwrite=2) parameter (gmfsca=1) parameter (gmfvec=2) parameter (gmfsymmat=3) parameter (gmfmat=4) - parameter (gmffloat=1) - parameter (gmfdouble=2) - parameter (gmfint=3) - parameter (gmflong=4) - parameter (gmfinttab=7) - parameter (gmflongtab=8) - parameter (gmffloatvec=5) - parameter (gmfdoublevec=6) - parameter (gmfintvec=7) - parameter (gmflongvec=8) + parameter (gmffloat=8) + parameter (gmfdouble=9) + parameter (gmfint=10) + parameter (gmflong=11) + parameter (gmfinttab=14) + parameter (gmflongtab=15) + parameter (gmffloatvec=12) + parameter (gmfdoublevec=13) + parameter (gmfintvec=14) + parameter (gmflongvec=15) parameter (gmfargtab=100) parameter (gmfarglst=101) @@ -296,8 +296,32 @@ module libmeshb7 integer(4) :: gmfreferencestrings integer(4) :: gmfprisms9 integer(4) :: gmfhexahedra12 + integer(4) :: gmfquadrilaterals6 + integer(4) :: gmfboundarypolygonheaders + integer(4) :: gmfboundarypolygonvertices + integer(4) :: gmfinnerpolygonheaders + integer(4) :: gmfinnerpolygonvertices + integer(4) :: gmfpolyhedraheaders + integer(4) :: gmfpolyhedrafaces + integer(4) :: gmfdomains + integer(4) :: gmfverticesgid + integer(4) :: gmfedgesgid + integer(4) :: gmftrianglesgid + integer(4) :: gmfquadrilateralsgid + integer(4) :: gmftetrahedragid + integer(4) :: gmfpyramidsgid + integer(4) :: gmfprismsgid + integer(4) :: gmfhexahedragid integer(4) :: gmfsolatboundarypolygons integer(4) :: gmfsolatpolyhedra + integer(4) :: gmfverticesongeometrynodes + integer(4) :: gmfverticesongeometryedges + integer(4) :: gmfedgesongeometryedges + integer(4) :: gmfverticesongeometryfaces + integer(4) :: gmfedgesongeometryfaces + integer(4) :: gmftrianglesongeometryfaces + integer(4) :: gmfquadrialteralsongeometryfaces + integer(4) :: gmfmeshongeometry parameter (gmfmeshversionformatted=1) parameter (gmfdimension=3) @@ -499,8 +523,32 @@ module libmeshb7 parameter (gmfreferencestrings=199) parameter (gmfprisms9=200) parameter (gmfhexahedra12=201) - parameter (gmfsolatboundarypolygons=202) - parameter (gmfsolatpolyhedra=203) + parameter (gmfquadrilaterals6=202) + parameter (gmfboundarypolygonheaders=203) + parameter (gmfboundarypolygonvertices=204) + parameter (gmfinnerpolygonheaders=205) + parameter (gmfinnerpolygonvertices=206) + parameter (gmfpolyhedraheaders=207) + parameter (gmfpolyhedrafaces=208) + parameter (gmfdomains=209) + parameter (gmfverticesgid=210) + parameter (gmfedgesgid=211) + parameter (gmftrianglesgid=212) + parameter (gmfquadrilateralsgid=213) + parameter (gmftetrahedragid=214) + parameter (gmfpyramidsgid=215) + parameter (gmfprismsgid=216) + parameter (gmfhexahedragid=217) + parameter (gmfsolatboundarypolygons=218) + parameter (gmfsolatpolyhedra=219) + parameter (gmfverticesongeometrynodes=220) + parameter (gmfverticesongeometryedges=221) + parameter (gmfedgesongeometryedges=222) + parameter (gmfverticesongeometryfaces=223) + parameter (gmfedgesongeometryfaces=224) + parameter (gmftrianglesongeometryfaces=225) + parameter (gmfquadrialteralsongeometryfaces=226) + parameter (gmfmeshongeometry=227) ! !> interface GmfSetHONodesOrdering_c ! interface From e13e41252a2595074dbe8d71138af05454d6eb41 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Mar=C3=A9chal?= Date: Mon, 12 Feb 2024 15:28:52 +0100 Subject: [PATCH 12/38] Rewrote the whole Fortran API: needs to be tested before merging with master --- CMakeLists.txt | 7 +- LICENSE.txt | 2 +- README.md | 4 +- copyright.txt | 2 +- examples/CMakeLists.txt | 10 +- examples/test_libmeshb.f | 44 +- examples/test_libmeshb_block.f | 106 +++-- examples/test_libmeshb_block_pipeline.f | 135 ------ sources/CMakeLists.txt | 27 +- sources/libmeshb7.c | 531 ++++++++---------------- sources/libmeshb7.h | 4 +- sources/libmeshb7.ins | 76 ++-- sources/libmeshb7_mod.f90 | 8 - whatsnew.md | 12 +- 14 files changed, 307 insertions(+), 661 deletions(-) delete mode 100644 examples/test_libmeshb_block_pipeline.f diff --git a/CMakeLists.txt b/CMakeLists.txt index a7af25c..ff2d1d5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -12,16 +12,12 @@ project(libMeshb VERSION ${libMeshb_VERSION_MAJOR}.${libMeshb_VERSION_MINOR} LAN option(WITH_GMF_AIO "Use Unix low-level and asynchronous I/O for higher speed" OFF) option(WITH_GMF_CPACK "Enable cpack target to generate a zip file containing binaries" OFF) option(WITH_GMF_CTEST "Enable ctest ti run basic validation tests" OFF) -option(WITH_GMF_FORTRAN "Build the Fortran API" ON ) include (CheckLanguage) check_language (Fortran) -if(CMAKE_Fortran_COMPILER AND WITH_GMF_FORTRAN) +if(CMAKE_Fortran_COMPILER) enable_language(Fortran) set(CMAKE_Fortran_MODULE_DIRECTORY ${CMAKE_BINARY_DIR}/modules) - if (CMAKE_Fortran_COMPILER_ID STREQUAL GNU) - set (CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -std=legacy -fno-backtrace") - endif () endif() if (NOT CMAKE_BUILD_TYPE) @@ -121,5 +117,4 @@ message("-- Build mode : " ${CMAKE_BUILD_TYPE}) message("-- cpack target enabled : " ${WITH_GMF_CPACK}) message("-- ctest target enabled : " ${WITH_GMF_CTEST}) message("-- Asynchronous IO : " ${WITH_GMF_AIO}) -message("-- Fortran API : " ${WITH_GMF_FORTRAN}) message("-- Install directory : " ${CMAKE_INSTALL_PREFIX}) diff --git a/LICENSE.txt b/LICENSE.txt index 6df08a8..97e0f51 100644 --- a/LICENSE.txt +++ b/LICENSE.txt @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2001-2022 Loïc Maréchal / INRIA +Copyright (c) 2001-2024 Loïc Maréchal / INRIA Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/README.md b/README.md index 8f9beff..0b5eed7 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) -## libMeshb version 7.62 +## libMeshb version 7.79 A library to handle the *.meshb file format. ## Overview @@ -33,7 +33,7 @@ Can call user's own pre and post processing routines in a separate thread while ## Usage The **libMeshb** library is written in *ANSI C*. It is made of a single C file and a header file to be compiled and linked alongside the calling program. -It may be used in C, C++, F77 and F90 programs (Fortran 77 and 90 APIs are provided). +It may be used in C and C++ programs (a partial Fortran77 APIs is provided). Tested on *Linux*, *macOS*, and *Windows 7->10*. Reading a mesh file is fairly easy: diff --git a/copyright.txt b/copyright.txt index 560ca26..d3ee61d 100644 --- a/copyright.txt +++ b/copyright.txt @@ -1,4 +1,4 @@ -All libMeshb code is Copyright 2001-2022 - by Loïc Maréchal / INRIA. +All libMeshb code is Copyright 2001-2024 - by Loïc Maréchal / INRIA. This program is a free software. You can redistribute it and/or modify it under the terms of the MIT License as published by the Open Source Initiative. diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 7b38774..c03da7d 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -37,16 +37,12 @@ install (TARGETS mesh2poly DESTINATION share/libMeshb/examples COMPONENT example ######################## -if (CMAKE_Fortran_COMPILER AND WITH_GMF_FORTRAN) +if (CMAKE_Fortran_COMPILER) add_executable(test_libmeshb_f77 test_libmeshb.f) - target_link_libraries(test_libmeshb_f77 Meshbf.7 ${AIO_LIBRARIES}) + target_link_libraries(test_libmeshb_f77 Meshb.7 ${AIO_LIBRARIES}) install (TARGETS test_libmeshb_f77 DESTINATION share/libMeshb/examples COMPONENT examples) add_executable(test_libmeshb_block_f77 test_libmeshb_block.f) - target_link_libraries(test_libmeshb_block_f77 Meshbf.7 ${AIO_LIBRARIES}) + target_link_libraries(test_libmeshb_block_f77 Meshb.7 ${AIO_LIBRARIES}) install (TARGETS test_libmeshb_block_f77 DESTINATION share/libMeshb/examples COMPONENT examples) - - add_executable(test_libmeshb_block_pipeline test_libmeshb_block_pipeline.f) - target_link_libraries(test_libmeshb_block_pipeline Meshbf.7 ${AIO_LIBRARIES}) - install (TARGETS test_libmeshb_block_pipeline DESTINATION share/libMeshb/examples COMPONENT examples) endif () diff --git a/examples/test_libmeshb.f b/examples/test_libmeshb.f index adddea1..4a0214e 100644 --- a/examples/test_libmeshb.f +++ b/examples/test_libmeshb.f @@ -1,5 +1,5 @@ -c libMeshb 7.2 basic example: +c libMeshb 7.79 basic example: c read a quad mesh, split it into triangles and write the result back include 'libmeshb7.ins' @@ -16,7 +16,7 @@ c -------------------------------------------- c Open the mesh file and check the version and dimension - InpMsh = gmfopenmesh('../sample_meshes/quad.mesh ', + InpMsh = gmfopenmeshf77('../sample_meshes/quad.mesh ', +GmfRead,ver,dim) print*, 'input mesh :', InpMsh,'version:',ver,'dim:',dim if(InpMsh.eq.0) STOP ' InpMsh = 0' @@ -24,60 +24,56 @@ if(dim.ne.3) STOP ' dimension <> 3' c Check memory bounds - NmbVer = gmfstatkwd(InpMsh, GmfVertices) + NmbVer = gmfstatkwdf77(InpMsh, GmfVertices) if(NmbVer.gt.n) STOP 'Too many vertices' - NmbQad = gmfstatkwd(InpMsh, GmfQuadrilaterals) + NmbQad = gmfstatkwdf77(InpMsh, GmfQuadrilaterals) if(NmbQad.gt.n) STOP 'Too many quads' print*, 'input mesh : ',NmbVer,' vertices,',NmbQad,'quads' c Read the quads - res = gmfgotokwd(InpMsh, GmfQuadrilaterals) + res = gmfgotokwdf77(InpMsh, GmfQuadrilaterals) do i = 1, NmbQad - res = gmfgetlin(InpMsh, GmfQuadrilaterals - +, QadTab(1,i),QadTab(2,i),QadTab(3,i),QadTab(4,i),QadTab(5,i)) + res =gmfgetquadrilateral(InpMsh,QadTab(1,i),QadTab(5,i)) end do c Read the vertices - kwd = GmfVertices - print*, 'InpMsh: ', InpMsh, 'kwd: ', kwd - res = gmfgotokwd(InpMsh, kwd) + res = gmfgotokwdf77(InpMsh, GmfVertices) do i = 1, NmbVer - VerTab(1,i) = -1 - res = gmfgetlin(InpMsh, kwd - +, VerTab(1,i), VerTab(2,i), VerTab(3,i), RefTab(i)) + res = gmfgetvertex(InpMsh, VerTab(1,i), RefTab(i)) end do c Close the quadrilateral mesh - res = gmfclosemesh(InpMsh) + res = gmfclosemeshf77(InpMsh) c ------------------------ c Create a triangular mesh c ------------------------ - OutMsh = gmfopenmesh('tri.mesh', GmfWrite, ver, dim) + OutMsh = gmfopenmeshf77('tri.mesh', GmfWrite, 2, 3) if(OutMsh.eq.0) STOP ' OutMsh = 0' + print*, 'output IDX: ',OutMsh c Set the number of vertices - res = gmfsetkwd(OutMsh, GmfVertices, NmbVer, 0 , 0) + res = gmfsetkwdf77(OutMsh, GmfVertices, NmbVer, 0 , 0) c Then write them down do i = 1, NmbVer - res = gmfsetlin(InpMsh, GmfVertices - +, VerTab(1,i), VerTab(2,i), VerTab(3,i), RefTab(i)) + res = gmfsetvertex(OutMsh, VerTab(1,i), RefTab(i)) end do c Write the triangles - res = gmfsetkwd(OutMsh, GmfTriangles, 2*NmbQad, 0, 0) + res = gmfsetkwdf77(OutMsh, GmfTriangles, 2*NmbQad, 0, 0) do i=1,NmbQad - res = gmfsetlin(InpMsh, GmfTriangles, - + QadTab(1,i),QadTab(2,i),QadTab(3,i),QadTab(5,i)) - res = gmfsetlin(InpMsh, GmfTriangles, - + QadTab(1,i),QadTab(3,i),QadTab(4,i),QadTab(5,i)) + res = gmfsettriangle(OutMsh,QadTab(1,i),QadTab(5,i)) +c Modify the quad to build the other triangle's diagonal + QadTab(2,i) = QadTab(3,i); + QadTab(3,i) = QadTab(4,i); + res = gmfsettriangle(OutMsh,QadTab(1,i),QadTab(5,i)) end do c Don't forget to close the file - res = gmfclosemesh(OutMsh) + res = gmfclosemeshf77(OutMsh) print*, 'output mesh: ',NmbVer,' vertices,', + 2*NmbQad,'triangles' diff --git a/examples/test_libmeshb_block.f b/examples/test_libmeshb_block.f index baa56da..5e0b933 100644 --- a/examples/test_libmeshb_block.f +++ b/examples/test_libmeshb_block.f @@ -1,16 +1,14 @@ -c libMeshb 7.5 example: transform a quadrilateral mesh into a triangular one -c using fast block transfer and pipelined post processing +c libMeshb 7.79 example: transform a quadrilateral mesh into a triangular one +c using fast block transfer include 'libmeshb7.ins' - external qad2tri - integer n parameter (n=4000) - integer i, ver, dim, res + integer i, ver, dim, res, NmbVer, NmbQad +, RefTab(n), TriTab(4,2*n), QadTab(5,n) - integer*8 InpMsh, OutMsh, NmbVer, NmbQad + integer*8 InpMsh, OutMsh real*8 VerTab(3,n) @@ -18,17 +16,17 @@ c Open the quadrilateral mesh file for reading c -------------------------------------------- - InpMsh = gmfopenmesh('../sample_meshes/quad.meshb' + InpMsh = gmfopenmeshf77('../sample_meshes/quad.meshb' +,GmfRead,ver,dim) if(InpMsh.eq.0) STOP ' InpMsh = 0' if(dim.ne.3) STOP ' dimension <> 3' c Check memory bounds - NmbVer = gmfstatkwd(InpMsh, GmfVertices) + NmbVer = gmfstatkwdf77(InpMsh, GmfVertices) if(NmbVer.gt.n) STOP 'Too many vertices' - NmbQad = gmfstatkwd(InpMsh, GmfQuadrilaterals) + NmbQad = gmfstatkwdf77(InpMsh, GmfQuadrilaterals) if(NmbQad.gt.n) STOP 'Too many quads' c Print some information on the open file @@ -40,78 +38,68 @@ c Read the vertices using a vector of 3 consecutive doubles c to store the coordinates - res = gmfgetblock(InpMsh,GmfVertices, - + 1_8, NmbVer, 0, %val(0), %val(0), - + GmfDoubleVec, 3, VerTab(1,1), VerTab(1,NmbVer), - + GmfInt, RefTab( 1), RefTab( NmbVer)) + res = gmfgetvertices(InpMsh, + + 1, NmbVer, 0, %val(0), + + VerTab(1,1), VerTab(1,NmbVer), + + RefTab( 1), RefTab( NmbVer)) c Read the quads using one single vector of 5 consecutive integers - res = gmfgetblock(InpMsh,GmfQuadrilaterals, - + 1_8, NmbQad, 0, %val(0), %val(0), - + GmfIntVec, 5, QadTab(1,1), QadTab(1,NmbQad)) + res = gmfgetquadrilaterals(InpMsh, + + 1, NmbQad, 0, %val(0), + + QadTab(1,1), QadTab(1,NmbQad), + + QadTab(5,1), QadTab(5,NmbQad)) c Close the quadrilateral mesh - res = gmfclosemesh(InpMsh) + res = gmfclosemeshf77(InpMsh) + + +c ------------------------------------------- +c Convert the quad mesh into a triangular one +c ------------------------------------------- + + do i = 1,2*NmbQad + if(mod(i,2) .EQ. 1) then + TriTab(1,i) = QadTab(1,(i+1)/2) + TriTab(2,i) = QadTab(2,(i+1)/2) + TriTab(3,i) = QadTab(3,(i+1)/2) + TriTab(4,i) = QadTab(5,(i+1)/2) + else + TriTab(1,i) = QadTab(1,(i+1)/2) + TriTab(2,i) = QadTab(3,(i+1)/2) + TriTab(3,i) = QadTab(4,(i+1)/2) + TriTab(4,i) = QadTab(5,(i+1)/2) + endif + end do c ----------------------- c Write a triangular mesh c ----------------------- - OutMsh = gmfopenmesh('tri.meshb', GmfWrite, ver, dim) + OutMsh = gmfopenmeshf77('tri.meshb', GmfWrite, ver, dim) if(OutMsh.eq.0) STOP ' OutMsh = 0' c Set the number of vertices - res = gmfsetkwd(OutMsh, GmfVertices, NmbVer, 0, 0) + res = gmfsetkwdf77(OutMsh, GmfVertices, NmbVer, 0, 0) c Write them down using separate pointers for each scalar entry - res = gmfsetblock(OutMsh,GmfVertices, - + 1_8, NmbVer, 0, %val(0), %val(0), - + GmfDouble, VerTab(1,1), VerTab(1,NmbVer), - + GmfDouble, VerTab(2,1), VerTab(2,NmbVer), - + GmfDouble, VerTab(3,1), VerTab(3,NmbVer), - + GmfInt, RefTab(1), RefTab(NmbVer)) + res = gmfsetvertices(OutMsh, + + 1, NmbVer, 0, %val(0), + + VerTab(1,1), VerTab(1,NmbVer), + + RefTab(1), RefTab(NmbVer)) c Write the triangles using 4 independant set of arguments c for each scalar entry: node1, node2, node3 and reference - res = gmfsetkwd(OutMsh, GmfTriangles, 2*NmbQad, 0, 0) - res = gmfsetblock(OutMsh, GmfTriangles, - + 1_8, 2*NmbQad, 0, %val(0), - + qad2tri, 2, QadTab, TriTab, - + GmfInt, TriTab(1,1), TriTab(1,2*NmbQad), - + GmfInt, TriTab(2,1), TriTab(2,2*NmbQad), - + GmfInt, TriTab(3,1), TriTab(3,2*NmbQad), - + GmfInt, TriTab(4,1), TriTab(4,2*NmbQad)) + res = gmfsetkwdf77(OutMsh, GmfTriangles, 2*NmbQad, 0, 0) + res = gmfsettriangles(OutMsh, + + 1, 2*NmbQad, 0, %val(0), + + TriTab(1,1), TriTab(1,2*NmbQad), + + TriTab(4,1), TriTab(4,2*NmbQad)) c Don't forget to close the file - res = gmfclosemesh(OutMsh) + res = gmfclosemeshf77(OutMsh) print*, 'output mesh :',NmbVer,' vertices,', + 2*NmbQad,'triangles' end - - -c A subroutine that reads quads ans splits them into triangles -c it is executed concurently with the block writing - subroutine qad2tri(BegIdx,EndIdx,QadTab,TriTab) - - integer*8 i,BegIdx,EndIdx - integer TriTab(4,*),QadTab(5,*) - - do i = BegIdx,EndIdx - if(mod(i,2) .EQ. 1) then - TriTab(1,i) = QadTab(1,(i+1)/2) - TriTab(2,i) = QadTab(2,(i+1)/2) - TriTab(3,i) = QadTab(3,(i+1)/2) - TriTab(4,i) = QadTab(5,(i+1)/2) - else - TriTab(1,i) = QadTab(1,(i+1)/2) - TriTab(2,i) = QadTab(3,(i+1)/2) - TriTab(3,i) = QadTab(4,(i+1)/2) - TriTab(4,i) = QadTab(5,(i+1)/2) - endif - end do - - return - end diff --git a/examples/test_libmeshb_block_pipeline.f b/examples/test_libmeshb_block_pipeline.f deleted file mode 100644 index e54a85c..0000000 --- a/examples/test_libmeshb_block_pipeline.f +++ /dev/null @@ -1,135 +0,0 @@ - -c libmeshb example: transform a quadrilateral mesh into a triangular one -c using fast block transfer and pipelined post processing - - include 'libmeshb7.ins' - - external qad2tri, movver - - integer n - parameter (n=4000) - integer i, ver, dim, res - +, RefTab(n), TriTab(4,2*n), QadTab(5,n) - integer*8 NmbVer, NmbQad, InpMsh, OutMsh - real*8 VerTab(3,n) - - -c -------------------------------------------- -c Open the quadrilateral mesh file for reading -c -------------------------------------------- - - InpMsh = gmfopenmesh('../sample_meshes/quad.meshb' - +,GmfRead,ver,dim) - print*, 'input mesh :', InpMsh,'version :',ver,'dim :',dim - - if(InpMsh.eq.0) STOP ' InpMsh = 0' - if(dim.ne.3) STOP ' dimension <> 3' - -c Check memory bounds - NmbVer = gmfstatkwd(InpMsh, GmfVertices) - if(NmbVer.gt.n) STOP 'Too many vertices' - - i = gmfstatkwd(InpMsh, GmfSolAtQuadrilaterals) - print*, i,'GmfSolAtQuadrilaterals' - - NmbQad = gmfstatkwd(InpMsh, GmfQuadrilaterals) - if(NmbQad.gt.n) STOP 'Too many quads' - - print*, 'input mesh : ',NmbVer,' vertices,',NmbQad,'quads' - -c Read the vertices - res = gmfgetblock(InpMsh, GmfVertices, 1_8, NmbVer, - + 0, %val(0), movver, 1, VerTab, - + GmfDouble, VerTab(1,1), VerTab(1,2), - + GmfDouble, VerTab(2,1), VerTab(2,2), - + GmfDouble, VerTab(3,1), VerTab(3,2), - + GmfInt, RefTab(1), RefTab(2)) - -c Read the quads - res = gmfgetblock(InpMsh, GmfQuadrilaterals, 1_8, NmbQad, - + 0, %val(0), %val(0), - + GmfInt, QadTab(1,1), QadTab(1,2), - + GmfInt, QadTab(2,1), QadTab(2,2), - + GmfInt, QadTab(3,1), QadTab(3,2), - + GmfInt, QadTab(4,1), QadTab(4,2), - + GmfInt, QadTab(5,1), QadTab(5,2)) - -c Close the quadrilateral mesh - res = gmfclosemesh(InpMsh) - print*, QadTab(1,1),QadTab(2,1),QadTab(3,1),QadTab(4,1) - - -c ------------------------ -c Create a triangular mesh -c ------------------------ - - OutMsh = gmfopenmesh('tri.meshb', GmfWrite, ver, dim) - if(OutMsh.eq.0) STOP ' OutMsh = 0' - -c Set the number of vertices - res = gmfsetkwd(OutMsh, GmfVertices, NmbVer, 0 , 0) - -c Then write them down - res = gmfsetblock(OutMsh, GmfVertices, 1_8, NmbVer, - + 0, %val(0) ,%val(0), - + GmfDouble, VerTab(1,1), VerTab(1,2), - + GmfDouble, VerTab(2,1), VerTab(2,2), - + GmfDouble, VerTab(3,1), VerTab(3,2), - + GmfInt, RefTab(1), RefTab(2)) - -c Write the triangles - res = gmfsetkwd(OutMsh, GmfTriangles, 2*NmbQad, 0, 0) - res = gmfsetblock(OutMsh, GmfTriangles, 1_8, 2*NmbQad, - + 0,%val(0), - + qad2tri, 2, QadTab, TriTab, - + GmfInt, TriTab(1,1), TriTab(1,2), - + GmfInt, TriTab(2,1), TriTab(2,2), - + GmfInt, TriTab(3,1), TriTab(3,2), - + GmfInt, TriTab(4,1), TriTab(4,2)) - -c Don't forget to close the file - res = gmfclosemesh(OutMsh) - - print*, 'output mesh : ',NmbVer,' vertices,', - + 2*NmbQad,'triangles' - - end - - - - subroutine qad2tri(BegIdx,EndIdx,QadTab,TriTab) - - integer*8 i,BegIdx,EndIdx - integer TriTab(4,*),QadTab(5,*) - print*, 'beg : ',BegIdx, 'end : ', EndIdx - - do i = BegIdx,EndIdx - if(mod(i,2) .EQ. 1) then - TriTab(1,i) = QadTab(1,i/2) - TriTab(2,i) = QadTab(2,i/2) - TriTab(3,i) = QadTab(3,i/2) - TriTab(4,i) = QadTab(5,i/2) - else - TriTab(1,i) = QadTab(1,i/2) - TriTab(2,i) = QadTab(3,i/2) - TriTab(3,i) = QadTab(4,i/2) - TriTab(4,i) = QadTab(5,i/2) - endif - end do - - return - end - - - subroutine movver(BegIdx,EndIdx,VerTab) - - integer*8 i,BegIdx,EndIdx - real*8 VerTab(3,*) - print*, 'beg : ',BegIdx, 'end : ', EndIdx - - do i = BegIdx,EndIdx - VerTab(1,i) = VerTab(1,i)*2 - end do - - return - end diff --git a/sources/CMakeLists.txt b/sources/CMakeLists.txt index ed2e4c8..381299c 100644 --- a/sources/CMakeLists.txt +++ b/sources/CMakeLists.txt @@ -4,7 +4,7 @@ ########################## add_library(Meshb.7 libmeshb7.c ../utilities/libmeshb7_helpers.c) -install (FILES libmeshb7.h ../utilities/libmeshb7_helpers.h DESTINATION include COMPONENT headers) +install (FILES libmeshb7.h libmeshb7.ins ../utilities/libmeshb7_helpers.h DESTINATION include COMPONENT headers) target_include_directories( Meshb.7 PUBLIC $ $) @@ -14,28 +14,3 @@ install (EXPORT meshb-target NAMESPACE ${PROJECT_NAME}:: install (TARGETS Meshb.7 EXPORT libMeshb-target DESTINATION lib COMPONENT libraries) install (EXPORT libMeshb-target DESTINATION lib/cmake/${PROJECT_NAME}) export (PACKAGE libMeshb) - - -#################################### -# BUILD THE LIBRARY WITH FORTRAN API -#################################### - -if (CMAKE_Fortran_COMPILER AND WITH_GMF_FORTRAN) - file(GLOB_RECURSE SOURCES *.[chfF] *.[fF]90) - add_library(Meshbf.7 STATIC ${SOURCES}) - set_target_properties(Meshbf.7 PROPERTIES COMPILE_FLAGS "-DF77API") - target_include_directories(Meshbf.7 - INTERFACE ${CMAKE_CURRENT_BINARY_DIR} - PRIVATE ${CMAKE_CURRENT_BINARY_DIR} - PRIVATE ${CMAKE_BINARY_DIR} - PUBLIC ${CMAKE_SOURCE_DIR} ) - - install(FILES libmeshb7.ins DESTINATION include) - - install(TARGETS Meshbf.7 - RUNTIME DESTINATION bin - LIBRARY DESTINATION lib - PUBLIC_HEADER DESTINATION include - ARCHIVE DESTINATION lib) - -endif () diff --git a/sources/libmeshb7.c b/sources/libmeshb7.c index 5dde963..6645049 100644 --- a/sources/libmeshb7.c +++ b/sources/libmeshb7.c @@ -2,14 +2,14 @@ /*----------------------------------------------------------------------------*/ /* */ -/* LIBMESHB V7.69 */ +/* LIBMESHB V7.79 */ /* */ /*----------------------------------------------------------------------------*/ /* */ /* Description: handles .meshb file format I/O */ /* Author: Loic MARECHAL */ /* Creation date: dec 09 1999 */ -/* Last modification: jan 04 2024 */ +/* Last modification: feb 08 2024 */ /* */ /*----------------------------------------------------------------------------*/ @@ -21,28 +21,11 @@ // Silent Visual Studio warnings on string functions #define _CRT_SECURE_NO_WARNINGS -#ifdef F77API - // Add a final underscore to Fortran procedure names #ifdef F77_NO_UNDER_SCORE -#define NAMF77(c,f) f -#define APIF77(x) x +#define APIF77(x) x #else -#define NAMF77(c,f) f ## _ -#define APIF77(x) x ## _ -#endif - -// Pass parameters as pointers in Fortran -#define VALF77(v) *v -#define TYPF77(t) t* - -#else - -// Pass parameters as values in C -#define NAMF77(c,f) c -#define VALF77(v) v -#define TYPF77(t) t - +#define APIF77(x) x ## _ #endif @@ -505,9 +488,6 @@ static void SwpWrd (char *, int); static int SetFilPos(GmfMshSct *, int64_t); static int64_t GetFilPos(GmfMshSct *msh); static int64_t GetFilSiz(GmfMshSct *); -#ifdef F77API -static void CalF77Prc(int64_t, int64_t, void *, int, void **); -#endif /*----------------------------------------------------------------------------*/ @@ -1052,17 +1032,17 @@ int GmfSetKwd(int64_t MshIdx, int KwdCod, int64_t NmbLin, ...) /* Read a full line from the current kwd */ /*----------------------------------------------------------------------------*/ -int NAMF77(GmfGetLin, gmfgetlin)(TYPF77(int64_t)MshIdx, TYPF77(int)KwdCod, ...) +int GmfGetLin(int64_t MshIdx, int KwdCod, ...) { int i, err; float *FltSolTab, FltVal, *PtrFlt; double *DblSolTab, *PtrDbl; va_list VarArg; - GmfMshSct *msh = (GmfMshSct *) VALF77(MshIdx); - KwdSct *kwd = &msh->KwdTab[ VALF77(KwdCod) ]; + GmfMshSct *msh = (GmfMshSct *)MshIdx; + KwdSct *kwd = &msh->KwdTab[ KwdCod ]; - if( (VALF77(KwdCod) < 1) || (VALF77(KwdCod) > GmfMaxKwd) ) + if( (KwdCod < 1) || (KwdCod > GmfMaxKwd) ) return(0); // Save the current stack environment for longjmp @@ -1117,8 +1097,6 @@ int NAMF77(GmfGetLin, gmfgetlin)(TYPF77(int64_t)MshIdx, TYPF77(int)KwdCod, ...) else if(kwd->fmt[i] == 'c') { safe_fscanf(msh->hdl, "%s", va_arg(VarArg, char *), msh->err); - //safe_fgets( va_arg(VarArg, char *), - // WrdSiz * FilStrSiz, msh->hdl, msh->err); } } } @@ -1178,17 +1156,17 @@ int NAMF77(GmfGetLin, gmfgetlin)(TYPF77(int64_t)MshIdx, TYPF77(int)KwdCod, ...) /* Write a full line from the current kwd */ /*----------------------------------------------------------------------------*/ -int NAMF77(GmfSetLin, gmfsetlin)(TYPF77(int64_t) MshIdx, TYPF77(int) KwdCod, ...) +int GmfSetLin(int64_t MshIdx, int KwdCod, ...) { int i, pos, *IntBuf, err; int64_t *LngBuf; float *FltSolTab, *FltBuf; double *DblSolTab, *DblBuf; va_list VarArg; - GmfMshSct *msh = (GmfMshSct *) VALF77(MshIdx); - KwdSct *kwd = &msh->KwdTab[ VALF77(KwdCod) ]; + GmfMshSct *msh = (GmfMshSct *)MshIdx; + KwdSct *kwd = &msh->KwdTab[ KwdCod ]; - if( ( VALF77(KwdCod) < 1) || ( VALF77(KwdCod) > GmfMaxKwd) ) + if( (KwdCod < 1) || (KwdCod > GmfMaxKwd) ) return(0); // Save the current stack environment for longjmp @@ -1213,23 +1191,18 @@ int NAMF77(GmfSetLin, gmfsetlin)(TYPF77(int64_t) MshIdx, TYPF77(int) KwdCod, ... if(kwd->fmt[i] == 'r') { if(msh->FltSiz == 32) -#ifdef F77API - fprintf(msh->hdl, "%.9g ", *(va_arg(VarArg, float *))); -#else fprintf(msh->hdl, "%.9g ", va_arg(VarArg, double)); -#endif else - fprintf(msh->hdl, "%.17g ", VALF77(va_arg(VarArg, TYPF77(double)))); + fprintf(msh->hdl, "%.17g ", va_arg(VarArg, double)); } else if(kwd->fmt[i] == 'i') { if(msh->ver <= 3) - fprintf(msh->hdl, "%d ", VALF77(va_arg(VarArg, TYPF77(int)))); + fprintf(msh->hdl, "%d ", va_arg(VarArg, int)); else { // [Bruno] %ld -> INT64_T_FMT - fprintf( msh->hdl, INT64_T_FMT " ", - VALF77(va_arg(VarArg, TYPF77(int64_t)))); + fprintf(msh->hdl, INT64_T_FMT " ", va_arg(VarArg, int64_t)); } } else if(kwd->fmt[i] == 'c') @@ -1247,17 +1220,13 @@ int NAMF77(GmfSetLin, gmfsetlin)(TYPF77(int64_t) MshIdx, TYPF77(int) KwdCod, ... if(msh->FltSiz == 32) { FltBuf = (void *)&msh->buf[ pos ]; -#ifdef F77API - *FltBuf = (float)*(va_arg(VarArg, float *)); -#else *FltBuf = (float)va_arg(VarArg, double); -#endif pos += 4; } else { DblBuf = (void *)&msh->buf[ pos ]; - *DblBuf = VALF77(va_arg(VarArg, TYPF77(double))); + *DblBuf = va_arg(VarArg, double); pos += 8; } } @@ -1266,13 +1235,13 @@ int NAMF77(GmfSetLin, gmfsetlin)(TYPF77(int64_t) MshIdx, TYPF77(int) KwdCod, ... if(msh->ver <= 3) { IntBuf = (void *)&msh->buf[ pos ]; - *IntBuf = VALF77(va_arg(VarArg, TYPF77(int))); + *IntBuf = va_arg(VarArg, int); pos += 4; } else { LngBuf = (void *)&msh->buf[ pos ]; - *LngBuf = VALF77(va_arg(VarArg, TYPF77(int64_t))); + *LngBuf = va_arg(VarArg, int64_t); pos += 8; } } @@ -1460,13 +1429,8 @@ int GmfCpyLin(int64_t InpIdx, int64_t OutIdx, int KwdCod) /* Bufferized asynchronous reading of all keyword's lines */ /*----------------------------------------------------------------------------*/ -int NAMF77(GmfGetBlock, gmfgetblock)( TYPF77(int64_t) MshIdx, - TYPF77(int) KwdCod, - TYPF77(int64_t) BegIdx, - TYPF77(int64_t) EndIdx, - TYPF77(int) MapTyp, - void *MapTab, - void *prc, ... ) +int GmfGetBlock( int64_t MshIdx, int KwdCod, int64_t BegIdx, int64_t EndIdx, + int MapTyp, void *MapTab, void *prc, ... ) { char *UsrDat[ GmfMaxTyp ], *UsrBas[ GmfMaxTyp ], *FilPos, *EndUsrDat; char *FilBuf = NULL, *FrtBuf = NULL, *BckBuf = NULL, *BegUsrDat; @@ -1480,19 +1444,14 @@ int NAMF77(GmfGetBlock, gmfgetblock)( TYPF77(int64_t) MshIdx, double *FilPtrR64, *UsrPtrR64; int64_t BlkNmbLin, *FilPtrI64, *UsrPtrI64, BlkBegIdx, BlkEndIdx = 0; int64_t *LngMapTab = NULL, OldIdx = 0, UsrNmbLin, VecLen; - size_t FilBegIdx = VALF77(BegIdx), FilEndIdx = VALF77(EndIdx); + size_t FilBegIdx = BegIdx, FilEndIdx = EndIdx; void (*UsrPrc)(int64_t, int64_t, void *) = NULL; size_t UsrLen[ GmfMaxTyp ], ret, LinSiz, b, l, NmbBlk; va_list VarArg; - GmfMshSct *msh = (GmfMshSct *) VALF77(MshIdx); - KwdSct *kwd = &msh->KwdTab[ VALF77(KwdCod) ]; + GmfMshSct *msh = (GmfMshSct *)MshIdx; + KwdSct *kwd = &msh->KwdTab[ KwdCod ]; struct aiocb aio; -#ifdef F77API - int NmbArg = 0; - void *ArgTab[ MaxArg ]; -#else char *UsrArg = NULL; -#endif // Save the current stack environment for longjmp if( (err = setjmp(msh->err)) != 0) @@ -1510,7 +1469,7 @@ int NAMF77(GmfGetBlock, gmfgetblock)( TYPF77(int64_t) MshIdx, } // Check mesh and keyword - if( (VALF77(KwdCod) < 1) || (VALF77(KwdCod) > GmfMaxKwd) || !kwd->NmbLin ) + if( (KwdCod < 1) || (KwdCod > GmfMaxKwd) || !kwd->NmbLin ) return(0); // Make sure it's not a simple information keyword @@ -1525,9 +1484,9 @@ int NAMF77(GmfGetBlock, gmfgetblock)( TYPF77(int64_t) MshIdx, UsrNmbLin = FilEndIdx - FilBegIdx + 1; // Get the renumbering map if any - if(VALF77(MapTyp) == GmfInt) + if(MapTyp == GmfInt) IntMapTab = (int *)MapTab; - else if(VALF77(MapTyp) == GmfLong) + else if(MapTyp == GmfLong) LngMapTab = (int64_t *)MapTab; // Start decoding the arguments @@ -1535,28 +1494,17 @@ int NAMF77(GmfGetBlock, gmfgetblock)( TYPF77(int64_t) MshIdx, LinSiz = 0; // Get the user's preprocessing procedure and argument adresses, if any -#ifdef F77API - if(prc) - { - UsrPrc = (void (*)(int64_t, int64_t, void *))prc; - NmbArg = *(va_arg(VarArg, int *)); - - for(i=0;ityp != RegKwd) && (kwd->typ != SolKwd) ) longjmp(msh->err, -36); // Read the first data type to select between list and table mode - typ = VALF77(va_arg(VarArg, TYPF77(int))); + typ = va_arg(VarArg, int); // If the table mode is selected, read the four additional tables // containing the arguments: type, vector size, begin and end pointers @@ -1580,14 +1528,14 @@ int NAMF77(GmfGetBlock, gmfgetblock)( TYPF77(int64_t) MshIdx, if(IniFlg) IniFlg = 0; else - typ = VALF77(va_arg(VarArg, TYPF77(int))); + typ = va_arg(VarArg, int); if(typ >= GmfFloatVec && typ <= GmfLongVec) { // In case the type is a vector, get its size and change // the type for the corresponding scalar type typ -= 4; - VecCnt = VALF77(va_arg(VarArg, TYPF77(int))); + VecCnt = va_arg(VarArg, int); } else if(typ >= GmfSca && typ <= GmfMat) { @@ -1703,11 +1651,7 @@ int NAMF77(GmfGetBlock, gmfgetblock)( TYPF77(int64_t) MshIdx, // Call the user's preprocessing procedure if(UsrPrc) -#ifdef F77API - CalF77Prc(1, kwd->NmbLin, UsrPrc, NmbArg, ArgTab); -#else UsrPrc(1, kwd->NmbLin, UsrArg); -#endif } } else @@ -1901,11 +1845,7 @@ int NAMF77(GmfGetBlock, gmfgetblock)( TYPF77(int64_t) MshIdx, // Call the user's preprocessing procedure if(UsrPrc) -#ifdef F77API - CalF77Prc(BlkBegIdx, BlkEndIdx, UsrPrc, NmbArg, ArgTab); -#else UsrPrc(BlkBegIdx, BlkEndIdx, UsrArg); -#endif } } @@ -1921,13 +1861,8 @@ int NAMF77(GmfGetBlock, gmfgetblock)( TYPF77(int64_t) MshIdx, /* Bufferized writing of all keyword's lines */ /*----------------------------------------------------------------------------*/ -int NAMF77(GmfSetBlock, gmfsetblock)( TYPF77(int64_t) MshIdx, - TYPF77(int) KwdCod, - TYPF77(int64_t) BegIdx, - TYPF77(int64_t) EndIdx, - TYPF77(int) MapTyp, - void *MapTab, - void *prc, ... ) +int GmfSetBlock( int64_t MshIdx, int KwdCod, int64_t BegIdx, int64_t EndIdx, + int MapTyp, void *MapTab, void *prc, ... ) { char *UsrDat[ GmfMaxTyp ], *UsrBas[ GmfMaxTyp ]; char *StrTab[4] = {"%.9g", "%.17g", "%d", "%lld" }, *FilPos; @@ -1941,19 +1876,14 @@ int NAMF77(GmfSetBlock, gmfsetblock)( TYPF77(int64_t) MshIdx, double *FilPtrR64, *UsrPtrR64; int64_t UsrNmbLin, BlkNmbLin = 0, BlkBegIdx, BlkEndIdx = 0; int64_t *FilPtrI64, *UsrPtrI64, *LngMapTab = NULL, OldIdx = 0; - size_t FilBegIdx = VALF77(BegIdx), FilEndIdx = VALF77(EndIdx); + size_t FilBegIdx = BegIdx, FilEndIdx = EndIdx; void (*UsrPrc)(int64_t, int64_t, void *) = NULL; size_t UsrLen[ GmfMaxTyp ], ret, LinSiz, VecLen, s, b, NmbBlk; va_list VarArg; - GmfMshSct *msh = (GmfMshSct *) VALF77(MshIdx); - KwdSct *kwd = &msh->KwdTab[ VALF77(KwdCod) ]; + GmfMshSct *msh = (GmfMshSct *)MshIdx; + KwdSct *kwd = &msh->KwdTab[ KwdCod ]; struct aiocb aio; -#ifdef F77API - int NmbArg = 0; - void *ArgTab[ MaxArg ]; -#else char *UsrArg = NULL; -#endif // Save the current stack environment for longjmp if( (err = setjmp(msh->err)) != 0) @@ -1968,7 +1898,7 @@ int NAMF77(GmfSetBlock, gmfsetblock)( TYPF77(int64_t) MshIdx, } // Check mesh and keyword - if( (VALF77(KwdCod) < 1) || (VALF77(KwdCod) > GmfMaxKwd) || !kwd->NmbLin ) + if( (KwdCod < 1) || (KwdCod > GmfMaxKwd) || !kwd->NmbLin ) return(0); // Make sure it's not a simple information keyword @@ -1988,9 +1918,9 @@ int NAMF77(GmfSetBlock, gmfsetblock)( TYPF77(int64_t) MshIdx, UsrNmbLin = FilEndIdx - FilBegIdx + 1; // Get the renumbering map if any - if(VALF77(MapTyp) == GmfInt) + if(MapTyp == GmfInt) IntMapTab = (int *)MapTab; - else if(VALF77(MapTyp) == GmfLong) + else if(MapTyp == GmfLong) LngMapTab = (int64_t *)MapTab; // Start decoding the arguments @@ -1998,28 +1928,17 @@ int NAMF77(GmfSetBlock, gmfsetblock)( TYPF77(int64_t) MshIdx, LinSiz = 0; // Get the user's postprocessing procedure and argument adresses, if any -#ifdef F77API - if(prc) - { - UsrPrc = (void (*)(int64_t, int64_t, void *))prc; - NmbArg = *(va_arg(VarArg, int *)); - - for(i=0;ityp != RegKwd) && (kwd->typ != SolKwd) ) longjmp(msh->err, -42); // Read the first data type to select between list and table mode - typ = VALF77(va_arg(VarArg, TYPF77(int))); + typ = va_arg(VarArg, int); // If the table mode is selected, read the four additional tables // containing the arguments: type, vector size, begin and end pointers @@ -2043,14 +1962,14 @@ int NAMF77(GmfSetBlock, gmfsetblock)( TYPF77(int64_t) MshIdx, if(IniFlg) IniFlg = 0; else - typ = VALF77(va_arg(VarArg, TYPF77(int))); + typ = va_arg(VarArg, int); // In case the type is a vector. get its size and change the type // for the corresponding scalar type if(typ >= GmfFloatVec && typ <= GmfLongVec) { typ -= 4; - VecCnt = VALF77(va_arg(VarArg, TYPF77(int))); + VecCnt = va_arg(VarArg, int); } else if(typ >= GmfSca && typ <= GmfMat) { @@ -2134,11 +2053,7 @@ int NAMF77(GmfSetBlock, gmfsetblock)( TYPF77(int64_t) MshIdx, if(msh->typ & Asc) { if(UsrPrc) -#ifdef F77API - CalF77Prc(1, kwd->NmbLin, UsrPrc, NmbArg, ArgTab); -#else UsrPrc(1, kwd->NmbLin, UsrArg); -#endif for(s=FilBegIdx; s<=FilEndIdx; s++) for(j=0;jSolSiz;j++) @@ -2238,11 +2153,7 @@ int NAMF77(GmfSetBlock, gmfsetblock)( TYPF77(int64_t) MshIdx, // Call user's preprocessing first if(UsrPrc) -#ifdef F77API - CalF77Prc(BlkBegIdx, BlkEndIdx, UsrPrc, NmbArg, ArgTab); -#else UsrPrc(BlkBegIdx, BlkEndIdx, UsrArg); -#endif // Then copy it's data to the file buffer for(i=0;i *NmbByt) - return(0); - *NmbByt = TmpNmb; - memcpy(BytFlo, TmpFlo, *NmbByt); - free(TmpFlo); +// VERTICES - return(TmpNmb); +int APIF77(gmfgetvertex)(int64_t *MshIdx, double *crd, int *ref) +{ + GmfMshSct *msh = (GmfMshSct *)*MshIdx; + + if(msh->dim == 3) + return(GmfGetLin(*MshIdx, GmfVertices, &crd[0], &crd[1], &crd[2], ref)); + else if(msh->dim == 2) + return(GmfGetLin(*MshIdx, GmfVertices, &crd[0], &crd[1], ref)); + else + return(0); } -int APIF77(gmfwritebyteflow)(int64_t *MshIdx, char *BytFlo, int *NmbByt) +int APIF77(gmfsetvertex)(int64_t *MshIdx, double *crd, int *ref) { - return(GmfWriteByteFlow(*MshIdx, BytFlo, *NmbByt)); + GmfMshSct *msh = (GmfMshSct *)*MshIdx; + + if(msh->dim == 3) + return(GmfSetLin(*MshIdx, GmfVertices, crd[0], crd[1], crd[2], *ref)); + else if(msh->dim == 2) + return(GmfSetLin(*MshIdx, GmfVertices, crd[0], crd[1], *ref)); + else + return(0); } -int APIF77(gmfgetfloatprecision)(int64_t *MshIdx) +int APIF77(gmfgetvertices)(int64_t *MshIdx, int *BegIdx, int *EndIdx, + int *MapTyp, int64_t *map, + double *BegNod, double *EndNod, + int *BegRef, int *EndRef ) { - return(GmfGetFloatPrecision(*MshIdx)); + GmfMshSct *msh = (GmfMshSct *)*MshIdx; + + return(GmfGetBlock( *MshIdx, GmfVertices, *BegIdx, *EndIdx, + *MapTyp, map, NULL, + GmfDoubleVec, msh->dim, BegNod, EndNod, + GmfInt, BegRef, EndRef )); } -int APIF77(gmfsetfloatprecision)(int64_t *MshIdx, int *FltSiz) +int APIF77(gmfsetvertices)(int64_t *MshIdx, int *BegIdx, int *EndIdx, + int *MapTyp, int64_t *map, + double *BegNod, double *EndNod, + int *BegRef, int *EndRef ) { - GmfSetFloatPrecision(*MshIdx, *FltSiz); - return(0); + GmfMshSct *msh = (GmfMshSct *)*MshIdx; + + return(GmfSetBlock( *MshIdx, GmfVertices, *BegIdx, *EndIdx, + *MapTyp, map, NULL, + GmfDoubleVec, msh->dim, BegNod, EndNod, + GmfInt, BegRef, EndRef )); } -*/ - -/*----------------------------------------------------------------------------*/ -/* Duplication macros */ -/*----------------------------------------------------------------------------*/ - -#define DUP(s,n) DUP ## n (s) -#define DUP1(s) s -#define DUP2(s) DUP1(s),s -#define DUP3(s) DUP2(s),s -#define DUP4(s) DUP3(s),s -#define DUP5(s) DUP4(s),s -#define DUP6(s) DUP5(s),s -#define DUP7(s) DUP6(s),s -#define DUP8(s) DUP7(s),s -#define DUP9(s) DUP8(s),s -#define DUP10(s) DUP9(s),s -#define DUP11(s) DUP10(s),s -#define DUP12(s) DUP11(s),s -#define DUP13(s) DUP12(s),s -#define DUP14(s) DUP13(s),s -#define DUP15(s) DUP14(s),s -#define DUP16(s) DUP15(s),s -#define DUP17(s) DUP16(s),s -#define DUP18(s) DUP17(s),s -#define DUP19(s) DUP18(s),s -#define DUP20(s) DUP19(s),s - - -#define ARG(a,n) ARG ## n (a) -#define ARG1(a) a[0] -#define ARG2(a) ARG1(a),a[1] -#define ARG3(a) ARG2(a),a[2] -#define ARG4(a) ARG3(a),a[3] -#define ARG5(a) ARG4(a),a[4] -#define ARG6(a) ARG5(a),a[5] -#define ARG7(a) ARG6(a),a[6] -#define ARG8(a) ARG7(a),a[7] -#define ARG9(a) ARG8(a),a[8] -#define ARG10(a) ARG9(a),a[9] -#define ARG11(a) ARG10(a),a[10] -#define ARG12(a) ARG11(a),a[11] -#define ARG13(a) ARG12(a),a[12] -#define ARG14(a) ARG13(a),a[13] -#define ARG15(a) ARG14(a),a[14] -#define ARG16(a) ARG15(a),a[15] -#define ARG17(a) ARG16(a),a[16] -#define ARG18(a) ARG17(a),a[17] -#define ARG19(a) ARG18(a),a[18] -#define ARG20(a) ARG19(a),a[19] - - -/*----------------------------------------------------------------------------*/ -/* Call a fortran thread with 1 to 20 arguments */ -/*----------------------------------------------------------------------------*/ - -static void CalF77Prc( int64_t BegIdx, int64_t EndIdx, - void *prc, int NmbArg, void **ArgTab ) -{ - switch(NmbArg) - { - case 1 : - { - void (*prc1)(int64_t *, int64_t *, DUP(void *, 1)) = - (void (*)(int64_t *, int64_t *, DUP(void *, 1)))prc; - prc1(&BegIdx, &EndIdx, ARG(ArgTab, 1)); - }break; - - case 2 : - { - void (*prc1)(int64_t *, int64_t *, DUP(void *, 2)) = - (void (*)(int64_t *, int64_t *, DUP(void *, 2)))prc; - prc1(&BegIdx, &EndIdx, ARG(ArgTab, 2)); - }break; - - case 3 : - { - void (*prc1)(int64_t *, int64_t *, DUP(void *, 3)) = - (void (*)(int64_t *, int64_t *, DUP(void *, 3)))prc; - prc1(&BegIdx, &EndIdx, ARG(ArgTab, 3)); - }break; - case 4 : - { - void (*prc1)(int64_t *, int64_t *, DUP(void *, 4)) = - (void (*)(int64_t *, int64_t *, DUP(void *, 4)))prc; - prc1(&BegIdx, &EndIdx, ARG(ArgTab, 4)); - }break; - case 5 : - { - void (*prc1)(int64_t *, int64_t *, DUP(void *, 5)) = - (void (*)(int64_t *, int64_t *, DUP(void *, 5)))prc; - prc1(&BegIdx, &EndIdx, ARG(ArgTab, 5)); - }break; +// TRIANGLES - case 6 : - { - void (*prc1)(int64_t *, int64_t *, DUP(void *, 6)) = - (void (*)(int64_t *, int64_t *, DUP(void *, 6)))prc; - prc1(&BegIdx, &EndIdx, ARG(ArgTab, 6)); - }break; +int APIF77(gmfgettriangle)(int64_t *MshIdx, int *nod, int *ref) +{ + return(GmfGetLin(*MshIdx, GmfTriangles, &nod[0], &nod[1], &nod[2], ref)); +} - case 7 : - { - void (*prc1)(int64_t *, int64_t *, DUP(void *, 7)) = - (void (*)(int64_t *, int64_t *, DUP(void *, 7)))prc; - prc1(&BegIdx, &EndIdx, ARG(ArgTab, 7)); - }break; +int APIF77(gmfsettriangle)(int64_t *MshIdx, int *nod, int *ref) +{ + return(GmfSetLin(*MshIdx, GmfTriangles, nod[0], nod[1], nod[2], *ref)); +} - case 8 : - { - void (*prc1)(int64_t *, int64_t *, DUP(void *, 8)) = - (void (*)(int64_t *, int64_t *, DUP(void *, 8)))prc; - prc1(&BegIdx, &EndIdx, ARG(ArgTab, 8)); - }break; +int APIF77(gmfgettriangles)( int64_t *MshIdx, int *BegIdx, int *EndIdx, + int *MapTyp, int64_t *map, + int *BegEle, int *EndEle, + int *BegRef, int *EndRef ) +{ + return(GmfGetBlock( *MshIdx, GmfTriangles, *BegIdx, *EndIdx, + *MapTyp, map, NULL, + GmfIntVec, 3, BegEle, EndEle, + GmfInt, BegRef, EndRef )); +} - case 9 : - { - void (*prc1)(int64_t *, int64_t *, DUP(void *, 9)) = - (void (*)(int64_t *, int64_t *, DUP(void *, 9)))prc; - prc1(&BegIdx, &EndIdx, ARG(ArgTab, 9)); - }break; +int APIF77(gmfsettriangles)( int64_t *MshIdx, int *BegIdx, int *EndIdx, + int *MapTyp, int64_t *map, + int *BegEle, int *EndEle, + int *BegRef, int *EndRef ) +{ + return(GmfSetBlock( *MshIdx, GmfTriangles, *BegIdx, *EndIdx, + *MapTyp, map, NULL, + GmfIntVec, 3, BegEle, EndEle, + GmfInt, BegRef, EndRef )); +} - case 10 : - { - void (*prc1)(int64_t *, int64_t *, DUP(void *, 10)) = - (void (*)(int64_t *, int64_t *, DUP(void *, 10)))prc; - prc1(&BegIdx, &EndIdx, ARG(ArgTab, 10)); - }break; - case 11 : - { - void (*prc1)(int64_t *, int64_t *, DUP(void *, 11)) = - (void (*)(int64_t *, int64_t *, DUP(void *, 11)))prc; - prc1(&BegIdx, &EndIdx, ARG(ArgTab, 11)); - }break; +// QUADS - case 12 : - { - void (*prc1)(int64_t *, int64_t *, DUP(void *, 12)) = - (void (*)(int64_t *, int64_t *, DUP(void *, 12)))prc; - prc1(&BegIdx, &EndIdx, ARG(ArgTab, 12)); - }break; +int APIF77(gmfgetquadrilateral)(int64_t *MshIdx, int *nod, int *ref) +{ + return(GmfGetLin(*MshIdx, GmfQuadrilaterals, &nod[0], &nod[1], &nod[2], &nod[3], ref)); +} - case 13 : - { - void (*prc1)(int64_t *, int64_t *, DUP(void *, 13)) = - (void (*)(int64_t *, int64_t *, DUP(void *, 13)))prc; - prc1(&BegIdx, &EndIdx, ARG(ArgTab, 13)); - }break; +int APIF77(gmfsetquadrilateral)(int64_t *MshIdx, int *nod, int *ref) +{ + return(GmfGetLin(*MshIdx, GmfQuadrilaterals, nod[0], nod[1], nod[2], nod[3], *ref)); +} - case 14 : - { - void (*prc1)(int64_t *, int64_t *, DUP(void *, 14)) = - (void (*)(int64_t *, int64_t *, DUP(void *, 14)))prc; - prc1(&BegIdx, &EndIdx, ARG(ArgTab, 14)); - }break; +int APIF77(gmfgetquadrilaterals)(int64_t *MshIdx, int *BegIdx, int *EndIdx, + int *MapTyp, int64_t *map, + int *BegEle, int *EndEle, + int *BegRef, int *EndRef ) +{ + return(GmfGetBlock( *MshIdx, GmfQuadrilaterals, *BegIdx, *EndIdx, + *MapTyp, map, NULL, + GmfIntVec, 4, BegEle, EndEle, + GmfInt, BegRef, EndRef )); +} - case 15 : - { - void (*prc1)(int64_t *, int64_t *, DUP(void *, 15)) = - (void (*)(int64_t *, int64_t *, DUP(void *, 15)))prc; - prc1(&BegIdx, &EndIdx, ARG(ArgTab, 15)); - }break; +int APIF77(gmfsetquadrilaterals)(int64_t *MshIdx, int *BegIdx, int *EndIdx, + int *MapTyp, int64_t *map, + int *BegEle, int *EndEle, + int *BegRef, int *EndRef ) +{ + return(GmfSetBlock( *MshIdx, GmfQuadrilaterals, *BegIdx, *EndIdx, + *MapTyp, map, NULL, + GmfIntVec, 4, BegEle, EndEle, + GmfInt, BegRef, EndRef )); +} - case 16 : - { - void (*prc1)(int64_t *, int64_t *, DUP(void *, 16)) = - (void (*)(int64_t *, int64_t *, DUP(void *, 16)))prc; - prc1(&BegIdx, &EndIdx, ARG(ArgTab, 16)); - }break; - case 17 : - { - void (*prc1)(int64_t *, int64_t *, DUP(void *, 17)) = - (void (*)(int64_t *, int64_t *, DUP(void *, 17)))prc; - prc1(&BegIdx, &EndIdx, ARG(ArgTab, 17)); - }break; +// TETS - case 18 : - { - void (*prc1)(int64_t *, int64_t *, DUP(void *, 18)) = - (void (*)(int64_t *, int64_t *, DUP(void *, 18)))prc; - prc1(&BegIdx, &EndIdx, ARG(ArgTab, 18)); - }break; +int APIF77(gmfgettetrahedron)(int64_t *MshIdx, int *nod, int *ref) +{ + return(GmfGetLin(*MshIdx, GmfTetrahedra, &nod[0], &nod[1], &nod[2], &nod[3], ref)); +} - case 19 : - { - void (*prc1)(int64_t *, int64_t *, DUP(void *, 19)) = - (void (*)(int64_t *, int64_t *, DUP(void *, 19)))prc; - prc1(&BegIdx, &EndIdx, ARG(ArgTab, 19)); - }break; +int APIF77(gmfsettetrahedron)(int64_t *MshIdx, int *nod, int *ref) +{ + return(GmfGetLin(*MshIdx, GmfTetrahedra, nod[0], nod[1], nod[2], nod[3], *ref)); +} - case 20 : - { - void (*prc1)(int64_t *, int64_t *, DUP(void *, 20)) = - (void (*)(int64_t *, int64_t *, DUP(void *, 20)))prc; - prc1(&BegIdx, &EndIdx, ARG(ArgTab, 20)); - }break; - } +int APIF77(gmfgettetrahedra)( int64_t *MshIdx, int *BegIdx, int *EndIdx, + int *MapTyp, int64_t *map, + int *BegEle, int *EndEle, + int *BegRef, int *EndRef ) +{ + return(GmfGetBlock( *MshIdx, GmfTetrahedra, *BegIdx, *EndIdx, + *MapTyp, map, NULL, + GmfIntVec, 4, BegEle, EndEle, + GmfInt, BegRef, EndRef )); } -#endif +int APIF77(gmfsettetrahedra)( int64_t *MshIdx, int *BegIdx, int *EndIdx, + int *MapTyp, int64_t *map, + int *BegEle, int *EndEle, + int *BegRef, int *EndRef ) +{ + return(GmfSetBlock( *MshIdx, GmfTetrahedra, *BegIdx, *EndIdx, + *MapTyp, map, NULL, + GmfIntVec, 4, BegEle, EndEle, + GmfInt, BegRef, EndRef )); +} diff --git a/sources/libmeshb7.h b/sources/libmeshb7.h index 9c9dd76..82982a0 100644 --- a/sources/libmeshb7.h +++ b/sources/libmeshb7.h @@ -2,14 +2,14 @@ /*----------------------------------------------------------------------------*/ /* */ -/* LIBMESHB V7.69 */ +/* LIBMESHB V7.79 */ /* */ /*----------------------------------------------------------------------------*/ /* */ /* Description: handle .meshb file format I/O */ /* Author: Loic MARECHAL */ /* Creation date: dec 09 1999 */ -/* Last modification: jan 04 2024 */ +/* Last modification: feb 08 2024 */ /* */ /*----------------------------------------------------------------------------*/ diff --git a/sources/libmeshb7.ins b/sources/libmeshb7.ins index 1436fd9..8b7b373 100644 --- a/sources/libmeshb7.ins +++ b/sources/libmeshb7.ins @@ -2,48 +2,64 @@ c---------------------------------------------------------- c -c LIBMESH V 7.69 +c LIBMESH V 7.79 c c---------------------------------------------------------- c c Description: handles .meshb file format I/O c Author: Loic MARECHAL c Creation date: dec 08 2015 -c Last modification: jan 15 2024 +c Last modification: feb 12 2024 c c---------------------------------------------------------- c Procedures definition - external gmfopenmesh - external gmfclosemesh - external gmfstatkwd - external gmfsetkwd - external gmfgotokwd - external gmfgetlin - external gmfsetlin - external gmfgetblock - external gmfsetblock - external gmfsethonodesordering -c external gmfreadbyteflow -c external gmfwritebyteflow -c external gmfgetfloatprecision -c external gmfsetfloatprecision + external gmfopenmeshf77 + external gmfclosemeshf77 + external gmfstatkwdf77 + external gmfsetkwdf77 + external gmfgotokwdf77 + external gmfgetvertex + external gmfsetvertex + external gmfgettriangle + external gmfsettriangle + external gmfgetquadrilateral + external gmfsetquadrilateral + external gmfgettetrahedron + external gmfsettetrahedron + external gmfsethonodesorderingf77 + external gmfgetvertices + external gmfsetvertices + external gmfgettriangles + external gmfsettriangles + external gmfgetquadrilaterals + external gmfsetquadrilaterals + external gmfgettetrahedra + external gmfsettetrahedra - integer*8 gmfopenmesh - integer gmfclosemesh - integer gmfstatkwd - integer gmfsetkwd - integer gmfgotokwd - integer gmfgetlin - integer gmfsetlin - integer gmfgetblock - integer gmfsetblock - integer gmfsethonodesordering -c integer gmfreadbyteflow -c integer gmfwritebyteflow -c integer gmfgetfloatprecision -c integer gmfsetfloatprecision + integer*8 gmfopenmeshf77 + integer gmfclosemeshf77 + integer gmfstatkwdf77 + integer gmfsetkwdf77 + integer gmfgotokwdf77 + integer gmfgetvertex + integer gmfsetvertex + integer gmfgettriangle + integer gmfsettriangle + integer gmfgetquadrilateral + integer gmfsetquadrilateral + integer gmfgettetrahedron + integer gmfsettetrahedron + integer gmfsethonodesorderingf77 + integer gmfgetvertices + integer gmfsetvertices + integer gmfgettriangles + integer gmfsettriangles + integer gmfgetquadrilaterals + integer gmfsetquadrilaterals + integer gmfgettetrahedra + integer gmfsettetrahedra c Parameters definition diff --git a/sources/libmeshb7_mod.f90 b/sources/libmeshb7_mod.f90 index 2680eec..a770f2a 100644 --- a/sources/libmeshb7_mod.f90 +++ b/sources/libmeshb7_mod.f90 @@ -30,10 +30,6 @@ module libmeshb7 external gmfgetblock external gmfsetblock external gmfsethonodesordering - !external gmfreadbyteflow - !external gmfwritebyteflow - !external gmfgetfloatprecision - !external gmfsetfloatprecision integer(8) :: gmfopenmesh integer(4) :: gmfclosemesh @@ -45,10 +41,6 @@ module libmeshb7 integer(4) :: gmfgetblock integer(4) :: gmfsetblock integer(4) :: gmfsethonodesordering - !integer(4) :: gmfreadbyteflow - !integer(4) :: gmfwritebyteflow - !integer(4) :: gmfgetfloatprecision - !integer(4) :: gmfsetfloatprecision !Parameters definition diff --git a/whatsnew.md b/whatsnew.md index 1fb0960..3d6fe19 100644 --- a/whatsnew.md +++ b/whatsnew.md @@ -1,8 +1,6 @@ -## Release 7.62 +## Release 7.79 -1. Corrected two bugs: - - GmfOpenMesh: could crash with a stack overflow a present some security issues - - test\_libmeshb\_pipeline.f: the Fortran version of the user's procedure call was crashing - -2. New helpers functions system to easily add specific features related to the libMeshb: - - See the helper's [readme](utilities/libmeshb7_helpers.md) for more information about the new functions to handle polyhedral meshes. +1. Complete rewrite of the Fortran API: + - No more variable arguments procedures are used in Fortran as such feature is no more supported by gfortran + - Addhoc procedures to handle a few keywords are provided + - Users are encouraged to add their own ! From b37ee4dffb5a277ed58a2636f1fd8d2fb52c297b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Mar=C3=A9chal?= Date: Mon, 12 Feb 2024 16:05:33 +0100 Subject: [PATCH 13/38] Chandeg the Fortran API for a more generic element-wise access --- README.md | 2 +- examples/test_libmeshb.f | 9 ++- examples/test_libmeshb_block.f | 4 +- sources/libmeshb7.c | 142 ++++++++++++++------------------- sources/libmeshb7.ins | 36 +++------ 5 files changed, 78 insertions(+), 115 deletions(-) diff --git a/README.md b/README.md index 0b5eed7..ac82c1a 100644 --- a/README.md +++ b/README.md @@ -33,7 +33,7 @@ Can call user's own pre and post processing routines in a separate thread while ## Usage The **libMeshb** library is written in *ANSI C*. It is made of a single C file and a header file to be compiled and linked alongside the calling program. -It may be used in C and C++ programs (a partial Fortran77 APIs is provided). +It may be used in C and C++ programs (a partial Fortran77 API is provided). Tested on *Linux*, *macOS*, and *Windows 7->10*. Reading a mesh file is fairly easy: diff --git a/examples/test_libmeshb.f b/examples/test_libmeshb.f index 4a0214e..730aaba 100644 --- a/examples/test_libmeshb.f +++ b/examples/test_libmeshb.f @@ -33,7 +33,8 @@ c Read the quads res = gmfgotokwdf77(InpMsh, GmfQuadrilaterals) do i = 1, NmbQad - res =gmfgetquadrilateral(InpMsh,QadTab(1,i),QadTab(5,i)) + res =gmfgetelement(InpMsh, GmfQuadrilaterals, + + QadTab(1,i), QadTab(5,i)) end do c Read the vertices @@ -65,11 +66,13 @@ c Write the triangles res = gmfsetkwdf77(OutMsh, GmfTriangles, 2*NmbQad, 0, 0) do i=1,NmbQad - res = gmfsettriangle(OutMsh,QadTab(1,i),QadTab(5,i)) + res = gmfsetelement(OutMsh, GmfTriangles, + + QadTab(1,i), QadTab(5,i)) c Modify the quad to build the other triangle's diagonal QadTab(2,i) = QadTab(3,i); QadTab(3,i) = QadTab(4,i); - res = gmfsettriangle(OutMsh,QadTab(1,i),QadTab(5,i)) + res = gmfsetelement(OutMsh, GmfTriangles, + + QadTab(1,i),QadTab(5,i)) end do c Don't forget to close the file diff --git a/examples/test_libmeshb_block.f b/examples/test_libmeshb_block.f index 5e0b933..9d89d28 100644 --- a/examples/test_libmeshb_block.f +++ b/examples/test_libmeshb_block.f @@ -44,7 +44,7 @@ + RefTab( 1), RefTab( NmbVer)) c Read the quads using one single vector of 5 consecutive integers - res = gmfgetquadrilaterals(InpMsh, + res = gmfgetelements(InpMsh, GmfQuadrilaterals, + 1, NmbQad, 0, %val(0), + QadTab(1,1), QadTab(1,NmbQad), + QadTab(5,1), QadTab(5,NmbQad)) @@ -91,7 +91,7 @@ c Write the triangles using 4 independant set of arguments c for each scalar entry: node1, node2, node3 and reference res = gmfsetkwdf77(OutMsh, GmfTriangles, 2*NmbQad, 0, 0) - res = gmfsettriangles(OutMsh, + res = gmfsetelements(OutMsh, GmfTriangles, + 1, 2*NmbQad, 0, %val(0), + TriTab(1,1), TriTab(1,2*NmbQad), + TriTab(4,1), TriTab(4,2*NmbQad)) diff --git a/sources/libmeshb7.c b/sources/libmeshb7.c index 6645049..ff87e84 100644 --- a/sources/libmeshb7.c +++ b/sources/libmeshb7.c @@ -3094,106 +3094,82 @@ int APIF77(gmfsetvertices)(int64_t *MshIdx, int *BegIdx, int *EndIdx, } -// TRIANGLES +// ELEMENTS -int APIF77(gmfgettriangle)(int64_t *MshIdx, int *nod, int *ref) +int APIF77(gmfgetelement)(int64_t *MshIdx, int *kwd, int *nod, int *ref) { - return(GmfGetLin(*MshIdx, GmfTriangles, &nod[0], &nod[1], &nod[2], ref)); -} - -int APIF77(gmfsettriangle)(int64_t *MshIdx, int *nod, int *ref) -{ - return(GmfSetLin(*MshIdx, GmfTriangles, nod[0], nod[1], nod[2], *ref)); -} - -int APIF77(gmfgettriangles)( int64_t *MshIdx, int *BegIdx, int *EndIdx, - int *MapTyp, int64_t *map, - int *BegEle, int *EndEle, - int *BegRef, int *EndRef ) -{ - return(GmfGetBlock( *MshIdx, GmfTriangles, *BegIdx, *EndIdx, - *MapTyp, map, NULL, - GmfIntVec, 3, BegEle, EndEle, - GmfInt, BegRef, EndRef )); -} - -int APIF77(gmfsettriangles)( int64_t *MshIdx, int *BegIdx, int *EndIdx, - int *MapTyp, int64_t *map, - int *BegEle, int *EndEle, - int *BegRef, int *EndRef ) -{ - return(GmfSetBlock( *MshIdx, GmfTriangles, *BegIdx, *EndIdx, - *MapTyp, map, NULL, - GmfIntVec, 3, BegEle, EndEle, - GmfInt, BegRef, EndRef )); + switch(*kwd) + { + case GmfEdges : + return(GmfGetLin(*MshIdx, *kwd, &nod[0], &nod[1], ref)); + case GmfTriangles : + return(GmfGetLin(*MshIdx, *kwd, &nod[0], &nod[1], &nod[2], ref)); + case GmfQuadrilaterals : + return(GmfGetLin(*MshIdx, *kwd, &nod[0], &nod[1], &nod[2], &nod[3], ref)); + case GmfTetrahedra : + return(GmfGetLin(*MshIdx, *kwd, &nod[0], &nod[1], &nod[2], &nod[3], ref)); + default : + return(0); + } } - -// QUADS - -int APIF77(gmfgetquadrilateral)(int64_t *MshIdx, int *nod, int *ref) +int APIF77(gmfsetelement)(int64_t *MshIdx, int *kwd, int *nod, int *ref) { - return(GmfGetLin(*MshIdx, GmfQuadrilaterals, &nod[0], &nod[1], &nod[2], &nod[3], ref)); + switch(*kwd) + { + case GmfEdges : + return(GmfSetLin(*MshIdx, *kwd, nod[0], nod[1], *ref)); + case GmfTriangles : + return(GmfSetLin(*MshIdx, *kwd, nod[0], nod[1], nod[2], *ref)); + case GmfQuadrilaterals : + return(GmfSetLin(*MshIdx, *kwd, nod[0], nod[1], nod[2], nod[3], *ref)); + case GmfTetrahedra : + return(GmfSetLin(*MshIdx, *kwd, nod[0], nod[1], nod[2], nod[3], *ref)); + default : + return(0); + } } -int APIF77(gmfsetquadrilateral)(int64_t *MshIdx, int *nod, int *ref) +int APIF77(gmfgetelements)(int64_t *MshIdx, int *kwd, int *BegIdx, int *EndIdx, + int *MapTyp, int64_t *map, + int *BegEle, int *EndEle, + int *BegRef, int *EndRef) { - return(GmfGetLin(*MshIdx, GmfQuadrilaterals, nod[0], nod[1], nod[2], nod[3], *ref)); -} + int EleSiz; -int APIF77(gmfgetquadrilaterals)(int64_t *MshIdx, int *BegIdx, int *EndIdx, - int *MapTyp, int64_t *map, - int *BegEle, int *EndEle, - int *BegRef, int *EndRef ) -{ - return(GmfGetBlock( *MshIdx, GmfQuadrilaterals, *BegIdx, *EndIdx, - *MapTyp, map, NULL, - GmfIntVec, 4, BegEle, EndEle, - GmfInt, BegRef, EndRef )); -} + switch(*kwd) + { + case GmfEdges : EleSiz = 2; break; + case GmfTriangles : EleSiz = 3; break; + case GmfQuadrilaterals : EleSiz = 4; break; + case GmfTetrahedra : EleSiz = 4; break; + default : return(0); + } -int APIF77(gmfsetquadrilaterals)(int64_t *MshIdx, int *BegIdx, int *EndIdx, - int *MapTyp, int64_t *map, - int *BegEle, int *EndEle, - int *BegRef, int *EndRef ) -{ - return(GmfSetBlock( *MshIdx, GmfQuadrilaterals, *BegIdx, *EndIdx, + return(GmfGetBlock( *MshIdx, *kwd, *BegIdx, *EndIdx, *MapTyp, map, NULL, - GmfIntVec, 4, BegEle, EndEle, + GmfIntVec, EleSiz, BegEle, EndEle, GmfInt, BegRef, EndRef )); } - -// TETS - -int APIF77(gmfgettetrahedron)(int64_t *MshIdx, int *nod, int *ref) -{ - return(GmfGetLin(*MshIdx, GmfTetrahedra, &nod[0], &nod[1], &nod[2], &nod[3], ref)); -} - -int APIF77(gmfsettetrahedron)(int64_t *MshIdx, int *nod, int *ref) +int APIF77(gmfsetelements)(int64_t *MshIdx, int *kwd, int *BegIdx, int *EndIdx, + int *MapTyp, int64_t *map, + int *BegEle, int *EndEle, + int *BegRef, int *EndRef) { - return(GmfGetLin(*MshIdx, GmfTetrahedra, nod[0], nod[1], nod[2], nod[3], *ref)); -} + int EleSiz; -int APIF77(gmfgettetrahedra)( int64_t *MshIdx, int *BegIdx, int *EndIdx, - int *MapTyp, int64_t *map, - int *BegEle, int *EndEle, - int *BegRef, int *EndRef ) -{ - return(GmfGetBlock( *MshIdx, GmfTetrahedra, *BegIdx, *EndIdx, - *MapTyp, map, NULL, - GmfIntVec, 4, BegEle, EndEle, - GmfInt, BegRef, EndRef )); -} + switch(*kwd) + { + case GmfEdges : EleSiz = 2; break; + case GmfTriangles : EleSiz = 3; break; + case GmfQuadrilaterals : EleSiz = 4; break; + case GmfTetrahedra : EleSiz = 4; break; + default : return(0); + } -int APIF77(gmfsettetrahedra)( int64_t *MshIdx, int *BegIdx, int *EndIdx, - int *MapTyp, int64_t *map, - int *BegEle, int *EndEle, - int *BegRef, int *EndRef ) -{ - return(GmfSetBlock( *MshIdx, GmfTetrahedra, *BegIdx, *EndIdx, + return(GmfSetBlock( *MshIdx, *kwd, *BegIdx, *EndIdx, *MapTyp, map, NULL, - GmfIntVec, 4, BegEle, EndEle, + GmfIntVec, EleSiz, BegEle, EndEle, GmfInt, BegRef, EndRef )); } diff --git a/sources/libmeshb7.ins b/sources/libmeshb7.ins index 8b7b373..517fdac 100644 --- a/sources/libmeshb7.ins +++ b/sources/libmeshb7.ins @@ -20,46 +20,30 @@ c Procedures definition external gmfstatkwdf77 external gmfsetkwdf77 external gmfgotokwdf77 + external gmfsethonodesorderingf77 external gmfgetvertex external gmfsetvertex - external gmfgettriangle - external gmfsettriangle - external gmfgetquadrilateral - external gmfsetquadrilateral - external gmfgettetrahedron - external gmfsettetrahedron - external gmfsethonodesorderingf77 + external gmfgetelement + external gmfsetelement external gmfgetvertices external gmfsetvertices - external gmfgettriangles - external gmfsettriangles - external gmfgetquadrilaterals - external gmfsetquadrilaterals - external gmfgettetrahedra - external gmfsettetrahedra + external gmfgetelements + external gmfsetelements integer*8 gmfopenmeshf77 integer gmfclosemeshf77 integer gmfstatkwdf77 integer gmfsetkwdf77 integer gmfgotokwdf77 + integer gmfsethonodesorderingf77 integer gmfgetvertex integer gmfsetvertex - integer gmfgettriangle - integer gmfsettriangle - integer gmfgetquadrilateral - integer gmfsetquadrilateral - integer gmfgettetrahedron - integer gmfsettetrahedron - integer gmfsethonodesorderingf77 + integer gmfgetelement + integer gmfsetelement integer gmfgetvertices integer gmfsetvertices - integer gmfgettriangles - integer gmfsettriangles - integer gmfgetquadrilaterals - integer gmfsetquadrilaterals - integer gmfgettetrahedra - integer gmfsettetrahedra + integer gmfgetelements + integer gmfsetelements c Parameters definition From b2e5a263f153033e6f6ebfb0d9899a321bcda759 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Mar=C3=A9chal?= Date: Tue, 13 Feb 2024 10:48:51 +0100 Subject: [PATCH 14/38] Further modifications in fortran examples to silent gfortran-13's warnings --- examples/test_libmeshb.f | 9 +++++---- examples/test_libmeshb_block.f | 19 ++++++++++--------- sources/libmeshb7.c | 4 ++-- 3 files changed, 17 insertions(+), 15 deletions(-) diff --git a/examples/test_libmeshb.f b/examples/test_libmeshb.f index 730aaba..cad3f84 100644 --- a/examples/test_libmeshb.f +++ b/examples/test_libmeshb.f @@ -7,6 +7,7 @@ integer n parameter (n=4000) integer i,NmbVer,NmbQad,ver,dim,res,RefTab(n),QadTab(5,n),kwd + integer t(1),d,ho,s integer*8 InpMsh, OutMsh real*8 VerTab(3,n) @@ -24,9 +25,9 @@ if(dim.ne.3) STOP ' dimension <> 3' c Check memory bounds - NmbVer = gmfstatkwdf77(InpMsh, GmfVertices) + NmbVer = gmfstatkwdf77(InpMsh, GmfVertices, 0, s, t, 0, ho) if(NmbVer.gt.n) STOP 'Too many vertices' - NmbQad = gmfstatkwdf77(InpMsh, GmfQuadrilaterals) + NmbQad = gmfstatkwdf77(InpMsh, GmfQuadrilaterals, 0, s, t, 0, ho) if(NmbQad.gt.n) STOP 'Too many quads' print*, 'input mesh : ',NmbVer,' vertices,',NmbQad,'quads' @@ -56,7 +57,7 @@ print*, 'output IDX: ',OutMsh c Set the number of vertices - res = gmfsetkwdf77(OutMsh, GmfVertices, NmbVer, 0 , 0) + res = gmfsetkwdf77(OutMsh, GmfVertices, NmbVer, 0, t, 0, ho) c Then write them down do i = 1, NmbVer @@ -64,7 +65,7 @@ end do c Write the triangles - res = gmfsetkwdf77(OutMsh, GmfTriangles, 2*NmbQad, 0, 0) + res = gmfsetkwdf77(OutMsh, GmfTriangles, 2*NmbQad, 0, t, 0, ho) do i=1,NmbQad res = gmfsetelement(OutMsh, GmfTriangles, + QadTab(1,i), QadTab(5,i)) diff --git a/examples/test_libmeshb_block.f b/examples/test_libmeshb_block.f index 9d89d28..834211d 100644 --- a/examples/test_libmeshb_block.f +++ b/examples/test_libmeshb_block.f @@ -8,7 +8,8 @@ parameter (n=4000) integer i, ver, dim, res, NmbVer, NmbQad +, RefTab(n), TriTab(4,2*n), QadTab(5,n) - integer*8 InpMsh, OutMsh + integer t(1),d,ho,s + integer*8 InpMsh, OutMsh, m(1) real*8 VerTab(3,n) @@ -23,10 +24,10 @@ if(dim.ne.3) STOP ' dimension <> 3' c Check memory bounds - NmbVer = gmfstatkwdf77(InpMsh, GmfVertices) + NmbVer = gmfstatkwdf77(InpMsh, GmfVertices, 0, s, t, 0, ho) if(NmbVer.gt.n) STOP 'Too many vertices' - NmbQad = gmfstatkwdf77(InpMsh, GmfQuadrilaterals) + NmbQad = gmfstatkwdf77(InpMsh, GmfQuadrilaterals, 0, s, t, 0, ho) if(NmbQad.gt.n) STOP 'Too many quads' c Print some information on the open file @@ -39,13 +40,13 @@ c Read the vertices using a vector of 3 consecutive doubles c to store the coordinates res = gmfgetvertices(InpMsh, - + 1, NmbVer, 0, %val(0), + + 1, NmbVer, 0, m, + VerTab(1,1), VerTab(1,NmbVer), + RefTab( 1), RefTab( NmbVer)) c Read the quads using one single vector of 5 consecutive integers res = gmfgetelements(InpMsh, GmfQuadrilaterals, - + 1, NmbQad, 0, %val(0), + + 1, NmbQad, 0, m, + QadTab(1,1), QadTab(1,NmbQad), + QadTab(5,1), QadTab(5,NmbQad)) @@ -80,19 +81,19 @@ if(OutMsh.eq.0) STOP ' OutMsh = 0' c Set the number of vertices - res = gmfsetkwdf77(OutMsh, GmfVertices, NmbVer, 0, 0) + res = gmfsetkwdf77(OutMsh, GmfVertices, NmbVer, 0, t, 0, ho) c Write them down using separate pointers for each scalar entry res = gmfsetvertices(OutMsh, - + 1, NmbVer, 0, %val(0), + + 1, NmbVer, 0, m, + VerTab(1,1), VerTab(1,NmbVer), + RefTab(1), RefTab(NmbVer)) c Write the triangles using 4 independant set of arguments c for each scalar entry: node1, node2, node3 and reference - res = gmfsetkwdf77(OutMsh, GmfTriangles, 2*NmbQad, 0, 0) + res = gmfsetkwdf77(OutMsh, GmfTriangles, 2*NmbQad, 0, t, 0, ho) res = gmfsetelements(OutMsh, GmfTriangles, - + 1, 2*NmbQad, 0, %val(0), + + 1, 2*NmbQad, 0, m, + TriTab(1,1), TriTab(1,2*NmbQad), + TriTab(4,1), TriTab(4,2*NmbQad)) diff --git a/sources/libmeshb7.c b/sources/libmeshb7.c index ff87e84..95d4955 100644 --- a/sources/libmeshb7.c +++ b/sources/libmeshb7.c @@ -2979,7 +2979,7 @@ static int64_t GetFilSiz(GmfMshSct *msh) /*----------------------------------------------------------------------------*/ int64_t APIF77(gmfopenmeshf77)( char *FilNam, int *mod, - int *ver, int *dim, int StrSiz ) + int *ver, int *dim, long int StrSiz ) { int i = 0; char TmpNam[ GmfStrSiz ]; @@ -3013,7 +3013,7 @@ int APIF77(gmfgotokwdf77)(int64_t *MshIdx, int *KwdIdx) } int APIF77(gmfstatkwdf77)( int64_t *MshIdx, int *KwdIdx, int *NmbTyp, - int *SolSiz, int *TypTab, int *deg, int *NmbNod ) + int *SolSiz, int *TypTab, int *deg, int *NmbNod ) { if(!strcmp(GmfKwdFmt[ *KwdIdx ][2], "hr")) return(GmfStatKwd(*MshIdx, *KwdIdx, NmbTyp, SolSiz, TypTab, deg, NmbNod)); From f342cee2131e02edf55b41c3df51ba93748dbc43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Mar=C3=A9chal?= Date: Wed, 14 Feb 2024 13:06:55 +0100 Subject: [PATCH 15/38] Updated the documentation on how to compile with asynchronous and low-level IO --- Documentation/libMeshb7.pdf | Bin 249388 -> 264522 bytes Documentation/libMeshb7.tex | 12 +++++++----- examples/test_libmeshb.f | 6 +++--- examples/test_libmeshb_block.f | 4 ++-- sources/libmeshb7.c | 2 +- 5 files changed, 13 insertions(+), 11 deletions(-) diff --git a/Documentation/libMeshb7.pdf b/Documentation/libMeshb7.pdf index c398e2e6b82a9f7e7b23e12cba2070bb1ae0ab90..a3098d6f87723a4aaf41570dd459fc8b819707d0 100644 GIT binary patch delta 99751 zcmYJ4V|OM@7o~H@wylnBqhs5)ZQil%q+{Fa*mgR$ZF`@$&YM<(C zq=_Wt1aeST;`Dhl02RA z&JZ<=@!&uf1`Z%t|C&IOz`Q!;_Bqa-HD)qCOJt7tafDmQAzu=r*WpzUIsLhZ)sT3k zrpLo|I+hf*g^~^++FV_5B;&9G+74kU`Q-EJ+{c<`Q(W6VMh6hiWj%YsF<7LH;ii61_&NUi3HSNiAy!=sw z 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 delta 85274 zcmV)lK%c+Lk`Sz%50E4QF_*E00V#iVQcZ8vKn%U-SNNDn#A{E+^KsmzEiBq1sB)tm z(vYe}O;=48P*41IoJ^Lsf+~l3@z~Gyytk>d)fqc57Jcvx^);{y7>otaf`J9}v2yLHDF)I-ahDu=Q;5z%9ZRXAV zi_JWvixHe5WM8Ej>YGmcdCBi?ujb|z=U0CtLo+=7x4lF{6XezQ$5f^Y$qN`4b&h%5 zhYYQyD09X$IA2Ag`A1?n23LREp5bJ#q))Wvk+*zCyjjF#kA}rgD;ve6kbOX=m{#8H z3ns~b7nN9*$WXhy{rX~7%3CBWV6j@%*PLp;DH*MU^6BRE?fdmERj<;q{dlomzxhYk zPlMV+O#Z!VXFb(sgiePo4P)fR5a-R%PQF?!V2IdN>T}Pa2jTqI!WDixmj54)=CLP9045HVUO2wUxP6@ zNfFH`&EsO3TMj{pz?ZASy6HFvy75;I?3D@wC&hYQgqNRHa~1x3oCpkRvw!Yp{p7xu z$U&B*48olkD&=#xeA5dO9Sx81spU9Y{&N*9P`8P*t1fSKbs0vk{eZf^Ysbwp3|NgzoMvL*KJsY)P;f^6xA|_BR~kF1V$8Qm$kmT6qDc5GR5P ziu~e}z0o!jqob`al{;UVmq7O_8J6$u-z50= ztagXYYT2|t%`uSs`ZVc%`eeO2yJ_>bszP=WTz>cdxvwDQkRVC#!Vb=?tQ!@;$nnVS zKfw@z0D?oojr6YS$bX#M!hXD4dcn}KM5(XD(+h__;5n&n-Qr;sjm7r8@!(-R?2&p@ z5Dz1KWM_lDA(3H7`6CS}`$@Y>TS$Hgk>}|)I7k>EIt+{ZkI#6P5e zKtrV%b2{IJhV*D$^mQ}}`+-V6<;lPy4F=lWt;*sa}PLCl^Jd7uy{g5kE+dhkpQ%hEz!Vy8hpI zu04#0u2mEM>k`_+=!^ad-leM7${H8f0!t2VOdX$|7_0r0dxrCuG?WY*N_HChL0`rW zM4PH(7q3)nRe9TOGuXxRqe8sN!yKl=2V9M3#c5;Z zokf(k9bh+lo3I=dMl0*@y$^$}(g*?T;<8elEqtgDZIjr&T^b$MZ^ERNsn_ww zt9T2NzB?5eilB5w+s8j=s@^J&$QSqP zg-+p5#fi=q_s!y;NL^hkl@`%mf0e0d^260NjLmK}xuL)M_x?9lkjGhGrl=rUT&Hz^ ztU(X2kAsH4w`PLHx`^D!O2~J7gqfuyA=zi;<_m2-O^Z< zns>V=jYU0cEUKUpn73C|I%|aa=cGtJ{C*3AVutA(UNZ$fW*oueR7WdkCfhKxbxUvj zf$hoEsXZCQPE|G7MfQLsZoj-_dS1nUwVov(A+oT|lWQ!S0E~?{-8C*9ho^+8tUx#v~7ad077a!jnPnRXuc!dXYgAT@2#38dEwxxNue3>uD&nT)I;dmib)?f4^% zrH;JmHxxG7%MTq>Pbh2sWWUJTfk$3Fw1=&2JeLSKaKVwmv(G(dB>AsVX%*QO1axEu zYDFQ)S?|7_2Z<#F`-GS}v`>^?$az491$(oU>?P*Xj8@1sqt`2eFi&c(5+o3GaWp(|aE_57 zrtE|y$CPQ_72=bpHPp4~8AagBM3^4bDmY6BH{mT#PIW+LjBcF72*RtQF)e(VKb!)E z9M74tu!C>tv{XUIYgWjAM~qhrY;D`&m@N%+mzaA8rX3oA1ZG(b+h$4habVV0QK1DQ z-$7~^C{5CnNTLAW@DRLZ(U9jbp`w6%GOm{eJ)3jE)73x#zI1&+@FbUL<(QEj7+jVW zUS%rUdEoetB4X)y@~F3a7JlZ+$lTd5oJeu;#54_`eID(%uC=FsTI{2ocpmK@CAd(_ zzPaRr6i^A-LwObE`j!u4uJMq^GJ|@5}^ZNy?qnbL9(puxe{{` z8|E9~93irR5M1tm7%OkL7D|VpLfWPGJe;*5-$jGV@L%TomGG~0c^UrGT7_nX8Mj3s6DuajyAh06w&O zu01f_483J4Kqt~*dwbL_ykYm)iY&QLJUPU#n;&WY0Agm;&ZPlG;v}^i<`8J2h>SNM zKix6)o`)HKck?Rxtg;;PINU;rq&i-`4H`tHVc{)A4om)AiJp~^h6*)o-{L({SJ6$| zUOFx(-9c|H+nwr}hl%evYB&vTORCS#0q3S2f)tkz%Zv0Jdu{>O$Ce0!_i}p3n`iPy z`o)_+@5C|=Iuh+ThzVRfMG+a-nq_N$#{0224+#Z-)%D|BUcC;D?5) z8s6-Gr>ZU@IW`G#mYr9l{W2ji1Nh-v_*>5i!io|aeJb98ZabU@KIYl@XifkUnEYr$ z%J2|6YNX}8<|_YJ>E1(?YH!z)ASfX#%wgO5Kza{{i|bt zONSG9;WyVWA2;5H6ROWExrwV>QrE69?hoOSfFI_Y4rs$`2<>*A5f%18@^IL7qN6{s z``$x@;O;HbR6N1eax|VGqF)68YJFEzPiIWKyzsjSmxQ0pNtb*M*_3{GD-59C_u=t6 z;}g(se3lJoKj6^aB0nx{2F{5zE#pEI=kP)XyvW3u6hFQB_5RKO-a10wmj@&PCju}s zm(d#mD}URL+c*+^&sX%zU}YdybeBADxoid*AhW@A1B1oxKF|_v6Okp4D5vB3`mMt% z%5skyX~2NUVzF4P%c-K@J-mAJF)r`oINaoUa`&*iD--&~VN|Af56#_wf;h~=c(sn> zBoFS*UwXAp%RFd$`o@8_JUyy$)Whn355JPQe19%3x?3kn7#Af=duKW|Txe4i1^{IRXsA3z>k*=LWcZRs>O*^wf&*pH{dbPzEzeLSenkF*iy zxA*TqIrdLHulsZ7MC;+ChS7Sx@@Ryp%gNMqlpLEzKjDJ7QJjTYR`8AJ29|cj;cA_w zd4KR*4+WsnDh@igmnIEs=`NcTfe{|7aQZi#rG;`*wPvQizwwa6I%@h7%xUQ5q=E&~on7iZmp%7DXD|i=Uw~SSX

CCJBoq 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�W89gZTS6Ew9cLQXBd=N2NYly^Cidj41m6n_@gT< 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 z�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 K)58<2f&T(F7fH(i diff --git a/Documentation/libMeshb7.tex b/Documentation/libMeshb7.tex index 99bd6eb..830c8b2 100644 --- a/Documentation/libMeshb7.tex +++ b/Documentation/libMeshb7.tex @@ -36,9 +36,9 @@ \begin{flushright} \Large Lo\"ic MAR\'ECHAL / INRIA, Gamma Project\\ -\Large March 2019 \\ -\normalsize Document v1.92 \\ -\normalsize Library v7.60 +\Large February 2024 \\ +\normalsize Document v1.93 \\ +\normalsize Library v7.79 \end{flushright} \end{titlepage} @@ -80,7 +80,7 @@ \subsection{A comprehensive C library} Reading, writing and querying files is easily done by calling a couple of commands which are provided in an ANSI C file ``libmeshb7.c'' and a header file ``libmeshb7.h''. All is needed is compiling those files along with the calling software. -Fortran APIs are also available: ``libmeshb7.ins'' for F77 and F90. +A partial Fortran API is also available: ``libmeshb7.ins'' for F77 and F90. Refer to fortran\_api.md for more information. \subsection{ASCII vs. Binary} @@ -101,6 +101,8 @@ \subsubsection{About performance} The \emph{libMeshb} performs very poorly in ASCII mode, which is more processor bound rather than hard-drive bound. Don't expect more than 5 or 10 MB/s throughput. +Higher performance can be achieved through \emph{asynchronous} and \emph{low-level} I/O. This mode is enabled by setting a flag while compiling: (-DWITH\_GMF\_AIO) and linking with an additional library (-lrt). + \subsubsection{Compatibility issue: little vs. big endian} When it comes to binary storage, the compatibility problem posed by endianness always comes to mind. @@ -467,7 +469,7 @@ \subsubsection{Writing mode} \normalfont \paragraph{Asynchronous Input Output:} -to get best performance out of flash storage SSD (more than a GB/s), the library needs to access the filesystem through low-level functions and perform the reading and processing tasks in parallel using asynchronous I/O. To do so, you need to compile the library with the {\tt -DWITH\_GMF\_AIO} option and link the final executable with the {\tt -lrt} library under Linux. +to get best performance out of flash storage SSD (more than a GB/s), the library needs to access the filesystem through low-level functions and perform the reading and processing tasks in parallel using asynchronous I/O. To do so, you need to compile the library with the {\tt -DWITH\_AIO} option and link the final executable with the {\tt -lrt} library under Linux. \subsection{GmfCloseMesh} diff --git a/examples/test_libmeshb.f b/examples/test_libmeshb.f index cad3f84..a57107a 100644 --- a/examples/test_libmeshb.f +++ b/examples/test_libmeshb.f @@ -25,9 +25,9 @@ if(dim.ne.3) STOP ' dimension <> 3' c Check memory bounds - NmbVer = gmfstatkwdf77(InpMsh, GmfVertices, 0, s, t, 0, ho) + NmbVer = gmfstatkwdf77(InpMsh, GmfVertices, 0, s, t, d, ho) if(NmbVer.gt.n) STOP 'Too many vertices' - NmbQad = gmfstatkwdf77(InpMsh, GmfQuadrilaterals, 0, s, t, 0, ho) + NmbQad = gmfstatkwdf77(InpMsh, GmfQuadrilaterals, 0, s, t, d, ho) if(NmbQad.gt.n) STOP 'Too many quads' print*, 'input mesh : ',NmbVer,' vertices,',NmbQad,'quads' @@ -82,4 +82,4 @@ print*, 'output mesh: ',NmbVer,' vertices,', + 2*NmbQad,'triangles' - end + end diff --git a/examples/test_libmeshb_block.f b/examples/test_libmeshb_block.f index 834211d..84b4f13 100644 --- a/examples/test_libmeshb_block.f +++ b/examples/test_libmeshb_block.f @@ -24,10 +24,10 @@ if(dim.ne.3) STOP ' dimension <> 3' c Check memory bounds - NmbVer = gmfstatkwdf77(InpMsh, GmfVertices, 0, s, t, 0, ho) + NmbVer = gmfstatkwdf77(InpMsh, GmfVertices, 0, s, t, d, ho) if(NmbVer.gt.n) STOP 'Too many vertices' - NmbQad = gmfstatkwdf77(InpMsh, GmfQuadrilaterals, 0, s, t, 0, ho) + NmbQad = gmfstatkwdf77(InpMsh, GmfQuadrilaterals, 0, s, t, d, ho) if(NmbQad.gt.n) STOP 'Too many quads' c Print some information on the open file diff --git a/sources/libmeshb7.c b/sources/libmeshb7.c index 95d4955..87666ab 100644 --- a/sources/libmeshb7.c +++ b/sources/libmeshb7.c @@ -9,7 +9,7 @@ /* Description: handles .meshb file format I/O */ /* Author: Loic MARECHAL */ /* Creation date: dec 09 1999 */ -/* Last modification: feb 08 2024 */ +/* Last modification: feb 13 2024 */ /* */ /*----------------------------------------------------------------------------*/ From c4c818959cf9e18b50a0b4696aaac7b9a13adc07 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Mar=C3=A9chal?= Date: Wed, 14 Feb 2024 13:47:56 +0100 Subject: [PATCH 16/38] Added a basic readme for Fortran API --- Documentation/fortran_api.md | 91 ++++++++++++++++++++++++++++++++++++ 1 file changed, 91 insertions(+) create mode 100644 Documentation/fortran_api.md diff --git a/Documentation/fortran_api.md b/Documentation/fortran_api.md new file mode 100644 index 0000000..050db5a --- /dev/null +++ b/Documentation/fortran_api.md @@ -0,0 +1,91 @@ +## GENERAL COMMENTS + +Default datatypes throughout the API are 4-byte integers and 8-byte reals except for the library's index, which is an 8-byte integer. + +All procedures' arguments are fixed and no more variable arguments are used. + +The API is provided to access vertices and some elements. Adding new elements if straightforward but other arbitrary keywords need a dedicated API. + +See corresponding C procedures in the main documentation for further information about what these procedures are doing. This readme file is only intended for argument’s description. + + +## GENERAL PURPOSE PROCEDURES + +### gmfopenmeshf77( "filename", mode, version, dimension) + +Calls C GmfOpenMesh() with the same arguments. + +### gmfclosemeshf77(lib) + +Calls C GmfCloseMesh() with the same arguments. + + +### gmfgotokwdf77(lib, kwd) + +Calls C GmfGotoKwd() with the same arguments. + +### gmfstatkwdf77(lib, kwd, NmbTyp, SolSiz, TypTab, HOdeg, HOsiz) + +Calls C GmfStatKwd with the right arguments depending on whether the keyword is regular, HO or a solution. + +From Fortran you need to provide all arguments even if they are not needed. + +### gmfsetkwdf77(lib, kwd, NmbTyp, SolSiz, TypTab, HOdeg, HOsiz) + +Calls C GmfSetKwd with the right arguments depending on whether the keyword is regular, HO or a solution. + +From Fortran you need to provide all arguments even if they are not needed. + +### gmfsethonodesorderingf77(lib, kwd, source-ordering, destination-ordering) + +Calls C GmfSetHONodesOrdering() with the same arguments. + +## VERTICES + +Vertices data is split in two fields: a pointer to consecutive REAL8 to store coordinates and a pointer on an INT4 that stores the reference. + + +### gmfgetvertex(lib, coordinates, ref) + +Reads a single vertex. +Calls C GmfGetLin() with keyword GmfVertices, a pointer on a vector of 2 or 3 consecutive REAL8 and a pointer on an integer ref. + +### gmfsetvertex(lib, coordinates, ref) + +Writes a single vertex. +Calls C GmfSetLin() with keyword GmfVertices, a pointer on a vector of 2 or 3 consecutive REAL8 and the value of the integer ref. + +### gmfgetvertices(lib, start-index, end-index, map-type, map, start-coordinates, end-coordinate, start-ref, end-ref) + +Reads a block of vertices. +Calls C GmfGetBlock with GmfVertices and pointers to the first vertex coordinates, last vertex coordinates, first vertex reference and last vertex reference. + +### gmfsetvertices(lib, start-index, end-index, map-type, map, start-coordinates, end-coordinate, start-ref, end-ref) + +Writes a block of vertices. +Calls C GmfSetBlock with GmfVertices and pointers to the first vertex coordinates, last vertex coordinates, first vertex reference and last vertex reference. + + +## ELEMENTS + +Elements data is split in two fields: a pointer to consecutive INT4 to store nodes indices and a pointer on an INT4 that stores the reference. + +### gmfgetelement(lib, element-kind, nodes, ref) + +Reads a single element. +Calls C GmfGetLin() with the provided element keyword, a pointer on a vector of several consecutive INT4 to store nodes indices and a pointer on an integer ref. + +### gmfsetelement(lib, element-kind, nodes, ref) + +Writes a single element. +Calls C GmfSetLin() with the provided element keyword, a pointer on a vector of several consecutive INT4 to store nodes indices and a pointer on an integer ref. + +### gmfgetelements(lib, element-kind, start-index, end-index, map-type, map, start-nodes, end-nodes, start-ref, end-ref) + +Reads a block of elements. +Calls C GmfGetBlock() with the provided element keyword, a pointer on the first element's nodes, a pointer on the last element's nodes, a pointer on the first element's reference and a pointer on the last element's reference. + +### gmfsetelements(lib, element-kind, start-index, end-index, map-type, map, start-nodes, end-nodes, start-ref, end-ref) + +Writes a block of elements. +Calls C GmfSetBlock() with the provided element keyword, a pointer on the first element's nodes, a pointer on the last element's nodes, a pointer on the first element's reference and a pointer on the last element's reference. From 53483b266ba50ee418b46314499e8c9b37b2ea92 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Mar=C3=A9chal?= Date: Thu, 15 Feb 2024 11:50:37 +0100 Subject: [PATCH 17/38] Fortran API: added access to solution fields but only line by line --- Documentation/fortran_api.md | 16 +++++++++++++++ examples/test_libmeshb.f | 38 +++++++++++++++++++++++++++++++++--- sources/libmeshb7.c | 13 ++++++++++++ sources/libmeshb7.ins | 6 +++++- 4 files changed, 69 insertions(+), 4 deletions(-) diff --git a/Documentation/fortran_api.md b/Documentation/fortran_api.md index 050db5a..63cfbec 100644 --- a/Documentation/fortran_api.md +++ b/Documentation/fortran_api.md @@ -89,3 +89,19 @@ Calls C GmfGetBlock() with the provided element keyword, a pointer on the first Writes a block of elements. Calls C GmfSetBlock() with the provided element keyword, a pointer on the first element's nodes, a pointer on the last element's nodes, a pointer on the first element's reference and a pointer on the last element's reference. + + +## SOLUTIONS + +Solution fields are stored in REAL8 into a .sol or .solb file. +All fields must be stored in a consecutive table. + +### gmfgetsolution(lib, solution-keyword, solutions) + +Reads one line of solution fields concatenated into a single REAL8 table. +Calls C GmfGetLin() with the provided solution keyword and a pointer on a vector of sufficent consecutive REAL8 to store a whole line of solution fields. + +### gmfsetsolution(lib, solution-keyword, solutions) + +Writes one line of solution fields concatenated into a single REAL8 table. +Calls C GmfSetLin() with the provided solution keyword and a pointer on a vector of sufficient consecutive REAL8 to store a whole line of solution fields. diff --git a/examples/test_libmeshb.f b/examples/test_libmeshb.f index a57107a..ba76ce1 100644 --- a/examples/test_libmeshb.f +++ b/examples/test_libmeshb.f @@ -1,15 +1,16 @@ -c libMeshb 7.79 basic example: +c libMeshb 7.79 basic example: c read a quad mesh, split it into triangles and write the result back +c write an associated dummy .sol file containing some data include 'libmeshb7.ins' integer n parameter (n=4000) integer i,NmbVer,NmbQad,ver,dim,res,RefTab(n),QadTab(5,n),kwd - integer t(1),d,ho,s + integer t(10),d,ho,s integer*8 InpMsh, OutMsh - real*8 VerTab(3,n) + real*8 VerTab(3,n), sol(10) c -------------------------------------------- @@ -82,4 +83,35 @@ print*, 'output mesh: ',NmbVer,' vertices,', + 2*NmbQad,'triangles' + +c ---------------------- +c Create a solution file +c ---------------------- + + OutMsh = gmfopenmeshf77('tri.sol', GmfWrite, 2, 3) + if(OutMsh.eq.0) STOP ' OutMsh = 0' + print*, 'output IDX: ',OutMsh + +c Set the solution kinds + t(1) = GmfSca; + t(2) = GmfVec; + t(3) = GmfSca; +c Set the number of solutions (one per vertex) + res = gmfsetkwdf77(OutMsh, GmfSolAtVertices, NmbVer, 3, t, 0, ho) + +c Write the dummy solution fields + do i = 1, NmbVer + sol(1) = i + sol(2) = i*2 + sol(3) = i*3 + sol(4) = i*4 + sol(5) = -i + res = gmfsetsolution(OutMsh, GmfSolAtVertices, sol) + end do + +c Don't forget to close the file + res = gmfclosemeshf77(OutMsh) + + print*, 'output sol: ',NmbVer,' solutions' + end diff --git a/sources/libmeshb7.c b/sources/libmeshb7.c index 87666ab..0e0df67 100644 --- a/sources/libmeshb7.c +++ b/sources/libmeshb7.c @@ -3173,3 +3173,16 @@ int APIF77(gmfsetelements)(int64_t *MshIdx, int *kwd, int *BegIdx, int *EndIdx, GmfIntVec, EleSiz, BegEle, EndEle, GmfInt, BegRef, EndRef )); } + + +// SOLUTION FIELDS + +int APIF77(gmfgetsolution)(int64_t *MshIdx, int *kwd, double *sol) +{ + return(GmfGetLin(*MshIdx, *kwd, sol)); +} + +int APIF77(gmfsetsolution)(int64_t *MshIdx, int *kwd, double *sol) +{ + return(GmfSetLin(*MshIdx, *kwd, sol)); +} diff --git a/sources/libmeshb7.ins b/sources/libmeshb7.ins index 517fdac..7947997 100644 --- a/sources/libmeshb7.ins +++ b/sources/libmeshb7.ins @@ -9,7 +9,7 @@ c c Description: handles .meshb file format I/O c Author: Loic MARECHAL c Creation date: dec 08 2015 -c Last modification: feb 12 2024 +c Last modification: feb 15 2024 c c---------------------------------------------------------- @@ -29,6 +29,8 @@ c Procedures definition external gmfsetvertices external gmfgetelements external gmfsetelements + external gmfgetsolution + external gmfsetsolution integer*8 gmfopenmeshf77 integer gmfclosemeshf77 @@ -44,6 +46,8 @@ c Procedures definition integer gmfsetvertices integer gmfgetelements integer gmfsetelements + integer gmfgetsolution + integer gmfsetsolution c Parameters definition From 0b42c627a7f3d48ccdba3d71c1d57007e62e4165 Mon Sep 17 00:00:00 2001 From: Christophe Peyret Date: Mon, 19 Feb 2024 11:52:12 +0100 Subject: [PATCH 18/38] Ajout version fortran 90 --- examples/CMakeLists.txt | 10 +- examples/test_libmeshb.f90 | 127 +++ examples/test_libmeshb_block.f90 | 133 ++++ sources/CMakeLists.txt | 12 +- sources/libmeshb7_mod.f90 | 1269 +++++++++++++++--------------- 5 files changed, 919 insertions(+), 632 deletions(-) create mode 100644 examples/test_libmeshb.f90 create mode 100644 examples/test_libmeshb_block.f90 diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index c03da7d..8f1ccd4 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -41,8 +41,16 @@ if (CMAKE_Fortran_COMPILER) add_executable(test_libmeshb_f77 test_libmeshb.f) target_link_libraries(test_libmeshb_f77 Meshb.7 ${AIO_LIBRARIES}) install (TARGETS test_libmeshb_f77 DESTINATION share/libMeshb/examples COMPONENT examples) - + + add_executable(test_libmeshb_f90 test_libmeshb.f90) + target_link_libraries(test_libmeshb_f90 Meshb.7 ${AIO_LIBRARIES}) + install (TARGETS test_libmeshb_f90 DESTINATION share/libMeshb/examples COMPONENT examples) + add_executable(test_libmeshb_block_f77 test_libmeshb_block.f) target_link_libraries(test_libmeshb_block_f77 Meshb.7 ${AIO_LIBRARIES}) install (TARGETS test_libmeshb_block_f77 DESTINATION share/libMeshb/examples COMPONENT examples) + + add_executable(test_libmeshb_block_f90 test_libmeshb_block.f90) + target_link_libraries(test_libmeshb_block_f90 Meshb.7 ${AIO_LIBRARIES}) + install (TARGETS test_libmeshb_block_f90 DESTINATION share/libMeshb/examples COMPONENT examples) endif () diff --git a/examples/test_libmeshb.f90 b/examples/test_libmeshb.f90 new file mode 100644 index 0000000..d2a8cb8 --- /dev/null +++ b/examples/test_libmeshb.f90 @@ -0,0 +1,127 @@ + +! libMeshb 7.79 basic example: +! read a quad mesh, split it into triangles and write the result back +! write an associated dummy .sol file containing some data + +program test_libmeshb_f90 + !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + use iso_fortran_env + use libmeshb7 + !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + implicit none + + integer :: i + integer :: NmbVer,NmbQad,ver,dim,res,kwd + integer :: t(1:10),d,ho,s + integer(8) :: InpMsh, OutMsh + real(real64) :: sol(1:10) + real(real64), pointer :: VerTab(:,:) + integer , pointer :: VerRef( :) + integer , pointer :: QadTab(:,:) + integer , pointer :: QadRef( :) + !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + + !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + ! Open the quadrilateral mesh file for reading + + ! Open the mesh file and check the version and dimension + InpMsh = GmfOpenMeshf77('../sample_meshes/quad.mesh ', GmfRead,ver,dim) + print '("Input mesh :",i0," version: ",i0," dim: ",i0)',InpMsh,ver,dim + if( InpMsh==0) stop ' InpMsh = 0' + if( ver<=1 ) stop ' version <= 1' + if( dim/=3 ) stop ' dimension <> 3' + + ! Allocate VerTab and VerRef + NmbVer = Gmfstatkwdf77(InpMsh, GmfVertices, 0, s, t, d, ho) + allocate(VerTab(1:3,1:NmbVer)) + allocate(VerRef( 1:NmbVer)) + + ! Allocate QadTab and QadRef + NmbQad=Gmfstatkwdf77(InpMsh, GmfQuadrilaterals, 0, s, t, d, ho) + allocate(QadTab(1:4,1:NmbQad)) + allocate(QadRef( 1:NmbQad)) + + print '("Input mesh : ",i0," vertices: ",i0," quads")',NmbVer,NmbQad + + ! Read the quads + res=Gmfgotokwdf77(InpMsh, GmfQuadrilaterals) + do i=1,NmbQad + res=GmfGetElement(InpMsh, GmfQuadrilaterals, QadTab(1:4,i), QadRef(i)) + enddo + + ! Read the vertices + res = Gmfgotokwdf77(InpMsh, GmfVertices) + do i=1,NmbVer + res=GmfGetVertex(InpMsh, VerTab(1:3,i), VerRef(i)) + end do + + ! Close the quadrilateral mesh + res=GmfCloseMeshf77(InpMsh) + !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + + !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + ! Create a triangular mesh + + OutMsh=GmfOpenMeshf77('tri.mesh', GmfWrite, 2, 3) + if(OutMsh==0) STOP ' OutMsh = 0' + print '(/"output tri.mesh IDX: ",i0)',OutMsh + + ! Set the number of vertices + res=GmfSetKwdf77(OutMsh, GmfVertices, NmbVer, 0, t, 0, ho) + + ! Then write them down + do i=1,NmbVer + res=GmfSetVertex(OutMsh, VerTab(1:3,i), VerRef(i)) + end do + + ! Write the triangles + res = Gmfsetkwdf77(OutMsh, GmfTriangles, 2*NmbQad, 0, t, 0, ho) + do i=1,NmbQad + res=GmfSetElement(OutMsh, GmfTriangles, QadTab(1,i), QadRef(i)) + ! Modify the quad to build the other triangle's diagonal + QadTab(2,i) = QadTab(3,i); + QadTab(3,i) = QadTab(4,i); + res=GmfSetElement(OutMsh, GmfTriangles, QadTab(1,i), QadRef(i)) + end do + + ! Don't forget to close the file + res = GmfCloseMeshf77(OutMsh) + + + print '("output mesh: ",i0," vertices: ",i0," triangles")',NmbVer,2*NmbQad + !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + + !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + !> Cleanning Memory + deallocate(VerTab,VerRef) + deallocate(QadTab,QadRef) + !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + + !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + ! Create a solution file + + OutMsh = GmfOpenMeshf77('tri.sol', GmfWrite, 2, 3) + if(OutMsh==0) STOP ' OutMsh = 0' + print '("output IDX: ",i0)',OutMsh + + ! Set the solution kinds + t(1:3) = [GmfSca,GmfVec,GmfSca] + + ! Set the number of solutions (one per vertex) + res = Gmfsetkwdf77(OutMsh, GmfSolAtVertices, NmbVer, 3, t, 0, ho) + + ! Write the dummy solution fields + do i = 1, NmbVer + sol(1:4) = [i,2*i,3*i,4*i] + sol(5) = -i + res = Gmfsetsolution(OutMsh, GmfSolAtVertices, sol) + end do + + ! Don't forget to close the file + res = GmfCloseMeshf77(OutMsh) + + print '("output sol: ",i0," solutions")',NmbVer + !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + +end program test_libmeshb_f90 diff --git a/examples/test_libmeshb_block.f90 b/examples/test_libmeshb_block.f90 new file mode 100644 index 0000000..1c147ae --- /dev/null +++ b/examples/test_libmeshb_block.f90 @@ -0,0 +1,133 @@ + +! libMeshb 7.79 example: transform a quadrilateral mesh into a triangular one +! using fast block transfer + +program test_libmeshb_block_f90 + !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + use iso_fortran_env + use libmeshb7 + !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + implicit none + integer :: i + integer :: NmbVer,NmbQad,NmbTri,ver,dim,res + integer(8) :: InpMsh, OutMsh, m(1) + real(real64) :: sol(1:10) + real(real64), pointer :: VerTab(:,:) + integer , pointer :: VerRef( :) + integer , pointer :: QadTab(:,:),QadRef( :) + integer , pointer :: TriTab(:,:),TriRef( :) + integer :: t(1),d,ho,s + !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + + !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + ! Open the quadrilateral mesh file for reading + + ! Open the mesh file and check the version and dimension + InpMsh = GmfOpenMeshf77('../sample_meshes/quad.mesh ', GmfRead,ver,dim) + print '("Input mesh :",i0," version: ",i0," dim: ",i0)',InpMsh,ver,dim + if( InpMsh==0) stop ' InpMsh = 0' + if( ver<=1 ) stop ' version <= 1' + if( dim/=3 ) stop ' dimension <> 3' + + ! Allocate VerTab and VerRef + NmbVer = Gmfstatkwdf77(InpMsh, GmfVertices, 0, s, t, d, ho) + allocate(VerTab(1:3,1:NmbVer)) + allocate(VerRef( 1:NmbVer)) + + ! Allocate QadTab and QadRef + NmbQad=Gmfstatkwdf77(InpMsh, GmfQuadrilaterals, 0, s, t, d, ho) + allocate(QadTab(1:4,1:NmbQad)) + allocate(QadRef( 1:NmbQad)) + + print '("Input mesh : ",i0," vertices: ",i0," quads")',NmbVer,NmbQad + + print '("input mesh: ",i0)', InpMsh + print '("version : ",i0)', ver + print '("dimension : ",i0)', dim + print '("vertices : ",i0)', NmbVer + print '("quads : ",i0)', NmbQad + + ! Read the vertices using a vector of 3 consecutive doubles to store the coordinates + res=GmfGetVertices( & + & InpMsh ,& + & 1, NmbVer, 0, m ,& + & VerTab(1,1), VerTab(1,NmbVer) ,& + & VerRef( 1), VerRef( NmbVer) ) + + ! Read the quads using one single vector of 5 consecutive integers + res=GmfGetElements( & + & InpMsh ,& + & GmfQuadrilaterals ,& + & 1, NmbQad, 0, m ,& + & QadTab(1,1), QadTab(1,NmbQad),& + & QadRef( 1), QadRef( NmbQad) ) + + ! Close the quadrilateral mesh + res=GmfCloseMeshf77(InpMsh) + !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + + !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + ! Convert the quad mesh into a triangular one + + NmbTri=2*NmbQad + allocate(TriTab(1:3,1:NmbTri)) + allocate(TriRef( 1:NmbTri)) + + do i=1,NmbTri + if(mod(i,2) .EQ. 1) then + TriTab(1,i) = QadTab(1,(i+1)/2) + TriTab(2,i) = QadTab(2,(i+1)/2) + TriTab(3,i) = QadTab(3,(i+1)/2) + TriRef( i) = QadRef( (i+1)/2) + else + TriTab(1,i) = QadTab(1,(i+1)/2) + TriTab(2,i) = QadTab(3,(i+1)/2) + TriTab(3,i) = QadTab(4,(i+1)/2) + TriRef( i) = QadRef( (i+1)/2) + endif + end do + !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + + !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + ! Write a triangular mesh + + OutMsh = GmfOpenMeshf77('tri.meshb', GmfWrite, ver, dim) + if(OutMsh==0) STOP ' OutMsh = 0' + + ! Set the number of vertices + res=Gmfsetkwdf77(OutMsh, GmfVertices, NmbVer, 0, t, 0, ho) + + ! Write them down using separate pointers for each scalar entry + res=Gmfsetvertices( & + & OutMsh ,& + & 1, NmbVer, 0, m ,& + & VerTab(1,1), VerTab(1,NmbVer),& + & VerRef( 1), VerRef( NmbVer) ) + + ! Write the triangles using 4 independant set of arguments + ! for each scalar entry: node1, node2, node3 and reference + res=Gmfsetkwdf77(OutMsh, GmfTriangles, NmbTri, 0, t, 0, ho) + res = GmfSetElements( & + & OutMsh ,& + & GmfTriangles ,& + & 1, 2*NmbQad, 0, m ,& + & TriTab(1,1), TriTab(1,NmbTri),& + & TriRef( 1), TriRef( NmbTri) ) + + ! Don't forget to close the file + res = GmfCloseMeshf77(OutMsh) + + print '("output mesh :",i0," vertices: ",i0," triangles")',NmbVer,NmbTri + !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + + !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + !> Cleanning Memory + deallocate(VerTab,VerRef) + deallocate(QadTab,QadRef) + deallocate(TriTab,TriRef) + !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + + +end program test_libmeshb_block_f90 + diff --git a/sources/CMakeLists.txt b/sources/CMakeLists.txt index 381299c..1b1519c 100644 --- a/sources/CMakeLists.txt +++ b/sources/CMakeLists.txt @@ -3,7 +3,12 @@ # BUILD THE STATIC LIBRARY ########################## -add_library(Meshb.7 libmeshb7.c ../utilities/libmeshb7_helpers.c) +if(CMAKE_Fortran_COMPILER) + add_library(Meshb.7 libmeshb7.c ../utilities/libmeshb7_helpers.c libmeshb7_mod.f90) +else() + add_library(Meshb.7 libmeshb7.c ../utilities/libmeshb7_helpers.c) +endif() + install (FILES libmeshb7.h libmeshb7.ins ../utilities/libmeshb7_helpers.h DESTINATION include COMPONENT headers) target_include_directories( Meshb.7 PUBLIC $ @@ -12,5 +17,10 @@ install (TARGETS Meshb.7 EXPORT meshb-target DESTINATION lib COMPONENT libraries install (EXPORT meshb-target NAMESPACE ${PROJECT_NAME}:: DESTINATION lib/cmake/${PROJECT_NAME}) install (TARGETS Meshb.7 EXPORT libMeshb-target DESTINATION lib COMPONENT libraries) + +install(DIRECTORY ${CMAKE_Fortran_MODULE_DIRECTORY}/ DESTINATION include) + install (EXPORT libMeshb-target DESTINATION lib/cmake/${PROJECT_NAME}) export (PACKAGE libMeshb) + + diff --git a/sources/libmeshb7_mod.f90 b/sources/libmeshb7_mod.f90 index a770f2a..ce74b64 100644 --- a/sources/libmeshb7_mod.f90 +++ b/sources/libmeshb7_mod.f90 @@ -1,647 +1,656 @@ - - !---------------------------------------------------------- ! -! LIBMESH V 7.69 +! LIBMESH V 7.79 ! !---------------------------------------------------------- ! -! Description: handles .meshb file format I/O -! Author: Loic MARECHAL -! Creation date: dec 08 2015 -! Last modification: jan 15 2024 +! Description: handles .meshb file format I/O +! Author: Loic MARECHAL +! Creation date: dec 08 2015 +! Last modification: feb 12 2024 ! !---------------------------------------------------------- -module libmeshb7 + module libmeshb7 - use, intrinsic :: iso_c_binding, only: c_int,c_long,c_loc,c_ptr + use, intrinsic :: iso_c_binding, only: c_int,c_long,c_loc,c_ptr + + implicit none + + !Procedures definition + external gmfopenmeshf77 + external gmfclosemeshf77 + external gmfstatkwdf77 + external gmfsetkwdf77 + external gmfgotokwdf77 + external gmfsethonodesorderingf77 + external gmfgetvertex + external gmfsetvertex + external gmfgetelement + external gmfsetelement + external gmfgetvertices + external gmfsetvertices + external gmfgetelements + external gmfsetelements + external gmfgetsolution + external gmfsetsolution + - implicit none + integer*8 gmfopenmeshf77 + integer gmfclosemeshf77 + integer gmfstatkwdf77 + integer gmfsetkwdf77 + integer gmfgotokwdf77 + integer gmfsethonodesorderingf77 + integer gmfgetvertex + integer gmfsetvertex + integer gmfgetelement + integer gmfsetelement + integer gmfgetvertices + integer gmfsetvertices + integer gmfgetelements + integer gmfsetelements + integer gmfgetsolution + integer gmfsetsolution - !Procedures definition - external gmfopenmesh - external gmfclosemesh - external gmfstatkwd - external gmfsetkwd - external gmfgotokwd - external gmfgetlin - external gmfsetlin - external gmfgetblock - external gmfsetblock - external gmfsethonodesordering - - integer(8) :: gmfopenmesh - integer(4) :: gmfclosemesh - integer(4) :: gmfstatkwd - integer(4) :: gmfsetkwd - integer(4) :: gmfgotokwd - integer(4) :: gmfgetlin - integer(4) :: gmfsetlin - integer(4) :: gmfgetblock - integer(4) :: gmfsetblock - integer(4) :: gmfsethonodesordering - - - !Parameters definition - integer(4) :: gmfmaxtyp - integer(4) :: gmfmaxkwd - integer(4) :: gmfread - integer(4) :: gmfwrite - integer(4) :: gmfsca - integer(4) :: gmfvec - integer(4) :: gmfsymmat - integer(4) :: gmfmat - integer(4) :: gmffloat - integer(4) :: gmfdouble - integer(4) :: gmfint - integer(4) :: gmflong - integer(4) :: gmfinttab - integer(4) :: gmflongtab - integer(4) :: gmffloatvec - integer(4) :: gmfdoublevec - integer(4) :: gmfintvec - integer(4) :: gmflongvec - integer(4) :: gmfargtab - integer(4) :: gmfarglst - - parameter (gmfmaxtyp=1000) - parameter (gmfmaxkwd=207) - parameter (gmfread=1) - parameter (gmfwrite=2) - parameter (gmfsca=1) - parameter (gmfvec=2) - parameter (gmfsymmat=3) - parameter (gmfmat=4) - parameter (gmffloat=8) - parameter (gmfdouble=9) - parameter (gmfint=10) - parameter (gmflong=11) - parameter (gmfinttab=14) - parameter (gmflongtab=15) - parameter (gmffloatvec=12) - parameter (gmfdoublevec=13) - parameter (gmfintvec=14) - parameter (gmflongvec=15) - parameter (gmfargtab=100) - parameter (gmfarglst=101) - - - !Keywords list - integer(4) :: gmfmeshversionformatted - integer(4) :: gmfdimension - integer(4) :: gmfvertices - integer(4) :: gmfedges - integer(4) :: gmftriangles - integer(4) :: gmfquadrilaterals - integer(4) :: gmftetrahedra - integer(4) :: gmfprisms - integer(4) :: gmfhexahedra - integer(4) :: gmfiterationsall - integer(4) :: gmftimesall - integer(4) :: gmfcorners - integer(4) :: gmfridges - integer(4) :: gmfrequiredvertices - integer(4) :: gmfrequirededges - integer(4) :: gmfrequiredtriangles - integer(4) :: gmfrequiredquadrilaterals - integer(4) :: gmftangentatedgevertices - integer(4) :: gmfnormalatvertices - integer(4) :: gmfnormalattrianglevertices - integer(4) :: gmfnormalatquadrilateralvertices - integer(4) :: gmfangleofcornerbound - integer(4) :: gmftrianglesp2 - integer(4) :: gmfedgesp2 - integer(4) :: gmfsolatpyramids - integer(4) :: gmfquadrilateralsq2 - integer(4) :: gmfisolatpyramids - integer(4) :: gmfsubdomainfromgeom - integer(4) :: gmftetrahedrap2 - integer(4) :: gmffault_neartri - integer(4) :: gmffault_inter - integer(4) :: gmfhexahedraq2 - integer(4) :: gmfextraverticesatedges - integer(4) :: gmfextraverticesattriangles - integer(4) :: gmfextraverticesatquadrilaterals - integer(4) :: gmfextraverticesattetrahedra - integer(4) :: gmfextraverticesatprisms - integer(4) :: gmfextraverticesathexahedra - integer(4) :: gmfverticesongeometricvertices - integer(4) :: gmfverticesongeometricedges - integer(4) :: gmfverticesongeometrictriangles - integer(4) :: gmfverticesongeometricquadrilaterals - integer(4) :: gmfedgesongeometricedges - integer(4) :: gmffault_freeedge - integer(4) :: gmfpolyhedra - integer(4) :: gmfpolygons - integer(4) :: gmffault_overlap - integer(4) :: gmfpyramids - integer(4) :: gmfboundingbox - integer(4) :: gmfbody - integer(4) :: gmfprivatetable - integer(4) :: gmffault_badshape - integer(4) :: gmfend - integer(4) :: gmftrianglesongeometrictriangles - integer(4) :: gmftrianglesongeometricquadrilaterals - integer(4) :: gmfquadrilateralsongeometrictriangles - integer(4) :: gmfquadrilateralsongeometricquadrilaterals - integer(4) :: gmftangents - integer(4) :: gmfnormals - integer(4) :: gmftangentatvertices - integer(4) :: gmfsolatvertices - integer(4) :: gmfsolatedges - integer(4) :: gmfsolattriangles - integer(4) :: gmfsolatquadrilaterals - integer(4) :: gmfsolattetrahedra - integer(4) :: gmfsolatprisms - integer(4) :: gmfsolathexahedra - integer(4) :: gmfdsolatvertices - integer(4) :: gmfisolatvertices - integer(4) :: gmfisolatedges - integer(4) :: gmfisolattriangles - integer(4) :: gmfisolatquadrilaterals - integer(4) :: gmfisolattetrahedra - integer(4) :: gmfisolatprisms - integer(4) :: gmfisolathexahedra - integer(4) :: gmfiterations - integer(4) :: gmftime - integer(4) :: gmffault_smalltri - integer(4) :: gmfcoarsehexahedra - integer(4) :: gmfcomments - integer(4) :: gmfperiodicvertices - integer(4) :: gmfperiodicedges - integer(4) :: gmfperiodictriangles - integer(4) :: gmfperiodicquadrilaterals - integer(4) :: gmfprismsp2 - integer(4) :: gmfpyramidsp2 - integer(4) :: gmfquadrilateralsq3 - integer(4) :: gmfquadrilateralsq4 - integer(4) :: gmftrianglesp3 - integer(4) :: gmftrianglesp4 - integer(4) :: gmfedgesp3 - integer(4) :: gmfedgesp4 - integer(4) :: gmfirefgroups - integer(4) :: gmfdrefgroups - integer(4) :: gmftetrahedrap3 - integer(4) :: gmftetrahedrap4 - integer(4) :: gmfhexahedraq3 - integer(4) :: gmfhexahedraq4 - integer(4) :: gmfpyramidsp3 - integer(4) :: gmfpyramidsp4 - integer(4) :: gmfprismsp3 - integer(4) :: gmfprismsp4 - integer(4) :: gmfhosolatedgesp1 - integer(4) :: gmfhosolatedgesp2 - integer(4) :: gmfhosolatedgesp3 - integer(4) :: gmfhosolattrianglesp1 - integer(4) :: gmfhosolattrianglesp2 - integer(4) :: gmfhosolattrianglesp3 - integer(4) :: gmfhosolatquadrilateralsq1 - integer(4) :: gmfhosolatquadrilateralsq2 - integer(4) :: gmfhosolatquadrilateralsq3 - integer(4) :: gmfhosolattetrahedrap1 - integer(4) :: gmfhosolattetrahedrap2 - integer(4) :: gmfhosolattetrahedrap3 - integer(4) :: gmfhosolatpyramidsp1 - integer(4) :: gmfhosolatpyramidsp2 - integer(4) :: gmfhosolatpyramidsp3 - integer(4) :: gmfhosolatprismsp1 - integer(4) :: gmfhosolatprismsp2 - integer(4) :: gmfhosolatprismsp3 - integer(4) :: gmfhosolathexahedraq1 - integer(4) :: gmfhosolathexahedraq2 - integer(4) :: gmfhosolathexahedraq3 - integer(4) :: gmfbezierbasis - integer(4) :: gmfbyteflow - integer(4) :: gmfedgesp2ordering - integer(4) :: gmfedgesp3ordering - integer(4) :: gmftrianglesp2ordering - integer(4) :: gmftrianglesp3ordering - integer(4) :: gmfquadrilateralsq2ordering - integer(4) :: gmfquadrilateralsq3ordering - integer(4) :: gmftetrahedrap2ordering - integer(4) :: gmftetrahedrap3ordering - integer(4) :: gmfpyramidsp2ordering - integer(4) :: gmfpyramidsp3ordering - integer(4) :: gmfprismsp2ordering - integer(4) :: gmfprismsp3ordering - integer(4) :: gmfhexahedraq2ordering - integer(4) :: gmfhexahedraq3ordering - integer(4) :: gmfedgesp1ordering - integer(4) :: gmfedgesp4ordering - integer(4) :: gmftrianglesp1ordering - integer(4) :: gmftrianglesp4ordering - integer(4) :: gmfquadrilateralsq1ordering - integer(4) :: gmfquadrilateralsq4ordering - integer(4) :: gmftetrahedrap1ordering - integer(4) :: gmftetrahedrap4ordering - integer(4) :: gmfpyramidsp1ordering - integer(4) :: gmfpyramidsp4ordering - integer(4) :: gmfprismsp1ordering - integer(4) :: gmfprismsp4ordering - integer(4) :: gmfhexahedraq1ordering - integer(4) :: gmfhexahedraq4ordering - integer(4) :: gmffloatingpointprecision - integer(4) :: gmfhosolatedgesp4 - integer(4) :: gmfhosolattrianglesp4 - integer(4) :: gmfhosolatquadrilateralsq4 - integer(4) :: gmfhosolattetrahedrap4 - integer(4) :: gmfhosolatpyramidsp4 - integer(4) :: gmfhosolatprismsp4 - integer(4) :: gmfhosolathexahedraq4 - integer(4) :: gmfhosolatedgesp1nodespositions - integer(4) :: gmfhosolatedgesp2nodespositions - integer(4) :: gmfhosolatedgesp3nodespositions - integer(4) :: gmfhosolatedgesp4nodespositions - integer(4) :: gmfhosolattrianglesp1nodespositions - integer(4) :: gmfhosolattrianglesp2nodespositions - integer(4) :: gmfhosolattrianglesp3nodespositions - integer(4) :: gmfhosolattrianglesp4nodespositions - integer(4) :: gmfhosolatquadrilateralsq1nodespositions - integer(4) :: gmfhosolatquadrilateralsq2nodespositions - integer(4) :: gmfhosolatquadrilateralsq3nodespositions - integer(4) :: gmfhosolatquadrilateralsq4nodespositions - integer(4) :: gmfhosolattetrahedrap1nodespositions - integer(4) :: gmfhosolattetrahedrap2nodespositions - integer(4) :: gmfhosolattetrahedrap3nodespositions - integer(4) :: gmfhosolattetrahedrap4nodespositions - integer(4) :: gmfhosolatpyramidsp1nodespositions - integer(4) :: gmfhosolatpyramidsp2nodespositions - integer(4) :: gmfhosolatpyramidsp3nodespositions - integer(4) :: gmfhosolatpyramidsp4nodespositions - integer(4) :: gmfhosolatprismsp1nodespositions - integer(4) :: gmfhosolatprismsp2nodespositions - integer(4) :: gmfhosolatprismsp3nodespositions - integer(4) :: gmfhosolatprismsp4nodespositions - integer(4) :: gmfhosolathexahedraq1nodespositions - integer(4) :: gmfhosolathexahedraq2nodespositions - integer(4) :: gmfhosolathexahedraq3nodespositions - integer(4) :: gmfhosolathexahedraq4nodespositions - integer(4) :: gmfedgesreferenceelement - integer(4) :: gmftrianglereferenceelement - integer(4) :: gmfquadrilateralreferenceelement - integer(4) :: gmftetrahedronreferenceelement - integer(4) :: gmfpyramidreferenceelement - integer(4) :: gmfprismreferenceelement - integer(4) :: gmfhexahedronreferenceelement - integer(4) :: gmfboundarylayers - integer(4) :: gmfreferencestrings - integer(4) :: gmfprisms9 - integer(4) :: gmfhexahedra12 - integer(4) :: gmfquadrilaterals6 - integer(4) :: gmfboundarypolygonheaders - integer(4) :: gmfboundarypolygonvertices - integer(4) :: gmfinnerpolygonheaders - integer(4) :: gmfinnerpolygonvertices - integer(4) :: gmfpolyhedraheaders - integer(4) :: gmfpolyhedrafaces - integer(4) :: gmfdomains - integer(4) :: gmfverticesgid - integer(4) :: gmfedgesgid - integer(4) :: gmftrianglesgid - integer(4) :: gmfquadrilateralsgid - integer(4) :: gmftetrahedragid - integer(4) :: gmfpyramidsgid - integer(4) :: gmfprismsgid - integer(4) :: gmfhexahedragid - integer(4) :: gmfsolatboundarypolygons - integer(4) :: gmfsolatpolyhedra - integer(4) :: gmfverticesongeometrynodes - integer(4) :: gmfverticesongeometryedges - integer(4) :: gmfedgesongeometryedges - integer(4) :: gmfverticesongeometryfaces - integer(4) :: gmfedgesongeometryfaces - integer(4) :: gmftrianglesongeometryfaces - integer(4) :: gmfquadrialteralsongeometryfaces - integer(4) :: gmfmeshongeometry - - parameter (gmfmeshversionformatted=1) - parameter (gmfdimension=3) - parameter (gmfvertices=4) - parameter (gmfedges=5) - parameter (gmftriangles=6) - parameter (gmfquadrilaterals=7) - parameter (gmftetrahedra=8) - parameter (gmfprisms=9) - parameter (gmfhexahedra=10) - parameter (gmfiterationsall=11) - parameter (gmftimesall=12) - parameter (gmfcorners=13) - parameter (gmfridges=14) - parameter (gmfrequiredvertices=15) - parameter (gmfrequirededges=16) - parameter (gmfrequiredtriangles=17) - parameter (gmfrequiredquadrilaterals=18) - parameter (gmftangentatedgevertices=19) - parameter (gmfnormalatvertices=20) - parameter (gmfnormalattrianglevertices=21) - parameter (gmfnormalatquadrilateralvertices=22) - parameter (gmfangleofcornerbound=23) - parameter (gmftrianglesp2=24) - parameter (gmfedgesp2=25) - parameter (gmfsolatpyramids=26) - parameter (gmfquadrilateralsq2=27) - parameter (gmfisolatpyramids=28) - parameter (gmfsubdomainfromgeom=29) - parameter (gmftetrahedrap2=30) - parameter (gmffault_neartri=31) - parameter (gmffault_inter=32) - parameter (gmfhexahedraq2=33) - parameter (gmfextraverticesatedges=34) - parameter (gmfextraverticesattriangles=35) - parameter (gmfextraverticesatquadrilaterals=36) - parameter (gmfextraverticesattetrahedra=37) - parameter (gmfextraverticesatprisms=38) - parameter (gmfextraverticesathexahedra=39) - parameter (gmfverticesongeometricvertices=40) - parameter (gmfverticesongeometricedges=41) - parameter (gmfverticesongeometrictriangles=42) - parameter (gmfverticesongeometricquadrilaterals=43) - parameter (gmfedgesongeometricedges=44) - parameter (gmffault_freeedge=45) - parameter (gmfpolyhedra=46) - parameter (gmfpolygons=47) - parameter (gmffault_overlap=48) - parameter (gmfpyramids=49) - parameter (gmfboundingbox=50) - parameter (gmfbody=51) - parameter (gmfprivatetable=52) - parameter (gmffault_badshape=53) - parameter (gmfend=54) - parameter (gmftrianglesongeometrictriangles=55) - parameter (gmftrianglesongeometricquadrilaterals=56) - parameter (gmfquadrilateralsongeometrictriangles=57) - parameter (gmfquadrilateralsongeometricquadrilaterals=58) - parameter (gmftangents=59) - parameter (gmfnormals=60) - parameter (gmftangentatvertices=61) - parameter (gmfsolatvertices=62) - parameter (gmfsolatedges=63) - parameter (gmfsolattriangles=64) - parameter (gmfsolatquadrilaterals=65) - parameter (gmfsolattetrahedra=66) - parameter (gmfsolatprisms=67) - parameter (gmfsolathexahedra=68) - parameter (gmfdsolatvertices=69) - parameter (gmfisolatvertices=70) - parameter (gmfisolatedges=71) - parameter (gmfisolattriangles=72) - parameter (gmfisolatquadrilaterals=73) - parameter (gmfisolattetrahedra=74) - parameter (gmfisolatprisms=75) - parameter (gmfisolathexahedra=76) - parameter (gmfiterations=77) - parameter (gmftime=78) - parameter (gmffault_smalltri=79) - parameter (gmfcoarsehexahedra=80) - parameter (gmfcomments=81) - parameter (gmfperiodicvertices=82) - parameter (gmfperiodicedges=83) - parameter (gmfperiodictriangles=84) - parameter (gmfperiodicquadrilaterals=85) - parameter (gmfprismsp2=86) - parameter (gmfpyramidsp2=87) - parameter (gmfquadrilateralsq3=88) - parameter (gmfquadrilateralsq4=89) - parameter (gmftrianglesp3=90) - parameter (gmftrianglesp4=91) - parameter (gmfedgesp3=92) - parameter (gmfedgesp4=93) - parameter (gmfirefgroups=94) - parameter (gmfdrefgroups=95) - parameter (gmftetrahedrap3=96) - parameter (gmftetrahedrap4=97) - parameter (gmfhexahedraq3=98) - parameter (gmfhexahedraq4=99) - parameter (gmfpyramidsp3=100) - parameter (gmfpyramidsp4=101) - parameter (gmfprismsp3=102) - parameter (gmfprismsp4=103) - parameter (gmfhosolatedgesp1=104) - parameter (gmfhosolatedgesp2=105) - parameter (gmfhosolatedgesp3=106) - parameter (gmfhosolattrianglesp1=107) - parameter (gmfhosolattrianglesp2=108) - parameter (gmfhosolattrianglesp3=109) - parameter (gmfhosolatquadrilateralsq1=110) - parameter (gmfhosolatquadrilateralsq2=111) - parameter (gmfhosolatquadrilateralsq3=112) - parameter (gmfhosolattetrahedrap1=113) - parameter (gmfhosolattetrahedrap2=114) - parameter (gmfhosolattetrahedrap3=115) - parameter (gmfhosolatpyramidsp1=116) - parameter (gmfhosolatpyramidsp2=117) - parameter (gmfhosolatpyramidsp3=118) - parameter (gmfhosolatprismsp1=119) - parameter (gmfhosolatprismsp2=120) - parameter (gmfhosolatprismsp3=121) - parameter (gmfhosolathexahedraq1=122) - parameter (gmfhosolathexahedraq2=123) - parameter (gmfhosolathexahedraq3=124) - parameter (gmfbezierbasis=125) - parameter (gmfbyteflow=126) - parameter (gmfedgesp2ordering=127) - parameter (gmfedgesp3ordering=128) - parameter (gmftrianglesp2ordering=129) - parameter (gmftrianglesp3ordering=130) - parameter (gmfquadrilateralsq2ordering=131) - parameter (gmfquadrilateralsq3ordering=132) - parameter (gmftetrahedrap2ordering=133) - parameter (gmftetrahedrap3ordering=134) - parameter (gmfpyramidsp2ordering=135) - parameter (gmfpyramidsp3ordering=136) - parameter (gmfprismsp2ordering=137) - parameter (gmfprismsp3ordering=138) - parameter (gmfhexahedraq2ordering=139) - parameter (gmfhexahedraq3ordering=140) - parameter (gmfedgesp1ordering=141) - parameter (gmfedgesp4ordering=142) - parameter (gmftrianglesp1ordering=143) - parameter (gmftrianglesp4ordering=144) - parameter (gmfquadrilateralsq1ordering=145) - parameter (gmfquadrilateralsq4ordering=146) - parameter (gmftetrahedrap1ordering=147) - parameter (gmftetrahedrap4ordering=148) - parameter (gmfpyramidsp1ordering=149) - parameter (gmfpyramidsp4ordering=150) - parameter (gmfprismsp1ordering=151) - parameter (gmfprismsp4ordering=152) - parameter (gmfhexahedraq1ordering=153) - parameter (gmfhexahedraq4ordering=154) - parameter (gmffloatingpointprecision=155) - parameter (gmfhosolatedgesp4=156) - parameter (gmfhosolattrianglesp4=157) - parameter (gmfhosolatquadrilateralsq4=158) - parameter (gmfhosolattetrahedrap4=159) - parameter (gmfhosolatpyramidsp4=160) - parameter (gmfhosolatprismsp4=161) - parameter (gmfhosolathexahedraq4=162) - parameter (gmfhosolatedgesp1nodespositions=163) - parameter (gmfhosolatedgesp2nodespositions=164) - parameter (gmfhosolatedgesp3nodespositions=165) - parameter (gmfhosolatedgesp4nodespositions=166) - parameter (gmfhosolattrianglesp1nodespositions=167) - parameter (gmfhosolattrianglesp2nodespositions=168) - parameter (gmfhosolattrianglesp3nodespositions=169) - parameter (gmfhosolattrianglesp4nodespositions=170) - parameter (gmfhosolatquadrilateralsq1nodespositions=171) - parameter (gmfhosolatquadrilateralsq2nodespositions=172) - parameter (gmfhosolatquadrilateralsq3nodespositions=173) - parameter (gmfhosolatquadrilateralsq4nodespositions=174) - parameter (gmfhosolattetrahedrap1nodespositions=175) - parameter (gmfhosolattetrahedrap2nodespositions=176) - parameter (gmfhosolattetrahedrap3nodespositions=177) - parameter (gmfhosolattetrahedrap4nodespositions=178) - parameter (gmfhosolatpyramidsp1nodespositions=179) - parameter (gmfhosolatpyramidsp2nodespositions=180) - parameter (gmfhosolatpyramidsp3nodespositions=181) - parameter (gmfhosolatpyramidsp4nodespositions=182) - parameter (gmfhosolatprismsp1nodespositions=183) - parameter (gmfhosolatprismsp2nodespositions=184) - parameter (gmfhosolatprismsp3nodespositions=185) - parameter (gmfhosolatprismsp4nodespositions=186) - parameter (gmfhosolathexahedraq1nodespositions=187) - parameter (gmfhosolathexahedraq2nodespositions=188) - parameter (gmfhosolathexahedraq3nodespositions=189) - parameter (gmfhosolathexahedraq4nodespositions=190) - parameter (gmfedgesreferenceelement=191) - parameter (gmftrianglereferenceelement=192) - parameter (gmfquadrilateralreferenceelement=193) - parameter (gmftetrahedronreferenceelement=194) - parameter (gmfpyramidreferenceelement=195) - parameter (gmfprismreferenceelement=196) - parameter (gmfhexahedronreferenceelement=197) - parameter (gmfboundarylayers=198) - parameter (gmfreferencestrings=199) - parameter (gmfprisms9=200) - parameter (gmfhexahedra12=201) - parameter (gmfquadrilaterals6=202) - parameter (gmfboundarypolygonheaders=203) - parameter (gmfboundarypolygonvertices=204) - parameter (gmfinnerpolygonheaders=205) - parameter (gmfinnerpolygonvertices=206) - parameter (gmfpolyhedraheaders=207) - parameter (gmfpolyhedrafaces=208) - parameter (gmfdomains=209) - parameter (gmfverticesgid=210) - parameter (gmfedgesgid=211) - parameter (gmftrianglesgid=212) - parameter (gmfquadrilateralsgid=213) - parameter (gmftetrahedragid=214) - parameter (gmfpyramidsgid=215) - parameter (gmfprismsgid=216) - parameter (gmfhexahedragid=217) - parameter (gmfsolatboundarypolygons=218) - parameter (gmfsolatpolyhedra=219) - parameter (gmfverticesongeometrynodes=220) - parameter (gmfverticesongeometryedges=221) - parameter (gmfedgesongeometryedges=222) - parameter (gmfverticesongeometryfaces=223) - parameter (gmfedgesongeometryfaces=224) - parameter (gmftrianglesongeometryfaces=225) - parameter (gmfquadrialteralsongeometryfaces=226) - parameter (gmfmeshongeometry=227) - -! !> interface GmfSetHONodesOrdering_c -! interface -! function GmfSetHONodesOrdering_c(InpMsh, GmfKey, BasOrd, FilOrd) result(iErr) bind(c, name="GmfSetHONodesOrdering") -! !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -! import c_long,c_int,c_ptr -! !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< -! !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -! integer(c_long) , intent(in) :: InpMsh -! integer(c_int) , intent(in) :: GmfKey -! !integer(c_int) , intent(in) :: BasOrd(:,:) -! !integer(c_int) , intent(in) :: FilOrd(:,:) -! type(c_ptr) , intent(in) :: BasOrd -! type(c_ptr) , intent(in) :: FilOrd -! integer(c_int) :: iErr -! !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< -! end function GmfSetHONodesOrdering_c -! -! function GmfCloseMesh_c(InpMsh) result(iErr) bind(c, name="GmfCloseMesh") -! !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -! import c_long,c_int,c_ptr -! !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< -! !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -! integer(c_long) , intent(in) :: InpMsh -! integer(c_int) :: iErr -! !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< -! end function GmfCloseMesh_c -! -! end interface -! -! -! public :: GmfSetHONodesOrdering_f90 -! public :: GmfOpenMesh_f90 -! public :: GmfCloseMesh_f90 + ! Parameters definition + integer gmfmaxtyp + integer gmfmaxkwd + integer gmfread + integer gmfwrite + integer gmfsca + integer gmfvec + integer gmfsymmat + integer gmfmat + integer gmffloat + integer gmfdouble + integer gmfint + integer gmflong + integer gmfinttab + integer gmflongtab + integer gmffloatvec + integer gmfdoublevec + integer gmfintvec + integer gmflongvec + integer gmfargtab + integer gmfarglst - !> les lignes suivantes sont en conflit avec la variable integer(4) :: gmfsethonodesordering - !interface GmfSetHONodesOrdering - ! module procedure GmfSetHONodesOrdering_f90 - ! module procedure GmfSetHONodesOrdering_c - !end interface + parameter (gmfmaxtyp=1000) + parameter (gmfmaxkwd=227) + parameter (gmfread=1) + parameter (gmfwrite=2) + parameter (gmfsca=1) + parameter (gmfvec=2) + parameter (gmfsymmat=3) + parameter (gmfmat=4) + parameter (gmffloat=8) + parameter (gmfdouble=9) + parameter (gmfint=10) + parameter (gmflong=11) + parameter (gmfinttab=14) + parameter (gmflongtab=15) + parameter (gmffloatvec=12) + parameter (gmfdoublevec=13) + parameter (gmfintvec=14) + parameter (gmflongvec=15) + parameter (gmfargtab=100) + parameter (gmfarglst=101) -contains - -! subroutine GmfSetHONodesOrdering_f90(unit, GmfKey, BasOrd, FilOrd) -! !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -! use, intrinsic :: iso_c_binding, only: c_loc,c_int,c_long,c_ptr -! !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< -! !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -! integer(8), intent(in) :: unit -! integer(4), intent(in) :: GmfKey -! integer(4), intent(in), pointer :: BasOrd(:,:) -! integer(4), intent(in), pointer :: FilOrd(:,:) -! !> -! integer(c_int) :: iErr -! !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< -! !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -! !> Broker -! iErr=GmfSetHONodesOrdering_c( & -! & InpMsh=int(unit,kind=c_long) ,& -! & GmfKey=int(GmfKey,kind=c_int) ,& -! & BasOrd=c_loc(BasOrd) ,& -! & FilOrd=c_loc(FilOrd) ) -! !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< -! -! return -! end subroutine GmfSetHONodesOrdering_f90 -! -! subroutine GmfOpenMesh_f90(unit, GmfKey, BasOrd, FilOrd) -! !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -! use, intrinsic :: iso_c_binding, only: c_loc,c_int,c_long -! !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< -! !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -! integej1r(8), intent(in) :: unit -! !> -! integer(c_int) :: iErr -! !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< -! !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -! !> Broker -! iErr=GmfOpenMesh_c(InpMsh=int(unit,kind=c_long) ) -! !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< -! return -! end subroutine GmfOpenMesh_f90 -! -! subroutine GmfCloseMesh_f90(unit, GmfKey, BasOrd, FilOrd) -! !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -! use, intrinsic :: iso_c_binding, only: c_loc,c_int,c_long -! !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< -! !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -! integer(8), intent(in) :: unit -! !> -! integer(c_int) :: iErr -! !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< -! !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -! !> Broker -! iErr=GmfCloseMesh_c(InpMsh=int(unit,kind=c_long) ) -! !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< -! return -! end subroutine GmfCloseMesh_f90 - + ! Keywords list + integer gmfmeshversionformatted + integer gmfdimension + integer gmfvertices + integer gmfedges + integer gmftriangles + integer gmfquadrilaterals + integer gmftetrahedra + integer gmfprisms + integer gmfhexahedra + integer gmfiterationsall + integer gmftimesall + integer gmfcorners + integer gmfridges + integer gmfrequiredvertices + integer gmfrequirededges + integer gmfrequiredtriangles + integer gmfrequiredquadrilaterals + integer gmftangentatedgevertices + integer gmfnormalatvertices + integer gmfnormalattrianglevertices + integer gmfnormalatquadrilateralvertices + integer gmfangleofcornerbound + integer gmftrianglesp2 + integer gmfedgesp2 + integer gmfsolatpyramids + integer gmfquadrilateralsq2 + integer gmfisolatpyramids + integer gmfsubdomainfromgeom + integer gmftetrahedrap2 + integer gmffault_neartri + integer gmffault_inter + integer gmfhexahedraq2 + integer gmfextraverticesatedges + integer gmfextraverticesattriangles + integer gmfextraverticesatquadrilaterals + integer gmfextraverticesattetrahedra + integer gmfextraverticesatprisms + integer gmfextraverticesathexahedra + integer gmfverticesongeometricvertices + integer gmfverticesongeometricedges + integer gmfverticesongeometrictriangles + integer gmfverticesongeometricquadrilaterals + integer gmfedgesongeometricedges + integer gmffault_freeedge + integer gmfpolyhedra + integer gmfpolygons + integer gmffault_overlap + integer gmfpyramids + integer gmfboundingbox + integer gmfbody + integer gmfprivatetable + integer gmffault_badshape + integer gmfend + integer gmftrianglesongeometrictriangles + integer gmftrianglesongeometricquadrilaterals + integer gmfquadrilateralsongeometrictriangles + integer gmfquadrilateralsongeometricquadrilaterals + integer gmftangents + integer gmfnormals + integer gmftangentatvertices + integer gmfsolatvertices + integer gmfsolatedges + integer gmfsolattriangles + integer gmfsolatquadrilaterals + integer gmfsolattetrahedra + integer gmfsolatprisms + integer gmfsolathexahedra + integer gmfdsolatvertices + integer gmfisolatvertices + integer gmfisolatedges + integer gmfisolattriangles + integer gmfisolatquadrilaterals + integer gmfisolattetrahedra + integer gmfisolatprisms + integer gmfisolathexahedra + integer gmfiterations + integer gmftime + integer gmffault_smalltri + integer gmfcoarsehexahedra + integer gmfcomments + integer gmfperiodicvertices + integer gmfperiodicedges + integer gmfperiodictriangles + integer gmfperiodicquadrilaterals + integer gmfprismsp2 + integer gmfpyramidsp2 + integer gmfquadrilateralsq3 + integer gmfquadrilateralsq4 + integer gmftrianglesp3 + integer gmftrianglesp4 + integer gmfedgesp3 + integer gmfedgesp4 + integer gmfirefgroups + integer gmfdrefgroups + integer gmftetrahedrap3 + integer gmftetrahedrap4 + integer gmfhexahedraq3 + integer gmfhexahedraq4 + integer gmfpyramidsp3 + integer gmfpyramidsp4 + integer gmfprismsp3 + integer gmfprismsp4 + integer gmfhosolatedgesp1 + integer gmfhosolatedgesp2 + integer gmfhosolatedgesp3 + integer gmfhosolattrianglesp1 + integer gmfhosolattrianglesp2 + integer gmfhosolattrianglesp3 + integer gmfhosolatquadrilateralsq1 + integer gmfhosolatquadrilateralsq2 + integer gmfhosolatquadrilateralsq3 + integer gmfhosolattetrahedrap1 + integer gmfhosolattetrahedrap2 + integer gmfhosolattetrahedrap3 + integer gmfhosolatpyramidsp1 + integer gmfhosolatpyramidsp2 + integer gmfhosolatpyramidsp3 + integer gmfhosolatprismsp1 + integer gmfhosolatprismsp2 + integer gmfhosolatprismsp3 + integer gmfhosolathexahedraq1 + integer gmfhosolathexahedraq2 + integer gmfhosolathexahedraq3 + integer gmfbezierbasis + integer gmfbyteflow + integer gmfedgesp2ordering + integer gmfedgesp3ordering + integer gmftrianglesp2ordering + integer gmftrianglesp3ordering + integer gmfquadrilateralsq2ordering + integer gmfquadrilateralsq3ordering + integer gmftetrahedrap2ordering + integer gmftetrahedrap3ordering + integer gmfpyramidsp2ordering + integer gmfpyramidsp3ordering + integer gmfprismsp2ordering + integer gmfprismsp3ordering + integer gmfhexahedraq2ordering + integer gmfhexahedraq3ordering + integer gmfedgesp1ordering + integer gmfedgesp4ordering + integer gmftrianglesp1ordering + integer gmftrianglesp4ordering + integer gmfquadrilateralsq1ordering + integer gmfquadrilateralsq4ordering + integer gmftetrahedrap1ordering + integer gmftetrahedrap4ordering + integer gmfpyramidsp1ordering + integer gmfpyramidsp4ordering + integer gmfprismsp1ordering + integer gmfprismsp4ordering + integer gmfhexahedraq1ordering + integer gmfhexahedraq4ordering + integer gmffloatingpointprecision + integer gmfhosolatedgesp4 + integer gmfhosolattrianglesp4 + integer gmfhosolatquadrilateralsq4 + integer gmfhosolattetrahedrap4 + integer gmfhosolatpyramidsp4 + integer gmfhosolatprismsp4 + integer gmfhosolathexahedraq4 + integer gmfhosolatedgesp1nodespositions + integer gmfhosolatedgesp2nodespositions + integer gmfhosolatedgesp3nodespositions + integer gmfhosolatedgesp4nodespositions + integer gmfhosolattrianglesp1nodespositions + integer gmfhosolattrianglesp2nodespositions + integer gmfhosolattrianglesp3nodespositions + integer gmfhosolattrianglesp4nodespositions + integer gmfhosolatquadrilateralsq1nodespositions + integer gmfhosolatquadrilateralsq2nodespositions + integer gmfhosolatquadrilateralsq3nodespositions + integer gmfhosolatquadrilateralsq4nodespositions + integer gmfhosolattetrahedrap1nodespositions + integer gmfhosolattetrahedrap2nodespositions + integer gmfhosolattetrahedrap3nodespositions + integer gmfhosolattetrahedrap4nodespositions + integer gmfhosolatpyramidsp1nodespositions + integer gmfhosolatpyramidsp2nodespositions + integer gmfhosolatpyramidsp3nodespositions + integer gmfhosolatpyramidsp4nodespositions + integer gmfhosolatprismsp1nodespositions + integer gmfhosolatprismsp2nodespositions + integer gmfhosolatprismsp3nodespositions + integer gmfhosolatprismsp4nodespositions + integer gmfhosolathexahedraq1nodespositions + integer gmfhosolathexahedraq2nodespositions + integer gmfhosolathexahedraq3nodespositions + integer gmfhosolathexahedraq4nodespositions + integer gmfedgesreferenceelement + integer gmftrianglereferenceelement + integer gmfquadrilateralreferenceelement + integer gmftetrahedronreferenceelement + integer gmfpyramidreferenceelement + integer gmfprismreferenceelement + integer gmfhexahedronreferenceelement + integer gmfboundarylayers + integer gmfreferencestrings + integer gmfprisms9 + integer gmfhexahedra12 + integer gmfquadrilaterals6 + integer gmfboundarypolygonheaders + integer gmfboundarypolygonvertices + integer gmfinnerpolygonheaders + integer gmfinnerpolygonvertices + integer gmfpolyhedraheaders + integer gmfpolyhedrafaces + integer gmfdomains + integer gmfverticesgid + integer gmfedgesgid + integer gmftrianglesgid + integer gmfquadrilateralsgid + integer gmftetrahedragid + integer gmfpyramidsgid + integer gmfprismsgid + integer gmfhexahedragid + integer gmfsolatboundarypolygons + integer gmfsolatpolyhedra + integer gmfverticesongeometrynodes + integer gmfverticesongeometryedges + integer gmfedgesongeometryedges + integer gmfverticesongeometryfaces + integer gmfedgesongeometryfaces + integer gmftrianglesongeometryfaces + integer gmfquadrialteralsongeometryfaces + integer gmfmeshongeometry + parameter (gmfmeshversionformatted=1) + parameter (gmfdimension=3) + parameter (gmfvertices=4) + parameter (gmfedges=5) + parameter (gmftriangles=6) + parameter (gmfquadrilaterals=7) + parameter (gmftetrahedra=8) + parameter (gmfprisms=9) + parameter (gmfhexahedra=10) + parameter (gmfiterationsall=11) + parameter (gmftimesall=12) + parameter (gmfcorners=13) + parameter (gmfridges=14) + parameter (gmfrequiredvertices=15) + parameter (gmfrequirededges=16) + parameter (gmfrequiredtriangles=17) + parameter (gmfrequiredquadrilaterals=18) + parameter (gmftangentatedgevertices=19) + parameter (gmfnormalatvertices=20) + parameter (gmfnormalattrianglevertices=21) + parameter (gmfnormalatquadrilateralvertices=22) + parameter (gmfangleofcornerbound=23) + parameter (gmftrianglesp2=24) + parameter (gmfedgesp2=25) + parameter (gmfsolatpyramids=26) + parameter (gmfquadrilateralsq2=27) + parameter (gmfisolatpyramids=28) + parameter (gmfsubdomainfromgeom=29) + parameter (gmftetrahedrap2=30) + parameter (gmffault_neartri=31) + parameter (gmffault_inter=32) + parameter (gmfhexahedraq2=33) + parameter (gmfextraverticesatedges=34) + parameter (gmfextraverticesattriangles=35) + parameter (gmfextraverticesatquadrilaterals=36) + parameter (gmfextraverticesattetrahedra=37) + parameter (gmfextraverticesatprisms=38) + parameter (gmfextraverticesathexahedra=39) + parameter (gmfverticesongeometricvertices=40) + parameter (gmfverticesongeometricedges=41) + parameter (gmfverticesongeometrictriangles=42) + parameter (gmfverticesongeometricquadrilaterals=43) + parameter (gmfedgesongeometricedges=44) + parameter (gmffault_freeedge=45) + parameter (gmfpolyhedra=46) + parameter (gmfpolygons=47) + parameter (gmffault_overlap=48) + parameter (gmfpyramids=49) + parameter (gmfboundingbox=50) + parameter (gmfbody=51) + parameter (gmfprivatetable=52) + parameter (gmffault_badshape=53) + parameter (gmfend=54) + parameter (gmftrianglesongeometrictriangles=55) + parameter (gmftrianglesongeometricquadrilaterals=56) + parameter (gmfquadrilateralsongeometrictriangles=57) + parameter (gmfquadrilateralsongeometricquadrilaterals=58) + parameter (gmftangents=59) + parameter (gmfnormals=60) + parameter (gmftangentatvertices=61) + parameter (gmfsolatvertices=62) + parameter (gmfsolatedges=63) + parameter (gmfsolattriangles=64) + parameter (gmfsolatquadrilaterals=65) + parameter (gmfsolattetrahedra=66) + parameter (gmfsolatprisms=67) + parameter (gmfsolathexahedra=68) + parameter (gmfdsolatvertices=69) + parameter (gmfisolatvertices=70) + parameter (gmfisolatedges=71) + parameter (gmfisolattriangles=72) + parameter (gmfisolatquadrilaterals=73) + parameter (gmfisolattetrahedra=74) + parameter (gmfisolatprisms=75) + parameter (gmfisolathexahedra=76) + parameter (gmfiterations=77) + parameter (gmftime=78) + parameter (gmffault_smalltri=79) + parameter (gmfcoarsehexahedra=80) + parameter (gmfcomments=81) + parameter (gmfperiodicvertices=82) + parameter (gmfperiodicedges=83) + parameter (gmfperiodictriangles=84) + parameter (gmfperiodicquadrilaterals=85) + parameter (gmfprismsp2=86) + parameter (gmfpyramidsp2=87) + parameter (gmfquadrilateralsq3=88) + parameter (gmfquadrilateralsq4=89) + parameter (gmftrianglesp3=90) + parameter (gmftrianglesp4=91) + parameter (gmfedgesp3=92) + parameter (gmfedgesp4=93) + parameter (gmfirefgroups=94) + parameter (gmfdrefgroups=95) + parameter (gmftetrahedrap3=96) + parameter (gmftetrahedrap4=97) + parameter (gmfhexahedraq3=98) + parameter (gmfhexahedraq4=99) + parameter (gmfpyramidsp3=100) + parameter (gmfpyramidsp4=101) + parameter (gmfprismsp3=102) + parameter (gmfprismsp4=103) + parameter (gmfhosolatedgesp1=104) + parameter (gmfhosolatedgesp2=105) + parameter (gmfhosolatedgesp3=106) + parameter (gmfhosolattrianglesp1=107) + parameter (gmfhosolattrianglesp2=108) + parameter (gmfhosolattrianglesp3=109) + parameter (gmfhosolatquadrilateralsq1=110) + parameter (gmfhosolatquadrilateralsq2=111) + parameter (gmfhosolatquadrilateralsq3=112) + parameter (gmfhosolattetrahedrap1=113) + parameter (gmfhosolattetrahedrap2=114) + parameter (gmfhosolattetrahedrap3=115) + parameter (gmfhosolatpyramidsp1=116) + parameter (gmfhosolatpyramidsp2=117) + parameter (gmfhosolatpyramidsp3=118) + parameter (gmfhosolatprismsp1=119) + parameter (gmfhosolatprismsp2=120) + parameter (gmfhosolatprismsp3=121) + parameter (gmfhosolathexahedraq1=122) + parameter (gmfhosolathexahedraq2=123) + parameter (gmfhosolathexahedraq3=124) + parameter (gmfbezierbasis=125) + parameter (gmfbyteflow=126) + parameter (gmfedgesp2ordering=127) + parameter (gmfedgesp3ordering=128) + parameter (gmftrianglesp2ordering=129) + parameter (gmftrianglesp3ordering=130) + parameter (gmfquadrilateralsq2ordering=131) + parameter (gmfquadrilateralsq3ordering=132) + parameter (gmftetrahedrap2ordering=133) + parameter (gmftetrahedrap3ordering=134) + parameter (gmfpyramidsp2ordering=135) + parameter (gmfpyramidsp3ordering=136) + parameter (gmfprismsp2ordering=137) + parameter (gmfprismsp3ordering=138) + parameter (gmfhexahedraq2ordering=139) + parameter (gmfhexahedraq3ordering=140) + parameter (gmfedgesp1ordering=141) + parameter (gmfedgesp4ordering=142) + parameter (gmftrianglesp1ordering=143) + parameter (gmftrianglesp4ordering=144) + parameter (gmfquadrilateralsq1ordering=145) + parameter (gmfquadrilateralsq4ordering=146) + parameter (gmftetrahedrap1ordering=147) + parameter (gmftetrahedrap4ordering=148) + parameter (gmfpyramidsp1ordering=149) + parameter (gmfpyramidsp4ordering=150) + parameter (gmfprismsp1ordering=151) + parameter (gmfprismsp4ordering=152) + parameter (gmfhexahedraq1ordering=153) + parameter (gmfhexahedraq4ordering=154) + parameter (gmffloatingpointprecision=155) + parameter (gmfhosolatedgesp4=156) + parameter (gmfhosolattrianglesp4=157) + parameter (gmfhosolatquadrilateralsq4=158) + parameter (gmfhosolattetrahedrap4=159) + parameter (gmfhosolatpyramidsp4=160) + parameter (gmfhosolatprismsp4=161) + parameter (gmfhosolathexahedraq4=162) + parameter (gmfhosolatedgesp1nodespositions=163) + parameter (gmfhosolatedgesp2nodespositions=164) + parameter (gmfhosolatedgesp3nodespositions=165) + parameter (gmfhosolatedgesp4nodespositions=166) + parameter (gmfhosolattrianglesp1nodespositions=167) + parameter (gmfhosolattrianglesp2nodespositions=168) + parameter (gmfhosolattrianglesp3nodespositions=169) + parameter (gmfhosolattrianglesp4nodespositions=170) + parameter (gmfhosolatquadrilateralsq1nodespositions=171) + parameter (gmfhosolatquadrilateralsq2nodespositions=172) + parameter (gmfhosolatquadrilateralsq3nodespositions=173) + parameter (gmfhosolatquadrilateralsq4nodespositions=174) + parameter (gmfhosolattetrahedrap1nodespositions=175) + parameter (gmfhosolattetrahedrap2nodespositions=176) + parameter (gmfhosolattetrahedrap3nodespositions=177) + parameter (gmfhosolattetrahedrap4nodespositions=178) + parameter (gmfhosolatpyramidsp1nodespositions=179) + parameter (gmfhosolatpyramidsp2nodespositions=180) + parameter (gmfhosolatpyramidsp3nodespositions=181) + parameter (gmfhosolatpyramidsp4nodespositions=182) + parameter (gmfhosolatprismsp1nodespositions=183) + parameter (gmfhosolatprismsp2nodespositions=184) + parameter (gmfhosolatprismsp3nodespositions=185) + parameter (gmfhosolatprismsp4nodespositions=186) + parameter (gmfhosolathexahedraq1nodespositions=187) + parameter (gmfhosolathexahedraq2nodespositions=188) + parameter (gmfhosolathexahedraq3nodespositions=189) + parameter (gmfhosolathexahedraq4nodespositions=190) + parameter (gmfedgesreferenceelement=191) + parameter (gmftrianglereferenceelement=192) + parameter (gmfquadrilateralreferenceelement=193) + parameter (gmftetrahedronreferenceelement=194) + parameter (gmfpyramidreferenceelement=195) + parameter (gmfprismreferenceelement=196) + parameter (gmfhexahedronreferenceelement=197) + parameter (gmfboundarylayers=198) + parameter (gmfreferencestrings=199) + parameter (gmfprisms9=200) + parameter (gmfhexahedra12=201) + parameter (gmfquadrilaterals6=202) + parameter (gmfboundarypolygonheaders=203) + parameter (gmfboundarypolygonvertices=204) + parameter (gmfinnerpolygonheaders=205) + parameter (gmfinnerpolygonvertices=206) + parameter (gmfpolyhedraheaders=207) + parameter (gmfpolyhedrafaces=208) + parameter (gmfdomains=209) + parameter (gmfverticesgid=210) + parameter (gmfedgesgid=211) + parameter (gmftrianglesgid=212) + parameter (gmfquadrilateralsgid=213) + parameter (gmftetrahedragid=214) + parameter (gmfpyramidsgid=215) + parameter (gmfprismsgid=216) + parameter (gmfhexahedragid=217) + parameter (gmfsolatboundarypolygons=218) + parameter (gmfsolatpolyhedra=219) + parameter (gmfverticesongeometrynodes=220) + parameter (gmfverticesongeometryedges=221) + parameter (gmfedgesongeometryedges=222) + parameter (gmfverticesongeometryfaces=223) + parameter (gmfedgesongeometryfaces=224) + parameter (gmftrianglesongeometryfaces=225) + parameter (gmfquadrialteralsongeometryfaces=226) + parameter (gmfmeshongeometry=227) -end module libmeshb7 + ! !> interface GmfSetHONodesOrdering_c + ! interface + ! function GmfSetHONodesOrdering_c(InpMsh, GmfKey, BasOrd, FilOrd) result(iErr) bind(c, name="GmfSetHONodesOrdering") + ! !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + ! import c_long,c_int,c_ptr + ! !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + ! !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + ! integer(c_long) , intent(in) :: InpMsh + ! integer(c_int) , intent(in) :: GmfKey + ! !integer(c_int) , intent(in) :: BasOrd(:,:) + ! !integer(c_int) , intent(in) :: FilOrd(:,:) + ! type(c_ptr) , intent(in) :: BasOrd + ! type(c_ptr) , intent(in) :: FilOrd + ! integer(c_int) :: iErr + ! !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + ! end function GmfSetHONodesOrdering_c + ! + ! function GmfCloseMesh_c(InpMsh) result(iErr) bind(c, name="GmfCloseMesh") + ! !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + ! import c_long,c_int,c_ptr + ! !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + ! !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + ! integer(c_long) , intent(in) :: InpMsh + ! integer(c_int) :: iErr + ! !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + ! end function GmfCloseMesh_c + ! + ! end interface + ! + ! + ! public :: GmfSetHONodesOrdering_f90 + ! public :: GmfOpenMesh_f90 + ! public :: GmfCloseMesh_f90 + + + !> les lignes suivantes sont en conflit avec la variable integer(4) :: gmfsethonodesordering + !interface GmfSetHONodesOrdering + ! module procedure GmfSetHONodesOrdering_f90 + ! module procedure GmfSetHONodesOrdering_c + !end interface + + contains + + ! subroutine GmfSetHONodesOrdering_f90(unit, GmfKey, BasOrd, FilOrd) + ! !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + ! use, intrinsic :: iso_c_binding, only: c_loc,c_int,c_long,c_ptr + ! !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + ! !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + ! integer(8), intent(in) :: unit + ! integer(4), intent(in) :: GmfKey + ! integer(4), intent(in), pointer :: BasOrd(:,:) + ! integer(4), intent(in), pointer :: FilOrd(:,:) + ! !> + ! integer(c_int) :: iErr + ! !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + ! !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + ! !> Broker + ! iErr=GmfSetHONodesOrdering_c( & + ! & InpMsh=int(unit,kind=c_long) ,& + ! & GmfKey=int(GmfKey,kind=c_int) ,& + ! & BasOrd=c_loc(BasOrd) ,& + ! & FilOrd=c_loc(FilOrd) ) + ! !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + ! + ! return + ! end subroutine GmfSetHONodesOrdering_f90 + ! + ! subroutine GmfOpenMesh_f90(unit, GmfKey, BasOrd, FilOrd) + ! !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + ! use, intrinsic :: iso_c_binding, only: c_loc,c_int,c_long + ! !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + ! !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + ! integej1r(8), intent(in) :: unit + ! !> + ! integer(c_int) :: iErr + ! !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + ! !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + ! !> Broker + ! iErr=GmfOpenMesh_c(InpMsh=int(unit,kind=c_long) ) + ! !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + ! return + ! end subroutine GmfOpenMesh_f90 + ! + ! subroutine GmfCloseMesh_f90(unit, GmfKey, BasOrd, FilOrd) + ! !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + ! use, intrinsic :: iso_c_binding, only: c_loc,c_int,c_long + ! !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + ! !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + ! integer(8), intent(in) :: unit + ! !> + ! integer(c_int) :: iErr + ! !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + ! !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + ! !> Broker + ! iErr=GmfCloseMesh_c(InpMsh=int(unit,kind=c_long) ) + ! !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + ! return + ! end subroutine GmfCloseMesh_f90 + + + end module libmeshb7 \ No newline at end of file From 0bf403507866eaf426127fbdf437f86d5fb1b89d Mon Sep 17 00:00:00 2001 From: Christophe Peyret Date: Mon, 19 Feb 2024 14:02:41 +0100 Subject: [PATCH 19/38] Ajout exemple test_libmeshb_HO_f90 --- examples/CMakeLists.txt | 4 + examples/test_libmeshb.f90 | 34 +++++-- examples/test_libmeshb_HO.f90 | 170 +++++++++++++++++++++++++++++++ examples/test_libmeshb_block.f90 | 60 +++++++---- 4 files changed, 242 insertions(+), 26 deletions(-) create mode 100644 examples/test_libmeshb_HO.f90 diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 8f1ccd4..e59d1ad 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -53,4 +53,8 @@ if (CMAKE_Fortran_COMPILER) add_executable(test_libmeshb_block_f90 test_libmeshb_block.f90) target_link_libraries(test_libmeshb_block_f90 Meshb.7 ${AIO_LIBRARIES}) install (TARGETS test_libmeshb_block_f90 DESTINATION share/libMeshb/examples COMPONENT examples) + + add_executable(test_libmeshb_HO_f90 test_libmeshb_HO.f90) + target_link_libraries(test_libmeshb_HO_f90 Meshb.7 ${AIO_LIBRARIES}) + install (TARGETS test_libmeshb_HO_f90 DESTINATION share/libMeshb/examples COMPONENT examples) endif () diff --git a/examples/test_libmeshb.f90 b/examples/test_libmeshb.f90 index d2a8cb8..585e3b7 100644 --- a/examples/test_libmeshb.f90 +++ b/examples/test_libmeshb.f90 @@ -11,10 +11,12 @@ program test_libmeshb_f90 !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> implicit none + integer(8) :: InpMsh, OutMsh + character(80) :: InpFile + character(80) :: OutFile integer :: i - integer :: NmbVer,NmbQad,ver,dim,res,kwd + integer :: NmbVer,NmbQad,NmbTri,ver,dim,res,kwd integer :: t(1:10),d,ho,s - integer(8) :: InpMsh, OutMsh real(real64) :: sol(1:10) real(real64), pointer :: VerTab(:,:) integer , pointer :: VerRef( :) @@ -22,12 +24,21 @@ program test_libmeshb_f90 integer , pointer :: QadRef( :) !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + print '(/"test_libmeshb_f90")' + !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + + !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + InpFile='../sample_meshes/quad.mesh' + OutFile='./tri.meshb' + !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ! Open the quadrilateral mesh file for reading ! Open the mesh file and check the version and dimension - InpMsh = GmfOpenMeshf77('../sample_meshes/quad.mesh ', GmfRead,ver,dim) - print '("Input mesh :",i0," version: ",i0," dim: ",i0)',InpMsh,ver,dim + InpMsh = GmfOpenMeshf77(trim(InpFile),GmfRead,ver,dim) + print '(/"Input Mesh File: ",a," Idx=",i0," version: ",i0," dim: ",i0)',trim(InpFile),InpMsh,ver,dim if( InpMsh==0) stop ' InpMsh = 0' if( ver<=1 ) stop ' version <= 1' if( dim/=3 ) stop ' dimension <> 3' @@ -62,10 +73,13 @@ program test_libmeshb_f90 !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ! Create a triangular mesh + NmbTri=2*NmbQad - OutMsh=GmfOpenMeshf77('tri.mesh', GmfWrite, 2, 3) + OutMsh = GmfOpenMeshf77(trim(OutFile), GmfWrite, ver, dim) + print '(/"Output Mesh File: ",a," Idx=",i0," version: ",i0," dim: ",i0)',trim(OutFile),OutMsh,ver,dim + print '( "vertices : ",i0)', NmbVer + print '( "triangles : ",i0)', NmbTri if(OutMsh==0) STOP ' OutMsh = 0' - print '(/"output tri.mesh IDX: ",i0)',OutMsh ! Set the number of vertices res=GmfSetKwdf77(OutMsh, GmfVertices, NmbVer, 0, t, 0, ho) @@ -97,7 +111,7 @@ program test_libmeshb_f90 deallocate(VerTab,VerRef) deallocate(QadTab,QadRef) !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - + !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ! Create a solution file @@ -124,4 +138,10 @@ program test_libmeshb_f90 print '("output sol: ",i0," solutions")',NmbVer !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + print '(/"vizir4 -in ",a," -sol tri.sol")',trim(OutFile) + print '(/"test_libmeshb_f90")' + !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + + end program test_libmeshb_f90 diff --git a/examples/test_libmeshb_HO.f90 b/examples/test_libmeshb_HO.f90 new file mode 100644 index 0000000..be66021 --- /dev/null +++ b/examples/test_libmeshb_HO.f90 @@ -0,0 +1,170 @@ + +! libMeshb 7 basic example: +! read a Q2 quad mesh while using the automatic HO reordering feature, +! split it into P2 triangles and write the result back using fast block transfer + +program test_libmeshb_HO_f90 + !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + use iso_fortran_env + use libmeshb7 + !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + implicit none + integer(8) :: InpMsh, OutMsh, m(1) + character(80) :: InpFile + character(80) :: OutFile + integer :: i,iTria + integer :: NmbVer,NmbQad,NmbTri,ver,dim,res + real(real64) :: sol(1:10) + real(real64), pointer :: VerTab(:,:) + integer , pointer :: VerRef( :) + integer , pointer :: QadTab(:,:),QadRef( :) + integer , pointer :: TriTab(:,:),TriRef( :) + integer :: t(1),d,ho,s + !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + + !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + print '(/"test_libmeshb_HO_f90")' + !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + + !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + InpFile='../sample_meshes/quad_q2.mesh' + OutFile='./tri_p2.mesh' + !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + + !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + ! Open the quadrilateral mesh file for reading + + ! Open the mesh file and check the version and dimension + InpMsh = GmfOpenMeshf77(trim(InpFile),GmfRead,ver,dim) + print '(/"Input Mesh File: ",a," Idx=",i0," version: ",i0," dim: ",i0)',trim(InpFile),InpMsh,ver,dim + if( InpMsh==0) stop ' InpMsh = 0' + if( ver<=1 ) stop ' version <= 1' + if( dim/=3 ) stop ' dimension <> 3' + + ! Allocate VerTab and VerRef + NmbVer = Gmfstatkwdf77(InpMsh, GmfVertices, 0, s, t, d, ho) + allocate(VerTab(1:3,1:NmbVer)) + allocate(VerRef( 1:NmbVer)) + + ! Allocate QadTab and QadRef + NmbQad=Gmfstatkwdf77(InpMsh, GmfQuadrilateralsQ2, 0, s, t, d, ho) + allocate(QadTab(1:9,1:NmbQad)) + allocate(QadRef( 1:NmbQad)) + + print '("Input mesh : ",i0," vertices: ",i0," quadsQ2")',NmbVer,NmbQad + + print '("input mesh: ",i0)', InpMsh + print '("version : ",i0)', ver + print '("dimension : ",i0)', dim + print '("vertices : ",i0)', NmbVer + print '("quadsQ2 : ",i0)', NmbQad + + ! Read the vertices using a vector of 3 consecutive doubles to store the coordinates + res=GmfGetVertices( & + & InpMsh ,& + & 1 ,& + & NmbVer ,& + & 0, m ,& + & VerTab(1,1), VerTab(1,NmbVer) ,& + & VerRef( 1), VerRef( NmbVer) ) + + ! Read the quads using one single vector of 5 consecutive integers + res=GmfGetElements( & + & InpMsh ,& + & GmfQuadrilateralsQ2 ,& + & 1 ,& + & NmbQad ,& + & 0, m ,& + & QadTab(1,1), QadTab(1,NmbQad),& + & QadRef( 1), QadRef( NmbQad) ) + + ! Close the quadrilateral mesh + res=GmfCloseMeshf77(InpMsh) + !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + + !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + + ! Allocate TriTab and TriRef + NmbTri=2*NmbQad + allocate(TriTab(1:6,1:NmbTri)) + allocate(TriRef( 1:NmbTri)) + + ! Convert the quad Q2 mesh into a triangular P2 one + do i=1,NmbQad + iTria=2*i-1 + TriTab(1,iTria) = QadTab(1,i) + TriTab(2,iTria) = QadTab(3,i) + TriTab(3,iTria) = QadTab(9,i) + TriTab(4,iTria) = QadTab(2,i) + TriTab(5,iTria) = QadTab(6,i) + TriTab(6,iTria) = QadTab(5,i) + TriRef( iTria) = QadRef( i) + + iTria=2*i + TriTab(1,iTria) = QadTab(1,i) + TriTab(2,iTria) = QadTab(9,i) + TriTab(3,iTria) = QadTab(7,i) + TriTab(4,iTria) = QadTab(5,i) + TriTab(5,iTria) = QadTab(8,i) + TriTab(6,iTria) = QadTab(5,i) + TriRef( iTria) = QadRef( i) + enddo + !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + + !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + ! Write a triangular mesh + + OutMsh = GmfOpenMeshf77(trim(OutFile), GmfWrite, ver, dim) + print '(/"Output Mesh File: ",a," Idx=",i0," version: ",i0," dim: ",i0)',trim(OutFile),OutMsh,ver,dim + print '( "vertices : ",i0)', NmbVer + print '( "triangleP2 : ",i0)', NmbTri + + if(OutMsh==0) STOP ' OutMsh = 0' + + ! Set the number of vertices + res=Gmfsetkwdf77(OutMsh, GmfVertices, NmbVer, 0, t, 0, ho) + + ! Write them down using separate pointers for each scalar entry + res=Gmfsetvertices( & + & OutMsh ,& + & 1 ,& + & NmbVer ,& + & 0, m ,& + & VerTab(1,1), VerTab(1,NmbVer),& + & VerRef( 1), VerRef( NmbVer) ) + + ! Write the triangles using 4 independant set of arguments + ! for each scalar entry: node1, node2, node3 and reference + res=Gmfsetkwdf77(OutMsh, GmfTrianglesP2, NmbTri, 0, t, 0, ho) + + res = GmfSetElements( & + & OutMsh ,& + & GmfTrianglesP2 ,& + & 1 ,& + & NmbTri ,& + & 0, m ,& + & TriTab(1,1), TriTab(1,NmbTri),& + & TriRef( 1), TriRef( NmbTri) ) + + ! Don't forget to close the file + res=GmfCloseMeshf77(OutMsh) + + print '("output mesh :",i0," vertices: ",i0," triangles")',NmbVer,NmbTri + !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + + !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + !> Cleanning Memory + deallocate(VerTab,VerRef) + deallocate(QadTab,QadRef) + deallocate(TriTab,TriRef) + !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + + !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + print '(/"vizir4 -in ",a)',trim(OutFile) + print '(/"test_libmeshb_HO_f90")' + !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + +end program test_libmeshb_HO_f90 + + \ No newline at end of file diff --git a/examples/test_libmeshb_block.f90 b/examples/test_libmeshb_block.f90 index 1c147ae..0b7b6bc 100644 --- a/examples/test_libmeshb_block.f90 +++ b/examples/test_libmeshb_block.f90 @@ -9,9 +9,11 @@ program test_libmeshb_block_f90 !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> implicit none + integer(8) :: InpMsh, OutMsh, m(1) + character(80) :: InpFile + character(80) :: OutFile integer :: i integer :: NmbVer,NmbQad,NmbTri,ver,dim,res - integer(8) :: InpMsh, OutMsh, m(1) real(real64) :: sol(1:10) real(real64), pointer :: VerTab(:,:) integer , pointer :: VerRef( :) @@ -19,13 +21,22 @@ program test_libmeshb_block_f90 integer , pointer :: TriTab(:,:),TriRef( :) integer :: t(1),d,ho,s !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - + + !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + print '(/"test_libmeshb_block_f90")' + !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + + !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + InpFile='../sample_meshes/quad.mesh' + OutFile='./tri.meshb' + !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ! Open the quadrilateral mesh file for reading ! Open the mesh file and check the version and dimension - InpMsh = GmfOpenMeshf77('../sample_meshes/quad.mesh ', GmfRead,ver,dim) - print '("Input mesh :",i0," version: ",i0," dim: ",i0)',InpMsh,ver,dim + InpMsh = GmfOpenMeshf77(trim(InpFile),GmfRead,ver,dim) + print '(/"Input Mesh File: ",a," Idx=",i0," version: ",i0," dim: ",i0)',trim(InpFile),InpMsh,ver,dim if( InpMsh==0) stop ' InpMsh = 0' if( ver<=1 ) stop ' version <= 1' if( dim/=3 ) stop ' dimension <> 3' @@ -40,18 +51,15 @@ program test_libmeshb_block_f90 allocate(QadTab(1:4,1:NmbQad)) allocate(QadRef( 1:NmbQad)) - print '("Input mesh : ",i0," vertices: ",i0," quads")',NmbVer,NmbQad - - print '("input mesh: ",i0)', InpMsh - print '("version : ",i0)', ver - print '("dimension : ",i0)', dim print '("vertices : ",i0)', NmbVer print '("quads : ",i0)', NmbQad ! Read the vertices using a vector of 3 consecutive doubles to store the coordinates res=GmfGetVertices( & & InpMsh ,& - & 1, NmbVer, 0, m ,& + & 1 ,& + & NmbVer ,& + & 0, m ,& & VerTab(1,1), VerTab(1,NmbVer) ,& & VerRef( 1), VerRef( NmbVer) ) @@ -59,21 +67,24 @@ program test_libmeshb_block_f90 res=GmfGetElements( & & InpMsh ,& & GmfQuadrilaterals ,& - & 1, NmbQad, 0, m ,& + & 1 ,& + & NmbQad ,& + & 0, m ,& & QadTab(1,1), QadTab(1,NmbQad),& & QadRef( 1), QadRef( NmbQad) ) - + ! Close the quadrilateral mesh res=GmfCloseMeshf77(InpMsh) !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - ! Convert the quad mesh into a triangular one - + + ! Allocate TriTab and TriRef NmbTri=2*NmbQad allocate(TriTab(1:3,1:NmbTri)) allocate(TriRef( 1:NmbTri)) + ! Convert the quad mesh into a triangular one do i=1,NmbTri if(mod(i,2) .EQ. 1) then TriTab(1,i) = QadTab(1,(i+1)/2) @@ -92,7 +103,10 @@ program test_libmeshb_block_f90 !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ! Write a triangular mesh - OutMsh = GmfOpenMeshf77('tri.meshb', GmfWrite, ver, dim) + OutMsh = GmfOpenMeshf77(trim(OutFile), GmfWrite, ver, dim) + print '(/"Output Mesh File: ",a," Idx=",i0," version: ",i0," dim: ",i0)',trim(OutFile),OutMsh,ver,dim + print '( "vertices : ",i0)', NmbVer + print '( "triangles : ",i0)', NmbTri if(OutMsh==0) STOP ' OutMsh = 0' ! Set the number of vertices @@ -101,7 +115,9 @@ program test_libmeshb_block_f90 ! Write them down using separate pointers for each scalar entry res=Gmfsetvertices( & & OutMsh ,& - & 1, NmbVer, 0, m ,& + & 1 ,& + & NmbVer ,& + & 0, m ,& & VerTab(1,1), VerTab(1,NmbVer),& & VerRef( 1), VerRef( NmbVer) ) @@ -111,12 +127,14 @@ program test_libmeshb_block_f90 res = GmfSetElements( & & OutMsh ,& & GmfTriangles ,& - & 1, 2*NmbQad, 0, m ,& + & 1 ,& + & NmbTri ,& + & 0, m ,& & TriTab(1,1), TriTab(1,NmbTri),& & TriRef( 1), TriRef( NmbTri) ) ! Don't forget to close the file - res = GmfCloseMeshf77(OutMsh) + res=GmfCloseMeshf77(OutMsh) print '("output mesh :",i0," vertices: ",i0," triangles")',NmbVer,NmbTri !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< @@ -128,6 +146,10 @@ program test_libmeshb_block_f90 deallocate(TriTab,TriRef) !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - + !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + print '(/"vizir4 -in ",a)',trim(OutFile) + print '(/"test_libmeshb_block_f90")' + !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + end program test_libmeshb_block_f90 From ed9bd3221aae34f40c1c638dcabf4337b30f5fa8 Mon Sep 17 00:00:00 2001 From: Christophe Peyret Date: Mon, 19 Feb 2024 15:26:58 +0100 Subject: [PATCH 20/38] =?UTF-8?q?fortran=2090=20:=20utilisation=20du=20bin?= =?UTF-8?q?ding=20QadTab(:,:)=20et=20nodes(:)=20afin=20d'=C3=A9crire=20les?= =?UTF-8?q?=20connectivit=C3=A9s=20=C3=A0=20l'aide=20d'un=20tableau=20une?= =?UTF-8?q?=20entr=C3=A9e=20plutot=20qu'un=20tablau=20=C3=A0=20deux=20entr?= =?UTF-8?q?=C3=A9es=20sans=20recopie=20des=20donn=C3=A9es.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- examples/test_libmeshb_block.f90 | 92 ++++++++++++++++++++++++-------- 1 file changed, 69 insertions(+), 23 deletions(-) diff --git a/examples/test_libmeshb_block.f90 b/examples/test_libmeshb_block.f90 index 0b7b6bc..e0efd8c 100644 --- a/examples/test_libmeshb_block.f90 +++ b/examples/test_libmeshb_block.f90 @@ -28,7 +28,7 @@ program test_libmeshb_block_f90 !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> InpFile='../sample_meshes/quad.mesh' - OutFile='./tri.meshb' + OutFile='./tri.mesh' !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> @@ -45,13 +45,12 @@ program test_libmeshb_block_f90 NmbVer = Gmfstatkwdf77(InpMsh, GmfVertices, 0, s, t, d, ho) allocate(VerTab(1:3,1:NmbVer)) allocate(VerRef( 1:NmbVer)) + print '("vertices : ",i0)', NmbVer ! Allocate QadTab and QadRef NmbQad=Gmfstatkwdf77(InpMsh, GmfQuadrilaterals, 0, s, t, d, ho) allocate(QadTab(1:4,1:NmbQad)) - allocate(QadRef( 1:NmbQad)) - - print '("vertices : ",i0)', NmbVer + allocate(QadRef( 1:NmbQad)) print '("quads : ",i0)', NmbQad ! Read the vertices using a vector of 3 consecutive doubles to store the coordinates @@ -63,15 +62,33 @@ program test_libmeshb_block_f90 & VerTab(1,1), VerTab(1,NmbVer) ,& & VerRef( 1), VerRef( NmbVer) ) - ! Read the quads using one single vector of 5 consecutive integers - res=GmfGetElements( & - & InpMsh ,& - & GmfQuadrilaterals ,& - & 1 ,& - & NmbQad ,& - & 0, m ,& - & QadTab(1,1), QadTab(1,NmbQad),& - & QadRef( 1), QadRef( NmbQad) ) + ! Read the quads using one single vector of 4 consecutive integers + + !res=GmfGetElements( & + !& InpMsh ,& + !& GmfQuadrilaterals ,& + !& 1 ,& + !& NmbQad ,& + !& 0, m ,& + !& QadTab(1,1), QadTab(1,NmbQad) ,& + !& QadRef( 1), QadRef( NmbQad) ) + + !> test lecture par tableau 1D + block + use iso_c_binding, only: c_loc,c_f_pointer + integer , pointer :: nodes(:) + + call c_f_pointer(cptr=c_loc(QadTab), fptr=nodes, shape=[4*NmbQad]) !> binding QadTab(:,:) and nodes(:) + + res=GmfGetElements( & + & InpMsh ,& + & GmfQuadrilaterals ,& + & 1 ,& + & NmbQad ,& + & 0, m ,& + & nodes( 1), nodes(4*NmbQad-3),& + & QadRef( 1), QadRef(NmbQad) ) + end block ! Close the quadrilateral mesh res=GmfCloseMeshf77(InpMsh) @@ -113,7 +130,7 @@ program test_libmeshb_block_f90 res=Gmfsetkwdf77(OutMsh, GmfVertices, NmbVer, 0, t, 0, ho) ! Write them down using separate pointers for each scalar entry - res=Gmfsetvertices( & + res=GmfSetVertices( & & OutMsh ,& & 1 ,& & NmbVer ,& @@ -124,17 +141,46 @@ program test_libmeshb_block_f90 ! Write the triangles using 4 independant set of arguments ! for each scalar entry: node1, node2, node3 and reference res=Gmfsetkwdf77(OutMsh, GmfTriangles, NmbTri, 0, t, 0, ho) - res = GmfSetElements( & - & OutMsh ,& - & GmfTriangles ,& - & 1 ,& - & NmbTri ,& - & 0, m ,& - & TriTab(1,1), TriTab(1,NmbTri),& - & TriRef( 1), TriRef( NmbTri) ) - + + !res = GmfSetElements( & + !& OutMsh ,& + !& GmfTriangles ,& + !& 1 ,& + !& NmbTri ,& + !& 0, m ,& + !& TriTab(1,1), TriTab(1,NmbTri),& + !& TriRef( 1), TriRef( NmbTri) ) + + !> test ecriture par tableau 1D + block + use iso_c_binding, only: c_loc,c_f_pointer + integer , pointer :: nodes(:) + + print '(/"binding TriTab(:,:) and nodes(:)")' + + call c_f_pointer(cptr=c_loc(TriTab), fptr=nodes, shape=[3*NmbTri]) !> binding TriTab(:,:) and nodes(:) + + print '(/"Triangle: ",i6)',1 + print '( "TriTab:",3(i6,1x) )',TriTab(1,1),TriTab(2,1),TriTab(3,1) + print '( "nodes: ",3(i6,1x)/)',nodes(1),nodes(2),nodes(3) + print '(/"Triangle: ",i6)',NmbTri + print '( "TriTab:",3(i6,1x) )',TriTab(1,NmbTri),TriTab(2,NmbTri),TriTab(3,NmbTri) + print '( "nodes: ",3(i6,1x)/)',nodes(3*NmbTri-2),nodes(3*NmbTri-1),nodes(3*NmbTri) + + res=GmfSetElements( & + & InpMsh ,& + & GmfTriangles ,& + & 1 ,& + & NmbTri ,& + & 0, m ,& + & nodes( 1), nodes(3*NmbTri-2),& + & TriRef( 1), TriRef(NmbTri) ) + + end block + ! Don't forget to close the file res=GmfCloseMeshf77(OutMsh) + print '("output mesh :",i0," vertices: ",i0," triangles")',NmbVer,NmbTri !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< From 6f18a7c77306e954ef4b43d47b80089d83bed1e5 Mon Sep 17 00:00:00 2001 From: Christophe Peyret Date: Tue, 20 Feb 2024 11:16:32 +0100 Subject: [PATCH 21/38] =?UTF-8?q?Mise=20au=20point=20test=5Flibmeshb=5FHO.?= =?UTF-8?q?f90=20et=20essai=20de=20binding=20fortran=20C=20avec=20test=5Fl?= =?UTF-8?q?ibmeshb=5Fblock=5FbindC.f90=20mais=20ce=20n'est=20pas=20gagn?= =?UTF-8?q?=C3=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- examples/CMakeLists.txt | 6 ++ examples/test_libmeshb_HO.f90 | 130 +++++++++++++++++------ examples/test_libmeshb_block_bindC.f90 | 138 +++++++++++++++++++++++++ 3 files changed, 241 insertions(+), 33 deletions(-) create mode 100644 examples/test_libmeshb_block_bindC.f90 diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index e59d1ad..556e4d9 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -57,4 +57,10 @@ if (CMAKE_Fortran_COMPILER) add_executable(test_libmeshb_HO_f90 test_libmeshb_HO.f90) target_link_libraries(test_libmeshb_HO_f90 Meshb.7 ${AIO_LIBRARIES}) install (TARGETS test_libmeshb_HO_f90 DESTINATION share/libMeshb/examples COMPONENT examples) + + + #add_executable(test_libmeshb_block_bindC test_libmeshb_block_bindC.f90) + #target_link_libraries(test_libmeshb_block_bindC Meshb.7 ${AIO_LIBRARIES}) + #install (TARGETS test_libmeshb_block_bindC DESTINATION share/libMeshb/examples COMPONENT examples) + endif () diff --git a/examples/test_libmeshb_HO.f90 b/examples/test_libmeshb_HO.f90 index be66021..26408a7 100644 --- a/examples/test_libmeshb_HO.f90 +++ b/examples/test_libmeshb_HO.f90 @@ -14,15 +14,16 @@ program test_libmeshb_HO_f90 character(80) :: InpFile character(80) :: OutFile integer :: i,iTria + integer :: GmfCell,GmfOrd integer :: NmbVer,NmbQad,NmbTri,ver,dim,res - real(real64) :: sol(1:10) + real(real64) :: sol(1:10) real(real64), pointer :: VerTab(:,:) integer , pointer :: VerRef( :) integer , pointer :: QadTab(:,:),QadRef( :) integer , pointer :: TriTab(:,:),TriRef( :) integer :: t(1),d,ho,s !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - + !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> print '(/"test_libmeshb_HO_f90")' !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< @@ -34,33 +35,25 @@ program test_libmeshb_HO_f90 !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ! Open the quadrilateral mesh file for reading + print '(/"Input Mesh File : ",a )',trim(InpFile) ! Open the mesh file and check the version and dimension InpMsh = GmfOpenMeshf77(trim(InpFile),GmfRead,ver,dim) - print '(/"Input Mesh File: ",a," Idx=",i0," version: ",i0," dim: ",i0)',trim(InpFile),InpMsh,ver,dim + print '( "Input Mesh Idx : ",i0)',InpMsh + print '( "Input Mesh ver : ",i0)',ver + print '( "Input Mesh dim : ",i0)',dim + if( InpMsh==0) stop ' InpMsh = 0' if( ver<=1 ) stop ' version <= 1' if( dim/=3 ) stop ' dimension <> 3' - ! Allocate VerTab and VerRef - NmbVer = Gmfstatkwdf77(InpMsh, GmfVertices, 0, s, t, d, ho) + ! Read the vertices using a vector of 3 consecutive doubles to store the coordinates + + NmbVer = Gmfstatkwdf77(InpMsh, GmfVertices , 0, s, t, d, ho) + print '( "Input Mesh NmbVer: ",i0)', NmbVer allocate(VerTab(1:3,1:NmbVer)) allocate(VerRef( 1:NmbVer)) - ! Allocate QadTab and QadRef - NmbQad=Gmfstatkwdf77(InpMsh, GmfQuadrilateralsQ2, 0, s, t, d, ho) - allocate(QadTab(1:9,1:NmbQad)) - allocate(QadRef( 1:NmbQad)) - - print '("Input mesh : ",i0," vertices: ",i0," quadsQ2")',NmbVer,NmbQad - - print '("input mesh: ",i0)', InpMsh - print '("version : ",i0)', ver - print '("dimension : ",i0)', dim - print '("vertices : ",i0)', NmbVer - print '("quadsQ2 : ",i0)', NmbQad - - ! Read the vertices using a vector of 3 consecutive doubles to store the coordinates res=GmfGetVertices( & & InpMsh ,& & 1 ,& @@ -69,28 +62,93 @@ program test_libmeshb_HO_f90 & VerTab(1,1), VerTab(1,NmbVer) ,& & VerRef( 1), VerRef( NmbVer) ) + + ! Read GmfQuadrilateralsQ2 + GmfCell=GmfQuadrilateralsQ2 ! <= + GmfOrd =GmfQuadrilateralsQ2Ordering ! <= + + NmbQad=Gmfstatkwdf77(InpMsh, GmfCell, 0, s, t, d, ho) + print '( "Input Mesh NmbQad: ",i0)', NmbQad + allocate(QadTab(1:9,1:NmbQad)) + allocate(QadRef( 1:NmbQad)) + + if( .not. Gmfstatkwdf77(InpMsh,GmfOrd,0,s,t,d,ho)==0 )then + print '("Input Mesh Reordering HO Nodes")' + block + integer :: orderingSpace(1:2,1:9) + integer :: orderingMesh (1:2,1:9) + integer :: ord + integer :: nNode + integer :: nUVW + !> 04 07 03 + !> 08 09 06 + !> 01 05 02 + orderingSpace(1:2,01)=[0,0] + orderingSpace(1:2,02)=[2,0] + orderingSpace(1:2,03)=[2,2] + orderingSpace(1:2,04)=[0,2] + orderingSpace(1:2,05)=[1,0] + orderingSpace(1:2,06)=[2,1] + orderingSpace(1:2,07)=[1,2] + orderingSpace(1:2,08)=[0,1] + orderingSpace(1:2,09)=[1,1] + + print '("Input Mesh Requested Order")' + do i=1,size(orderingSpace,2) + print '(3x,"uv(",i2.2,")=",2(i2,1x))',i,orderingSpace(1:2,i) + enddo + + !> Q2 -> ord=2 + ord=2 + nNode=(ord+1)*(ord+1) ! <= + nUVW=2 ! <= + + !res=GmfGetBlock( & + !& InpMsh ,& + !& GmfOrd ,& + !& int( 1,kind=8) ,& + !& int(nNode,kind=8) ,& + !& 0, %val(0), %val(0) ,& + !& GmfIntTab, nUVW, orderingMesh(1,1), orderingMesh(1,nNode) ) + + print '("Input Mesh Gmf HO Order")' + do i=1,size(orderingSpace,2) + print '(3x,"uv(",i2.2,")=",2(i2,1x))',i,orderingMesh(1:2,i) + enddo + + !res=GmfSetHONodesOrdering(InpMsh,GmfCell,orderingSpace,orderingMesh) + + end block + endif + ! Read the quads using one single vector of 5 consecutive integers res=GmfGetElements( & & InpMsh ,& - & GmfQuadrilateralsQ2 ,& + & GmfCell ,& & 1 ,& & NmbQad ,& & 0, m ,& & QadTab(1,1), QadTab(1,NmbQad),& & QadRef( 1), QadRef( NmbQad) ) - + ! Close the quadrilateral mesh res=GmfCloseMeshf77(InpMsh) + + + print '("Input Mesh")' + do i=1,10 !NmbQad + print '(3x,"qad",i6," nd:",9(i6,1x)," ref: ",i0)',i,QadTab(1:9,i),QadRef(i) + enddo !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - + ! Convert the quad Q2 mesh into a triangular P2 one + ! Allocate TriTab and TriRef NmbTri=2*NmbQad allocate(TriTab(1:6,1:NmbTri)) allocate(TriRef( 1:NmbTri)) - ! Convert the quad Q2 mesh into a triangular P2 one do i=1,NmbQad iTria=2*i-1 TriTab(1,iTria) = QadTab(1,i) @@ -115,15 +173,23 @@ program test_libmeshb_HO_f90 !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ! Write a triangular mesh - OutMsh = GmfOpenMeshf77(trim(OutFile), GmfWrite, ver, dim) - print '(/"Output Mesh File: ",a," Idx=",i0," version: ",i0," dim: ",i0)',trim(OutFile),OutMsh,ver,dim - print '( "vertices : ",i0)', NmbVer - print '( "triangleP2 : ",i0)', NmbTri + print '(/"Output Mesh File : ",a )',trim(OutFile) + print '("Output Mesh")' + do i=1,10 !NmbQad + print '(3x,"tri",i6," nd:",6(i6,1x)," ref: ",i0)',i,TriTab(1:6,i),TriRef(i) + enddo + + ! Open the mesh file and check the version and dimension + OutMsh = GmfOpenMeshf77(trim(OutFile), GmfWrite, ver, dim) + print '( "Output Mesh Idx : ",i0)',InpMsh + print '( "Output Mesh ver : ",i0)',ver + print '( "Output Mesh dim : ",i0)',dim if(OutMsh==0) STOP ' OutMsh = 0' ! Set the number of vertices res=Gmfsetkwdf77(OutMsh, GmfVertices, NmbVer, 0, t, 0, ho) + print '( "Output Mesh NmbVer: ",i0)', NmbVer ! Write them down using separate pointers for each scalar entry res=Gmfsetvertices( & @@ -137,7 +203,8 @@ program test_libmeshb_HO_f90 ! Write the triangles using 4 independant set of arguments ! for each scalar entry: node1, node2, node3 and reference res=Gmfsetkwdf77(OutMsh, GmfTrianglesP2, NmbTri, 0, t, 0, ho) - + print '( "Output Mesh NmbTri: ",i0)', NmbTri + res = GmfSetElements( & & OutMsh ,& & GmfTrianglesP2 ,& @@ -148,9 +215,7 @@ program test_libmeshb_HO_f90 & TriRef( 1), TriRef( NmbTri) ) ! Don't forget to close the file - res=GmfCloseMeshf77(OutMsh) - - print '("output mesh :",i0," vertices: ",i0," triangles")',NmbVer,NmbTri + res=GmfCloseMeshf77(OutMsh) !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> @@ -161,8 +226,7 @@ program test_libmeshb_HO_f90 !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - print '(/"vizir4 -in ",a)',trim(OutFile) - print '(/"test_libmeshb_HO_f90")' + print '(/"control: vizir4 -in ",a/)',trim(OutFile) !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< end program test_libmeshb_HO_f90 diff --git a/examples/test_libmeshb_block_bindC.f90 b/examples/test_libmeshb_block_bindC.f90 new file mode 100644 index 0000000..b8fdeb5 --- /dev/null +++ b/examples/test_libmeshb_block_bindC.f90 @@ -0,0 +1,138 @@ +program test_libmeshb_block_bindC + !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + use, intrinsic :: iso_fortran_env + use, intrinsic :: iso_c_binding + use libmeshb7 + !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + implicit none + + character(80) :: InpFile + character(80) :: OutFile + + integer(c_long) :: InpMsh + integer(c_long) :: OutMsh + integer(c_int) :: NmbVer + real(c_double), pointer :: VerTab(:,:) + integer(c_int), pointer :: VerRef( :) + integer(c_int) :: NmbQad + integer(c_int) :: ver + integer(c_int) :: dim + type(c_ptr) :: RefTab + type(c_ptr) :: QadTab + type(c_ptr) :: TriTab + !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + !if(!(InpMsh = GmfOpenMesh("../sample_meshes/quad.meshb", GmfRead, &ver, &dim))) + interface + function GmfOpenMesh(name, Gmf, ver, dim) result(unit) bind(c, name="GmfOpenMesh") + use, intrinsic :: iso_c_binding + type(c_ptr) , value :: name + integer(c_int), value :: Gmf + integer(c_int) :: ver + integer(c_int) :: dim + integer(c_long) :: unit + end function GmfOpenMesh + + function GmfStatKwd(unit, Gmf) result(numb) bind(c, name="GmfStatKwd") + use, intrinsic :: iso_c_binding + integer(c_long), value :: unit + integer(c_int) , value :: Gmf + integer(c_int) :: numb + end function GmfStatKwd + + subroutine GmfSetKwd(unit, Gmf, numb) bind(c, name="GmfSetKwd") + use, intrinsic :: iso_c_binding + integer(c_long), value :: unit + integer(c_int) , value :: Gmf + integer(c_int) :: numb + end subroutine GmfSetKwd + + subroutine GmfCloseMesh(unit) bind(c, name="GmfCloseMesh") + use, intrinsic :: iso_c_binding + integer(c_long), value :: unit + end subroutine GmfCloseMesh + + !GmfGetBlock(InpMsh, GmfVertices, 1, NmbVer, 0, NULL, NULL, + !GmfFloat, &VerTab[1][0], &VerTab[ NmbVer ][0], + !GmfFloat, &VerTab[1][1], &VerTab[ NmbVer ][1], + !GmfFloat, &VerTab[1][2], &VerTab[ NmbVer ][2], + !GmfInt, &RefTab[1], &RefTab[ NmbVer ] ); + + !subroutine GmfGetBlock(unit, Gmf, ) + ! + !end subroutine + + end interface + + + !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + + !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + InpFile='../sample_meshes/quad.mesh' + OutFile='./tri.mesh' + !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + + !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + !block + ! integer :: nChar + ! character(:), pointer :: nameC=>null() + ! + ! nChar=len_trim(InpFile) !> print '("nChar: ",i0)',nChar + ! allocate(character(len=nChar+1) :: nameC) + ! nameC = trim(InpFile) // C_NULL_CHAR + ! + ! InpMsh=GmfOpenMesh(name=c_loc(nameC), Gmf=GmfRead, ver=ver, dim=dim) + ! + !end block + + InpMsh=GmfOpenMesh(name=convertName(name=InpFile), Gmf=GmfRead, ver=ver, dim=dim) + + print '(/"Input Mesh File: ",a," Idx=",i0," version: ",i0," dim: ",i0)',trim(InpFile),InpMsh,ver,dim + if( InpMsh==0) stop ' InpMsh = 0' + if( ver<=1 ) stop ' version <= 1' + if( dim/=3 ) stop ' dimension <> 3' + + NmbVer=GmfStatKwd(unit=InpMsh, Gmf=GmfVertices) + allocate(VerTab(1:3,1:NmbVer)) + allocate(VerRef( 1:NmbVer)) + print '("vertices : ",i0)', NmbVer + + NmbQad=GmfStatKwd(unit=InpMsh, Gmf=GmfQuadrilaterals) + !allocate(QadTab(1:4,1:NmbQad)) + !allocate(QadRef( 1:NmbQad)) + print '("quads : ",i0)', NmbQad + + + call GmfCloseMesh(unit=InpMsh) + !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + + !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + OutMsh=GmfOpenMesh(name=convertName(name=OutFile), Gmf=GmfWrite, ver=ver, dim=dim) + + print '(/"Output Mesh File: ",a," Idx=",i0," version: ",i0," dim: ",i0)',trim(OutFile),OutMsh,ver,dim + if( OutMsh==0) stop ' OutMsh = 0' + + call GmfSetKwd(unit=OutMsh, Gmf=GmfVertices, numb=NmbVer); + call GmfCloseMesh(unit=OutMsh) + !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + +contains + + function convertName(name) result (res) + !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + character(*) :: name + integer :: nChar + character(:), pointer :: nameC=>null() + type(c_ptr) :: res + !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + nChar=len_trim(name) ! print '("nChar: ",i0)',nChar + allocate(character(len=nChar+1) :: nameC) + nameC=trim(name) // C_NULL_CHAR + res=c_loc(nameC) + !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + return + end function convertName + +end program test_libmeshb_block_bindC From 771a5a97cf755b89402c7b5b1103b4379c1ceef7 Mon Sep 17 00:00:00 2001 From: Christophe Peyret Date: Wed, 21 Feb 2024 11:38:24 +0100 Subject: [PATCH 22/38] Mise au point des exemples version f90 --- examples/test_libmeshb.f90 | 141 ++++++++++++++------------ examples/test_libmeshb_HO.f90 | 61 ++++++----- examples/test_libmeshb_block.f90 | 168 ++++++++++++++++--------------- 3 files changed, 200 insertions(+), 170 deletions(-) diff --git a/examples/test_libmeshb.f90 b/examples/test_libmeshb.f90 index 585e3b7..dcb79ec 100644 --- a/examples/test_libmeshb.f90 +++ b/examples/test_libmeshb.f90 @@ -11,17 +11,18 @@ program test_libmeshb_f90 !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> implicit none - integer(8) :: InpMsh, OutMsh - character(80) :: InpFile - character(80) :: OutFile - integer :: i - integer :: NmbVer,NmbQad,NmbTri,ver,dim,res,kwd - integer :: t(1:10),d,ho,s - real(real64) :: sol(1:10) - real(real64), pointer :: VerTab(:,:) - integer , pointer :: VerRef( :) - integer , pointer :: QadTab(:,:) - integer , pointer :: QadRef( :) + integer(int64) :: InpMsh, OutMsh, OutSol + character(80) :: InpFile + character(80) :: OutFile + character(80) :: SolFile + integer(int32) :: i + integer(int32) :: NmbVer,NmbQad,NmbTri,ver,dim,res,kwd + integer(int32) :: NmbField,fields(1:10),ho,s,d + real(real64) , pointer :: sol(:) + real(real64) , pointer :: VerTab(:,:) + integer(int32), pointer :: VerRef( :) + integer(int32), pointer :: QadTab(:,:) + integer(int32), pointer :: QadRef( :) !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> @@ -31,58 +32,66 @@ program test_libmeshb_f90 !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> InpFile='../sample_meshes/quad.mesh' OutFile='./tri.meshb' + SolFile='./tri.solb' !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ! Open the quadrilateral mesh file for reading + print '(/"Input Mesh Open : ",a )',trim(InpFile) ! Open the mesh file and check the version and dimension InpMsh = GmfOpenMeshf77(trim(InpFile),GmfRead,ver,dim) - print '(/"Input Mesh File: ",a," Idx=",i0," version: ",i0," dim: ",i0)',trim(InpFile),InpMsh,ver,dim - if( InpMsh==0) stop ' InpMsh = 0' - if( ver<=1 ) stop ' version <= 1' - if( dim/=3 ) stop ' dimension <> 3' + print '( "Input Mesh Idx : ",i0)',InpMsh + print '( "Input Mesh ver : ",i0)',ver + print '( "Input Mesh dim : ",i0)',dim - ! Allocate VerTab and VerRef - NmbVer = Gmfstatkwdf77(InpMsh, GmfVertices, 0, s, t, d, ho) + if( InpMsh==0 ) stop ' InpMsh = 0' + if( ver<=1 ) stop ' version <= 1' + if( dim/=3 ) stop ' dimension <> 3' + + ! Read the vertices + + NmbVer = Gmfstatkwdf77(InpMsh, GmfVertices, 0, s, fields, d, ho) + print '( "Input Mesh NmbVer : ",i0)', NmbVer allocate(VerTab(1:3,1:NmbVer)) allocate(VerRef( 1:NmbVer)) - ! Allocate QadTab and QadRef - NmbQad=Gmfstatkwdf77(InpMsh, GmfQuadrilaterals, 0, s, t, d, ho) + res = Gmfgotokwdf77(InpMsh, GmfVertices) + do i=1,NmbVer + res=GmfGetVertex(InpMsh, VerTab(1:3,i), VerRef(i)) + end do + + ! Read the quads + + NmbQad=Gmfstatkwdf77(InpMsh, GmfQuadrilaterals, 0, s, fields, d, ho) + print '( "Input Mesh NmbQad : ",i0)', NmbQad allocate(QadTab(1:4,1:NmbQad)) allocate(QadRef( 1:NmbQad)) - print '("Input mesh : ",i0," vertices: ",i0," quads")',NmbVer,NmbQad - - ! Read the quads res=Gmfgotokwdf77(InpMsh, GmfQuadrilaterals) do i=1,NmbQad res=GmfGetElement(InpMsh, GmfQuadrilaterals, QadTab(1:4,i), QadRef(i)) enddo - ! Read the vertices - res = Gmfgotokwdf77(InpMsh, GmfVertices) - do i=1,NmbVer - res=GmfGetVertex(InpMsh, VerTab(1:3,i), VerRef(i)) - end do - ! Close the quadrilateral mesh res=GmfCloseMeshf77(InpMsh) + print '("Input Mesh Close : ",a)',trim(InpFile) !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ! Create a triangular mesh NmbTri=2*NmbQad + print '(/"Output Mesh Open : ",a )',trim(OutFile) OutMsh = GmfOpenMeshf77(trim(OutFile), GmfWrite, ver, dim) - print '(/"Output Mesh File: ",a," Idx=",i0," version: ",i0," dim: ",i0)',trim(OutFile),OutMsh,ver,dim - print '( "vertices : ",i0)', NmbVer - print '( "triangles : ",i0)', NmbTri - if(OutMsh==0) STOP ' OutMsh = 0' - + print '( "Output Mesh Idx : ",i0)',InpMsh + print '( "Output Mesh ver : ",i0)',ver + print '( "Output Mesh dim : ",i0)',dim + if( OutMsh==0 ) STOP ' OutMsh = 0' + ! Set the number of vertices - res=GmfSetKwdf77(OutMsh, GmfVertices, NmbVer, 0, t, 0, ho) + res=GmfSetKwdf77(OutMsh, GmfVertices, NmbVer, 0, fields, 0, ho) + print '( "Output Mesh NmbVer : ",i0)', NmbVer ! Then write them down do i=1,NmbVer @@ -90,7 +99,9 @@ program test_libmeshb_f90 end do ! Write the triangles - res = Gmfsetkwdf77(OutMsh, GmfTriangles, 2*NmbQad, 0, t, 0, ho) + res = Gmfsetkwdf77(OutMsh, GmfTriangles, 2*NmbQad, 0, fields, 0, ho) + print '( "Output Mesh NmbTri : ",i0)', NmbTri + do i=1,NmbQad res=GmfSetElement(OutMsh, GmfTriangles, QadTab(1,i), QadRef(i)) ! Modify the quad to build the other triangle's diagonal @@ -101,47 +112,53 @@ program test_libmeshb_f90 ! Don't forget to close the file res = GmfCloseMeshf77(OutMsh) - - - print '("output mesh: ",i0," vertices: ",i0," triangles")',NmbVer,2*NmbQad + print '("Output Mesh Close : ",a)',trim(OutFile) !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - !> Cleanning Memory - deallocate(VerTab,VerRef) - deallocate(QadTab,QadRef) - !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ! Create a solution file + print '(/"Output Solu Open : ",a )',trim(SolFile) - OutMsh = GmfOpenMeshf77('tri.sol', GmfWrite, 2, 3) - if(OutMsh==0) STOP ' OutMsh = 0' - print '("output IDX: ",i0)',OutMsh + OutSol = GmfOpenMeshf77(trim(SolFile), GmfWrite, ver, dim) + print '( "Output Solu Idx : ",i0)',OutSol + print '( "Output Solu ver : ",i0)',ver + print '( "Output Solu dim : ",i0)',dim + if( OutSol==0 ) STOP ' OutSol = 0' ! Set the solution kinds - t(1:3) = [GmfSca,GmfVec,GmfSca] + NmbField=3 + fields(1:NmbField) = [GmfSca,GmfVec,GmfSca] + allocate(sol(1:5)) ! 1+ dim+ 1 + print '( "Output Solu NmbVer : ",i0)',NmbVer + print '( "Output Solu nFields : ",i0)',NmbField + print '( "Output Solu fields : ", *(i0,1x))',fields(1:NmbField) ! Set the number of solutions (one per vertex) - res = Gmfsetkwdf77(OutMsh, GmfSolAtVertices, NmbVer, 3, t, 0, ho) + res = GmfSetKwdF77(OutSol, GmfSolAtVertices, NmbVer, NmbField, fields(1:NmbField), 0, ho) ! Write the dummy solution fields - do i = 1, NmbVer - sol(1:4) = [i,2*i,3*i,4*i] - sol(5) = -i - res = Gmfsetsolution(OutMsh, GmfSolAtVertices, sol) - end do - + do i=1,NmbVer + sol( 1)=VerTab(1,i) + sol(2:4)=[VerTab(1,i),VerTab(2,i),0d0] + sol( 5)=VerTab(2,i) + res=GmfSetSolution(OutSol, GmfSolAtVertices, sol) + enddo + ! Don't forget to close the file - res = GmfCloseMeshf77(OutMsh) + res = GmfCloseMeshf77(OutSol) + print '("Output Solu Close : ",a)',trim(SolFile) + !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - print '("output sol: ",i0," solutions")',NmbVer + !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + !> Cleanning Memory + deallocate(VerTab,VerRef) + deallocate(QadTab,QadRef) + deallocate(sol) !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - + !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - print '(/"vizir4 -in ",a," -sol tri.sol")',trim(OutFile) - print '(/"test_libmeshb_f90")' + !> User Control + print '(/"Control:"/"vizir4 -in ",a," -sol ",a/)',trim(OutFile),trim(SolFile) !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - - + end program test_libmeshb_f90 diff --git a/examples/test_libmeshb_HO.f90 b/examples/test_libmeshb_HO.f90 index 26408a7..7489b0a 100644 --- a/examples/test_libmeshb_HO.f90 +++ b/examples/test_libmeshb_HO.f90 @@ -1,4 +1,3 @@ - ! libMeshb 7 basic example: ! read a Q2 quad mesh while using the automatic HO reordering feature, ! split it into P2 triangles and write the result back using fast block transfer @@ -10,18 +9,18 @@ program test_libmeshb_HO_f90 !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> implicit none - integer(8) :: InpMsh, OutMsh, m(1) - character(80) :: InpFile - character(80) :: OutFile - integer :: i,iTria - integer :: GmfCell,GmfOrd - integer :: NmbVer,NmbQad,NmbTri,ver,dim,res - real(real64) :: sol(1:10) - real(real64), pointer :: VerTab(:,:) - integer , pointer :: VerRef( :) - integer , pointer :: QadTab(:,:),QadRef( :) - integer , pointer :: TriTab(:,:),TriRef( :) - integer :: t(1),d,ho,s + integer(int64) :: InpMsh, OutMsh, m(1) + character(80) :: InpFile + character(80) :: OutFile + character(80) :: SolFile + integer(int32) :: i,iTria + integer(int32) :: GmfCell,GmfOrd + integer(int32) :: NmbVer,NmbQad,NmbTri,ver,dim,res + real(real64) , pointer :: VerTab(:,:) + integer(int32), pointer :: VerRef( :) + integer(int32), pointer :: QadTab(:,:),QadRef( :) + integer(int32), pointer :: TriTab(:,:),TriRef( :) + integer(int32) :: t(1),d,ho,s !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> @@ -31,6 +30,7 @@ program test_libmeshb_HO_f90 !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> InpFile='../sample_meshes/quad_q2.mesh' OutFile='./tri_p2.mesh' + SolFile='./tri_p2.sol' !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> @@ -43,9 +43,9 @@ program test_libmeshb_HO_f90 print '( "Input Mesh ver : ",i0)',ver print '( "Input Mesh dim : ",i0)',dim - if( InpMsh==0) stop ' InpMsh = 0' - if( ver<=1 ) stop ' version <= 1' - if( dim/=3 ) stop ' dimension <> 3' + if( InpMsh==0 ) stop ' InpMsh = 0' + if( ver<=1 ) stop ' version <= 1' + if( dim/=3 ) stop ' dimension <> 3' ! Read the vertices using a vector of 3 consecutive doubles to store the coordinates @@ -97,7 +97,7 @@ program test_libmeshb_HO_f90 do i=1,size(orderingSpace,2) print '(3x,"uv(",i2.2,")=",2(i2,1x))',i,orderingSpace(1:2,i) enddo - + !> Q2 -> ord=2 ord=2 nNode=(ord+1)*(ord+1) ! <= @@ -111,16 +111,27 @@ program test_libmeshb_HO_f90 !& 0, %val(0), %val(0) ,& !& GmfIntTab, nUVW, orderingMesh(1,1), orderingMesh(1,nNode) ) + !> en attendant de pouvoir récupérer orderingMesh ses valeurs sont imposées manuellement + orderingMesh(1:2,01)=[0,0] + orderingMesh(1:2,02)=[2,0] + orderingMesh(1:2,03)=[2,2] + orderingMesh(1:2,04)=[0,2] + orderingMesh(1:2,05)=[1,0] + orderingMesh(1:2,06)=[2,1] + orderingMesh(1:2,07)=[1,2] + orderingMesh(1:2,08)=[0,1] + orderingMesh(1:2,09)=[1,1] + print '("Input Mesh Gmf HO Order")' do i=1,size(orderingSpace,2) print '(3x,"uv(",i2.2,")=",2(i2,1x))',i,orderingMesh(1:2,i) enddo !res=GmfSetHONodesOrdering(InpMsh,GmfCell,orderingSpace,orderingMesh) - + res=GmfSetHONodesOrderingF77(InpMsh,GmfCell,orderingSpace,orderingMesh) end block endif - + ! Read the quads using one single vector of 5 consecutive integers res=GmfGetElements( & & InpMsh ,& @@ -133,7 +144,7 @@ program test_libmeshb_HO_f90 ! Close the quadrilateral mesh res=GmfCloseMeshf77(InpMsh) - + print '("Input Mesh Close : ",a)',trim(InpFile) print '("Input Mesh")' do i=1,10 !NmbQad @@ -172,20 +183,20 @@ program test_libmeshb_HO_f90 !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ! Write a triangular mesh - + print '(/"Output Mesh File : ",a )',trim(OutFile) - + print '("Output Mesh")' do i=1,10 !NmbQad print '(3x,"tri",i6," nd:",6(i6,1x)," ref: ",i0)',i,TriTab(1:6,i),TriRef(i) enddo - + ! Open the mesh file and check the version and dimension OutMsh = GmfOpenMeshf77(trim(OutFile), GmfWrite, ver, dim) print '( "Output Mesh Idx : ",i0)',InpMsh print '( "Output Mesh ver : ",i0)',ver print '( "Output Mesh dim : ",i0)',dim - if(OutMsh==0) STOP ' OutMsh = 0' + if( OutMsh==0 ) STOP ' OutMsh = 0' ! Set the number of vertices res=Gmfsetkwdf77(OutMsh, GmfVertices, NmbVer, 0, t, 0, ho) @@ -226,7 +237,7 @@ program test_libmeshb_HO_f90 !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - print '(/"control: vizir4 -in ",a/)',trim(OutFile) + print '(/"control:"/"vizir4 -in ",a/)',trim(OutFile) !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< end program test_libmeshb_HO_f90 diff --git a/examples/test_libmeshb_block.f90 b/examples/test_libmeshb_block.f90 index e0efd8c..12677ab 100644 --- a/examples/test_libmeshb_block.f90 +++ b/examples/test_libmeshb_block.f90 @@ -12,6 +12,7 @@ program test_libmeshb_block_f90 integer(8) :: InpMsh, OutMsh, m(1) character(80) :: InpFile character(80) :: OutFile + character(80) :: SolFile integer :: i integer :: NmbVer,NmbQad,NmbTri,ver,dim,res real(real64) :: sol(1:10) @@ -29,30 +30,25 @@ program test_libmeshb_block_f90 !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> InpFile='../sample_meshes/quad.mesh' OutFile='./tri.mesh' + SolFile='./tri.sol' !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ! Open the quadrilateral mesh file for reading + print '(/"Input Mesh Open : ",a )',trim(InpFile) ! Open the mesh file and check the version and dimension InpMsh = GmfOpenMeshf77(trim(InpFile),GmfRead,ver,dim) - print '(/"Input Mesh File: ",a," Idx=",i0," version: ",i0," dim: ",i0)',trim(InpFile),InpMsh,ver,dim - if( InpMsh==0) stop ' InpMsh = 0' - if( ver<=1 ) stop ' version <= 1' - if( dim/=3 ) stop ' dimension <> 3' + print '( "Input Mesh Idx : ",i0)',InpMsh + print '( "Input Mesh ver : ",i0)',ver + print '( "Input Mesh dim : ",i0)',dim - ! Allocate VerTab and VerRef + ! Allocate VerRef NmbVer = Gmfstatkwdf77(InpMsh, GmfVertices, 0, s, t, d, ho) + print '( "Input Mesh NmbVer : ",i0)', NmbVer allocate(VerTab(1:3,1:NmbVer)) allocate(VerRef( 1:NmbVer)) - print '("vertices : ",i0)', NmbVer - - ! Allocate QadTab and QadRef - NmbQad=Gmfstatkwdf77(InpMsh, GmfQuadrilaterals, 0, s, t, d, ho) - allocate(QadTab(1:4,1:NmbQad)) - allocate(QadRef( 1:NmbQad)) - print '("quads : ",i0)', NmbQad - + ! Read the vertices using a vector of 3 consecutive doubles to store the coordinates res=GmfGetVertices( & & InpMsh ,& @@ -62,40 +58,46 @@ program test_libmeshb_block_f90 & VerTab(1,1), VerTab(1,NmbVer) ,& & VerRef( 1), VerRef( NmbVer) ) + ! Allocate QadTab + NmbQad=Gmfstatkwdf77(InpMsh, GmfQuadrilaterals, 0, s, t, d, ho) + print '( "Input Mesh NmbQad : ",i0)', NmbQad + allocate(QadTab(1:4,1:NmbQad)) + allocate(QadRef( 1:NmbQad)) + ! Read the quads using one single vector of 4 consecutive integers - !res=GmfGetElements( & - !& InpMsh ,& - !& GmfQuadrilaterals ,& - !& 1 ,& - !& NmbQad ,& - !& 0, m ,& - !& QadTab(1,1), QadTab(1,NmbQad) ,& - !& QadRef( 1), QadRef( NmbQad) ) - - !> test lecture par tableau 1D - block - use iso_c_binding, only: c_loc,c_f_pointer - integer , pointer :: nodes(:) - - call c_f_pointer(cptr=c_loc(QadTab), fptr=nodes, shape=[4*NmbQad]) !> binding QadTab(:,:) and nodes(:) - - res=GmfGetElements( & - & InpMsh ,& - & GmfQuadrilaterals ,& - & 1 ,& - & NmbQad ,& - & 0, m ,& - & nodes( 1), nodes(4*NmbQad-3),& - & QadRef( 1), QadRef(NmbQad) ) - end block + res=GmfGetElements( & + & InpMsh ,& + & GmfQuadrilaterals ,& + & 1 ,& + & NmbQad ,& + & 0, m ,& + & QadTab(1,1), QadTab(1,NmbQad) ,& + & QadRef( 1), QadRef( NmbQad) ) + + !!> Lecture par tableau 1D sans recopie + !block + ! use iso_c_binding, only: c_loc,c_f_pointer + ! integer , pointer :: nodes(:) + ! + ! call c_f_pointer(cptr=c_loc(QadTab), fptr=nodes, shape=[4*NmbQad]) !> binding QadTab(:,:) and nodes(:) + ! + ! res=GmfGetElements( & + ! & InpMsh ,& + ! & GmfQuadrilaterals ,& + ! & 1 ,& + ! & NmbQad ,& + ! & 0, m ,& + ! & nodes( 1), nodes(4*NmbQad-3),& + ! & QadRef( 1), QadRef(NmbQad) ) + !end block ! Close the quadrilateral mesh res=GmfCloseMeshf77(InpMsh) + print '("Input Mesh Close : ",a)',trim(InpFile) !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - ! Allocate TriTab and TriRef NmbTri=2*NmbQad allocate(TriTab(1:3,1:NmbTri)) @@ -119,15 +121,17 @@ program test_libmeshb_block_f90 !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ! Write a triangular mesh + print '(/"Output Mesh Open : ",a )',trim(OutFile) OutMsh = GmfOpenMeshf77(trim(OutFile), GmfWrite, ver, dim) - print '(/"Output Mesh File: ",a," Idx=",i0," version: ",i0," dim: ",i0)',trim(OutFile),OutMsh,ver,dim - print '( "vertices : ",i0)', NmbVer - print '( "triangles : ",i0)', NmbTri + print '( "Output Mesh Idx : ",i0)',InpMsh + print '( "Output Mesh ver : ",i0)',ver + print '( "Output Mesh dim : ",i0)',dim if(OutMsh==0) STOP ' OutMsh = 0' ! Set the number of vertices res=Gmfsetkwdf77(OutMsh, GmfVertices, NmbVer, 0, t, 0, ho) + print '( "Output Mesh NmbVer : ",i0)', NmbVer ! Write them down using separate pointers for each scalar entry res=GmfSetVertices( & @@ -141,48 +145,47 @@ program test_libmeshb_block_f90 ! Write the triangles using 4 independant set of arguments ! for each scalar entry: node1, node2, node3 and reference res=Gmfsetkwdf77(OutMsh, GmfTriangles, NmbTri, 0, t, 0, ho) - - !res = GmfSetElements( & - !& OutMsh ,& - !& GmfTriangles ,& - !& 1 ,& - !& NmbTri ,& - !& 0, m ,& - !& TriTab(1,1), TriTab(1,NmbTri),& - !& TriRef( 1), TriRef( NmbTri) ) - - !> test ecriture par tableau 1D - block - use iso_c_binding, only: c_loc,c_f_pointer - integer , pointer :: nodes(:) - - print '(/"binding TriTab(:,:) and nodes(:)")' - - call c_f_pointer(cptr=c_loc(TriTab), fptr=nodes, shape=[3*NmbTri]) !> binding TriTab(:,:) and nodes(:) - - print '(/"Triangle: ",i6)',1 - print '( "TriTab:",3(i6,1x) )',TriTab(1,1),TriTab(2,1),TriTab(3,1) - print '( "nodes: ",3(i6,1x)/)',nodes(1),nodes(2),nodes(3) - print '(/"Triangle: ",i6)',NmbTri - print '( "TriTab:",3(i6,1x) )',TriTab(1,NmbTri),TriTab(2,NmbTri),TriTab(3,NmbTri) - print '( "nodes: ",3(i6,1x)/)',nodes(3*NmbTri-2),nodes(3*NmbTri-1),nodes(3*NmbTri) - - res=GmfSetElements( & - & InpMsh ,& - & GmfTriangles ,& - & 1 ,& - & NmbTri ,& - & 0, m ,& - & nodes( 1), nodes(3*NmbTri-2),& - & TriRef( 1), TriRef(NmbTri) ) - - end block + print '( "Output Mesh NmbTri : ",i0)', NmbTri + + res = GmfSetElements( & + & OutMsh ,& + & GmfTriangles ,& + & 1 ,& + & NmbTri ,& + & 0, m ,& + & TriTab(1,1), TriTab(1,NmbTri),& + & TriRef( 1), TriRef( NmbTri) ) + + !!> Ecriture par tableau 1D sans recopie + !block + ! use iso_c_binding, only: c_loc,c_f_pointer + ! integer , pointer :: nodes(:) + ! + ! print '(/"binding TriTab(:,:) and nodes(:)")' + ! + ! call c_f_pointer(cptr=c_loc(TriTab), fptr=nodes, shape=[3*NmbTri]) !> binding TriTab(:,:) and nodes(:) + ! + ! print '(/"Triangle: ",i6)',1 + ! print '( "TriTab:",3(i6,1x) )',TriTab(1,1),TriTab(2,1),TriTab(3,1) + ! print '( "nodes: ",3(i6,1x)/)',nodes(1),nodes(2),nodes(3) + ! print '(/"Triangle: ",i6)',NmbTri + ! print '( "TriTab:",3(i6,1x) )',TriTab(1,NmbTri),TriTab(2,NmbTri),TriTab(3,NmbTri) + ! print '( "nodes: ",3(i6,1x)/)',nodes(3*NmbTri-2),nodes(3*NmbTri-1),nodes(3*NmbTri) + ! + ! res=GmfSetElements( & + ! & InpMsh ,& + ! & GmfTriangles ,& + ! & 1 ,& + ! & NmbTri ,& + ! & 0, m ,& + ! & nodes( 1), nodes(3*NmbTri-2),& + ! & TriRef( 1), TriRef(NmbTri) ) + ! + !end block ! Don't forget to close the file res=GmfCloseMeshf77(OutMsh) - - - print '("output mesh :",i0," vertices: ",i0," triangles")',NmbVer,NmbTri + print '("Output Mesh Close : ",a)',trim(OutFile) !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> @@ -193,8 +196,7 @@ program test_libmeshb_block_f90 !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - print '(/"vizir4 -in ",a)',trim(OutFile) - print '(/"test_libmeshb_block_f90")' + print '(/"Constrol"/"vizir4 -in ",a/)',trim(OutFile) !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< end program test_libmeshb_block_f90 From 08bc9479fb18260e5551189d6b416e4624403910 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Mar=C3=A9chal?= Date: Wed, 21 Feb 2024 14:18:14 +0100 Subject: [PATCH 23/38] Added more elements handling to the Fortran API --- sources/libmeshb7.c | 321 ++++++++++++++++++++++++++++++++++++++------ 1 file changed, 283 insertions(+), 38 deletions(-) diff --git a/sources/libmeshb7.c b/sources/libmeshb7.c index 0e0df67..f7e73e3 100644 --- a/sources/libmeshb7.c +++ b/sources/libmeshb7.c @@ -469,6 +469,238 @@ const char *GmfKwdFmt[ GmfMaxKwd + 1 ][3] = int GmfMaxRefTab[ GmfMaxKwd + 1 ]; #endif +static char NmbEleNod[ GmfMaxKwd + 1 ] = +{ + 0, + 0, + 0, + 0, + 0, + 2, + 3, + 4, + 4, + 6, + 8, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 6, + 3, + 0, + 0, + 0, + 0, + 10, + 0, + 0, + 27, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 32, + 8, + 0, + 5, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 18, + 14, + 14, + 25, + 9, + 13, + 4, + 5, + 0, + 0, + 20, + 35, + 64, + 125, + 30, + 55, + 40, + 75, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 +}; + /*----------------------------------------------------------------------------*/ /* Prototypes of local procedures */ @@ -3096,35 +3328,59 @@ int APIF77(gmfsetvertices)(int64_t *MshIdx, int *BegIdx, int *EndIdx, // ELEMENTS -int APIF77(gmfgetelement)(int64_t *MshIdx, int *kwd, int *nod, int *ref) +int APIF77(gmfgetelement)(int64_t *MshIdx, int *kwd, int *n, int *r) { - switch(*kwd) + switch(NmbEleNod[ *kwd ]) { - case GmfEdges : - return(GmfGetLin(*MshIdx, *kwd, &nod[0], &nod[1], ref)); - case GmfTriangles : - return(GmfGetLin(*MshIdx, *kwd, &nod[0], &nod[1], &nod[2], ref)); - case GmfQuadrilaterals : - return(GmfGetLin(*MshIdx, *kwd, &nod[0], &nod[1], &nod[2], &nod[3], ref)); - case GmfTetrahedra : - return(GmfGetLin(*MshIdx, *kwd, &nod[0], &nod[1], &nod[2], &nod[3], ref)); + case 1 : + return(GmfGetLin(*MshIdx, *kwd, &n[0], r)); + case 2 : + return(GmfGetLin(*MshIdx, *kwd, &n[0], &n[1], r)); + case 3 : + return(GmfGetLin(*MshIdx, *kwd, &n[0], &n[1], &n[2], r)); + case 4 : + return(GmfGetLin(*MshIdx, *kwd, &n[0], &n[1], &n[2], &n[3], r)); + case 5 : + return(GmfGetLin(*MshIdx, *kwd, &n[0], &n[1], &n[2], &n[3], &n[4], r)); + case 6 : + return(GmfGetLin(*MshIdx, *kwd, &n[0], &n[1], &n[2], &n[3], &n[4], &n[5], r)); + case 7 : + return(GmfGetLin(*MshIdx, *kwd, &n[0], &n[1], &n[2], &n[3], &n[4], &n[5], &n[6], r)); + case 8 : + return(GmfGetLin(*MshIdx, *kwd, &n[0], &n[1], &n[2], &n[3], &n[4], &n[5], &n[6], &n[7], r)); + case 9 : + return(GmfGetLin(*MshIdx, *kwd, &n[0], &n[1], &n[2], &n[3], &n[4], &n[5], &n[6], &n[7], &n[8], r)); + case 10 : + return(GmfGetLin(*MshIdx, *kwd, &n[0], &n[1], &n[2], &n[3], &n[4], &n[5], &n[6], &n[7], &n[8], &n[9], r)); default : return(0); } } -int APIF77(gmfsetelement)(int64_t *MshIdx, int *kwd, int *nod, int *ref) +int APIF77(gmfsetelement)(int64_t *MshIdx, int *kwd, int *n, int *r) { - switch(*kwd) + switch(NmbEleNod[ *kwd ]) { - case GmfEdges : - return(GmfSetLin(*MshIdx, *kwd, nod[0], nod[1], *ref)); - case GmfTriangles : - return(GmfSetLin(*MshIdx, *kwd, nod[0], nod[1], nod[2], *ref)); - case GmfQuadrilaterals : - return(GmfSetLin(*MshIdx, *kwd, nod[0], nod[1], nod[2], nod[3], *ref)); - case GmfTetrahedra : - return(GmfSetLin(*MshIdx, *kwd, nod[0], nod[1], nod[2], nod[3], *ref)); + case 1 : + return(GmfSetLin(*MshIdx, *kwd, n[0], *r)); + case 2 : + return(GmfSetLin(*MshIdx, *kwd, n[0], n[1], *r)); + case 3 : + return(GmfSetLin(*MshIdx, *kwd, n[0], n[1], n[2], *r)); + case 4 : + return(GmfSetLin(*MshIdx, *kwd, n[0], n[1], n[2], n[3], *r)); + case 5 : + return(GmfSetLin(*MshIdx, *kwd, n[0], n[1], n[2], n[3], n[4], *r)); + case 6 : + return(GmfSetLin(*MshIdx, *kwd, n[0], n[1], n[2], n[3], n[4], n[5], *r)); + case 7 : + return(GmfSetLin(*MshIdx, *kwd, n[0], n[1], n[2], n[3], n[4], n[5], n[6], *r)); + case 8 : + return(GmfSetLin(*MshIdx, *kwd, n[0], n[1], n[2], n[3], n[4], n[5], n[6], n[7], *r)); + case 9 : + return(GmfSetLin(*MshIdx, *kwd, n[0], n[1], n[2], n[3], n[4], n[5], n[6], n[7], n[8], *r)); + case 10 : + return(GmfSetLin(*MshIdx, *kwd, n[0], n[1], n[2], n[3], n[4], n[5], n[6], n[7], n[8], n[9], *r)); default : return(0); } @@ -3135,16 +3391,10 @@ int APIF77(gmfgetelements)(int64_t *MshIdx, int *kwd, int *BegIdx, int *EndIdx, int *BegEle, int *EndEle, int *BegRef, int *EndRef) { - int EleSiz; + int EleSiz = NmbEleNod[ *kwd ]; - switch(*kwd) - { - case GmfEdges : EleSiz = 2; break; - case GmfTriangles : EleSiz = 3; break; - case GmfQuadrilaterals : EleSiz = 4; break; - case GmfTetrahedra : EleSiz = 4; break; - default : return(0); - } + if(!EleSiz) + return(0); return(GmfGetBlock( *MshIdx, *kwd, *BegIdx, *EndIdx, *MapTyp, map, NULL, @@ -3157,16 +3407,11 @@ int APIF77(gmfsetelements)(int64_t *MshIdx, int *kwd, int *BegIdx, int *EndIdx, int *BegEle, int *EndEle, int *BegRef, int *EndRef) { - int EleSiz; + int EleSiz = NmbEleNod[ *kwd ]; + + if(!EleSiz) + return(0); - switch(*kwd) - { - case GmfEdges : EleSiz = 2; break; - case GmfTriangles : EleSiz = 3; break; - case GmfQuadrilaterals : EleSiz = 4; break; - case GmfTetrahedra : EleSiz = 4; break; - default : return(0); - } return(GmfSetBlock( *MshIdx, *kwd, *BegIdx, *EndIdx, *MapTyp, map, NULL, From 073b67b0ea1348627ce49c41f50db271b50fdc8d Mon Sep 17 00:00:00 2001 From: Christophe Peyret Date: Wed, 21 Feb 2024 15:11:13 +0100 Subject: [PATCH 24/38] =?UTF-8?q?=C3=A9criture=20plus=20compacte=20de=20li?= =?UTF-8?q?bmeshb7=5Fmod.f90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sources/libmeshb7_mod.f90 | 779 +++++++++++++------------------------- 1 file changed, 267 insertions(+), 512 deletions(-) diff --git a/sources/libmeshb7_mod.f90 b/sources/libmeshb7_mod.f90 index ce74b64..edae72c 100644 --- a/sources/libmeshb7_mod.f90 +++ b/sources/libmeshb7_mod.f90 @@ -12,12 +12,13 @@ !---------------------------------------------------------- module libmeshb7 - + + use iso_fortran_env use, intrinsic :: iso_c_binding, only: c_int,c_long,c_loc,c_ptr implicit none - !Procedures definition + !Procedures definition external gmfopenmeshf77 external gmfclosemeshf77 external gmfstatkwdf77 @@ -36,522 +37,276 @@ module libmeshb7 external gmfsetsolution - integer*8 gmfopenmeshf77 - integer gmfclosemeshf77 - integer gmfstatkwdf77 - integer gmfsetkwdf77 - integer gmfgotokwdf77 - integer gmfsethonodesorderingf77 - integer gmfgetvertex - integer gmfsetvertex - integer gmfgetelement - integer gmfsetelement - integer gmfgetvertices - integer gmfsetvertices - integer gmfgetelements - integer gmfsetelements - integer gmfgetsolution - integer gmfsetsolution + integer(int64) gmfopenmeshf77 + integer(int32) gmfclosemeshf77 + integer(int32) gmfstatkwdf77 + integer(int32) gmfsetkwdf77 + integer(int32) gmfgotokwdf77 + integer(int32) gmfsethonodesorderingf77 + integer(int32) gmfgetvertex + integer(int32) gmfsetvertex + integer(int32) gmfgetelement + integer(int32) gmfsetelement + integer(int32) gmfgetvertices + integer(int32) gmfsetvertices + integer(int32) gmfgetelements + integer(int32) gmfsetelements + integer(int32) gmfgetsolution + integer(int32) gmfsetsolution ! Parameters definition - integer gmfmaxtyp - integer gmfmaxkwd - integer gmfread - integer gmfwrite - integer gmfsca - integer gmfvec - integer gmfsymmat - integer gmfmat - integer gmffloat - integer gmfdouble - integer gmfint - integer gmflong - integer gmfinttab - integer gmflongtab - integer gmffloatvec - integer gmfdoublevec - integer gmfintvec - integer gmflongvec - integer gmfargtab - integer gmfarglst - - parameter (gmfmaxtyp=1000) - parameter (gmfmaxkwd=227) - parameter (gmfread=1) - parameter (gmfwrite=2) - parameter (gmfsca=1) - parameter (gmfvec=2) - parameter (gmfsymmat=3) - parameter (gmfmat=4) - parameter (gmffloat=8) - parameter (gmfdouble=9) - parameter (gmfint=10) - parameter (gmflong=11) - parameter (gmfinttab=14) - parameter (gmflongtab=15) - parameter (gmffloatvec=12) - parameter (gmfdoublevec=13) - parameter (gmfintvec=14) - parameter (gmflongvec=15) - parameter (gmfargtab=100) - parameter (gmfarglst=101) + + integer(int32), parameter :: gmfmaxtyp=1000 + integer(int32), parameter :: gmfmaxkwd=227 + integer(int32), parameter :: gmfread=1 + integer(int32), parameter :: gmfwrite=2 + integer(int32), parameter :: gmfsca=1 + integer(int32), parameter :: gmfvec=2 + integer(int32), parameter :: gmfsymmat=3 + integer(int32), parameter :: gmfmat=4 + integer(int32), parameter :: gmffloat=8 + integer(int32), parameter :: gmfdouble=9 + integer(int32), parameter :: gmfint=10 + integer(int32), parameter :: gmflong=11 + integer(int32), parameter :: gmfinttab=14 + integer(int32), parameter :: gmflongtab=15 + integer(int32), parameter :: gmffloatvec=12 + integer(int32), parameter :: gmfdoublevec=13 + integer(int32), parameter :: gmfintvec=14 + integer(int32), parameter :: gmflongvec=15 + integer(int32), parameter :: gmfargtab=100 + integer(int32), parameter :: gmfarglst=101 ! Keywords list - integer gmfmeshversionformatted - integer gmfdimension - integer gmfvertices - integer gmfedges - integer gmftriangles - integer gmfquadrilaterals - integer gmftetrahedra - integer gmfprisms - integer gmfhexahedra - integer gmfiterationsall - integer gmftimesall - integer gmfcorners - integer gmfridges - integer gmfrequiredvertices - integer gmfrequirededges - integer gmfrequiredtriangles - integer gmfrequiredquadrilaterals - integer gmftangentatedgevertices - integer gmfnormalatvertices - integer gmfnormalattrianglevertices - integer gmfnormalatquadrilateralvertices - integer gmfangleofcornerbound - integer gmftrianglesp2 - integer gmfedgesp2 - integer gmfsolatpyramids - integer gmfquadrilateralsq2 - integer gmfisolatpyramids - integer gmfsubdomainfromgeom - integer gmftetrahedrap2 - integer gmffault_neartri - integer gmffault_inter - integer gmfhexahedraq2 - integer gmfextraverticesatedges - integer gmfextraverticesattriangles - integer gmfextraverticesatquadrilaterals - integer gmfextraverticesattetrahedra - integer gmfextraverticesatprisms - integer gmfextraverticesathexahedra - integer gmfverticesongeometricvertices - integer gmfverticesongeometricedges - integer gmfverticesongeometrictriangles - integer gmfverticesongeometricquadrilaterals - integer gmfedgesongeometricedges - integer gmffault_freeedge - integer gmfpolyhedra - integer gmfpolygons - integer gmffault_overlap - integer gmfpyramids - integer gmfboundingbox - integer gmfbody - integer gmfprivatetable - integer gmffault_badshape - integer gmfend - integer gmftrianglesongeometrictriangles - integer gmftrianglesongeometricquadrilaterals - integer gmfquadrilateralsongeometrictriangles - integer gmfquadrilateralsongeometricquadrilaterals - integer gmftangents - integer gmfnormals - integer gmftangentatvertices - integer gmfsolatvertices - integer gmfsolatedges - integer gmfsolattriangles - integer gmfsolatquadrilaterals - integer gmfsolattetrahedra - integer gmfsolatprisms - integer gmfsolathexahedra - integer gmfdsolatvertices - integer gmfisolatvertices - integer gmfisolatedges - integer gmfisolattriangles - integer gmfisolatquadrilaterals - integer gmfisolattetrahedra - integer gmfisolatprisms - integer gmfisolathexahedra - integer gmfiterations - integer gmftime - integer gmffault_smalltri - integer gmfcoarsehexahedra - integer gmfcomments - integer gmfperiodicvertices - integer gmfperiodicedges - integer gmfperiodictriangles - integer gmfperiodicquadrilaterals - integer gmfprismsp2 - integer gmfpyramidsp2 - integer gmfquadrilateralsq3 - integer gmfquadrilateralsq4 - integer gmftrianglesp3 - integer gmftrianglesp4 - integer gmfedgesp3 - integer gmfedgesp4 - integer gmfirefgroups - integer gmfdrefgroups - integer gmftetrahedrap3 - integer gmftetrahedrap4 - integer gmfhexahedraq3 - integer gmfhexahedraq4 - integer gmfpyramidsp3 - integer gmfpyramidsp4 - integer gmfprismsp3 - integer gmfprismsp4 - integer gmfhosolatedgesp1 - integer gmfhosolatedgesp2 - integer gmfhosolatedgesp3 - integer gmfhosolattrianglesp1 - integer gmfhosolattrianglesp2 - integer gmfhosolattrianglesp3 - integer gmfhosolatquadrilateralsq1 - integer gmfhosolatquadrilateralsq2 - integer gmfhosolatquadrilateralsq3 - integer gmfhosolattetrahedrap1 - integer gmfhosolattetrahedrap2 - integer gmfhosolattetrahedrap3 - integer gmfhosolatpyramidsp1 - integer gmfhosolatpyramidsp2 - integer gmfhosolatpyramidsp3 - integer gmfhosolatprismsp1 - integer gmfhosolatprismsp2 - integer gmfhosolatprismsp3 - integer gmfhosolathexahedraq1 - integer gmfhosolathexahedraq2 - integer gmfhosolathexahedraq3 - integer gmfbezierbasis - integer gmfbyteflow - integer gmfedgesp2ordering - integer gmfedgesp3ordering - integer gmftrianglesp2ordering - integer gmftrianglesp3ordering - integer gmfquadrilateralsq2ordering - integer gmfquadrilateralsq3ordering - integer gmftetrahedrap2ordering - integer gmftetrahedrap3ordering - integer gmfpyramidsp2ordering - integer gmfpyramidsp3ordering - integer gmfprismsp2ordering - integer gmfprismsp3ordering - integer gmfhexahedraq2ordering - integer gmfhexahedraq3ordering - integer gmfedgesp1ordering - integer gmfedgesp4ordering - integer gmftrianglesp1ordering - integer gmftrianglesp4ordering - integer gmfquadrilateralsq1ordering - integer gmfquadrilateralsq4ordering - integer gmftetrahedrap1ordering - integer gmftetrahedrap4ordering - integer gmfpyramidsp1ordering - integer gmfpyramidsp4ordering - integer gmfprismsp1ordering - integer gmfprismsp4ordering - integer gmfhexahedraq1ordering - integer gmfhexahedraq4ordering - integer gmffloatingpointprecision - integer gmfhosolatedgesp4 - integer gmfhosolattrianglesp4 - integer gmfhosolatquadrilateralsq4 - integer gmfhosolattetrahedrap4 - integer gmfhosolatpyramidsp4 - integer gmfhosolatprismsp4 - integer gmfhosolathexahedraq4 - integer gmfhosolatedgesp1nodespositions - integer gmfhosolatedgesp2nodespositions - integer gmfhosolatedgesp3nodespositions - integer gmfhosolatedgesp4nodespositions - integer gmfhosolattrianglesp1nodespositions - integer gmfhosolattrianglesp2nodespositions - integer gmfhosolattrianglesp3nodespositions - integer gmfhosolattrianglesp4nodespositions - integer gmfhosolatquadrilateralsq1nodespositions - integer gmfhosolatquadrilateralsq2nodespositions - integer gmfhosolatquadrilateralsq3nodespositions - integer gmfhosolatquadrilateralsq4nodespositions - integer gmfhosolattetrahedrap1nodespositions - integer gmfhosolattetrahedrap2nodespositions - integer gmfhosolattetrahedrap3nodespositions - integer gmfhosolattetrahedrap4nodespositions - integer gmfhosolatpyramidsp1nodespositions - integer gmfhosolatpyramidsp2nodespositions - integer gmfhosolatpyramidsp3nodespositions - integer gmfhosolatpyramidsp4nodespositions - integer gmfhosolatprismsp1nodespositions - integer gmfhosolatprismsp2nodespositions - integer gmfhosolatprismsp3nodespositions - integer gmfhosolatprismsp4nodespositions - integer gmfhosolathexahedraq1nodespositions - integer gmfhosolathexahedraq2nodespositions - integer gmfhosolathexahedraq3nodespositions - integer gmfhosolathexahedraq4nodespositions - integer gmfedgesreferenceelement - integer gmftrianglereferenceelement - integer gmfquadrilateralreferenceelement - integer gmftetrahedronreferenceelement - integer gmfpyramidreferenceelement - integer gmfprismreferenceelement - integer gmfhexahedronreferenceelement - integer gmfboundarylayers - integer gmfreferencestrings - integer gmfprisms9 - integer gmfhexahedra12 - integer gmfquadrilaterals6 - integer gmfboundarypolygonheaders - integer gmfboundarypolygonvertices - integer gmfinnerpolygonheaders - integer gmfinnerpolygonvertices - integer gmfpolyhedraheaders - integer gmfpolyhedrafaces - integer gmfdomains - integer gmfverticesgid - integer gmfedgesgid - integer gmftrianglesgid - integer gmfquadrilateralsgid - integer gmftetrahedragid - integer gmfpyramidsgid - integer gmfprismsgid - integer gmfhexahedragid - integer gmfsolatboundarypolygons - integer gmfsolatpolyhedra - integer gmfverticesongeometrynodes - integer gmfverticesongeometryedges - integer gmfedgesongeometryedges - integer gmfverticesongeometryfaces - integer gmfedgesongeometryfaces - integer gmftrianglesongeometryfaces - integer gmfquadrialteralsongeometryfaces - integer gmfmeshongeometry - - parameter (gmfmeshversionformatted=1) - parameter (gmfdimension=3) - parameter (gmfvertices=4) - parameter (gmfedges=5) - parameter (gmftriangles=6) - parameter (gmfquadrilaterals=7) - parameter (gmftetrahedra=8) - parameter (gmfprisms=9) - parameter (gmfhexahedra=10) - parameter (gmfiterationsall=11) - parameter (gmftimesall=12) - parameter (gmfcorners=13) - parameter (gmfridges=14) - parameter (gmfrequiredvertices=15) - parameter (gmfrequirededges=16) - parameter (gmfrequiredtriangles=17) - parameter (gmfrequiredquadrilaterals=18) - parameter (gmftangentatedgevertices=19) - parameter (gmfnormalatvertices=20) - parameter (gmfnormalattrianglevertices=21) - parameter (gmfnormalatquadrilateralvertices=22) - parameter (gmfangleofcornerbound=23) - parameter (gmftrianglesp2=24) - parameter (gmfedgesp2=25) - parameter (gmfsolatpyramids=26) - parameter (gmfquadrilateralsq2=27) - parameter (gmfisolatpyramids=28) - parameter (gmfsubdomainfromgeom=29) - parameter (gmftetrahedrap2=30) - parameter (gmffault_neartri=31) - parameter (gmffault_inter=32) - parameter (gmfhexahedraq2=33) - parameter (gmfextraverticesatedges=34) - parameter (gmfextraverticesattriangles=35) - parameter (gmfextraverticesatquadrilaterals=36) - parameter (gmfextraverticesattetrahedra=37) - parameter (gmfextraverticesatprisms=38) - parameter (gmfextraverticesathexahedra=39) - parameter (gmfverticesongeometricvertices=40) - parameter (gmfverticesongeometricedges=41) - parameter (gmfverticesongeometrictriangles=42) - parameter (gmfverticesongeometricquadrilaterals=43) - parameter (gmfedgesongeometricedges=44) - parameter (gmffault_freeedge=45) - parameter (gmfpolyhedra=46) - parameter (gmfpolygons=47) - parameter (gmffault_overlap=48) - parameter (gmfpyramids=49) - parameter (gmfboundingbox=50) - parameter (gmfbody=51) - parameter (gmfprivatetable=52) - parameter (gmffault_badshape=53) - parameter (gmfend=54) - parameter (gmftrianglesongeometrictriangles=55) - parameter (gmftrianglesongeometricquadrilaterals=56) - parameter (gmfquadrilateralsongeometrictriangles=57) - parameter (gmfquadrilateralsongeometricquadrilaterals=58) - parameter (gmftangents=59) - parameter (gmfnormals=60) - parameter (gmftangentatvertices=61) - parameter (gmfsolatvertices=62) - parameter (gmfsolatedges=63) - parameter (gmfsolattriangles=64) - parameter (gmfsolatquadrilaterals=65) - parameter (gmfsolattetrahedra=66) - parameter (gmfsolatprisms=67) - parameter (gmfsolathexahedra=68) - parameter (gmfdsolatvertices=69) - parameter (gmfisolatvertices=70) - parameter (gmfisolatedges=71) - parameter (gmfisolattriangles=72) - parameter (gmfisolatquadrilaterals=73) - parameter (gmfisolattetrahedra=74) - parameter (gmfisolatprisms=75) - parameter (gmfisolathexahedra=76) - parameter (gmfiterations=77) - parameter (gmftime=78) - parameter (gmffault_smalltri=79) - parameter (gmfcoarsehexahedra=80) - parameter (gmfcomments=81) - parameter (gmfperiodicvertices=82) - parameter (gmfperiodicedges=83) - parameter (gmfperiodictriangles=84) - parameter (gmfperiodicquadrilaterals=85) - parameter (gmfprismsp2=86) - parameter (gmfpyramidsp2=87) - parameter (gmfquadrilateralsq3=88) - parameter (gmfquadrilateralsq4=89) - parameter (gmftrianglesp3=90) - parameter (gmftrianglesp4=91) - parameter (gmfedgesp3=92) - parameter (gmfedgesp4=93) - parameter (gmfirefgroups=94) - parameter (gmfdrefgroups=95) - parameter (gmftetrahedrap3=96) - parameter (gmftetrahedrap4=97) - parameter (gmfhexahedraq3=98) - parameter (gmfhexahedraq4=99) - parameter (gmfpyramidsp3=100) - parameter (gmfpyramidsp4=101) - parameter (gmfprismsp3=102) - parameter (gmfprismsp4=103) - parameter (gmfhosolatedgesp1=104) - parameter (gmfhosolatedgesp2=105) - parameter (gmfhosolatedgesp3=106) - parameter (gmfhosolattrianglesp1=107) - parameter (gmfhosolattrianglesp2=108) - parameter (gmfhosolattrianglesp3=109) - parameter (gmfhosolatquadrilateralsq1=110) - parameter (gmfhosolatquadrilateralsq2=111) - parameter (gmfhosolatquadrilateralsq3=112) - parameter (gmfhosolattetrahedrap1=113) - parameter (gmfhosolattetrahedrap2=114) - parameter (gmfhosolattetrahedrap3=115) - parameter (gmfhosolatpyramidsp1=116) - parameter (gmfhosolatpyramidsp2=117) - parameter (gmfhosolatpyramidsp3=118) - parameter (gmfhosolatprismsp1=119) - parameter (gmfhosolatprismsp2=120) - parameter (gmfhosolatprismsp3=121) - parameter (gmfhosolathexahedraq1=122) - parameter (gmfhosolathexahedraq2=123) - parameter (gmfhosolathexahedraq3=124) - parameter (gmfbezierbasis=125) - parameter (gmfbyteflow=126) - parameter (gmfedgesp2ordering=127) - parameter (gmfedgesp3ordering=128) - parameter (gmftrianglesp2ordering=129) - parameter (gmftrianglesp3ordering=130) - parameter (gmfquadrilateralsq2ordering=131) - parameter (gmfquadrilateralsq3ordering=132) - parameter (gmftetrahedrap2ordering=133) - parameter (gmftetrahedrap3ordering=134) - parameter (gmfpyramidsp2ordering=135) - parameter (gmfpyramidsp3ordering=136) - parameter (gmfprismsp2ordering=137) - parameter (gmfprismsp3ordering=138) - parameter (gmfhexahedraq2ordering=139) - parameter (gmfhexahedraq3ordering=140) - parameter (gmfedgesp1ordering=141) - parameter (gmfedgesp4ordering=142) - parameter (gmftrianglesp1ordering=143) - parameter (gmftrianglesp4ordering=144) - parameter (gmfquadrilateralsq1ordering=145) - parameter (gmfquadrilateralsq4ordering=146) - parameter (gmftetrahedrap1ordering=147) - parameter (gmftetrahedrap4ordering=148) - parameter (gmfpyramidsp1ordering=149) - parameter (gmfpyramidsp4ordering=150) - parameter (gmfprismsp1ordering=151) - parameter (gmfprismsp4ordering=152) - parameter (gmfhexahedraq1ordering=153) - parameter (gmfhexahedraq4ordering=154) - parameter (gmffloatingpointprecision=155) - parameter (gmfhosolatedgesp4=156) - parameter (gmfhosolattrianglesp4=157) - parameter (gmfhosolatquadrilateralsq4=158) - parameter (gmfhosolattetrahedrap4=159) - parameter (gmfhosolatpyramidsp4=160) - parameter (gmfhosolatprismsp4=161) - parameter (gmfhosolathexahedraq4=162) - parameter (gmfhosolatedgesp1nodespositions=163) - parameter (gmfhosolatedgesp2nodespositions=164) - parameter (gmfhosolatedgesp3nodespositions=165) - parameter (gmfhosolatedgesp4nodespositions=166) - parameter (gmfhosolattrianglesp1nodespositions=167) - parameter (gmfhosolattrianglesp2nodespositions=168) - parameter (gmfhosolattrianglesp3nodespositions=169) - parameter (gmfhosolattrianglesp4nodespositions=170) - parameter (gmfhosolatquadrilateralsq1nodespositions=171) - parameter (gmfhosolatquadrilateralsq2nodespositions=172) - parameter (gmfhosolatquadrilateralsq3nodespositions=173) - parameter (gmfhosolatquadrilateralsq4nodespositions=174) - parameter (gmfhosolattetrahedrap1nodespositions=175) - parameter (gmfhosolattetrahedrap2nodespositions=176) - parameter (gmfhosolattetrahedrap3nodespositions=177) - parameter (gmfhosolattetrahedrap4nodespositions=178) - parameter (gmfhosolatpyramidsp1nodespositions=179) - parameter (gmfhosolatpyramidsp2nodespositions=180) - parameter (gmfhosolatpyramidsp3nodespositions=181) - parameter (gmfhosolatpyramidsp4nodespositions=182) - parameter (gmfhosolatprismsp1nodespositions=183) - parameter (gmfhosolatprismsp2nodespositions=184) - parameter (gmfhosolatprismsp3nodespositions=185) - parameter (gmfhosolatprismsp4nodespositions=186) - parameter (gmfhosolathexahedraq1nodespositions=187) - parameter (gmfhosolathexahedraq2nodespositions=188) - parameter (gmfhosolathexahedraq3nodespositions=189) - parameter (gmfhosolathexahedraq4nodespositions=190) - parameter (gmfedgesreferenceelement=191) - parameter (gmftrianglereferenceelement=192) - parameter (gmfquadrilateralreferenceelement=193) - parameter (gmftetrahedronreferenceelement=194) - parameter (gmfpyramidreferenceelement=195) - parameter (gmfprismreferenceelement=196) - parameter (gmfhexahedronreferenceelement=197) - parameter (gmfboundarylayers=198) - parameter (gmfreferencestrings=199) - parameter (gmfprisms9=200) - parameter (gmfhexahedra12=201) - parameter (gmfquadrilaterals6=202) - parameter (gmfboundarypolygonheaders=203) - parameter (gmfboundarypolygonvertices=204) - parameter (gmfinnerpolygonheaders=205) - parameter (gmfinnerpolygonvertices=206) - parameter (gmfpolyhedraheaders=207) - parameter (gmfpolyhedrafaces=208) - parameter (gmfdomains=209) - parameter (gmfverticesgid=210) - parameter (gmfedgesgid=211) - parameter (gmftrianglesgid=212) - parameter (gmfquadrilateralsgid=213) - parameter (gmftetrahedragid=214) - parameter (gmfpyramidsgid=215) - parameter (gmfprismsgid=216) - parameter (gmfhexahedragid=217) - parameter (gmfsolatboundarypolygons=218) - parameter (gmfsolatpolyhedra=219) - parameter (gmfverticesongeometrynodes=220) - parameter (gmfverticesongeometryedges=221) - parameter (gmfedgesongeometryedges=222) - parameter (gmfverticesongeometryfaces=223) - parameter (gmfedgesongeometryfaces=224) - parameter (gmftrianglesongeometryfaces=225) - parameter (gmfquadrialteralsongeometryfaces=226) - parameter (gmfmeshongeometry=227) + + integer(int32), parameter :: gmfdimension=3 + integer(int32), parameter :: gmfmeshversionformatted=1 + integer(int32), parameter :: gmfvertices=4 + integer(int32), parameter :: gmfedges=5 + integer(int32), parameter :: gmftriangles=6 + integer(int32), parameter :: gmfquadrilaterals=7 + integer(int32), parameter :: gmftetrahedra=8 + integer(int32), parameter :: gmfprisms=9 + integer(int32), parameter :: gmfhexahedra=10 + integer(int32), parameter :: gmfiterationsall=11 + integer(int32), parameter :: gmftimesall=12 + integer(int32), parameter :: gmfcorners=13 + integer(int32), parameter :: gmfridges=14 + integer(int32), parameter :: gmfrequiredvertices=15 + integer(int32), parameter :: gmfrequirededges=16 + integer(int32), parameter :: gmfrequiredtriangles=17 + integer(int32), parameter :: gmfrequiredquadrilaterals=18 + integer(int32), parameter :: gmftangentatedgevertices=19 + integer(int32), parameter :: gmfnormalatvertices=20 + integer(int32), parameter :: gmfnormalattrianglevertices=21 + integer(int32), parameter :: gmfnormalatquadrilateralvertices=22 + integer(int32), parameter :: gmfangleofcornerbound=23 + integer(int32), parameter :: gmftrianglesp2=24 + integer(int32), parameter :: gmfedgesp2=25 + integer(int32), parameter :: gmfsolatpyramids=26 + integer(int32), parameter :: gmfquadrilateralsq2=27 + integer(int32), parameter :: gmfisolatpyramids=28 + integer(int32), parameter :: gmfsubdomainfromgeom=29 + integer(int32), parameter :: gmftetrahedrap2=30 + integer(int32), parameter :: gmffault_neartri=31 + integer(int32), parameter :: gmffault_inter=32 + integer(int32), parameter :: gmfhexahedraq2=33 + integer(int32), parameter :: gmfextraverticesatedges=34 + integer(int32), parameter :: gmfextraverticesattriangles=35 + integer(int32), parameter :: gmfextraverticesatquadrilaterals=36 + integer(int32), parameter :: gmfextraverticesattetrahedra=37 + integer(int32), parameter :: gmfextraverticesatprisms=38 + integer(int32), parameter :: gmfextraverticesathexahedra=39 + integer(int32), parameter :: gmfverticesongeometricvertices=40 + integer(int32), parameter :: gmfverticesongeometricedges=41 + integer(int32), parameter :: gmfverticesongeometrictriangles=42 + integer(int32), parameter :: gmfverticesongeometricquadrilaterals=43 + integer(int32), parameter :: gmfedgesongeometricedges=44 + integer(int32), parameter :: gmffault_freeedge=45 + integer(int32), parameter :: gmfpolyhedra=46 + integer(int32), parameter :: gmfpolygons=47 + integer(int32), parameter :: gmffault_overlap=48 + integer(int32), parameter :: gmfpyramids=49 + integer(int32), parameter :: gmfboundingbox=50 + integer(int32), parameter :: gmfbody=51 + integer(int32), parameter :: gmfprivatetable=52 + integer(int32), parameter :: gmffault_badshape=53 + integer(int32), parameter :: gmfend=54 + integer(int32), parameter :: gmftrianglesongeometrictriangles=55 + integer(int32), parameter :: gmftrianglesongeometricquadrilaterals=56 + integer(int32), parameter :: gmfquadrilateralsongeometrictriangles=57 + integer(int32), parameter :: gmfquadrilateralsongeometricquadrilaterals=58 + integer(int32), parameter :: gmftangents=59 + integer(int32), parameter :: gmfnormals=60 + integer(int32), parameter :: gmftangentatvertices=61 + integer(int32), parameter :: gmfsolatvertices=62 + integer(int32), parameter :: gmfsolatedges=63 + integer(int32), parameter :: gmfsolattriangles=64 + integer(int32), parameter :: gmfsolatquadrilaterals=65 + integer(int32), parameter :: gmfsolattetrahedra=66 + integer(int32), parameter :: gmfsolatprisms=67 + integer(int32), parameter :: gmfsolathexahedra=68 + integer(int32), parameter :: gmfdsolatvertices=69 + integer(int32), parameter :: gmfisolatvertices=70 + integer(int32), parameter :: gmfisolatedges=71 + integer(int32), parameter :: gmfisolattriangles=72 + integer(int32), parameter :: gmfisolatquadrilaterals=73 + integer(int32), parameter :: gmfisolattetrahedra=74 + integer(int32), parameter :: gmfisolatprisms=75 + integer(int32), parameter :: gmfisolathexahedra=76 + integer(int32), parameter :: gmfiterations=77 + integer(int32), parameter :: gmftime=78 + integer(int32), parameter :: gmffault_smalltri=79 + integer(int32), parameter :: gmfcoarsehexahedra=80 + integer(int32), parameter :: gmfcomments=81 + integer(int32), parameter :: gmfperiodicvertices=82 + integer(int32), parameter :: gmfperiodicedges=83 + integer(int32), parameter :: gmfperiodictriangles=84 + integer(int32), parameter :: gmfperiodicquadrilaterals=85 + integer(int32), parameter :: gmfprismsp2=86 + integer(int32), parameter :: gmfpyramidsp2=87 + integer(int32), parameter :: gmfquadrilateralsq3=88 + integer(int32), parameter :: gmfquadrilateralsq4=89 + integer(int32), parameter :: gmftrianglesp3=90 + integer(int32), parameter :: gmftrianglesp4=91 + integer(int32), parameter :: gmfedgesp3=92 + integer(int32), parameter :: gmfedgesp4=93 + integer(int32), parameter :: gmfirefgroups=94 + integer(int32), parameter :: gmfdrefgroups=95 + integer(int32), parameter :: gmftetrahedrap3=96 + integer(int32), parameter :: gmftetrahedrap4=97 + integer(int32), parameter :: gmfhexahedraq3=98 + integer(int32), parameter :: gmfhexahedraq4=99 + integer(int32), parameter :: gmfpyramidsp3=100 + integer(int32), parameter :: gmfpyramidsp4=101 + integer(int32), parameter :: gmfprismsp3=102 + integer(int32), parameter :: gmfprismsp4=103 + integer(int32), parameter :: gmfhosolatedgesp1=104 + integer(int32), parameter :: gmfhosolatedgesp2=105 + integer(int32), parameter :: gmfhosolatedgesp3=106 + integer(int32), parameter :: gmfhosolattrianglesp1=107 + integer(int32), parameter :: gmfhosolattrianglesp2=108 + integer(int32), parameter :: gmfhosolattrianglesp3=109 + integer(int32), parameter :: gmfhosolatquadrilateralsq1=110 + integer(int32), parameter :: gmfhosolatquadrilateralsq2=111 + integer(int32), parameter :: gmfhosolatquadrilateralsq3=112 + integer(int32), parameter :: gmfhosolattetrahedrap1=113 + integer(int32), parameter :: gmfhosolattetrahedrap2=114 + integer(int32), parameter :: gmfhosolattetrahedrap3=115 + integer(int32), parameter :: gmfhosolatpyramidsp1=116 + integer(int32), parameter :: gmfhosolatpyramidsp2=117 + integer(int32), parameter :: gmfhosolatpyramidsp3=118 + integer(int32), parameter :: gmfhosolatprismsp1=119 + integer(int32), parameter :: gmfhosolatprismsp2=120 + integer(int32), parameter :: gmfhosolatprismsp3=121 + integer(int32), parameter :: gmfhosolathexahedraq1=122 + integer(int32), parameter :: gmfhosolathexahedraq2=123 + integer(int32), parameter :: gmfhosolathexahedraq3=124 + integer(int32), parameter :: gmfbezierbasis=125 + integer(int32), parameter :: gmfbyteflow=126 + integer(int32), parameter :: gmfedgesp2ordering=127 + integer(int32), parameter :: gmfedgesp3ordering=128 + integer(int32), parameter :: gmftrianglesp2ordering=129 + integer(int32), parameter :: gmftrianglesp3ordering=130 + integer(int32), parameter :: gmfquadrilateralsq2ordering=131 + integer(int32), parameter :: gmfquadrilateralsq3ordering=132 + integer(int32), parameter :: gmftetrahedrap2ordering=133 + integer(int32), parameter :: gmftetrahedrap3ordering=134 + integer(int32), parameter :: gmfpyramidsp2ordering=135 + integer(int32), parameter :: gmfpyramidsp3ordering=136 + integer(int32), parameter :: gmfprismsp2ordering=137 + integer(int32), parameter :: gmfprismsp3ordering=138 + integer(int32), parameter :: gmfhexahedraq2ordering=139 + integer(int32), parameter :: gmfhexahedraq3ordering=140 + integer(int32), parameter :: gmfedgesp1ordering=141 + integer(int32), parameter :: gmfedgesp4ordering=142 + integer(int32), parameter :: gmftrianglesp1ordering=143 + integer(int32), parameter :: gmftrianglesp4ordering=144 + integer(int32), parameter :: gmfquadrilateralsq1ordering=145 + integer(int32), parameter :: gmfquadrilateralsq4ordering=146 + integer(int32), parameter :: gmftetrahedrap1ordering=147 + integer(int32), parameter :: gmftetrahedrap4ordering=148 + integer(int32), parameter :: gmfpyramidsp1ordering=149 + integer(int32), parameter :: gmfpyramidsp4ordering=150 + integer(int32), parameter :: gmfprismsp1ordering=151 + integer(int32), parameter :: gmfprismsp4ordering=152 + integer(int32), parameter :: gmfhexahedraq1ordering=153 + integer(int32), parameter :: gmfhexahedraq4ordering=154 + integer(int32), parameter :: gmffloatingpointprecision=155 + integer(int32), parameter :: gmfhosolatedgesp4=156 + integer(int32), parameter :: gmfhosolattrianglesp4=157 + integer(int32), parameter :: gmfhosolatquadrilateralsq4=158 + integer(int32), parameter :: gmfhosolattetrahedrap4=159 + integer(int32), parameter :: gmfhosolatpyramidsp4=160 + integer(int32), parameter :: gmfhosolatprismsp4=161 + integer(int32), parameter :: gmfhosolathexahedraq4=162 + integer(int32), parameter :: gmfhosolatedgesp1nodespositions=163 + integer(int32), parameter :: gmfhosolatedgesp2nodespositions=164 + integer(int32), parameter :: gmfhosolatedgesp3nodespositions=165 + integer(int32), parameter :: gmfhosolatedgesp4nodespositions=166 + integer(int32), parameter :: gmfhosolattrianglesp1nodespositions=167 + integer(int32), parameter :: gmfhosolattrianglesp2nodespositions=168 + integer(int32), parameter :: gmfhosolattrianglesp3nodespositions=169 + integer(int32), parameter :: gmfhosolattrianglesp4nodespositions=170 + integer(int32), parameter :: gmfhosolatquadrilateralsq1nodespositions=171 + integer(int32), parameter :: gmfhosolatquadrilateralsq2nodespositions=172 + integer(int32), parameter :: gmfhosolatquadrilateralsq3nodespositions=173 + integer(int32), parameter :: gmfhosolatquadrilateralsq4nodespositions=174 + integer(int32), parameter :: gmfhosolattetrahedrap1nodespositions=175 + integer(int32), parameter :: gmfhosolattetrahedrap2nodespositions=176 + integer(int32), parameter :: gmfhosolattetrahedrap3nodespositions=177 + integer(int32), parameter :: gmfhosolattetrahedrap4nodespositions=178 + integer(int32), parameter :: gmfhosolatpyramidsp1nodespositions=179 + integer(int32), parameter :: gmfhosolatpyramidsp2nodespositions=180 + integer(int32), parameter :: gmfhosolatpyramidsp3nodespositions=181 + integer(int32), parameter :: gmfhosolatpyramidsp4nodespositions=182 + integer(int32), parameter :: gmfhosolatprismsp1nodespositions=183 + integer(int32), parameter :: gmfhosolatprismsp2nodespositions=184 + integer(int32), parameter :: gmfhosolatprismsp3nodespositions=185 + integer(int32), parameter :: gmfhosolatprismsp4nodespositions=186 + integer(int32), parameter :: gmfhosolathexahedraq1nodespositions=187 + integer(int32), parameter :: gmfhosolathexahedraq2nodespositions=188 + integer(int32), parameter :: gmfhosolathexahedraq3nodespositions=189 + integer(int32), parameter :: gmfhosolathexahedraq4nodespositions=190 + integer(int32), parameter :: gmfedgesreferenceelement=191 + integer(int32), parameter :: gmftrianglereferenceelement=192 + integer(int32), parameter :: gmfquadrilateralreferenceelement=193 + integer(int32), parameter :: gmftetrahedronreferenceelement=194 + integer(int32), parameter :: gmfpyramidreferenceelement=195 + integer(int32), parameter :: gmfprismreferenceelement=196 + integer(int32), parameter :: gmfhexahedronreferenceelement=197 + integer(int32), parameter :: gmfboundarylayers=198 + integer(int32), parameter :: gmfreferencestrings=199 + integer(int32), parameter :: gmfprisms9=200 + integer(int32), parameter :: gmfhexahedra12=201 + integer(int32), parameter :: gmfquadrilaterals6=202 + integer(int32), parameter :: gmfboundarypolygonheaders=203 + integer(int32), parameter :: gmfboundarypolygonvertices=204 + integer(int32), parameter :: gmfinnerpolygonheaders=205 + integer(int32), parameter :: gmfinnerpolygonvertices=206 + integer(int32), parameter :: gmfpolyhedraheaders=207 + integer(int32), parameter :: gmfpolyhedrafaces=208 + integer(int32), parameter :: gmfdomains=209 + integer(int32), parameter :: gmfverticesgid=210 + integer(int32), parameter :: gmfedgesgid=211 + integer(int32), parameter :: gmftrianglesgid=212 + integer(int32), parameter :: gmfquadrilateralsgid=213 + integer(int32), parameter :: gmftetrahedragid=214 + integer(int32), parameter :: gmfpyramidsgid=215 + integer(int32), parameter :: gmfprismsgid=216 + integer(int32), parameter :: gmfhexahedragid=217 + integer(int32), parameter :: gmfsolatboundarypolygons=218 + integer(int32), parameter :: gmfsolatpolyhedra=219 + integer(int32), parameter :: gmfverticesongeometrynodes=220 + integer(int32), parameter :: gmfverticesongeometryedges=221 + integer(int32), parameter :: gmfedgesongeometryedges=222 + integer(int32), parameter :: gmfverticesongeometryfaces=223 + integer(int32), parameter :: gmfedgesongeometryfaces=224 + integer(int32), parameter :: gmftrianglesongeometryfaces=225 + integer(int32), parameter :: gmfquadrialteralsongeometryfaces=226 + integer(int32), parameter :: gmfmeshongeometry=227 ! !> interface GmfSetHONodesOrdering_c ! interface From 6c868b7475bd80b8ba6073b7b8da72ab3a2bf90a Mon Sep 17 00:00:00 2001 From: Christophe Peyret Date: Wed, 21 Feb 2024 16:47:29 +0100 Subject: [PATCH 25/38] =?UTF-8?q?Ajout=20dans=20le=20module=20fortran=20d'?= =?UTF-8?q?appels=20=C3=A0=20nombre=20r=C3=A9duit=20d'arguments.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- examples/test_libmeshb.f90 | 10 +- examples/test_libmeshb_HO.f90 | 10 +- examples/test_libmeshb_block.f90 | 8 +- sources/libmeshb7_mod.f90 | 757 +++++++++++++++---------------- 4 files changed, 380 insertions(+), 405 deletions(-) diff --git a/examples/test_libmeshb.f90 b/examples/test_libmeshb.f90 index dcb79ec..0ff6268 100644 --- a/examples/test_libmeshb.f90 +++ b/examples/test_libmeshb.f90 @@ -51,7 +51,7 @@ program test_libmeshb_f90 ! Read the vertices - NmbVer = Gmfstatkwdf77(InpMsh, GmfVertices, 0, s, fields, d, ho) + NmbVer = Gmfstatkwd(unit=InpMsh, GmfKey=GmfVertices) print '( "Input Mesh NmbVer : ",i0)', NmbVer allocate(VerTab(1:3,1:NmbVer)) allocate(VerRef( 1:NmbVer)) @@ -63,7 +63,7 @@ program test_libmeshb_f90 ! Read the quads - NmbQad=Gmfstatkwdf77(InpMsh, GmfQuadrilaterals, 0, s, fields, d, ho) + NmbQad = Gmfstatkwd(unit=InpMsh, GmfKey=GmfQuadrilaterals) print '( "Input Mesh NmbQad : ",i0)', NmbQad allocate(QadTab(1:4,1:NmbQad)) allocate(QadRef( 1:NmbQad)) @@ -90,7 +90,7 @@ program test_libmeshb_f90 if( OutMsh==0 ) STOP ' OutMsh = 0' ! Set the number of vertices - res=GmfSetKwdf77(OutMsh, GmfVertices, NmbVer, 0, fields, 0, ho) + res=GmfSetKwd(OutMsh, GmfVertices, NmbVer) print '( "Output Mesh NmbVer : ",i0)', NmbVer ! Then write them down @@ -99,7 +99,7 @@ program test_libmeshb_f90 end do ! Write the triangles - res = Gmfsetkwdf77(OutMsh, GmfTriangles, 2*NmbQad, 0, fields, 0, ho) + res = GmfSetKwd(OutMsh, GmfTriangles, 2*NmbQad) print '( "Output Mesh NmbTri : ",i0)', NmbTri do i=1,NmbQad @@ -134,7 +134,7 @@ program test_libmeshb_f90 print '( "Output Solu fields : ", *(i0,1x))',fields(1:NmbField) ! Set the number of solutions (one per vertex) - res = GmfSetKwdF77(OutSol, GmfSolAtVertices, NmbVer, NmbField, fields(1:NmbField), 0, ho) + res = GmfSetKwd(OutSol, GmfSolAtVertices, NmbVer, NmbField, fields(1:NmbField), 0, ho) ! Write the dummy solution fields do i=1,NmbVer diff --git a/examples/test_libmeshb_HO.f90 b/examples/test_libmeshb_HO.f90 index 7489b0a..3f8fd4c 100644 --- a/examples/test_libmeshb_HO.f90 +++ b/examples/test_libmeshb_HO.f90 @@ -49,7 +49,7 @@ program test_libmeshb_HO_f90 ! Read the vertices using a vector of 3 consecutive doubles to store the coordinates - NmbVer = Gmfstatkwdf77(InpMsh, GmfVertices , 0, s, t, d, ho) + NmbVer = Gmfstatkwd(unit=InpMsh, GmfKey=GmfVertices) print '( "Input Mesh NmbVer: ",i0)', NmbVer allocate(VerTab(1:3,1:NmbVer)) allocate(VerRef( 1:NmbVer)) @@ -67,12 +67,12 @@ program test_libmeshb_HO_f90 GmfCell=GmfQuadrilateralsQ2 ! <= GmfOrd =GmfQuadrilateralsQ2Ordering ! <= - NmbQad=Gmfstatkwdf77(InpMsh, GmfCell, 0, s, t, d, ho) + NmbQad=Gmfstatkwd(unit=InpMsh,GmfKey=GmfCell) print '( "Input Mesh NmbQad: ",i0)', NmbQad allocate(QadTab(1:9,1:NmbQad)) allocate(QadRef( 1:NmbQad)) - if( .not. Gmfstatkwdf77(InpMsh,GmfOrd,0,s,t,d,ho)==0 )then + if( .not. Gmfstatkwd(unit=InpMsh,GmfKey=GmfOrd)==0 )then print '("Input Mesh Reordering HO Nodes")' block integer :: orderingSpace(1:2,1:9) @@ -199,7 +199,7 @@ program test_libmeshb_HO_f90 if( OutMsh==0 ) STOP ' OutMsh = 0' ! Set the number of vertices - res=Gmfsetkwdf77(OutMsh, GmfVertices, NmbVer, 0, t, 0, ho) + res=GmfSetKwd(OutMsh, GmfVertices, NmbVer) print '( "Output Mesh NmbVer: ",i0)', NmbVer ! Write them down using separate pointers for each scalar entry @@ -213,7 +213,7 @@ program test_libmeshb_HO_f90 ! Write the triangles using 4 independant set of arguments ! for each scalar entry: node1, node2, node3 and reference - res=Gmfsetkwdf77(OutMsh, GmfTrianglesP2, NmbTri, 0, t, 0, ho) + res=GmfSetKwd(OutMsh, GmfTrianglesP2, NmbTri) print '( "Output Mesh NmbTri: ",i0)', NmbTri res = GmfSetElements( & diff --git a/examples/test_libmeshb_block.f90 b/examples/test_libmeshb_block.f90 index 12677ab..c025a11 100644 --- a/examples/test_libmeshb_block.f90 +++ b/examples/test_libmeshb_block.f90 @@ -44,7 +44,7 @@ program test_libmeshb_block_f90 print '( "Input Mesh dim : ",i0)',dim ! Allocate VerRef - NmbVer = Gmfstatkwdf77(InpMsh, GmfVertices, 0, s, t, d, ho) + NmbVer = GmfStatKwd(InpMsh, GmfVertices) print '( "Input Mesh NmbVer : ",i0)', NmbVer allocate(VerTab(1:3,1:NmbVer)) allocate(VerRef( 1:NmbVer)) @@ -59,7 +59,7 @@ program test_libmeshb_block_f90 & VerRef( 1), VerRef( NmbVer) ) ! Allocate QadTab - NmbQad=Gmfstatkwdf77(InpMsh, GmfQuadrilaterals, 0, s, t, d, ho) + NmbQad=GmfStatKwd(InpMsh, GmfQuadrilaterals) print '( "Input Mesh NmbQad : ",i0)', NmbQad allocate(QadTab(1:4,1:NmbQad)) allocate(QadRef( 1:NmbQad)) @@ -130,7 +130,7 @@ program test_libmeshb_block_f90 if(OutMsh==0) STOP ' OutMsh = 0' ! Set the number of vertices - res=Gmfsetkwdf77(OutMsh, GmfVertices, NmbVer, 0, t, 0, ho) + res=GmfSetKwd(OutMsh, GmfVertices, NmbVer) print '( "Output Mesh NmbVer : ",i0)', NmbVer ! Write them down using separate pointers for each scalar entry @@ -144,7 +144,7 @@ program test_libmeshb_block_f90 ! Write the triangles using 4 independant set of arguments ! for each scalar entry: node1, node2, node3 and reference - res=Gmfsetkwdf77(OutMsh, GmfTriangles, NmbTri, 0, t, 0, ho) + res=GmfSetKwd(OutMsh, GmfTriangles, NmbTri) print '( "Output Mesh NmbTri : ",i0)', NmbTri res = GmfSetElements( & diff --git a/sources/libmeshb7_mod.f90 b/sources/libmeshb7_mod.f90 index edae72c..d87d252 100644 --- a/sources/libmeshb7_mod.f90 +++ b/sources/libmeshb7_mod.f90 @@ -11,401 +11,376 @@ ! !---------------------------------------------------------- - module libmeshb7 - - use iso_fortran_env - use, intrinsic :: iso_c_binding, only: c_int,c_long,c_loc,c_ptr - - implicit none - - !Procedures definition - external gmfopenmeshf77 - external gmfclosemeshf77 - external gmfstatkwdf77 - external gmfsetkwdf77 - external gmfgotokwdf77 - external gmfsethonodesorderingf77 - external gmfgetvertex - external gmfsetvertex - external gmfgetelement - external gmfsetelement - external gmfgetvertices - external gmfsetvertices - external gmfgetelements - external gmfsetelements - external gmfgetsolution - external gmfsetsolution - +module libmeshb7 - integer(int64) gmfopenmeshf77 - integer(int32) gmfclosemeshf77 - integer(int32) gmfstatkwdf77 - integer(int32) gmfsetkwdf77 - integer(int32) gmfgotokwdf77 - integer(int32) gmfsethonodesorderingf77 - integer(int32) gmfgetvertex - integer(int32) gmfsetvertex - integer(int32) gmfgetelement - integer(int32) gmfsetelement - integer(int32) gmfgetvertices - integer(int32) gmfsetvertices - integer(int32) gmfgetelements - integer(int32) gmfsetelements - integer(int32) gmfgetsolution - integer(int32) gmfsetsolution + use iso_fortran_env + use, intrinsic :: iso_c_binding, only: c_int,c_long,c_loc,c_ptr + implicit none - ! Parameters definition - - integer(int32), parameter :: gmfmaxtyp=1000 - integer(int32), parameter :: gmfmaxkwd=227 - integer(int32), parameter :: gmfread=1 - integer(int32), parameter :: gmfwrite=2 - integer(int32), parameter :: gmfsca=1 - integer(int32), parameter :: gmfvec=2 - integer(int32), parameter :: gmfsymmat=3 - integer(int32), parameter :: gmfmat=4 - integer(int32), parameter :: gmffloat=8 - integer(int32), parameter :: gmfdouble=9 - integer(int32), parameter :: gmfint=10 - integer(int32), parameter :: gmflong=11 - integer(int32), parameter :: gmfinttab=14 - integer(int32), parameter :: gmflongtab=15 - integer(int32), parameter :: gmffloatvec=12 - integer(int32), parameter :: gmfdoublevec=13 - integer(int32), parameter :: gmfintvec=14 - integer(int32), parameter :: gmflongvec=15 - integer(int32), parameter :: gmfargtab=100 - integer(int32), parameter :: gmfarglst=101 + !Procedures definition + external gmfopenmeshf77 + external gmfclosemeshf77 + external GmfStatKwdf77 + external gmfsetkwdf77 + external gmfgotokwdf77 + external gmfsethonodesorderingf77 + external gmfgetvertex + external gmfsetvertex + external gmfgetelement + external gmfsetelement + external gmfgetvertices + external gmfsetvertices + external gmfgetelements + external gmfsetelements + external gmfgetsolution + external gmfsetsolution + integer(int64) gmfopenmeshf77 + integer(int32) gmfclosemeshf77 + integer(int32) GmfStatKwdf77 + integer(int32) gmfsetkwdf77 + integer(int32) gmfgotokwdf77 + integer(int32) gmfsethonodesorderingf77 + integer(int32) gmfgetvertex + integer(int32) gmfsetvertex + integer(int32) gmfgetelement + integer(int32) gmfsetelement + integer(int32) gmfgetvertices + integer(int32) gmfsetvertices + integer(int32) gmfgetelements + integer(int32) gmfsetelements + integer(int32) gmfgetsolution + integer(int32) gmfsetsolution - ! Keywords list - - integer(int32), parameter :: gmfdimension=3 - integer(int32), parameter :: gmfmeshversionformatted=1 - integer(int32), parameter :: gmfvertices=4 - integer(int32), parameter :: gmfedges=5 - integer(int32), parameter :: gmftriangles=6 - integer(int32), parameter :: gmfquadrilaterals=7 - integer(int32), parameter :: gmftetrahedra=8 - integer(int32), parameter :: gmfprisms=9 - integer(int32), parameter :: gmfhexahedra=10 - integer(int32), parameter :: gmfiterationsall=11 - integer(int32), parameter :: gmftimesall=12 - integer(int32), parameter :: gmfcorners=13 - integer(int32), parameter :: gmfridges=14 - integer(int32), parameter :: gmfrequiredvertices=15 - integer(int32), parameter :: gmfrequirededges=16 - integer(int32), parameter :: gmfrequiredtriangles=17 - integer(int32), parameter :: gmfrequiredquadrilaterals=18 - integer(int32), parameter :: gmftangentatedgevertices=19 - integer(int32), parameter :: gmfnormalatvertices=20 - integer(int32), parameter :: gmfnormalattrianglevertices=21 - integer(int32), parameter :: gmfnormalatquadrilateralvertices=22 - integer(int32), parameter :: gmfangleofcornerbound=23 - integer(int32), parameter :: gmftrianglesp2=24 - integer(int32), parameter :: gmfedgesp2=25 - integer(int32), parameter :: gmfsolatpyramids=26 - integer(int32), parameter :: gmfquadrilateralsq2=27 - integer(int32), parameter :: gmfisolatpyramids=28 - integer(int32), parameter :: gmfsubdomainfromgeom=29 - integer(int32), parameter :: gmftetrahedrap2=30 - integer(int32), parameter :: gmffault_neartri=31 - integer(int32), parameter :: gmffault_inter=32 - integer(int32), parameter :: gmfhexahedraq2=33 - integer(int32), parameter :: gmfextraverticesatedges=34 - integer(int32), parameter :: gmfextraverticesattriangles=35 - integer(int32), parameter :: gmfextraverticesatquadrilaterals=36 - integer(int32), parameter :: gmfextraverticesattetrahedra=37 - integer(int32), parameter :: gmfextraverticesatprisms=38 - integer(int32), parameter :: gmfextraverticesathexahedra=39 - integer(int32), parameter :: gmfverticesongeometricvertices=40 - integer(int32), parameter :: gmfverticesongeometricedges=41 - integer(int32), parameter :: gmfverticesongeometrictriangles=42 - integer(int32), parameter :: gmfverticesongeometricquadrilaterals=43 - integer(int32), parameter :: gmfedgesongeometricedges=44 - integer(int32), parameter :: gmffault_freeedge=45 - integer(int32), parameter :: gmfpolyhedra=46 - integer(int32), parameter :: gmfpolygons=47 - integer(int32), parameter :: gmffault_overlap=48 - integer(int32), parameter :: gmfpyramids=49 - integer(int32), parameter :: gmfboundingbox=50 - integer(int32), parameter :: gmfbody=51 - integer(int32), parameter :: gmfprivatetable=52 - integer(int32), parameter :: gmffault_badshape=53 - integer(int32), parameter :: gmfend=54 - integer(int32), parameter :: gmftrianglesongeometrictriangles=55 - integer(int32), parameter :: gmftrianglesongeometricquadrilaterals=56 - integer(int32), parameter :: gmfquadrilateralsongeometrictriangles=57 - integer(int32), parameter :: gmfquadrilateralsongeometricquadrilaterals=58 - integer(int32), parameter :: gmftangents=59 - integer(int32), parameter :: gmfnormals=60 - integer(int32), parameter :: gmftangentatvertices=61 - integer(int32), parameter :: gmfsolatvertices=62 - integer(int32), parameter :: gmfsolatedges=63 - integer(int32), parameter :: gmfsolattriangles=64 - integer(int32), parameter :: gmfsolatquadrilaterals=65 - integer(int32), parameter :: gmfsolattetrahedra=66 - integer(int32), parameter :: gmfsolatprisms=67 - integer(int32), parameter :: gmfsolathexahedra=68 - integer(int32), parameter :: gmfdsolatvertices=69 - integer(int32), parameter :: gmfisolatvertices=70 - integer(int32), parameter :: gmfisolatedges=71 - integer(int32), parameter :: gmfisolattriangles=72 - integer(int32), parameter :: gmfisolatquadrilaterals=73 - integer(int32), parameter :: gmfisolattetrahedra=74 - integer(int32), parameter :: gmfisolatprisms=75 - integer(int32), parameter :: gmfisolathexahedra=76 - integer(int32), parameter :: gmfiterations=77 - integer(int32), parameter :: gmftime=78 - integer(int32), parameter :: gmffault_smalltri=79 - integer(int32), parameter :: gmfcoarsehexahedra=80 - integer(int32), parameter :: gmfcomments=81 - integer(int32), parameter :: gmfperiodicvertices=82 - integer(int32), parameter :: gmfperiodicedges=83 - integer(int32), parameter :: gmfperiodictriangles=84 - integer(int32), parameter :: gmfperiodicquadrilaterals=85 - integer(int32), parameter :: gmfprismsp2=86 - integer(int32), parameter :: gmfpyramidsp2=87 - integer(int32), parameter :: gmfquadrilateralsq3=88 - integer(int32), parameter :: gmfquadrilateralsq4=89 - integer(int32), parameter :: gmftrianglesp3=90 - integer(int32), parameter :: gmftrianglesp4=91 - integer(int32), parameter :: gmfedgesp3=92 - integer(int32), parameter :: gmfedgesp4=93 - integer(int32), parameter :: gmfirefgroups=94 - integer(int32), parameter :: gmfdrefgroups=95 - integer(int32), parameter :: gmftetrahedrap3=96 - integer(int32), parameter :: gmftetrahedrap4=97 - integer(int32), parameter :: gmfhexahedraq3=98 - integer(int32), parameter :: gmfhexahedraq4=99 - integer(int32), parameter :: gmfpyramidsp3=100 - integer(int32), parameter :: gmfpyramidsp4=101 - integer(int32), parameter :: gmfprismsp3=102 - integer(int32), parameter :: gmfprismsp4=103 - integer(int32), parameter :: gmfhosolatedgesp1=104 - integer(int32), parameter :: gmfhosolatedgesp2=105 - integer(int32), parameter :: gmfhosolatedgesp3=106 - integer(int32), parameter :: gmfhosolattrianglesp1=107 - integer(int32), parameter :: gmfhosolattrianglesp2=108 - integer(int32), parameter :: gmfhosolattrianglesp3=109 - integer(int32), parameter :: gmfhosolatquadrilateralsq1=110 - integer(int32), parameter :: gmfhosolatquadrilateralsq2=111 - integer(int32), parameter :: gmfhosolatquadrilateralsq3=112 - integer(int32), parameter :: gmfhosolattetrahedrap1=113 - integer(int32), parameter :: gmfhosolattetrahedrap2=114 - integer(int32), parameter :: gmfhosolattetrahedrap3=115 - integer(int32), parameter :: gmfhosolatpyramidsp1=116 - integer(int32), parameter :: gmfhosolatpyramidsp2=117 - integer(int32), parameter :: gmfhosolatpyramidsp3=118 - integer(int32), parameter :: gmfhosolatprismsp1=119 - integer(int32), parameter :: gmfhosolatprismsp2=120 - integer(int32), parameter :: gmfhosolatprismsp3=121 - integer(int32), parameter :: gmfhosolathexahedraq1=122 - integer(int32), parameter :: gmfhosolathexahedraq2=123 - integer(int32), parameter :: gmfhosolathexahedraq3=124 - integer(int32), parameter :: gmfbezierbasis=125 - integer(int32), parameter :: gmfbyteflow=126 - integer(int32), parameter :: gmfedgesp2ordering=127 - integer(int32), parameter :: gmfedgesp3ordering=128 - integer(int32), parameter :: gmftrianglesp2ordering=129 - integer(int32), parameter :: gmftrianglesp3ordering=130 - integer(int32), parameter :: gmfquadrilateralsq2ordering=131 - integer(int32), parameter :: gmfquadrilateralsq3ordering=132 - integer(int32), parameter :: gmftetrahedrap2ordering=133 - integer(int32), parameter :: gmftetrahedrap3ordering=134 - integer(int32), parameter :: gmfpyramidsp2ordering=135 - integer(int32), parameter :: gmfpyramidsp3ordering=136 - integer(int32), parameter :: gmfprismsp2ordering=137 - integer(int32), parameter :: gmfprismsp3ordering=138 - integer(int32), parameter :: gmfhexahedraq2ordering=139 - integer(int32), parameter :: gmfhexahedraq3ordering=140 - integer(int32), parameter :: gmfedgesp1ordering=141 - integer(int32), parameter :: gmfedgesp4ordering=142 - integer(int32), parameter :: gmftrianglesp1ordering=143 - integer(int32), parameter :: gmftrianglesp4ordering=144 - integer(int32), parameter :: gmfquadrilateralsq1ordering=145 - integer(int32), parameter :: gmfquadrilateralsq4ordering=146 - integer(int32), parameter :: gmftetrahedrap1ordering=147 - integer(int32), parameter :: gmftetrahedrap4ordering=148 - integer(int32), parameter :: gmfpyramidsp1ordering=149 - integer(int32), parameter :: gmfpyramidsp4ordering=150 - integer(int32), parameter :: gmfprismsp1ordering=151 - integer(int32), parameter :: gmfprismsp4ordering=152 - integer(int32), parameter :: gmfhexahedraq1ordering=153 - integer(int32), parameter :: gmfhexahedraq4ordering=154 - integer(int32), parameter :: gmffloatingpointprecision=155 - integer(int32), parameter :: gmfhosolatedgesp4=156 - integer(int32), parameter :: gmfhosolattrianglesp4=157 - integer(int32), parameter :: gmfhosolatquadrilateralsq4=158 - integer(int32), parameter :: gmfhosolattetrahedrap4=159 - integer(int32), parameter :: gmfhosolatpyramidsp4=160 - integer(int32), parameter :: gmfhosolatprismsp4=161 - integer(int32), parameter :: gmfhosolathexahedraq4=162 - integer(int32), parameter :: gmfhosolatedgesp1nodespositions=163 - integer(int32), parameter :: gmfhosolatedgesp2nodespositions=164 - integer(int32), parameter :: gmfhosolatedgesp3nodespositions=165 - integer(int32), parameter :: gmfhosolatedgesp4nodespositions=166 - integer(int32), parameter :: gmfhosolattrianglesp1nodespositions=167 - integer(int32), parameter :: gmfhosolattrianglesp2nodespositions=168 - integer(int32), parameter :: gmfhosolattrianglesp3nodespositions=169 - integer(int32), parameter :: gmfhosolattrianglesp4nodespositions=170 - integer(int32), parameter :: gmfhosolatquadrilateralsq1nodespositions=171 - integer(int32), parameter :: gmfhosolatquadrilateralsq2nodespositions=172 - integer(int32), parameter :: gmfhosolatquadrilateralsq3nodespositions=173 - integer(int32), parameter :: gmfhosolatquadrilateralsq4nodespositions=174 - integer(int32), parameter :: gmfhosolattetrahedrap1nodespositions=175 - integer(int32), parameter :: gmfhosolattetrahedrap2nodespositions=176 - integer(int32), parameter :: gmfhosolattetrahedrap3nodespositions=177 - integer(int32), parameter :: gmfhosolattetrahedrap4nodespositions=178 - integer(int32), parameter :: gmfhosolatpyramidsp1nodespositions=179 - integer(int32), parameter :: gmfhosolatpyramidsp2nodespositions=180 - integer(int32), parameter :: gmfhosolatpyramidsp3nodespositions=181 - integer(int32), parameter :: gmfhosolatpyramidsp4nodespositions=182 - integer(int32), parameter :: gmfhosolatprismsp1nodespositions=183 - integer(int32), parameter :: gmfhosolatprismsp2nodespositions=184 - integer(int32), parameter :: gmfhosolatprismsp3nodespositions=185 - integer(int32), parameter :: gmfhosolatprismsp4nodespositions=186 - integer(int32), parameter :: gmfhosolathexahedraq1nodespositions=187 - integer(int32), parameter :: gmfhosolathexahedraq2nodespositions=188 - integer(int32), parameter :: gmfhosolathexahedraq3nodespositions=189 - integer(int32), parameter :: gmfhosolathexahedraq4nodespositions=190 - integer(int32), parameter :: gmfedgesreferenceelement=191 - integer(int32), parameter :: gmftrianglereferenceelement=192 - integer(int32), parameter :: gmfquadrilateralreferenceelement=193 - integer(int32), parameter :: gmftetrahedronreferenceelement=194 - integer(int32), parameter :: gmfpyramidreferenceelement=195 - integer(int32), parameter :: gmfprismreferenceelement=196 - integer(int32), parameter :: gmfhexahedronreferenceelement=197 - integer(int32), parameter :: gmfboundarylayers=198 - integer(int32), parameter :: gmfreferencestrings=199 - integer(int32), parameter :: gmfprisms9=200 - integer(int32), parameter :: gmfhexahedra12=201 - integer(int32), parameter :: gmfquadrilaterals6=202 - integer(int32), parameter :: gmfboundarypolygonheaders=203 - integer(int32), parameter :: gmfboundarypolygonvertices=204 - integer(int32), parameter :: gmfinnerpolygonheaders=205 - integer(int32), parameter :: gmfinnerpolygonvertices=206 - integer(int32), parameter :: gmfpolyhedraheaders=207 - integer(int32), parameter :: gmfpolyhedrafaces=208 - integer(int32), parameter :: gmfdomains=209 - integer(int32), parameter :: gmfverticesgid=210 - integer(int32), parameter :: gmfedgesgid=211 - integer(int32), parameter :: gmftrianglesgid=212 - integer(int32), parameter :: gmfquadrilateralsgid=213 - integer(int32), parameter :: gmftetrahedragid=214 - integer(int32), parameter :: gmfpyramidsgid=215 - integer(int32), parameter :: gmfprismsgid=216 - integer(int32), parameter :: gmfhexahedragid=217 - integer(int32), parameter :: gmfsolatboundarypolygons=218 - integer(int32), parameter :: gmfsolatpolyhedra=219 - integer(int32), parameter :: gmfverticesongeometrynodes=220 - integer(int32), parameter :: gmfverticesongeometryedges=221 - integer(int32), parameter :: gmfedgesongeometryedges=222 - integer(int32), parameter :: gmfverticesongeometryfaces=223 - integer(int32), parameter :: gmfedgesongeometryfaces=224 - integer(int32), parameter :: gmftrianglesongeometryfaces=225 - integer(int32), parameter :: gmfquadrialteralsongeometryfaces=226 - integer(int32), parameter :: gmfmeshongeometry=227 + ! Parameters definition + integer(int32), parameter :: gmfmaxtyp=1000 + integer(int32), parameter :: gmfmaxkwd=227 + integer(int32), parameter :: gmfread=1 + integer(int32), parameter :: gmfwrite=2 + integer(int32), parameter :: gmfsca=1 + integer(int32), parameter :: gmfvec=2 + integer(int32), parameter :: gmfsymmat=3 + integer(int32), parameter :: gmfmat=4 + integer(int32), parameter :: gmffloat=8 + integer(int32), parameter :: gmfdouble=9 + integer(int32), parameter :: gmfint=10 + integer(int32), parameter :: gmflong=11 + integer(int32), parameter :: gmfinttab=14 + integer(int32), parameter :: gmflongtab=15 + integer(int32), parameter :: gmffloatvec=12 + integer(int32), parameter :: gmfdoublevec=13 + integer(int32), parameter :: gmfintvec=14 + integer(int32), parameter :: gmflongvec=15 + integer(int32), parameter :: gmfargtab=100 + integer(int32), parameter :: gmfarglst=101 - ! !> interface GmfSetHONodesOrdering_c - ! interface - ! function GmfSetHONodesOrdering_c(InpMsh, GmfKey, BasOrd, FilOrd) result(iErr) bind(c, name="GmfSetHONodesOrdering") - ! !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - ! import c_long,c_int,c_ptr - ! !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - ! !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - ! integer(c_long) , intent(in) :: InpMsh - ! integer(c_int) , intent(in) :: GmfKey - ! !integer(c_int) , intent(in) :: BasOrd(:,:) - ! !integer(c_int) , intent(in) :: FilOrd(:,:) - ! type(c_ptr) , intent(in) :: BasOrd - ! type(c_ptr) , intent(in) :: FilOrd - ! integer(c_int) :: iErr - ! !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - ! end function GmfSetHONodesOrdering_c - ! - ! function GmfCloseMesh_c(InpMsh) result(iErr) bind(c, name="GmfCloseMesh") - ! !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - ! import c_long,c_int,c_ptr - ! !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - ! !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - ! integer(c_long) , intent(in) :: InpMsh - ! integer(c_int) :: iErr - ! !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - ! end function GmfCloseMesh_c - ! - ! end interface - ! - ! - ! public :: GmfSetHONodesOrdering_f90 - ! public :: GmfOpenMesh_f90 - ! public :: GmfCloseMesh_f90 - - - !> les lignes suivantes sont en conflit avec la variable integer(4) :: gmfsethonodesordering - !interface GmfSetHONodesOrdering - ! module procedure GmfSetHONodesOrdering_f90 - ! module procedure GmfSetHONodesOrdering_c - !end interface - - contains + ! Keywords list + integer(int32), parameter :: gmfdimension=3 + integer(int32), parameter :: gmfmeshversionformatted=1 + integer(int32), parameter :: gmfvertices=4 + integer(int32), parameter :: gmfedges=5 + integer(int32), parameter :: gmftriangles=6 + integer(int32), parameter :: gmfquadrilaterals=7 + integer(int32), parameter :: gmftetrahedra=8 + integer(int32), parameter :: gmfprisms=9 + integer(int32), parameter :: gmfhexahedra=10 + integer(int32), parameter :: gmfiterationsall=11 + integer(int32), parameter :: gmftimesall=12 + integer(int32), parameter :: gmfcorners=13 + integer(int32), parameter :: gmfridges=14 + integer(int32), parameter :: gmfrequiredvertices=15 + integer(int32), parameter :: gmfrequirededges=16 + integer(int32), parameter :: gmfrequiredtriangles=17 + integer(int32), parameter :: gmfrequiredquadrilaterals=18 + integer(int32), parameter :: gmftangentatedgevertices=19 + integer(int32), parameter :: gmfnormalatvertices=20 + integer(int32), parameter :: gmfnormalattrianglevertices=21 + integer(int32), parameter :: gmfnormalatquadrilateralvertices=22 + integer(int32), parameter :: gmfangleofcornerbound=23 + integer(int32), parameter :: gmftrianglesp2=24 + integer(int32), parameter :: gmfedgesp2=25 + integer(int32), parameter :: gmfsolatpyramids=26 + integer(int32), parameter :: gmfquadrilateralsq2=27 + integer(int32), parameter :: gmfisolatpyramids=28 + integer(int32), parameter :: gmfsubdomainfromgeom=29 + integer(int32), parameter :: gmftetrahedrap2=30 + integer(int32), parameter :: gmffault_neartri=31 + integer(int32), parameter :: gmffault_inter=32 + integer(int32), parameter :: gmfhexahedraq2=33 + integer(int32), parameter :: gmfextraverticesatedges=34 + integer(int32), parameter :: gmfextraverticesattriangles=35 + integer(int32), parameter :: gmfextraverticesatquadrilaterals=36 + integer(int32), parameter :: gmfextraverticesattetrahedra=37 + integer(int32), parameter :: gmfextraverticesatprisms=38 + integer(int32), parameter :: gmfextraverticesathexahedra=39 + integer(int32), parameter :: gmfverticesongeometricvertices=40 + integer(int32), parameter :: gmfverticesongeometricedges=41 + integer(int32), parameter :: gmfverticesongeometrictriangles=42 + integer(int32), parameter :: gmfverticesongeometricquadrilaterals=43 + integer(int32), parameter :: gmfedgesongeometricedges=44 + integer(int32), parameter :: gmffault_freeedge=45 + integer(int32), parameter :: gmfpolyhedra=46 + integer(int32), parameter :: gmfpolygons=47 + integer(int32), parameter :: gmffault_overlap=48 + integer(int32), parameter :: gmfpyramids=49 + integer(int32), parameter :: gmfboundingbox=50 + integer(int32), parameter :: gmfbody=51 + integer(int32), parameter :: gmfprivatetable=52 + integer(int32), parameter :: gmffault_badshape=53 + integer(int32), parameter :: gmfend=54 + integer(int32), parameter :: gmftrianglesongeometrictriangles=55 + integer(int32), parameter :: gmftrianglesongeometricquadrilaterals=56 + integer(int32), parameter :: gmfquadrilateralsongeometrictriangles=57 + integer(int32), parameter :: gmfquadrilateralsongeometricquadrilaterals=58 + integer(int32), parameter :: gmftangents=59 + integer(int32), parameter :: gmfnormals=60 + integer(int32), parameter :: gmftangentatvertices=61 + integer(int32), parameter :: gmfsolatvertices=62 + integer(int32), parameter :: gmfsolatedges=63 + integer(int32), parameter :: gmfsolattriangles=64 + integer(int32), parameter :: gmfsolatquadrilaterals=65 + integer(int32), parameter :: gmfsolattetrahedra=66 + integer(int32), parameter :: gmfsolatprisms=67 + integer(int32), parameter :: gmfsolathexahedra=68 + integer(int32), parameter :: gmfdsolatvertices=69 + integer(int32), parameter :: gmfisolatvertices=70 + integer(int32), parameter :: gmfisolatedges=71 + integer(int32), parameter :: gmfisolattriangles=72 + integer(int32), parameter :: gmfisolatquadrilaterals=73 + integer(int32), parameter :: gmfisolattetrahedra=74 + integer(int32), parameter :: gmfisolatprisms=75 + integer(int32), parameter :: gmfisolathexahedra=76 + integer(int32), parameter :: gmfiterations=77 + integer(int32), parameter :: gmftime=78 + integer(int32), parameter :: gmffault_smalltri=79 + integer(int32), parameter :: gmfcoarsehexahedra=80 + integer(int32), parameter :: gmfcomments=81 + integer(int32), parameter :: gmfperiodicvertices=82 + integer(int32), parameter :: gmfperiodicedges=83 + integer(int32), parameter :: gmfperiodictriangles=84 + integer(int32), parameter :: gmfperiodicquadrilaterals=85 + integer(int32), parameter :: gmfprismsp2=86 + integer(int32), parameter :: gmfpyramidsp2=87 + integer(int32), parameter :: gmfquadrilateralsq3=88 + integer(int32), parameter :: gmfquadrilateralsq4=89 + integer(int32), parameter :: gmftrianglesp3=90 + integer(int32), parameter :: gmftrianglesp4=91 + integer(int32), parameter :: gmfedgesp3=92 + integer(int32), parameter :: gmfedgesp4=93 + integer(int32), parameter :: gmfirefgroups=94 + integer(int32), parameter :: gmfdrefgroups=95 + integer(int32), parameter :: gmftetrahedrap3=96 + integer(int32), parameter :: gmftetrahedrap4=97 + integer(int32), parameter :: gmfhexahedraq3=98 + integer(int32), parameter :: gmfhexahedraq4=99 + integer(int32), parameter :: gmfpyramidsp3=100 + integer(int32), parameter :: gmfpyramidsp4=101 + integer(int32), parameter :: gmfprismsp3=102 + integer(int32), parameter :: gmfprismsp4=103 + integer(int32), parameter :: gmfhosolatedgesp1=104 + integer(int32), parameter :: gmfhosolatedgesp2=105 + integer(int32), parameter :: gmfhosolatedgesp3=106 + integer(int32), parameter :: gmfhosolattrianglesp1=107 + integer(int32), parameter :: gmfhosolattrianglesp2=108 + integer(int32), parameter :: gmfhosolattrianglesp3=109 + integer(int32), parameter :: gmfhosolatquadrilateralsq1=110 + integer(int32), parameter :: gmfhosolatquadrilateralsq2=111 + integer(int32), parameter :: gmfhosolatquadrilateralsq3=112 + integer(int32), parameter :: gmfhosolattetrahedrap1=113 + integer(int32), parameter :: gmfhosolattetrahedrap2=114 + integer(int32), parameter :: gmfhosolattetrahedrap3=115 + integer(int32), parameter :: gmfhosolatpyramidsp1=116 + integer(int32), parameter :: gmfhosolatpyramidsp2=117 + integer(int32), parameter :: gmfhosolatpyramidsp3=118 + integer(int32), parameter :: gmfhosolatprismsp1=119 + integer(int32), parameter :: gmfhosolatprismsp2=120 + integer(int32), parameter :: gmfhosolatprismsp3=121 + integer(int32), parameter :: gmfhosolathexahedraq1=122 + integer(int32), parameter :: gmfhosolathexahedraq2=123 + integer(int32), parameter :: gmfhosolathexahedraq3=124 + integer(int32), parameter :: gmfbezierbasis=125 + integer(int32), parameter :: gmfbyteflow=126 + integer(int32), parameter :: gmfedgesp2ordering=127 + integer(int32), parameter :: gmfedgesp3ordering=128 + integer(int32), parameter :: gmftrianglesp2ordering=129 + integer(int32), parameter :: gmftrianglesp3ordering=130 + integer(int32), parameter :: gmfquadrilateralsq2ordering=131 + integer(int32), parameter :: gmfquadrilateralsq3ordering=132 + integer(int32), parameter :: gmftetrahedrap2ordering=133 + integer(int32), parameter :: gmftetrahedrap3ordering=134 + integer(int32), parameter :: gmfpyramidsp2ordering=135 + integer(int32), parameter :: gmfpyramidsp3ordering=136 + integer(int32), parameter :: gmfprismsp2ordering=137 + integer(int32), parameter :: gmfprismsp3ordering=138 + integer(int32), parameter :: gmfhexahedraq2ordering=139 + integer(int32), parameter :: gmfhexahedraq3ordering=140 + integer(int32), parameter :: gmfedgesp1ordering=141 + integer(int32), parameter :: gmfedgesp4ordering=142 + integer(int32), parameter :: gmftrianglesp1ordering=143 + integer(int32), parameter :: gmftrianglesp4ordering=144 + integer(int32), parameter :: gmfquadrilateralsq1ordering=145 + integer(int32), parameter :: gmfquadrilateralsq4ordering=146 + integer(int32), parameter :: gmftetrahedrap1ordering=147 + integer(int32), parameter :: gmftetrahedrap4ordering=148 + integer(int32), parameter :: gmfpyramidsp1ordering=149 + integer(int32), parameter :: gmfpyramidsp4ordering=150 + integer(int32), parameter :: gmfprismsp1ordering=151 + integer(int32), parameter :: gmfprismsp4ordering=152 + integer(int32), parameter :: gmfhexahedraq1ordering=153 + integer(int32), parameter :: gmfhexahedraq4ordering=154 + integer(int32), parameter :: gmffloatingpointprecision=155 + integer(int32), parameter :: gmfhosolatedgesp4=156 + integer(int32), parameter :: gmfhosolattrianglesp4=157 + integer(int32), parameter :: gmfhosolatquadrilateralsq4=158 + integer(int32), parameter :: gmfhosolattetrahedrap4=159 + integer(int32), parameter :: gmfhosolatpyramidsp4=160 + integer(int32), parameter :: gmfhosolatprismsp4=161 + integer(int32), parameter :: gmfhosolathexahedraq4=162 + integer(int32), parameter :: gmfhosolatedgesp1nodespositions=163 + integer(int32), parameter :: gmfhosolatedgesp2nodespositions=164 + integer(int32), parameter :: gmfhosolatedgesp3nodespositions=165 + integer(int32), parameter :: gmfhosolatedgesp4nodespositions=166 + integer(int32), parameter :: gmfhosolattrianglesp1nodespositions=167 + integer(int32), parameter :: gmfhosolattrianglesp2nodespositions=168 + integer(int32), parameter :: gmfhosolattrianglesp3nodespositions=169 + integer(int32), parameter :: gmfhosolattrianglesp4nodespositions=170 + integer(int32), parameter :: gmfhosolatquadrilateralsq1nodespositions=171 + integer(int32), parameter :: gmfhosolatquadrilateralsq2nodespositions=172 + integer(int32), parameter :: gmfhosolatquadrilateralsq3nodespositions=173 + integer(int32), parameter :: gmfhosolatquadrilateralsq4nodespositions=174 + integer(int32), parameter :: gmfhosolattetrahedrap1nodespositions=175 + integer(int32), parameter :: gmfhosolattetrahedrap2nodespositions=176 + integer(int32), parameter :: gmfhosolattetrahedrap3nodespositions=177 + integer(int32), parameter :: gmfhosolattetrahedrap4nodespositions=178 + integer(int32), parameter :: gmfhosolatpyramidsp1nodespositions=179 + integer(int32), parameter :: gmfhosolatpyramidsp2nodespositions=180 + integer(int32), parameter :: gmfhosolatpyramidsp3nodespositions=181 + integer(int32), parameter :: gmfhosolatpyramidsp4nodespositions=182 + integer(int32), parameter :: gmfhosolatprismsp1nodespositions=183 + integer(int32), parameter :: gmfhosolatprismsp2nodespositions=184 + integer(int32), parameter :: gmfhosolatprismsp3nodespositions=185 + integer(int32), parameter :: gmfhosolatprismsp4nodespositions=186 + integer(int32), parameter :: gmfhosolathexahedraq1nodespositions=187 + integer(int32), parameter :: gmfhosolathexahedraq2nodespositions=188 + integer(int32), parameter :: gmfhosolathexahedraq3nodespositions=189 + integer(int32), parameter :: gmfhosolathexahedraq4nodespositions=190 + integer(int32), parameter :: gmfedgesreferenceelement=191 + integer(int32), parameter :: gmftrianglereferenceelement=192 + integer(int32), parameter :: gmfquadrilateralreferenceelement=193 + integer(int32), parameter :: gmftetrahedronreferenceelement=194 + integer(int32), parameter :: gmfpyramidreferenceelement=195 + integer(int32), parameter :: gmfprismreferenceelement=196 + integer(int32), parameter :: gmfhexahedronreferenceelement=197 + integer(int32), parameter :: gmfboundarylayers=198 + integer(int32), parameter :: gmfreferencestrings=199 + integer(int32), parameter :: gmfprisms9=200 + integer(int32), parameter :: gmfhexahedra12=201 + integer(int32), parameter :: gmfquadrilaterals6=202 + integer(int32), parameter :: gmfboundarypolygonheaders=203 + integer(int32), parameter :: gmfboundarypolygonvertices=204 + integer(int32), parameter :: gmfinnerpolygonheaders=205 + integer(int32), parameter :: gmfinnerpolygonvertices=206 + integer(int32), parameter :: gmfpolyhedraheaders=207 + integer(int32), parameter :: gmfpolyhedrafaces=208 + integer(int32), parameter :: gmfdomains=209 + integer(int32), parameter :: gmfverticesgid=210 + integer(int32), parameter :: gmfedgesgid=211 + integer(int32), parameter :: gmftrianglesgid=212 + integer(int32), parameter :: gmfquadrilateralsgid=213 + integer(int32), parameter :: gmftetrahedragid=214 + integer(int32), parameter :: gmfpyramidsgid=215 + integer(int32), parameter :: gmfprismsgid=216 + integer(int32), parameter :: gmfhexahedragid=217 + integer(int32), parameter :: gmfsolatboundarypolygons=218 + integer(int32), parameter :: gmfsolatpolyhedra=219 + integer(int32), parameter :: gmfverticesongeometrynodes=220 + integer(int32), parameter :: gmfverticesongeometryedges=221 + integer(int32), parameter :: gmfedgesongeometryedges=222 + integer(int32), parameter :: gmfverticesongeometryfaces=223 + integer(int32), parameter :: gmfedgesongeometryfaces=224 + integer(int32), parameter :: gmftrianglesongeometryfaces=225 + integer(int32), parameter :: gmfquadrialteralsongeometryfaces=226 + integer(int32), parameter :: gmfmeshongeometry=227 + + interface GmfStatKwd + module procedure GmfStatKwdf77_0 + module procedure GmfStatKwdf77_1 + end interface GmfStatKwd + + interface GmfSetKwd + module procedure GmfSetKwdF77_0 + module procedure GmfSetKwdF77_1 + end interface - ! subroutine GmfSetHONodesOrdering_f90(unit, GmfKey, BasOrd, FilOrd) - ! !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - ! use, intrinsic :: iso_c_binding, only: c_loc,c_int,c_long,c_ptr - ! !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - ! !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - ! integer(8), intent(in) :: unit - ! integer(4), intent(in) :: GmfKey - ! integer(4), intent(in), pointer :: BasOrd(:,:) - ! integer(4), intent(in), pointer :: FilOrd(:,:) - ! !> - ! integer(c_int) :: iErr - ! !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - ! !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - ! !> Broker - ! iErr=GmfSetHONodesOrdering_c( & - ! & InpMsh=int(unit,kind=c_long) ,& - ! & GmfKey=int(GmfKey,kind=c_int) ,& - ! & BasOrd=c_loc(BasOrd) ,& - ! & FilOrd=c_loc(FilOrd) ) - ! !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - ! - ! return - ! end subroutine GmfSetHONodesOrdering_f90 - ! - ! subroutine GmfOpenMesh_f90(unit, GmfKey, BasOrd, FilOrd) - ! !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - ! use, intrinsic :: iso_c_binding, only: c_loc,c_int,c_long - ! !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - ! !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - ! integej1r(8), intent(in) :: unit - ! !> - ! integer(c_int) :: iErr - ! !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - ! !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - ! !> Broker - ! iErr=GmfOpenMesh_c(InpMsh=int(unit,kind=c_long) ) - ! !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - ! return - ! end subroutine GmfOpenMesh_f90 - ! - ! subroutine GmfCloseMesh_f90(unit, GmfKey, BasOrd, FilOrd) - ! !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - ! use, intrinsic :: iso_c_binding, only: c_loc,c_int,c_long - ! !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - ! !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - ! integer(8), intent(in) :: unit - ! !> - ! integer(c_int) :: iErr - ! !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - ! !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - ! !> Broker - ! iErr=GmfCloseMesh_c(InpMsh=int(unit,kind=c_long) ) - ! !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - ! return - ! end subroutine GmfCloseMesh_f90 - - - end module libmeshb7 \ No newline at end of file +contains + + function GmfStatKwdf77_0(unit, GmfKey) result(res) + !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + use iso_fortran_env + !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + integer(int64) :: unit + integer(int32) :: GmfKey + integer(int32) :: Nmb + !> + integer(int32) :: t(1),d,ho,s + integer(int32) :: res + !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + res = GmfStatKwdf77(unit, GmfKey, 0, 0, t(1), 0, 0) + !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + return + end function GmfStatKwdf77_0 + + function GmfStatKwdf77_1(unit, GmfKey, r, s, t, d, ho) result(res) + !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + use iso_fortran_env + !> + integer(int64) :: unit + integer(int32) :: GmfKey + integer(int32) :: Nmb + !> + integer(int32) :: r,s,t(*),d,ho + integer(int32) :: res + !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + res = GmfStatKwdf77(unit, GmfKey, r, s, t, d, ho) + !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + return + end function GmfStatKwdf77_1 + + function GmfSetKwdF77_0(unit, GmfKey, Nmb) result(res) + !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + use iso_fortran_env + !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + integer(int64) :: unit + integer(int32) :: GmfKey + integer(int32) :: Nmb + !> + integer(int32) :: t(1),d,ho,s + integer(int32) :: res + !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + res = GmfSetKwdF77(unit, GmfKey, Nmb, 0, t(1), 0, ho) + !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + return + end function GmfSetKwdF77_0 + + function GmfSetKwdF77_1(unit, GmfKey, Nmb, d, t, s, ho) result(res) + !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + use iso_fortran_env + !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + integer(int64) :: unit + integer(int32) :: GmfKey + integer(int32) :: Nmb + integer(int32) :: t(*) + integer(int32) :: d,ho,s + integer(int32) :: res + !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + res = GmfSetKwdF77(unit, GmfKey, Nmb, d, t, s, ho) + !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + return + end function GmfSetKwdF77_1 + +end module libmeshb7 \ No newline at end of file From 08127e39db6999f5d6c05b3fe01a726dba2aea54 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Mar=C3=A9chal?= Date: Wed, 21 Feb 2024 16:49:45 +0100 Subject: [PATCH 26/38] Added block access to solution fields and four procedures to access to integer only keywords. Nothing has been tested. --- sources/libmeshb7.c | 138 +++++++++++++++++++++++++++++++++++++++++- sources/libmeshb7.ins | 14 ++++- 2 files changed, 148 insertions(+), 4 deletions(-) diff --git a/sources/libmeshb7.c b/sources/libmeshb7.c index f7e73e3..3208163 100644 --- a/sources/libmeshb7.c +++ b/sources/libmeshb7.c @@ -9,7 +9,7 @@ /* Description: handles .meshb file format I/O */ /* Author: Loic MARECHAL */ /* Creation date: dec 09 1999 */ -/* Last modification: feb 13 2024 */ +/* Last modification: feb 21 2024 */ /* */ /*----------------------------------------------------------------------------*/ @@ -206,7 +206,7 @@ int my_aio_write(struct aiocb *aiocbp) typedef struct { int typ, deg, NmbNod, SolSiz, NmbWrd, NmbTyp, TypTab[ GmfMaxTyp ]; - int *OrdTab; + int *OrdTab, NmbInt, NmbDbl; int64_t NmbLin; size_t pos; char fmt[ GmfMaxTyp*9 ]; @@ -498,7 +498,7 @@ static char NmbEleNod[ GmfMaxKwd + 1 ] = 6, 3, 0, - 0, + 9, 0, 0, 10, @@ -2953,6 +2953,13 @@ static void ExpFmt(GmfMshSct *msh, int KwdCod) kwd->SolSiz *= kwd->NmbNod; kwd->NmbWrd *= kwd->NmbNod; } + + // Count the final number of intergers and reals needed by the Fortran API + for(i=0;iSolSiz;i++) + if(kwd->fmt[i] == 'i') + kwd->NmbInt++; + else if(kwd->fmt[i] == 'r') + kwd->NmbDbl++; } @@ -3431,3 +3438,128 @@ int APIF77(gmfsetsolution)(int64_t *MshIdx, int *kwd, double *sol) { return(GmfSetLin(*MshIdx, *kwd, sol)); } + +int APIF77(gmfgetsolutionss)(int64_t *MshIdx, int *KwdCod, int *BegIdx, int *EndIdx, + int *MapTyp, int64_t *map, + double *BegSol, double *EndSol) +{ + GmfMshSct *msh = (GmfMshSct *)*MshIdx; + KwdSct *kwd = &msh->KwdTab[ *KwdCod ]; + + return(GmfGetBlock( *MshIdx, *KwdCod, *BegIdx, *EndIdx, + *MapTyp, map, NULL, + GmfDoubleVec, kwd->SolSiz, BegSol, EndSol )); +} + +int APIF77(gmfsetsolutionss)(int64_t *MshIdx, int *KwdCod, int *BegIdx, int *EndIdx, + int *MapTyp, int64_t *map, + double *BegSol, double *EndSol) +{ + GmfMshSct *msh = (GmfMshSct *)*MshIdx; + KwdSct *kwd = &msh->KwdTab[ *KwdCod ]; + + return(GmfSetBlock( *MshIdx, *KwdCod, *BegIdx, *EndIdx, + *MapTyp, map, NULL, + GmfDoubleVec, kwd->SolSiz, BegSol, EndSol )); +} + + +// INTERGER BASED KEYWORDS + +int APIF77(gmfgetlinei4)(int64_t *MshIdx, int *KwdCod, int *i) +{ + GmfMshSct *msh = (GmfMshSct *)*MshIdx; + KwdSct *kwd = &msh->KwdTab[ *KwdCod ]; + + if(kwd->SolSiz != kwd->NmbInt) + return(0); + + switch(kwd->NmbInt) + { + case 1 : + return(GmfGetLin(*MshIdx, *KwdCod, &i[0])); + case 2 : + return(GmfGetLin(*MshIdx, *KwdCod, &i[0], &i[1])); + case 3 : + return(GmfGetLin(*MshIdx, *KwdCod, &i[0], &i[1], &i[2])); + case 4 : + return(GmfGetLin(*MshIdx, *KwdCod, &i[0], &i[1], &i[2], &i[3])); + case 5 : + return(GmfGetLin(*MshIdx, *KwdCod, &i[0], &i[1], &i[2], &i[3], &i[4])); + case 6 : + return(GmfGetLin(*MshIdx, *KwdCod, &i[0], &i[1], &i[2], &i[3], &i[4], &i[5])); + case 7 : + return(GmfGetLin(*MshIdx, *KwdCod, &i[0], &i[1], &i[2], &i[3], &i[4], &i[5], &i[6])); + case 8 : + return(GmfGetLin(*MshIdx, *KwdCod, &i[0], &i[1], &i[2], &i[3], &i[4], &i[5], &i[6], &i[7])); + case 9 : + return(GmfGetLin(*MshIdx, *KwdCod, &i[0], &i[1], &i[2], &i[3], &i[4], &i[5], &i[6], &i[7], &i[8])); + case 10 : + return(GmfGetLin(*MshIdx, *KwdCod, &i[0], &i[1], &i[2], &i[3], &i[4], &i[5], &i[6], &i[7], &i[8], &i[9])); + default : + return(0); + } +} + +int APIF77(gmfsetlinei4)(int64_t *MshIdx, int *KwdCod, int *i) +{ + GmfMshSct *msh = (GmfMshSct *)*MshIdx; + KwdSct *kwd = &msh->KwdTab[ *KwdCod ]; + + if(kwd->SolSiz != kwd->NmbInt) + return(0); + + switch(kwd->NmbInt) + { + case 1 : + return(GmfSetLin(*MshIdx, *KwdCod, i[0])); + case 2 : + return(GmfSetLin(*MshIdx, *KwdCod, i[0], i[1])); + case 3 : + return(GmfSetLin(*MshIdx, *KwdCod, i[0], i[1], i[2])); + case 4 : + return(GmfSetLin(*MshIdx, *KwdCod, i[0], i[1], i[2], i[3])); + case 5 : + return(GmfSetLin(*MshIdx, *KwdCod, i[0], i[1], i[2], i[3], i[4])); + case 6 : + return(GmfSetLin(*MshIdx, *KwdCod, i[0], i[1], i[2], i[3], i[4], i[5])); + case 7 : + return(GmfSetLin(*MshIdx, *KwdCod, i[0], i[1], i[2], i[3], i[4], i[5], i[6])); + case 8 : + return(GmfSetLin(*MshIdx, *KwdCod, i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7])); + case 9 : + return(GmfSetLin(*MshIdx, *KwdCod, i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7], i[8])); + case 10 : + return(GmfSetLin(*MshIdx, *KwdCod, i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7], i[8], i[9])); + default : + return(0); + } +} + +int APIF77(gmfgetblocki4)( int64_t *MshIdx, int *KwdCod, + int *BegIdx, int *EndIdx, + int *BegDat, int *EndDat ) +{ + GmfMshSct *msh = (GmfMshSct *)*MshIdx; + KwdSct *kwd = &msh->KwdTab[ *KwdCod ]; + + if(kwd->SolSiz != kwd->NmbInt) + return(0); + + return(GmfGetBlock( *MshIdx, *KwdCod, *BegIdx, *EndIdx, 0, NULL, NULL, + GmfIntVec, kwd->NmbInt, BegDat, EndDat )); +} + +int APIF77(gmfsetblocki4)( int64_t *MshIdx, int *KwdCod, + int *BegIdx, int *EndIdx, + int *BegDat, int *EndDat ) +{ + GmfMshSct *msh = (GmfMshSct *)*MshIdx; + KwdSct *kwd = &msh->KwdTab[ *KwdCod ]; + + if(kwd->SolSiz != kwd->NmbInt) + return(0); + + return(GmfSetBlock( *MshIdx, *KwdCod, *BegIdx, *EndIdx, 0, NULL, NULL, + GmfIntVec, kwd->NmbInt, BegDat, EndDat )); +} diff --git a/sources/libmeshb7.ins b/sources/libmeshb7.ins index 7947997..defda79 100644 --- a/sources/libmeshb7.ins +++ b/sources/libmeshb7.ins @@ -9,7 +9,7 @@ c c Description: handles .meshb file format I/O c Author: Loic MARECHAL c Creation date: dec 08 2015 -c Last modification: feb 15 2024 +c Last modification: feb 21 2024 c c---------------------------------------------------------- @@ -31,6 +31,12 @@ c Procedures definition external gmfsetelements external gmfgetsolution external gmfsetsolution + external gmfgetsolutions + external gmfsetsolutions + external gmfgetlinei4 + external gmfsetlinei4 + external gmfgetblocki4 + external gmfsetblocki4 integer*8 gmfopenmeshf77 integer gmfclosemeshf77 @@ -48,6 +54,12 @@ c Procedures definition integer gmfsetelements integer gmfgetsolution integer gmfsetsolution + integer gmfgetsolutions + integer gmfsetsolutions + integer gmfgetlinei4 + integer gmfsetlinei4 + integer gmfgetblocki4 + integer gmfsetblocki4 c Parameters definition From 51471c39dac29cc566e529685ae24e25806c9005 Mon Sep 17 00:00:00 2001 From: Christophe Peyret Date: Wed, 21 Feb 2024 16:53:58 +0100 Subject: [PATCH 27/38] on retire les use iso_fortran_env inutiles --- sources/libmeshb7_mod.f90 | 8 -------- 1 file changed, 8 deletions(-) diff --git a/sources/libmeshb7_mod.f90 b/sources/libmeshb7_mod.f90 index d87d252..b6c3cfa 100644 --- a/sources/libmeshb7_mod.f90 +++ b/sources/libmeshb7_mod.f90 @@ -317,8 +317,6 @@ module libmeshb7 function GmfStatKwdf77_0(unit, GmfKey) result(res) !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - use iso_fortran_env - !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< integer(int64) :: unit integer(int32) :: GmfKey integer(int32) :: Nmb @@ -334,8 +332,6 @@ end function GmfStatKwdf77_0 function GmfStatKwdf77_1(unit, GmfKey, r, s, t, d, ho) result(res) !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - use iso_fortran_env - !> integer(int64) :: unit integer(int32) :: GmfKey integer(int32) :: Nmb @@ -351,8 +347,6 @@ end function GmfStatKwdf77_1 function GmfSetKwdF77_0(unit, GmfKey, Nmb) result(res) !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - use iso_fortran_env - !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< integer(int64) :: unit integer(int32) :: GmfKey integer(int32) :: Nmb @@ -368,8 +362,6 @@ end function GmfSetKwdF77_0 function GmfSetKwdF77_1(unit, GmfKey, Nmb, d, t, s, ho) result(res) !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - use iso_fortran_env - !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< integer(int64) :: unit integer(int32) :: GmfKey integer(int32) :: Nmb From 6ab59c558b8a96635a5eb97d63a9d46191ed59ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Mar=C3=A9chal?= Date: Fri, 23 Feb 2024 17:35:36 +0100 Subject: [PATCH 28/38] Changed again the whole Fortran API: now using general purpose getline/setline --- examples/test_libmeshb.f | 37 +-- sources/libmeshb7.c | 619 +++++++++++++++++---------------------- sources/libmeshb7.ins | 42 +-- 3 files changed, 294 insertions(+), 404 deletions(-) diff --git a/examples/test_libmeshb.f b/examples/test_libmeshb.f index ba76ce1..79d9486 100644 --- a/examples/test_libmeshb.f +++ b/examples/test_libmeshb.f @@ -8,9 +8,9 @@ integer n parameter (n=4000) integer i,NmbVer,NmbQad,ver,dim,res,RefTab(n),QadTab(5,n),kwd - integer t(10),d,ho,s + integer t(10),d,ho,s,dummyint(1),dummyref integer*8 InpMsh, OutMsh - real*8 VerTab(3,n), sol(10) + real*8 VerTab(3,n), sol(10), dummyreal(1) c -------------------------------------------- @@ -18,7 +18,7 @@ c -------------------------------------------- c Open the mesh file and check the version and dimension - InpMsh = gmfopenmeshf77('../sample_meshes/quad.mesh ', + InpMsh = gmfopenmeshf77('../sample_meshes/quad.mesh', +GmfRead,ver,dim) print*, 'input mesh :', InpMsh,'version:',ver,'dim:',dim if(InpMsh.eq.0) STOP ' InpMsh = 0' @@ -32,17 +32,18 @@ if(NmbQad.gt.n) STOP 'Too many quads' print*, 'input mesh : ',NmbVer,' vertices,',NmbQad,'quads' -c Read the quads - res = gmfgotokwdf77(InpMsh, GmfQuadrilaterals) - do i = 1, NmbQad - res =gmfgetelement(InpMsh, GmfQuadrilaterals, - + QadTab(1,i), QadTab(5,i)) - end do - c Read the vertices res = gmfgotokwdf77(InpMsh, GmfVertices) do i = 1, NmbVer - res = gmfgetvertex(InpMsh, VerTab(1,i), RefTab(i)) + res = gmfgetlinef77(InpMsh, GmfVertices, dummyint(1), + +VerTab(1,i), RefTab(i)) + end do + +c Read the quads + res = gmfgotokwdf77(InpMsh, GmfQuadrilaterals) + do i = 1, NmbQad + res =gmfgetlinef77(InpMsh, GmfQuadrilaterals, + + QadTab(1,i), dummyreal(1), QadTab(5,i)) end do c Close the quadrilateral mesh @@ -62,19 +63,20 @@ c Then write them down do i = 1, NmbVer - res = gmfsetvertex(OutMsh, VerTab(1,i), RefTab(i)) + res = gmfsetlinef77(OutMsh, GmfVertices, dummyint, + +VerTab(1,i), RefTab(i)) end do c Write the triangles res = gmfsetkwdf77(OutMsh, GmfTriangles, 2*NmbQad, 0, t, 0, ho) do i=1,NmbQad - res = gmfsetelement(OutMsh, GmfTriangles, - + QadTab(1,i), QadTab(5,i)) + res = gmfsetlinef77(OutMsh, GmfTriangles, + + QadTab(1,i), dummyreal, QadTab(5,i)) c Modify the quad to build the other triangle's diagonal QadTab(2,i) = QadTab(3,i); QadTab(3,i) = QadTab(4,i); - res = gmfsetelement(OutMsh, GmfTriangles, - + QadTab(1,i),QadTab(5,i)) + res = gmfsetlinef77(OutMsh, GmfTriangles, + + QadTab(1,i), dummyreal, QadTab(5,i)) end do c Don't forget to close the file @@ -106,7 +108,8 @@ sol(3) = i*3 sol(4) = i*4 sol(5) = -i - res = gmfsetsolution(OutMsh, GmfSolAtVertices, sol) + res = gmfsetlinef77(OutMsh, GmfSolAtVertices, + +dummyint, sol, dummyref) end do c Don't forget to close the file diff --git a/sources/libmeshb7.c b/sources/libmeshb7.c index 3208163..0f4c7d9 100644 --- a/sources/libmeshb7.c +++ b/sources/libmeshb7.c @@ -9,7 +9,7 @@ /* Description: handles .meshb file format I/O */ /* Author: Loic MARECHAL */ /* Creation date: dec 09 1999 */ -/* Last modification: feb 21 2024 */ +/* Last modification: feb 23 2024 */ /* */ /*----------------------------------------------------------------------------*/ @@ -192,13 +192,13 @@ int my_aio_write(struct aiocb *aiocbp) #define RegKwd 2 #define SolKwd 3 #define CmtKwd 4 +#define F77Kwd 5 #define WrdSiz 4 #define FilStrSiz 64 #define BufSiz 10000L #define MaxArg 20 - /*----------------------------------------------------------------------------*/ /* Structures */ /*----------------------------------------------------------------------------*/ @@ -475,7 +475,7 @@ static char NmbEleNod[ GmfMaxKwd + 1 ] = 0, 0, 0, - 0, + 1, 2, 3, 4, @@ -1266,13 +1266,25 @@ int GmfSetKwd(int64_t MshIdx, int KwdCod, int64_t NmbLin, ...) int GmfGetLin(int64_t MshIdx, int KwdCod, ...) { - int i, err; + int i, err, typ, *IntTab, *RefPtr, IntVal; + int64_t LngVal; float *FltSolTab, FltVal, *PtrFlt; - double *DblSolTab, *PtrDbl; + double *DblSolTab, *PtrDbl, *DblTab, DblVal; va_list VarArg; - GmfMshSct *msh = (GmfMshSct *)MshIdx; - KwdSct *kwd = &msh->KwdTab[ KwdCod ]; + KwdSct *kwd; + + if(KwdCod < 0) + { + KwdCod = -KwdCod; + kwd = &msh->KwdTab[ KwdCod ]; + typ = F77Kwd; + } + else + { + kwd = &msh->KwdTab[ KwdCod ]; + typ = kwd->typ; + } if( (KwdCod < 1) || (KwdCod > GmfMaxKwd) ) return(0); @@ -1289,7 +1301,7 @@ int GmfGetLin(int64_t MshIdx, int KwdCod, ...) // Start decoding the arguments va_start(VarArg, KwdCod); - switch(kwd->typ) + switch(typ) { case InfKwd : case RegKwd : case CmtKwd : { @@ -1376,6 +1388,62 @@ int GmfGetLin(int64_t MshIdx, int KwdCod, ...) ScaDblWrd(msh, (unsigned char *)&DblSolTab[i]); } }break; + + case F77Kwd : + { + IntTab = va_arg(VarArg, int *); + DblTab = va_arg(VarArg, double *); + RefPtr = va_arg(VarArg, int *); + + for(i=0;iSolSiz;i++) + { + if(kwd->fmt[i] == 'i') + { + if(msh->ver <= 3) + { + if(msh->typ & Asc) + safe_fscanf(msh->hdl, "%d", &IntVal, msh->err); + else + ScaWrd(msh, (unsigned char *)&IntVal); + } + else + { + if(msh->typ & Asc) + safe_fscanf(msh->hdl, INT64_T_FMT, &LngVal, msh->err); + else + ScaDblWrd(msh, (unsigned char *)&LngVal); + + IntVal = (int)LngVal; + } + + if(!NmbEleNod[ KwdCod ] || (i < kwd->SolSiz - 1)) + IntTab[i] = IntVal; + else + *RefPtr = IntVal; + } + else if(kwd->fmt[i] == 'r') + { + if(msh->FltSiz == 32) + { + if(msh->typ & Asc) + safe_fscanf(msh->hdl, "%f", &FltVal, msh->err); + else + ScaWrd(msh, (unsigned char *)&FltVal); + + DblVal = (double)FltVal; + } + else + { + if(msh->typ & Asc) + safe_fscanf(msh->hdl, "%lf", &DblVal, msh->err); + else + ScaDblWrd(msh, (unsigned char *)&DblVal); + } + + DblTab[i] = DblVal; + } + } + }break; } va_end(VarArg); @@ -1390,13 +1458,25 @@ int GmfGetLin(int64_t MshIdx, int KwdCod, ...) int GmfSetLin(int64_t MshIdx, int KwdCod, ...) { - int i, pos, *IntBuf, err; + int i, pos, *IntBuf, err, typ, *IntTab, *RefPtr; int64_t *LngBuf; float *FltSolTab, *FltBuf; - double *DblSolTab, *DblBuf; + double *DblSolTab, *DblBuf, *DblTab; va_list VarArg; GmfMshSct *msh = (GmfMshSct *)MshIdx; - KwdSct *kwd = &msh->KwdTab[ KwdCod ]; + KwdSct *kwd; + + if(KwdCod < 0) + { + KwdCod = -KwdCod; + kwd = &msh->KwdTab[ KwdCod ]; + typ = F77Kwd; + } + else + { + kwd = &msh->KwdTab[ KwdCod ]; + typ = kwd->typ; + } if( (KwdCod < 1) || (KwdCod > GmfMaxKwd) ) return(0); @@ -1414,102 +1494,192 @@ int GmfSetLin(int64_t MshIdx, int KwdCod, ...) // Start decoding the arguments va_start(VarArg, KwdCod); - if(kwd->typ != SolKwd) + switch(typ) { - if(msh->typ & Asc) + case InfKwd : case RegKwd : case CmtKwd : { - for(i=0;iSolSiz;i++) + if(msh->typ & Asc) { - if(kwd->fmt[i] == 'r') - { - if(msh->FltSiz == 32) - fprintf(msh->hdl, "%.9g ", va_arg(VarArg, double)); - else - fprintf(msh->hdl, "%.17g ", va_arg(VarArg, double)); - } - else if(kwd->fmt[i] == 'i') + for(i=0;iSolSiz;i++) { - if(msh->ver <= 3) - fprintf(msh->hdl, "%d ", va_arg(VarArg, int)); - else + if(kwd->fmt[i] == 'r') + { + if(msh->FltSiz == 32) + fprintf(msh->hdl, "%.9g ", va_arg(VarArg, double)); + else + fprintf(msh->hdl, "%.17g ", va_arg(VarArg, double)); + } + else if(kwd->fmt[i] == 'i') { - // [Bruno] %ld -> INT64_T_FMT - fprintf(msh->hdl, INT64_T_FMT " ", va_arg(VarArg, int64_t)); + if(msh->ver <= 3) + fprintf(msh->hdl, "%d ", va_arg(VarArg, int)); + else + { + // [Bruno] %ld -> INT64_T_FMT + fprintf(msh->hdl, INT64_T_FMT " ", va_arg(VarArg, int64_t)); + } } + else if(kwd->fmt[i] == 'c') + fprintf(msh->hdl, "%s ", va_arg(VarArg, char *)); } - else if(kwd->fmt[i] == 'c') - fprintf(msh->hdl, "%s ", va_arg(VarArg, char *)); } - } - else - { - pos = 0; - - for(i=0;iSolSiz;i++) + else { - if(kwd->fmt[i] == 'r') + pos = 0; + + for(i=0;iSolSiz;i++) { - if(msh->FltSiz == 32) - { - FltBuf = (void *)&msh->buf[ pos ]; - *FltBuf = (float)va_arg(VarArg, double); - pos += 4; - } - else + if(kwd->fmt[i] == 'r') { - DblBuf = (void *)&msh->buf[ pos ]; - *DblBuf = va_arg(VarArg, double); - pos += 8; + if(msh->FltSiz == 32) + { + FltBuf = (void *)&msh->buf[ pos ]; + *FltBuf = (float)va_arg(VarArg, double); + pos += 4; + } + else + { + DblBuf = (void *)&msh->buf[ pos ]; + *DblBuf = va_arg(VarArg, double); + pos += 8; + } } - } - else if(kwd->fmt[i] == 'i') - { - if(msh->ver <= 3) + else if(kwd->fmt[i] == 'i') { - IntBuf = (void *)&msh->buf[ pos ]; - *IntBuf = va_arg(VarArg, int); - pos += 4; + if(msh->ver <= 3) + { + IntBuf = (void *)&msh->buf[ pos ]; + *IntBuf = va_arg(VarArg, int); + pos += 4; + } + else + { + LngBuf = (void *)&msh->buf[ pos ]; + *LngBuf = va_arg(VarArg, int64_t); + pos += 8; + } } - else + else if(kwd->fmt[i] == 'c') { - LngBuf = (void *)&msh->buf[ pos ]; - *LngBuf = va_arg(VarArg, int64_t); - pos += 8; + memset(&msh->buf[ pos ], 0, FilStrSiz * WrdSiz); + strncpy(&msh->buf[ pos ], va_arg(VarArg, char *), FilStrSiz * WrdSiz); + pos += FilStrSiz; } } - else if(kwd->fmt[i] == 'c') - { - memset(&msh->buf[ pos ], 0, FilStrSiz * WrdSiz); - strncpy(&msh->buf[ pos ], va_arg(VarArg, char *), FilStrSiz * WrdSiz); - pos += FilStrSiz; - } + + RecBlk(msh, msh->buf, kwd->NmbWrd); } + }break; - RecBlk(msh, msh->buf, kwd->NmbWrd); - } - } - else - { - if(msh->FltSiz == 32) + case SolKwd : { - FltSolTab = va_arg(VarArg, float *); + if(msh->FltSiz == 32) + { + FltSolTab = va_arg(VarArg, float *); - if(msh->typ & Asc) - for(i=0; iSolSiz; i++) - fprintf(msh->hdl, "%.9g ", (double)FltSolTab[i]); + if(msh->typ & Asc) + for(i=0; iSolSiz; i++) + fprintf(msh->hdl, "%.9g ", (double)FltSolTab[i]); + else + RecBlk(msh, (unsigned char *)FltSolTab, kwd->NmbWrd); + } else - RecBlk(msh, (unsigned char *)FltSolTab, kwd->NmbWrd); - } - else + { + DblSolTab = va_arg(VarArg, double *); + + if(msh->typ & Asc) + for(i=0; iSolSiz; i++) + fprintf(msh->hdl, "%.17g ", DblSolTab[i]); + else + RecBlk(msh, (unsigned char *)DblSolTab, kwd->NmbWrd); + } + }break; + + case F77Kwd : { - DblSolTab = va_arg(VarArg, double *); + IntTab = va_arg(VarArg, int *); + DblTab = va_arg(VarArg, double *); + RefPtr = va_arg(VarArg, int *); if(msh->typ & Asc) - for(i=0; iSolSiz; i++) - fprintf(msh->hdl, "%.17g ", DblSolTab[i]); + { + for(i=0;iSolSiz;i++) + { + if(kwd->fmt[i] == 'r') + { + if(msh->FltSiz == 32) + fprintf(msh->hdl, "%.9g ", (float)DblTab[i]); + else + fprintf(msh->hdl, "%.17g ", DblTab[i]); + } + else if(kwd->fmt[i] == 'i') + { + if(msh->ver <= 3) + if(!NmbEleNod[ KwdCod ] || (i < kwd->SolSiz - 1)) + fprintf(msh->hdl, "%d ", IntTab[i]); + else + fprintf(msh->hdl, "%d ", *RefPtr); + else + { + if(!NmbEleNod[ KwdCod ] || (i < kwd->SolSiz - 1)) + fprintf(msh->hdl, INT64_T_FMT " ", (int64_t)IntTab[i]); + else + fprintf(msh->hdl, INT64_T_FMT " ", (int64_t)*RefPtr); + } + } + } + } else - RecBlk(msh, (unsigned char *)DblSolTab, kwd->NmbWrd); - } + { + pos = 0; + + for(i=0;iSolSiz;i++) + { + if(kwd->fmt[i] == 'r') + { + if(msh->FltSiz == 32) + { + FltBuf = (void *)&msh->buf[ pos ]; + *FltBuf = (float)DblTab[i]; + pos += 4; + } + else + { + DblBuf = (void *)&msh->buf[ pos ]; + *DblBuf = DblTab[i]; + pos += 8; + } + } + else if(kwd->fmt[i] == 'i') + { + if(msh->ver <= 3) + { + IntBuf = (void *)&msh->buf[ pos ]; + + if(!NmbEleNod[ KwdCod ] || (i < kwd->SolSiz - 1)) + *IntBuf = IntTab[i]; + else + *IntBuf = *RefPtr; + + pos += 4; + } + else + { + LngBuf = (void *)&msh->buf[ pos ]; + + if(!NmbEleNod[ KwdCod ] || (i < kwd->SolSiz - 1)) + *LngBuf = (int64_t)IntTab[i]; + else + *LngBuf = (int64_t)*RefPtr; + + pos += 8; + } + } + } + + RecBlk(msh, msh->buf, kwd->NmbWrd); + } + }break; } va_end(VarArg); @@ -3279,287 +3449,28 @@ int APIF77(gmfsethonodesorderingf77)( int64_t *MshIdx, int *KwdCod, return(GmfSetHONodesOrdering(*MshIdx, *KwdCod, BasTab, OrdTab)); } - -// VERTICES - -int APIF77(gmfgetvertex)(int64_t *MshIdx, double *crd, int *ref) -{ - GmfMshSct *msh = (GmfMshSct *)*MshIdx; - - if(msh->dim == 3) - return(GmfGetLin(*MshIdx, GmfVertices, &crd[0], &crd[1], &crd[2], ref)); - else if(msh->dim == 2) - return(GmfGetLin(*MshIdx, GmfVertices, &crd[0], &crd[1], ref)); - else - return(0); -} - -int APIF77(gmfsetvertex)(int64_t *MshIdx, double *crd, int *ref) +int APIF77(gmfgetlinef77)(int64_t *MshIdx, int *kwd, int *i, double *d, int *r) { - GmfMshSct *msh = (GmfMshSct *)*MshIdx; - - if(msh->dim == 3) - return(GmfSetLin(*MshIdx, GmfVertices, crd[0], crd[1], crd[2], *ref)); - else if(msh->dim == 2) - return(GmfSetLin(*MshIdx, GmfVertices, crd[0], crd[1], *ref)); - else - return(0); + return(GmfGetLin(*MshIdx, -*kwd, i, d, r)); } -int APIF77(gmfgetvertices)(int64_t *MshIdx, int *BegIdx, int *EndIdx, - int *MapTyp, int64_t *map, - double *BegNod, double *EndNod, - int *BegRef, int *EndRef ) +int APIF77(gmfsetlinef77)(int64_t *MshIdx, int *kwd, int *i, double *d, int *r) { - GmfMshSct *msh = (GmfMshSct *)*MshIdx; - - return(GmfGetBlock( *MshIdx, GmfVertices, *BegIdx, *EndIdx, - *MapTyp, map, NULL, - GmfDoubleVec, msh->dim, BegNod, EndNod, - GmfInt, BegRef, EndRef )); + return(GmfSetLin(*MshIdx, -*kwd, i, d, r)); } -int APIF77(gmfsetvertices)(int64_t *MshIdx, int *BegIdx, int *EndIdx, - int *MapTyp, int64_t *map, - double *BegNod, double *EndNod, - int *BegRef, int *EndRef ) +int APIF77(gmfgetblockf77)(int64_t *MshIdx, int *kwd, int *BegIdx, int *EndIdx, + int *MapTyp, int *MatTab, int *BegInt, int *EndInt, + double *BegDbl, double *EndDbl, int *BegRef, int *EndRef) { - GmfMshSct *msh = (GmfMshSct *)*MshIdx; - - return(GmfSetBlock( *MshIdx, GmfVertices, *BegIdx, *EndIdx, - *MapTyp, map, NULL, - GmfDoubleVec, msh->dim, BegNod, EndNod, - GmfInt, BegRef, EndRef )); + return(GmfGetBlock( *MshIdx, -*kwd, *BegIdx, *EndIdx, *MapTyp, MatTab, + NULL, BegInt, EndInt, BegDbl, EndDbl, BegRef, EndRef )); } - -// ELEMENTS - -int APIF77(gmfgetelement)(int64_t *MshIdx, int *kwd, int *n, int *r) +int APIF77(gmfsetblockf77)(int64_t *MshIdx, int *kwd, int *BegIdx, int *EndIdx, + int *MapTyp, int *MatTab, int *BegInt, int *EndInt, + double *BegDbl, double *EndDbl, int *BegRef, int *EndRef) { - switch(NmbEleNod[ *kwd ]) - { - case 1 : - return(GmfGetLin(*MshIdx, *kwd, &n[0], r)); - case 2 : - return(GmfGetLin(*MshIdx, *kwd, &n[0], &n[1], r)); - case 3 : - return(GmfGetLin(*MshIdx, *kwd, &n[0], &n[1], &n[2], r)); - case 4 : - return(GmfGetLin(*MshIdx, *kwd, &n[0], &n[1], &n[2], &n[3], r)); - case 5 : - return(GmfGetLin(*MshIdx, *kwd, &n[0], &n[1], &n[2], &n[3], &n[4], r)); - case 6 : - return(GmfGetLin(*MshIdx, *kwd, &n[0], &n[1], &n[2], &n[3], &n[4], &n[5], r)); - case 7 : - return(GmfGetLin(*MshIdx, *kwd, &n[0], &n[1], &n[2], &n[3], &n[4], &n[5], &n[6], r)); - case 8 : - return(GmfGetLin(*MshIdx, *kwd, &n[0], &n[1], &n[2], &n[3], &n[4], &n[5], &n[6], &n[7], r)); - case 9 : - return(GmfGetLin(*MshIdx, *kwd, &n[0], &n[1], &n[2], &n[3], &n[4], &n[5], &n[6], &n[7], &n[8], r)); - case 10 : - return(GmfGetLin(*MshIdx, *kwd, &n[0], &n[1], &n[2], &n[3], &n[4], &n[5], &n[6], &n[7], &n[8], &n[9], r)); - default : - return(0); - } -} - -int APIF77(gmfsetelement)(int64_t *MshIdx, int *kwd, int *n, int *r) -{ - switch(NmbEleNod[ *kwd ]) - { - case 1 : - return(GmfSetLin(*MshIdx, *kwd, n[0], *r)); - case 2 : - return(GmfSetLin(*MshIdx, *kwd, n[0], n[1], *r)); - case 3 : - return(GmfSetLin(*MshIdx, *kwd, n[0], n[1], n[2], *r)); - case 4 : - return(GmfSetLin(*MshIdx, *kwd, n[0], n[1], n[2], n[3], *r)); - case 5 : - return(GmfSetLin(*MshIdx, *kwd, n[0], n[1], n[2], n[3], n[4], *r)); - case 6 : - return(GmfSetLin(*MshIdx, *kwd, n[0], n[1], n[2], n[3], n[4], n[5], *r)); - case 7 : - return(GmfSetLin(*MshIdx, *kwd, n[0], n[1], n[2], n[3], n[4], n[5], n[6], *r)); - case 8 : - return(GmfSetLin(*MshIdx, *kwd, n[0], n[1], n[2], n[3], n[4], n[5], n[6], n[7], *r)); - case 9 : - return(GmfSetLin(*MshIdx, *kwd, n[0], n[1], n[2], n[3], n[4], n[5], n[6], n[7], n[8], *r)); - case 10 : - return(GmfSetLin(*MshIdx, *kwd, n[0], n[1], n[2], n[3], n[4], n[5], n[6], n[7], n[8], n[9], *r)); - default : - return(0); - } -} - -int APIF77(gmfgetelements)(int64_t *MshIdx, int *kwd, int *BegIdx, int *EndIdx, - int *MapTyp, int64_t *map, - int *BegEle, int *EndEle, - int *BegRef, int *EndRef) -{ - int EleSiz = NmbEleNod[ *kwd ]; - - if(!EleSiz) - return(0); - - return(GmfGetBlock( *MshIdx, *kwd, *BegIdx, *EndIdx, - *MapTyp, map, NULL, - GmfIntVec, EleSiz, BegEle, EndEle, - GmfInt, BegRef, EndRef )); -} - -int APIF77(gmfsetelements)(int64_t *MshIdx, int *kwd, int *BegIdx, int *EndIdx, - int *MapTyp, int64_t *map, - int *BegEle, int *EndEle, - int *BegRef, int *EndRef) -{ - int EleSiz = NmbEleNod[ *kwd ]; - - if(!EleSiz) - return(0); - - - return(GmfSetBlock( *MshIdx, *kwd, *BegIdx, *EndIdx, - *MapTyp, map, NULL, - GmfIntVec, EleSiz, BegEle, EndEle, - GmfInt, BegRef, EndRef )); -} - - -// SOLUTION FIELDS - -int APIF77(gmfgetsolution)(int64_t *MshIdx, int *kwd, double *sol) -{ - return(GmfGetLin(*MshIdx, *kwd, sol)); -} - -int APIF77(gmfsetsolution)(int64_t *MshIdx, int *kwd, double *sol) -{ - return(GmfSetLin(*MshIdx, *kwd, sol)); -} - -int APIF77(gmfgetsolutionss)(int64_t *MshIdx, int *KwdCod, int *BegIdx, int *EndIdx, - int *MapTyp, int64_t *map, - double *BegSol, double *EndSol) -{ - GmfMshSct *msh = (GmfMshSct *)*MshIdx; - KwdSct *kwd = &msh->KwdTab[ *KwdCod ]; - - return(GmfGetBlock( *MshIdx, *KwdCod, *BegIdx, *EndIdx, - *MapTyp, map, NULL, - GmfDoubleVec, kwd->SolSiz, BegSol, EndSol )); -} - -int APIF77(gmfsetsolutionss)(int64_t *MshIdx, int *KwdCod, int *BegIdx, int *EndIdx, - int *MapTyp, int64_t *map, - double *BegSol, double *EndSol) -{ - GmfMshSct *msh = (GmfMshSct *)*MshIdx; - KwdSct *kwd = &msh->KwdTab[ *KwdCod ]; - - return(GmfSetBlock( *MshIdx, *KwdCod, *BegIdx, *EndIdx, - *MapTyp, map, NULL, - GmfDoubleVec, kwd->SolSiz, BegSol, EndSol )); -} - - -// INTERGER BASED KEYWORDS - -int APIF77(gmfgetlinei4)(int64_t *MshIdx, int *KwdCod, int *i) -{ - GmfMshSct *msh = (GmfMshSct *)*MshIdx; - KwdSct *kwd = &msh->KwdTab[ *KwdCod ]; - - if(kwd->SolSiz != kwd->NmbInt) - return(0); - - switch(kwd->NmbInt) - { - case 1 : - return(GmfGetLin(*MshIdx, *KwdCod, &i[0])); - case 2 : - return(GmfGetLin(*MshIdx, *KwdCod, &i[0], &i[1])); - case 3 : - return(GmfGetLin(*MshIdx, *KwdCod, &i[0], &i[1], &i[2])); - case 4 : - return(GmfGetLin(*MshIdx, *KwdCod, &i[0], &i[1], &i[2], &i[3])); - case 5 : - return(GmfGetLin(*MshIdx, *KwdCod, &i[0], &i[1], &i[2], &i[3], &i[4])); - case 6 : - return(GmfGetLin(*MshIdx, *KwdCod, &i[0], &i[1], &i[2], &i[3], &i[4], &i[5])); - case 7 : - return(GmfGetLin(*MshIdx, *KwdCod, &i[0], &i[1], &i[2], &i[3], &i[4], &i[5], &i[6])); - case 8 : - return(GmfGetLin(*MshIdx, *KwdCod, &i[0], &i[1], &i[2], &i[3], &i[4], &i[5], &i[6], &i[7])); - case 9 : - return(GmfGetLin(*MshIdx, *KwdCod, &i[0], &i[1], &i[2], &i[3], &i[4], &i[5], &i[6], &i[7], &i[8])); - case 10 : - return(GmfGetLin(*MshIdx, *KwdCod, &i[0], &i[1], &i[2], &i[3], &i[4], &i[5], &i[6], &i[7], &i[8], &i[9])); - default : - return(0); - } -} - -int APIF77(gmfsetlinei4)(int64_t *MshIdx, int *KwdCod, int *i) -{ - GmfMshSct *msh = (GmfMshSct *)*MshIdx; - KwdSct *kwd = &msh->KwdTab[ *KwdCod ]; - - if(kwd->SolSiz != kwd->NmbInt) - return(0); - - switch(kwd->NmbInt) - { - case 1 : - return(GmfSetLin(*MshIdx, *KwdCod, i[0])); - case 2 : - return(GmfSetLin(*MshIdx, *KwdCod, i[0], i[1])); - case 3 : - return(GmfSetLin(*MshIdx, *KwdCod, i[0], i[1], i[2])); - case 4 : - return(GmfSetLin(*MshIdx, *KwdCod, i[0], i[1], i[2], i[3])); - case 5 : - return(GmfSetLin(*MshIdx, *KwdCod, i[0], i[1], i[2], i[3], i[4])); - case 6 : - return(GmfSetLin(*MshIdx, *KwdCod, i[0], i[1], i[2], i[3], i[4], i[5])); - case 7 : - return(GmfSetLin(*MshIdx, *KwdCod, i[0], i[1], i[2], i[3], i[4], i[5], i[6])); - case 8 : - return(GmfSetLin(*MshIdx, *KwdCod, i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7])); - case 9 : - return(GmfSetLin(*MshIdx, *KwdCod, i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7], i[8])); - case 10 : - return(GmfSetLin(*MshIdx, *KwdCod, i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7], i[8], i[9])); - default : - return(0); - } -} - -int APIF77(gmfgetblocki4)( int64_t *MshIdx, int *KwdCod, - int *BegIdx, int *EndIdx, - int *BegDat, int *EndDat ) -{ - GmfMshSct *msh = (GmfMshSct *)*MshIdx; - KwdSct *kwd = &msh->KwdTab[ *KwdCod ]; - - if(kwd->SolSiz != kwd->NmbInt) - return(0); - - return(GmfGetBlock( *MshIdx, *KwdCod, *BegIdx, *EndIdx, 0, NULL, NULL, - GmfIntVec, kwd->NmbInt, BegDat, EndDat )); -} - -int APIF77(gmfsetblocki4)( int64_t *MshIdx, int *KwdCod, - int *BegIdx, int *EndIdx, - int *BegDat, int *EndDat ) -{ - GmfMshSct *msh = (GmfMshSct *)*MshIdx; - KwdSct *kwd = &msh->KwdTab[ *KwdCod ]; - - if(kwd->SolSiz != kwd->NmbInt) - return(0); - - return(GmfSetBlock( *MshIdx, *KwdCod, *BegIdx, *EndIdx, 0, NULL, NULL, - GmfIntVec, kwd->NmbInt, BegDat, EndDat )); + return(GmfSetBlock( *MshIdx, -*kwd, *BegIdx, *EndIdx, *MapTyp, MatTab, + NULL, BegInt, EndInt, BegDbl, EndDbl, BegRef, EndRef )); } diff --git a/sources/libmeshb7.ins b/sources/libmeshb7.ins index defda79..bf9da1f 100644 --- a/sources/libmeshb7.ins +++ b/sources/libmeshb7.ins @@ -9,7 +9,7 @@ c c Description: handles .meshb file format I/O c Author: Loic MARECHAL c Creation date: dec 08 2015 -c Last modification: feb 21 2024 +c Last modification: feb 22 2024 c c---------------------------------------------------------- @@ -21,22 +21,10 @@ c Procedures definition external gmfsetkwdf77 external gmfgotokwdf77 external gmfsethonodesorderingf77 - external gmfgetvertex - external gmfsetvertex - external gmfgetelement - external gmfsetelement - external gmfgetvertices - external gmfsetvertices - external gmfgetelements - external gmfsetelements - external gmfgetsolution - external gmfsetsolution - external gmfgetsolutions - external gmfsetsolutions - external gmfgetlinei4 - external gmfsetlinei4 - external gmfgetblocki4 - external gmfsetblocki4 + external gmfgetlinef77 + external gmfsetlinef77 + external gmfgetblockf77 + external gmfsetblockf77 integer*8 gmfopenmeshf77 integer gmfclosemeshf77 @@ -44,22 +32,10 @@ c Procedures definition integer gmfsetkwdf77 integer gmfgotokwdf77 integer gmfsethonodesorderingf77 - integer gmfgetvertex - integer gmfsetvertex - integer gmfgetelement - integer gmfsetelement - integer gmfgetvertices - integer gmfsetvertices - integer gmfgetelements - integer gmfsetelements - integer gmfgetsolution - integer gmfsetsolution - integer gmfgetsolutions - integer gmfsetsolutions - integer gmfgetlinei4 - integer gmfsetlinei4 - integer gmfgetblocki4 - integer gmfsetblocki4 + integer gmfgetlinef77 + integer gmfsetlinef77 + integer gmfgetblockf77 + integer gmfsetblockf77 c Parameters definition From 34d8b2ab95c59be9413b8c2898c7292fe4450285 Mon Sep 17 00:00:00 2001 From: Christophe Peyret Date: Sun, 25 Feb 2024 19:00:56 +0100 Subject: [PATCH 29/38] =?UTF-8?q?Mises=20=C3=A0=20jour=20module=20fortran?= =?UTF-8?q?=2090=20et=20des=20exemples=20fortran=2090.=20Il=20reste=20enco?= =?UTF-8?q?re=20=C3=A0=20mettre=20au=20point=20les=20exemples=20test=5Flib?= =?UTF-8?q?mesgb=5Fblock.f90=20et=20test=5Flibmesgb=5FHO.f90.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- examples/test_libmeshb.f90 | 84 ++++-- examples/test_libmeshb_HO.f90 | 118 ++++---- examples/test_libmeshb_block.f90 | 134 ++++++--- sources/libmeshb7_mod.f90 | 487 ++++++++++++++++++++++++++++--- 4 files changed, 660 insertions(+), 163 deletions(-) diff --git a/examples/test_libmeshb.f90 b/examples/test_libmeshb.f90 index 0ff6268..ea4ff73 100644 --- a/examples/test_libmeshb.f90 +++ b/examples/test_libmeshb.f90 @@ -1,11 +1,15 @@ - ! libMeshb 7.79 basic example: ! read a quad mesh, split it into triangles and write the result back ! write an associated dummy .sol file containing some data +!> A FAIRE ajouter time +!> A FAIRE ajouter iteration +!> A FAIRE ajouter nom des champs + program test_libmeshb_f90 !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> use iso_fortran_env + use iso_c_binding, only: C_NULL_CHAR use libmeshb7 !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> @@ -17,7 +21,9 @@ program test_libmeshb_f90 character(80) :: SolFile integer(int32) :: i integer(int32) :: NmbVer,NmbQad,NmbTri,ver,dim,res,kwd - integer(int32) :: NmbField,fields(1:10),ho,s,d + integer(int32) :: NmbField,ho,s,d + integer(int32), pointer :: fields(:) + character(32) , pointer :: fieldsName(:)=>null() real(real64) , pointer :: sol(:) real(real64) , pointer :: VerTab(:,:) integer(int32), pointer :: VerRef( :) @@ -39,8 +45,8 @@ program test_libmeshb_f90 ! Open the quadrilateral mesh file for reading print '(/"Input Mesh Open : ",a )',trim(InpFile) - ! Open the mesh file and check the version and dimension - InpMsh = GmfOpenMeshf77(trim(InpFile),GmfRead,ver,dim) + call GmfOpenMeshF90(name=trim(InpFile),unit=InpMsh,GmfKey=GmfRead,ver=ver,dim=dim) + print '( "Input Mesh Idx : ",i0)',InpMsh print '( "Input Mesh ver : ",i0)',ver print '( "Input Mesh dim : ",i0)',dim @@ -51,30 +57,30 @@ program test_libmeshb_f90 ! Read the vertices - NmbVer = Gmfstatkwd(unit=InpMsh, GmfKey=GmfVertices) + NmbVer = GmfstatkwdF90(unit=InpMsh, GmfKey=GmfVertices) print '( "Input Mesh NmbVer : ",i0)', NmbVer allocate(VerTab(1:3,1:NmbVer)) allocate(VerRef( 1:NmbVer)) - res = Gmfgotokwdf77(InpMsh, GmfVertices) + res=GmfGotoKwdF90(unit=InpMsh, GmfKey=GmfVertices) do i=1,NmbVer - res=GmfGetVertex(InpMsh, VerTab(1:3,i), VerRef(i)) + res=GmfGetLineF90(unit=InpMsh, GmfKey=GmfVertices, Tab=VerTab(:,i), Ref=VerRef(i)) end do ! Read the quads - NmbQad = Gmfstatkwd(unit=InpMsh, GmfKey=GmfQuadrilaterals) + NmbQad = GmfstatkwdF90(unit=InpMsh, GmfKey=GmfQuadrilaterals) print '( "Input Mesh NmbQad : ",i0)', NmbQad allocate(QadTab(1:4,1:NmbQad)) allocate(QadRef( 1:NmbQad)) - res=Gmfgotokwdf77(InpMsh, GmfQuadrilaterals) + res=GmfgotokwdF90(unit=InpMsh, GmfKey=GmfQuadrilaterals) do i=1,NmbQad - res=GmfGetElement(InpMsh, GmfQuadrilaterals, QadTab(1:4,i), QadRef(i)) + res=GmfGetLineF90(unit=InpMsh, GmfKey=GmfQuadrilaterals, Tab=QadTab(:,i), Ref=QadRef(i)) enddo ! Close the quadrilateral mesh - res=GmfCloseMeshf77(InpMsh) + res=GmfCloseMeshF90(unit=InpMsh) print '("Input Mesh Close : ",a)',trim(InpFile) !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< @@ -83,43 +89,47 @@ program test_libmeshb_f90 NmbTri=2*NmbQad print '(/"Output Mesh Open : ",a )',trim(OutFile) - OutMsh = GmfOpenMeshf77(trim(OutFile), GmfWrite, ver, dim) + + call GmfOpenMeshF90(name=trim(OutFile),unit=OutMsh,GmfKey=GmfWrite,ver=ver,dim=dim) + print '( "Output Mesh Idx : ",i0)',InpMsh print '( "Output Mesh ver : ",i0)',ver print '( "Output Mesh dim : ",i0)',dim if( OutMsh==0 ) STOP ' OutMsh = 0' - + ! Set the number of vertices - res=GmfSetKwd(OutMsh, GmfVertices, NmbVer) + res=GmfSetKwdF90(unit=OutMsh, GmfKey=GmfVertices, Nmb=NmbVer) print '( "Output Mesh NmbVer : ",i0)', NmbVer ! Then write them down do i=1,NmbVer - res=GmfSetVertex(OutMsh, VerTab(1:3,i), VerRef(i)) + res=GmfSetLineF90(unit=OutMsh, GmfKey=GmfVertices, Tab=VerTab(:,i), Ref=VerRef(i)) end do ! Write the triangles - res = GmfSetKwd(OutMsh, GmfTriangles, 2*NmbQad) + res=GmfSetKwdF90(unit=OutMsh, GmfKey=GmfTriangles, Nmb=NmbTri) print '( "Output Mesh NmbTri : ",i0)', NmbTri do i=1,NmbQad - res=GmfSetElement(OutMsh, GmfTriangles, QadTab(1,i), QadRef(i)) + res=GmfSetLineF90(unit=OutMsh, GmfKey=GmfTriangles, Tab=QadTab(1:3,i), Ref=QadRef(i)) ! Modify the quad to build the other triangle's diagonal - QadTab(2,i) = QadTab(3,i); - QadTab(3,i) = QadTab(4,i); - res=GmfSetElement(OutMsh, GmfTriangles, QadTab(1,i), QadRef(i)) + QadTab(2,i) = QadTab(3,i) + QadTab(3,i) = QadTab(4,i) + res=GmfSetLineF90(unit=OutMsh, GmfKey=GmfTriangles, Tab=QadTab(1:3,i), Ref=QadRef(i)) end do ! Don't forget to close the file - res = GmfCloseMeshf77(OutMsh) + res=GmfCloseMeshF90(unit=OutMsh) print '("Output Mesh Close : ",a)',trim(OutFile) !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ! Create a solution file + print '(/"Output Solu Open : ",a )',trim(SolFile) - OutSol = GmfOpenMeshf77(trim(SolFile), GmfWrite, ver, dim) + call GmfOpenMeshF90(name=trim(SolFile),unit=OutSol,GmfKey=GmfWrite,ver=ver,dim=dim) + print '( "Output Solu Idx : ",i0)',OutSol print '( "Output Solu ver : ",i0)',ver print '( "Output Solu dim : ",i0)',dim @@ -127,25 +137,45 @@ program test_libmeshb_f90 ! Set the solution kinds NmbField=3 - fields(1:NmbField) = [GmfSca,GmfVec,GmfSca] + allocate( fields (1:NmbField)) + allocate( fieldsName(1:NmbField)) + fields(1:NmbField) = [GmfSca,GmfVec,GmfSca] + fieldsName(1:NmbField)=['sca_1','vec_1','sca_2'] + + !nomDesChamps : block + ! integer :: iField,nChar + ! character(:), pointer :: fieldName=>null() + ! res=GmfSetKwdF90(unit=OutSol, GmfKey=GmfReferenceStrings, Nmb=NmbField) + ! do iField=1,NmbField + ! nChar=len_trim(fieldsName(iField)) ! print '("nChar: ",i0)',nChar + ! allocate(character(len=nChar+3) :: fieldName) + ! write(fieldName,'(a,1x,i0,a)')trim(fieldsName(iField)),iField,C_NULL_CHAR + ! print '("fieldName: ",a)',fieldName + ! + ! !ress=GmfSetLin(unit=OutSol, GmfKey=GmfReferenceStrings, GmfSolAtVertices, 1, fieldName) + ! + ! deallocate(fieldName) + ! enddo + !end block nomDesChamps + allocate(sol(1:5)) ! 1+ dim+ 1 print '( "Output Solu NmbVer : ",i0)',NmbVer print '( "Output Solu nFields : ",i0)',NmbField print '( "Output Solu fields : ", *(i0,1x))',fields(1:NmbField) ! Set the number of solutions (one per vertex) - res = GmfSetKwd(OutSol, GmfSolAtVertices, NmbVer, NmbField, fields(1:NmbField), 0, ho) + res=GmfSetKwdF90(unit=OutSol, GmfKey=GmfSolAtVertices, Nmb=NmbVer, d=NmbField, t=fields(1:NmbField), s=0, ho=ho) ! Write the dummy solution fields do i=1,NmbVer sol( 1)=VerTab(1,i) sol(2:4)=[VerTab(1,i),VerTab(2,i),0d0] sol( 5)=VerTab(2,i) - res=GmfSetSolution(OutSol, GmfSolAtVertices, sol) + res=GmfSetLineF90(unit=OutMsh, GmfKey=GmfSolAtVertices, dTab=sol(:)) enddo ! Don't forget to close the file - res = GmfCloseMeshf77(OutSol) + res=GmfCloseMeshF90(unit=OutSol) print '("Output Solu Close : ",a)',trim(SolFile) !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< @@ -153,7 +183,7 @@ program test_libmeshb_f90 !> Cleanning Memory deallocate(VerTab,VerRef) deallocate(QadTab,QadRef) - deallocate(sol) + deallocate(fields,fieldsName,sol) !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> diff --git a/examples/test_libmeshb_HO.f90 b/examples/test_libmeshb_HO.f90 index 3f8fd4c..862c31d 100644 --- a/examples/test_libmeshb_HO.f90 +++ b/examples/test_libmeshb_HO.f90 @@ -5,6 +5,7 @@ program test_libmeshb_HO_f90 !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> use iso_fortran_env + use, intrinsic :: iso_c_binding, only: c_null_ptr use libmeshb7 !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> @@ -49,7 +50,7 @@ program test_libmeshb_HO_f90 ! Read the vertices using a vector of 3 consecutive doubles to store the coordinates - NmbVer = Gmfstatkwd(unit=InpMsh, GmfKey=GmfVertices) + NmbVer = GmfstatkwdF90(unit=InpMsh, GmfKey=GmfVertices) print '( "Input Mesh NmbVer: ",i0)', NmbVer allocate(VerTab(1:3,1:NmbVer)) allocate(VerRef( 1:NmbVer)) @@ -58,7 +59,8 @@ program test_libmeshb_HO_f90 & InpMsh ,& & 1 ,& & NmbVer ,& - & 0, m ,& + ! 0, m ,& + & 0, c_null_ptr ,& & VerTab(1,1), VerTab(1,NmbVer) ,& & VerRef( 1), VerRef( NmbVer) ) @@ -67,35 +69,35 @@ program test_libmeshb_HO_f90 GmfCell=GmfQuadrilateralsQ2 ! <= GmfOrd =GmfQuadrilateralsQ2Ordering ! <= - NmbQad=Gmfstatkwd(unit=InpMsh,GmfKey=GmfCell) + NmbQad=GmfstatkwdF90(unit=InpMsh,GmfKey=GmfCell) print '( "Input Mesh NmbQad: ",i0)', NmbQad allocate(QadTab(1:9,1:NmbQad)) allocate(QadRef( 1:NmbQad)) - if( .not. Gmfstatkwd(unit=InpMsh,GmfKey=GmfOrd)==0 )then + if( .not. GmfstatkwdF90(unit=InpMsh,GmfKey=GmfOrd)==0 )then print '("Input Mesh Reordering HO Nodes")' block - integer :: orderingSpace(1:2,1:9) - integer :: orderingMesh (1:2,1:9) + integer :: BasTab(1:2,1:9) + integer :: OrdTab(1:2,1:9) integer :: ord integer :: nNode integer :: nUVW !> 04 07 03 !> 08 09 06 !> 01 05 02 - orderingSpace(1:2,01)=[0,0] - orderingSpace(1:2,02)=[2,0] - orderingSpace(1:2,03)=[2,2] - orderingSpace(1:2,04)=[0,2] - orderingSpace(1:2,05)=[1,0] - orderingSpace(1:2,06)=[2,1] - orderingSpace(1:2,07)=[1,2] - orderingSpace(1:2,08)=[0,1] - orderingSpace(1:2,09)=[1,1] + BasTab(1:2,01)=[0,0] + BasTab(1:2,02)=[2,0] + BasTab(1:2,03)=[2,2] + BasTab(1:2,04)=[0,2] + BasTab(1:2,05)=[1,0] + BasTab(1:2,06)=[2,1] + BasTab(1:2,07)=[1,2] + BasTab(1:2,08)=[0,1] + BasTab(1:2,09)=[1,1] print '("Input Mesh Requested Order")' - do i=1,size(orderingSpace,2) - print '(3x,"uv(",i2.2,")=",2(i2,1x))',i,orderingSpace(1:2,i) + do i=1,size(BasTab,2) + print '(3x,"uv(",i2.2,")=",2(i2,1x))',i,BasTab(1:2,i) enddo !> Q2 -> ord=2 @@ -103,32 +105,41 @@ program test_libmeshb_HO_f90 nNode=(ord+1)*(ord+1) ! <= nUVW=2 ! <= - !res=GmfGetBlock( & - !& InpMsh ,& - !& GmfOrd ,& - !& int( 1,kind=8) ,& - !& int(nNode,kind=8) ,& - !& 0, %val(0), %val(0) ,& - !& GmfIntTab, nUVW, orderingMesh(1,1), orderingMesh(1,nNode) ) + !res=GmfGetBlock( & + !& InpMsh ,& + !& GmfOrd ,& + !& int( 1,kind=8) ,& + !& int(nNode,kind=8) ,& + !& 0, %val(0), %val(0) ,& + !& GmfIntTab, nUVW, OrdTab(1,1), OrdTab(1,nNode) ) !> en attendant de pouvoir récupérer orderingMesh ses valeurs sont imposées manuellement - orderingMesh(1:2,01)=[0,0] - orderingMesh(1:2,02)=[2,0] - orderingMesh(1:2,03)=[2,2] - orderingMesh(1:2,04)=[0,2] - orderingMesh(1:2,05)=[1,0] - orderingMesh(1:2,06)=[2,1] - orderingMesh(1:2,07)=[1,2] - orderingMesh(1:2,08)=[0,1] - orderingMesh(1:2,09)=[1,1] - + !OrdTab(1:2,01)=[0,0] + !OrdTab(1:2,02)=[2,0] + !OrdTab(1:2,03)=[2,2] + !OrdTab(1:2,04)=[0,2] + !OrdTab(1:2,05)=[1,0] + !OrdTab(1:2,06)=[2,1] + !OrdTab(1:2,07)=[1,2] + !OrdTab(1:2,08)=[0,1] + !OrdTab(1:2,09)=[1,1] + + OrdTab(1:2,01)=[0,0] + OrdTab(1:2,02)=[2,0] + OrdTab(1:2,03)=[2,2] + OrdTab(1:2,04)=[0,2] + OrdTab(1:2,05)=[1,0] + OrdTab(1:2,06)=[2,1] + OrdTab(1:2,07)=[1,2] + OrdTab(1:2,08)=[0,1] + OrdTab(1:2,09)=[1,1] + print '("Input Mesh Gmf HO Order")' - do i=1,size(orderingSpace,2) - print '(3x,"uv(",i2.2,")=",2(i2,1x))',i,orderingMesh(1:2,i) + do i=1,size(OrdTab,2) + print '(3x,"uv(",i2.2,")=",2(i2,1x))',i,OrdTab(1:2,i) enddo - !res=GmfSetHONodesOrdering(InpMsh,GmfCell,orderingSpace,orderingMesh) - res=GmfSetHONodesOrderingF77(InpMsh,GmfCell,orderingSpace,orderingMesh) + res=GmfSetHONodesOrderingF90(unit=InpMsh,GmfKey=GmfCell,BasTab=BasTab,OrdTab=OrdTab) end block endif @@ -138,7 +149,8 @@ program test_libmeshb_HO_f90 & GmfCell ,& & 1 ,& & NmbQad ,& - & 0, m ,& + ! 0, m ,& + & 0, c_null_ptr ,& & QadTab(1,1), QadTab(1,NmbQad),& & QadRef( 1), QadRef( NmbQad) ) @@ -176,8 +188,8 @@ program test_libmeshb_HO_f90 TriTab(3,iTria) = QadTab(7,i) TriTab(4,iTria) = QadTab(5,i) TriTab(5,iTria) = QadTab(8,i) - TriTab(6,iTria) = QadTab(5,i) - TriRef( iTria) = QadRef( i) + TriTab(6,iTria) = QadTab(4,i) + TriRef( iTria) = QadRef( i) enddo !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< @@ -199,7 +211,7 @@ program test_libmeshb_HO_f90 if( OutMsh==0 ) STOP ' OutMsh = 0' ! Set the number of vertices - res=GmfSetKwd(OutMsh, GmfVertices, NmbVer) + res=GmfSetKwdF90(unit=OutMsh, GmfKey=GmfVertices, Nmb=NmbVer) print '( "Output Mesh NmbVer: ",i0)', NmbVer ! Write them down using separate pointers for each scalar entry @@ -207,23 +219,25 @@ program test_libmeshb_HO_f90 & OutMsh ,& & 1 ,& & NmbVer ,& - & 0, m ,& + ! 0, m ,& + & 0, c_null_ptr ,& & VerTab(1,1), VerTab(1,NmbVer),& & VerRef( 1), VerRef( NmbVer) ) ! Write the triangles using 4 independant set of arguments ! for each scalar entry: node1, node2, node3 and reference - res=GmfSetKwd(OutMsh, GmfTrianglesP2, NmbTri) + res=GmfSetKwdF90(unit=OutMsh, GmfKey=GmfTrianglesP2, Nmb=NmbTri) print '( "Output Mesh NmbTri: ",i0)', NmbTri - res = GmfSetElements( & - & OutMsh ,& - & GmfTrianglesP2 ,& - & 1 ,& - & NmbTri ,& - & 0, m ,& - & TriTab(1,1), TriTab(1,NmbTri),& - & TriRef( 1), TriRef( NmbTri) ) + res=GmfSetElements( & + & OutMsh ,& + & GmfTrianglesP2 ,& + & 1 ,& + & NmbTri ,& + & 0, c_null_ptr ,& + ! 0, m ,& + & TriTab(1,1), TriTab(1,NmbTri),& + & TriRef( 1), TriRef( NmbTri) ) ! Don't forget to close the file res=GmfCloseMeshf77(OutMsh) diff --git a/examples/test_libmeshb_block.f90 b/examples/test_libmeshb_block.f90 index c025a11..0b1b751 100644 --- a/examples/test_libmeshb_block.f90 +++ b/examples/test_libmeshb_block.f90 @@ -6,6 +6,7 @@ program test_libmeshb_block_f90 !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> use iso_fortran_env use libmeshb7 + use, intrinsic :: iso_c_binding, only: c_int,c_long,c_loc,c_ptr,c_null_ptr !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> implicit none @@ -15,7 +16,6 @@ program test_libmeshb_block_f90 character(80) :: SolFile integer :: i integer :: NmbVer,NmbQad,NmbTri,ver,dim,res - real(real64) :: sol(1:10) real(real64), pointer :: VerTab(:,:) integer , pointer :: VerRef( :) integer , pointer :: QadTab(:,:),QadRef( :) @@ -38,43 +38,73 @@ program test_libmeshb_block_f90 print '(/"Input Mesh Open : ",a )',trim(InpFile) ! Open the mesh file and check the version and dimension - InpMsh = GmfOpenMeshf77(trim(InpFile),GmfRead,ver,dim) + call GmfOpenMeshF90(name=trim(InpFile),unit=InpMsh,GmfKey=GmfRead,ver=ver,dim=dim) + print '( "Input Mesh Idx : ",i0)',InpMsh print '( "Input Mesh ver : ",i0)',ver print '( "Input Mesh dim : ",i0)',dim ! Allocate VerRef - NmbVer = GmfStatKwd(InpMsh, GmfVertices) + NmbVer = GmfstatkwdF90(unit=InpMsh, GmfKey=GmfVertices) print '( "Input Mesh NmbVer : ",i0)', NmbVer allocate(VerTab(1:3,1:NmbVer)) allocate(VerRef( 1:NmbVer)) ! Read the vertices using a vector of 3 consecutive doubles to store the coordinates - res=GmfGetVertices( & - & InpMsh ,& - & 1 ,& - & NmbVer ,& - & 0, m ,& - & VerTab(1,1), VerTab(1,NmbVer) ,& - & VerRef( 1), VerRef( NmbVer) ) + !res=GmfGetVertices( & + !& InpMsh ,& + !& 1 ,& + !& NmbVer ,& + !& 0, m ,& + !& VerTab(1,1), VerTab(1,NmbVer) ,& + !& VerRef( 1), VerRef( NmbVer) ) + + !res=GmfGetVertices( & + !& InpMsh ,& + !& 1 ,& + !& NmbVer ,& + !& 0, c_null_ptr ,& + !& VerTab(1,1), VerTab(1,NmbVer) ,& + !& VerRef( 1), VerRef( NmbVer) ) + + res=GmfGetBlockF90( & + & unit=InpMsh ,& + & GmfKey=GmfVertices ,& + & ad0=1 ,& + & ad1=NmbVer ,& + & Tab=VerTab(:,1:NmbVer) ,& + & Ref=VerRef( 1:NmbVer) ) + ! Allocate QadTab - NmbQad=GmfStatKwd(InpMsh, GmfQuadrilaterals) + NmbQad=GmfstatkwdF90(unit=InpMsh, GmfKey=GmfQuadrilaterals) print '( "Input Mesh NmbQad : ",i0)', NmbQad allocate(QadTab(1:4,1:NmbQad)) allocate(QadRef( 1:NmbQad)) ! Read the quads using one single vector of 4 consecutive integers - res=GmfGetElements( & - & InpMsh ,& - & GmfQuadrilaterals ,& - & 1 ,& - & NmbQad ,& - & 0, m ,& - & QadTab(1,1), QadTab(1,NmbQad) ,& - & QadRef( 1), QadRef( NmbQad) ) + !res=GmfGetElements( & + !& InpMsh ,& + !& GmfQuadrilaterals ,& + !& 1 ,& + !& NmbQad ,& + !& 0, c_null_ptr ,& + !& QadTab(1,1), QadTab(1,NmbQad) ,& + !& QadRef( 1), QadRef( NmbQad) ) + + res=GmfGetBlockF90( & + & unit=InpMsh ,& + & GmfKey=GmfQuadrilaterals,& + & ad0=1 ,& + & ad1=NmbQad ,& + & Tab=QadTab(:,1:) ,& + & Ref=QadRef( 1:) ) + do i=1,10 + print '(3x,"qad",i6," nd:",4(i6,1x)," ref: ",i0)',i,QadTab(1:4,i),QadRef(i) + enddo + !!> Lecture par tableau 1D sans recopie !block ! use iso_c_binding, only: c_loc,c_f_pointer @@ -93,7 +123,7 @@ program test_libmeshb_block_f90 !end block ! Close the quadrilateral mesh - res=GmfCloseMeshf77(InpMsh) + res=GmfCloseMeshF90(unit=InpMsh) print '("Input Mesh Close : ",a)',trim(InpFile) !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< @@ -123,38 +153,61 @@ program test_libmeshb_block_f90 ! Write a triangular mesh print '(/"Output Mesh Open : ",a )',trim(OutFile) - OutMsh = GmfOpenMeshf77(trim(OutFile), GmfWrite, ver, dim) + call GmfOpenMeshF90(name=trim(OutFile),unit=OutMsh,GmfKey=GmfWrite,ver=ver,dim=dim) + print '( "Output Mesh Idx : ",i0)',InpMsh print '( "Output Mesh ver : ",i0)',ver print '( "Output Mesh dim : ",i0)',dim if(OutMsh==0) STOP ' OutMsh = 0' ! Set the number of vertices - res=GmfSetKwd(OutMsh, GmfVertices, NmbVer) + res=GmfSetKwdF90(unit=OutMsh, GmfKey=GmfVertices, Nmb=NmbVer) print '( "Output Mesh NmbVer : ",i0)', NmbVer ! Write them down using separate pointers for each scalar entry - res=GmfSetVertices( & - & OutMsh ,& - & 1 ,& - & NmbVer ,& - & 0, m ,& - & VerTab(1,1), VerTab(1,NmbVer),& - & VerRef( 1), VerRef( NmbVer) ) + !res=GmfSetVertices( & + !& OutMsh ,& + !& 1 ,& + !& NmbVer ,& + !& 0, c_null_ptr ,& + !& VerTab(1,1), VerTab(1,NmbVer),& + !& VerRef( 1), VerRef( NmbVer) ) + !res=GmfGetBlockF90_2( & + !& unit=OutMsh ,& + !& GmfKey=GmfVertices ,& + !& ad0=1 ,& + !& ad1=NmbVer ,& + !& dTab0=VerTab(1,1) ,& + !& dTab1=VerTab(1,NmbVer),& + !& iRef0=VerRef(1) ,& + !& iRef1=VerRef(NmbVer) ) + + !res=GmfGetBlockF90( & + !& unit=OutMsh ,& + !& GmfKey=GmfVertices ,& + !& ad0=1 ,& + !& ad1=NmbVer ,& + !& dTab=VerTab(:,1:NmbVer),& + !& iRef=VerRef( 1:NmbVer) ) + + !function GmfGetBlockF90_02(unit, GmfKey, ad0, ad1, iTab, iRef) result(res) + + ! Write the triangles using 4 independant set of arguments ! for each scalar entry: node1, node2, node3 and reference - res=GmfSetKwd(OutMsh, GmfTriangles, NmbTri) + res=GmfSetKwdF90(unit=OutMsh, GmfKey=GmfTriangles, Nmb=NmbTri) print '( "Output Mesh NmbTri : ",i0)', NmbTri - res = GmfSetElements( & - & OutMsh ,& - & GmfTriangles ,& - & 1 ,& - & NmbTri ,& - & 0, m ,& - & TriTab(1,1), TriTab(1,NmbTri),& - & TriRef( 1), TriRef( NmbTri) ) + !res=GmfSetElements( & + !& OutMsh ,& + !& GmfTriangles ,& + !& 1 ,& + !& NmbTri ,& + !! 0, m ,& + !& 0, c_null_ptr ,& + !& TriTab(1,1), TriTab(1,NmbTri),& + !& TriRef( 1), TriRef( NmbTri) ) !!> Ecriture par tableau 1D sans recopie !block @@ -177,14 +230,15 @@ program test_libmeshb_block_f90 ! & GmfTriangles ,& ! & 1 ,& ! & NmbTri ,& - ! & 0, m ,& + ! ! 0, m ,& + ! & 0, c_null_ptr ,& ! & nodes( 1), nodes(3*NmbTri-2),& ! & TriRef( 1), TriRef(NmbTri) ) ! !end block ! Don't forget to close the file - res=GmfCloseMeshf77(OutMsh) + res=GmfCloseMeshF90(unit=OutMsh) print '("Output Mesh Close : ",a)',trim(OutFile) !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< diff --git a/sources/libmeshb7_mod.f90 b/sources/libmeshb7_mod.f90 index b6c3cfa..e64840c 100644 --- a/sources/libmeshb7_mod.f90 +++ b/sources/libmeshb7_mod.f90 @@ -14,7 +14,7 @@ module libmeshb7 use iso_fortran_env - use, intrinsic :: iso_c_binding, only: c_int,c_long,c_loc,c_ptr + use, intrinsic :: iso_c_binding, only: c_int,c_long,c_loc,c_ptr,c_null_ptr implicit none @@ -25,34 +25,23 @@ module libmeshb7 external gmfsetkwdf77 external gmfgotokwdf77 external gmfsethonodesorderingf77 - external gmfgetvertex - external gmfsetvertex - external gmfgetelement - external gmfsetelement - external gmfgetvertices - external gmfsetvertices - external gmfgetelements - external gmfsetelements - external gmfgetsolution - external gmfsetsolution + external gmfgetlinef77 + external gmfsetlinef77 + external gmfgetblockf77 + external gmfsetblockf77 integer(int64) gmfopenmeshf77 integer(int32) gmfclosemeshf77 integer(int32) GmfStatKwdf77 integer(int32) gmfsetkwdf77 integer(int32) gmfgotokwdf77 - integer(int32) gmfsethonodesorderingf77 - integer(int32) gmfgetvertex - integer(int32) gmfsetvertex - integer(int32) gmfgetelement - integer(int32) gmfsetelement - integer(int32) gmfgetvertices - integer(int32) gmfsetvertices - integer(int32) gmfgetelements - integer(int32) gmfsetelements - integer(int32) gmfgetsolution - integer(int32) gmfsetsolution - + integer(int32) gmfsethonodesorderingf77 + integer(int32) gmfgetlinef77 + integer(int32) gmfsetlinef77 + integer(int32) gmfgetblockf77 + integer(int32) gmfsetblockf77 + + ! Parameters definition integer(int32), parameter :: gmfmaxtyp=1000 integer(int32), parameter :: gmfmaxkwd=227 @@ -303,49 +292,107 @@ module libmeshb7 integer(int32), parameter :: gmfquadrialteralsongeometryfaces=226 integer(int32), parameter :: gmfmeshongeometry=227 - interface GmfStatKwd - module procedure GmfStatKwdf77_0 - module procedure GmfStatKwdf77_1 - end interface GmfStatKwd + interface GmfStatKwdF90 + module procedure GmfStatKwdF90_0 + module procedure GmfStatKwdF90_1 + end interface GmfStatKwdF90 + + interface GmfSetKwdF90 + module procedure GmfSetKwdF90_0 + module procedure GmfSetKwdF90_1 + end interface GmfSetKwdF90 + + interface GmfGetLineF90 + module procedure GmfGetLineF90_i + module procedure GmfGetLineF90_d + end interface GmfGetLineF90 + + interface GmfSetLineF90 + module procedure GmfSetLineF90_i + module procedure GmfSetLineF90_d + module procedure GmfSetLineF90_sol_i + module procedure GmfSetLineF90_sol_d + end interface GmfSetLineF90 + + + + interface GmfGetBlockF90 + module procedure GmfGetBlockF90_00 + module procedure GmfGetBlockF90_01 + module procedure GmfGetBlockF90_02 + end interface GmfGetBlockF90 + - interface GmfSetKwd - module procedure GmfSetKwdF77_0 - module procedure GmfSetKwdF77_1 - end interface - contains - function GmfStatKwdf77_0(unit, GmfKey) result(res) + subroutine GmfOpenMeshF90(name, unit, GmfKey, ver, dim) + !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + character(*) , intent(in) :: name + integer(int64), intent(out) :: unit + integer(int32), intent(in) :: GmfKey + integer(int32), intent(inout) :: ver + integer(int32), intent(inout) :: dim + !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + unit = GmfOpenMeshf77(trim(name), GmfKey, ver, dim) + !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + return + end subroutine GmfOpenMeshF90 + + function GmfCloseMeshF90(unit) result(res) + !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + integer(int64) :: unit + integer(int32) :: res + !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + res=GmfCloseMeshF77(unit) + !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + return + end function GmfCloseMeshF90 + + function GmfStatKwdF90_0(unit, GmfKey) result(res) !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> integer(int64) :: unit integer(int32) :: GmfKey integer(int32) :: Nmb + integer(int32) :: res !> integer(int32) :: t(1),d,ho,s - integer(int32) :: res !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> res = GmfStatKwdf77(unit, GmfKey, 0, 0, t(1), 0, 0) !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< return - end function GmfStatKwdf77_0 + end function GmfStatKwdF90_0 - function GmfStatKwdf77_1(unit, GmfKey, r, s, t, d, ho) result(res) + function GmfStatKwdF90_1(unit, GmfKey, r, s, t, d, ho) result(res) !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> integer(int64) :: unit integer(int32) :: GmfKey integer(int32) :: Nmb + integer(int32) :: res !> - integer(int32) :: r,s,t(*),d,ho + integer(int32) :: r,s,t(:),d,ho + !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + res = GmfStatKwdf77(unit, GmfKey, r, s, t(1), d, ho) + !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + return + end function GmfStatKwdF90_1 + + function GmfGotoKwdF90(unit, GmfKey) result(res) + !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + integer(int64) :: unit + integer(int32) :: GmfKey integer(int32) :: res !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - res = GmfStatKwdf77(unit, GmfKey, r, s, t, d, ho) + res=GmfgotokwdF77(unit, GmfKey) !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< return - end function GmfStatKwdf77_1 + end function GmfGotoKwdF90 - function GmfSetKwdF77_0(unit, GmfKey, Nmb) result(res) + function GmfSetKwdF90_0(unit, GmfKey, Nmb) result(res) !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> integer(int64) :: unit integer(int32) :: GmfKey @@ -358,14 +405,14 @@ function GmfSetKwdF77_0(unit, GmfKey, Nmb) result(res) res = GmfSetKwdF77(unit, GmfKey, Nmb, 0, t(1), 0, ho) !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< return - end function GmfSetKwdF77_0 + end function GmfSetKwdF90_0 - function GmfSetKwdF77_1(unit, GmfKey, Nmb, d, t, s, ho) result(res) + function GmfSetKwdF90_1(unit, GmfKey, Nmb, d, t, s, ho) result(res) !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> integer(int64) :: unit integer(int32) :: GmfKey integer(int32) :: Nmb - integer(int32) :: t(*) + integer(int32) :: t(:) integer(int32) :: d,ho,s integer(int32) :: res !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< @@ -373,6 +420,358 @@ function GmfSetKwdF77_1(unit, GmfKey, Nmb, d, t, s, ho) result(res) res = GmfSetKwdF77(unit, GmfKey, Nmb, d, t, s, ho) !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< return - end function GmfSetKwdF77_1 + end function GmfSetKwdF90_1 + + function GmfSetHONodesOrderingF90(unit, GmfKey, BasTab, OrdTab) result(res) + !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + integer(int64) :: unit + integer(int32) :: GmfKey + integer(int32) :: BasTab(:,:) + integer(int32) :: OrdTab(:,:) + integer(int32) :: res + !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + res=GmfSetHONodesOrderingF77(unit,GmfKey,BasTab,OrdTab) + !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + return + end function GmfSetHONodesOrderingF90 + + function GmfGetLineF90_i(unit, GmfKey, Tab, Ref) result(res) + !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + !> Reading Nodes and Ref + !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + integer(int64) :: unit + integer(int32) :: GmfKey + integer(int32) :: Tab(:) + integer(int32) :: Ref + integer(int32) :: res + !> + real(real64) :: dTab(1) + !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + res=GmfGetLineF77(unit, GmfKey, Tab(1), dTab(1), Ref) + !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + return + end function GmfGetLineF90_i + + function GmfGetLineF90_d(unit, GmfKey, Tab, Ref) result(res) + !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + !> Reading Vertices and Ref + !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + integer(int64) :: unit + integer(int32) :: GmfKey + real(real64) :: Tab(:) + integer(int32) :: Ref + integer(int32) :: res + !> + integer(int32) :: iTab(1) + !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + res=GmfGetLineF77(unit, GmfKey, iTab(1), Tab(1), Ref) + !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + return + !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + end function GmfGetLineF90_d + + function GmfSetLineF90_i(unit, GmfKey, Tab, Ref) result(res) + !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + !> Writting Nodes and Ref + !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + integer(int64) :: unit + integer(int32) :: GmfKey + integer(int32) :: Tab(:) + integer(int32) :: Ref + integer(int32) :: res + !> + real(real64) :: dTab(1) + !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + res=GmfSetLineF77(unit, GmfKey, Tab(1), dTab(1), Ref) + !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + return + end function GmfSetLineF90_i + + function GmfSetLineF90_d(unit, GmfKey, Tab, Ref) result(res) + !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + !> Writting Vertices and Ref + !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + integer(int64) :: unit + integer(int32) :: GmfKey + real(real64) :: Tab(:) + integer(int32) :: Ref + integer(int32) :: res + !> + integer(int32) :: iTab(1) + !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + res=GmfSetLineF77(unit, GmfKey, iTab(1), Tab(1), Ref) + !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + return + end function GmfSetLineF90_d + + function GmfSetLineF90_sol_i(unit, GmfKey, iTab) result(res) + !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + !> Writting Nodes and Ref + !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + integer(int64) :: unit + integer(int32) :: GmfKey + integer(int32) :: iTab(:) + integer(int32) :: iRef + integer(int32) :: res + !> + real(real64) :: dTab(1) + !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + res=GmfSetLineF77(unit, GmfKey, iTab(1), dTab(1), iRef) + !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + return + end function GmfSetLineF90_sol_i + + function GmfSetLineF90_sol_d(unit, GmfKey, dTab) result(res) + !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + !> Writting Vertices and Ref + !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + integer(int64) :: unit + integer(int32) :: GmfKey + real(real64) :: dTab(:) + integer(int32) :: res + !> + integer(int32) :: iRef + integer(int32) :: iTab(1) + !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + res=GmfSetLineF77(unit, GmfKey, iTab(1), dTab(1), iRef) + !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + return + end function GmfSetLineF90_sol_d + + !> GmfGetBlicF77(idx,kwd, int beginIdx, int endIdx, int int(:,:), real(8) (:,:) , ref(:) ) + !> GmfSetBlicF77(idx,kwd, int beginIdx, int endIdx, int int(:,:), real(8) (:,:) , ref(:) ) + + function GmfGetBlockF90_00(unit, GmfKey, ad0, ad1, iTab, dTab, Ref) result(res) + !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + integer(int64) :: unit + integer(int32) :: GmfKey + integer(int32) :: ad0 + integer(int32) :: ad1 + integer(int32) :: iTab(:,:) + real(real64) :: dTab(:,:) + integer(int32) :: Ref( :) + integer(int32) :: res + !> + integer(int32) :: Nmb + !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + Nmb=ad1-ad0+1 + + res=GmfGetBlockF77(unit ,& + & GmfKey ,& + & ad0 ,& + & ad1 ,& + & 0 ,& + & c_null_ptr ,& + & iTab(:, 1),& + & iTab(:,Nmb),& + & dTab(:, 1),& + & dTab(:,Nmb),& + & Ref( 1),& + & Ref( Nmb) ) + !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + return + end function GmfGetBlockF90_00 + + function GmfGetBlockF90_01(unit, GmfKey, ad0, ad1, Tab, Ref) result(res) + !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + integer(int64) :: unit + integer(int32) :: GmfKey + integer(int32) :: ad0 + integer(int32) :: ad1 + integer(int32) :: Tab(:,:) + integer(int32) :: Ref( :) + integer(int32) :: res + !> + integer(int32) :: Nmb + real(real64) :: dTab(1,1) + !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + + Nmb=ad1-ad0+1 + + print '("GmfGetBlockF90_01 (ad0,ad1)=(",i0,",",i0,") Nmb=",i0)',ad0,ad1,Nmb + print '("GmfGetBlockF90_01 size(Tab)=",i0,"x",i0)',size(Tab,1),size(Tab,2) + print '("GmfGetBlockF90_01 size(Ref)= ",i0)',size(Ref) + + res=GmfGetBlockF77(unit ,& + & GmfKey ,& + & ad0 ,& + & ad1 ,& + & 0 ,& + & c_null_ptr ,& + & Tab(1, 1) ,& + & Tab(1,Nmb) ,& + & dTab(1,1) ,& + & dTab(1,1) ,& + & Ref( 1) ,& + & Ref( Nmb) ) + !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + return + end function GmfGetBlockF90_01 + + function GmfGetBlockF90_02(unit, GmfKey, ad0, ad1, Tab, Ref) result(res) + !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + integer(int64) :: unit + integer(int32) :: GmfKey + integer(int32) :: ad0 + integer(int32) :: ad1 + real(real64) :: Tab(:,:) + integer(int32) :: Ref( :) + integer(int32) :: res + !> + integer(int32) :: iTab(1,1) + integer(int32) :: Nmb + !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + Nmb=ad1-ad0+1 + + res=GmfGetBlockF77(unit,GmfKey,& + & ad0 ,& + & ad1 ,& + & 0 ,& + & c_null_ptr ,& + & iTab(1, 1),& + & iTab(1, 1),& + & Tab(:, 1),& + & Tab(:,Nmb),& + & Ref( 1),& + & Ref( Nmb) ) + !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + return + end function GmfGetBlockF90_02 + + !function GmfGetBlockF90_0(unit, GmfKey, ad0, ad1, iTab0, iTab1, dTab0, dTab1, iRef0, iRef1) result(res) + ! !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + ! integer(int64) :: unit + ! integer(int32) :: GmfKey + ! integer(int32) :: ad0 + ! integer(int32) :: ad1 + ! integer(int32) :: iTab0(:,:) + ! integer(int32) :: iTab1(:,:) + ! real(real64) :: dTab0(:,:) + ! real(real64) :: dTab1(:,:) + ! integer(int32) :: iRef0( :) + ! integer(int32) :: iRef1( :) + ! integer(int32) :: res + ! !> + ! !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + ! !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + ! res=GmfGetBlockF77(unit ,& + ! & GmfKey ,& + ! & ad0 ,& + ! & ad1 ,& + ! & 0 ,& + ! & c_null_ptr ,& + ! & iTab0 ,& + ! & iTab1 ,& + ! & dTab0 ,& + ! & dTab1 ,& + ! & iRef0 ,& + ! & iRef1 ) + ! + ! !int APIF77(gmfsetblockf77)(int64_t *MshIdx, int *kwd, int *BegIdx, int *EndIdx, + ! ! int *MapTyp, int *MatTab, int *BegInt, int *EndInt, + ! ! double *BegDbl, double *EndDbl, int *BegRef, int *EndRef) + ! + ! !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + ! return + !end function GmfGetBlockF90_0 + ! + !function GmfGetBlockF90_1(unit, GmfKey, ad0, ad1, iTab0, iTab1, iRef0, iRef1) result(res) + ! !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + ! integer(int64) :: unit + ! integer(int32) :: GmfKey + ! integer(int32) :: ad0 + ! integer(int32) :: ad1 + ! integer(int32) :: iTab0(:,:) + ! integer(int32) :: iTab1(:,:) + ! integer(int32) :: iRef0( :) + ! integer(int32) :: iRef1( :) + ! integer(int32) :: res + ! !> + ! real(real64) :: dTab0(1,1) + ! real(real64) :: dTab1(1,1) + ! !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + ! !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + ! res=GmfGetBlockF77(unit ,& + ! & GmfKey ,& + ! & ad0 ,& + ! & ad1 ,& + ! & 0 ,& + ! & c_null_ptr ,& + ! & iTab0 ,& + ! & iTab1 ,& + ! & dTab0 ,& + ! & dTab1 ,& + ! & iRef0 ,& + ! & iRef1 ) + ! !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + ! return + !end function GmfGetBlockF90_1 + ! + !function GmfGetBlockF90_2(unit, GmfKey, ad0, ad1, dTab0, dTab1, iRef0, iRef1) result(res) + ! !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + ! integer(int64) :: unit + ! integer(int32) :: GmfKey + ! integer(int32) :: ad0 + ! integer(int32) :: ad1 + ! real(real64) :: dTab0(:,:) + ! real(real64) :: dTab1(:,:) + ! integer(int32) :: iRef0( :) + ! integer(int32) :: iRef1( :) + ! integer(int32) :: res + ! !> + ! integer(int32) :: iTab0(1,1) + ! integer(int32) :: iTab1(1,1) + ! !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + ! !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + ! res=GmfGetBlockF77(unit ,& + ! & GmfKey ,& + ! & ad0 ,& + ! & ad1 ,& + ! & 0 ,& + ! & c_null_ptr ,& + ! & iTab0 ,& + ! & iTab1 ,& + ! & dTab0 ,& + ! & dTab1 ,& + ! & iRef0 ,& + ! & iRef1 ) + ! !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + ! return + !end function GmfGetBlockF90_2 + + + + + + + + + !> GmfGetLineF77(idx,kwd, int int(:,:), real(8) (:,:) , ref(:) ) + !> GmfSetLineF77(idx,kwd, int int(:,:), real(8) (:,:) , ref(:) ) + + !> GmfGetLineF90(idx) + !> GmfSetLineF90(idx) + + !> GmfGetBlockF77(idx,kwd, int beginIdx, int endIdx, int int(:,:), real(8) (:,:) , ref(:) ) + !> GmfSetBlockF77(idx,kwd, int beginIdx, int endIdx, int int(:,:), real(8) (:,:) , ref(:) ) + + !> GmfGetBlockF90 + !> GmfSetBlockF90 end module libmeshb7 \ No newline at end of file From 482b1602f9278589ab7e0cb3b325c39ba1e2bfe3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Mar=C3=A9chal?= Date: Mon, 26 Feb 2024 13:47:57 +0100 Subject: [PATCH 30/38] Adde block access to the new Fortran API --- examples/test_libmeshb_block.f | 28 ++++++----- sources/libmeshb7.c | 88 ++++++++++++++++++++++++++++++---- 2 files changed, 94 insertions(+), 22 deletions(-) diff --git a/examples/test_libmeshb_block.f b/examples/test_libmeshb_block.f index 84b4f13..90640eb 100644 --- a/examples/test_libmeshb_block.f +++ b/examples/test_libmeshb_block.f @@ -8,9 +8,9 @@ parameter (n=4000) integer i, ver, dim, res, NmbVer, NmbQad +, RefTab(n), TriTab(4,2*n), QadTab(5,n) - integer t(1),d,ho,s - integer*8 InpMsh, OutMsh, m(1) - real*8 VerTab(3,n) + integer t(1),d,ho,s, fooint(1) + integer*8 InpMsh, OutMsh + real*8 VerTab(3,n),foodbl(1) c -------------------------------------------- @@ -39,15 +39,17 @@ c Read the vertices using a vector of 3 consecutive doubles c to store the coordinates - res = gmfgetvertices(InpMsh, - + 1, NmbVer, 0, m, + res = gmfgetblockf77(InpMsh, GmfVertices, + + 1, NmbVer, 0, fooint(1), + + fooint(1), fooint(1), + VerTab(1,1), VerTab(1,NmbVer), + RefTab( 1), RefTab( NmbVer)) c Read the quads using one single vector of 5 consecutive integers - res = gmfgetelements(InpMsh, GmfQuadrilaterals, - + 1, NmbQad, 0, m, + res = gmfgetblockf77(InpMsh, GmfQuadrilaterals, + + 1, NmbQad, 0, fooint(1), + QadTab(1,1), QadTab(1,NmbQad), + + foodbl(1), foodbl(1), + QadTab(5,1), QadTab(5,NmbQad)) c Close the quadrilateral mesh @@ -84,17 +86,19 @@ res = gmfsetkwdf77(OutMsh, GmfVertices, NmbVer, 0, t, 0, ho) c Write them down using separate pointers for each scalar entry - res = gmfsetvertices(OutMsh, - + 1, NmbVer, 0, m, + res = gmfsetblockf77(OutMsh, GmfVertices, + + 1, NmbVer, 0, fooint(1), + + fooint(1), fooint(1), + VerTab(1,1), VerTab(1,NmbVer), + RefTab(1), RefTab(NmbVer)) c Write the triangles using 4 independant set of arguments c for each scalar entry: node1, node2, node3 and reference res = gmfsetkwdf77(OutMsh, GmfTriangles, 2*NmbQad, 0, t, 0, ho) - res = gmfsetelements(OutMsh, GmfTriangles, - + 1, 2*NmbQad, 0, m, + res = gmfsetblockf77(OutMsh, GmfTriangles, + + 1, 2*NmbQad, 0, fooint(1), + TriTab(1,1), TriTab(1,2*NmbQad), + + foodbl(1), foodbl(1), + TriTab(4,1), TriTab(4,2*NmbQad)) c Don't forget to close the file @@ -103,4 +107,4 @@ print*, 'output mesh :',NmbVer,' vertices,', + 2*NmbQad,'triangles' - end + end diff --git a/sources/libmeshb7.c b/sources/libmeshb7.c index 0f4c7d9..6a98e2f 100644 --- a/sources/libmeshb7.c +++ b/sources/libmeshb7.c @@ -3459,18 +3459,86 @@ int APIF77(gmfsetlinef77)(int64_t *MshIdx, int *kwd, int *i, double *d, int *r) return(GmfSetLin(*MshIdx, -*kwd, i, d, r)); } -int APIF77(gmfgetblockf77)(int64_t *MshIdx, int *kwd, int *BegIdx, int *EndIdx, - int *MapTyp, int *MatTab, int *BegInt, int *EndInt, - double *BegDbl, double *EndDbl, int *BegRef, int *EndRef) +int APIF77(gmfgetblockf77)(int64_t *MshIdx, int *KwdCod, + int *BegIdx, int *EndIdx, + int *MapTyp, int *MatTab, + int *BegInt, int *EndInt, + double *BegDbl, double *EndDbl, + int *BegRef, int *EndRef) { - return(GmfGetBlock( *MshIdx, -*kwd, *BegIdx, *EndIdx, *MapTyp, MatTab, - NULL, BegInt, EndInt, BegDbl, EndDbl, BegRef, EndRef )); + int i, TypTab[ MaxArg ], SizTab[ MaxArg ]; + char *BegTab[ MaxArg ], *EndTab[ MaxArg ]; + GmfMshSct *msh = (GmfMshSct *)*MshIdx; + KwdSct *kwd = &msh->KwdTab[ *KwdCod ]; + + for(i=0;iSolSiz;i++) + { + if(kwd->fmt[i] == 'i') + { + TypTab[i] = GmfInt; + SizTab[i] = 1; + + if( (NmbEleNod[ *KwdCod ]) && (i == kwd->SolSiz-1) ) + { + BegTab[i] = (char *)BegRef; + EndTab[i] = (char *)EndRef; + } + else + { + BegTab[i] = (char *)&BegInt[i]; + EndTab[i] = (char *)&EndInt[i]; + } + }else if(kwd->fmt[i] == 'r') + { + TypTab[i] = GmfDouble; + SizTab[i] = 1; + BegTab[i] = (char *)&BegDbl[i]; + EndTab[i] = (char *)&EndDbl[i]; + } + } + + return(GmfGetBlock( *MshIdx, *KwdCod, *BegIdx, *EndIdx, *MapTyp, MatTab, + NULL, GmfArgTab, TypTab, SizTab, BegTab, EndTab )); } -int APIF77(gmfsetblockf77)(int64_t *MshIdx, int *kwd, int *BegIdx, int *EndIdx, - int *MapTyp, int *MatTab, int *BegInt, int *EndInt, - double *BegDbl, double *EndDbl, int *BegRef, int *EndRef) +int APIF77(gmfsetblockf77)(int64_t *MshIdx, int *KwdCod, + int *BegIdx, int *EndIdx, + int *MapTyp, int *MatTab, + int *BegInt, int *EndInt, + double *BegDbl, double *EndDbl, + int *BegRef, int *EndRef) { - return(GmfSetBlock( *MshIdx, -*kwd, *BegIdx, *EndIdx, *MapTyp, MatTab, - NULL, BegInt, EndInt, BegDbl, EndDbl, BegRef, EndRef )); + int i, TypTab[ MaxArg ], SizTab[ MaxArg ]; + char *BegTab[ MaxArg ], *EndTab[ MaxArg ]; + GmfMshSct *msh = (GmfMshSct *)*MshIdx; + KwdSct *kwd = &msh->KwdTab[ *KwdCod ]; + + for(i=0;iSolSiz;i++) + { + if(kwd->fmt[i] == 'i') + { + TypTab[i] = GmfInt; + SizTab[i] = 1; + + if( (NmbEleNod[ *KwdCod ]) && (i == kwd->SolSiz-1) ) + { + BegTab[i] = (char *)BegRef; + EndTab[i] = (char *)EndRef; + } + else + { + BegTab[i] = (char *)&BegInt[i]; + EndTab[i] = (char *)&EndInt[i]; + } + }else if(kwd->fmt[i] == 'r') + { + TypTab[i] = GmfDouble; + SizTab[i] = 1; + BegTab[i] = (char *)&BegDbl[i]; + EndTab[i] = (char *)&EndDbl[i]; + } + } + + return(GmfSetBlock( *MshIdx, *KwdCod, *BegIdx, *EndIdx, *MapTyp, MatTab, + NULL, GmfArgTab, TypTab, SizTab, BegTab, EndTab )); } From 57343cd55d9e6d5a902349a4d125ad3aa8544050 Mon Sep 17 00:00:00 2001 From: Christophe Peyret Date: Mon, 26 Feb 2024 19:26:35 +0100 Subject: [PATCH 31/38] =?UTF-8?q?Lecture=20=C3=A9criture=20par=20bloc=20:?= =?UTF-8?q?=20mise=20au=20point=20du=20module=20fortran90=20et=20de=20l'ex?= =?UTF-8?q?emple=20correspondant?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- examples/test_libmeshb.f90 | 10 +- examples/test_libmeshb_block.f90 | 104 +++------- sources/libmeshb7_mod.f90 | 316 ++++++++++++++----------------- 3 files changed, 173 insertions(+), 257 deletions(-) diff --git a/examples/test_libmeshb.f90 b/examples/test_libmeshb.f90 index ea4ff73..0bfcef8 100644 --- a/examples/test_libmeshb.f90 +++ b/examples/test_libmeshb.f90 @@ -37,15 +37,15 @@ program test_libmeshb_f90 !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> InpFile='../sample_meshes/quad.mesh' - OutFile='./tri.meshb' - SolFile='./tri.solb' + OutFile='./tri.mesh' + SolFile='./tri.sol' !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ! Open the quadrilateral mesh file for reading print '(/"Input Mesh Open : ",a )',trim(InpFile) - call GmfOpenMeshF90(name=trim(InpFile),unit=InpMsh,GmfKey=GmfRead,ver=ver,dim=dim) + InpMsh=GmfOpenMeshF90(name=trim(InpFile),GmfKey=GmfRead,ver=ver,dim=dim) print '( "Input Mesh Idx : ",i0)',InpMsh print '( "Input Mesh ver : ",i0)',ver @@ -90,7 +90,7 @@ program test_libmeshb_f90 print '(/"Output Mesh Open : ",a )',trim(OutFile) - call GmfOpenMeshF90(name=trim(OutFile),unit=OutMsh,GmfKey=GmfWrite,ver=ver,dim=dim) + OutMsh=GmfOpenMeshF90(name=trim(OutFile),GmfKey=GmfWrite,ver=ver,dim=dim) print '( "Output Mesh Idx : ",i0)',InpMsh print '( "Output Mesh ver : ",i0)',ver @@ -128,7 +128,7 @@ program test_libmeshb_f90 print '(/"Output Solu Open : ",a )',trim(SolFile) - call GmfOpenMeshF90(name=trim(SolFile),unit=OutSol,GmfKey=GmfWrite,ver=ver,dim=dim) + OutSol=GmfOpenMeshF90(name=trim(SolFile),GmfKey=GmfWrite,ver=ver,dim=dim) print '( "Output Solu Idx : ",i0)',OutSol print '( "Output Solu ver : ",i0)',ver diff --git a/examples/test_libmeshb_block.f90 b/examples/test_libmeshb_block.f90 index 0b1b751..31c68b8 100644 --- a/examples/test_libmeshb_block.f90 +++ b/examples/test_libmeshb_block.f90 @@ -1,4 +1,3 @@ - ! libMeshb 7.79 example: transform a quadrilateral mesh into a triangular one ! using fast block transfer @@ -38,7 +37,7 @@ program test_libmeshb_block_f90 print '(/"Input Mesh Open : ",a )',trim(InpFile) ! Open the mesh file and check the version and dimension - call GmfOpenMeshF90(name=trim(InpFile),unit=InpMsh,GmfKey=GmfRead,ver=ver,dim=dim) + InpMsh=GmfOpenMeshF90(name=trim(InpFile),GmfKey=GmfRead,ver=ver,dim=dim) print '( "Input Mesh Idx : ",i0)',InpMsh print '( "Input Mesh ver : ",i0)',ver @@ -49,24 +48,8 @@ program test_libmeshb_block_f90 print '( "Input Mesh NmbVer : ",i0)', NmbVer allocate(VerTab(1:3,1:NmbVer)) allocate(VerRef( 1:NmbVer)) - - ! Read the vertices using a vector of 3 consecutive doubles to store the coordinates - !res=GmfGetVertices( & - !& InpMsh ,& - !& 1 ,& - !& NmbVer ,& - !& 0, m ,& - !& VerTab(1,1), VerTab(1,NmbVer) ,& - !& VerRef( 1), VerRef( NmbVer) ) - - !res=GmfGetVertices( & - !& InpMsh ,& - !& 1 ,& - !& NmbVer ,& - !& 0, c_null_ptr ,& - !& VerTab(1,1), VerTab(1,NmbVer) ,& - !& VerRef( 1), VerRef( NmbVer) ) + ! Read the vertices using a vector of 3 consecutive doubles to store the coordinates res=GmfGetBlockF90( & & unit=InpMsh ,& & GmfKey=GmfVertices ,& @@ -75,6 +58,9 @@ program test_libmeshb_block_f90 & Tab=VerTab(:,1:NmbVer) ,& & Ref=VerRef( 1:NmbVer) ) + do i=1,10 + print '(3x,"ver",i6," xyz:",3(f12.5,1x)," ref: ",i0)',i,VerTab(1:3,i),VerRef(i) + enddo ! Allocate QadTab NmbQad=GmfstatkwdF90(unit=InpMsh, GmfKey=GmfQuadrilaterals) @@ -82,17 +68,7 @@ program test_libmeshb_block_f90 allocate(QadTab(1:4,1:NmbQad)) allocate(QadRef( 1:NmbQad)) - ! Read the quads using one single vector of 4 consecutive integers - - !res=GmfGetElements( & - !& InpMsh ,& - !& GmfQuadrilaterals ,& - !& 1 ,& - !& NmbQad ,& - !& 0, c_null_ptr ,& - !& QadTab(1,1), QadTab(1,NmbQad) ,& - !& QadRef( 1), QadRef( NmbQad) ) - + ! Read the quads using one single vector of 4 consecutive integers res=GmfGetBlockF90( & & unit=InpMsh ,& & GmfKey=GmfQuadrilaterals,& @@ -104,8 +80,8 @@ program test_libmeshb_block_f90 do i=1,10 print '(3x,"qad",i6," nd:",4(i6,1x)," ref: ",i0)',i,QadTab(1:4,i),QadRef(i) enddo - - !!> Lecture par tableau 1D sans recopie + + !!> Lecture par tableau 1D sans recopie (interface à écrire en indiquand le stride) !block ! use iso_c_binding, only: c_loc,c_f_pointer ! integer , pointer :: nodes(:) @@ -153,7 +129,7 @@ program test_libmeshb_block_f90 ! Write a triangular mesh print '(/"Output Mesh Open : ",a )',trim(OutFile) - call GmfOpenMeshF90(name=trim(OutFile),unit=OutMsh,GmfKey=GmfWrite,ver=ver,dim=dim) + OutMsh=GmfOpenMeshF90(name=trim(OutFile),GmfKey=GmfWrite,ver=ver,dim=dim) print '( "Output Mesh Idx : ",i0)',InpMsh print '( "Output Mesh ver : ",i0)',ver @@ -164,52 +140,29 @@ program test_libmeshb_block_f90 res=GmfSetKwdF90(unit=OutMsh, GmfKey=GmfVertices, Nmb=NmbVer) print '( "Output Mesh NmbVer : ",i0)', NmbVer - ! Write them down using separate pointers for each scalar entry - !res=GmfSetVertices( & - !& OutMsh ,& - !& 1 ,& - !& NmbVer ,& - !& 0, c_null_ptr ,& - !& VerTab(1,1), VerTab(1,NmbVer),& - !& VerRef( 1), VerRef( NmbVer) ) + ! Write them down using separate pointers for each scalar entry + res=GmfSetBlockF90( & + & unit=OutMsh ,& + & GmfKey=GmfVertices ,& + & ad0=1 ,& + & ad1=NmbVer ,& + & Tab=VerTab(:,1:NmbVer),& + & Ref=VerRef( 1:NmbVer) ) - !res=GmfGetBlockF90_2( & - !& unit=OutMsh ,& - !& GmfKey=GmfVertices ,& - !& ad0=1 ,& - !& ad1=NmbVer ,& - !& dTab0=VerTab(1,1) ,& - !& dTab1=VerTab(1,NmbVer),& - !& iRef0=VerRef(1) ,& - !& iRef1=VerRef(NmbVer) ) - - !res=GmfGetBlockF90( & - !& unit=OutMsh ,& - !& GmfKey=GmfVertices ,& - !& ad0=1 ,& - !& ad1=NmbVer ,& - !& dTab=VerTab(:,1:NmbVer),& - !& iRef=VerRef( 1:NmbVer) ) - - !function GmfGetBlockF90_02(unit, GmfKey, ad0, ad1, iTab, iRef) result(res) - - ! Write the triangles using 4 independant set of arguments ! for each scalar entry: node1, node2, node3 and reference res=GmfSetKwdF90(unit=OutMsh, GmfKey=GmfTriangles, Nmb=NmbTri) print '( "Output Mesh NmbTri : ",i0)', NmbTri - - !res=GmfSetElements( & - !& OutMsh ,& - !& GmfTriangles ,& - !& 1 ,& - !& NmbTri ,& - !! 0, m ,& - !& 0, c_null_ptr ,& - !& TriTab(1,1), TriTab(1,NmbTri),& - !& TriRef( 1), TriRef( NmbTri) ) - - !!> Ecriture par tableau 1D sans recopie + + res=GmfSetBlockF90( & + & unit=OutMsh ,& + & GmfKey=GmfTriangles ,& + & ad0=1 ,& + & ad1=NmbTri ,& + & Tab=TriTab(:,1:NmbTri),& + & Ref=TriRef( 1:NmbVer) ) + + !!> Ecriture par tableau 1D sans recopie (interface fortran à écrire) !block ! use iso_c_binding, only: c_loc,c_f_pointer ! integer , pointer :: nodes(:) @@ -253,5 +206,4 @@ program test_libmeshb_block_f90 print '(/"Constrol"/"vizir4 -in ",a/)',trim(OutFile) !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< -end program test_libmeshb_block_f90 - +end program test_libmeshb_block_f90 \ No newline at end of file diff --git a/sources/libmeshb7_mod.f90 b/sources/libmeshb7_mod.f90 index e64840c..29242b9 100644 --- a/sources/libmeshb7_mod.f90 +++ b/sources/libmeshb7_mod.f90 @@ -18,7 +18,7 @@ module libmeshb7 implicit none - !Procedures definition + ! Procedures definition external gmfopenmeshf77 external gmfclosemeshf77 external GmfStatKwdf77 @@ -314,30 +314,33 @@ module libmeshb7 module procedure GmfSetLineF90_sol_d end interface GmfSetLineF90 - - interface GmfGetBlockF90 - module procedure GmfGetBlockF90_00 + !module procedure GmfGetBlockF90_00 module procedure GmfGetBlockF90_01 module procedure GmfGetBlockF90_02 end interface GmfGetBlockF90 + interface GmfSetBlockF90 + !module procedure GmfGetBlockF90_00 + module procedure GmfSetBlockF90_01 + module procedure GmfSetBlockF90_02 + end interface GmfSetBlockF90 contains - - subroutine GmfOpenMeshF90(name, unit, GmfKey, ver, dim) + + function GmfOpenMeshF90(name, GmfKey, ver, dim) result(unit) !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> character(*) , intent(in) :: name - integer(int64), intent(out) :: unit integer(int32), intent(in) :: GmfKey integer(int32), intent(inout) :: ver integer(int32), intent(inout) :: dim + integer(int64) :: unit !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> unit = GmfOpenMeshf77(trim(name), GmfKey, ver, dim) !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< return - end subroutine GmfOpenMeshF90 + end function GmfOpenMeshF90 function GmfCloseMeshF90(unit) result(res) !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> @@ -550,22 +553,20 @@ function GmfSetLineF90_sol_d(unit, GmfKey, dTab) result(res) !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< return end function GmfSetLineF90_sol_d - - !> GmfGetBlicF77(idx,kwd, int beginIdx, int endIdx, int int(:,:), real(8) (:,:) , ref(:) ) - !> GmfSetBlicF77(idx,kwd, int beginIdx, int endIdx, int int(:,:), real(8) (:,:) , ref(:) ) - + function GmfGetBlockF90_00(unit, GmfKey, ad0, ad1, iTab, dTab, Ref) result(res) !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - integer(int64) :: unit - integer(int32) :: GmfKey - integer(int32) :: ad0 - integer(int32) :: ad1 - integer(int32) :: iTab(:,:) - real(real64) :: dTab(:,:) - integer(int32) :: Ref( :) - integer(int32) :: res + integer(int64), intent(in) :: unit + integer(int32), intent(in) :: GmfKey + integer(int32), intent(in) :: ad0 + integer(int32), intent(in) :: ad1 + integer(int32), intent(inout) :: iTab(:,:) + real(real64) , intent(inout) :: dTab(:,:) + integer(int32), intent(inout) :: Ref( :) + integer(int32) :: res !> - integer(int32) :: Nmb + integer(int32) :: Nmb + integer(int32), pointer :: map(:)=>null() !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Nmb=ad1-ad0+1 @@ -574,30 +575,32 @@ function GmfGetBlockF90_00(unit, GmfKey, ad0, ad1, iTab, dTab, Ref) result(r & GmfKey ,& & ad0 ,& & ad1 ,& - & 0 ,& - & c_null_ptr ,& - & iTab(:, 1),& - & iTab(:,Nmb),& - & dTab(:, 1),& - & dTab(:,Nmb),& + & int32 ,& + & map ,& + & iTab(1, 1),& + & iTab(1,Nmb),& + & dTab(1, 1),& + & dTab(1,Nmb),& & Ref( 1),& & Ref( Nmb) ) !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< return end function GmfGetBlockF90_00 - + function GmfGetBlockF90_01(unit, GmfKey, ad0, ad1, Tab, Ref) result(res) !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - integer(int64) :: unit - integer(int32) :: GmfKey - integer(int32) :: ad0 - integer(int32) :: ad1 - integer(int32) :: Tab(:,:) - integer(int32) :: Ref( :) - integer(int32) :: res + integer(int64), intent(in) :: unit + integer(int32), intent(in) :: GmfKey + integer(int32), intent(in) :: ad0 + integer(int32), intent(in) :: ad1 + integer(int32), intent(inout) :: Tab(:,:) + integer(int32), intent(inout) :: Ref( :) + integer(int32) :: res !> - integer(int32) :: Nmb - real(real64) :: dTab(1,1) + integer(int32) :: Nmb + real(real64) :: dTab(1) + integer(int32), pointer :: map(:)=>null() + !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> @@ -611,167 +614,128 @@ function GmfGetBlockF90_01(unit, GmfKey, ad0, ad1, Tab, Ref) result(res) & GmfKey ,& & ad0 ,& & ad1 ,& - & 0 ,& - & c_null_ptr ,& + & int32 ,& + & map ,& & Tab(1, 1) ,& & Tab(1,Nmb) ,& - & dTab(1,1) ,& - & dTab(1,1) ,& + & dTab(1) ,& + & dTab(1) ,& & Ref( 1) ,& & Ref( Nmb) ) !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< return end function GmfGetBlockF90_01 - + function GmfGetBlockF90_02(unit, GmfKey, ad0, ad1, Tab, Ref) result(res) !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - integer(int64) :: unit - integer(int32) :: GmfKey - integer(int32) :: ad0 - integer(int32) :: ad1 - real(real64) :: Tab(:,:) - integer(int32) :: Ref( :) - integer(int32) :: res + integer(int64), intent(in) :: unit + integer(int32), intent(in) :: GmfKey + integer(int32), intent(in) :: ad0 + integer(int32), intent(in) :: ad1 + real(real64) , intent(inout) :: Tab(:,:) + integer(int32), intent(inout) :: Ref( :) + integer(int32) :: res !> - integer(int32) :: iTab(1,1) + integer(int32) :: iTab(1) integer(int32) :: Nmb + integer(int32), pointer :: map(:)=>null() !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Nmb=ad1-ad0+1 - res=GmfGetBlockF77(unit,GmfKey,& + print '("GmfGetBlockF90_02 (ad0,ad1)=(",i0,",",i0,") Nmb=",i0)',ad0,ad1,Nmb + print '("GmfGetBlockF90_02 size(Tab)=",i0,"x",i0)',size(Tab,1),size(Tab,2) + print '("GmfGetBlockF90_02 size(Ref)= ",i0)',size(Ref) + + res=GmfGetBlockF77(unit ,& + & GmfKey ,& & ad0 ,& & ad1 ,& - & 0 ,& - & c_null_ptr ,& - & iTab(1, 1),& - & iTab(1, 1),& - & Tab(:, 1),& - & Tab(:,Nmb),& - & Ref( 1),& - & Ref( Nmb) ) + & int32 ,& + & map ,& + & iTab(1) ,& + & iTab(1) ,& + & Tab(1, 1) ,& + & Tab(1,Nmb) ,& + & Ref( 1) ,& + & Ref( Nmb) ) !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< return end function GmfGetBlockF90_02 - !function GmfGetBlockF90_0(unit, GmfKey, ad0, ad1, iTab0, iTab1, dTab0, dTab1, iRef0, iRef1) result(res) - ! !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - ! integer(int64) :: unit - ! integer(int32) :: GmfKey - ! integer(int32) :: ad0 - ! integer(int32) :: ad1 - ! integer(int32) :: iTab0(:,:) - ! integer(int32) :: iTab1(:,:) - ! real(real64) :: dTab0(:,:) - ! real(real64) :: dTab1(:,:) - ! integer(int32) :: iRef0( :) - ! integer(int32) :: iRef1( :) - ! integer(int32) :: res - ! !> - ! !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - ! !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - ! res=GmfGetBlockF77(unit ,& - ! & GmfKey ,& - ! & ad0 ,& - ! & ad1 ,& - ! & 0 ,& - ! & c_null_ptr ,& - ! & iTab0 ,& - ! & iTab1 ,& - ! & dTab0 ,& - ! & dTab1 ,& - ! & iRef0 ,& - ! & iRef1 ) - ! - ! !int APIF77(gmfsetblockf77)(int64_t *MshIdx, int *kwd, int *BegIdx, int *EndIdx, - ! ! int *MapTyp, int *MatTab, int *BegInt, int *EndInt, - ! ! double *BegDbl, double *EndDbl, int *BegRef, int *EndRef) - ! - ! !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - ! return - !end function GmfGetBlockF90_0 - ! - !function GmfGetBlockF90_1(unit, GmfKey, ad0, ad1, iTab0, iTab1, iRef0, iRef1) result(res) - ! !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - ! integer(int64) :: unit - ! integer(int32) :: GmfKey - ! integer(int32) :: ad0 - ! integer(int32) :: ad1 - ! integer(int32) :: iTab0(:,:) - ! integer(int32) :: iTab1(:,:) - ! integer(int32) :: iRef0( :) - ! integer(int32) :: iRef1( :) - ! integer(int32) :: res - ! !> - ! real(real64) :: dTab0(1,1) - ! real(real64) :: dTab1(1,1) - ! !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - ! !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - ! res=GmfGetBlockF77(unit ,& - ! & GmfKey ,& - ! & ad0 ,& - ! & ad1 ,& - ! & 0 ,& - ! & c_null_ptr ,& - ! & iTab0 ,& - ! & iTab1 ,& - ! & dTab0 ,& - ! & dTab1 ,& - ! & iRef0 ,& - ! & iRef1 ) - ! !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - ! return - !end function GmfGetBlockF90_1 - ! - !function GmfGetBlockF90_2(unit, GmfKey, ad0, ad1, dTab0, dTab1, iRef0, iRef1) result(res) - ! !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - ! integer(int64) :: unit - ! integer(int32) :: GmfKey - ! integer(int32) :: ad0 - ! integer(int32) :: ad1 - ! real(real64) :: dTab0(:,:) - ! real(real64) :: dTab1(:,:) - ! integer(int32) :: iRef0( :) - ! integer(int32) :: iRef1( :) - ! integer(int32) :: res - ! !> - ! integer(int32) :: iTab0(1,1) - ! integer(int32) :: iTab1(1,1) - ! !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - ! !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - ! res=GmfGetBlockF77(unit ,& - ! & GmfKey ,& - ! & ad0 ,& - ! & ad1 ,& - ! & 0 ,& - ! & c_null_ptr ,& - ! & iTab0 ,& - ! & iTab1 ,& - ! & dTab0 ,& - ! & dTab1 ,& - ! & iRef0 ,& - ! & iRef1 ) - ! !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - ! return - !end function GmfGetBlockF90_2 - - - - + function GmfSetBlockF90_01(unit, GmfKey, ad0, ad1, Tab, Ref) result(res) + !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + integer(int64), intent(in) :: unit + integer(int32), intent(in) :: GmfKey + integer(int32), intent(in) :: ad0 + integer(int32), intent(in) :: ad1 + integer(int32), intent(inout) :: Tab(:,:) + integer(int32), intent(inout) :: Ref( :) + integer(int32) :: res + !> + integer(int32) :: Nmb + real(real64) :: dTab(1) + integer(int32), pointer :: map(:)=>null() + !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + Nmb=ad1-ad0+1 + + print '("GmfSetBlockF90_01 (ad0,ad1)=(",i0,",",i0,") Nmb=",i0)',ad0,ad1,Nmb + print '("GmfSetBlockF90_01 size(Tab)=",i0,"x",i0)',size(Tab,1),size(Tab,2) + print '("GmfSetBlockF90_01 size(Ref)= ",i0)',size(Ref) + + res=GmfSetBlockF77(unit ,& + & GmfKey ,& + & ad0 ,& + & ad1 ,& + & int32 ,& + & map ,& + & Tab(1, 1) ,& + & Tab(1,Nmb) ,& + & dTab(1) ,& + & dTab(1) ,& + & Ref( 1) ,& + & Ref( Nmb) ) + !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + return + end function GmfSetBlockF90_01 + function GmfSetBlockF90_02(unit, GmfKey, ad0, ad1, Tab, Ref) result(res) + !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + integer(int64), intent(in) :: unit + integer(int32), intent(in) :: GmfKey + integer(int32), intent(in) :: ad0 + integer(int32), intent(in) :: ad1 + real(real64) , intent(inout) :: Tab(:,:) + integer(int32), intent(inout) :: Ref( :) + integer(int32) :: res + !> + integer(int32) :: iTab(1) + integer(int32) :: Nmb + integer(int32), pointer :: map(:)=>null() + !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + Nmb=ad1-ad0+1 + + print '("GmfSetBlockF90_02 (ad0,ad1)=(",i0,",",i0,") Nmb=",i0)',ad0,ad1,Nmb + print '("GmfSetBlockF90_02 size(Tab)=",i0,"x",i0)',size(Tab,1),size(Tab,2) + print '("GmfSetBlockF90_02 size(Ref)= ",i0)',size(Ref) + + res=GmfSetBlockF77(unit ,& + & GmfKey ,& + & ad0 ,& + & ad1 ,& + & int32 ,& + & map ,& + & iTab(1) ,& + & iTab(1) ,& + & Tab(1, 1) ,& + & Tab(1,Nmb) ,& + & Ref( 1) ,& + & Ref( Nmb) ) + !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + return + end function GmfSetBlockF90_02 - - !> GmfGetLineF77(idx,kwd, int int(:,:), real(8) (:,:) , ref(:) ) - !> GmfSetLineF77(idx,kwd, int int(:,:), real(8) (:,:) , ref(:) ) - - !> GmfGetLineF90(idx) - !> GmfSetLineF90(idx) - - !> GmfGetBlockF77(idx,kwd, int beginIdx, int endIdx, int int(:,:), real(8) (:,:) , ref(:) ) - !> GmfSetBlockF77(idx,kwd, int beginIdx, int endIdx, int int(:,:), real(8) (:,:) , ref(:) ) - - !> GmfGetBlockF90 - !> GmfSetBlockF90 - end module libmeshb7 \ No newline at end of file From 8064fa2023a83e4ae5186732457f2e8f82339f30 Mon Sep 17 00:00:00 2001 From: Christophe Peyret Date: Mon, 26 Feb 2024 20:01:20 +0100 Subject: [PATCH 32/38] =?UTF-8?q?Ajout=20=C3=A9criture=20solution=20par=20?= =?UTF-8?q?block?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- examples/test_libmeshb_block.f90 | 96 +++++++++++++++++++++++++++----- sources/libmeshb7_mod.f90 | 86 ++++++++++++++++++++++++++-- 2 files changed, 162 insertions(+), 20 deletions(-) diff --git a/examples/test_libmeshb_block.f90 b/examples/test_libmeshb_block.f90 index 31c68b8..7a20487 100644 --- a/examples/test_libmeshb_block.f90 +++ b/examples/test_libmeshb_block.f90 @@ -9,17 +9,20 @@ program test_libmeshb_block_f90 !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> implicit none - integer(8) :: InpMsh, OutMsh, m(1) - character(80) :: InpFile - character(80) :: OutFile - character(80) :: SolFile - integer :: i - integer :: NmbVer,NmbQad,NmbTri,ver,dim,res - real(real64), pointer :: VerTab(:,:) - integer , pointer :: VerRef( :) - integer , pointer :: QadTab(:,:),QadRef( :) - integer , pointer :: TriTab(:,:),TriRef( :) - integer :: t(1),d,ho,s + integer(int64) :: InpMsh, OutMsh, OutSol + character(80) :: InpFile + character(80) :: OutFile + character(80) :: SolFile + integer :: i + integer :: NmbVer,NmbQad,NmbTri,ver,dim,res + real(real64) , pointer :: VerTab(:,:) + integer , pointer :: VerRef( :) + integer , pointer :: QadTab(:,:),QadRef( :) + integer , pointer :: TriTab(:,:),TriRef( :) + integer(int32) :: NmbField,ho,s,d + integer(int32), pointer :: fields(:) + character(32) , pointer :: fieldsName(:)=>null() + real(real64) , pointer :: solTab(:,:) !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> @@ -28,8 +31,8 @@ program test_libmeshb_block_f90 !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> InpFile='../sample_meshes/quad.mesh' - OutFile='./tri.mesh' - SolFile='./tri.sol' + OutFile='./tri.meshb' + SolFile='./tri.solb' !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> @@ -153,7 +156,7 @@ program test_libmeshb_block_f90 ! for each scalar entry: node1, node2, node3 and reference res=GmfSetKwdF90(unit=OutMsh, GmfKey=GmfTriangles, Nmb=NmbTri) print '( "Output Mesh NmbTri : ",i0)', NmbTri - + res=GmfSetBlockF90( & & unit=OutMsh ,& & GmfKey=GmfTriangles ,& @@ -195,15 +198,78 @@ program test_libmeshb_block_f90 print '("Output Mesh Close : ",a)',trim(OutFile) !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + ! Create a solution file + + print '(/"Output Solu Open : ",a )',trim(SolFile) + + OutSol=GmfOpenMeshF90(name=trim(SolFile),GmfKey=GmfWrite,ver=ver,dim=dim) + + print '( "Output Solu Idx : ",i0)',OutSol + print '( "Output Solu ver : ",i0)',ver + print '( "Output Solu dim : ",i0)',dim + if( OutSol==0 ) STOP ' OutSol = 0' + + ! Set the solution kinds + NmbField=3 + allocate( fields (1:NmbField)) + allocate( fieldsName(1:NmbField)) + fields(1:NmbField) = [GmfSca,GmfVec,GmfSca] + fieldsName(1:NmbField)=['sca_1','vec_1','sca_2'] + + !nomDesChamps : block + ! integer :: iField,nChar + ! character(:), pointer :: fieldName=>null() + ! res=GmfSetKwdF90(unit=OutSol, GmfKey=GmfReferenceStrings, Nmb=NmbField) + ! do iField=1,NmbField + ! nChar=len_trim(fieldsName(iField)) ! print '("nChar: ",i0)',nChar + ! allocate(character(len=nChar+3) :: fieldName) + ! write(fieldName,'(a,1x,i0,a)')trim(fieldsName(iField)),iField,C_NULL_CHAR + ! print '("fieldName: ",a)',fieldName + ! + ! !ress=GmfSetLin(unit=OutSol, GmfKey=GmfReferenceStrings, GmfSolAtVertices, 1, fieldName) + ! + ! deallocate(fieldName) + ! enddo + !end block nomDesChamps + + allocate(solTab(1:5,NmbVer)) ! 1+ dim+ 1 + print '( "Output Solu NmbVer : ",i0)',NmbVer + print '( "Output Solu nFields : ",i0)',NmbField + print '( "Output Solu fields : ", *(i0,1x))',fields(1:NmbField) + + ! Set the number of solutions (one per vertex) + res=GmfSetKwdF90(unit=OutSol, GmfKey=GmfSolAtVertices, Nmb=NmbVer, d=NmbField, t=fields(1:NmbField), s=0, ho=ho) + + ! Compute the dummy solution fields + do i=1,NmbVer + solTab( 1,i)=VerTab(1,i) + solTab(2:4,i)=[VerTab(1,i),VerTab(2,i),0d0] + solTab( 5,i)=VerTab(2,i) + enddo + + res=GmfSetBlockF90( & + & unit=OutMsh ,& + & GmfKey=GmfSolAtVertices ,& + & ad0=1 ,& + & ad1=NmbVer ,& + & Tab=solTab(:,1:NmbVer) ) + + ! Don't forget to close the file + res=GmfCloseMeshF90(unit=OutSol) + print '("Output Solu Close : ",a)',trim(SolFile) + !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> !> Cleanning Memory deallocate(VerTab,VerRef) deallocate(QadTab,QadRef) deallocate(TriTab,TriRef) + deallocate(solTab) !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - print '(/"Constrol"/"vizir4 -in ",a/)',trim(OutFile) + print '(/"Constrol"/"vizir4 -in ",a," -sol ",a,/)',trim(OutFile),trim(SolFile) !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< end program test_libmeshb_block_f90 \ No newline at end of file diff --git a/sources/libmeshb7_mod.f90 b/sources/libmeshb7_mod.f90 index 29242b9..41dc559 100644 --- a/sources/libmeshb7_mod.f90 +++ b/sources/libmeshb7_mod.f90 @@ -316,14 +316,16 @@ module libmeshb7 interface GmfGetBlockF90 !module procedure GmfGetBlockF90_00 - module procedure GmfGetBlockF90_01 - module procedure GmfGetBlockF90_02 + module procedure GmfGetBlockF90_01 !> nodes + ref + module procedure GmfGetBlockF90_02 !> vertices + ref + module procedure GmfGetBlockF90_03 !> solutions end interface GmfGetBlockF90 interface GmfSetBlockF90 !module procedure GmfGetBlockF90_00 - module procedure GmfSetBlockF90_01 - module procedure GmfSetBlockF90_02 + module procedure GmfSetBlockF90_01 !> nodes + ref + module procedure GmfSetBlockF90_02 !> vertices + ref + module procedure GmfSetBlockF90_03 !> solutions end interface GmfSetBlockF90 contains @@ -663,6 +665,43 @@ function GmfGetBlockF90_02(unit, GmfKey, ad0, ad1, Tab, Ref) result(res) return end function GmfGetBlockF90_02 + function GmfGetBlockF90_03(unit, GmfKey, ad0, ad1, Tab) result(res) + !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + integer(int64), intent(in) :: unit + integer(int32), intent(in) :: GmfKey + integer(int32), intent(in) :: ad0 + integer(int32), intent(in) :: ad1 + real(real64) , intent(inout) :: Tab(:,:) + integer(int32) :: res + !> + integer(int32) :: Ref (1) + integer(int32) :: iTab(1) + integer(int32) :: Nmb + integer(int32), pointer :: map(:)=>null() + !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + Nmb=ad1-ad0+1 + + print '("GmfGetBlockF90_03 (ad0,ad1)=(",i0,",",i0,") Nmb=",i0)',ad0,ad1,Nmb + print '("GmfGetBlockF90_03 size(Tab)=",i0,"x",i0)',size(Tab,1),size(Tab,2) + print '("GmfGetBlockF90_03 size(Ref)= ",i0)',size(Ref) + + res=GmfGetBlockF77(unit ,& + & GmfKey ,& + & ad0 ,& + & ad1 ,& + & int32 ,& + & map ,& + & iTab(1) ,& + & iTab(1) ,& + & Tab(1, 1) ,& + & Tab(1,Nmb) ,& + & Ref( 1) ,& + & Ref( 1) ) + !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + return + end function GmfGetBlockF90_03 + function GmfSetBlockF90_01(unit, GmfKey, ad0, ad1, Tab, Ref) result(res) !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> integer(int64), intent(in) :: unit @@ -700,7 +739,7 @@ function GmfSetBlockF90_01(unit, GmfKey, ad0, ad1, Tab, Ref) result(res) !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< return end function GmfSetBlockF90_01 - + function GmfSetBlockF90_02(unit, GmfKey, ad0, ad1, Tab, Ref) result(res) !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> integer(int64), intent(in) :: unit @@ -738,4 +777,41 @@ function GmfSetBlockF90_02(unit, GmfKey, ad0, ad1, Tab, Ref) result(res) return end function GmfSetBlockF90_02 + function GmfSetBlockF90_03(unit, GmfKey, ad0, ad1, Tab) result(res) + !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + integer(int64), intent(in) :: unit + integer(int32), intent(in) :: GmfKey + integer(int32), intent(in) :: ad0 + integer(int32), intent(in) :: ad1 + real(real64) , intent(inout) :: Tab(:,:) + integer(int32) :: res + !> + integer(int32) :: Ref(1) + integer(int32) :: iTab(1) + integer(int32) :: Nmb + integer(int32), pointer :: map(:)=>null() + !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + Nmb=ad1-ad0+1 + + print '("GmfSetBlockF90_03 (ad0,ad1)=(",i0,",",i0,") Nmb=",i0)',ad0,ad1,Nmb + print '("GmfSetBlockF90_03 size(Tab)=",i0,"x",i0)',size(Tab,1),size(Tab,2) + print '("GmfSetBlockF90_03 size(Ref)= ",i0)',size(Ref) + + res=GmfSetBlockF77(unit ,& + & GmfKey ,& + & ad0 ,& + & ad1 ,& + & int32 ,& + & map ,& + & iTab( 1) ,& + & iTab( 1) ,& + & Tab(1, 1) ,& + & Tab(1,Nmb) ,& + & Ref( 1) ,& + & Ref( 1) ) + !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + return + end function GmfSetBlockF90_03 + end module libmeshb7 \ No newline at end of file From f7e3a1ca8677fca402f4bf86e12de0cacdfb50bc Mon Sep 17 00:00:00 2001 From: Christophe Peyret Date: Mon, 26 Feb 2024 20:04:30 +0100 Subject: [PATCH 33/38] ajout commentaires dans module fortran 90 --- sources/libmeshb7_mod.f90 | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/sources/libmeshb7_mod.f90 b/sources/libmeshb7_mod.f90 index 41dc559..ae3837e 100644 --- a/sources/libmeshb7_mod.f90 +++ b/sources/libmeshb7_mod.f90 @@ -293,13 +293,13 @@ module libmeshb7 integer(int32), parameter :: gmfmeshongeometry=227 interface GmfStatKwdF90 - module procedure GmfStatKwdF90_0 - module procedure GmfStatKwdF90_1 + module procedure GmfStatKwdF90_0 !> vertices & nodes + module procedure GmfStatKwdF90_1 !> solutions end interface GmfStatKwdF90 interface GmfSetKwdF90 - module procedure GmfSetKwdF90_0 - module procedure GmfSetKwdF90_1 + module procedure GmfSetKwdF90_0 !> vertices & nodes + module procedure GmfSetKwdF90_1 !> solutions end interface GmfSetKwdF90 interface GmfGetLineF90 @@ -315,14 +315,14 @@ module libmeshb7 end interface GmfSetLineF90 interface GmfGetBlockF90 - !module procedure GmfGetBlockF90_00 + !module procedure GmfGetBlockF90_00 module procedure GmfGetBlockF90_01 !> nodes + ref module procedure GmfGetBlockF90_02 !> vertices + ref module procedure GmfGetBlockF90_03 !> solutions end interface GmfGetBlockF90 interface GmfSetBlockF90 - !module procedure GmfGetBlockF90_00 + !module procedure GmfGetBlockF90_00 module procedure GmfSetBlockF90_01 !> nodes + ref module procedure GmfSetBlockF90_02 !> vertices + ref module procedure GmfSetBlockF90_03 !> solutions From 768ed808d3f627f072dde2204d05a0ed7b687611 Mon Sep 17 00:00:00 2001 From: Christophe Peyret Date: Mon, 26 Feb 2024 20:10:10 +0100 Subject: [PATCH 34/38] =?UTF-8?q?=C3=A9criture=20plus=20compacte=20du=20mo?= =?UTF-8?q?dule=20fortran?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sources/libmeshb7_mod.f90 | 37 +++++++++++++------------------------ 1 file changed, 13 insertions(+), 24 deletions(-) diff --git a/sources/libmeshb7_mod.f90 b/sources/libmeshb7_mod.f90 index ae3837e..0eb8519 100644 --- a/sources/libmeshb7_mod.f90 +++ b/sources/libmeshb7_mod.f90 @@ -19,29 +19,18 @@ module libmeshb7 implicit none ! Procedures definition - external gmfopenmeshf77 - external gmfclosemeshf77 - external GmfStatKwdf77 - external gmfsetkwdf77 - external gmfgotokwdf77 - external gmfsethonodesorderingf77 - external gmfgetlinef77 - external gmfsetlinef77 - external gmfgetblockf77 - external gmfsetblockf77 - - integer(int64) gmfopenmeshf77 - integer(int32) gmfclosemeshf77 - integer(int32) GmfStatKwdf77 - integer(int32) gmfsetkwdf77 - integer(int32) gmfgotokwdf77 - integer(int32) gmfsethonodesorderingf77 - integer(int32) gmfgetlinef77 - integer(int32) gmfsetlinef77 - integer(int32) gmfgetblockf77 - integer(int32) gmfsetblockf77 - - + integer(int64) , external :: gmfopenmeshf77 + integer(int32) , external :: gmfclosemeshf77 + integer(int32) , external :: GmfStatKwdf77 + integer(int32) , external :: gmfsetkwdf77 + integer(int32) , external :: gmfgotokwdf77 + integer(int32) , external :: gmfsethonodesorderingf77 + integer(int32) , external :: gmfgetlinef77 + integer(int32) , external :: gmfsetlinef77 + integer(int32) , external :: gmfgetblockf77 + integer(int32) , external :: gmfsetblockf77 + + ! Parameters definition integer(int32), parameter :: gmfmaxtyp=1000 integer(int32), parameter :: gmfmaxkwd=227 @@ -329,7 +318,7 @@ module libmeshb7 end interface GmfSetBlockF90 contains - + function GmfOpenMeshF90(name, GmfKey, ver, dim) result(unit) !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> character(*) , intent(in) :: name From 91f5c2b824a867b1d67d5b181224e0ff15a82636 Mon Sep 17 00:00:00 2001 From: Christophe Peyret Date: Mon, 26 Feb 2024 21:31:31 +0100 Subject: [PATCH 35/38] =?UTF-8?q?Pr=C3=A9paration=20=C3=A9criture=20par=20?= =?UTF-8?q?block=20en=20fortran=2090?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- examples/test_libmeshb_HO.f90 | 155 +++++++++++++------------------ examples/test_libmeshb_block.f90 | 3 +- sources/libmeshb7_mod.f90 | 56 +++++++++-- 3 files changed, 112 insertions(+), 102 deletions(-) diff --git a/examples/test_libmeshb_HO.f90 b/examples/test_libmeshb_HO.f90 index 862c31d..5c31a07 100644 --- a/examples/test_libmeshb_HO.f90 +++ b/examples/test_libmeshb_HO.f90 @@ -5,7 +5,6 @@ program test_libmeshb_HO_f90 !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> use iso_fortran_env - use, intrinsic :: iso_c_binding, only: c_null_ptr use libmeshb7 !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> @@ -30,7 +29,7 @@ program test_libmeshb_HO_f90 !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> InpFile='../sample_meshes/quad_q2.mesh' - OutFile='./tri_p2.mesh' + OutFile='./tri_p2f.mesh' SolFile='./tri_p2.sol' !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< @@ -39,7 +38,7 @@ program test_libmeshb_HO_f90 print '(/"Input Mesh File : ",a )',trim(InpFile) ! Open the mesh file and check the version and dimension - InpMsh = GmfOpenMeshf77(trim(InpFile),GmfRead,ver,dim) + InpMsh=GmfOpenMeshF90(name=trim(InpFile),GmfKey=GmfRead,ver=ver,dim=dim) print '( "Input Mesh Idx : ",i0)',InpMsh print '( "Input Mesh ver : ",i0)',ver print '( "Input Mesh dim : ",i0)',dim @@ -55,15 +54,17 @@ program test_libmeshb_HO_f90 allocate(VerTab(1:3,1:NmbVer)) allocate(VerRef( 1:NmbVer)) - res=GmfGetVertices( & - & InpMsh ,& - & 1 ,& - & NmbVer ,& - ! 0, m ,& - & 0, c_null_ptr ,& - & VerTab(1,1), VerTab(1,NmbVer) ,& - & VerRef( 1), VerRef( NmbVer) ) + res=GmfGetBlockF90( & + & unit=InpMsh ,& + & GmfKey=GmfVertices ,& + & ad0=1 ,& + & ad1=NmbVer ,& + & Tab=VerTab(:,1:NmbVer) ,& + & Ref=VerRef( 1:NmbVer) ) + do i=1,10 + print '(3x,"ver",i6," xyz:",3(f12.5,1x)," ref: ",i0)',i,VerTab(1:3,i),VerRef(i) + enddo ! Read GmfQuadrilateralsQ2 GmfCell=GmfQuadrilateralsQ2 ! <= @@ -81,7 +82,6 @@ program test_libmeshb_HO_f90 integer :: OrdTab(1:2,1:9) integer :: ord integer :: nNode - integer :: nUVW !> 04 07 03 !> 08 09 06 !> 01 05 02 @@ -103,38 +103,15 @@ program test_libmeshb_HO_f90 !> Q2 -> ord=2 ord=2 nNode=(ord+1)*(ord+1) ! <= - nUVW=2 ! <= - - !res=GmfGetBlock( & - !& InpMsh ,& - !& GmfOrd ,& - !& int( 1,kind=8) ,& - !& int(nNode,kind=8) ,& - !& 0, %val(0), %val(0) ,& - !& GmfIntTab, nUVW, OrdTab(1,1), OrdTab(1,nNode) ) - - !> en attendant de pouvoir récupérer orderingMesh ses valeurs sont imposées manuellement - !OrdTab(1:2,01)=[0,0] - !OrdTab(1:2,02)=[2,0] - !OrdTab(1:2,03)=[2,2] - !OrdTab(1:2,04)=[0,2] - !OrdTab(1:2,05)=[1,0] - !OrdTab(1:2,06)=[2,1] - !OrdTab(1:2,07)=[1,2] - !OrdTab(1:2,08)=[0,1] - !OrdTab(1:2,09)=[1,1] - OrdTab(1:2,01)=[0,0] - OrdTab(1:2,02)=[2,0] - OrdTab(1:2,03)=[2,2] - OrdTab(1:2,04)=[0,2] - OrdTab(1:2,05)=[1,0] - OrdTab(1:2,06)=[2,1] - OrdTab(1:2,07)=[1,2] - OrdTab(1:2,08)=[0,1] - OrdTab(1:2,09)=[1,1] - - print '("Input Mesh Gmf HO Order")' + res=GmfGetBlockF90( & + & unit=InpMsh ,& + & GmfKey=GmfOrd ,& + & ad0=1 ,& + & ad1=nNode ,& + & Tab=OrdTab(:,1:nNode) ) + + print '("Input Mesh Order")' do i=1,size(OrdTab,2) print '(3x,"uv(",i2.2,")=",2(i2,1x))',i,OrdTab(1:2,i) enddo @@ -143,19 +120,16 @@ program test_libmeshb_HO_f90 end block endif - ! Read the quads using one single vector of 5 consecutive integers - res=GmfGetElements( & - & InpMsh ,& - & GmfCell ,& - & 1 ,& - & NmbQad ,& - ! 0, m ,& - & 0, c_null_ptr ,& - & QadTab(1,1), QadTab(1,NmbQad),& - & QadRef( 1), QadRef( NmbQad) ) + ! Read the quads using one single vector of 5 consecutive integers + res=GmfGetBlockF90( & + & unit=InpMsh ,& + & GmfKey=GmfQuadrilateralsQ2,& + & ad0=1 ,& + & ad1=NmbQad ,& + & Tab=QadTab(:,1:) ,& + & Ref=QadRef( 1:) ) ! Close the quadrilateral mesh - res=GmfCloseMeshf77(InpMsh) print '("Input Mesh Close : ",a)',trim(InpFile) print '("Input Mesh")' @@ -173,23 +147,23 @@ program test_libmeshb_HO_f90 allocate(TriRef( 1:NmbTri)) do i=1,NmbQad - iTria=2*i-1 - TriTab(1,iTria) = QadTab(1,i) - TriTab(2,iTria) = QadTab(3,i) - TriTab(3,iTria) = QadTab(9,i) - TriTab(4,iTria) = QadTab(2,i) - TriTab(5,iTria) = QadTab(6,i) - TriTab(6,iTria) = QadTab(5,i) - TriRef( iTria) = QadRef( i) - - iTria=2*i - TriTab(1,iTria) = QadTab(1,i) - TriTab(2,iTria) = QadTab(9,i) - TriTab(3,iTria) = QadTab(7,i) - TriTab(4,iTria) = QadTab(5,i) - TriTab(5,iTria) = QadTab(8,i) - TriTab(6,iTria) = QadTab(4,i) - TriRef( iTria) = QadRef( i) + iTria=2*i-1 + TriTab(1,iTria) = QadTab(1,i) + TriTab(2,iTria) = QadTab(3,i) + TriTab(3,iTria) = QadTab(9,i) + TriTab(4,iTria) = QadTab(2,i) + TriTab(5,iTria) = QadTab(6,i) + TriTab(6,iTria) = QadTab(5,i) + TriRef( iTria) = QadRef( i) + + iTria=2*i + TriTab(1,iTria) = QadTab(1,i) + TriTab(2,iTria) = QadTab(9,i) + TriTab(3,iTria) = QadTab(7,i) + TriTab(4,iTria) = QadTab(5,i) + TriTab(5,iTria) = QadTab(8,i) + TriTab(6,iTria) = QadTab(4,i) + TriRef( iTria) = QadRef( i) enddo !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< @@ -199,12 +173,12 @@ program test_libmeshb_HO_f90 print '(/"Output Mesh File : ",a )',trim(OutFile) print '("Output Mesh")' - do i=1,10 !NmbQad + do i=1,10 print '(3x,"tri",i6," nd:",6(i6,1x)," ref: ",i0)',i,TriTab(1:6,i),TriRef(i) enddo ! Open the mesh file and check the version and dimension - OutMsh = GmfOpenMeshf77(trim(OutFile), GmfWrite, ver, dim) + OutMsh=GmfOpenMeshF90(name=trim(OutFile),GmfKey=GmfWrite,ver=ver,dim=dim) print '( "Output Mesh Idx : ",i0)',InpMsh print '( "Output Mesh ver : ",i0)',ver print '( "Output Mesh dim : ",i0)',dim @@ -214,33 +188,30 @@ program test_libmeshb_HO_f90 res=GmfSetKwdF90(unit=OutMsh, GmfKey=GmfVertices, Nmb=NmbVer) print '( "Output Mesh NmbVer: ",i0)', NmbVer - ! Write them down using separate pointers for each scalar entry - res=Gmfsetvertices( & - & OutMsh ,& - & 1 ,& - & NmbVer ,& - ! 0, m ,& - & 0, c_null_ptr ,& - & VerTab(1,1), VerTab(1,NmbVer),& - & VerRef( 1), VerRef( NmbVer) ) + ! Write them down using separate pointers for each scalar entry + res=GmfSetBlockF90( & + & unit=OutMsh ,& + & GmfKey=GmfVertices ,& + & ad0=1 ,& + & ad1=NmbVer ,& + & Tab=VerTab(:,1:NmbVer),& + & Ref=VerRef( 1:NmbVer) ) ! Write the triangles using 4 independant set of arguments ! for each scalar entry: node1, node2, node3 and reference res=GmfSetKwdF90(unit=OutMsh, GmfKey=GmfTrianglesP2, Nmb=NmbTri) print '( "Output Mesh NmbTri: ",i0)', NmbTri - res=GmfSetElements( & - & OutMsh ,& - & GmfTrianglesP2 ,& - & 1 ,& - & NmbTri ,& - & 0, c_null_ptr ,& - ! 0, m ,& - & TriTab(1,1), TriTab(1,NmbTri),& - & TriRef( 1), TriRef( NmbTri) ) + res=GmfSetBlockF90( & + & unit=OutMsh ,& + & GmfKey=GmfTrianglesP2 ,& + & ad0=1 ,& + & ad1=NmbTri ,& + & Tab=TriTab(:,1:NmbTri),& + & Ref=TriRef( 1:NmbVer) ) ! Don't forget to close the file - res=GmfCloseMeshf77(OutMsh) + res=GmfCloseMeshF90(unit=OutMsh) !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> diff --git a/examples/test_libmeshb_block.f90 b/examples/test_libmeshb_block.f90 index 7a20487..e47b856 100644 --- a/examples/test_libmeshb_block.f90 +++ b/examples/test_libmeshb_block.f90 @@ -5,7 +5,6 @@ program test_libmeshb_block_f90 !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> use iso_fortran_env use libmeshb7 - use, intrinsic :: iso_c_binding, only: c_int,c_long,c_loc,c_ptr,c_null_ptr !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> implicit none @@ -41,7 +40,7 @@ program test_libmeshb_block_f90 ! Open the mesh file and check the version and dimension InpMsh=GmfOpenMeshF90(name=trim(InpFile),GmfKey=GmfRead,ver=ver,dim=dim) - + print '( "Input Mesh Idx : ",i0)',InpMsh print '( "Input Mesh ver : ",i0)',ver print '( "Input Mesh dim : ",i0)',dim diff --git a/sources/libmeshb7_mod.f90 b/sources/libmeshb7_mod.f90 index 0eb8519..a8aedcf 100644 --- a/sources/libmeshb7_mod.f90 +++ b/sources/libmeshb7_mod.f90 @@ -305,9 +305,10 @@ module libmeshb7 interface GmfGetBlockF90 !module procedure GmfGetBlockF90_00 - module procedure GmfGetBlockF90_01 !> nodes + ref - module procedure GmfGetBlockF90_02 !> vertices + ref - module procedure GmfGetBlockF90_03 !> solutions + module procedure GmfGetBlockF90_01 !> nodes + ref + module procedure GmfGetBlockF90_01Bis !> nodes + module procedure GmfGetBlockF90_02 !> vertices + ref + module procedure GmfGetBlockF90_02Bis !> solutions end interface GmfGetBlockF90 interface GmfSetBlockF90 @@ -616,6 +617,45 @@ function GmfGetBlockF90_01(unit, GmfKey, ad0, ad1, Tab, Ref) result(res) !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< return end function GmfGetBlockF90_01 + + function GmfGetBlockF90_01Bis(unit, GmfKey, ad0, ad1, Tab) result(res) + !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + integer(int64), intent(in) :: unit + integer(int32), intent(in) :: GmfKey + integer(int32), intent(in) :: ad0 + integer(int32), intent(in) :: ad1 + integer(int32), intent(inout) :: Tab(:,:) + integer(int32) :: res + !> + integer(int32) :: Nmb + real(real64) :: dTab(1) + integer(int32) :: Ref(1) + integer(int32), pointer :: map(:)=>null() + + !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + + Nmb=ad1-ad0+1 + + print '("GmfGetBlockF90_01Bis (ad0,ad1)=(",i0,",",i0,") Nmb=",i0)',ad0,ad1,Nmb + print '("GmfGetBlockF90_01Bis size(Tab)=",i0,"x",i0)',size(Tab,1),size(Tab,2) + print '("GmfGetBlockF90_01Bis size(Ref)= ",i0)',size(Ref) + + res=GmfGetBlockF77(unit ,& + & GmfKey ,& + & ad0 ,& + & ad1 ,& + & int32 ,& + & map ,& + & Tab(1, 1) ,& + & Tab(1,Nmb) ,& + & dTab(1) ,& + & dTab(1) ,& + & Ref( 1) ,& + & Ref( 1) ) + !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + return + end function GmfGetBlockF90_01Bis function GmfGetBlockF90_02(unit, GmfKey, ad0, ad1, Tab, Ref) result(res) !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> @@ -654,7 +694,7 @@ function GmfGetBlockF90_02(unit, GmfKey, ad0, ad1, Tab, Ref) result(res) return end function GmfGetBlockF90_02 - function GmfGetBlockF90_03(unit, GmfKey, ad0, ad1, Tab) result(res) + function GmfGetBlockF90_02Bis(unit, GmfKey, ad0, ad1, Tab) result(res) !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> integer(int64), intent(in) :: unit integer(int32), intent(in) :: GmfKey @@ -671,9 +711,9 @@ function GmfGetBlockF90_03(unit, GmfKey, ad0, ad1, Tab) result(res) !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Nmb=ad1-ad0+1 - print '("GmfGetBlockF90_03 (ad0,ad1)=(",i0,",",i0,") Nmb=",i0)',ad0,ad1,Nmb - print '("GmfGetBlockF90_03 size(Tab)=",i0,"x",i0)',size(Tab,1),size(Tab,2) - print '("GmfGetBlockF90_03 size(Ref)= ",i0)',size(Ref) + print '("GmfGetBlockF90_02Bis (ad0,ad1)=(",i0,",",i0,") Nmb=",i0)',ad0,ad1,Nmb + print '("GmfGetBlockF90_02Bis size(Tab)=",i0,"x",i0)',size(Tab,1),size(Tab,2) + print '("GmfGetBlockF90_02Bis size(Ref)= ",i0)',size(Ref) res=GmfGetBlockF77(unit ,& & GmfKey ,& @@ -689,7 +729,7 @@ function GmfGetBlockF90_03(unit, GmfKey, ad0, ad1, Tab) result(res) & Ref( 1) ) !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< return - end function GmfGetBlockF90_03 + end function GmfGetBlockF90_02Bis function GmfSetBlockF90_01(unit, GmfKey, ad0, ad1, Tab, Ref) result(res) !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> From 1a7c56f8a778df6d1d3af0333f30b64882abd5f8 Mon Sep 17 00:00:00 2001 From: Christophe Peyret Date: Mon, 26 Feb 2024 22:06:18 +0100 Subject: [PATCH 36/38] test_libmeshb_HO_f90 fonctionne --- examples/test_libmeshb_HO.f90 | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/examples/test_libmeshb_HO.f90 b/examples/test_libmeshb_HO.f90 index 5c31a07..609c85b 100644 --- a/examples/test_libmeshb_HO.f90 +++ b/examples/test_libmeshb_HO.f90 @@ -29,7 +29,7 @@ program test_libmeshb_HO_f90 !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> InpFile='../sample_meshes/quad_q2.mesh' - OutFile='./tri_p2f.mesh' + OutFile='./tri_p2.mesh' SolFile='./tri_p2.sol' !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< @@ -146,23 +146,30 @@ program test_libmeshb_HO_f90 allocate(TriTab(1:6,1:NmbTri)) allocate(TriRef( 1:NmbTri)) + !> 04 07 03 !> 03 04 07 03 + !> 08 09 06 => !> 09 06 + 08 09 + !> 01 05 02 !> 01 05 02 01 + + !> 03 + !> 06 05 + !> 01 04 02 do i=1,NmbQad iTria=2*i-1 TriTab(1,iTria) = QadTab(1,i) - TriTab(2,iTria) = QadTab(3,i) - TriTab(3,iTria) = QadTab(9,i) - TriTab(4,iTria) = QadTab(2,i) + TriTab(2,iTria) = QadTab(2,i) + TriTab(3,iTria) = QadTab(3,i) + TriTab(4,iTria) = QadTab(5,i) TriTab(5,iTria) = QadTab(6,i) - TriTab(6,iTria) = QadTab(5,i) + TriTab(6,iTria) = QadTab(9,i) TriRef( iTria) = QadRef( i) iTria=2*i TriTab(1,iTria) = QadTab(1,i) - TriTab(2,iTria) = QadTab(9,i) - TriTab(3,iTria) = QadTab(7,i) - TriTab(4,iTria) = QadTab(5,i) - TriTab(5,iTria) = QadTab(8,i) - TriTab(6,iTria) = QadTab(4,i) + TriTab(2,iTria) = QadTab(3,i) + TriTab(3,iTria) = QadTab(4,i) + TriTab(4,iTria) = QadTab(9,i) + TriTab(5,iTria) = QadTab(7,i) + TriTab(6,iTria) = QadTab(8,i) TriRef( iTria) = QadRef( i) enddo !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< From 9a55e837c61f7597b96ce6de4d023473d29c6aaf Mon Sep 17 00:00:00 2001 From: Christophe Peyret Date: Mon, 26 Feb 2024 22:13:25 +0100 Subject: [PATCH 37/38] =?UTF-8?q?coh=C3=A9rence=20des=20nomenclatures?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- examples/test_libmeshb_HO.f90 | 8 ++++---- sources/libmeshb7_mod.f90 | 16 ++++++++-------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/examples/test_libmeshb_HO.f90 b/examples/test_libmeshb_HO.f90 index 609c85b..25a43f3 100644 --- a/examples/test_libmeshb_HO.f90 +++ b/examples/test_libmeshb_HO.f90 @@ -110,7 +110,7 @@ program test_libmeshb_HO_f90 & ad0=1 ,& & ad1=nNode ,& & Tab=OrdTab(:,1:nNode) ) - + print '("Input Mesh Order")' do i=1,size(OrdTab,2) print '(3x,"uv(",i2.2,")=",2(i2,1x))',i,OrdTab(1:2,i) @@ -146,9 +146,9 @@ program test_libmeshb_HO_f90 allocate(TriTab(1:6,1:NmbTri)) allocate(TriRef( 1:NmbTri)) - !> 04 07 03 !> 03 04 07 03 - !> 08 09 06 => !> 09 06 + 08 09 - !> 01 05 02 !> 01 05 02 01 + !> 04 07 03 03 04 07 03 + !> 08 09 06 => 09 06 + 08 09 + !> 01 05 02 01 05 02 01 !> 03 !> 06 05 diff --git a/sources/libmeshb7_mod.f90 b/sources/libmeshb7_mod.f90 index a8aedcf..4fa2c46 100644 --- a/sources/libmeshb7_mod.f90 +++ b/sources/libmeshb7_mod.f90 @@ -313,9 +313,9 @@ module libmeshb7 interface GmfSetBlockF90 !module procedure GmfGetBlockF90_00 - module procedure GmfSetBlockF90_01 !> nodes + ref - module procedure GmfSetBlockF90_02 !> vertices + ref - module procedure GmfSetBlockF90_03 !> solutions + module procedure GmfSetBlockF90_01 !> nodes + ref + module procedure GmfSetBlockF90_02 !> vertices + ref + module procedure GmfSetBlockF90_02Bis !> solutions end interface GmfSetBlockF90 contains @@ -806,7 +806,7 @@ function GmfSetBlockF90_02(unit, GmfKey, ad0, ad1, Tab, Ref) result(res) return end function GmfSetBlockF90_02 - function GmfSetBlockF90_03(unit, GmfKey, ad0, ad1, Tab) result(res) + function GmfSetBlockF90_02Bis(unit, GmfKey, ad0, ad1, Tab) result(res) !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> integer(int64), intent(in) :: unit integer(int32), intent(in) :: GmfKey @@ -823,9 +823,9 @@ function GmfSetBlockF90_03(unit, GmfKey, ad0, ad1, Tab) result(res) !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Nmb=ad1-ad0+1 - print '("GmfSetBlockF90_03 (ad0,ad1)=(",i0,",",i0,") Nmb=",i0)',ad0,ad1,Nmb - print '("GmfSetBlockF90_03 size(Tab)=",i0,"x",i0)',size(Tab,1),size(Tab,2) - print '("GmfSetBlockF90_03 size(Ref)= ",i0)',size(Ref) + print '("GmfSetBlockF90_02Bis (ad0,ad1)=(",i0,",",i0,") Nmb=",i0)',ad0,ad1,Nmb + print '("GmfSetBlockF90_02Bis size(Tab)=",i0,"x",i0)',size(Tab,1),size(Tab,2) + print '("GmfSetBlockF90_02Bis size(Ref)= ",i0)',size(Ref) res=GmfSetBlockF77(unit ,& & GmfKey ,& @@ -841,6 +841,6 @@ function GmfSetBlockF90_03(unit, GmfKey, ad0, ad1, Tab) result(res) & Ref( 1) ) !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< return - end function GmfSetBlockF90_03 + end function GmfSetBlockF90_02Bis end module libmeshb7 \ No newline at end of file From 8993274f2d95ac44a80251a4a73465ab4c754b10 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Mar=C3=A9chal?= Date: Tue, 27 Feb 2024 10:26:57 +0100 Subject: [PATCH 38/38] Final commit with the new Fortran API and updated docs before mergin with the master branch --- CMakeLists.txt | 2 +- Documentation/fortran_api.md | 72 +++++----- README.md | 2 +- sources/libmeshb7.c | 265 ++++------------------------------- sources/libmeshb7.h | 4 +- sources/libmeshb7.ins | 4 +- todolist.md | 14 +- whatsnew.md | 8 +- 8 files changed, 76 insertions(+), 295 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ff2d1d5..2ce3d4b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,7 +6,7 @@ cmake_minimum_required (VERSION 3.7.2) set (libMeshb_VERSION_MAJOR 7) -set (libMeshb_VERSION_MINOR 54) +set (libMeshb_VERSION_MINOR 80) project(libMeshb VERSION ${libMeshb_VERSION_MAJOR}.${libMeshb_VERSION_MINOR} LANGUAGES C) option(WITH_GMF_AIO "Use Unix low-level and asynchronous I/O for higher speed" OFF) diff --git a/Documentation/fortran_api.md b/Documentation/fortran_api.md index 63cfbec..44d6a3e 100644 --- a/Documentation/fortran_api.md +++ b/Documentation/fortran_api.md @@ -40,68 +40,66 @@ From Fortran you need to provide all arguments even if they are not needed. Calls C GmfSetHONodesOrdering() with the same arguments. -## VERTICES +### gmfgetlinef77(lib, kwd, IntTab, RealTab, Ref) -Vertices data is split in two fields: a pointer to consecutive REAL8 to store coordinates and a pointer on an INT4 that stores the reference. +Reads a full line of a giver keyword's data. +Right now, the default data kinds are integer*4 and real*8. +Integer fields are stored in IntTab(), floating point values are stored in DblTab() and if the keyword includes a reference (GmfVertices and all elements), it is stored in Ref. -### gmfgetvertex(lib, coordinates, ref) +Note that even though some keywords don't need all the parameters, you need to provide them all to the function call, use dummy parameters if needed. -Reads a single vertex. -Calls C GmfGetLin() with keyword GmfVertices, a pointer on a vector of 2 or 3 consecutive REAL8 and a pointer on an integer ref. +### gmfsetlinef77(lib, kwd, IntTab, RealTab, Ref) -### gmfsetvertex(lib, coordinates, ref) +Writes a full line of a giver keyword's data. +Right now, the default data kinds are integer*4 and real*8. -Writes a single vertex. -Calls C GmfSetLin() with keyword GmfVertices, a pointer on a vector of 2 or 3 consecutive REAL8 and the value of the integer ref. +Integer fields are stored in IntTab(), floating point values are stored in DblTab() and if the keyword includes a reference (GmfVertices and all elements), it is stored in Ref. -### gmfgetvertices(lib, start-index, end-index, map-type, map, start-coordinates, end-coordinate, start-ref, end-ref) +Note that even though some keywords don't need all the parameters, you need to provide them all to the function call, use dummy parameters if needed. -Reads a block of vertices. -Calls C GmfGetBlock with GmfVertices and pointers to the first vertex coordinates, last vertex coordinates, first vertex reference and last vertex reference. -### gmfsetvertices(lib, start-index, end-index, map-type, map, start-coordinates, end-coordinate, start-ref, end-ref) +### gmfget blockf77(lib, kwd, BegIdx, EndIdx, MapTyp, MapTab, BegInt, EndInt, BegReal, EndReal, BegRef, EndRef) -Writes a block of vertices. -Calls C GmfSetBlock with GmfVertices and pointers to the first vertex coordinates, last vertex coordinates, first vertex reference and last vertex reference. +Reads multiple data lines in a row. +You need to provide tables big enough to store all the data in one huge memory area. -## ELEMENTS +BegIdx and EndIdx are the first and last line number to be read (1 .. NbElements reads the whole mesh). -Elements data is split in two fields: a pointer to consecutive INT4 to store nodes indices and a pointer on an INT4 that stores the reference. +BegInt points to the first entity integer's data. -### gmfgetelement(lib, element-kind, nodes, ref) +EndInt points to the last entity integer's data. -Reads a single element. -Calls C GmfGetLin() with the provided element keyword, a pointer on a vector of several consecutive INT4 to store nodes indices and a pointer on an integer ref. +BegReal points to the first entity REAL*8's data. -### gmfsetelement(lib, element-kind, nodes, ref) +EndReal points to the last entity REAL*8's data. -Writes a single element. -Calls C GmfSetLin() with the provided element keyword, a pointer on a vector of several consecutive INT4 to store nodes indices and a pointer on an integer ref. +BegRef points to the first entity's reference -### gmfgetelements(lib, element-kind, start-index, end-index, map-type, map, start-nodes, end-nodes, start-ref, end-ref) +EndRef points to the last entity's reference -Reads a block of elements. -Calls C GmfGetBlock() with the provided element keyword, a pointer on the first element's nodes, a pointer on the last element's nodes, a pointer on the first element's reference and a pointer on the last element's reference. +Like with gmgetlinef77(), some arguments may be useless depending on the keyword but you need to provide some dummy argument instead. -### gmfsetelements(lib, element-kind, start-index, end-index, map-type, map, start-nodes, end-nodes, start-ref, end-ref) -Writes a block of elements. -Calls C GmfSetBlock() with the provided element keyword, a pointer on the first element's nodes, a pointer on the last element's nodes, a pointer on the first element's reference and a pointer on the last element's reference. +### gmfset blockf77(lib, kwd, BegIdx, EndIdx, MapTyp, MapTab, BegInt, EndInt, BegReal, EndReal, BegRef, EndRef) +Writes multiple data lines in a row. -## SOLUTIONS +You need to provide tables big enough to store all the data in one huge memory area. -Solution fields are stored in REAL8 into a .sol or .solb file. -All fields must be stored in a consecutive table. +BegIdx and EndIdx are the first and last line number to be read (1 .. NbElements reads the whole mesh). -### gmfgetsolution(lib, solution-keyword, solutions) +BegInt points to the first entity integer's data. -Reads one line of solution fields concatenated into a single REAL8 table. -Calls C GmfGetLin() with the provided solution keyword and a pointer on a vector of sufficent consecutive REAL8 to store a whole line of solution fields. +EndInt points to the last entity integer's data. -### gmfsetsolution(lib, solution-keyword, solutions) +BegReal points to the first entity REAL*8's data. -Writes one line of solution fields concatenated into a single REAL8 table. -Calls C GmfSetLin() with the provided solution keyword and a pointer on a vector of sufficient consecutive REAL8 to store a whole line of solution fields. +EndReal points to the last entity REAL*8's data. + +BegRef points to the first entity's reference + +EndRef points to the last entity's reference + +Like with gmsetlinef77(), some arguments may be useless depending on the keyword but you need to provide some dummy argument instead. diff --git a/README.md b/README.md index ac82c1a..273cdc1 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) -## libMeshb version 7.79 +## libMeshb version 7.80 A library to handle the *.meshb file format. ## Overview diff --git a/sources/libmeshb7.c b/sources/libmeshb7.c index 6a98e2f..cc4d075 100644 --- a/sources/libmeshb7.c +++ b/sources/libmeshb7.c @@ -2,14 +2,14 @@ /*----------------------------------------------------------------------------*/ /* */ -/* LIBMESHB V7.79 */ +/* LIBMESHB V7.80 */ /* */ /*----------------------------------------------------------------------------*/ /* */ /* Description: handles .meshb file format I/O */ /* Author: Loic MARECHAL */ /* Creation date: dec 09 1999 */ -/* Last modification: feb 23 2024 */ +/* Last modification: feb 27 2024 */ /* */ /*----------------------------------------------------------------------------*/ @@ -469,236 +469,15 @@ const char *GmfKwdFmt[ GmfMaxKwd + 1 ][3] = int GmfMaxRefTab[ GmfMaxKwd + 1 ]; #endif -static char NmbEleNod[ GmfMaxKwd + 1 ] = +static char F77RefFlg[ GmfMaxKwd + 1 ] = { - 0, - 0, - 0, - 0, - 1, - 2, - 3, - 4, - 4, - 6, - 8, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 6, - 3, - 0, - 9, - 0, - 0, - 10, - 0, - 0, - 27, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 32, - 8, - 0, - 5, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 18, - 14, - 14, - 25, - 9, - 13, - 4, - 5, - 0, - 0, - 20, - 35, - 64, - 125, - 30, - 55, - 40, - 75, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0 + 0,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,1,0,0,1,0,0,1,0,0,0, + 0,0,0,0,0,0,0,0,0,1,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0 }; @@ -1274,8 +1053,10 @@ int GmfGetLin(int64_t MshIdx, int KwdCod, ...) GmfMshSct *msh = (GmfMshSct *)MshIdx; KwdSct *kwd; + // Special trick: if the kwd is negative the call come from Fortran if(KwdCod < 0) { + // Set Fortran mode ON KwdCod = -KwdCod; kwd = &msh->KwdTab[ KwdCod ]; typ = F77Kwd; @@ -1416,7 +1197,7 @@ int GmfGetLin(int64_t MshIdx, int KwdCod, ...) IntVal = (int)LngVal; } - if(!NmbEleNod[ KwdCod ] || (i < kwd->SolSiz - 1)) + if(!F77RefFlg[ KwdCod ] || (i < kwd->SolSiz - 1)) IntTab[i] = IntVal; else *RefPtr = IntVal; @@ -1466,8 +1247,10 @@ int GmfSetLin(int64_t MshIdx, int KwdCod, ...) GmfMshSct *msh = (GmfMshSct *)MshIdx; KwdSct *kwd; + // Special trick: if the kwd is negative the call come from Fortran if(KwdCod < 0) { + // Set Fortran mode ON KwdCod = -KwdCod; kwd = &msh->KwdTab[ KwdCod ]; typ = F77Kwd; @@ -1615,13 +1398,13 @@ int GmfSetLin(int64_t MshIdx, int KwdCod, ...) else if(kwd->fmt[i] == 'i') { if(msh->ver <= 3) - if(!NmbEleNod[ KwdCod ] || (i < kwd->SolSiz - 1)) + if(!F77RefFlg[ KwdCod ] || (i < kwd->SolSiz - 1)) fprintf(msh->hdl, "%d ", IntTab[i]); else fprintf(msh->hdl, "%d ", *RefPtr); else { - if(!NmbEleNod[ KwdCod ] || (i < kwd->SolSiz - 1)) + if(!F77RefFlg[ KwdCod ] || (i < kwd->SolSiz - 1)) fprintf(msh->hdl, INT64_T_FMT " ", (int64_t)IntTab[i]); else fprintf(msh->hdl, INT64_T_FMT " ", (int64_t)*RefPtr); @@ -1656,7 +1439,7 @@ int GmfSetLin(int64_t MshIdx, int KwdCod, ...) { IntBuf = (void *)&msh->buf[ pos ]; - if(!NmbEleNod[ KwdCod ] || (i < kwd->SolSiz - 1)) + if(!F77RefFlg[ KwdCod ] || (i < kwd->SolSiz - 1)) *IntBuf = IntTab[i]; else *IntBuf = *RefPtr; @@ -1667,7 +1450,7 @@ int GmfSetLin(int64_t MshIdx, int KwdCod, ...) { LngBuf = (void *)&msh->buf[ pos ]; - if(!NmbEleNod[ KwdCod ] || (i < kwd->SolSiz - 1)) + if(!F77RefFlg[ KwdCod ] || (i < kwd->SolSiz - 1)) *LngBuf = (int64_t)IntTab[i]; else *LngBuf = (int64_t)*RefPtr; @@ -3451,11 +3234,13 @@ int APIF77(gmfsethonodesorderingf77)( int64_t *MshIdx, int *KwdCod, int APIF77(gmfgetlinef77)(int64_t *MshIdx, int *kwd, int *i, double *d, int *r) { + // Special trick: use a negative value kwd to set Fortran mode on return(GmfGetLin(*MshIdx, -*kwd, i, d, r)); } int APIF77(gmfsetlinef77)(int64_t *MshIdx, int *kwd, int *i, double *d, int *r) { + // Special trick: use a negative value kwd to set Fortran mode on return(GmfSetLin(*MshIdx, -*kwd, i, d, r)); } @@ -3471,6 +3256,8 @@ int APIF77(gmfgetblockf77)(int64_t *MshIdx, int *KwdCod, GmfMshSct *msh = (GmfMshSct *)*MshIdx; KwdSct *kwd = &msh->KwdTab[ *KwdCod ]; + // Fortran call to getblock uses the GmfArgTab mode where pointers are passed + // through tables: types[], vec sizes[], begin pointers[] and end pointers[] for(i=0;iSolSiz;i++) { if(kwd->fmt[i] == 'i') @@ -3478,7 +3265,7 @@ int APIF77(gmfgetblockf77)(int64_t *MshIdx, int *KwdCod, TypTab[i] = GmfInt; SizTab[i] = 1; - if( (NmbEleNod[ *KwdCod ]) && (i == kwd->SolSiz-1) ) + if( (F77RefFlg[ *KwdCod ]) && (i == kwd->SolSiz-1) ) { BegTab[i] = (char *)BegRef; EndTab[i] = (char *)EndRef; @@ -3513,6 +3300,8 @@ int APIF77(gmfsetblockf77)(int64_t *MshIdx, int *KwdCod, GmfMshSct *msh = (GmfMshSct *)*MshIdx; KwdSct *kwd = &msh->KwdTab[ *KwdCod ]; + // Fortran call to setblock uses the GmfArgTab mode where pointers are passed + // through tables: types[], vec sizes[], begin pointers[] and end pointers[] for(i=0;iSolSiz;i++) { if(kwd->fmt[i] == 'i') @@ -3520,7 +3309,7 @@ int APIF77(gmfsetblockf77)(int64_t *MshIdx, int *KwdCod, TypTab[i] = GmfInt; SizTab[i] = 1; - if( (NmbEleNod[ *KwdCod ]) && (i == kwd->SolSiz-1) ) + if( (F77RefFlg[ *KwdCod ]) && (i == kwd->SolSiz-1) ) { BegTab[i] = (char *)BegRef; EndTab[i] = (char *)EndRef; diff --git a/sources/libmeshb7.h b/sources/libmeshb7.h index 82982a0..5237375 100644 --- a/sources/libmeshb7.h +++ b/sources/libmeshb7.h @@ -2,14 +2,14 @@ /*----------------------------------------------------------------------------*/ /* */ -/* LIBMESHB V7.79 */ +/* LIBMESHB V7.80 */ /* */ /*----------------------------------------------------------------------------*/ /* */ /* Description: handle .meshb file format I/O */ /* Author: Loic MARECHAL */ /* Creation date: dec 09 1999 */ -/* Last modification: feb 08 2024 */ +/* Last modification: feb 27 2024 */ /* */ /*----------------------------------------------------------------------------*/ diff --git a/sources/libmeshb7.ins b/sources/libmeshb7.ins index bf9da1f..2e80863 100644 --- a/sources/libmeshb7.ins +++ b/sources/libmeshb7.ins @@ -2,14 +2,14 @@ c---------------------------------------------------------- c -c LIBMESH V 7.79 +c LIBMESH V 7.80 c c---------------------------------------------------------- c c Description: handles .meshb file format I/O c Author: Loic MARECHAL c Creation date: dec 08 2015 -c Last modification: feb 22 2024 +c Last modification: feb 27 2024 c c---------------------------------------------------------- diff --git a/todolist.md b/todolist.md index 0a418b1..5b76c73 100644 --- a/todolist.md +++ b/todolist.md @@ -13,21 +13,11 @@ - Setup a keyword to store Pk elements. - Give along a routine to convert to and from well-known high-order numberings. -### Handle arbitrary degree polygons and polyhedra -- Add a helper that cuts a polyhedron through a plane and generates the intersection's triangulated mesh in an STL-like format. - ### Solution fields comments - Add a procedure that would search for a string among comments. - Input: keyword name, physical property, free comment, wildcards. - Output: list of solutions keywords and particular field number. -### Convert HO examples to Fortran -- test_libmeshb_HO.c -- test_libmeshb_p2_sol.c - -### Add F77 API to GmfSetHONodesOrdering -An easy one. - ### Add IHOSol* + DHOSol* for each element kinds, For example: @@ -65,3 +55,7 @@ For example: - Added a set of keywords for each kind of element that stores the number of vertices and their barycentric coordinates. - Added a section about the AIO mode (Asynchronous Input Output). - Added a helper that evaluates the quality of a mesh numbering in terms of efficient cache reuse and inner concurrency. +- Added F77 API to GmfSetHONodesOrdering +- Completely rewrote the whole Fortran API because GFortran dropped support for C variable argumeents procedure. +- H.O. tests converted to Fortran by Christophe Peyret +- Added a helper that cuts a polyhedron through a plane and generates the intersection's triangulated mesh in an STL-like format. diff --git a/whatsnew.md b/whatsnew.md index 3d6fe19..dad7d3b 100644 --- a/whatsnew.md +++ b/whatsnew.md @@ -1,6 +1,6 @@ -## Release 7.79 +## Release 7.80 1. Complete rewrite of the Fortran API: - - No more variable arguments procedures are used in Fortran as such feature is no more supported by gfortran - - Addhoc procedures to handle a few keywords are provided - - Users are encouraged to add their own ! + - No more variable arguments procedures are used in Fortran as such feature is no more supported by gfortran. + - Line-based read and write go through three tables: one that stores all INTEGER4 values, one for REAL8 and an INTEGER4 scalar to store the reference. + - Block based access use the same data structures but each table is duplicated: one to store pointers to the first entities and the other one to store pointers to the last entities. This way, the procedure is able to compute the byte stride and store the mesh file data directly to or from the user's data structures. \ No newline at end of file