def test_cut_triangle(): geom = SplineGeometry() pnts = [(0, 0), (1, 0), (0, 1)] pnums = [geom.AppendPoint(*p) for p in pnts] lines = [(0, 1, 1, 1, 0), (1, 2, 1, 1, 0), (2, 0, 1, 1, 0)] for p1, p2, bc, left, right in lines: geom.Append(["line", pnums[p1], pnums[p2]], bc=bc, leftdomain=left, rightdomain=right) mesh = Mesh(geom.GenerateMesh(maxh=1)) # <- will have 4 elements levelset = x + y - 0.25 lsetp1 = GridFunction(H1(mesh, order=1)) InterpolateToP1(levelset, lsetp1) lset_neg = {"levelset": lsetp1, "domain_type": NEG, "subdivlvl": 0} lset_pos = {"levelset": lsetp1, "domain_type": POS, "subdivlvl": 0} for order in range(16): measure_neg = Integrate(levelset_domain=lset_neg, cf=CoefficientFunction(1.0), mesh=mesh, order=order) measure_pos = Integrate(levelset_domain=lset_pos, cf=CoefficientFunction(1.0), mesh=mesh, order=order) assert abs(measure_neg - 1.0 / 32.0) < 5e-16 * (order + 1) * (order + 1) assert abs(measure_pos - 1.0 / 2.0 + 1.0 / 32.0) < 5e-16 * (order + 1) * (order + 1) assert abs(measure_neg + measure_pos - 1.0 / 2.0) < 5e-16 * (order + 1) * (order + 1)
def test_leftdom_equals_rightdom(): geo = SplineGeometry() pnts = [(0, 0), (1, 0), (2, 0), (2, 1), (1, 1), (0, 1)] gp = [geo.AppendPoint(*p) for p in pnts] lines = [(0, 1, 0), (1, 2, 0), (2, 3, 0), (3, 4, 0), (4, 5, 0), (5, 0, 0), (1, 4, 1)] for p1, p2, rd in lines: geo.Append(["line", p1, p2], leftdomain=1, rightdomain=rd) mesh = geo.GenerateMesh()
def MakeHexagonalMesh2D(maxh=0.1): geo = SplineGeometry() pnums = [ geo.AddPoint(math.cos(phi), math.sin(phi)) for phi in [xx * math.pi / 3 for xx in range(6)] ] l1 = geo.Append(["line", 0, 1], leftdomain=1, rightdomain=0, bc="upperRight") geo.Append(["line", 4, 3], leftdomain=0, rightdomain=1, bc="lowerLeft", copy=l1) l2 = geo.Append(["line", 1, 2], leftdomain=1, rightdomain=0, bc="upperCenter") geo.Append(["line", 5, 4], leftdomain=0, rightdomain=1, bc="lowerCenter", copy=l2) l3 = geo.Append(["line", 2, 3], leftdomain=1, rightdomain=0, bc="upperLeft") geo.Append(["line", 0, 5], leftdomain=0, rightdomain=1, bc="lowerRight", copy=l3) return geo.GenerateMesh(maxh=maxh)
def MakeGeometry(): geometry = SplineGeometry() # point coordinates ... pnts = [(0, 0), (1, 0), (1, 0.6), (0.5, 0.6), (0.5, 0.8), (0, 0.8)] pnums = [geometry.AppendPoint(*p) for p in pnts] # start-point, end-point, boundary-condition, domain on left side, domain on right side: lines = [(0, 1, 1, 1, 0), (1, 2, 1, 1, 0), (2, 3, 1, 1, 0), (3, 4, 1, 1, 0), (4, 5, 1, 1, 0), (5, 0, 1, 1, 0)] for p1, p2, bc, left, right in lines: geometry.Append(["line", pnums[p1], pnums[p2]], bc=bc, leftdomain=left, rightdomain=right) return geometry
def MakeGeometry(): geometry = SplineGeometry() # point coordinates ... pnts = [ (0,0), (1,0), (1,0.6), (0,0.6), \ (0.2,0.6), (0.8,0.6), (0.8,0.8), (0.2,0.8), \ (0.5,0.15), (0.65,0.3), (0.5,0.45), (0.35,0.3) ] pnums = [geometry.AppendPoint(*p) for p in pnts] # start-point, end-point, boundary-condition, domain on left side, domain on right side: lines = [ (0,1,1,1,0), (1,2,2,1,0), (2,5,2,1,0), (5,4,2,1,2), (4,3,2,1,0), (3,0,2,1,0), \ (5,6,2,2,0), (6,7,2,2,0), (7,4,2,2,0), \ (8,9,2,3,1), (9,10,2,3,1), (10,11,2,3,1), (11,8,2,3,1) ] for p1,p2,bc,left,right in lines: geometry.Append( ["line", pnums[p1], pnums[p2]], bc=bc, leftdomain=left, rightdomain=right) return geometry
from netgen.geom2d import unit_square from netgen.geom2d import SplineGeometry from netgen.meshing import MeshingParameters from ngsolve.internal import * from xfem import * from numpy import pi from xfem.lset_spacetime import * # geometry periodic = SplineGeometry() pnts = [ (0,0), (2,0), (2,2), (0,2) ] pnums = [periodic.AppendPoint(*p) for p in pnts] uright = periodic.Append ( ["line", pnums[0], pnums[1]], bc="periodic") periodic.Append ( ["line", pnums[3], pnums[2]], leftdomain=0, rightdomain=1, copy=uright, bc="periodic") lright = periodic.Append ( ["line", pnums[1], pnums[2]], bc="periodic") periodic.Append ( ["line", pnums[0], pnums[3]], leftdomain=0, rightdomain=1, copy=lright, bc="periodic") maxh = 0.1 mesh = Mesh(periodic.GenerateMesh(maxh=maxh)) n_ref = 0 for i in range(n_ref): mesh.Refine() h = specialcf.mesh_size # FE Spaces
from ngsolve import * from netgen.geom2d import SplineGeometry from math import sqrt geo = SplineGeometry() s = 0.3 Points = [(-s/2,-sqrt(3)/6*s),(s/2,-sqrt(3)/6*s),(0,sqrt(3)/3*s), (-s/2*4,-sqrt(3)/6*s*4),(s/2*4,-sqrt(3)/6*s*4),(0,sqrt(3)/3*s*4), (-s/2*6,-sqrt(3)/6*s*6),(s/2*6,-sqrt(3)/6*s*6),(0,sqrt(3)/3*s*6)] for pnt in Points: geo.AddPoint(*pnt) for pids in [[0,1],[1,2],[2,0]]: geo.Append(["line"]+pids,leftdomain=0,rightdomain=1,bc="scatterer") for pids in [[3,4],[4,5],[5,3]]: geo.Append(["line"]+pids,leftdomain=1,rightdomain=2) for pids in [[6,7],[7,8],[8,6]]: geo.Append(["line"]+pids,leftdomain=2,rightdomain=0) ngmesh = geo.GenerateMesh(maxh=0.04) # ngmesh.Save("scattering.vol") mesh = Mesh(ngmesh) # mesh = Mesh ("scattering.vol") p=pml.HalfSpace(point=(0,4/3*sqrt(3)*s),normal=(sqrt(3),1),alpha=0.5j)+pml.HalfSpace(point=(0,4/3*sqrt(3)*s),normal=(-sqrt(3),1),alpha=0.5j)+pml.HalfSpace(point=(0,-sqrt(3)*s*2/3),normal=(0,-1),alpha=0.5j) print(p) mesh.SetPML(p,definedon=2)
from ngsolve import * from netgen.geom2d import SplineGeometry geo = SplineGeometry() p1, p2, p3, p4 = [ geo.AppendPoint(x, y) for x, y in [(0, 0), (1, 0), (1, 1), (0, 1)] ] p5, p6 = [geo.AppendPoint(x, y) for x, y in [(2, 0), (2, 1)]] geo.Append(["line", p1, p2], leftdomain=1, rightdomain=0, bc='outer') geo.Append(["line", p2, p3], leftdomain=1, rightdomain=2, bc='interface') geo.Append(["line", p3, p4], leftdomain=1, rightdomain=0, bc='outer') geo.Append(["line", p4, p1], leftdomain=1, rightdomain=0, bc='outer') geo.Append(["line", p2, p5], leftdomain=2, rightdomain=0, bc='outer') geo.Append(["line", p5, p6], leftdomain=2, rightdomain=0, bc='outer') geo.Append(["line", p6, p3], leftdomain=2, rightdomain=0, bc='outer') geo.SetMaterial(1, 'left') geo.SetMaterial(2, 'right') mesh = Mesh(geo.GenerateMesh(maxh=0.1)) Draw(mesh) order = 3 Vl = H1(mesh, order=order, definedon="left") Vr = H1(mesh, order=order, definedon="right") Q = SurfaceL2(mesh, order=order - 1) X = FESpace([Vl, Vr, Q]) a = BilinearForm(X)
def test_st2d1_drag_lift(): # ----------------------------------- DATA ------------------------------------ def levelset_func(t): return 0.05 - sqrt((x - 0.2) * (x - 0.2) + (y - 0.2) * (y - 0.2)) u_inflow = CoefficientFunction((4 * 0.3 * y * (0.41 - y) / (0.41**2), 0.0)) # ------------------------------ BACKGROUND MESH ------------------------------ geo = SplineGeometry() p1, p2, p3, p4, p5, p6 = [ geo.AppendPoint(x, y) for x, y in [(0, 0), (0.7, 0), (2.2, 0), (2.2, 0.41), (0.7, 0.41), (0, 0.41)] ] geo.Append(["line", p1, p2], leftdomain=1, rightdomain=0, bc="wall") geo.Append(["line", p2, p5], leftdomain=1, rightdomain=2) geo.Append(["line", p5, p6], leftdomain=1, rightdomain=0, bc="wall") geo.Append(["line", p6, p1], leftdomain=1, rightdomain=0, bc="inlet") geo.Append(["line", p2, p3], leftdomain=2, rightdomain=0, bc="wall") geo.Append(["line", p3, p4], leftdomain=2, rightdomain=0, bc="outlet") geo.Append(["line", p4, p5], leftdomain=2, rightdomain=0, bc="wall") geo.SetDomainMaxH(1, h_max / 6) mesh = Mesh(geo.GenerateMesh(maxh=h_max)) # --------------------------- FINITE ELEMENT SPACE ---------------------------- V = VectorH1(mesh, order=k, dirichlet="wall|inlet") Q = H1(mesh, order=k - 1) X = FESpace([V, Q], dgjumps=True) gfu = GridFunction(X) vel, pre = gfu.components gfu.vec[:] = 0.0 # ---------------------------- LEVELSET & CUT-INFO ---------------------------- # Levelset approximation if mapping: lset_meshadap = LevelSetMeshAdaptation(mesh, order=k, discontinuous_qn=True) deformation = lset_meshadap.CalcDeformation(levelset_func(0.0)) mesh.SetDeformation(deformation) lsetp1 = lset_meshadap.lset_p1 else: lsetp1 = GridFunction(H1(mesh, order=1)) InterpolateToP1(levelset_func(0.0), lsetp1) # Integration dictionaries lset_neg = {"levelset": lsetp1, "domain_type": NEG, "subdivlvl": 0} lset_if = {"levelset": lsetp1, "domain_type": IF, "subdivlvl": 0} # Cut-info class ci_main = CutInfo(mesh, lsetp1) # ------------------------------ ELEMENT MARKERS ------------------------------ els_hasneg, els_if = BitArray(mesh.ne), BitArray(mesh.ne) facets_gp = BitArray(mesh.nedge) active_dofs = BitArray(X.ndof) UpdateMarkers(els_hasneg, ci_main.GetElementsOfType(HASNEG)) UpdateMarkers(els_if, ci_main.GetElementsOfType(IF)) UpdateMarkers( facets_gp, GetFacetsWithNeighborTypes(mesh, a=els_hasneg, b=els_if, use_and=True)) if condense: MarkCutElementsForCondensing(mesh, X, facets_gp) UpdateMarkers(active_dofs, GetDofsOfElements(X, els_hasneg), X.FreeDofs(coupling=condense)) # ----------------------------- (BI)LINEAR FORMS ------------------------------ (u, p), (v, q) = X.TnT() h = specialcf.mesh_size n_levelset = 1.0 / Norm(grad(lsetp1)) * grad(lsetp1) stokes = nu * InnerProduct(Grad(u), Grad(v)) - p * div(v) - q * div(u) convect = InnerProduct(Grad(u) * vel, v) convect_lin = InnerProduct(Grad(u) * vel, v) + InnerProduct( Grad(vel) * u, v) nitsche = -nu * InnerProduct(grad(u) * n_levelset, v) nitsche += -nu * InnerProduct(grad(v) * n_levelset, u) nitsche += nu * (gamma_n * k * k / h) * InnerProduct(u, v) nitsche += p * InnerProduct(v, n_levelset) nitsche += q * InnerProduct(u, n_levelset) ghost_penalty = gamma_gp * nu * (1 / h**2) * (u - u.Other()) * (v - v.Other()) ghost_penalty += -gamma_gp * (1 / nu) * (p - p.Other()) * (q - q.Other()) # -------------------------------- INTEGRATORS -------------------------------- a = RestrictedBilinearForm(X, element_restriction=els_hasneg, facet_restriction=facets_gp, check_unused=False, flags={"symmetric": False}) a += SymbolicBFI(lset_neg, form=stokes + convect, definedonelements=els_hasneg) a += SymbolicBFI(lset_if, form=nitsche, definedonelements=els_if) a += SymbolicFacetPatchBFI(form=ghost_penalty, skeleton=False, definedonelements=facets_gp) a_lin = RestrictedBilinearForm(X, element_restriction=els_hasneg, facet_restriction=facets_gp, check_unused=False, flags={ "condense": condense, "symmetric": False }) a_lin += SymbolicBFI(lset_neg, form=stokes - pReg * p * q + convect_lin, definedonelements=els_hasneg) a_lin += SymbolicBFI(lset_if, form=nitsche, definedonelements=els_if) a_lin += SymbolicFacetPatchBFI(form=ghost_penalty, skeleton=False, definedonelements=facets_gp) # ------------------------- SOLVE STATIONARY PROBLEM -------------------------- with TaskManager(): vel.Set(u_inflow, definedon=mesh.Boundaries("inlet")) CutFEM_QuasiNewton(a=a, alin=a_lin, u=gfu, f=None, freedofs=active_dofs, maxit=maxit_newt, maxerr=tol_newt, inverse=inverse, jacobi_update_tol=update_jacobi_tol, reuse=reuse_jacobi, printing=print_newt) # --------------------------- FUNTIONAL EVALUATION ---------------------------- drag_x_test, drag_y_test = GridFunction(X), GridFunction(X) drag_x_test.components[0].Set(CoefficientFunction((1.0, 0.0))) drag_y_test.components[0].Set(CoefficientFunction((0.0, 1.0))) n = specialcf.normal(mesh.dim) a_test = BilinearForm(X, symmetric=False, check_unused=False) a_test += SymbolicBFI(lset_neg, form=convect, definedonelements=els_hasneg) a_test += SymbolicBFI(form=-InnerProduct(nu * Grad(u) * n - p * n, v), skeleton=True, definedon=mesh.Boundaries("inlet|wall")) with TaskManager(): a_test.Assemble() Um = 2 * 0.3 / 3 C_drag = -2.0 / (0.1 * Um**2) * a_test(gfu, drag_x_test) C_lift = -2.0 / (0.1 * Um**2) * a_test(gfu, drag_y_test) pdiff = pre(0.15, 0.2) - pre(0.25, 0.2) err_drag = abs(C_drag - 5.57953523384) err_lift = abs(C_lift - 0.010618948146) err_p = abs(pdiff - 0.11752016697) print("\n C_drag C_lift pdiff") print("Val: {:10.8f} {:10.8f} {:10.8f}".format(C_drag, C_lift, pdiff)) print("Err: {:1.2e} {:1.2e} {:1.2e}".format(err_drag, err_lift, err_p)) assert err_drag < 2.5e-5 assert err_lift < 2e-6 assert err_p < 2e-4
# Example for generating a simple netgen mesh from ngsolve import * from netgen.geom2d import SplineGeometry geo = SplineGeometry() p1,p12a,p12b,p2,p3,p4 = [ geo.AppendPoint(x,y) for x,y in [(-5,5),(-5,2),(-5, -2),(-5,-5),(5,-5),(5,5)] ] geo.SetMaterial(1, "background") geo.SetMaterial(2, "circles") # In NetGen, regions are defined using 'left' and 'right', # For example, leftdomain=2, rightdomain=1 means when moving from a # from a point A to B, region 2 is always on the left side and # region 1 is on the right. geo.Append (["line", p1, p12a], leftdomain=1, bc="boundary1") geo.Append (["line", p12a, p12b], leftdomain=1, bc="lightsource") geo.Append (["line", p12b, p2], leftdomain=1, bc="boundary1") geo.Append (["line", p2, p3], leftdomain=1, bc="boundary1") geo.Append (["line", p3, p4], leftdomain=1, bc="boundary1") geo.Append (["line", p4, p1], leftdomain=1, bc="boundary1") geo.AddCircle(c=(1,1), r=1, leftdomain=2,rightdomain=1) geo.AddCircle(c=(-2,-2), r=2, leftdomain=2,rightdomain=1) mesh = geo.GenerateMesh(maxh=0.1) mesh.Save("square_with_two_circles.vol")