CFD Online Discussion Forums

CFD Online Discussion Forums (https://www.cfd-online.com/Forums/)
-   Mesh Generation & Pre-Processing (https://www.cfd-online.com/Forums/mesh-generation/)
-   -   Gmsh.jl (https://www.cfd-online.com/Forums/mesh-generation/235036-gmsh-jl.html)

dlahaye March 29, 2021 12:19

Gmsh.jl
 
Short Version of Query:

Consider a unit square (2D) domain and a triangular mesh on this geometry. I would like to perform a loop over all the elements in the mesh, compute the area of each triangle and verify that the sum of all areas equals one. I I am not sure that I am using connectivity between the elements and the nodes correctly. That is, I have doubt on the functions getNodes() and getElements() in Julia interface to gmsh correctly. I am obtaining elements with zero area.

Longer Version of Query:

using Plots
using Gmsh

gmsh.initialize()
#..define the model
model = gmsh.model
model.add("Square")
#..define mesh density near a point
cl = 0.5;
#..define four points in the geometry
gmsh.model.geo.addPoint(0.5, 0.5, 0., cl, 1)
gmsh.model.geo.addPoint(-0.5, 0.5, 0., cl, 2)
gmsh.model.geo.addPoint(-0.5, -0.5,0., cl, 3)
gmsh.model.geo.addPoint(0.5, -0.5, 0., cl, 4)
#..define four edges in the geometry
gmsh.model.geo.addLine(1, 2, 1)
gmsh.model.geo.addLine(2, 3, 2)
gmsh.model.geo.addLine(3, 4, 3)
gmsh.model.geo.addLine(4, 1, 4)
#..define outer boundary
gmsh.model.geo.addCurveLoop([1, 2, 3, 4], 1)
#..define planar surface
gmsh.model.geo.addPlaneSurface([1], 1)
#..define physics
gmsh.model.addPhysicalGroup(1, [1], 1)
#..synchronize the model
gmsh.model.geo.synchronize()
#..generate the mesh in 2D
model.mesh.generate(2)
#..save the mesh to file for future reference
gmsh.write("square.msh")
# Finalize GMSH
#gmsh.finalize()

node_ids, node_coord, _ = gmsh.model.mesh.getNodes()
nnodes = length(node_ids)
xnode = node_coord[1:3:end]
ynode = node_coord[2:3:end]

#..Plot the mesh nodes

#..plots nodes only
scatter(xnode, ynode)

#..or alternatively
using GR
z = ones(length(xnode))
trisurf(xnode,ynode,z)

#..Retrieve the set of mesh nodes and the number of nodes (nnodes)

# Observe that although the mesh is a two-dimensional mesh, the z-coordinate that is equal to zero is stored as well. Observe that the coordinates are stored contiguously

node_ids, node_coord, _ = gmsh.model.mesh.getNodes()
nnodes = length(node_ids)
xnode = node_coord[1:3:end]
ynode = node_coord[2:3:end]

#..Retrieve the set of mesh elements and the number of elements in the mesh..

element_types, element_ids, element_connectivity = gmsh.model.mesh.getElements(2,1)
nelements = length(element_ids[1])

for element_id in 1:nelements

node1_id = element_connectivity[1][3*(element_id-1)+1]
node2_id = element_connectivity[1][3*(element_id-1)+2]
node3_id = element_connectivity[1][3*(element_id-1)+3]

xnode1 = xnode[node1_id]; xnode2 = xnode[node2_id]; xnode3 = xnode[node3_id];
ynode1 = ynode[node1_id]; ynode2 = ynode[node2_id]; ynode3 = ynode[node3_id];

x12 = xnode2 - xnode1; x13 = xnode3-xnode1;
y12 = ynode2 - ynode1; y13 = ynode3-ynode1;

area_id = x12*y13 - x13*y12; area_id = abs(area_id)/2

println("on element ", element_id, " node-1 has global number ", node1_id)
println("on element ", element_id, " node-2 has global number ", node2_id)
println("on element ", element_id, " node-3 has global number ", node3_id)
println("on element ", element_id, " area = ", area_id)
println(" ")

end


Components Used:
I am using Julia Version 1.3.1 and koehlerson/gmsh.jl .

Thank you in advance for your input, Domenico Lahaye.

dlahaye March 30, 2021 08:30

edit: issue resolved by reordering nodes prior to loop over elements.

#..1/ Define geometry and mesh

gmsh.initialize()
#..define the model
model = gmsh.model
model.add("Square")
#..define mesh density near a point
cl = 0.1;
#..define four points in the geometry
gmsh.model.geo.addPoint(0.5, 0.5, 0., cl, 1)
gmsh.model.geo.addPoint(-0.5, 0.5, 0., cl, 2)
gmsh.model.geo.addPoint(-0.5, -0.5,0., cl, 3)
gmsh.model.geo.addPoint(0.5, -0.5, 0., cl, 4)
#..define four edges in the geometry
gmsh.model.geo.addLine(1, 2, 1)
gmsh.model.geo.addLine(2, 3, 2)
gmsh.model.geo.addLine(3, 4, 3)
gmsh.model.geo.addLine(4, 1, 4)
#..define outer boundary
gmsh.model.geo.addCurveLoop([1, 2, 3, 4], 1)
#..define planar surface
gmsh.model.geo.addPlaneSurface([1], 1)
#..define physics
gmsh.model.addPhysicalGroup(1, [1], 1)
#..synchronize the model
gmsh.model.geo.synchronize()
# gmsh.option.setNumber("Mesh.MeshSizeMin", 5)
# gmsh.option.setNumber("Mesh.MeshSizeMax", 10)
#..generate the mesh in 2D
model.mesh.generate(2)
#..save the mesh to file for future reference
gmsh.write("square.msh")
# Finalize GMSH
#gmsh.finalize()

#..2/ Get and sort the mesh nodes
#..Observe that although the mesh is two-dimensional,
#..the z-coordinate that is equal to zero is stored as well.
#..Observe that the coordinates are stored contiguously for computational
#..efficiency

node_ids, node_coord, _ = gmsh.model.mesh.getNodes()
nnodes = length(node_ids)
#..sort the node coordinates by ID, such that Node one sits at row 1
tosort = [node_ids node_coord[1:3:end] node_coord[2:3:end]];
sorted = sortslices(tosort , dims = 1);
node_ids = sorted[:,1]
xnode = sorted[:,2]
ynode = sorted[:,3]

#..3/ Plotting the mesh

#..first alternative of two: plotting the nodes only
scatter(xnode, ynode)

#..second alternative of two: plotting the elements
z = ones(length(xnode))
trisurf(xnode,ynode,z)

#..4/ Get the mesh elements

element_types, element_ids, element_connectivity = gmsh.model.mesh.getElements(2)
nelements = length(element_ids[1])

#..5/ Perform a loop over the elements

for element_id in 1:nelements

node1_id = element_connectivity[1][3*(element_id-1)+1]
node2_id = element_connectivity[1][3*(element_id-1)+2]
node3_id = element_connectivity[1][3*(element_id-1)+3]

xnode1 = xnode[node1_id]; xnode2 = xnode[node2_id]; xnode3 = xnode[node3_id];
ynode1 = ynode[node1_id]; ynode2 = ynode[node2_id]; ynode3 = ynode[node3_id];

x12 = xnode2 - xnode1; x13 = xnode3-xnode1;
y12 = ynode2 - ynode1; y13 = ynode3-ynode1;

area_id = x12*y13 - x13*y12; area_id = abs(area_id)/2

println("on element ", element_id, " node-1 has global number ", node1_id)
println("on element ", element_id, " node-2 has global number ", node2_id)
println("on element ", element_id, " node-3 has global number ", node3_id)
println("on element ", element_id, " area = ", area_id)
println(" ")

end


All times are GMT -4. The time now is 03:43.