def __init__(self, mesh=None, levelset=None): self.deform = GridFunction(H1(mesh, order=1, dim=mesh.dim), "dummy_deform") self.deform.vec.data[:] = 0.0 if levelset != None: if mesh == None: raise Exception("need mesh") self.lset_p1 = GridFunction(H1(mesh, order=1)) InterpolateToP1(levelset, self.lset_p1)
def PartialApproximateWithFESpace(N=64, order=3, f="sin(3·pi·x)", j=2): i = j if f == "sin(3·pi·x)": f = Sin(3 * pi * X) elif f == "sin(3·pi·x)·cos(5·pi·x)": f = Sin(3 * pi * X) * Cos(5 * pi * X) else: print("no function provided") return mesh1D = Mesh1D(N) try: f(mesh1D(0.5)) except: print("expression for f not valid!") return fes = H1(mesh1D, order=order) if (i > fes.ndof): print("j is too large. Setting j = ", fes.ndof - 1) i = fes.ndof gf = GridFunction(fes) gf.Set(f) for j in range(i, fes.ndof): gf.vec[j] = 0 Draw1D(mesh1D, [(gf, "FE Approximation"), (f, "exakte Funktion")], n_p=20) for j in range(i): print("{:5.2f}".format(gf.vec[j]), end=" ") if (j > 0 and j % 18 == 17): print("")
def ApproximateWithFESpace(N=64, order=3, f="sin(3·pi·x)"): if f == "sin(3·pi·x)": f = Sin(3 * pi * X) elif f == "sin(3·pi·x)·cos(5·pi·x)": f = Sin(3 * pi * X) * Cos(5 * pi * X) else: print("no function provided") return mesh1D = Mesh1D(N) try: f(mesh1D(0.5)) except: print("expression for f not valid!") return fes = H1(mesh1D, order=order) gf = GridFunction(fes) gf.Set(f) Draw1D(mesh1D, [(gf, "FE Approximation"), (f, "exakte Funktion")], n_p=20) for i in range(fes.ndof): print("{:5.2f}".format(gf.vec[i]), end=" ") if (i > 0 and i % 18 == 17): print("")
def dxtref(mesh, order=None, time_order=-1, **kwargs): """ Differential symbol for the integration over all elements extruded by the reference interval [0,1] to space-time prisms. Parameters ---------- mesh : ngsolve.Mesh The spatial mesh. The domain type of interest. order : int Modify the order of the integration rule used. definedon : Region Domain description on where the integrator is defined. vb : {VOL, BND, BBND} Integration on domains volume or boundary. Default: VOL (if combined with skeleton VOL means interior facets, BND means boundary facets) element_boundary : bool Integration on each element boundary. Default: False element_vb : {VOL, BND, BBND} Integration on each element or its (B)boundary. Default: VOL (is overwritten by element_boundary if element_boundary is True) skeleton : bool Integration over element-interface. Default: False. deformation : ngsolve.GridFunction Mesh deformation. Default: None. definedonelements : ngsolve.BitArray Allows integration only on elements or facets (if skeleton=True) that are marked True. Default: None. time_order : int Order in time that is used in the space-time integration. Default: time_order=-1 means that no space-time rule will be applied. This is only relevant for space-time discretizations. Return ------ CutDifferentialSymbol(VOL) """ tFE = ScalarTimeFE(1) STFES = tFE*H1(mesh) gflset = GridFunction(STFES) gflset.vec[:] = 1 for i in range(gflset.space.ndof): gflset.vec[i] = i+1 lsetdom = {"levelset": gflset, "domain_type": POS} if order is not None: if type(order) != int: raise Exception("dxtref: order is not an integer! use keyword arguments for vb=VOL/BND.") lsetdom["order"] = order if type(time_order) != int: raise Exception("dxtref: time_order is not an integer! use keyword arguments for vb=VOL/BND.") if time_order > -1: lsetdom["time_order"] = time_order return _dCut_raw(lsetdom, **kwargs)
def DrawBasisFunction(N=4, i=0, order=1): mesh1D = Mesh1D(N) fes = H1(mesh1D, order=order) gf = GridFunction(fes) gf.vec[:] = 0 if i >= fes.ndof: print(" i is too large. Setting it to", fes.ndof - 1) i = fes.ndof - 1 gf.vec[i] = 1 Draw1D(mesh1D, [(gf, "Basisfunktion " + str(i))], n_p=2 * order**2)
def SpyDG(N=8, order=1): mesh1D = Mesh1D(N) fes = Discontinuous(H1(mesh1D, order=order)) #, dirichlet=) u, v = fes.TnT() a = BilinearForm(fes) a += SymbolicBFI(grad(u) * grad(v)) a.Assemble() rows, cols, vals = a.mat.COO() A = sp.csr_matrix((vals, (rows, cols))) plt.figure(figsize=(7, 7)) plt.spy(A) plt.show()
def makeforms(mesh, p, F, q_zero, mu_zero, cwave, epsil=0): d = mesh.dim W = L2(mesh, order=p + d) U = L2(mesh, order=p) Zq = H1(mesh, order=p + 1, dirichlet=q_zero, orderinner=0) Zmu = H1(mesh, order=p + 1, dirichlet=mu_zero, orderinner=0) spacelist = [W] * d + [U] * d + [Zq] * (d - 1) + [Zmu] X = FESpace(spacelist) # separate W...W, U...U, Zq...Zq, Zmu separators = [d, 2 * d, 2 * d + (d - 1)] Xtrials = X.TrialFunction() e = Xtrials[0:separators[0]] u = Xtrials[separators[0]:separators[1]] zu = Xtrials[separators[1]:] Xtests = X.TestFunction() w = Xtests[0:separators[0]] v = Xtests[separators[0]:separators[1]] zv = Xtests[separators[1]:] n = specialcf.normal(d) a = BilinearForm(X, symmetric=True, eliminate_internal=True) a += SymbolicBFI(vec(e) * vec(w)) a += SymbolicBFI(waveA(e, cwave) * waveA(w, cwave)) a += SymbolicBFI(-vec(u) * waveA(w, cwave)) a += SymbolicBFI(-waveA(e, cwave) * vec(v)) a += SymbolicBFI(vec(e) * waveD(n, zv, cwave), element_boundary=True) a += SymbolicBFI(waveD(n, zu, cwave) * vec(w), element_boundary=True) a += SymbolicBFI(-epsil * vec(zu) * vec(zv)) f = LinearForm(X) f += SymbolicLFI(F * vec(w)) return (a, f, X, separators)
def dmesh(mesh=None, *args, **kwargs): """ Differential symbol for the integration over all elements in the mesh. Parameters ---------- mesh : ngsolve.Mesh The spatial mesh. The domain type of interest. definedon : Region Domain description on where the integrator is defined. element_boundary : bool Integration on each element boundary. Default: False element_vb : {VOL, BND, BBND} Integration on each element or its (B)boundary. Default: VOL (is overwritten by element_boundary if element_boundary is True) skeleton : bool Integration over element-interface. Default: False. deformation : ngsolve.GridFunction Mesh deformation. Default: None. definedonelements : ngsolve.BitArray Allows integration only on elements or facets (if skeleton=True) that are marked True. Default: None. tref : float turns a spatial integral resulting in spatial integration rules into a space-time quadrature rule with fixed reference time tref Return ------ CutDifferentialSymbol(VOL) """ if "tref" in kwargs: if mesh == None: raise Exception("dx(..,tref..) needs mesh") gflset = GridFunction(H1(mesh)) gflset.vec[:] = 1 lsetdom = { "levelset": gflset, "domain_type": POS, "tref": kwargs["tref"] } del kwargs["tref"] return _dCut_raw(lsetdom, **kwargs) else: return dx(*args, **kwargs)
def dxtref(mesh, order=None, time_order=-1, **kwargs): """ Differential symbol for the integration over all elements extruded by the reference interval [0,1] to space-time prisms. Parameters ---------- mesh : ngsolve.Mesh The spatial mesh. The domain type of interest. order : int Modify the order of the integration rule used. definedon : Region Domain description on where the integrator is defined. element_boundary : bool Integration on each element boundary. Default: False element_vb : {VOL, BND, BBND} Integration on each element or its (B)boundary. Default: VOL (is overwritten by element_boundary if element_boundary is True) skeleton : bool Integration over element-interface. Default: False. deformation : ngsolve.GridFunction Mesh deformation. Default: None. definedonelements : ngsolve.BitArray Allows integration only on elements or facets (if skeleton=True) that are marked True. Default: None. time_order : int Order in time that is used in the space-time integration. Default: time_order=-1 means that no space-time rule will be applied. This is only relevant for space-time discretizations. Return ------ CutDifferentialSymbol(VOL) """ gflset = GridFunction(H1(mesh)) gflset.vec[:] = 1 lsetdom = {"levelset": gflset, "domain_type": POS} if order is not None: lsetdom["order"] = order if time_order > -1: lsetdom["time_order"] = time_order return _dCut_raw(lsetdom, **kwargs)
def ComputeMatrixEntry2(N=8, order=1, k=1, i=0, j=0): mesh1D = Mesh1D(N) fes = H1(mesh1D, order=order) #, dirichlet=) gf1 = GridFunction(fes) gf2 = GridFunction(fes) gf1.vec[:] = 0 gf1.vec[i] = 1. gf2.vec[:] = 0 gf2.vec[j] = 1. Draw1D(mesh1D, [(gf1, "phi_i"), (gf2, "phi_j")], n_p=5 * order**2, figsize=(12, 3.5)) Draw1D(mesh1D, [(grad(gf1)[0], "dphi_idx"), (grad(gf2)[0], "dphi_jdx")], n_p=5 * order**2, figsize=(12, 3.5)) print("A[i,j] = ", Integrate(gf1.Deriv() * gf2.Deriv(), mesh1D, order=2 * (order - 1)))
# solve the Poisson equation -Delta u = f # with Dirichlet boundary condition u = 0 from ngsolve import Mesh, H1, LinearForm, x, y, dx, BilinearForm, grad, GridFunction, Draw, ngsglobals, sqrt, Integrate from netgen.geom2d import unit_square ngsglobals.msg_level = 1 # generate a triangular mesh of mesh-size 0.2 mesh = Mesh(unit_square.GenerateMesh(maxh=0.2)) # H1-conforming finite element space fes = H1(mesh, order=3, dirichlet=[1,2,3,4]) # define trial- and test-functions u = fes.TrialFunction() v = fes.TestFunction() # the right hand side f = LinearForm(fes) f += 32 * (y*(1-y)+x*(1-x)) * v * dx # the bilinear-form a = BilinearForm(fes, symmetric=True) a += grad(u)*grad(v)*dx a.Assemble() f.Assemble() # the solution field gfu = GridFunction(fes)
def discretize_ngsolve(): from ngsolve import (ngsglobals, Mesh, H1, CoefficientFunction, LinearForm, SymbolicLFI, BilinearForm, SymbolicBFI, grad, TaskManager) from netgen.csg import CSGeometry, OrthoBrick, Pnt import numpy as np ngsglobals.msg_level = 1 geo = CSGeometry() obox = OrthoBrick(Pnt(-1, -1, -1), Pnt(1, 1, 1)).bc("outer") b = [] b.append( OrthoBrick(Pnt(-1, -1, -1), Pnt(0.0, 0.0, 0.0)).mat("mat1").bc("inner")) b.append( OrthoBrick(Pnt(-1, 0, -1), Pnt(0.0, 1.0, 0.0)).mat("mat2").bc("inner")) b.append( OrthoBrick(Pnt(0, -1, -1), Pnt(1.0, 0.0, 0.0)).mat("mat3").bc("inner")) b.append( OrthoBrick(Pnt(0, 0, -1), Pnt(1.0, 1.0, 0.0)).mat("mat4").bc("inner")) b.append( OrthoBrick(Pnt(-1, -1, 0), Pnt(0.0, 0.0, 1.0)).mat("mat5").bc("inner")) b.append( OrthoBrick(Pnt(-1, 0, 0), Pnt(0.0, 1.0, 1.0)).mat("mat6").bc("inner")) b.append( OrthoBrick(Pnt(0, -1, 0), Pnt(1.0, 0.0, 1.0)).mat("mat7").bc("inner")) b.append( OrthoBrick(Pnt(0, 0, 0), Pnt(1.0, 1.0, 1.0)).mat("mat8").bc("inner")) box = (obox - b[0] - b[1] - b[2] - b[3] - b[4] - b[5] - b[6] - b[7]) geo.Add(box) for bi in b: geo.Add(bi) # domain 0 is empty! mesh = Mesh(geo.GenerateMesh(maxh=0.3)) # H1-conforming finite element space V = H1(mesh, order=NGS_ORDER, dirichlet="outer") v = V.TestFunction() u = V.TrialFunction() # Coeff as array: variable coefficient function (one CoefFct. per domain): sourcefct = CoefficientFunction([1 for i in range(9)]) with TaskManager(): # the right hand side f = LinearForm(V) f += SymbolicLFI(sourcefct * v) f.Assemble() # the bilinear-form mats = [] coeffs = [[0, 1, 0, 0, 0, 0, 0, 0, 1], [0, 0, 1, 0, 0, 0, 0, 1, 0], [0, 0, 0, 1, 0, 0, 1, 0, 0], [0, 0, 0, 0, 1, 1, 0, 0, 0]] for c in coeffs: diffusion = CoefficientFunction(c) a = BilinearForm(V, symmetric=False) a += SymbolicBFI(diffusion * grad(u) * grad(v), definedon=(np.where(np.array(c) == 1)[0] + 1).tolist()) a.Assemble() mats.append(a.mat) from pymor.bindings.ngsolve import NGSolveVectorSpace, NGSolveMatrixOperator, NGSolveVisualizer space = NGSolveVectorSpace(V) op = LincombOperator( [NGSolveMatrixOperator(m, space, space) for m in mats], [ ProjectionParameterFunctional('diffusion', (len(coeffs), ), (i, )) for i in range(len(coeffs)) ]) h1_0_op = op.assemble([1] * len(coeffs)).with_(name='h1_0_semi') F = space.zeros() F._list[0].real_part.impl.vec.data = f.vec F = VectorOperator(F) return StationaryModel(op, F, visualizer=NGSolveVisualizer(mesh, V), products={'h1_0_semi': h1_0_op}, parameter_space=CubicParameterSpace( op.parameter_type, 0.1, 1.))
def Heat1DFEM(N=8, order=1, k1=1, k2=1, Q1=0, Q2=10, boundary_condition_left="Robin", boundary_condition_right="Dirichlet", value_left=0, value_right=1, q_value_left=0, q_value_right=1, r_value_left=0, r_value_right=1, intervalsize=0.14): if (boundary_condition_left == "Neumann" or (boundary_condition_left == "Robin" and r_value_left == 0)) and ( boundary_condition_right == "Neumann" or (boundary_condition_right == "Robin" and r_value_right == 0)): print("Temperatur ist nicht eindeutig bestimmt.") #return mesh1D = Mesh1D(N, interval=(0, intervalsize)) dbnds = [] if boundary_condition_left == "Dirichlet": dbnds.append(1) # print(True) if boundary_condition_right == "Dirichlet": dbnds.append(2) fes = H1(mesh1D, order=order, dirichlet=dbnds) gf = GridFunction(fes) if boundary_condition_left == "Dirichlet": gf.vec[0] = value_left if boundary_condition_right == "Dirichlet": gf.vec[N] = value_right Q = IfPos(X - 0.5 * intervalsize, Q2, Q1) k = IfPos(X - 0.5 * intervalsize, k2, k1) u, v = fes.TnT() a = BilinearForm(fes) a += SymbolicBFI(k * grad(u) * grad(v)) if boundary_condition_left == "Robin": a += SymbolicBFI(r_value_left * u * v, definedon=mesh1D.Boundaries("left")) if boundary_condition_right == "Robin": a += SymbolicBFI(r_value_right * u * v, definedon=mesh1D.Boundaries("right")) a.Assemble() f = LinearForm(fes) f += SymbolicLFI(Q * v) f.Assemble() if boundary_condition_left == "Neumann": f.vec[0] += q_value_left elif boundary_condition_left == "Robin": f.vec[0] += r_value_left * value_left if boundary_condition_right == "Neumann": f.vec[N] += q_value_right elif boundary_condition_right == "Robin": f.vec[N] += r_value_right * value_right f.vec.data -= a.mat * gf.vec gf.vec.data += a.mat.Inverse(fes.FreeDofs()) * f.vec Draw1D(mesh1D, [(gf, "u_h")], n_p=5 * order**2)