# Boundary conditions of newly added csg.CSGeometry is automatically merged

Hi, I post an error of netgen here: bc and mat will be erroneous merged in netgen.csg · Issue #49 · NGSolve/netgen · GitHub

I want to add 2 small cylinders (electrodes) to 1 big cylinder, the boundary conditions are set on the outer surface of the small cylinder. However, If I place them at the same z axis with 0.5 spacing, the bc will be automatically merged. If I offset 1 small cylinder with theta=theta+0.01, then its bc will be preserved. Any hint on this issue?

``````import numpy as np
from netgen import csg
from ngsolve.comp import Mesh

def cylinder(p0, p1, unit_vec, r, bc="bc"):
""" a pointed cylinder (numpy interface) """
# generate CSG primitives
csg_p0 = csg.Pnt(p0, p0, p0)
csg_p1 = csg.Pnt(p1, p1, p1)
csg_vec = csg.Vec(unit_vec, unit_vec, unit_vec)

# generate cylinder shape
bot = csg.Plane(csg_p0, -csg_vec)
top = csg.Plane(csg_p1, csg_vec)
cy_surface = csg.Cylinder(csg_p0, csg_p1, r)

# specify bc on top
top.bc(bc)

# geo
cy = top * cy_surface * bot

return cy

def unit_cylinder(h=1.0, r=0.5, bc="cyl"):
""" scaled unit z-axis cylinder """
p0 = [0, 0, 0]
p1 = [0, 0, h]
unit_vec = [0, 0, 1]
return cylinder(p0, p1, unit_vec, r, bc)

def electrode_cylinder(p0=[0, 0, 0], unit_vec=[1, 0, 0], shape=[0.1, 0.1],
bc="e0"):
"""
cylinder electrode (numpy interface)

shape: NDArray
"""
r, thick = shape
# calculate the center of the other face
p1 = np.asarray(p0) + thick * np.asarray(unit_vec)

# generate cylinder electrode with annotation
ele = cylinder(p0, p1, unit_vec, r, bc)
ele.mat('agcl')

return ele

def cylinder_with_electrodes():
""" [test only, will be deleted] """
h = 1.0
r = 0.5
g0 = unit_cylinder(h=h, r=r)
g0.mat('g0')

# generate cylinder electrode
ele_shape = [0.1, 0.1]  # radius, thick
thick = ele_shape
ele_pos = [30, h/2.0]  # angle (degree), z

# infer locations
rad = ele_pos * 2 * np.pi / 360.0
# warning: a thin contact of electrode with domain will cause
# netgen failed to generate proper mesh
p0 = (r - thick/2.0)*unit_vec
p0 = ele_pos

# place 1st electrode
ele = electrode_cylinder(p0, unit_vec, shape=ele_shape, bc="e0")
# geo = g0 + ele

# place 2nd electrode
p0 += 0.25
# p0 += 0.01  # <-- https://github.com/NGSolve/netgen/issues/49
ele2 = electrode_cylinder(p0, unit_vec, shape=ele_shape, bc="e1")
# geo = geo + ele2
ele = ele - g0
ele2 = ele2 - g0

return g0, ele, ele2

if __name__ == "__main__":
g, ele, ele2 = cylinder_with_electrodes()
geo = csg.CSGeometry()

ngmesh = geo.GenerateMesh(maxh=0.1)

mesh = Mesh(ngmesh)
# mesh.Curve(3)

print(mesh.GetBoundaries())
print(mesh.GetMaterials())``````

Hi liubenyuan,

there is the possiblity to tell NETGEN to use the correct boundary condition by using the bcmod flag

``` geo.Add (cyl, bcmod=[(plane,'bc')])```

The attached code demonstrates this for the example of a simple cube “in a cube”.

Best,
Michael

https://ngsolve.org/media/kunena/attachments/889/bc_mod.py

Attachment: bc_mod.py

But in order to use bcmod, you should keep top2 within you scope, right?
I need to generate some elementary volumetric shapes, these shapes are the domain to be computed. And then add some electrodes around it, which is written in a separate function, calls csg codes. Is there any other way in doing this?

Thank you. I use your method, and the function electrode_cylinder is now returning both a CSGeometry and its top surface. The bcs are correctly setup using bcmod.

https://github.com/liubenyuan/netgen-note/blob/master/examples/csg_issue_bc_cyl.py

But, why the bc is merging in the original code? Do I have to manually set the bc using bcmod every time using CSG?

Hi, Michael

Your solution using bcmod works for me. But I would like to know, in the function def cylinder_with_electrodes(), line 26, If I set a small offset p0 += 0.01, both the bcs of ele1 and ele2 will be kept. But when I comment this line out, the bcs of ele1 and ele2 are merged. Is it a feature of netgen or is it an issue?

Best.

Benyuan

This isn’t a feature, but has historic reasons. It is on the radar to fix this when someone got time to clean that code up.
Basically Netgen detects same objects and uses only the first, this leads to the wrong boundary condition.