Possible to set boundary conditions on a geometry from an STL source?

Hi,
I have a CSG geometry defined in an STL file which includes a small detailed model of a sailplane inside a large bounding box. I’m able to load this geometry in Netgen.

I have been looking at I-Tutorial 4.2 on CSG geometries in 3D. In that tutorial, I can see how to set boundary and material labels for a CSG object such as a sphere, then add that object to the geometry before meshing. I would like to be able to do something similar with my geometry from the STL file, for example, to set one boundary label on the surface of the airplane and a different label on the surface of the bounding box.

When I look at the contents of the STL file, I see only a list of facet definitions. Is there some way to assign boundary labels to specific facets either in Netgen/Python or directly in the STL file? I may not be thinking about this problem the right way – any suggestions would be most welcome! I’m attaching the STL file in case that is helpful…

Thanks!

Attachment: Ak8.stl

Hi,
It seems like your model is placed on the surface of your bounding box and not inside, there may be a mistake in the stl file. But anyhow I think it’s easier to mesh the stl model and the bounding CSG seperately and merge them afterwards. There is a (not fully up to date) documentation on how to do that here:
https://ngsolve.org/docu/latest/netgen_tutorials/working_with_meshes.html
When adding the facedescriptors you can give each of the surfaces a different number and a different name, so that they represent different boundary conditions.
Some new stuff that is not in that docu example:
You can mesh only surfaces (this saves quite some time) by:

import netgen.meshing as meshing
stlgeo.GenerateMesh(maxh=maxh,perfstepsend= meshing.MeshingStep.MESHSURFACE)

Then copy all the surface elements together into one mesh, set the maximum meshsize and name for each domain and generate the volume mesh:

# material numbers are 1 based
mesh.SetMaterial(1,"mat1")
mesh.SetMaterial(2,"mat2")
meshsize = [maxh[dom] for dom in mesh.GetMaterials()]
mesh.SetMaxHDomain(meshsize)
mesh.CalcLocalH(0.5)
mesh.GenerateVolumeMesh()

The 0.5 in CalcLocalH is a grading factor.
You can set names for the bc numbers with

# boundary condition numbers are 0 based! - yes this is a bit annoying... ;)
mesh.SetBCName(number,name)

I’ve attached a file that can be used to merge the surface meshes by calling

add_surfaces(mesh1,mesh2,outerdomain)

If you have any questions or if the code isn’t working (I use it in a bigger module, there may be something missing…) feel free to ask :wink:

PS:
To check if everything is set correctly I use a short snippet:

    from ngsolve import *
    from ngsolve.internal import *
    boundaries = ["bc1",...]
    materials = ["mat1",...]
    fes = H1(mesh)
    u = GridFunction(fes,"u")
    viewoptions.clipping.enable = 1
    Draw(u)
    visoptions.clipsolution = "scal"
    for bc in boundaries:
        u.Set(CoefficientFunction(1),definedon=mesh.Boundaries(bc))
        Redraw()
        input(bc)
    for mat in materials:
        u.Set(CoefficientFunction(1),definedon=mesh.Materials(mat))
        Redraw()
        input(mat)

Best
Christopher

Attachment: merge_meshes.py

Hi Christopher,

In my version 6.2.1806 is missing:

from ngsolve_mri.meshtools import max_surfnr, nr_bcs, nr_materials

Where can I find this missing part?

Sorry that file was missing, I’ve attached it. Just put it in the same folder and change

from ngsolve_mri.meshtools import max_surfnr, nr_bcs, nr_materials

to

from .meshtools import max_surfnr, nr_bcs, nr_materials

Attachment: meshtools.py