Skip to content

GitLab

  • Projects
  • Groups
  • Snippets
  • Help
    • Loading...
  • Help
    • Help
    • Support
    • Community forum
    • Submit feedback
    • Contribute to GitLab
  • Sign in / Register
gmsh
gmsh
  • Project overview
    • Project overview
    • Details
    • Activity
    • Releases
  • Repository
    • Repository
    • Files
    • Commits
    • Branches
    • Tags
    • Contributors
    • Graph
    • Compare
  • Issues 111
    • Issues 111
    • List
    • Boards
    • Labels
    • Service Desk
    • Milestones
  • Merge Requests 5
    • Merge Requests 5
  • CI / CD
    • CI / CD
    • Pipelines
    • Jobs
    • Schedules
  • Operations
    • Operations
    • Incidents
    • Environments
  • Analytics
    • Analytics
    • CI / CD
    • Repository
    • Value Stream
  • Wiki
    • Wiki
  • Snippets
    • Snippets
  • Members
    • Members
  • Collapse sidebar
  • Activity
  • Graph
  • Create a new issue
  • Jobs
  • Commits
  • Issue Boards
  • gmsh
  • gmshgmsh
  • Issues
  • #1100

Closed
Open
Opened Dec 03, 2020 by Keunwoo Park@Keunwoo

Question about CPU utilization for multithreading

Hi. I'm trying to generate a mesh with multithreads. I installed Gmsh with OpenMP enabled. However, Gmsh seems like it only uses a single core.

This is the code that I used. It is just a slightly different version of t16.py in the tutorial.

# ------------------------------------------------------------------------------
#
#  Gmsh Python tutorial 16
#
#  Constructive Solid Geometry, OpenCASCADE geometry kernel
#
# ------------------------------------------------------------------------------

# Instead of constructing a model in a bottom-up fashion with Gmsh's built-in
# geometry kernel, starting with version 3 Gmsh allows you to directly use
# alternative geometry kernels. Here we will use the OpenCASCADE kernel.

import gmsh
import math
import sys

gmsh.initialize()
gmsh.option.setNumber("General.NumThreads", 4)
print("nt:", gmsh.option.getNumber("General.NumThreads"))
gmsh.model.add("t16")

# Let's build the same model as in `t5.py', but using constructive solid
# geometry.

# We can log all messages for further processing with:
gmsh.logger.start()

# We first create two cubes:
gmsh.model.occ.addBox(0, 0, 0, 1, 1, 1, 1)
gmsh.model.occ.addBox(0, 0, 0, 0.5, 0.5, 0.5, 2)

# We apply a boolean difference to create the "cube minus one eigth" shape:
gmsh.model.occ.cut([(3, 1)], [(3, 2)], 3)

# Boolean operations with OpenCASCADE always create new entities. By default the
# extra arguments `removeObject' and `removeTool' in `cut()' are set to `True',
# which will delete the original entities.

# We then create the five spheres:
x = 0
y = 0.75
z = 0
r = 0.09
holes = []
for t in range(1, 6):
    x += 0.166
    z += 0.166
    gmsh.model.occ.addSphere(x, y, z, r, 3 + t)
    holes.append((3, 3 + t))

# If we had wanted five empty holes we would have used `cut()' again. Here we
# want five spherical inclusions, whose mesh should be conformal with the mesh
# of the cube: we thus use `fragment()', which intersects all volumes in a
# conformal manner (without creating duplicate interfaces):
ov, ovv = gmsh.model.occ.fragment([(3, 3)], holes)

# ov contains all the generated entities of the same dimension as the input
# entities:
print("fragment produced volumes:")
for e in ov:
    print(e)

# ovv contains the parent-child relationships for all the input entities:
print("before/after fragment relations:")
for e in zip([(3, 3)] + holes, ovv):
    print("parent " + str(e[0]) + " -> child " + str(e[1]))

gmsh.model.occ.synchronize()

# When the boolean operation leads to simple modifications of entities, and if
# one deletes the original entities, Gmsh tries to assign the same tag to the
# new entities. (This behavior is governed by the
# `Geometry.OCCBooleanPreserveNumbering' option.)

# Here the `Physical Volume' definitions can thus be made for the 5 spheres
# directly, as the five spheres (volumes 4, 5, 6, 7 and 8), which will be
# deleted by the fragment operations, will be recreated identically (albeit with
# new surfaces) with the same tags:
for i in range(1, 6):
    gmsh.model.addPhysicalGroup(3, [3 + i], i)

# The tag of the cube will change though, so we need to access it
# programmatically:
gmsh.model.addPhysicalGroup(3, [ov[-1][1]], 10)

# Creating entities using constructive solid geometry is very powerful, but can
# lead to practical issues for e.g. setting mesh sizes at points, or identifying
# boundaries.

# To identify points or other bounding entities you can take advantage of the
# `getEntities()', `getBoundary()' and `getEntitiesInBoundingBox()' functions:

lcar1 = .01
lcar2 = .0005
lcar3 = .055

# Assign a mesh size to all the points:
gmsh.model.mesh.setSize(gmsh.model.getEntities(0), lcar1)

# Override this constraint on the points of the five spheres:
gmsh.model.mesh.setSize(gmsh.model.getBoundary(holes, False, False, True),
                        lcar3)

# Select the corner point by searching for it geometrically:
eps = 1e-3
ov = gmsh.model.getEntitiesInBoundingBox(0.5 - eps, 0.5 - eps, 0.5 - eps,
                                         0.5 + eps, 0.5 + eps, 0.5 + eps, 0)
gmsh.model.mesh.setSize(ov, lcar2)

gmsh.model.mesh.generate(3)

gmsh.write("t16.msh")

# Additional examples created with the OpenCASCADE geometry kernel are available
# in `t18.py', `t19.py' and `t20.py', as well as in the `demos/api' directory.

# Inspect the log:
log = gmsh.logger.get()
print("Logger has recorded " + str(len(log)) + " lines")
gmsh.logger.stop()

# Launch the GUI to see the results:
if '-nopopup' not in sys.argv:
    gmsh.fltk.run()

gmsh.finalize()

I set General.Numthreads to 4 and checked it was correctly updated. However, when I checked CPU utilization, only one CPU was running heavily. Screenshot_2020-12-03_225937

Is this a normal behavior? Or is there something that I'm missing? Any advice is appreciated.

Assignee
Assign to
None
Milestone
None
Assign milestone
Time tracking
None
Due date
None
Reference: gmsh/gmsh#1100