def kappa(mesh,lset_approx, subdivlvl=0): """ Tuple of ratios between negative/positive and full part of an element (deprecated). """ print("kappa-function is deprecated - use CutRatioGF instead") kappa1 = GridFunction(L2(mesh,order=0)) lset_neg = { "levelset" : lset_approx, "domain_type" : NEG, "subdivlvl" : subdivlvl} kappa_f = LinearForm(kappa1.space) kappa_f += SymbolicLFI(levelset_domain = lset_neg, form = kappa1.space.TestFunction() ) kappa_f.Assemble(); kappa1.space.SolveM(CoefficientFunction(1.0),kappa_f.vec) kappa1.vec.data = kappa_f.vec kappa2 = 1.0 - kappa1 return (kappa1,kappa2)
def single_iteration(self, a: ngs.BilinearForm, L: ngs.LinearForm, precond: ngs.Preconditioner, gfu: ngs.GridFunction) -> None: if self.linearize == 'Oseen': self.construct_and_run_solver(a, L, precond, gfu) component = self.model_components['u'] err = norm("l2_norm", self.W[0], gfu.components[0], self.mesh, self.fes.components[component], average=False) gfu_norm = mean(gfu.components[0], self.mesh) numit = 1 if self.verbose > 0: print(numit, err) while (err > self.abs_nonlinear_tolerance + self.rel_nonlinear_tolerance * gfu_norm) and ( numit < self.nonlinear_max_iters): self.W[0].vec.data = gfu.components[0].vec self.apply_dirichlet_bcs_to(gfu) a.Assemble() L.Assemble() precond.Update() self.construct_and_run_solver(a, L, precond, gfu) err = norm("l2_norm", self.W[0], gfu.components[0], self.mesh, self.fes.components[component], average=False) gfu_norm = mean(gfu.components[0], self.mesh) numit += 1 if self.verbose > 0: print(numit, err) self.W[0].vec.data = gfu.components[0].vec elif self.linearize == 'IMEX': self.construct_and_run_solver(a, L, precond, gfu)
# 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) gfu.vec.data = a.mat.Inverse(fes.FreeDofs(), inverse="sparsecholesky") * f.vec # print (u.vec) # plot the solution (netgen-gui only) Draw (gfu) Draw (-grad(gfu), mesh, "Flux") exact = 16*x*(1-x)*y*(1-y) print ("L2-error:", sqrt (Integrate ( (gfu-exact)*(gfu-exact), mesh)))
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)