[Gmsh] c++ API - Import mesh vertices and elements

Simone GREMMO [531257] Simone.GREMMO at umons.ac.be
Sat Aug 22 05:15:17 CEST 2015


Hi Ryan,
I used the addPhysicalEntity(1) so that when saving the mesh, it will write to file the volume mesh and not the surfaces used to bound the volume.
As far as I could understand the addPhysicalEntity should not interfere with the mesh generation, but can used to save in the msh just a part of the mesh: so maybe you generate the mesh, but do not write to file. Is it possible?
Have you tried to comment the lines
regionInterface->addPhysicalEntity(1);
modelGmsh->add(regionInterface);
and see if in the resulting msh file you get something different?

Can you copy the relevant lines of your code? It may be easier to understand your problem.

Simone


________________________________
De : rjdurscher at gmail.com [rjdurscher at gmail.com]
Envoyé : samedi 22 août 2015 1.37
À : Gmsh
Cc : gmsh at geuz.org; Simone GREMMO [531257]
Objet : Re: [Gmsh] c++ API - Import mesh vertices and elements

Hi Simone,

I am trying to implement the same thing you describe here in my code with Gmsh. I have followed your code below exactly however I am unable to generate the volume mesh. Outputting a *.msh file (model->writeMSH()) at various stages  the problem seems to come about during "regionInterface->addPhysicalEntity(1);" in which the previously defined surface mesh now disappears (according the *.msh file). Any help would be greatly appreciated. I am currently using the latest version of Gmsh (2.10.1). Furthermore any additional code you could share regarding your second post (meshing between two surface) would be greatly appreciated.

Thanks,
Ryan


On Monday, February 9, 2015 at 6:41:49 AM UTC-5, Simone GREMMO [531257] wrote:
Dear all,
I think I have partially solved my problem. Here is the code that I have written and let me to create the volume mesh (Thanks to Mikhail for his suggestion in this answer: http://geuz.org/pipermail/gmsh/2015/009536.html):

GmshInitialize();
    GmshSetOption("Mesh","Algorithm",1.);
    //Create Gmsh model and set the factory
    GModel *modelGmsh = new GModel;
    modelGmsh->setFactory("Gmsh");

    //GFace is defined by a mesh and not through GVertex and GEdge
    GFace *interfaceGmsh = new discreteFace(modelGmsh,1);
    //Function that loops over mesh vertices and elements and import them in a gmsh structure [see at the bottom of the main function]
    importSurfaceMeshintoGmsh(interface, interfaceGmsh);
    modelGmsh->add(interfaceGmsh);

    //Using the previously defined surface, define a surface loop, used to enclose a volume
    std::vector<GFace*> interfaceFace;  //in my case the surface is given in one piece only
    interfaceFace.push_back(interfaceGmsh);
    std::vector <std::vector<GFace*> > interfaceLoop;
    interfaceLoop.push_back(interfaceFace);

    //Add the volume enclose by the surface loop to the model and create the related GRegion
    GRegion *regionInterface = modelGmsh->addVolume(interfaceLoop);
    //Add a volume physical entity
    regionInterface->addPhysicalEntity(1);
    //Add the region to the model
    modelGmsh->add(regionInterface);
    //Mesh the model
    modelGmsh->mesh(3);
    modelGmsh->writeGEO("/home/simoneg/Hexpress-Hybrid_projects/IncludeGmsh-HH/TESTGMSHAPI_keyword/interfaceVertGmsh.geo");
    modelGmsh->writeMSH("/home/simoneg/Hexpress-Hybrid_projects/IncludeGmsh-HH/TESTGMSHAPI_keyword/interfaceVertGmsh.msh");
    delete modelGmsh;
GmshFinalize();

//Function to import the mesh in a Gmsh structure
//inMesh is the input mesh, created with another tool
//gmshMesh is the structure containing the inMesh, but that can be used by Gmsh to generate the volume mesh
bool importSurfaceMeshintoGmsh(const My_Mesh &inMesh, GFace *gmshMesh)
{
    My_int numNodes = inMesh.numVerticies(); //get the number of vertices from the inMesh
    My_int numCells = inMesh.numCells(); ////get the number of elements from the inMesh

    //Get all the vertices from the mesh
    std::vector<MVertex*> mv;
    mv.resize((int)numNodes);
    for (MC_Index nodeCounter = 0; nodeCounter < numNodes; nodeCounter++)
    {
        My_Coord3D coordHH = inMesh.vertex(nodeCounter); //a 3 dimensions vector with the vertex coordinates
        mv[nodeCounter] = new MVertex((double)coordHH[0], (double)coordHH[1], (double)coordHH[2],gmshMesh, nodeCounter+1);
        gmshMesh->addMeshVertex(mv[nodeCounter]); //add the vertex to the mesh
    }


    //Get all the elements from the mesh
    for (My_int cellCounter = 0; cellCounter < numCells; cellCounter++)
    {
        My_int numVertCell = inMesh.numElems(cellCounter); //for element #cellCounter, get the number of vertices
        switch (numVertCell)
        {
        case 3: //triangle
            gmshMesh->addTriangle(new MTriangle(mv[inMesh.elem(cellCounter,0)],   //extract the vertexID for element #cellCounter
                                                 mv[inMesh.elem(cellCounter,1)],
                                 mv[inMesh.elem(cellCounter,2)]));
            break;
        case 4: //quadrangle
            gmshMesh->addQuadrangle(new MQuadrangle(mv[inMesh. elem(cellCounter,0)],
                                                                                                                mv[inMesh. elem(cellCounter,1)],
                                 mv[inMesh. elem(cellCounter,2)],
                                 mv[inMesh. elem(cellCounter,3)]));
            break;
        default:
            return false;
            break;
        }
    }
    return true;
}

This code generates a mesh in a volume without any hole inside. Does anyone know how to add a hole inside the volume and mesh the region between the two surfaces?
The .geo commands looks like:
Merge "interfaceMesh.msh";
Surface Loop(3) = {1};
Merge "envelopeMovingMesh.msh";
Surface Loop(4) = {2};
Volume(1) = {3,4};
Physical Volume(1) = {5};

Thanks for your help.
Simone

Dear all,
I have included Gmsh as library in my c++ program and I need to use it to mesh a volume region bounded by a surface mesh: in my program I have defined a surface mesh and I need to import its vertices and elements into a gmsh structure to be able to create a volume mesh starting from this surface.
Steps to do so, as far as I can understand, are:

-          Declare a GModel* that will contain the surface

-          Add a GFace* into the GModel

-          Add vertices and cells to the GFace* (get them from the mesh created in my program). Actually define a mesh for this GFace object

-          Create the volume mesh

Is this correct? Does anyone have any suggestion on how to write this portion of code?

PS I have already looked at the example in utils/api_demos/mainSimple.cpp and have adapted it to my case, but I would rather avoid reading/writing files to transfer meshes between the my program and gmsh to avoid performance issues.

Simone
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.geuz.org/pipermail/gmsh/attachments/20150822/1646e884/attachment-0001.html>