Boundary conditions of newly added csg.CSGeometry is automatically merged

More
4 years 11 months ago - 4 years 11 months ago #2185 by liubenyuan
Hi, I post an error of netgen here: github.com/NGSolve/netgen/issues/49

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?
Code:
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[0], p0[1], p0[2]) csg_p1 = csg.Pnt(p1[0], p1[1], p1[2]) csg_vec = csg.Vec(unit_vec[0], unit_vec[1], unit_vec[2]) # 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 [radius, thickness] """ 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[1] ele_pos = [30, h/2.0] # angle (degree), z # infer locations rad = ele_pos[0] * 2 * np.pi / 360.0 unit_vec = np.array([np.cos(rad), np.sin(rad), 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[2] = ele_pos[1] # place 1st electrode ele = electrode_cylinder(p0, unit_vec, shape=ele_shape, bc="e0") # geo = g0 + ele # place 2nd electrode p0[2] += 0.25 # p0[0] += 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() geo.Add(g) geo.Add(ele) geo.Add(ele2) ngmesh = geo.GenerateMesh(maxh=0.1) mesh = Mesh(ngmesh) # mesh.Curve(3) print(mesh.GetBoundaries()) print(mesh.GetMaterials())
Last edit: 4 years 11 months ago by liubenyuan.
More
4 years 11 months ago #2186 by mneunteufel
Hi liubenyuan,

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

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

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

Best,
Michael

File Attachment:

File Name: bc_mod.py
File Size:1 KB
Attachments:
The following user(s) said Thank You: liubenyuan
More
4 years 11 months ago #2191 by liubenyuan
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?
More
4 years 11 months ago - 4 years 11 months ago #2192 by liubenyuan
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.

github.com/liubenyuan/netgen-note/blob/m.../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?
Last edit: 4 years 11 months ago by liubenyuan.
More
4 years 11 months ago #2220 by liubenyuan
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] += 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
More
4 years 11 months ago #2223 by christopher
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.
The following user(s) said Thank You: liubenyuan
Time to create page: 0.108 seconds