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 SBDF(model: Model, gfu_0: List[ngs.GridFunction], U: List[ProxyFunction], V: List[ProxyFunction], dt: List[ngs.Parameter]) -> Tuple[ngs.BilinearForm, ngs.LinearForm]: """ Third order semi-implicit backwards differencing time integration scheme. This function constructs the final bilinear and linear forms for the time integration scheme by adding the necessary time-dependent terms to the model's stationary terms. The returned bilinear and linear forms have NOT been assembled. Args: model: The model to solve. gfu_0: List of the solutions of previous time steps ordered from most recent to oldest. U: List of trial functions for the model. V: List of test (weighting) functions. dt: List of timestep sizes ordered from most recent to oldest. Returns: a: The final bilinear form (as a ngs.BilinearForm but not assembled). L: The final linear form (as a ngs.LinearForm but not assembled). """ # Separate out the various components of each gridfunction solution to a previous timestep. # gfu_lst = [[component 0, component 1...] at t^n, [component 0, component 1...] at t^n-1, ...] gfu_lst = [] for i in range(len(gfu_0)): if (len(gfu_0[i].components) > 0): gfu_lst.append([ gfu_0[i].components[j] for j in range(len(gfu_0[i].components)) ]) else: gfu_lst.append([gfu_0[i]]) # Construct the bilinear form a = ngs.BilinearForm(model.fes) a += model.construct_bilinear(U, V, dt[0]) # Construct the linear form L = ngs.LinearForm(model.fes) L += 3.0 * model.construct_linear(V, gfu_lst[0], dt[0]) L += -3.0 * model.construct_linear(V, gfu_lst[1], dt[0]) L += model.construct_linear(V, gfu_lst[2], dt[0]) a_dt, L_dt = model.time_derivative_terms(gfu_lst, 'SBDF') # When adding the time discretization term, multiply by the phase field if using the diffuse interface method. if model.DIM: a_dt *= model.DIM_solver.phi_gfu L_dt *= model.DIM_solver.phi_gfu a += a_dt * dx L += L_dt * dx return a, L
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 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
import ngsolve as ngs from ngsolve import grad from netgen.geom2d import unit_square CDLL('libh1amg.so') 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()
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()
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)
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, 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 setup_rot_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 mysum = lambda x: sum(x[1:], x[0]) if dim == 2: to_skew = lambda x: ngs.CoefficientFunction( (0, -x[0], x[0], 0), dims=(2, 2)) else: # to_skew = lambda x : ngs.CoefficientFunction( ( 0 , x[2], -x[1], \ # -x[2], 0 , x[0], \ # x[1], -x[0], 0), dims = (3,3) ) to_skew = lambda x : ngs.CoefficientFunction( ( 0 , -x[2], x[1], \ x[2], 0 , -x[0], \ -x[1], x[0], 0), dims = (3,3) ) if multidim: mdim = dim + ((dim - 1) * dim) // 2 V = ngs.H1(mesh, order=order, dirichlet=diri, **fes_opts, dim=mdim) if reorder: V = ngs.comp.Reorder(V) trial, test = V.TnT() u = ngs.CoefficientFunction(tuple(trial[x] for x in range(dim))) gradu = ngs.CoefficientFunction(tuple( ngs.Grad(trial)[i, j] for i in range(dim) for j in range(dim)), dims=(dim, dim)) divu = mysum([ngs.Grad(trial)[i, i] for i in range(dim)]) w = to_skew([trial[x] for x in range(dim, mdim)]) ut = ngs.CoefficientFunction(tuple(test[x] for x in range(dim))) gradut = ngs.CoefficientFunction(tuple( ngs.Grad(test)[i, j] for i in range(dim) for j in range(dim)), dims=(dim, dim)) divut = mysum([ngs.Grad(test)[i, i] for i in range(dim)]) wt = to_skew([test[x] for x in range(dim, mdim)]) else: Vu = ngs.VectorH1(mesh, order=order, dirichlet=diri, **fes_opts) if reorder == "sep": Vu = ngs.comp.Reorder(Vu) if dim == 3: Vw = Vu else: Vw = ngs.H1(mesh, order=order, dirichlet=diri, **fes_opts) if reorder == "sep": Vw = ngs.comp.Reorder(Vw) V = ngs.FESpace([Vu, Vw]) # print("free pre RO: ", V.FreeDofs()) if reorder is True: V = ngs.comp.Reorder(V) # print("free post RO: ", V.FreeDofs()) (u, w), (ut, wt) = V.TnT() gradu = ngs.Grad(u) divu = mysum([ngs.Grad(u)[i, i] for i in range(dim)]) w = to_skew(w) gradut = ngs.Grad(ut) divut = mysum([ngs.Grad(ut)[i, i] for i in range(dim)]) wt = to_skew(wt) a = ngs.BilinearForm(V, **blf_opts) a += (mu * ngs.InnerProduct(gradu - w, gradut - wt)) * ngs.dx #a += ngs.InnerProduct(w,wt) * ngs.dx #trial, test = V.TnT() #a += 0.1 * ngs.InnerProduct(trial,test) * ngs.dx if lam != 0: a += lam * divu * divut * ngs.dx lf = ngs.LinearForm(V) lf += f_vol * ut * ngs.dx return V, a, lf
def adaptive_IMEX_pred( model: Model, gfu_0: List[ngs.GridFunction], U: List[ProxyFunction], V: List[ProxyFunction], dt: List[ngs.Parameter]) -> Tuple[ngs.BilinearForm, ngs.LinearForm]: """ Predictor for the adaptive time-stepping IMEX time integration scheme. This function constructs the final bilinear and linear forms for the time integration scheme by adding the necessary time-dependent terms to the model's stationary terms. The returned bilinear and linear forms have NOT been assembled. Args: model: The model to solve. gfu_0: List of the solutions of previous time steps ordered from most recent to oldest. U: List of trial functions for the model. V: List of test (weighting) functions. dt: List of timestep sizes ordered from most recent to oldest. Returns: a: The final bilinear form (as a ngs.BilinearForm but not assembled). L: The final linear form (as a ngs.LinearForm but not assembled). """ # Separate out the various components of each gridfunction solution to a previous timestep. # gfu_lst = [[component 0, component 1...] at t^n, [component 0, component 1...] at t^n-1, ...] gfu_lst = [] for i in range(len(gfu_0)): if (len(gfu_0[i].components) > 0): gfu_lst.append([ gfu_0[i].components[j] for j in range(len(gfu_0[i].components)) ]) else: gfu_lst.append([gfu_0[i]]) # Operators specific to this time integration scheme. w = dt[0] / dt[1] E = model.construct_gfu().components[0] E_expr = (1.0 + w) * gfu_lst[0][0] - w * gfu_lst[1][0] E.Set(E_expr) # Construct the bilinear form a = ngs.BilinearForm(model.fes) a += model.construct_bilinear(U, V, dt[0]) # Construct the linear form L = ngs.LinearForm(model.fes) L += model.construct_linear( V, [gfu_lst[0][0], 0.0], dt[0]) # TODO: Why doesn't using E work? Numerical error? a_dt, L_dt = model.time_derivative_terms(gfu_lst, 'crank nicolson') # When adding the time discretization term, multiply by the phase field if using the diffuse interface method. if model.DIM: a_dt *= model.DIM_solver.phi_gfu L_dt *= model.DIM_solver.phi_gfu a += a_dt * dx L += L_dt * dx return a, L
# Initial conditions gfu = ngs.GridFunction(V) cf_n0 = ngs.CoefficientFunction([init_concentr[mat] for mat in mesh.GetMaterials()]) gfu.components[0].Set(cf_n0) ## Poisson's equation for initial potential # An extra space is needed, due to different dirichlet conditions for the initial potential initial_potential_space = ngs.H1(mesh, order=1, dirichlet='particle|anode') phi = initial_potential_space.TrialFunction() psi = initial_potential_space.TestFunction() a_pot = ngs.BilinearForm(initial_potential_space) a_pot += ngs.SymbolicBFI(grad(phi) * grad(psi)) a_pot.Assemble() f_pot = ngs.LinearForm(initial_potential_space) # permittivity seems to be missing, but gives too high value if included f_pot += ngs.SymbolicLFI(cf_valence * cf_n0 * F * psi) f_pot.Assemble() gf_phi = ngs.GridFunction(initial_potential_space) gf_phi.Set(ngs.CoefficientFunction(cathode_init_pot), definedon=mesh.Materials('particle')) ngs.Draw(gf_phi) res = f_pot.vec.CreateVector() res.data = f_pot.vec - a_pot.mat * gf_phi.vec gf_phi.vec.data += a_pot.mat.Inverse(initial_potential_space.FreeDofs()) * res gfu.components[1].vec.data = gf_phi.vec # Visualization ngs.Draw(gfu.components[1]) input()
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() L.Assemble()
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() # Time stepping timestep = 1
def _create_linear_and_bilinear_forms(self) -> None: self.a = ngs.BilinearForm(self.model.fes) self.a += self.model.construct_bilinear(self.U, self.V) self.L = ngs.LinearForm(self.model.fes) self.L += self.model.construct_linear(self.V)