### Start Docker daemon Source: https://ngsuite.pages.gwdg.de/ngsxfem/INSTALLATION.md Commands to manually start the Docker daemon on most Linux distributions. ```bash systemctl start docker ``` ```bash service docker start ``` -------------------------------- ### Install ngsxfem from GitHub source Source: https://ngsuite.pages.gwdg.de/ngsxfem/INSTALLATION.md Installs the latest development version directly from the master branch on GitHub. ```bash pip3 install git+https://github.com/ngsxfem/ngsxfem.git@master ``` -------------------------------- ### Element-wise post-processing setup Source: https://ngsuite.pages.gwdg.de/ngsxfem/_sources/jupyter/unfmixed.ipynb.txt Sets up the finite element spaces and bilinear form for element-wise post-processing of the pressure field. ```python #FE Spaces for el-wise post-processing Vhpbase = L2(mesh, order=order+1, dgjumps=False, dirichlet=[]) # order+1 Lhbase = L2(mesh, order=0, dgjumps=False, dirichlet=[]) Vhp = Restrict(Vhpbase, hasneg) Lh = Restrict(Lhbase, hasneg) Zh = Vhp * Lh gflh = GridFunction(Lh) gfz = GridFunction(Zh) gfps, gflam = gfz.components #Test- & Trialfunction (ps,lam),(vs,mu) = Zh.TnT() #Bilinear Form p = RestrictedBilinearForm(Zh, symmetric=False) p += grad(ps) * grad(vs) * dxbar ``` -------------------------------- ### Get help for AggEmbedding Source: https://ngsuite.pages.gwdg.de/ngsxfem/_sources/jupyter/aggregation.ipynb.txt Displays the documentation for the AggEmbedding method. ```python help(AggEmbedding) ``` -------------------------------- ### Setup Formulation Integrals Source: https://ngsuite.pages.gwdg.de/ngsxfem/_sources/jupyter/unfmixed.ipynb.txt Defines the integration domain for ghost penalty and the left-hand side and right-hand side integrals for the formulation. ```python #Integration domain for ghost penalty dP = dFacetPatch(definedonelements=EA.patch_interior_facets, deformation=deformation) lhs_integrals = [grad(ps) * grad(vs) * dX, (lam * vs + mu * ps) * dxinner, 1/h**2 * (ps - ps.Other()) * (vs - vs.Other()) * dP] rhs_integrals = [gfu * grad(vs) * dX, gfpT * mu * dxinner] ``` -------------------------------- ### Get Help for PatchwiseSolve Source: https://ngsuite.pages.gwdg.de/ngsxfem/_sources/jupyter/unfmixed.ipynb.txt Displays the help documentation for the PatchwiseSolve function. ```python help(PatchwiseSolve) ``` -------------------------------- ### Basic imports for netgen, ngsolve, and ngsxfem Source: https://ngsuite.pages.gwdg.de/ngsxfem/jupyter/unfmixed.html Imports the basic functionality of netgen, ngsolve, and ngsxfem. This is the initial setup for the notebook. ```python #basic imports from netgen.occ import * from ngsolve import * from ngsolve.internal import * from xfem import * from xfem.lsetcurv import * ``` -------------------------------- ### Visualize Extended Basis Functions Source: https://ngsuite.pages.gwdg.de/ngsxfem/_sources/jupyter/aggregation.ipynb.txt Initial setup to visualize extended basis functions using the ExtendedBasisFunctionsAsMultiDim utility. ```python gfshow = ExtendedBasisFunctionsAsMultiDim(EA,fes) Draw (gfshow, mesh, interpolate_multidim=False, animate=False, autoscale=True); ``` -------------------------------- ### Define parameters, trial/test functions, and mesh size Source: https://ngsuite.pages.gwdg.de/ngsxfem/jupyter/mlset_pde.html Sets up the penalty parameters gamma_n and gamma_s, gets the trial and test functions from the finite element space V, and obtains the mesh size coefficient function h. ```python gamma_n = 10 gamma_s = 0.5 u, v = V.TnT() h = specialcf.mesh_size ``` -------------------------------- ### Install ngsxfem development version via pip Source: https://ngsuite.pages.gwdg.de/ngsxfem/INSTALLATION.md Installs the pre-release version of ngsxfem by building from source without binary or build isolation. ```bash pip3 install xfem --no-binary --no-build-isolation --pre ``` -------------------------------- ### Setup Restricted Bilinear Form Source: https://ngsuite.pages.gwdg.de/ngsxfem/jupyter/spacetime_unfitted.html Initializes the restricted bilinear form for the space-time finite element space. ```python a = RestrictedBilinearForm(st_fes, "a", check_unused=False, element_restriction=ci.GetElementsOfType(HASNEG), facet_restriction=ba_facets) ``` -------------------------------- ### Element-wise post-processing setup and solve Source: https://ngsuite.pages.gwdg.de/ngsxfem/jupyter/unfmixed.html Defines FE spaces for element-wise post-processing, assembles the bilinear form and linear form, solves the system, and sets values for visualization. Requires GP stabilization to be used. Uses RestrictedBilinearForm and LinearForm with the given spaces. ```python #FE Spaces for el-wise post-processing Vhpbase = L2(mesh, order=order+1, dgjumps=False, dirichlet=[]) # order+1 Lhbase = L2(mesh, order=0, dgjumps=False, dirichlet=[]) Vhp = Restrict(Vhpbase, hasneg) Lh = Restrict(Lhbase, hasneg) Zh = Vhp * Lh gflh = GridFunction(Lh) gfz = GridFunction(Zh) gfps, gflam = gfz.components #Test- & Trialfunction (ps,lam),(vs,mu) = Zh.TnT() #Bilinear Form p = RestrictedBilinearForm(Zh, symmetric=False) p += grad(ps) * grad(vs) * dxbar p += (lam * vs + mu * ps) * dxinner p += (lam * vs + mu * ps) * ds # R.h.s. term: pf = LinearForm(Zh) pf += gfu * grad(vs) * dxbar pf += p_exact * mu * ds pf += gfpT * mu * dxinner #Assembly p.Assemble() pf.Assemble() #Solving the system gfz.vec.data = p.mat.Inverse(Zh.FreeDofs(),inverse="umfpack") * pf.vec #For visualization: gflh.Set(p_exact, definedonelements=ci.GetElementsOfType(HASNEG)) gflam.Set(gfps, definedonelements=ci.GetElementsOfType(HASNEG)) ``` ```python DrawDC(lsetp1,gfps,-1,mesh,"p",deformation=deformation, min=-1, max=1) # p on physical domain ``` ```python BaseWebGuiScene ``` ```python ps_l2error = sqrt(Integrate((gfps - p_exact)**2*dX.order(2*order+3), mesh)) print("ps_l2error = ", ps_l2error) ``` ```python ps_l2error = 5.574194899390954e-06 ``` -------------------------------- ### Setup convergence study with isoparametric mapping Source: https://ngsuite.pages.gwdg.de/ngsxfem/jupyter/intlset.html Sets up the convergence study: defines order, mesh, levelset, reference values, and initializes error and EOC dictionaries. ```python order = 2 mesh = Mesh(geo.GenerateMesh(maxh=0.7,quad_dominated=False)) levelset = sqrt(x*x+y*y)-1 referencevals = { POS : 9-pi, NEG : pi, IF : 2*pi } lsetmeshadap = LevelSetMeshAdaptation(mesh, order=order, threshold=0.2, discontinuous_qn=True) lsetp1 = lsetmeshadap.lset_p1 errors_uncurved = dict() errors_curved = dict() eoc_uncurved = dict() eoc_curved = dict() for key in [NEG,POS,IF]: errors_curved[key] = [] errors_uncurved[key] = [] eoc_curved[key] = [] eoc_uncurved[key] = [] ``` -------------------------------- ### Install ngsxfem release via pip Source: https://ngsuite.pages.gwdg.de/ngsxfem/INSTALLATION.md Installs the latest release version of ngsxfem using pip3. ```bash pip3 install xfem ``` -------------------------------- ### Run Jupyter server in Docker Source: https://ngsuite.pages.gwdg.de/ngsxfem/INSTALLATION.md Starts a Jupyter server in a Docker container and maps port 8888 to the host machine. ```bash docker run -p 8888:8888 ngsxfem/ngsxfem-jupyter ``` -------------------------------- ### Run Jupyter with persistent local directory Source: https://ngsuite.pages.gwdg.de/ngsxfem/INSTALLATION.md Starts the Jupyter Docker container while mounting the current working directory to the container for persistent file access. ```bash docker run -p 8888:8888 -v ${PWD}:/home/jovyan ngsxfem/ngsxfem-jupyter ``` -------------------------------- ### Import libraries for ngsxfem and mlset Source: https://ngsuite.pages.gwdg.de/ngsxfem/jupyter/mlset_pde.html Imports NGSolve, ngsxfem, and the mlset convenience layer, along with visualization tools. This is the standard setup for using ngsxfem with multiple level sets. ```python # Basic NGSolve things from netgen.occ import * from ngsolve import * from ngsolve.solvers import PreconditionedRichardson as PreRic # ngsxfem and the mlset convenience layer from xfem import * from xfem.mlset import * # Visualisation from ngsolve.webgui import * DrawDC = MakeDiscontinuousDraw(Draw) ``` -------------------------------- ### Define Parameters and Trial/Test Functions Source: https://ngsuite.pages.gwdg.de/ngsxfem/_sources/jupyter/mlset_pde.ipynb.txt Set up stabilization parameters, trial/test functions, and mesh-size coefficient functions. ```python gamma_n = 10 gamma_s = 0.5 u, v = V.TnT() h = specialcf.mesh_size ``` -------------------------------- ### Create CutInfo and show help Source: https://ngsuite.pages.gwdg.de/ngsxfem/_sources/jupyter/basics.ipynb.txt Creates a CutInfo object from a mesh and a P1 level set function, then displays its help. ```python ci = CutInfo(mesh, lsetp1) help(CutInfo) ``` -------------------------------- ### L2 low order output Source: https://ngsuite.pages.gwdg.de/ngsxfem/jupyter/aggregation.html The output of the L2 low order aggregation example. ```text Row 0: 0: 1 Row 1: 1: 1 Row 2: 2: 1 Row 3: 3: 1 Row 4: 3: 1 Row 5: 3: 1 Row 6: 4: 1 Row 7: 5: 1 Row 8: 6: 1 Row 9: 7: 1 Row 10: 7: 1 Row 11: 7: 1 ``` -------------------------------- ### Get outward normals Source: https://ngsuite.pages.gwdg.de/ngsxfem/_sources/jupyter/mlset_basic.ipynb.txt Computes the outward pointing unit normal vectors for each section of the boundary. ```python normals = z_disc2.GetOuterNormals(level_sets_p1) normals ``` -------------------------------- ### Get Outer Normals Source: https://ngsuite.pages.gwdg.de/ngsxfem/_sources/jupyter/mlset_pde.ipynb.txt Retrieve outer normals for the square domain using level set functions. ```python normals = square.GetOuterNormals(level_sets_p1) ``` -------------------------------- ### Assemble and Solve Linear System Source: https://ngsuite.pages.gwdg.de/ngsxfem/_sources/jupyter/unfmixed.ipynb.txt Assembles the bilinear form p and linear form pf, then solves the system using the UMFPACK inverse solver. ```python p += (lam * vs + mu * ps) * dxinner p += (lam * vs + mu * ps) * ds # R.h.s. term: pf = LinearForm(Zh) pf += gfu * grad(vs) * dxbar pf += p_exact * mu * ds pf += gfpT * mu * dxinner #Assembly p.Assemble() pf.Assemble() #Solving the system gfz.vec.data = p.mat.Inverse(Zh.FreeDofs(),inverse="umfpack") * pf.vec #For visualization: gflh.Set(p_exact, definedonelements=ci.GetElementsOfType(HASNEG)) gflam.Set(gfps, definedonelements=ci.GetElementsOfType(HASNEG)) ``` -------------------------------- ### Initialize convergence study with order 2 and error dictionaries Source: https://ngsuite.pages.gwdg.de/ngsxfem/_sources/jupyter/intlset.ipynb.txt Sets up the mesh, level set function, reference values, and error/EOC dictionaries for the convergence study. Uses LevelSetMeshAdaptation with order 2 and discontinuous quadrature. ```python order = 2 mesh = Mesh(geo.GenerateMesh(maxh=0.7,quad_dominated=False)) levelset = sqrt(x*x+y*y)-1 referencevals = { POS : 9-pi, NEG : pi, IF : 2*pi } lsetmeshadap = LevelSetMeshAdaptation(mesh, order=order, threshold=0.2, discontinuous_qn=True) lsetp1 = lsetmeshadap.lset_p1 errors_uncurved = dict() errors_curved = dict() eoc_uncurved = dict() eoc_curved = dict() for key in [NEG,POS,IF]: errors_curved[key] = [] errors_uncurved[key] = [] eoc_curved[key] = [] eoc_uncurved[key] = [] ``` -------------------------------- ### Importing libraries Source: https://ngsuite.pages.gwdg.de/ngsxfem/_sources/jupyter/mlset_basic.ipynb.txt Imports the necessary modules for geometry, NGSolve, and xfem, and sets up the discontinuous drawing utility. ```python # Import geometry features, NGSolve and xfem from netgen.occ import * from ngsolve import * from xfem import * # Visualisation from ngsolve.webgui import * DrawDC = MakeDiscontinuousDraw(Draw) ``` -------------------------------- ### Define Time Mapping Source: https://ngsuite.pages.gwdg.de/ngsxfem/jupyter/spacetime_unfitted.html Maps the reference time variable to physical time using parameters for the start time and time step size. ```python # Map from reference time to physical time told = Parameter(tstart) t = told + delta_t * tref t.MakeVariable() ``` ```python ``` -------------------------------- ### Assemble and solve the system Source: https://ngsuite.pages.gwdg.de/ngsxfem/_sources/jupyter/mlset_pde.ipynb.txt Assembles the linear system and solves it using a sparse Cholesky inverse as a preconditioner. ```python f.Assemble() a.Assemble() inv = a.mat.Inverse(freedofs=freedofs, inverse="sparsecholesky") gfu.vec.data = PreRic(a=a, rhs=f.vec, pre=inv, freedofs=freedofs) ``` -------------------------------- ### Get outer normals for the domain boundary Source: https://ngsuite.pages.gwdg.de/ngsxfem/jupyter/mlset_pde.html Uses DomainTypeArray.GetOuterNormals() to obtain the normal vectors for the square domain, given the level set function level_sets_p1. ```python normals = square.GetOuterNormals(level_sets_p1) ``` -------------------------------- ### Initialize Geometry and Level Sets Source: https://ngsuite.pages.gwdg.de/ngsxfem/_sources/jupyter/mlset_basic.ipynb.txt Sets up the OCC geometry, generates the mesh, and initializes level set grid functions. ```python geo = OCCGeometry(unit_square_shape.Scale((0,0,0),2.2).Move((-1.1,-1.1,0)), dim=2) mesh = Mesh (geo.GenerateMesh(maxh=0.2/interactive)) level_sets = [x * x + y * y - 1, -x - 1 / 3, x - 1 / 3, y - 0.5] level_sets_p1 = tuple(GridFunction(H1(mesh, order=1)) for i in range(len(level_sets))) for i, lsetp1 in enumerate(level_sets_p1): InterpolateToP1(level_sets[i], lsetp1) DrawDC(lsetp1, -3.5, 2.5, mesh, "lset_p1_" + str(i)) ``` -------------------------------- ### Visualize exact solution Source: https://ngsuite.pages.gwdg.de/ngsxfem/jupyter/spacetime_fitted.html Project and animate the exact solution over the time interval. ```python u_exact = sin(pi * t) * sin(pi * x)**2 * sin(pi * y)**2 from helper import ProjectOnMultiDimGF u_exact_to_show = ProjectOnMultiDimGF(sin(pi * tref) * sin(pi * x)**2 * sin(pi * y)**2,mesh,order=3,sampling=8) Draw(u_exact_to_show,mesh,"u_exact",autoscale=False,min=0,max=1, interpolate_multidim=True, animate=True, deformation=True) # The multidim-option now samples within the time interval [0,1]. ``` ```python BaseWebGuiScene ``` -------------------------------- ### Create GridFunction, trial/test functions, and standard coefficients Source: https://ngsuite.pages.gwdg.de/ngsxfem/_sources/jupyter/unfmixed.ipynb.txt Creates a GridFunction on the product space Wh, extracts its first two components, and defines trial/test functions. Also defines the mesh size h and the unit normal n to the level set. ```python gfw = GridFunction(Wh) gfu, gfpT = gfw.components[0:2] (uh,pT), (vh,qT) = Wh.TnT() h = specialcf.mesh_size # mesh size n = Normalize(grad(lsetp1)) # normal to level set ``` -------------------------------- ### Get element markers for cut and active elements Source: https://ngsuite.pages.gwdg.de/ngsxfem/_sources/jupyter/unfmixed.ipynb.txt Creates a CutInfo object and retrieves element markers for negative, positive, cut, and all elements. These markers are used to identify the active mesh and cut elements. ```python ci = CutInfo(mesh, lsetp1) hasneg = ci.GetElementsOfType(HASNEG) # elements with negative level set (root elements) pos = ci.GetElementsOfType(POS) # outside elements hasif = ci.GetElementsOfType(IF) # cut elements hasany = ci.GetElementsOfType(ANY) # all elements (trivial array) ``` -------------------------------- ### Import Netgen/NGSolve and visualization modules Source: https://ngsuite.pages.gwdg.de/ngsxfem/jupyter/basics.html Imports NGSolve, webgui, netgen.occ, and internal visualization. The netgen.gui import is commented out. ```python #import netgen.gui # ngsolve stuff from ngsolve import * from ngsolve.webgui import * # basic geometry features (for the background mesh) from netgen.occ import * # visualization stuff from ngsolve.internal import * ``` -------------------------------- ### Initializing MultiLevelsetCutInfo Source: https://ngsuite.pages.gwdg.de/ngsxfem/_sources/jupyter/mlset_pde.ipynb.txt Creates the cut information object required for handling multiple level sets. ```python mlci = MultiLevelsetCutInfo(mesh, level_sets_p1) ``` -------------------------------- ### Display ElementAggregation help Source: https://ngsuite.pages.gwdg.de/ngsxfem/jupyter/aggregation.html Shows the help output for the ElementAggregation class, including its constructor, Update method, and properties like element_to_patch and patch_interior_facets. ```python help(ElementAggregation) ``` ```output Help on class ElementAggregation in module xfem.xfem: class ElementAggregation(pybind11_builtins.pybind11_object) | ElementAggregation does the following: | It collects patches of elements that allow to stabilize bad cut elements by at least one | good element (the root element). | ) | | Method resolution order: | ElementAggregation | pybind11_builtins.pybind11_object | builtins.object | | Methods defined here: | | Update(...) | Update(self: xfem.xfem.ElementAggregation, root_elements: pyngcore.pyngcore.BitArray, bad_elements: pyngcore.pyngcore.BitArray, heapsize: int = 1000000) -> None | | | Updates a Element Aggregation based ... | | __init__(...) | __init__(self: xfem.xfem.ElementAggregation, mesh: ngsolve.comp.Mesh, root_elements: object = None, bad_elements: object = None, heapsize: int = 1000000) -> None | | | Creates a ElementAggregation based on a mesh, a list of root and a list of bad elements. | | ---------------------------------------------------------------------- | Readonly properties defined here: | | element_to_patch | vector mapping elements to (non-trivial) patches | | els_in_nontrivial_patch | BitArray that is true for every element that is part of a (non-trivial) patch | | els_in_trivial_patch | BitArray that is true for every element that is not part of a (non-trivial) patch | | facet_to_patch | vector mapping facets to (non-trivial) patches | | patch_interior_facets | BitArray that is true for every facet that is *inside* an aggregation cluster | | ---------------------------------------------------------------------- | Static methods inherited from pybind11_builtins.pybind11_object: | | __new__(*args, **kwargs) class method of pybind11_builtins.pybind11_object | Create and return a new object. See help(type) for accurate signature. ``` -------------------------------- ### Prepare visualization storage Source: https://ngsuite.pages.gwdg.de/ngsxfem/jupyter/spacetime_fitted.html Creates a multidimensional GridFunction to store spatial solutions across time steps. ```python gfut = GridFunction(u_last.space, multidim=0) gfut.AddMultiDimComponent(u_last.vec) ``` -------------------------------- ### Do Source: https://ngsuite.pages.gwdg.de/ngsxfem/xfem_doc/xfem.xfem.html Executes the space-time VTK output for a given time interval and optional element selection. ```APIDOC ## Do ### Description Executes the space-time VTK output for a given time interval and optional element selection. ### Method Do ### Signature Do(self: xfem.xfem.SpaceTimeVTKOutput, vb: ngsolve.comp.VorB = , t_start: float = 0, t_end: float = 1) -> None Do(self: xfem.xfem.SpaceTimeVTKOutput, vb: ngsolve.comp.VorB = , t_start: float = 0, t_end: float = 1, drawelems: pyngcore.pyngcore.BitArray) -> None ### Parameters - **vb** (ngsolve.comp.VorB) - Optional - Volume or boundary selection (default: VOL). - **t_start** (float) - Optional - Start time (default: 0). - **t_end** (float) - Optional - End time (default: 1). - **drawelems** (pyngcore.pyngcore.BitArray) - Optional - BitArray specifying which elements to draw. ### Returns None ``` -------------------------------- ### Construct Domains from DomainTypeArrays Source: https://ngsuite.pages.gwdg.de/ngsxfem/_sources/jupyter/mlset_basic.ipynb.txt Initializes geometry and visualizes a domain defined by level sets. ```python geo = OCCGeometry( Rectangle(3.5,3.5).Face().Move((-2.5,-1,0)), dim=2 ) mesh = Mesh (geo.GenerateMesh(maxh=0.3/interactive)) level_sets1 = [-2*x + y - 1, 2*x + y - 1, -y + 2] dta1 = DomainTypeArray((POS, POS, POS)) DrawDC(dta1.Indicator(level_sets1), -3.5, 2.5, mesh, "dta1") level_sets2 = [-2*x + y - 4, 2*x + y + 2, -y] ``` -------------------------------- ### Initialize initial value and visualization storage Source: https://ngsuite.pages.gwdg.de/ngsxfem/_sources/jupyter/spacetime_fitted.ipynb.txt Sets the initial value u_last by restricting the exact solution to tref=0, and initializes the time variable. Also creates a multidim GridFunction to store solutions for visualization. ```python u_last.Set(fix_tref(u_exact, 0)) told.Set(0.) ``` ```python gfut = GridFunction(u_last.space, multidim=0) gfut.AddMultiDimComponent(u_last.vec) ``` -------------------------------- ### Assemble and solve system with PreRic Source: https://ngsuite.pages.gwdg.de/ngsxfem/jupyter/mlset_pde.html Assembles the bilinear form 'a' and linear form 'f', creates a sparse Cholesky inverse, and solves the system using the PreRic preconditioned Richardson iteration. The output shows the residual norm converging to machine precision. ```python f.Assemble() a.Assemble() inv = a.mat.Inverse(freedofs=freedofs, inverse="sparsecholesky") gfu.vec.data = PreRic(a=a, rhs=f.vec, pre=inv, freedofs=freedofs) ``` ```text it = 0 ||res||_2 = 1.0429822833324238 it = 1 ||res||_2 = 9.764445829407985e-15 ``` -------------------------------- ### Import basic libraries for unfitted FEM Source: https://ngsuite.pages.gwdg.de/ngsxfem/_sources/jupyter/unfmixed.ipynb.txt Imports the core modules from netgen, ngsolve, and ngsxfem (including xfem and lsetcurv) needed for unfitted finite element simulations. ```python #basic imports from netgen.occ import * from ngsolve import * from ngsolve.internal import * from xfem import * from xfem.lsetcurv import * ``` -------------------------------- ### Initialize Geometry and Level Set Source: https://ngsuite.pages.gwdg.de/ngsxfem/jupyter/cutfem.html Defines the geometry using OCCGeometry and sets up the level set function for the interface problem. ```python geo = OCCGeometry(unit_square_shape.Scale((0,0,0),3).Move((-1.5,-1.5,0)), dim=2) mesh = Mesh(geo.GenerateMesh(maxh=0.4,quad_dominated=False)) levelset = (sqrt(x*x+y*y) - 1.0) DrawDC(levelset, -3.5, 2.5, mesh,"levelset") lsetp1 = GridFunction(H1(mesh,order=1)) InterpolateToP1(levelset,lsetp1) DrawDC(lsetp1, -3.5, 2.5, mesh, "lsetp1") ``` -------------------------------- ### Import ngsxfem and dependencies Source: https://ngsuite.pages.gwdg.de/ngsxfem/jupyter/intlset.html Imports required modules for background geometry, ngsolve, xfem, isoparametric mapping, visualization, and the constant pi. ```python # basic geometry features (for the background mesh) from netgen.geom2d import SplineGeometry # ngsolve from netgen.occ import * # basic xfem functionality from xfem import * # for isoparametric mapping from xfem.lsetcurv import * # visualisation from ngsolve.webgui import * # the contant pi from math import pi ``` -------------------------------- ### Initialize Restricted Bilinear Form Source: https://ngsuite.pages.gwdg.de/ngsxfem/_sources/jupyter/mlset_pde.ipynb.txt Create a RestrictedBilinearForm for the unfitted problem. ```python a = RestrictedBilinearForm(V, element_restriction=els_hasneg, facet_restriction=facets_gp, check_unused=False) ``` -------------------------------- ### Importing required libraries Source: https://ngsuite.pages.gwdg.de/ngsxfem/_sources/jupyter/mlset_pde.ipynb.txt Imports necessary modules for NGSolve, ngsxfem, and visualization. ```python # Basic NGSolve things from netgen.occ import * from ngsolve import * from ngsolve.solvers import PreconditionedRichardson as PreRic # ngsxfem and the mlset convenience layer from xfem import * from xfem.mlset import * # Visualisation from ngsolve.webgui import * DrawDC = MakeDiscontinuousDraw(Draw) ``` -------------------------------- ### Inspect ElementAggregation class Source: https://ngsuite.pages.gwdg.de/ngsxfem/_sources/jupyter/aggregation.ipynb.txt Displays help information for the ElementAggregation class. ```python help(ElementAggregation) ``` -------------------------------- ### Initialize DomainTypeArray with persistent compression Source: https://ngsuite.pages.gwdg.de/ngsxfem/_sources/jupyter/mlset_basic.ipynb.txt Initializes a DomainTypeArray with level sets and enables persistent compression for derived objects. ```python tmp1 = DomainTypeArray((NEG,ANY,ANY,ANY), lsets=level_sets_p1, persistent_compress=True) tmp2 = DomainTypeArray((NEG,NEG,NEG,NEG), lsets=level_sets_p1, persistent_compress=True) z_disc2 = tmp1 & ~tmp2 z_disc2.as_list ``` -------------------------------- ### Initialize mesh and level set Source: https://ngsuite.pages.gwdg.de/ngsxfem/_sources/jupyter/aggregation.ipynb.txt Sets up a structured 2D mesh and a level set function to identify cut elements. ```python from ngsolve.meshes import MakeStructured2DMesh mesh = MakeStructured2DMesh(quads=False, nx=3, ny=2) levelset = x - 0.8 gflset = GridFunction(H1(mesh)) InterpolateToP1(levelset, gflset) DrawDC(gflset, -1.0, 2.0, mesh, "x") ``` -------------------------------- ### Initialize CutInfo for space-time Source: https://ngsuite.pages.gwdg.de/ngsxfem/jupyter/spacetime_unfitted.html Initializes the CutInfo class for space-time geometries using the time_order argument. ```python ci = CutInfo(mesh, time_order=0) ``` -------------------------------- ### Create and visualize aggregation patches Source: https://ngsuite.pages.gwdg.de/ngsxfem/_sources/jupyter/aggregation.ipynb.txt Instantiates an ElementAggregation object and visualizes the resulting patch distribution. ```python EA = ElementAggregation(mesh, roots, bads) patch_number_field = GridFunction(L2(mesh)) patch_number_field.vec.FV()[:] = EA.element_to_patch Draw(patch_number_field, mesh, "patch_number_field", deformation=CF((0,0,0.02*patch_number_field))) ``` -------------------------------- ### xfem.DrawDiscontinuous_webgui Source: https://ngsuite.pages.gwdg.de/ngsxfem/xfem_doc/xfem.html Visualization method for discontinuous functions using the webgui Draw backend. ```APIDOC ## xfem.DrawDiscontinuous_webgui ### Description Visualization method for discontinuous functions using the webgui Draw backend. ### Parameters - **WebGuiDraw** - Required - The webgui Draw object. - **levelset** - Required - Level set function. - **fneg** - Required - CoefficientFunction for negative side. - **fpos** - Required - CoefficientFunction for positive side. - **args** - Optional - Additional arguments passed to Draw. - **kwargs** - Optional - Additional keyword arguments passed to Draw. ``` -------------------------------- ### Draw Background Components Source: https://ngsuite.pages.gwdg.de/ngsxfem/jupyter/cutfem.html Visualizes the background components of the solution. ```python Draw(gfu.components[0], mesh, "background_uneg") ``` -------------------------------- ### Compress and Restrict Finite Element Spaces Source: https://ngsuite.pages.gwdg.de/ngsxfem/_sources/jupyter/basics.ipynb.txt Demonstrates reducing a finite element space to specific degrees of freedom using Compress and Restrict. ```python Vhbase = H1(mesh, order=1, dirichlet=[]) VhC = Compress(Vhbase,GetDofsOfElements(Vhbase,ci.GetElementsOfType(HASNEG))) ``` ```python VhR = Restrict(Vhbase,ci.GetElementsOfType(HASNEG)) ``` ```python print(Vhbase.ndof, VhC.ndof, VhR.ndof) ``` -------------------------------- ### Create bilinear and linear forms for unfitted mixed method Source: https://ngsuite.pages.gwdg.de/ngsxfem/_sources/jupyter/unfmixed.ipynb.txt Creates the BilinearForm (or RestrictedBilinearForm for ghost penalty) and LinearForm. The ghost penalty case requires a larger sparsity pattern, but only on the stabilizing patches. ```python if gamma_stab > 0: a = RestrictedBilinearForm(Wh, element_restriction=hasneg, facet_restriction=EA.patch_interior_facets, symmetric=True) else: a = BilinearForm(Wh, symmetric=True,condense=False) f = LinearForm(Wh) ``` -------------------------------- ### Define exact solution and right-hand side Source: https://ngsuite.pages.gwdg.de/ngsxfem/_sources/jupyter/spacetime_fitted.ipynb.txt Sets up the exact solution u_exact and computes the corresponding right-hand side f by applying the differential operator. The coefficient is then compiled for efficient evaluation. ```python u_exact = ... coeff_f = u_exact.Diff(t) - (u_exact.Diff(x).Diff(x) + u_exact.Diff(y).Diff(y)) coeff_f = coeff_f.Compile() ``` -------------------------------- ### Generate Background Mesh Source: https://ngsuite.pages.gwdg.de/ngsxfem/jupyter/spacetime_unfitted.html Creates a square background domain using OCCGeometry and generates a mesh with specified refinement levels. ```python # Outer domain: rect = OCCGeometry(Rectangle(1.2,2).Face().Move((-0.6,-1,0)),dim=2) ngmesh = rect.GenerateMesh(maxh=maxh, quad_dominated=False) for j in range(space_refs): ngmesh.Refine() mesh = Mesh(ngmesh) ``` -------------------------------- ### Import ngsxfem modules Source: https://ngsuite.pages.gwdg.de/ngsxfem/jupyter/spacetime_fitted.html Initial imports and configuration for the ngsxfem environment. ```python from netgen.occ import * from ngsolve import * from xfem import * import time from math import pi ngsglobals.msg_level = 1 ``` ```python importing ngsxfem-2.1.2506.dev0 ``` -------------------------------- ### Assemble Bilinear and Linear Forms Source: https://ngsuite.pages.gwdg.de/ngsxfem/jupyter/cutfem.html Assembles the bilinear and linear forms. ```python a.Assemble() f.Assemble() ``` ```python ``` -------------------------------- ### Execute spacetime time loop Source: https://ngsuite.pages.gwdg.de/ngsxfem/jupyter/spacetime_unfitted.html Sets initial values, registers GridFunctions for projection, and iterates through time slabs to solve the problem. ```python # Set initial values u_last.Set(fix_tref(u_exact, 0)) # Project u_last at the beginning of each time step lsetadap.ProjectOnUpdate(u_last) told.Set(0) gf_lset_to_show = GridFunction(H1(mesh, order=1),multidim=0) gf_u_to_show = GridFunction(u_last.space,multidim=0) timestep = 0 md_comps = 0 with TaskManager(): while tend - told.Get() > delta_t/2: UpdateTimeSlabGeometry() if timestep % 1 == 0: gf_lset_to_show.AddMultiDimComponent(lsetadap.levelsetp1[BOTTOM].vec) gf_u_to_show.AddMultiDimComponent(u_last.vec) md_comps += 1 SolveForTimeSlab() timestep += 1 told.Set(told.Get() + delta_t) FinalizeStep(scene) gf_lset_to_show.AddMultiDimComponent(lsetadap.levelsetp1[TOP].vec) gf_u_to_show.AddMultiDimComponent(u_last.vec) print("") ``` -------------------------------- ### Visualize the solution Source: https://ngsuite.pages.gwdg.de/ngsxfem/_sources/jupyter/mlset_pde.ipynb.txt Defines the exact solution and its gradient, then visualizes the computed solution. ```python u_ex = 16 * x * (1 - x) * y * (1 - y) grad_u_ex = CoefficientFunction((16 * (1 - 2 * x) * y * (1 - y), 16 * x * (1 - x) * (1 - 2 * y))) DrawDC(square.Indicator(level_sets_p1), 0, gfu, mesh, "solution") ``` -------------------------------- ### Visualize spacetime results Source: https://ngsuite.pages.gwdg.de/ngsxfem/jupyter/spacetime_unfitted.html Uses MultiDimPairToGF to prepare and draw the spacetime solution with animation. ```python from helper import MultiDimPairToGF gf_pair_to_show = MultiDimPairToGF(gf_lset_to_show,gf_u_to_show,mesh,sampling=md_comps) Draw(gf_pair_to_show, mesh,"uh",eval_function="value.x>0.0?value.z:value.y",autoscale=False, min=-0.5,max=1, interpolate_multidim=True, animate=True) ``` -------------------------------- ### Visualize Post-processed Solution Source: https://ngsuite.pages.gwdg.de/ngsxfem/jupyter/unfmixed.html Visualizes the post-processed pressure field on the physical domain. ```python DrawDC(lsetp1,gfps,-1,mesh,"p",deformation=deformation, min=-1, max=1) # p on physical domain ``` ```text BaseWebGuiScene ``` -------------------------------- ### xfem.DummyScene.Redraw Source: https://ngsuite.pages.gwdg.de/ngsxfem/xfem_doc/xfem.html Redraws the dummy scene, optionally blocking. ```APIDOC ## xfem.DummyScene.Redraw ### Description Redraws the dummy scene. ### Parameters - **blocking** (bool) - Optional - If True, blocks until redraw is complete. ``` -------------------------------- ### Embed YouTube demonstration video Source: https://ngsuite.pages.gwdg.de/ngsxfem/jupyter/spacetime_unfitted.html Displays the simulation result video for the unfitted space-time functionality. ```html %%html ``` -------------------------------- ### Create solution GridFunction Source: https://ngsuite.pages.gwdg.de/ngsxfem/jupyter/spacetime_unfitted.html Initializes the GridFunction for the space-time FESpace and creates a time-restricted version. ```python gfu = GridFunction(st_fes) u_last = CreateTimeRestrictedGF(gfu, 1) ``` -------------------------------- ### SpaceTimeVTKOutput Source: https://ngsuite.pages.gwdg.de/ngsxfem/xfem_doc/xfem.xfem.html A class for VTK output of space-time solutions. ```APIDOC ## SpaceTimeVTKOutput ### Description A class for VTK output of space-time solutions. ### Constructor SpaceTimeVTKOutput() ``` -------------------------------- ### Integration output Source: https://ngsuite.pages.gwdg.de/ngsxfem/jupyter/mlset_basic.html The expected output after running the integration code. ```text Result of the integration: 0.49999999999999994 Error of the integration: 5.551e-17 ``` -------------------------------- ### Create background mesh Source: https://ngsuite.pages.gwdg.de/ngsxfem/_sources/jupyter/basics.ipynb.txt Generates a background mesh for the domain using OCCGeometry and Mesh. ```python geo = OCCGeometry(unit_square_shape.Scale((0,0,0),3).Move((-1.5,-1.5,0)), dim=2) mesh = Mesh(geo.GenerateMesh(maxh=0.5,quad_dominated=False)) ``` -------------------------------- ### Visualize boundary 1 Source: https://ngsuite.pages.gwdg.de/ngsxfem/jupyter/mlset_basic.html Sets visualization options and draws the first normal vector and boundary indicator. ```python ngsolve.internal.visoptions.showsurfacesolution=1 Draw(normals[(IF,NEG,NEG,POS)], mesh, "normal_1", vectors={'grid_size': 14}) DrawDC(DomainTypeArray((IF,NEG,NEG,POS)).IndicatorSmoothed(level_sets_p1, eps=0.08/interactive), -3.5, 2.5, mesh, "boundary_1") ``` ```python BaseWebGuiScene ``` -------------------------------- ### Assemble and solve the unfitted mixed problem Source: https://ngsuite.pages.gwdg.de/ngsxfem/_sources/jupyter/unfmixed.ipynb.txt Assembles the bilinear and linear forms and solves the linear system for the GridFunction gfw. ```python a.Assemble() f.Assemble() gfw.vec.data = a.mat.Inverse(Wh.FreeDofs()) * f.vec ``` -------------------------------- ### Generate Boundaries and Corners Source: https://ngsuite.pages.gwdg.de/ngsxfem/_sources/jupyter/mlset_basic.ipynb.txt Use the Boundary method to obtain the boundary of a region or the corners of a boundary. ```python boundary = triangle.Boundary() boundary.as_list ``` ```python corners = boundary.Boundary() corners.as_list ``` -------------------------------- ### Visualize Level Set and Exact Solution Pair Source: https://ngsuite.pages.gwdg.de/ngsxfem/jupyter/spacetime_unfitted.html Projects both the level set and the exact solution as a pair onto a multi-dimensional grid function for visualization. ```python u_exact_one_timestep = cos(pi * r_one_timestep / R) * sin(pi * tref * tend) from helper import ProjectPairOnMultiDimGF lset_cf_to_show = ProjectPairOnMultiDimGF(levelset_one_timestep, u_exact_one_timestep,mesh,order=3,sampling=8) Draw(lset_cf_to_show,mesh,"u_exact",eval_function="value.x>0.0?value.z:value.y",autoscale=False, min=-0.5,max=1, interpolate_multidim=True, animate=True) ``` ```python BaseWebGuiScene ``` -------------------------------- ### Define FE Spaces for Post-processing Source: https://ngsuite.pages.gwdg.de/ngsxfem/_sources/jupyter/unfmixed.ipynb.txt Sets up the finite element spaces for the solution p and integral constraints, then creates a combined space and GridFunction. ```python #FE Spaces for el-wise post-processing Vhpbase = L2(mesh, order=order+1, dgjumps=True, dirichlet=[]) # for p Lhbase = L2(mesh, order=0, dgjumps=True, dirichlet=[]) # for integral constraints Vhp = Restrict(Vhpbase, hasneg) Lh = Restrict(Lhbase, ci.GetElementsOfType(NEG)) # one constraint per patch / root element Zh = Vhp * Lh (ps,lam),(vs,mu) = Zh.TnT() gfz = GridFunction(Zh) gfps, gflam = gfz.components ``` -------------------------------- ### Visualize solution with DrawDC Source: https://ngsuite.pages.gwdg.de/ngsxfem/jupyter/mlset_pde.html Defines the exact solution and its gradient, then visualizes the computed solution using DrawDC with the level set indicator. The output is a BaseWebGuiScene. ```python u_ex = 16 * x * (1 - x) * y * (1 - y) grad_u_ex = CoefficientFunction((16 * (1 - 2 * x) * y * (1 - y), 16 * x * (1 - x) * (1 - 2 * y))) DrawDC(square.Indicator(level_sets_p1), 0, gfu, mesh, "solution") ``` ```text BaseWebGuiScene ``` -------------------------------- ### Define XFEM space with XFESpace Source: https://ngsuite.pages.gwdg.de/ngsxfem/jupyter/cutfem.html Creates a standard H1 space and an XFEM space Vhx, then combines them into a product space VhG. The XFEM space enriches the standard space on cut elements. ```python Vh = H1(mesh, order=2, dirichlet=[1,2,3,4]) Vhx = XFESpace(Vh,ci) VhG = FESpace([Vh,Vhx]) ``` -------------------------------- ### Visualize L2 Higher Order Basis Functions Source: https://ngsuite.pages.gwdg.de/ngsxfem/_sources/jupyter/aggregation.ipynb.txt Visualizes extended basis functions for an L2 finite element space of order 2. ```python fes = L2(mesh, order=2) ShowPattern(AggEmbedding(EA, fes)) gfshow = ExtendedBasisFunctionsAsMultiDim(EA,fes) Draw (gfshow, mesh, interpolate_multidim=False, animate=False, autoscale=True); ``` -------------------------------- ### Identify Elements and Visualize Source: https://ngsuite.pages.gwdg.de/ngsxfem/_sources/jupyter/mlset_pde.ipynb.txt Extract elements with contributions from the square and boundary, then visualize them using BitArrayCF. ```python els_hasneg = mlci.GetElementsWithContribution(square) els_if = mlci.GetElementsWithContribution(boundary) Draw(BitArrayCF(els_hasneg), mesh, "els_hasneg") Draw(BitArrayCF(els_if), mesh, "els_if") ``` -------------------------------- ### Visualize time evolution with animation Source: https://ngsuite.pages.gwdg.de/ngsxfem/_sources/jupyter/spacetime_fitted.ipynb.txt Draws the stored multidim solution with animation and deformation enabled, allowing interactive control of the time evolution. ```python Draw (gfut, mesh, interpolate_multidim=True, animate=True, deformation=True, min=0, max=1, autoscale=False) ``` -------------------------------- ### Initialize DrawDC scene Source: https://ngsuite.pages.gwdg.de/ngsxfem/jupyter/spacetime_unfitted.html Initializes the visualization scene using DrawDC with specific mesh and deformation parameters. ```python scene = DrawDC(lsetadap.levelsetp1[TOP],u_last,-2, mesh,"u", autoscale=False, min = -2, max = 1, deformation = lsetadap.deformation[TOP]) ``` -------------------------------- ### Run convergence study with refinements Source: https://ngsuite.pages.gwdg.de/ngsxfem/jupyter/intlset.html Performs the convergence study: refines the mesh, computes integrals with and without deformation, and records errors. ```python f = CoefficientFunction (1.0) refinements = 5 for reflevel in range(refinements): if(reflevel > 0): mesh.Refine() for key in [NEG,POS,IF]: # Applying the mesh deformation deformation = lsetmeshadap.CalcDeformation(levelset) integrals_uncurved = Integrate(f * dCut(levelset=lsetp1, domain_type=key, order=order), mesh=mesh) # dCut deals with the mesh deformation internally integrals_curved = Integrate(f * dCut(levelset=lsetp1, domain_type=key, order=order, deformation=deformation), mesh=mesh) errors_curved[key].append(abs(integrals_curved - referencevals[key])) errors_uncurved[key].append(abs(integrals_uncurved - referencevals[key])) # refine cut elements: RefineAtLevelSet(gf=lsetmeshadap.lset_p1) ``` -------------------------------- ### Defining Finite Element spaces Source: https://ngsuite.pages.gwdg.de/ngsxfem/_sources/jupyter/mlset_pde.ipynb.txt Sets up the H1 finite element space and grid function. ```python k = 3 V = H1(mesh, order=k, dgjumps=True) gfu = GridFunction(V) ``` -------------------------------- ### Manual Domain Construction Source: https://ngsuite.pages.gwdg.de/ngsxfem/_sources/jupyter/mlset_basic.ipynb.txt Constructs a domain union manually by defining specific region combinations. ```python dta3 = DomainTypeArray([(POS, POS, POS, ANY, ANY, ANY), (ANY, ANY, ANY, NEG, NEG, NEG)]) DrawDC(dta3.Indicator(level_sets1 + level_sets2), -3.5, 2.5, mesh, "union") ``` -------------------------------- ### XFESpace Source: https://ngsuite.pages.gwdg.de/ngsxfem/xfem_doc/xfem.xfem.html Constructor for XFESpace, an extended finite element space based on cut information. ```APIDOC ## XFESpace ### Description Constructor for XFESpace. Extended finite element space. Takes a basis FESpace and creates an enrichment space based on cut information. The cut information is provided by a CutInfo object or - if a level set function is only provided - a CutInfo object is created. The enrichment doubles the unknowns on all cut elements and assigns to them a sign (NEG/POS). One of the differential operators neg(…) or pos(…) evaluates like the basis function of the origin space, the other one as zero for every basis function. Away from cut elements no basis function is supported. ### Signature xfem.xfem.XFESpace(basefes: ngsolve.comp.FESpace, cutinfo: object = None, lset: object = None, flags: dict = {}, heapsize: int = 1000000) -> ngcomp::XFESpace ### Parameters - **basefes** (ngsolve.comp.FESpace) - Required - Basic FESpace to be extended. - **cutinfo** (xfem.CutInfo / None) - Optional - Information on the cut configurations (cut elements, sign of vertices…). - **lset** (ngsolve.CoefficientFunction / None) - Optional - Level set function to construct own CutInfo (if no CutInfo is provided). - **flags** (Flags) - Optional - Additional FESpace-flags. - **heapsize** (int) - Optional - Heapsize of local computations (default: 1000000). ### Returns ngcomp::XFESpace ``` -------------------------------- ### Setting interactive parameter Source: https://ngsuite.pages.gwdg.de/ngsxfem/_sources/jupyter/mlset_basic.ipynb.txt Sets the interactive parameter to control grid coarseness. ```python interactive = 1 ``` -------------------------------- ### Initialize LevelSetMeshAdaptation_Spacetime Source: https://ngsuite.pages.gwdg.de/ngsxfem/jupyter/spacetime_unfitted.html Configures the space-time version of the Levelset Mesh Adaptation object for higher-order accuracy. ```python # Space time version of Levelset Mesh Adapation object. Also offers integrator # helper functions that involve the correct mesh deformation lsetadap = LevelSetMeshAdaptation_Spacetime(mesh, order_space=k_s, order_time=lset_order_time, threshold=0.5, discontinuous_qn=True) ``` -------------------------------- ### Generating the background mesh Source: https://ngsuite.pages.gwdg.de/ngsxfem/_sources/jupyter/mlset_pde.ipynb.txt Creates a background mesh for the unit square domain. ```python geo = OCCGeometry(unit_square_shape.Scale((0,0,0),1.5).Move((-0.2,-0.2,0)), dim=2) mesh = Mesh(geo.GenerateMesh(maxh=0.1)) ``` -------------------------------- ### Import xfem package Source: https://ngsuite.pages.gwdg.de/ngsxfem/jupyter/basics.html Imports the basic xfem functionality from the ngsxfem package. ```python # basic xfem functionality from xfem import * ``` -------------------------------- ### Initialize Space-Time Finite Element Space Source: https://ngsuite.pages.gwdg.de/ngsxfem/jupyter/spacetime_unfitted.html Initializes the finite element space and mesh size constant for space-time calculations. ```python u,v = st_fes.TnT() h = specialcf.mesh_size ``` -------------------------------- ### Define discretization parameters Source: https://ngsuite.pages.gwdg.de/ngsxfem/jupyter/spacetime_unfitted.html Sets parameters for refinement, polynomial order, time stepping, and ghost-penalty stabilization. ```python # DISCRETIZATION PARAMETERS: # Parameter for refinement study: i = 3 n_steps = 2**i space_refs = i # Polynomial order in time k_t = 2 # Polynomial order in space k_s = k_t # Polynomial order in time for level set approximation lset_order_time = k_t # Integration order in time time_order = 2 * k_t # Time stepping parameters tstart = 0 tend = 0.5 delta_t = (tend - tstart) / n_steps maxh = 0.5 # Ghost-penalty parameter gamma = 0.05 ``` -------------------------------- ### Visualize Domain Boundary 7 Source: https://ngsuite.pages.gwdg.de/ngsxfem/_sources/jupyter/mlset_basic.ipynb.txt Draws normals and boundary for the seventh domain configuration. ```python Draw(normals[(NEG,IF,NEG,NEG)], mesh, "normal_7", vectors={'grid_size': 14}) DrawDC(DomainTypeArray((NEG,IF,NEG,NEG)).IndicatorSmoothed(level_sets_p1, eps=0.08/interactive), -3.5, 2.5, mesh, "boundary_7") ``` -------------------------------- ### Solve System with PatchwiseSolve Source: https://ngsuite.pages.gwdg.de/ngsxfem/_sources/jupyter/unfmixed.ipynb.txt Computes the solution by exploiting the decoupling of the linear system into patches. ```python gfz.vec.data = PatchwiseSolve(EA,Zh,sum(lhs_integrals),sum(rhs_integrals)) ```