4.1.2 CSG in 2D¶

An alternative approach to SplineGeometry is the new CSG2d interface, which allows using constructive solid geometry definitions (similar to 3D).

This feature is new and currently has some limitations compared to SplineGeometry, like periodic boundaries.

First Example¶

[1]:

from netgen.geom2d import CSG2d, Circle, Rectangle

geo = CSG2d()

# define some primitives
circle = Circle( center=(0,0), radius=1.0, mat="mat1", bc="bc_circle" )
rect = Rectangle( pmin=(0,0), pmax=(1.5,1.5), mat="mat2", bc="bc_rect" )

# use operators +, - and * for union, difference and intersection operations
domain1 = circle - rect
domain2 = circle * rect
domain2.Mat("mat3").Maxh(0.1) # change domain name and maxh
domain3 = rect-circle

# add top level objects to geometry

# generate mesh
m = geo.GenerateMesh(maxh=0.3)

# use NGSolve just for visualization
from ngsolve.webgui import Draw
from ngsolve import Mesh, VOL
mesh = Mesh(m)
mesh.Curve(3)
cf = mesh.RegionCF(VOL, dict(mat1=0, mat2=4, mat3=7))
Draw(cf, mesh)

[1]:

BaseWebGuiScene


Solid2d class¶

Internally, there is just one solid type (Solid2d), containing a closed chain of quadratic spline segments. For convenience, there are a few helper Functions, like Rectangle and Circle used above.

The general constructor of Solid2d expects a list of points. To define curved segments and set individual edge propierties (like boundary condition name and maxh), you can put EdgeInfo objects between two points, or a PointInfo object after a Point.

[2]:

from netgen.geom2d import EdgeInfo as EI, PointInfo as PI, Solid2d

geo = CSG2d()

rect = Solid2d( [
(0,0),
(1,0),
PI(maxh=0.02),   # set maxh at point (1,0)
EI(bc="right"),  # set bc for segment (1,0)-(1,1)
(1,1),
(0,1),
EI(maxh=0.05)    # set maxh for segment (0,1)-(0,0)
], mat="rect" )

circle = Solid2d( [
(0, -1),
EI(( 1,  -1)), # control point for quadratic spline
(1,0),
EI(( 1,  1), maxh=0.05), # spline with maxh
(0,1),
EI((-1,  1)),
(-1,0),
EI((-1, -1), bc="left"), # spline with bc
])

# Solid2d has some methods to change it in-place:
# Move(), Scale() and Rotate()
circle.Scale(0.5).Move((2,0))
circles = circle + circle.Copy().Move((-3,0))

rect.Rotate(45, center=(0.5,0.5))

mesh = Mesh(geo.GenerateMesh())
mesh.Curve(3)
print(mesh.GetBoundaries())
Draw(mesh)

('', 'right', '', '', '', '', '', 'left', '', '', '', 'left')

[2]:

BaseWebGuiScene

[3]:

help(Solid2d)

Help on class Solid2d in module netgen.libngpy._geom2d:

