def test_2(self, presets_load_coefficientfunction_into_gridfunction): """ Check that coefficientfunctions can be loaded into different component of a gridfunction correctly. Check 2D and 3D. Also check scalar and vector coefficientfunctions. """ mesh_2d, fes_scalar_2d, fes_vector_2d, fes_mixed_2d, mesh_3d, fes_scalar_3d, fes_vector_3d, fes_mixed_3d = presets_load_coefficientfunction_into_gridfunction cfu_scalar = ngs.CoefficientFunction(ngs.x + ngs.y) gfu_mixed_2d = ngs.GridFunction(fes_mixed_2d) cfu_vector_2d = ngs.CoefficientFunction((ngs.x, ngs.y)) coef_dict_2d = {0: cfu_vector_2d, 1: cfu_scalar} gfu_mixed_3d = ngs.GridFunction(fes_mixed_3d) cfu_vector_3d = ngs.CoefficientFunction((ngs.x, ngs.y, ngs.z)) coef_dict_3d = {0: cfu_vector_3d, 1: cfu_scalar} # Check 2D load_coefficientfunction_into_gridfunction(gfu_mixed_2d, coef_dict_2d) err_scalar_2d = ngs.Integrate((cfu_scalar - gfu_mixed_2d.components[1]) * (cfu_scalar - gfu_mixed_2d.components[1]), mesh_2d) err_vector_2d = ngs.Integrate((cfu_vector_2d - gfu_mixed_2d.components[0]) * (cfu_vector_2d - gfu_mixed_2d.components[0]), mesh_2d) assert math.isclose(err_scalar_2d, 0.0, abs_tol=1e-16) assert math.isclose(err_vector_2d, 0.0, abs_tol=1e-16) # Check 3D load_coefficientfunction_into_gridfunction(gfu_mixed_3d, coef_dict_3d) err_scalar_3d = ngs.Integrate((cfu_scalar - gfu_mixed_3d.components[1]) * (cfu_scalar - gfu_mixed_3d.components[1]), mesh_3d) err_vector_3d = ngs.Integrate((cfu_vector_3d - gfu_mixed_3d.components[0]) * (cfu_vector_3d - gfu_mixed_3d.components[0]), mesh_3d) assert math.isclose(err_scalar_3d, 0.0, abs_tol=1e-16) assert math.isclose(err_vector_3d, 0.0, abs_tol=1e-16)
def _calculate_local_error(self) -> Tuple[List[float], List[float]]: if len(self.gfu.components) == 0: # Only one model variable to estimate local error with. local_errors = [ ngs.sqrt( ngs.Integrate((self.gfu - self.gfu_long)**2, self.model.mesh)) ] # Also get the gridfunction norm to use for the relative error tolerance. gfu_norms = [ngs.sqrt(ngs.Integrate(self.gfu**2, self.model.mesh))] else: # Include any variables specified by the model as included in local error. local_errors = [] # Also get the gridfunction norms to use for the relative error tolerance. gfu_norms = [] for var, use in self.model.model_local_error_components.items(): if use: component = self.model.model_components[var] local_errors.append( ngs.sqrt( ngs.Integrate( (self.gfu.components[component] - self.gfu_long.components[component])**2, self.model.mesh))) gfu_norms.append( ngs.sqrt( ngs.Integrate(self.gfu.components[component]**2, self.model.mesh))) return local_errors, gfu_norms
def _calculate_local_error(self) -> Tuple[List[float], List[float]]: # Use the model component corresponding to velocity. component = self.model.model_components['u'] # Operators specific to this time integration scheme. w_0 = self.dt_param[0] / self.dt_param[1] w_00 = self.dt_param[1] / self.dt_param[2] # The two error expressions. err_1 = ngs.sqrt( ngs.Integrate((self.gfu_pred.components[component] - self.gfu_corr.components[component])**2, self.model.mesh)) err_2_expr = w_00 * w_0 * (1.0 + w_0) / (1.0 + 2.0 * w_0 + w_00 * (1.0 + 4.0 * w_0 + 3.0 * w_0 * w_0)) \ * (self.gfu_corr.components[component] - (1.0 + w_0) * (1.0 + w_00 * (1.0 + w_0)) * self.gfu_0_list[0].components[component] / (1.0 + w_00) + w_0 * (1.0 + w_00 * (1.0 + w_0)) * self.gfu_0_list[1].components[component] - w_00 * w_00 * w_0 * (1.0 + w_0) * self.gfu_0_list[2].components[component] / (1.0 + w_00)) err_2 = ngs.sqrt(ngs.Integrate(err_2_expr**2, self.model.mesh)) # Keep the larger of the errors that meet the tolerance. # TODO: This only accounts for absolute tolerance, following the paper. # Possibly should also include relative tolerance. if (err_1 <= self.dt_abs_tol) and (err_2 <= self.dt_abs_tol): if err_1 > err_2: # Keep the solution from the predictor (if the timestep is accepted). self.gfu.vec.data = self.gfu_pred.vec local_error = [err_1] else: # Keep the solution from the corrector (if the timestep is accepted). self.gfu.components[0].vec.data = self.gfu_corr.components[ 0].vec self.gfu.components[1].vec.data = self.gfu_pred.components[ 1].vec local_error = [err_2] elif err_1 <= self.dt_abs_tol: self.gfu.vec.data = self.gfu_pred.vec local_error = [err_1] elif err_2 <= self.dt_abs_tol: # Keep the solution from the corrector (if the timestep is accepted). self.gfu.components[0].vec.data = self.gfu_corr.components[0].vec self.gfu.components[1].vec.data = self.gfu_pred.components[1].vec local_error = [err_2] else: # Neither error will be acceptable. Output the error closest to the tolerance. self.gfu.vec.data = self.gfu_pred.vec local_error = [min(err_1, err_2)] # Make sure the correct gridfunction is being used to get the norm for the relative error tolerance. It # should be the gridfunction corresponding to the maximum local error. gfu_norm = [ ngs.sqrt( ngs.Integrate(self.gfu.components[component]**2, self.model.mesh)) ] return local_error, gfu_norm
def test_1(self, presets_load_coefficientfunction_into_gridfunction): """ Check that a coefficientfunction can be loaded into a full gridfunction correctly. Check 2D and 3D. """ mesh_2d, fes_scalar_2d, fes_vector_2d, fes_mixed_2d, mesh_3d, fes_scalar_3d, fes_vector_3d, fes_mixed_3d = presets_load_coefficientfunction_into_gridfunction gfu_scalar_2d = ngs.GridFunction(fes_scalar_2d) gfu_scalar_3d = ngs.GridFunction(fes_scalar_3d) cfu_scalar = ngs.CoefficientFunction(ngs.x + ngs.y) coef_dict = {None: cfu_scalar} # Check 2D load_coefficientfunction_into_gridfunction(gfu_scalar_2d, coef_dict) err_2d = ngs.Integrate((cfu_scalar - gfu_scalar_2d) * (cfu_scalar - gfu_scalar_2d), mesh_2d) assert math.isclose(err_2d, 0.0, abs_tol=1e-16) # Check 3D load_coefficientfunction_into_gridfunction(gfu_scalar_3d, coef_dict) err_3d = ngs.Integrate((cfu_scalar - gfu_scalar_3d) * (cfu_scalar - gfu_scalar_3d), mesh_3d) assert math.isclose(err_3d, 0.0, abs_tol=1e-16)
def compute_error(euz, sep, exactu): uh = vec([euz.components[i] for i in range(sep[0], sep[1])]) if exactu is None: er = None else: er = ngs.sqrt(ngs.Integrate((uh - exactu) * (uh - exactu), mesh)) print("|| u - uh || = ", er) return er
def test_code_generation(): mesh = ngs.Mesh(unit_square.GenerateMesh(maxh=0.2)) for order in range(10): functions = [f(ngs.x + 1j * ngs.y, order) for f in fs_ng] for f in functions: f_err = f - f.Compile(True, wait=True) f_err = f_err * ngs.Conj(f_err) error = ngs.Integrate(f_err, mesh) assert abs(error) < 1e-13
def mark_for_refinement(): # extract estimator component from solution: eh = [euz.components[i] for i in range(sep[0])] elerr = ngs.Integrate(vec(eh)*vec(eh) + waveA(eh,cwave)*waveA(eh,cwave), mesh, ngs.VOL, element_wise=True) maxerr = max(abs(elerr.NumPy())) # mark elements for el in mesh.Elements(): mesh.SetRefinementFlag(el, bool(abs(elerr[el.nr]) > markprm * maxerr)) globalerr = sqrt(abs(sum(elerr))) print("Adaptive step %d: Estimated error=%g, Ndofs=%d" % (itcount, globalerr, X.ndof))
def mean(gfu: Union[GridFunction, CoefficientFunction], mesh: Mesh) -> float: """ Function to calculate the mean value of a gridfunction. Args: gfu: The gridfunction of interest. mesh: The mesh the gridfunction is defined on. Returns: avg: The mean value of the gridfunction. """ avg = ngs.sqrt(ngs.Integrate(gfu**2, mesh)) return avg
def test_parallel(): mesh = ngs.Mesh(unit_square.GenerateMesh(maxh=0.2)) fes = ngs.L2(mesh, order=5, complex=True) g1 = ngs.GridFunction(fes) g2 = ngs.GridFunction(fes) for order in range(10): functions = [(f(ngs.x + 1j * ngs.y, order)) for f in fs_ng] for f in functions: g1.Set(f) with ngs.TaskManager(): g2.Set(f) error = ngs.Integrate(g1 - g2, mesh) assert error == 0j
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 _divergence(sol: GridFunction, mesh: Mesh) -> float: """ Function to calculate the divergence of a variable over the domain. Use with velocity to confirm that conservation of mass is being satisfied. Args: sol: The solution GridFunction. mesh: The mesh that was solved on. Returns: div_u: The L2 norm of the divergence of the field. """ div_var = ngs.sqrt(ngs.Integrate((ngs.div(sol)**2), mesh)) return div_var
def _facet_jumps(sol: GridFunction, mesh: Mesh) -> float: """ Function to check how continuous the solution is across mesh facets. This is mainly of interest when DG is used. Continuous Galerkin FEM solutions will always be perfectly continuous across facets. Args: sol: The solution GridFunction. mesh: The mesh that was solved on. Returns: mag_jumps: The L2 norm of the facet jumps. """ mag_jumps = ngs.sqrt( ngs.Integrate((sol - sol.Other())**2 * ngs.dx(element_boundary=True), mesh)) return mag_jumps
return 1 / (1 + ng.exp(-x)) # vectorize the logistic function for component-wise application vσ = np.vectorize(σ) # NNet coefficient function u_net = W3.dot(vσ(W2.dot(vσ(Wx.dot(ng.x) + Wy.dot(ng.y) + b1)) + b2)) + b3 # unit square domain #mesh = Mesh(unit_square.GenerateMesh(maxh=0.2)) ngmesh = unit_square.GenerateMesh(maxh=0.2) ngmesh.Refine() #ngmesh.Refine() mesh = ng.Mesh(ngmesh) mesh.ngmesh.SetGeometry(unit_square) ng.Draw(mesh) uₕ = poisson_solve() ΔFEM = uₕ - uexact ΔNET = u_net - uexact FEM_error = ng.sqrt(ng.Integrate(ng.InnerProduct(ΔFEM, ΔFEM), mesh)) NET_error = ng.sqrt(ng.Integrate(ng.InnerProduct(ΔNET, ΔNET), mesh)) print('FEM error = ', FEM_error) print('NET_error = ', NET_error) ng.Draw(uₕ) ng.Draw(u_net, mesh, "u_net")
def normL2(self): try: return ngs.sqrt(ngs.Integrate((self._gfu-self._ngs_ex)*(self._gfu-self._ngs_ex), self._mesh)) except TypeError: print("FEM approximate solution not ready - try to call solve() first")
ns.append(fem_size) actual0 = bempp.api.GridFunction(bc_space, fun=zero) errs.append((actual0 - bem_soln).l2_norm()) actual_u = ngs.CoefficientFunction((ngs.cos(k * ngs.z), 0, 0)) actual_curl_u = ngs.CoefficientFunction((0, -k * ngs.sin(k * ngs.z), 0)) actual_sol = np.concatenate([soln_fem, soln_bem]) from math import sqrt u_H1 = sqrt( abs( ngs.Integrate((actual_u - u) * (actual_u - u) + (actual_curl_u - u.Deriv())**2, mesh, order=10))) err2s.append(u_H1) print("ns: ", ns) print("Hcurl error:", err2s) print("BEM error", errs) plt.plot(ns, err2s, "ro-") plt.plot(ns, errs, "bo-") plt.legend(["FEM part", "BEM part"]) plt.xscale("log") plt.yscale("log") plt.xlabel("number of FEM DOFs") plt.ylabel("Error") plt.savefig("output/conv.png")
def _l_2(sol: GridFunction, ref_sol: Union[GridFunction, CoefficientFunction], mesh: Mesh) -> float: """ L2 norm """ return ngs.sqrt(ngs.Integrate((sol - ref_sol) * (sol - ref_sol), mesh))