def test_h1_real(): """Test h1 amg for real example.""" with ngs.TaskManager(): mesh = ngs.Mesh(unit_square.GenerateMesh(maxh=0.2)) fes = ngs.H1(mesh, dirichlet=[1, 2, 3], order=1) u = fes.TrialFunction() v = fes.TestFunction() # rhs f = ngs.LinearForm(fes) f += ngs.SymbolicLFI(v) f.Assemble() # lhs a = ngs.BilinearForm(fes, symmetric=True) a += ngs.SymbolicBFI(grad(u) * grad(v)) c = ngs.Preconditioner(a, 'h1amg2') a.Assemble() solver = ngs.CGSolver(mat=a.mat, pre=c.mat) gfu = ngs.GridFunction(fes) gfu.vec.data = solver * f.vec assert_greater(solver.GetSteps(), 0) assert_less_equal(solver.GetSteps(), 4)
def _adjoint(self, argument): # Bilinearform already defined from _eval # Definition of Linearform # But it only needs to be defined on boundary self._set_boundary_values(argument) # self.gfu_dir.Set(self.gfu_in) # Note: Here the linearform f for the dirichlet problem is just zero # Update for boundary values # self.r.data=-self.a.mat * self.gfu_dir.vec # Solve system # self.gfu_toret.vec.data=self.gfu_dir.vec.data+self._solve(self.a, self.r) # self.gfu_adjtoret.Set(-grad(self.gfu_toret)*grad(self.gfu)) # return self.gfu_adjtoret.vec.FV().NumPy().copy() self.gfu_b.Set(self.gfu_in) self.b.Assemble() self.gfu_toret.vec.data = self._solve(self.a, self.b.vec) self.gfu_adjtoret.Set(-ngs.grad(self.gfu_toret) * ngs.grad(self.gfu)) return self.gfu_adjtoret.vec.FV().NumPy().copy()
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 waveA(u, cwave): # Return action of the first order wave operator on u if len(u) == 2: q, mu = u dxq, dtq = ngs.grad(q) dxmu, dtmu = ngs.grad(mu) return CoefficientFunction((dtq - cwave * dxmu, dtmu - cwave * dxq)) elif len(u) == 3: q1, q2, mu = u dxq1, dyq1, dtq1 = ngs.grad(q1) dxq2, dyq2, dtq2 = ngs.grad(q2) dxmu, dymu, dtmu = ngs.grad(mu) return CoefficientFunction((dtq1 - cwave * dxmu, dtq2 - cwave * dymu, dtmu - cwave * dxq1 - cwave * dyq2)) else: raise ValueError('Wave operator cannot act on vectors of length %d' % len(u))
def setup_poisson(mesh, alpha=1, beta=0, f=1, diri=".*", order=1, fes_opts=dict(), blf_opts=dict(), lf_opts=dict()): V = ngs.H1(mesh, order=order, dirichlet=diri, **fes_opts) u, v = V.TnT() a = ngs.BilinearForm(V, **blf_opts) a += ngs.SymbolicBFI(alpha * ngs.grad(u) * ngs.grad(v)) if beta != 0: a += ngs.SymbolicBFI(beta * u * v) lf = ngs.LinearForm(V) lf += ngs.SymbolicLFI(f * v) return V, a, lf
def waveA(u,cwave): # Return action of the first order wave operator on u if len(u) == 2: q, mu = u dxq, dtq = ngs.grad(q) dxmu, dtmu = ngs.grad(mu) return CoefficientFunction((dtq - cwave*dxmu, dtmu - cwave*dxq)) elif len(u) == 3: q1, q2, mu = u dxq1, dyq1, dtq1 = ngs.grad(q1) dxq2, dyq2, dtq2 = ngs.grad(q2) dxmu, dymu, dtmu = ngs.grad(mu) return CoefficientFunction((dtq1 - cwave*dxmu, dtq2 - cwave*dymu, dtmu - cwave*dxq1 - cwave*dyq2)) else: raise ValueError('Wave operator cannot act on vectors of length %d' % len(u))
def spaces_and_forms(mesh, order=1): # Create a distributed finite element space. dirichlet = 'top|right|bottom|left' X = ng.H1(mesh, order=order, dirichlet=dirichlet, complex=True) # Create the test and trial functions. u, v = X.TnT() # Create the bilinear form for the left-hand-side. a = ng.BilinearForm(X) a += ng.SymbolicBFI(ng.grad(u) * ng.grad(v)) a.Assemble() # Create the second needed bilinear form as is needed for FEAST. b = ng.BilinearForm(X) b += ng.SymbolicBFI(u * v) b.Assemble() return X, a, b
def _adjoint(self, argument): # Bilinearform already defined from _eval # Definition of Linearform self.gfu_rhs.vec.FV().NumPy()[:] = argument # self.gfu_rhs.Set(rhs) self.f.Assemble() # Solve system self.gfu_inner.vec.data = self._solve(self.a, self.f.vec) if self.diffusion: res = -ngs.grad(self.gfu) * ngs.grad(self.gfu_inner) elif self.reaction: res = -self.gfu * self.gfu_inner self.gfu_toret.Set(res) return self.gfu_toret.vec.FV().NumPy().copy()
def systems_and_preconditioners(mesh, X, z, order=1): # Create a real analogue of our vector space for the wrapper preconditioner. dirichlet = 'top|right|bottom|left' X_real = ng.H1(mesh, order=order, dirichlet=dirichlet, complex=False) # Test and trial functions for the original space. u, v = X.TnT() # Real trial and test functions. ur, vr = X_real.TnT() # Create a real analogue of the bilinear form a. a_real = ng.BilinearForm(X_real) a_real += ng.SymbolicBFI(ng.grad(ur) * ng.grad(vr)) a_real.Assemble() # Initialize petsc prior to conswtructing preconditioners. petsc.Initialize() # Create a bilinear form and a preconditioner for each z. zbas = [] precs = [] for k in range(len(z)): # Create a bilinear form for the given z-value. zba = ng.BilinearForm(X) zba += ng.SymbolicBFI(z[k] * u * v - ng.grad(u) * ng.grad(v)) # Create a preconditioner for the given z-value. mat_convert = petsc.PETScMatrix(a_real.mat, freedofs=X_real.FreeDofs()) real_pc = petsc.PETSc2NGsPrecond(mat=mat_convert, name="real_pc", petsc_options={"pc_type": "gamg"}) prec = WrapperPrec(real_pc) # Assemble the given bilinear form. zba.Assemble() # Tack the bilinear forms and preconditioners onto their respective lists. zbas += [zba] precs += [prec] return zbas, precs
def setup_norot_elast(mesh, mu=1, lam=0, f_vol=None, multidim=True, reorder=False, diri=".*", order=1, fes_opts=dict(), blf_opts=dict(), lf_opts=dict()): dim = mesh.dim if multidim: V = ngs.H1(mesh, order=order, dirichlet=diri, **fes_opts, dim=mesh.dim) else: V = ngs.VectorH1(mesh, order=order, dirichlet=diri, **fes_opts) if reorder: raise Exception( "reordered does not work anymore (now ordered by elements)!!") V = ngs.comp.Reorder(V) u, v = V.TnT() sym = lambda X: 0.5 * (X + X.trans) grd = lambda X: ngs.CoefficientFunction(tuple( ngs.grad(X)[i, j] for i in range(dim) for j in range(dim)), dims=(dim, dim)) eps = lambda X: sym(grd(X)) a = ngs.BilinearForm(V, symmetric=False, **blf_opts) a += mu * ngs.InnerProduct(eps(u), eps(v)) * ngs.dx if lam != 0: div = lambda U: sum([ngs.grad(U)[i, i] for i in range(1, dim)], start=ngs.grad(U)[0, 0]) a += lam * div(u) * div(v) * ngs.dx lf = ngs.LinearForm(V) lf += f_vol * v * ngs.dx return V, a, lf
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)))
def _estimateError(self): # compute the flux flux = ngs.grad(self._gfu) # interpolate the gradient in the Hcurls space self._gf_flux.Set(flux) # compute estimator: err = (flux-self._gf_flux)*(flux-self._gf_flux) eta2 = ngs.Integrate(err, self._mesh, ngs.VOL, element_wise=True) # set max error for calculating the worst 25% maxerr = max(eta2) # mark for refinement: for el in self._mesh.Elements(): # mark worst 25% elements to refinement self._mesh.SetRefinementFlag(el, eta2[el.nr] > 0.25*maxerr)
def __init__(self, domain, rhs, bc_left=None, bc_right=None, bc_top=None, bc_bottom=None, codomain=None, diffusion=True, reaction=False, dim=1): assert dim in (1, 2) assert diffusion or reaction codomain = codomain or domain self.rhs = rhs self.diffusion = diffusion self.reaction = reaction self.dim = domain.fes.mesh.dim bc_left = bc_left or 0 bc_right = bc_right or 0 bc_top = bc_top or 0 bc_bottom = bc_bottom or 0 # Define mesh and finite element space self.fes_domain = domain.fes # self.mesh=self.fes.mesh self.fes_codomain = codomain.fes # if dim==1: # self.mesh = Make1DMesh(meshsize) # self.fes = H1(self.mesh, order=2, dirichlet="left|right") # elif dim==2: # self.mesh = MakeQuadMesh(meshsize) # self.fes = H1(self.mesh, order=2, dirichlet="left|top|right|bottom") # grid functions for later use self.gfu = ngs.GridFunction( self.fes_codomain) # solution, return value of _eval self.gfu_bdr = ngs.GridFunction( self.fes_codomain) # grid function holding boundary values self.gfu_integrator = ngs.GridFunction( self.fes_domain ) # grid function for defining integrator (bilinearform) self.gfu_integrator_codomain = ngs.GridFunction(self.fes_codomain) self.gfu_rhs = ngs.GridFunction( self.fes_codomain ) # grid function for defining right hand side (Linearform) self.gfu_inner_domain = ngs.GridFunction( self.fes_domain ) # grid function for reading in values in derivative self.gfu_inner = ngs.GridFunction( self.fes_codomain ) # grid function for inner computation in derivative and adjoint self.gfu_deriv = ngs.GridFunction( self.fes_codomain) # return value of derivative self.gfu_toret = ngs.GridFunction( self.fes_domain ) # grid function for returning values in adjoint and derivative u = self.fes_codomain.TrialFunction() # symbolic object v = self.fes_codomain.TestFunction() # symbolic object # Define Bilinearform, will be assembled later self.a = ngs.BilinearForm(self.fes_codomain, symmetric=True) if self.diffusion: self.a += ngs.SymbolicBFI( ngs.grad(u) * ngs.grad(v) * self.gfu_integrator_codomain) elif self.reaction: self.a += ngs.SymbolicBFI( ngs.grad(u) * ngs.grad(v) + u * v * self.gfu_integrator_codomain) # Define Linearform, will be assembled later self.f = ngs.LinearForm(self.fes_codomain) self.f += ngs.SymbolicLFI(self.gfu_rhs * v) if diffusion: self.f_deriv = ngs.LinearForm(self.fes_codomain) self.f_deriv += ngs.SymbolicLFI(-self.gfu_rhs * ngs.grad(self.gfu) * ngs.grad(v)) # Precompute Boundary values and boundary valued corrected rhs if self.dim == 1: self.gfu_bdr.Set( [bc_left, bc_right], definedon=self.fes_codomain.mesh.Boundaries("left|right")) elif self.dim == 2: self.gfu_bdr.Set([bc_left, bc_top, bc_right, bc_bottom], definedon=self.fes_codomain.mesh.Boundaries( "left|top|right|bottom")) self.r = self.f.vec.CreateVector() super().__init__(domain, codomain)
def material_overpotential_cathode(concentr, pot): """Return material overpotential for cathode Li_yMn2O4 particles""" return pot - open_circuit_manganese(concentr) + ohmic_contact_pot # V def material_overpotential_anode(concentr, pot): """Return material overpotential for Li_xC6 anode""" return pot - open_circuit_carbon(concentr) + ohmic_contact_pot # V mass = ngs.BilinearForm(V) mass += ngs.SymbolicBFI(u * v) a = ngs.BilinearForm(V) a += ngs.SymbolicBFI(-cf_diffusivity * grad(u) * grad(v)) a += ngs.SymbolicBFI(cf_diffusivity * discharge_rate / F * v, ngs.BND, definedon=mesh.Boundaries('anode')) a += ngs.SymbolicBFI(-cf_diffusivity * cf_valence * F / R / temperature * u * grad(p) * grad(v)) # a += ngs.SymbolicBFI(-charge_flux_prefactor_cathode(u) * (alpha_a + alpha_c) # * material_overpotential_cathode(u, p) * cf_diffusivity # * cf_valence * F**2 / R**2 / temperature**2 / conductivity['particle'] * u * v, # ngs.BND, definedon=mesh.Boundaries('particle')) # a += ngs.SymbolicBFI(-charge_flux_prefactor_anode(u) * (alpha_a + alpha_c) # * material_overpotential_anode(u, p) * cf_diffusivity # * cf_valence * F**2 / R**2 / temperature**2 / cf_conductivity * u * v, # ngs.BND, definedon=mesh.Boundaries('anode')) a += ngs.SymbolicBFI(cf_diffusivity * F / R / temperature / conductivity['electrolyte'] * discharge_rate * u * v, ngs.BND, definedon=mesh.Boundaries('cathode'))
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].impl.vec.data = f.vec F = VectorFunctional(F) return StationaryDiscretization(op, F, visualizer=NGSolveVisualizer(mesh, V), products={'h1_0_semi': h1_0_op}, parameter_space=CubicParameterSpace(op.parameter_type, 0.1, 1.))
def gram(self): u, v = self.discr.fes.TnT() form = ngs.BilinearForm(self.discr.fes, symmetric=True) form += ngs.SymbolicBFI(u * v + ngs.grad(u) * ngs.grad(v)) return Matrix(self.discr, form)
def __init__(self, domain, g, codomain=None): codomain = codomain or domain self.g = g # self.pts=pts # Define mesh and finite element space # geo=SplineGeometry() # geo.AddCircle((0,0), 1, bc="circle") # ngmesh = geo.GenerateMesh() # ngmesh.Save('ngmesh') # self.mesh=MakeQuadMesh(10) # self.mesh=Mesh(ngmesh) self.fes_domain = domain.fes self.fes_codomain = codomain.fes # Variables for setting of boundary values later # self.ind=[v.point in pts for v in self.mesh.vertices] self.pts = [v.point for v in self.fes_codomain.mesh.vertices] self.ind = [np.linalg.norm(np.array(p)) > 0.95 for p in self.pts] self.pts_bdr = np.array(self.pts)[self.ind] self.fes_in = ngs.H1(self.fes_codomain.mesh, order=1) self.gfu_in = ngs.GridFunction(self.fes_in) # grid functions for later use self.gfu = ngs.GridFunction( self.fes_codomain) # solution, return value of _eval self.gfu_bdr = ngs.GridFunction( self.fes_codomain ) # grid function holding boundary values, g/sigma=du/dn self.gfu_integrator = ngs.GridFunction( self.fes_domain ) # grid function for defining integrator (bilinearform) self.gfu_integrator_codomain = ngs.GridFunction(self.fes_codomain) self.gfu_rhs = ngs.GridFunction( self.fes_codomain ) # grid function for defining right hand side (linearform), f self.gfu_inner_domain = ngs.GridFunction( self.fes_domain ) # grid function for reading in values in derivative self.gfu_inner = ngs.GridFunction( self.fes_codomain ) # grid function for inner computation in derivative and adjoint self.gfu_deriv = ngs.GridFunction( self.fes_codomain) # gridd function return value of derivative self.gfu_toret = ngs.GridFunction( self.fes_domain ) # grid function for returning values in adjoint and derivative self.gfu_dir = ngs.GridFunction( self.fes_domain ) # grid function for solving the dirichlet problem in adjoint self.gfu_error = ngs.GridFunction( self.fes_codomain ) # grid function used in _target to compute the error in forward computation self.gfu_tar = ngs.GridFunction( self.fes_codomain ) # grid function used in _target, holding the arguments self.gfu_adjtoret = ngs.GridFunction(self.fes_domain) self.Number = ngs.NumberSpace(self.fes_codomain.mesh) r, s = self.Number.TnT() u = self.fes_codomain.TrialFunction() # symbolic object v = self.fes_codomain.TestFunction() # symbolic object # Define Bilinearform, will be assembled later self.a = ngs.BilinearForm(self.fes_codomain, symmetric=True) self.a += ngs.SymbolicBFI( ngs.grad(u) * ngs.grad(v) * self.gfu_integrator_codomain) ########new self.a += ngs.SymbolicBFI( u * s + v * r, definedon=self.fes_codomain.mesh.Boundaries("cyc")) self.fes1 = ngs.H1(self.fes_codomain.mesh, order=2, definedon=self.fes_codomain.mesh.Boundaries("cyc")) self.gfu_getbdr = ngs.GridFunction(self.fes1) self.gfu_setbdr = ngs.GridFunction(self.fes_codomain) # Define Linearform, will be assembled later self.f = ngs.LinearForm(self.fes_codomain) self.f += ngs.SymbolicLFI(self.gfu_rhs * v) self.r = self.f.vec.CreateVector() self.b = ngs.LinearForm(self.fes_codomain) self.gfu_b = ngs.GridFunction(self.fes_codomain) self.b += ngs.SymbolicLFI( self.gfu_b * v.Trace(), definedon=self.fes_codomain.mesh.Boundaries("cyc")) self.f_deriv = ngs.LinearForm(self.fes_codomain) self.f_deriv += ngs.SymbolicLFI(self.gfu_rhs * ngs.grad(self.gfu) * ngs.grad(v)) # self.b2=LinearForm(self.fes) # self.b2+=SymbolicLFI(div(v*grad(self.gfu)) super().__init__(domain, codomain)
def __init__(self, domain, g, codomain=None): codomain = codomain or domain self.g = g self.fes_domain = domain.fes self.fes_codomain = codomain.fes self.fes_in = ngs.H1(self.fes_codomain.mesh, order=1) self.gfu_in = ngs.GridFunction(self.fes_in) # grid functions for later use self.gfu = ngs.GridFunction( self.fes_codomain) # solution, return value of _eval # self.gfu_bdr=ngs.GridFunction(self.fes_codomain) #grid function holding boundary values, g/sigma=du/dn self.gfu_bilinearform = ngs.GridFunction( self.fes_domain ) # grid function for defining integrator (bilinearform) self.gfu_bilinearform_codomain = ngs.GridFunction( self.fes_codomain ) # grid function for defining integrator of bilinearform self.gfu_linearform_domain = ngs.GridFunction( self.fes_codomain) # grid function for defining linearform self.gfu_linearform_codomain = ngs.GridFunction(self.fes_domain) self.gfu_deriv_toret = ngs.GridFunction( self.fes_codomain) # grid function: return value of derivative self.gfu_adj = ngs.GridFunction( self.fes_domain) # grid function for inner computation in adjoint self.gfu_adj_toret = ngs.GridFunction( self.fes_domain) # grid function: return value of adjoint self.gfu_b = ngs.GridFunction( self.fes_codomain) # grid function for defining the boundary term u = self.fes_codomain.TrialFunction() # symbolic object v = self.fes_codomain.TestFunction() # symbolic object # Define Bilinearform, will be assembled later self.a = ngs.BilinearForm(self.fes_codomain, symmetric=True) self.a += ngs.SymbolicBFI(-ngs.grad(u) * ngs.grad(v) + u * v * self.gfu_bilinearform_codomain) # Interaction with Trace self.fes_bdr = ngs.H1( self.fes_codomain.mesh, order=self.fes_codomain.globalorder, definedon=self.fes_codomain.mesh.Boundaries("cyc")) self.gfu_getbdr = ngs.GridFunction(self.fes_bdr) self.gfu_setbdr = ngs.GridFunction(self.fes_codomain) # Boundary term self.b = ngs.LinearForm(self.fes_codomain) self.b += ngs.SymbolicLFI( -self.gfu_b * v.Trace(), definedon=self.fes_codomain.mesh.Boundaries("cyc")) # Linearform (only appears in derivative) self.f_deriv = ngs.LinearForm(self.fes_codomain) self.f_deriv += ngs.SymbolicLFI(-self.gfu_linearform_codomain * self.gfu * v) super().__init__(domain, codomain)
with ngs.TaskManager(): mesh = ngs.Mesh('mesh.vol') V = ngs.H1(mesh, order=1) print(V.ndof) u = V.TrialFunction() v = V.TestFunction() mass = ngs.BilinearForm(V) mass += ngs.SymbolicBFI(u * v) mass.Assemble() a = ngs.BilinearForm(V) a += ngs.SymbolicBFI(diffusivity * grad(u) * grad(v)) a.Assemble() f = ngs.LinearForm(V) f += ngs.SymbolicLFI(discharge_current_density / F * v.Trace(), ngs.BND, definedon=mesh.Boundaries('anode')) f.Assemble() # Initial conditions gfu = ngs.GridFunction(V) gfu.Set(ngs.CoefficientFunction(initial_concentration)) # Visualization ngs.Draw(gfu) print('0s') input()
with ngs.TaskManager(): mesh = ngs.Mesh(unit_square.GenerateMesh(maxh=0.15)) fes = ngs.H1(mesh, dirichlet=[1, 2, 3], order=1, complex=True) u = fes.TrialFunction() v = fes.TestFunction() # rhs f = ngs.LinearForm(fes) f += ngs.SymbolicLFI(v) # lhs a = ngs.BilinearForm(fes, symmetric=True) a += ngs.SymbolicBFI(grad(u) * grad(v) + 1j * u * v) c = ngs.Preconditioner(a, 'h1amg2') # c = ngs.Preconditioner(a, 'direct') gfu = ngs.GridFunction(fes) bvp = ngs.BVP(bf=a, lf=f, gf=gfu, pre=c) while True: fes.Update() gfu.Update() a.Assemble() f.Assemble() bvp.Do()
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)
# $$ # \begin{bmatrix} # \mathsf{A}-k^2 \mathsf{M} & -\mathsf{M}_\Gamma\\ # \tfrac{1}{2}\mathsf{Id}-\mathsf{K} & \mathsf{V} # \end{bmatrix}. # $$ # In[8]: from scipy.sparse.linalg.interface import LinearOperator blocks = [[None, None], [None, None]] trace_op = LinearOperator(trace_matrix.shape, lambda x: trace_matrix * x) blfA = ngs.BilinearForm(ng_space) blfA += ngs.SymbolicBFI(ngs.grad(u) * ngs.grad(v) - k**2 * n**2 * u * v) c = ngs.Preconditioner(blfA, type="direct") blfA.Assemble() blocks[0][0] = NgOperator(blfA) blocks[0][1] = -trace_matrix.T * mass.weak_form().sparse_operator blocks[1][0] = (.5 * id_op - dlp).weak_form() * trace_op blocks[1][1] = slp.weak_form() blocked = bempp.api.BlockedDiscreteOperator(np.array(blocks)) # Next, we solve the system, then split the solution into the parts assosiated with u and λ. For an efficient solve, preconditioning is required. # In[9]:
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) 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)
def solve(self): # disable garbage collector # --------------------------------------------------------------------# gc.disable() while (gc.isenabled()): time.sleep(0.1) # --------------------------------------------------------------------# # measure how much memory is used until here process = psutil.Process() memstart = process.memory_info().vms # starts timer tstart = time.time() if self.show_gui: import netgen.gui # create mesh with initial size 0.1 self._mesh = ngs.Mesh(unit_square.GenerateMesh(maxh=0.1)) #create finite element space self._fes = ngs.H1(self._mesh, order=2, dirichlet=".*", autoupdate=True) # test and trail function u = self._fes.TrialFunction() v = self._fes.TestFunction() # create bilinear form and enable static condensation self._a = ngs.BilinearForm(self._fes, condense=True) self._a += ngs.grad(u) * ngs.grad(v) * ngs.dx # creat linear functional and apply RHS self._f = ngs.LinearForm(self._fes) self._f += (-4) * v * ngs.dx # preconditioner: multigrid - what prerequisits must the problem have? self._c = ngs.Preconditioner(self._a, "multigrid") # create grid function that holds the solution and set the boundary to 0 self._gfu = ngs.GridFunction(self._fes, autoupdate=True) # solution self._g = self._ngs_ex self._gfu.Set(self._g, definedon=self._mesh.Boundaries(".*")) # draw grid function in gui if self.show_gui: ngs.Draw(self._gfu) # create Hcurl space for flux calculation and estimate error self._space_flux = ngs.HDiv(self._mesh, order=2, autoupdate=True) self._gf_flux = ngs.GridFunction(self._space_flux, "flux", autoupdate=True) # TaskManager starts threads that (standard thread nr is numer of cores) with ngs.TaskManager(): # this is the adaptive loop while self._fes.ndof < self.max_ndof: self._solveStep() self._estimateError() self._mesh.Refine() # since the adaptive loop stopped with a mesh refinement, the gfu must be # calculated one last time self._solveStep() if self.show_gui: ngs.Draw(self._gfu) # set measured exectution time self._exec_time = time.time() - tstart # set measured used memory memstop = process.memory_info().vms - memstart self._mem_consumption = memstop # enable garbage collector # --------------------------------------------------------------------# gc.enable() gc.collect()
import ngsolve as ngs from ngsolve import grad from netgen.geom2d import unit_square from random import random mesh = ngs.Mesh(unit_square.GenerateMesh(maxh=0.05)) fes = ngs.H1(mesh, order=2, dirichlet=[1,2,3,4], complex=True) u = fes.TrialFunction() v = fes.TestFunction() a = ngs.BilinearForm(fes) a += ngs.SymbolicBFI(hbar / 2 / m_e * grad(u) * grad(v)) a.Assemble() m = ngs.BilinearForm(fes) m += ngs.SymbolicBFI(u * v) m.Assemble() gf_psi = ngs.GridFunction(fes) freedofs = fes.FreeDofs() for i in range(len(gf_psi.vec)): gf_psi.vec[i] = random() if freedofs[i] else 0 inv = a.mat.Inverse(freedofs) w = gf_psi.vec.CreateVector()
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.))
# Time-stepping t = 0 # write initial temperature datafile.write("%f\t%f\n" % (t, T_n(mesh(0., 0.25)))) psi = ng.GridFunction(V, "pot") # solution for potential psi.Set(bc_cf_pot, ng.BND) T_n1 = ng.GridFunction(VT, "T") # solution for T T_n1.Set(bc_cf_T, ng.BND) ng.Draw(psi) ng.Draw(T_n1) # weak forms # potential a = ng.BilinearForm(V) a += sigma_T(T_n) * ng.grad(psi_T) * ng.grad(v) * ng.dx L = ng.LinearForm(V) L += f * v * ng.dx # keep in mind: f=0 # temperature a_1 = ng.BilinearForm(VT) a_1 += (rho * C_p * T_n1_T * vT * ng.dx + k_iso * dt * ng.grad(T_n1_T) * ng.grad(vT) * ng.dx) L_1 = ng.LinearForm(VT) L_1 += (rho * C_p * T_n + dt * sigma_T(T_n) * (ng.grad(psi) * ng.grad(psi))) * v * ng.dx for n in range(num_steps): # assemble EM problem a.Assemble()
with ngs.TaskManager(): mesh = ngs.Mesh(unit_square.GenerateMesh(maxh=0.2)) fes = ngs.H1(mesh, dirichlet=[1, 2, 3], order=1) u = fes.TrialFunction() v = fes.TestFunction() # rhs f = ngs.LinearForm(fes) f += ngs.SymbolicLFI(v) # lhs a = ngs.BilinearForm(fes, symmetric=True) a += ngs.SymbolicBFI(grad(u) * grad(v)) c = ngs.Preconditioner(a, 'h1amg', test=True) gfu = ngs.GridFunction(fes) bvp = ngs.BVP(bf=a, lf=f, gf=gfu, pre=c) while True: fes.Update() gfu.Update() a.Assemble() f.Assemble() bvp.Do() ngs.Draw(gfu, mesh, 'solution')
barrier_w = 2 barrier_h = 1 potential = ngs.CoefficientFunction( ngs.IfPos(x, barrier_h, 0) - ngs.IfPos(x - barrier_w, barrier_h, 0)) ### Square potential # potential = ngs.CoefficientFunction(1/2*x*x-10) ### Zero potential # potential = ngs.CoefficientFunction(0) gf_potential = ngs.GridFunction(fes) gf_potential.Set(potential) a = ngs.BilinearForm(fes) a += ngs.SymbolicBFI(1 / 2 * grad(u) * grad(v) + potential * u * v) a.Assemble() m = ngs.BilinearForm(fes) m += ngs.SymbolicBFI(1j * u * v) m.Assemble() ## Initial condition ### Gaussian wave packet delta_x = 2 x0 = -20 kx = 2 wave_packet = ngs.CoefficientFunction( exp(1j * (kx * x)) * exp(-((x - x0)**2) / 4 / delta_x**2)) ### Heaviside function