class Solid2d(pybind11_builtins.pybind11_object)
|  Method resolution order:
|      Solid2d
|      pybind11_builtins.pybind11_object
|      builtins.object
|
|  Methods defined here:
|
|  BC(...)
|      BC(self: netgen.libngpy._geom2d.Solid2d, arg0: str) -> netgen.libngpy._geom2d.Solid2d
|
|  Copy(...)
|      Copy(self: netgen.libngpy._geom2d.Solid2d) -> netgen.libngpy._geom2d.Solid2d
|
|  Layer(...)
|      Layer(self: netgen.libngpy._geom2d.Solid2d, arg0: int) -> netgen.libngpy._geom2d.Solid2d
|
|  Mat(...)
|      Mat(self: netgen.libngpy._geom2d.Solid2d, arg0: str) -> netgen.libngpy._geom2d.Solid2d
|
|  Maxh(...)
|      Maxh(self: netgen.libngpy._geom2d.Solid2d, arg0: float) -> netgen.libngpy._geom2d.Solid2d
|
|  Move(...)
|      Move(self: netgen.libngpy._geom2d.Solid2d, arg0: netgen.libngpy._meshing.Vec2d) -> netgen.libngpy._geom2d.Solid2d
|
|  Rotate(...)
|      Rotate(self: netgen.libngpy._geom2d.Solid2d, angle: float, center: netgen.libngpy._meshing.Point2d = <netgen.libngpy._meshing.Point2d object at 0x7fcd4c3b0bb0>) -> netgen.libngpy._geom2d.Solid2d
|
|  Scale(...)
|      Scale(*args, **kwargs)
|
|      1. Scale(self: netgen.libngpy._geom2d.Solid2d, arg0: float) -> netgen.libngpy._geom2d.Solid2d
|
|      2. Scale(self: netgen.libngpy._geom2d.Solid2d, arg0: netgen.libngpy._meshing.Vec2d) -> netgen.libngpy._geom2d.Solid2d
|
|      __add__(self: netgen.libngpy._geom2d.Solid2d, arg0: netgen.libngpy._geom2d.Solid2d) -> netgen.libngpy._geom2d.Solid2d
|
|      __iadd__(self: netgen.libngpy._geom2d.Solid2d, arg0: netgen.libngpy._geom2d.Solid2d) -> netgen.libngpy._geom2d.Solid2d
|
|  __imul__(...)
|      __imul__(self: netgen.libngpy._geom2d.Solid2d, arg0: netgen.libngpy._geom2d.Solid2d) -> netgen.libngpy._geom2d.Solid2d
|
|  __init__(...)
|      __init__(*args, **kwargs)
|
|      1. __init__(self: netgen.libngpy._geom2d.Solid2d) -> None
|
|      2. __init__(self: netgen.libngpy._geom2d.Solid2d, points: Array[Union[netgen.libngpy._meshing.Point2d, netgen::EdgeInfo, netgen::PointInfo]], mat: str = '', bc: str = '') -> None
|
|  __isub__(...)
|      __isub__(self: netgen.libngpy._geom2d.Solid2d, arg0: netgen.libngpy._geom2d.Solid2d) -> netgen.libngpy._geom2d.Solid2d
|
|  __mul__(...)
|      __mul__(self: netgen.libngpy._geom2d.Solid2d, arg0: netgen.libngpy._geom2d.Solid2d) -> netgen.libngpy._geom2d.Solid2d
|
|  __sub__(...)
|      __sub__(self: netgen.libngpy._geom2d.Solid2d, arg0: netgen.libngpy._geom2d.Solid2d) -> netgen.libngpy._geom2d.Solid2d
|
|  ----------------------------------------------------------------------
|  Static methods inherited from pybind11_builtins.pybind11_object:
|
|  __new__(*args, **kwargs) from pybind11_builtins.pybind11_type
|      Create and return a new object.  See help(type) for accurate signature.


[4]:

help(PI)

Help on class PointInfo in module netgen.libngpy._geom2d:

class PointInfo(pybind11_builtins.pybind11_object)
|  Method resolution order:
|      PointInfo
|      pybind11_builtins.pybind11_object
|      builtins.object
|
|  Methods defined here:
|
|  __init__(...)
|      __init__(*args, **kwargs)
|
|      1. __init__(self: netgen.libngpy._geom2d.PointInfo) -> None
|
|      2. __init__(self: netgen.libngpy._geom2d.PointInfo, maxh: float) -> None
|
|      3. __init__(self: netgen.libngpy._geom2d.PointInfo, name: str) -> None
|
|      4. __init__(self: netgen.libngpy._geom2d.PointInfo, maxh: float, name: str) -> None
|
|  ----------------------------------------------------------------------
|  Static methods inherited from pybind11_builtins.pybind11_object:
|
|  __new__(*args, **kwargs) from pybind11_builtins.pybind11_type
|      Create and return a new object.  See help(type) for accurate signature.


[5]:

help(EI)

Help on class EdgeInfo in module netgen.libngpy._geom2d:

class EdgeInfo(pybind11_builtins.pybind11_object)
|  Method resolution order:
|      EdgeInfo
|      pybind11_builtins.pybind11_object
|      builtins.object
|
|  Methods defined here:
|
|  __init__(...)
|      __init__(*args, **kwargs)
|
|      1. __init__(self: netgen.libngpy._geom2d.EdgeInfo) -> None
|
|      2. __init__(self: netgen.libngpy._geom2d.EdgeInfo, control_point: netgen.libngpy._meshing.Point2d) -> None
|
|      3. __init__(self: netgen.libngpy._geom2d.EdgeInfo, maxh: float) -> None
|
|      4. __init__(self: netgen.libngpy._geom2d.EdgeInfo, bc: str) -> None
|
|      5. __init__(self: netgen.libngpy._geom2d.EdgeInfo, control_point: Optional[netgen.libngpy._meshing.Point2d] = None, maxh: float = 1e+99, bc: str = '') -> None
|
|  ----------------------------------------------------------------------
|  Static methods inherited from pybind11_builtins.pybind11_object:
|
|  __new__(*args, **kwargs) from pybind11_builtins.pybind11_type
|      Create and return a new object.  See help(type) for accurate signature.


[ ]: