# GmshCommon - A .NET/CLI wrapper for Gmsh

**URL:** <https://prepomax.discourse.group/t/gmshcommon-a-net-cli-wrapper-for-gmsh/999>\
**Category:** General Questions\
**Created:** [July 25, 2023, 8:40am UTC](https://prepomax.discourse.group/t/gmshcommon-a-net-cli-wrapper-for-gmsh/999 "2023-07-25T08:40:48Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![tsvilans](https://yyz2.discourse-cdn.com/free1/user_avatar/prepomax.discourse.group/tsvilans/32/516_2.png) [@tsvilans](https://prepomax.discourse.group/u/tsvilans)\
**Post date:** [July 25, 2023, 8:40am UTC](https://prepomax.discourse.group/t/gmshcommon-a-net-cli-wrapper-for-gmsh/999/1 "2023-07-25T08:40:48Z")

</div>

Hello again,

Due to some work that I am doing, I have been working on a Gmsh .NET/CLI wrapper to allow me to use Gmsh within a .NET program directly.

It is not feature-complete yet, by any means, but it does expose most of the core functionality for loading entities, meshing, and extracting mesh data.

I have been using it alongside PrePoMax through the PrePoMax API and it works pretty seamlessly, avoiding the need to write meshes to a file and subsequently loading them in PrePoMax.

It is available [here](https://github.com/tsvilans/gmsh_common/releases/tag/v1.0).

---

<div class="post-metadata">

**Author:** ![Matej](https://avatars.discourse-cdn.com/v4/letter/m/a698b9/32.png) [@Matej](https://prepomax.discourse.group/u/Matej)\
**Post date:** [July 25, 2023, 2:09pm UTC](https://prepomax.discourse.group/t/gmshcommon-a-net-cli-wrapper-for-gmsh/999/2 "2023-07-25T14:09:43Z")

</div>

Dear Tom,

I think this is great coincidence. My next big goal is to add support for Gmsh to PrePoMax to enable structured 2D and 3D meshing. At least for simple geometries in 3D. I was planning to use .geo files so I will take a look at your code shortly (vacation).

Have you any experience creating hexahedral meshes?

---

<div class="post-metadata">

**Author:** ![tsvilans](https://yyz2.discourse-cdn.com/free1/user_avatar/prepomax.discourse.group/tsvilans/32/516_2.png) [@tsvilans](https://prepomax.discourse.group/u/tsvilans)\
**Post date:** [July 26, 2023, 7:43am UTC](https://prepomax.discourse.group/t/gmshcommon-a-net-cli-wrapper-for-gmsh/999/3 "2023-07-26T07:43:46Z")

</div>

Great!

I can share some code for going from GmshCommon to adding nodes and elements in PrePoMax without exporting/importing 🙂

> Have you any experience creating hexahedral meshes?

No… I’ve been sticking to tetrahedra in my work 😛 Would be interesting to see how good Gmsh is at this…

---

<div class="post-metadata">

**Author:** ![Matej](https://avatars.discourse-cdn.com/v4/letter/m/a698b9/32.png) [@Matej](https://prepomax.discourse.group/u/Matej)\
**Post date:** [July 26, 2023, 8:07am UTC](https://prepomax.discourse.group/t/gmshcommon-a-net-cli-wrapper-for-gmsh/999/4 "2023-07-26T08:07:04Z")

</div>

> [@tsvilans](#):
>
> I can share some code for going from GmshCommon to adding nodes and elements in PrePoMax without exporting/importing

That woud be great it woud help a lot.

---

<div class="post-metadata">

**Author:** ![tsvilans](https://yyz2.discourse-cdn.com/free1/user_avatar/prepomax.discourse.group/tsvilans/32/516_2.png) [@tsvilans](https://prepomax.discourse.group/u/tsvilans)\
**Post date:** [July 26, 2023, 9:42am UTC](https://prepomax.discourse.group/t/gmshcommon-a-net-cli-wrapper-for-gmsh/999/5 "2023-07-26T09:42:36Z")

</div>

Code to get node data…

```csharp
// Get all nodes
var nodes = new Dictionary<int, double[]>;

IntPtr[] nodeTagsIntPtr;
double[] coords;
Gmsh.Mesh.GetNodes(out nodeTagsIntPtr, out coords, 3, -1, true, false);

for (int i = 0; i < nodeTagsIntPtr.Length; ++i)
{
     var nodeTag = (int)nodeTagsIntPtr[i];
     var nodeCoord = new double[] { coords[i * 3], coords[i * 3 + 1], coords[i * 3 + 2] };
 
     nodes[nodeTag] = nodeCoord;
}

```

… and element data…

```csharp
var elements = new Dictionary<int, int[]>();
var elementTypes = new Dictionary<int, int>();
int dimension = 3;

int[] elementTypesTemp;
IntPtr[][] elementTagsIntPtr;
IntPtr[][] elementNodeTags;
Gmsh.Mesh.GetElements(out elementTypesTemp, out elementTagsIntPtr, out elementNodeTags, dimension , -1);

// This reshuffling is required due to the way Gmsh 
// organizes the returned element data
for (int i = 0; i < elementTypesTemp.Length; ++i)
{
    var elementType = elementTypesTemp[i];

    int dim, order, numNodes, numPrimaryNodes;
    string elementName;
    double[] localNodeCoords;

    elementName = GmshCommon.Gmsh.Mesh.GetElementProperties(elementType, out dim, out order, out numNodes, out localNodeCoords, out numPrimaryNodes);

    for (int j = 0; j < elementTagsIntPtr[i].Length; ++j)
    {
        var elementTag = (int)elementTagsIntPtr[i][j];
        elementTypes[elementTag] = elementType;
        var elementNodes = new int[numNodes];

        for (int k = 0; k < numNodes; ++k)
        {
            elementNodes[k] = (int)elementNodeTags[i][j * numNodes + k];
        }

        elements[elementTag] = elementNodes;
    }
}

```

Then, to make nodes in PrePoMax…

```csharp
foreach (var entry in nodes)
{
    model.Mesh.Nodes.Add(entry .Key, new FeNode(entry .Key, entry .Value));
}

```

…and elements…

```csharp
var partId = 1;
foreach (var entry in elements)
{
    // Element types from http://gmsh.info/doc/texinfo/gmsh.html#MSH-file-format
    switch (elementTypes[entry.Key])
    {
        case (4): // 4-node tetrahedron. 
            model.Mesh.Elements.Add(entry.Key, new LinearTetraElement(entry.Key, partId , entry.Value));
            break;
        case (11): // 10-node second order tetrahedron
            model.Mesh.Elements.Add(entry.Key, new ParabolicTetraElement(entry.Key, partId , entry.Value));
            break;
        case (...): // other element types...
            model.Mesh.Elements.Add(entry.Key, new ...);
            break;
        default:
            break;
    }
}

```

---

<div class="post-metadata">

**Author:** ![tsvilans](https://yyz2.discourse-cdn.com/free1/user_avatar/prepomax.discourse.group/tsvilans/32/516_2.png) [@tsvilans](https://prepomax.discourse.group/u/tsvilans)\
**Post date:** [July 26, 2023, 9:44am UTC](https://prepomax.discourse.group/t/gmshcommon-a-net-cli-wrapper-for-gmsh/999/6 "2023-07-26T09:44:24Z")

</div>

Then there is more fun stuff to do with defining physical groups, making a compound mesh (fragmenting with the OCC kernel), and more 🙂

---

<div class="post-metadata">

**Author:** ![FEAnalyst](https://yyz2.discourse-cdn.com/free1/user_avatar/prepomax.discourse.group/feanalyst/32/688_2.png) [@FEAnalyst](https://prepomax.discourse.group/u/FEAnalyst)\
**Post date:** [July 26, 2023, 10:02am UTC](https://prepomax.discourse.group/t/gmshcommon-a-net-cli-wrapper-for-gmsh/999/7 "2023-07-26T10:02:28Z")

</div>

> [@tsvilans](#):
>
> defining physical groups

This part can be very important since without it you get unnecessary 1D and 2D elements in the exported input file containing a 3D mesh.

---

<div class="post-metadata">

**Author:** ![tsvilans](https://yyz2.discourse-cdn.com/free1/user_avatar/prepomax.discourse.group/tsvilans/32/516_2.png) [@tsvilans](https://prepomax.discourse.group/u/tsvilans)\
**Post date:** [July 26, 2023, 11:03am UTC](https://prepomax.discourse.group/t/gmshcommon-a-net-cli-wrapper-for-gmsh/999/8 "2023-07-26T11:03:54Z")

</div>

> This part can be very important since without it you get unnecessary 1D and 2D elements in the exported input file containing a 3D mesh.

The cool things is that with this way, you are in control of exactly what you transfer over to PrePoMax, since Gmsh isn’t exporting any `.inp` files. So you can decide how to construct the FE model.

That said, assigning and manipulating physical groups are already supported in GmshCommon 😉 This is so that we can create element- or node-sets from Gmsh entities - very useful for multi-part input geometries.

At some point I will try to document things better, but for now you can see what functions are available in the source code [here](https://github.com/tsvilans/gmsh_common/blob/main/src/GmshCommon/GmshCommon.h).

---

<div class="post-metadata">

**Author:** ![synt](https://yyz2.discourse-cdn.com/free1/user_avatar/prepomax.discourse.group/synt/32/4658_2.png) [@synt](https://prepomax.discourse.group/u/synt)\
**Post date:** [July 26, 2023, 6:26pm UTC](https://prepomax.discourse.group/t/gmshcommon-a-net-cli-wrapper-for-gmsh/999/9 "2023-07-26T18:26:28Z")

</div>

> [@tsvilans](#):
>
> Would be interesting to see how good Gmsh is at this…

possible by using extrusion based on surface with fully quad mesh (quasi-structured) or hex dominant mesh as an alternative.

both approach are semi and fully automatic i.e no partition is needed before.

---

<div class="post-metadata">

**Author:** ![Matej](https://avatars.discourse-cdn.com/v4/letter/m/a698b9/32.png) [@Matej](https://prepomax.discourse.group/u/Matej)\
**Post date:** [August 3, 2023, 11:18am UTC](https://prepomax.discourse.group/t/gmshcommon-a-net-cli-wrapper-for-gmsh/999/10 "2023-08-03T11:18:03Z")

</div>

I will add support for extruded mesh and for revolved mesh. But first, I will have to figure out how this works in Gmsh and how to incorporate it into PrePoMax.

---

<div class="post-metadata">

**Author:** ![synt](https://yyz2.discourse-cdn.com/free1/user_avatar/prepomax.discourse.group/synt/32/4658_2.png) [@synt](https://prepomax.discourse.group/u/synt)\
**Post date:** [August 3, 2023, 1:14pm UTC](https://prepomax.discourse.group/t/gmshcommon-a-net-cli-wrapper-for-gmsh/999/11 "2023-08-03T13:14:53Z")

</div>

thanks for interesting in extrusion and revolwing of surfaces to generates hexahedral element. may spliting surfaces by line curently available in PrePoMax be extended to a body.

quasi-structured algorithm no need a surfaces to be partiton before as common user task in structured quads.

![2023-03-07 14_52_52-Options - Mesh](https://global.discourse-cdn.com/free1/uploads/prepomax/original/2X/c/c3facc40ea80cf03bb1146209a277a3c071bbb9e.png)

 ![2023-03-08 01_48_05-Gmsh - C__Users_user_Documents_quasistructured.geo](https://global.discourse-cdn.com/free1/uploads/prepomax/original/2X/9/9a251156114ca687435ab1dfd9fbe983a83c3041.png)

 ![2023-03-07 06_48_49-Gmsh - C__Users_user_Documents_quasistructured_res5.unv](https://global.discourse-cdn.com/free1/uploads/prepomax/original/2X/c/cb4fca98ebbf3852c86c98ceee937c01cbff578d.png)

then a base of quad results can be extruded by thickness definition and number of element layer.

some workflow still required a partition when the model has intersection, this video [YouTube links](https://www.youtube.com/watch?v=hLe8M4QIuNE) is more detailed about the steps.

however, i did net yet to test for latest GMSH capabilities in normal extrusion of complex 3D surfaces or Nurbs.

---

<div class="post-metadata">

**Author:** ![Matej](https://avatars.discourse-cdn.com/v4/letter/m/a698b9/32.png) [@Matej](https://prepomax.discourse.group/u/Matej)\
**Post date:** [August 11, 2023, 2:20pm UTC](https://prepomax.discourse.group/t/gmshcommon-a-net-cli-wrapper-for-gmsh/999/12 "2023-08-11T14:20:18Z")

</div>

I am starting to test the capabilities of the Gmsh, and I also started to test the GmshCommon.dll. I managed to set it up and run a test model. Great (I was missing the x64 configuration at the beginning).

But I had no success in building the GmshCommon .dll from the source. I downloaded it in a separate folder, added the dependencies in the deps folder and tried compiling it using the solution file with Visual Studi 2017 and 2022, but I got the same error: unresolved external symbols. It seems the error occurs for all methods/functions of the class GmshCommon. Something is missing.

I know I am missing something basic, but I can not figure it out. @tsvilans any ideas?

---

<div class="post-metadata">

**Author:** ![tsvilans](https://yyz2.discourse-cdn.com/free1/user_avatar/prepomax.discourse.group/tsvilans/32/516_2.png) [@tsvilans](https://prepomax.discourse.group/u/tsvilans)\
**Post date:** [August 13, 2023, 11:45am UTC](https://prepomax.discourse.group/t/gmshcommon-a-net-cli-wrapper-for-gmsh/999/13 "2023-08-13T11:45:47Z")

</div>

Hmm… is it linking with the Gmsh libs from the SDK? It sounds like it cannot find the Gmsh dependencies… What is your `deps` folder structure?

---

<div class="post-metadata">

**Author:** ![Matej](https://avatars.discourse-cdn.com/v4/letter/m/a698b9/32.png) [@Matej](https://prepomax.discourse.group/u/Matej)\
**Post date:** [August 13, 2023, 2:26pm UTC](https://prepomax.discourse.group/t/gmshcommon-a-net-cli-wrapper-for-gmsh/999/14 "2023-08-13T14:26:05Z")

</div>

My opinion is the same but I do not know why the Gmsh files would not be found. Did you apply any special settings when you prepared the project? And I am wondering which software you are using to build it and which version of it.

I created a folder Gmsh and used the instructions you provided. I downloaded the gmsh SDK and copied it into deps folder (I also checked the settings for the Include and Library directories and despite that they were pointing to the right path I added additional absolute paths to it).

 ![image](https://global.discourse-cdn.com/free1/uploads/prepomax/original/2X/4/477edb34dc6b6cb53335eb988711eae3422628d3.png)

---

<div class="post-metadata">

**Author:** ![tsvilans](https://yyz2.discourse-cdn.com/free1/user_avatar/prepomax.discourse.group/tsvilans/32/516_2.png) [@tsvilans](https://prepomax.discourse.group/u/tsvilans)\
**Post date:** [August 14, 2023, 10:03am UTC](https://prepomax.discourse.group/t/gmshcommon-a-net-cli-wrapper-for-gmsh/999/15 "2023-08-14T10:03:55Z")

</div>

Interesting. I will take a closer look after an imminent deadline this week… it must be something simple.  
I’m using Visual Studio 2022, nothing really extraordinary. I will check the paths as well…

---

<div class="post-metadata">

**Author:** ![tsvilans](https://yyz2.discourse-cdn.com/free1/user_avatar/prepomax.discourse.group/tsvilans/32/516_2.png) [@tsvilans](https://prepomax.discourse.group/u/tsvilans)\
**Post date:** [August 14, 2023, 10:38am UTC](https://prepomax.discourse.group/t/gmshcommon-a-net-cli-wrapper-for-gmsh/999/16 "2023-08-14T10:38:11Z")

</div>

This is where it is looking for the libs:

 ![image](https://global.discourse-cdn.com/free1/uploads/prepomax/original/2X/6/666ebaa1c72d86c8455ca39301649f2ed0a0287b.png)

So it looks the same as yours. What does your `$(SolutionDir)` variable resolve to?

---

<div class="post-metadata">

**Author:** ![Matej](https://avatars.discourse-cdn.com/v4/letter/m/a698b9/32.png) [@Matej](https://prepomax.discourse.group/u/Matej)\
**Post date:** [August 14, 2023, 12:51pm UTC](https://prepomax.discourse.group/t/gmshcommon-a-net-cli-wrapper-for-gmsh/999/17 "2023-08-14T12:51:54Z")

</div>

The `$(SolutionDir)` is equal to C:\Pc\Programiranje\Gmsh\gmsh\_common\src

If I change the Configuration Type to a Static library, it compiles it without errors.

 ![image](https://global.discourse-cdn.com/free1/uploads/prepomax/original/2X/9/9ef66954030e6517e758d7e0ce20a2fb63b7a6c4.png)

---

<div class="post-metadata">

**Author:** ![tsvilans](https://yyz2.discourse-cdn.com/free1/user_avatar/prepomax.discourse.group/tsvilans/32/516_2.png) [@tsvilans](https://prepomax.discourse.group/u/tsvilans)\
**Post date:** [August 15, 2023, 11:55am UTC](https://prepomax.discourse.group/t/gmshcommon-a-net-cli-wrapper-for-gmsh/999/18 "2023-08-15T11:55:11Z")

</div>

> [@Matej](#):
>
> (I also checked the settings for the Include and Library directories and despite that they were pointing to the right path I added additional absolute paths to it).

Do you think this might cause problems if it finds the same libs twice? Or do you mean you used absolute paths **instead** of relative ones?

The only other thing I can think of if it is somehow related to the CLI, but I’m kind of in the dark there…

> [@Matej](#):
>
> If I change the Configuration Type to a Static library, it compiles it without errors.

This is very weird… It needs to be a dynamic library, but I’m not sure why it would work as a static library…

---

<div class="post-metadata">

**Author:** ![tsvilans](https://yyz2.discourse-cdn.com/free1/user_avatar/prepomax.discourse.group/tsvilans/32/516_2.png) [@tsvilans](https://prepomax.discourse.group/u/tsvilans)\
**Post date:** [August 15, 2023, 11:58am UTC](https://prepomax.discourse.group/t/gmshcommon-a-net-cli-wrapper-for-gmsh/999/19 "2023-08-15T11:58:05Z")

</div>

Does this page look the same on your side?

 ![image](https://global.discourse-cdn.com/free1/uploads/prepomax/original/2X/f/fbec3d32cbdd22b3839a107e750cf4cf2642cfaf.png)

---

<div class="post-metadata">

**Author:** ![Matej](https://avatars.discourse-cdn.com/v4/letter/m/a698b9/32.png) [@Matej](https://prepomax.discourse.group/u/Matej)\
**Post date:** [August 15, 2023, 7:44pm UTC](https://prepomax.discourse.group/t/gmshcommon-a-net-cli-wrapper-for-gmsh/999/20 "2023-08-15T19:44:45Z")

</div>

The settings are the same.

I tried it on a second “clean” machine and I get the same error.

Can you compare the command line from C/C++ settings with your version:

`/Yu"pch.h" /ifcOutput "x64\Debug\" /GS /W3 /Zc:wchar_t /I"C:\Programiranje\Gmsh\gmsh_common\src\..\deps\gmsh-4.11.1-Windows64-sdk\include" /Zi /O2 /Fd"x64\Debug\vc143.pdb" /Zc:inline /fp:precise /D "_DEBUG" /D "_WINDLL" /D "_UNICODE" /D "UNICODE" /errorReport:prompt /WX- /Zc:forScope /clr /FU"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.8\mscorlib.dll" /FU"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.8\System.Data.dll" /FU"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.8\System.dll" /FU"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.8\System.Xml.dll" /MD /FC /Fa"x64\Debug\" /EHa /nologo /Fo"x64\Debug\" /Fp"x64\Debug\GmshCommon.pch" /diagnostics:column`

And the command line from the Linker settings:

`/OUT:"C:\Programiranje\Gmsh\gmsh_common\src\..\bin\GmshCommon.dll" /MANIFEST /NXCOMPAT /PDB:"C:\Programiranje\Gmsh\gmsh_common\src\..\bin\GmshCommon.pdb" /DYNAMICBASE "gmsh.lib" /FIXED:NO /DEBUG:FULL /DLL /MACHINE:X64 /PGD:"C:\Programiranje\Gmsh\gmsh_common\src\..\bin\GmshCommon.pgd" /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /ManifestFile:"x64\Debug\GmshCommon.dll.intermediate.manifest" /LTCGOUT:"x64\Debug\GmshCommon.iobj" /ERRORREPORT:PROMPT /ILK:"x64\Debug\GmshCommon.ilk" /NOLOGO /LIBPATH:"C:\Programiranje\Gmsh\gmsh_common\src\..\deps\gmsh-4.11.1-Windows64-sdk\lib" /TLBID:1`

This lines are from my second machine where the base folder is: `C:\Programiranje\Gmsh\gmsh_common`

[Next page](https://prepomax.discourse.group/t/gmshcommon-a-net-cli-wrapper-for-gmsh/999.md?page=2)
