Changing boundary names via bcmod argument of CSGeometry::Add

More
1 year 8 months ago - 1 year 8 months ago #4696 by orlandini
Hello,

In my geometry I have a cylinder embedded in a cube. I also have a plane cutting these cylinder in the transverse direction. I would like to give different names for the surfaces in the plane (surface inside the cylinder and surface outside the cylinder)

Code:
from ngsolve import * import netgen.gui from netgen.csg import * d_box = 1 r_cyl = 0.3 cube = OrthoBrick(Pnt(-d_box,-d_box,-d_box),Pnt(d_box,d_box,d_box)).bc('outer') mid = Plane(Pnt(0,0,0), Vec(0,0,1)).bc('plane') infcyl = Cylinder(Pnt(0,0,0), Pnt(0,0,1), r_cyl).bc('cyl') corefront = ((cube*infcyl)-mid).mat('core') coreback = ((cube*infcyl)*mid).mat('core') cladfront = ((cube-infcyl)-mid).mat('clad') cladback = ((cube-infcyl)*mid).mat('clad') geo = CSGeometry() geo.Add(corefront) geo.Add(coreback,bcmod=[(corefront,'core_2d')]) geo.Add(cladfront) geo.Add(cladback,bcmod=[(cladfront,'clad_2d')]) mesh = Mesh(geo.GenerateMesh(maxh=0.1)) print(mesh.GetMaterials()) print(mesh.GetBoundaries()) cf = mesh.BoundaryCF({'core_2d':1,'clad_2d':2,'cyl':3,'outer':4},default=-1) g = GridFunction(H1(mesh),name='bndry') g.Set(cf, definedon=~mesh.Boundaries('')) Draw(g)


That is my resulting code. If I change the lines in which I add coreback and cladback by removing the ,bcmod=..., I do get what I expected: cylinder walls are cyl, plane is plane and the outer boundary is outer. However, with the code as is, bcmod apparently changes all the boundaries of the volume being inserted, and not only the ones between the other volume in the bcmod call.

I would appreciate if you could point me in the direction of understanding what am I missing here.

All the best,

Francisco
Last edit: 1 year 8 months ago by orlandini. Reason: bcmod instead of bcpos
More
1 year 8 months ago - 1 year 8 months ago #4698 by valentin
Dear Mr Orlandini,

unfortunately I can not answer your questions about bcmod. However, I think that your indention can be solve by geo.AddSurface(a, b.bc("name")), where as far as I understand it the intersection of the boundaries of the solids a and b will be added as an additional surface.
Code:

from ngsolve import *
import netgen.gui
from netgen.csg import *

d_box = 1
r_cyl = 0.3

cube = OrthoBrick(Pnt(-d_box,-d_box,-d_box),Pnt(d_box,d_box,d_box)).bc('outer')
infcyl = Cylinder(Pnt(0,0,0), Pnt(0,0,1), r_cyl).bc('cyl')
core = ((cube*infcyl)).bc("outer").mat('core')
clad = ((cube-infcyl)).bc("outer").mat('clad')

geo = CSGeometry()
geo.Add(core)
geo.Add(clad)
for solid, bnd_name in zip((core, clad), ("core_2d", "clad_2d")):
   mid = Plane(Pnt(0,0,0), Vec(0,0,1))
   geo.AddSurface(mid, (mid*solid).bc(bnd_name))

mesh = Mesh(geo.GenerateMesh(maxh=0.1))
print(mesh.GetMaterials())
print(set(mesh.GetBoundaries()))
cf = mesh.BoundaryCF({'core_2d':1,'clad_2d':2,'cyl':3,'outer':4},default=-1)

Draw(cf, mesh, "boundary", draw_vol = False)


The for loop is necessary since each solid can only hold one name for bc.

I hope that solves your problem.

Best regards,

valentin

 
Last edit: 1 year 8 months ago by valentin.
More
1 year 8 months ago #4699 by orlandini
Dear Mr. Valentin,

Thank you for your workaround! However, the same approach apparently does not me allow to give a name to the boundary of the 2d plane, i.e., edges on the intersection between this plane and the cube.

Would you have any guesses on how to proceed?

from ngsolve import *
import netgen.gui
from netgen.csg import *

d_box = 1
r_cyl = 0.3

cube = OrthoBrick(Pnt(-d_box,-d_box,-d_box),Pnt(d_box,d_box,d_box)).bc('outer')
infcyl = Cylinder(Pnt(0,0,0), Pnt(0,0,1), r_cyl).bc('cyl')
core = ((cube*infcyl)).bc("outer").mat('core')
clad = ((cube-infcyl)).bc("outer").mat('clad')

geo = CSGeometry()
geo.Add(core)
geo.Add(clad)
for solid, bnd_name in zip((core, clad), ("core_2d", "clad_2d")):
mid = Plane(Pnt(0,0,0), Vec(0,0,1))
geo.AddSurface(mid, (mid*solid).bc(bnd_name))
mid = Plane(Pnt(0,0,0), Vec(0,0,1))
geo.NameEdge(cube,mid,"dirichlet_2d")

mesh = Mesh(geo.GenerateMesh(maxh=0.1))
print(mesh.GetMaterials())
print(mesh.GetBoundaries())
print(mesh.GetBBoundaries())
cf = mesh.BoundaryCF({'core_2d':1,'clad_2d':2,'cyl':3,'outer':4},default=-1)

Draw(cf, mesh, "boundary", draw_vol = False)
More
1 year 8 months ago #4700 by valentin
Dear Mr. Orlandini,

your task is indeed challenging and full of troubles. After using the "netgen-correct" order and the "netgen-correct" halfspace I came up with that solution:

Code:

from ngsolve import *
import netgen.gui
from netgen.csg import *


d_box = 1
r_cyl = 0.3


cube = OrthoBrick(Pnt(-d_box,-d_box,-d_box),Pnt(d_box,d_box,d_box)).bc('outer')

infcyl = Cylinder(Pnt(0,0,0), Pnt(0,0,1), r_cyl).bc('cyl')
core = ((cube*infcyl)).bc("outer").mat('core')
clad = ((cube-infcyl)).bc("outer").mat('clad')

geo = CSGeometry()

# solids
geo.Add(core)
geo.Add(clad)

# surfaces
mid1 = Plane(Pnt(0,0,0), Vec(0,0,1))
geo.AddSurface(mid1, (mid1*core).bc("core_2d"))

mid2 = Plane(Pnt(0,0,0), Vec(0,0,1))
geo.AddSurface(mid2, (mid2*clad).bc("clad_2d"))

# edges
geo.NameEdge(mid1, cube, "dirichlet_2d")

mesh = Mesh(geo.GenerateMesh(maxh=0.1))

#cheks
print(mesh.GetMaterials())
print(set(mesh.GetBoundaries()))
print(set(mesh.GetBBoundaries()))
cf = mesh.BoundaryCF({'core_2d':1,'clad_2d':2,'cyl':3,'outer':4},default=-1)

Draw(cf, mesh, "boundary", draw_vol = False)

g = GridFunction(H1(mesh, dirichlet_bbnd="dirichlet_2d"),name='bbndry')
g.Set(CF([1 if bbnd=="dirichlet_2d" else 0 for bbnd in mesh.GetBBoundaries()]), VOL_or_BND=BBND)
Draw(g)


 
More
1 year 8 months ago #4701 by orlandini
In case anyone is facing a similar problem, it was suggested that I tried the OCC kernel for generating the mesh, and it indeed made the code considerably simpler.

I am sharing here a code snippet in case it might be helpful to someone in the future

Thank you for the support.




from ngsolve import *
import netgen.gui
from netgen.occ import *
from numpy import random


d_box = 1
l_domain = 1
r_cyl = 0.3
el_clad = 0.2
el_core = 0.1
cube_back = Box(Pnt(-d_box,-d_box,-l_domain/2),Pnt(d_box,d_box,0)).bc('outer')
cube_front = Box(Pnt(-d_box,-d_box,0),Pnt(d_box,d_box,l_domain/2)).bc('outer')
cyl = Cylinder(Pnt(0,0,-l_domain/2),Z, r=r_cyl, h=l_domain)

clad_front = cube_front - cyl
clad_front.mat('clad').maxh = el_clad
clad_back = cube_back - cyl
clad_back.mat('clad').maxh = el_clad
core_front = cube_front * cyl
core_front.mat('core').maxh = el_core
core_back = cube_back * cyl
core_back.mat('core').maxh = el_core

clad_front.faces.Min(Z).name = 'clad_2d'
core_front.faces.Min(Z).name = 'core_2d'

domain_list = [clad_front,clad_back,core_front,core_back]
geo = OCCGeometry(domain_list)
mesh = Mesh(geo.GenerateMesh(maxh=el_core))

#checking surface domains
surflist = {"core_2d":1, "clad_2d":2, "outer":3}
surf = mesh.BoundaryCF(surflist)
gu = GridFunction(H1(mesh),name='surfs')
gu.Set(surf, definedon=~mesh.Boundaries(''))
Draw(gu)
Time to create page: 0.108 seconds