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 test_4(self, presets_load_coefficientfunction_into_gridfunction): """ Check that the coefficientfunction and gridfunction dimensions must agree. 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 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)) gfu_mixed_3d = ngs.GridFunction(fes_mixed_3d) cfu_vector_3d = ngs.CoefficientFunction((ngs.x, ngs.y, ngs.z)) # Check 2D. with pytest.raises(netgen.libngpy._meshing.NgException): coef_dict = {1: cfu_vector_2d} # Vector coefficientfunction but scalar gridfunction. load_coefficientfunction_into_gridfunction(gfu_mixed_2d, coef_dict) with pytest.raises(netgen.libngpy._meshing.NgException): coef_dict = {0: cfu_scalar} # Scalar coefficientfunction but vector gridfunction. load_coefficientfunction_into_gridfunction(gfu_mixed_2d, coef_dict) # Check 3D. with pytest.raises(netgen.libngpy._meshing.NgException): coef_dict = {1: cfu_vector_3d} # Vector coefficientfunction but scalar gridfunction. load_coefficientfunction_into_gridfunction(gfu_mixed_3d, coef_dict) with pytest.raises(netgen.libngpy._meshing.NgException): coef_dict = {0: cfu_scalar} # Scalar coefficientfunction but vector gridfunction. load_coefficientfunction_into_gridfunction(gfu_mixed_3d, coef_dict)
def test_3(self, presets_load_coefficientfunction_into_gridfunction): """ Check that passing in a coef_dict with multiple keys, one of which is None raises an error. """ 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 = ngs.GridFunction(fes_scalar_2d) cfu_1 = ngs.CoefficientFunction(ngs.x + ngs.y) cfu_2 = ngs.CoefficientFunction(ngs.x * ngs.y) coef_dict = {None: cfu_1, 0: cfu_2} with pytest.raises(AssertionError): load_coefficientfunction_into_gridfunction(gfu, coef_dict)
def test_evaluate(): from netgen.geom2d import unit_square import ngsolve as ngs import numpy as np mesh = ngs.Mesh(unit_square.GenerateMesh(maxh=0.2)) pnts = np.linspace(0.1, 0.9, 9) cf = ngs.CoefficientFunction((ngs.x, ngs.y)) cf2 = ngs.CoefficientFunction((ngs.y, ngs.x * 1J)) mips = mesh(pnts, 0.5) vals = cf(mips) vals2 = cf2(mips) assert np.linalg.norm(vals - np.array(list(zip(pnts, [0.5] * 10)))) < 1e-10 assert np.linalg.norm( vals2 - np.array(list(zip([0.5 + 0J] * 10, pnts * 1J)))) < 1e-10 assert ngs.x(mesh(0.5, 0.5)) - 0.5 < 1e-10
def do_test(rots, reo, ms=50): print('======= test 3d, lo, rots =', rots, ', reorder=', reo) sys.stdout.flush() geo, mesh = gen_beam(dim=3, maxh=0.2, lens=[7, 1, 1], nref=0, comm=ngsolve.mpi_world) V, a, f = setup_elast(mesh, rotations=rots, f_vol=ngsolve.CoefficientFunction((0, -0.005, 0)), diri="left", multidim=False, reorder=reo) print('V ndof', V.ndof) ngsolve.ngsglobals.msg_level = 5 pc_opts = {"ngs_amg_max_coarse_size": 10} if reo == "sep": pc_opts["ngs_amg_dof_blocks"] = [3, 3] if rots else [3] elif reo is not False: pc_opts["ngs_amg_dof_blocks"] = [6] if rots else [3] if rots: pc_opts["ngs_amg_rots"] = True c = ngsolve.Preconditioner(a, "ngs_amg.elast_3d", **pc_opts) Solve(a, f, c, ms=ms) print('======= completed test 3d, lo, rots =', rots, ', reorder=', reo, '\n\n') sys.stdout.flush()
def do_ho_smooth(rots, ms, pc_opts): print('test 2d, rots = ', rots) geo, mesh = gen_beam(dim = 2, maxh = 0.2, lens = [10,1], nref = 0, comm = ngsolve.mpi_world) V, a, f = setup_elast(mesh, order = 4, rotations = rots, f_vol = ngsolve.CoefficientFunction( (0, -0.005) ), diri = "left") print('V ndof', V.ndof) pc_opts["ngs_amg_rots"] = rots c = ngsolve.Preconditioner(a, "ngs_amg.elast_2d", **pc_opts) Solve(a, f, c, ms = ms)
def do_test_2d_lo(jump, rots, ms=40): geo, mesh = gen_sq_with_sqs(maxh=0.1, nref=0, comm=ngsolve.mpi_world) a0 = 1 mu = {"mat_a": a0, "mat_b": jump * a0} V, a, f = setup_elast(mesh, rotations=rots, f_vol=ngsolve.CoefficientFunction((0, -0.005)), diri="outer_left", mu=ngsolve.CoefficientFunction( [mu[name] for name in mesh.GetMaterials()])) print('V ndof', V.ndof) pc_opts = { "ngs_amg_max_coarse_size": 10, "ngs_amg_log_level": "extra", "ngs_amg_print_log": True } if rots: pc_opts["ngs_amg_rots"] = True c = ngsolve.Preconditioner(a, "ngs_amg.elast_2d", **pc_opts) Solve(a, f, c, ms=50)
def set_initial_conditions(self, gfu_IC: ngs.GridFunction, mesh: ngs.Mesh, model_name: str, model_components: Dict[str, int]) -> None: """ Function to load the initial conditions from their configfile into a gridfunction. Args: mesh: The model's mesh. model_name: Sometimes several models will use the same IC configfile. This identifies which model's ICs should be loaded. gfu_IC: A gridfunction to hold the initial conditions. model_components: Maps between variable names and their component in the model's finite element space. """ coef_dict = {} file_dict = {} for var, marker_dict in self.ic_dict[model_name].items(): # Determine which component of the gridfunction the initial condition is for if var == 'all': component = None else: component = model_components[var] # Check if the initial condition is specified as a file, a coefficientfunction, or a dict of material # markers and coefficientfunctions. if len(marker_dict) == 1: # One single file or coefficientfunction. assert next(iter(marker_dict.keys())) == 'all' val = next(iter(marker_dict.values())) if val is None: # No initial condition needed so just keep the zeroed out gridfunction. return if isinstance(val, str): # Check that the file exists. val = self._find_rel_path_for_file(val) file_dict[component] = val else: coef_dict[component] = val else: # Need to construct a coefficientfunction from a set of material markers. coef = ngs.CoefficientFunction([marker_dict[mat] for mat in mesh.GetMaterials()]) coef_dict[component] = coef if coef_dict: load_coefficientfunction_into_gridfunction(gfu_IC, coef_dict) if file_dict: update_gridfunction_from_files(gfu_IC, file_dict)
def do_ho_smooth(rots, ms, pc_opts): print('test 3d, rots = ', rots) sys.stdout.flush() geo, mesh = gen_beam(dim = 3, maxh = 0.35, lens = [5,1,1], nref = 0, comm = ngsolve.mpi_world) V, a, f = setup_elast(mesh, order = 2, rotations = rots, f_vol = ngsolve.CoefficientFunction( (0, -0.005, 0) ), diri = "left") pc_opts["ngs_amg_rots"] = rots if not rots: pc_opts["ngs_amg_reg_mats"] = True pc_opts["ngs_amg_reg_rmats"] = True c = ngs_amg.elast_3d(a, **pc_opts) Solve(a, f, c, ms = ms)
def inital_span(X): # Coefficient funtions in the span. coeffs = (ng.CoefficientFunction([1]), ng.x, ng.y) # The span as a list. span = [ng.GridFunction(X) for k in range(len(coeffs))] # Set the values of each GridFunction. for k in range(len(coeffs)): span[k].Set(coeffs[k]) return span
def rbms(dim, V, rots): if rots: tups = [(1, 0, 0), (0, 1, 0), (y, -x, 1)] else: tups = [(1, 0), (0, 1), (y, -x)] cfs = [ngsolve.CoefficientFunction(x) for x in tups] gf = ngsolve.GridFunction(V) kvecs = [gf.vec.CreateVector() for c in cfs] for vec, cf in zip(kvecs, cfs): gf.Set(cf) vec.data = gf.vec return kvecs
def test_2d_lo_R(): geo, mesh = gen_beam(dim=2, maxh=0.1, lens=[10, 1], nref=0, comm=ngsolve.mpi_world) V, a, f = setup_elast(mesh, rotations=True, f_vol=ngsolve.CoefficientFunction((0, -0.005)), diri="left") pc_opts = {"ngs_amg_rots": True, "ngs_amg_max_coarse_size": 20} c = ngsolve.Preconditioner(a, "ngs_amg.elast_2d", **pc_opts) Solve(a, f, c, ms=50)
def test_3d_lo(): geo, mesh = gen_beam(dim=3, maxh=0.25, lens=[10, 1, 1], nref=0, comm=ngsolve.mpi_world) V, a, f = setup_elast(mesh, rotations=False, f_vol=ngsolve.CoefficientFunction( (0, -0.005, 0.002)), diri="left") pc_opts = {"ngs_amg_reg_rmats": True, "ngs_amg_max_coarse_size": 10} c = ngsolve.Preconditioner(a, "ngs_amg.elast_3d", **pc_opts) Solve(a, f, c, ms=40)
def do_test_2d_ho(jump): print('test sq_with_sqs, jump =', jump) sys.stdout.flush() geo, mesh = gen_sq_with_sqs(maxh=0.1, nref=0, comm=ngsolve.mpi_world) a0 = 1 alpha = {"mat_a": a0, "mat_b": jump * a0} V, a, f = setup_poisson(mesh, order=3, diri="outer_.*", alpha=ngsolve.CoefficientFunction( [alpha[name] for name in mesh.GetMaterials()])) pc_opts = { "ngs_amg_max_coarse_size": 5, "ngs_amg_log_level": "extra", "ngs_amg_print_hog": True } c = ngsolve.Preconditioner(a, "ngs_amg.h1_scal", **pc_opts) Solve(a, f, c, ms=100, tol=1e-6, nocb=False)
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 do_test_2d_lo_fiber(jump, ms=25): print('\n\n---\ntest 2d fibers, jump =', jump, '\n---') sys.stdout.flush() geo, mesh = gen_fibers_2d(maxh=0.1, nref=1, comm=ngsolve.mpi_world) a0 = 1 alpha = {"mat_a": a0, "mat_b": jump * a0} V, a, f = setup_poisson(mesh, order=1, diri="outer_top|outer_bot", alpha=ngsolve.CoefficientFunction( [alpha[name] for name in mesh.GetMaterials()])) pc_opts = { "ngs_amg_max_coarse_size": 5, "ngs_amg_sm_type": "bgs", "ngs_amg_log_level": "extra", "ngs_amg_print_log": True } c = ngsolve.Preconditioner(a, "ngs_amg.h1_scal", **pc_opts) Solve(a, f, c, ms=ms, tol=1e-6)
def __init__(self, cf, mesh, order, min_, max_, draw_vol, draw_surf, autoscale, deformation, interpolate_multidim, animate): from IPython.display import display, Javascript import threading self.cf = cf self.mesh = mesh self.order = order self.min = min_ self.max = max_ self.draw_vol = draw_vol self.draw_surf = draw_surf self.autoscale = autoscale self.interpolate_multidim = interpolate_multidim self.animate = animate if isinstance(deformation, ngs.CoefficientFunction): if deformation.dim == 2: deformation = ngs.CoefficientFunction((deformation, 0.0)) self.deformation = deformation
def do_ho_smooth_nodalp2(rots, ms, pc_opts, order = 3): print('test 3d with nodalp2, order = ', order, 'rots = ', rots) sys.stdout.flush() geo, mesh = gen_beam(dim = 3, maxh = 0.35, lens = [5,1,1], nref = 0, comm = ngsolve.mpi_world) V, a, f = setup_elast(mesh, order = order, rotations = rots, f_vol = ngsolve.CoefficientFunction( (0, -0.005, 0) ), diri = "left", fes_opts = {"nodalp2" : True} ) print('V ndof', V.ndof) pc_opts["ngs_amg_rots"] = rots pc_opts["ngs_amg_first_aaf"] = 0.1 if order == 2: pc_opts["ngs_amg_lo"] = False else: pc_opts["ngs_amg_on_dofs"] = "select" pc_opts["ngs_amg_subset"] = "nodalp2" if rots is False: pc_opts["ngs_amg_reg_mats"] = True pc_opts["ngs_amg_reg_rmats"] = True c = ngs_amg.elast_3d(a, **pc_opts) Solve(a, f, c, ms = ms)
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 do_test_2d_lo(jump, ms=25): print('\n\n---\ntest sq_with_sqs, jump =', jump, '\n---') sys.stdout.flush() geo, mesh = gen_sq_with_sqs(maxh=0.05, nref=1, comm=ngsolve.mpi_world) a0 = 1 alpha = {"mat_a": a0, "mat_b": jump * a0} V, a, f = setup_poisson(mesh, order=1, diri="outer_bot|outer_top|outer_left|outer_right", \ alpha = ngsolve.CoefficientFunction([alpha[name] for name in mesh.GetMaterials()]) ) pc_opts = { "ngs_amg_max_coarse_size": 5, "ngs_amg_log_level": "extra", "ngs_amg_crs_alg": "agg", "ngs_amg_agg_wt_geom": True, "ngs_amg_enable_disc": False, #"ngs_amg_max_levels" : 4, "ngs_amg_enable_sp": True, "ngs_amg_print_log": True } c = ngsolve.Preconditioner(a, "ngs_amg.h1_scal", **pc_opts) Solve(a, f, c, ms=ms, tol=1e-6)
def _eval(self, diff, differentiate=False): # Assemble Bilinearform self.gfu_integrator.vec.FV().NumPy()[:] = diff self.gfu_integrator_codomain.Set(self.gfu_integrator) self.a.Assemble() # Assemble Linearform, boundary term self.gfu_b.Set(self.g) self.b.Assemble() # Solve system self.gfu.vec.data = self._solve(self.a, self.b.vec) # res=sco.minimize((lambda u: self._target(u, self.b.vec)), np.zeros(self.fes_codomain.ndof), constraints={"fun": self._constraint, "type": "eq"}) if differentiate: sigma = ngs.CoefficientFunction(self.gfu_integrator) self.gfu_bdr.Set(self.g / sigma) # self.gfu.vec.FV().NumPy()[:]=res.x return self._get_boundary_values(self.gfu)
def linear_combo(v, W): """ Method that multiplies the list v containing the span of our vectors to the matrix W that solved the eigenproblem vAv*W = vBv*W*E, where E is the diagonal matrix of eigenvalues. """ # Create an array of new eigenfunctions. q = [] for k in range(len(v)): q += [ng.GridFunction(v[k].space)] q[k].Set(ng.CoefficientFunction(0)) # Now set the values of each new grid function. for k in range(len(q)): for m in range(len(v)): q[k].vec.data += np.complex(W[m, k]) * v[m].vec return q
def Solve(a, f, c, ms=100): ngs.ngsglobals.msg_level = 5 gfu = ngs.GridFunction(a.space) with ngs.TaskManager(): a.Assemble() f.Assemble() ngs.ngsglobals.msg_level = 5 if c is None: c = a.mat.Inverse(V.FreeDofs()) else: c.Test() cb = None if a.space.mesh.comm.rank != 0 else lambda k, x: print( "it =", k, ", err =", x) cg = ngs.krylovspace.CGSolver(mat=a.mat, pre=c, callback=cb, maxsteps=ms, tol=1e-6) cg.Solve(sol=gfu.vec, rhs=f.vec) print("used nits = ", cg.iterations) ngsolve.Draw(mesh, deformation=ngsolve.CoefficientFunction( (gfu[0], gfu[1], 0)))
# PARAMETERS: p = 3 # polynomial degree h0 = 1 # coarse mesh size for unit square domain markprm = 0.5 # percentage of max total error for marking # SET UP: mesh = Mesh(unit_square.GenerateMesh(maxh=h0)) q_zero = 'bottom' # Mesh boundary parts where q and mu_zero = 'bottom|right|left' # mu has essential b.c u00 = exp(-1000 * ((x - 0.5) * (x - 0.5))) # Nonzero initial condition cwave = 1. # wave speed F = ngs.CoefficientFunction((0, 0)) # Zero source a, f, X, sep = makeforms(mesh, p, F, q_zero, mu_zero, cwave, epsil=1.e-10) euz = GridFunction(X) # Contains solution at each adaptive step q = euz.components[sep[0]] # Volume (L2) components mu = euz.components[sep[0]+1] zq = euz.components[sep[1]] # Interface components zmu = euz.components[sep[1]+1] zq.Set(u00, definedon='bottom') zmu.Set(-u00, definedon='bottom') ngs.Draw(mu, autoscale=False, # draw only one of the solution components min=-1.0, max=1.0)
landweber = Landweber(setting, data, init_solution, stepsize=1) stoprule = (rules.CountIterations(1000) + rules.Discrepancy(setting.Hcodomain.norm, data, noiselevel=setting.Hcodomain.norm(noise), tau=1.1)) reco, reco_data = landweber.run(stoprule) ngs.Draw(exact_solution_coeff, op.fes_domain.mesh, "exact") ngs.Draw(init, op.fes_domain.mesh, "init") # Draw recondtructed solution gfu_reco = ngs.GridFunction(op.fes_domain) gfu_reco.vec.FV().NumPy()[:] = reco coeff_reco = ngs.CoefficientFunction(gfu_reco) ngs.Draw(coeff_reco, op.fes_domain.mesh, "reco") # Draw data space gfu_data = ngs.GridFunction(op.fes_codomain) gfu_reco_data = ngs.GridFunction(op.fes_codomain) gfu_data.vec.FV().NumPy()[:] = data coeff_data = ngs.CoefficientFunction(gfu_data) gfu_reco_data.vec.FV().NumPy()[:] = reco_data coeff_reco_data = ngs.CoefficientFunction(gfu_reco_data) ngs.Draw(coeff_data, op.fes_codomain.mesh, "data") ngs.Draw(coeff_reco_data, op.fes_codomain.mesh, "reco_data")
import ngsolve, ngs_amg from amg_utils import * maxh = 0.25 geo, mesh = gen_beam(dim=3, maxh=maxh, lens=[10, 1, 1], nref=0, comm=ngsolve.mpi_world) V, a, f = setup_elast(mesh, rotations=False, f_vol=ngsolve.CoefficientFunction((0, -1e-5, -1e-5)), diri="left") #pc_opts = { "ngs_amg_reg_rmats" : True } pc_opts = { "ngs_amg_reg_rmats": True, "ngs_amg_rots": False, "mgs_amg_max_levels": 2, #"ngs_amg_aaf" : 0.25, "ngs_amg_max_coarse_size": 20, #"ngs_amg_max_levels" : 4, "ngs_amg_log_level": "extra", "ngs_amg_enable_sp": True, "ngs_amg_sp_max_per_row": 4, "ngs_amg_enable_redist": True, "ngs_amg_first_aaf": 0.025 } gfu = ngsolve.GridFunction(V) a.Assemble() f.Assemble()
def BuildRenderData(mesh, func, order=2, draw_surf=True, draw_vol=True, deformation=None): timer.Start() #TODO: handle quads and non-smooth functions #TODO: subdivision d = {} d['ngsolve_version'] = ngs.__version__ d['mesh_dim'] = mesh.dim # order = order or mesh.GetCurveOrder() if (not func) and (mesh.GetCurveOrder() == 1): order = 1 order2d = min(order, 3) order3d = min(order, 2) d['order2d'] = order2d d['order3d'] = order3d d['draw_vol'] = func and mesh.dim == 3 and draw_vol d['draw_surf'] = func and draw_surf if isinstance(deformation, bool): d['deformation'] = deformation deformation = None func2 = None if func and func.is_complex: d['is_complex'] = True func1 = func[0].real func2 = ngs.CoefficientFunction((func[0].imag, 0.0)) d['funcdim'] = 2 elif func and func.dim > 1: func1 = func[0] func2 = ngs.CoefficientFunction( tuple(func[i] if i < func.dim else 0.0 for i in range(1, 3))) # max 3-dimensional functions d['funcdim'] = func.dim elif func: func1 = func d['funcdim'] = 1 else: func1 = ngs.CoefficientFunction(0.0) d['funcdim'] = 0 func1 = ngs.CoefficientFunction((ngs.x, ngs.y, ngs.z, func1)) func0 = ngs.CoefficientFunction((ngs.x, ngs.y, ngs.z, 0.0)) if deformation is not None: func1 += ngs.CoefficientFunction((deformation, 0.0)) func0 += ngs.CoefficientFunction((deformation, 0.0)) d['show_wireframe'] = False d['show_mesh'] = False if order2d > 0: og = order2d d['show_wireframe'] = True d['show_mesh'] = True timer2.Start() timer3Bvals.Start() # transform point-values to Bernsteinbasis def Binomial(n, i): return math.factorial(n) / math.factorial(i) / math.factorial(n - i) def Bernstein(x, i, n): return Binomial(n, i) * x**i * (1 - x)**(n - i) Bvals = ngs.Matrix(og + 1, og + 1) for i in range(og + 1): for j in range(og + 1): Bvals[i, j] = Bernstein(i / og, j, og) iBvals = Bvals.I timer3Bvals.Stop() # print (Bvals) # print (iBvals) Bezier_points = [] # TODO: Quads ipts = [(i / og, 0) for i in range(og + 1)] + [ (0, i / og) for i in range(og + 1) ] + [(i / og, 1.0 - i / og) for i in range(og + 1)] ir = ngs.IntegrationRule(ipts, [ 0, ] * len(ipts)) vb = [ngs.VOL, ngs.BND][mesh.dim - 2] pts = mesh.MapToAllElements(ir, vb) cf = func1 if draw_surf else func0 pmat = cf(pts) timermult.Start() pmat = pmat.reshape(-1, og + 1, 4) BezierPnts = np.tensordot(iBvals.NumPy(), pmat, axes=(1, 1)) timermult.Stop() timer2list.Start() for i in range(og + 1): Bezier_points.append(encodeData(BezierPnts[i])) timer2list.Stop() if func2 and draw_surf: pmat = func2(pts) pmat = pmat.reshape(-1, og + 1, 2) timermult.Start() BezierPnts = np.tensordot(iBvals.NumPy(), pmat, axes=(1, 1)) timermult.Stop() timer2list.Start() for i in range(og + 1): Bezier_points.append(encodeData(BezierPnts[i])) timer2list.Stop() d['Bezier_points'] = Bezier_points timer2.Stop() timer3.Start() ndtrig = int((og + 1) * (og + 2) / 2) if og in bezier_trig_trafos.keys(): iBvals_trig = bezier_trig_trafos[og] else: def BernsteinTrig(x, y, i, j, n): return math.factorial(n)/math.factorial(i)/math.factorial(j)/math.factorial(n-i-j) \ * x**i*y**j*(1-x-y)**(n-i-j) Bvals = ngs.Matrix(ndtrig, ndtrig) ii = 0 for ix in range(og + 1): for iy in range(og + 1 - ix): jj = 0 for jx in range(og + 1): for jy in range(og + 1 - jx): Bvals[ii, jj] = BernsteinTrig(ix / og, iy / og, jx, jy, og) jj += 1 ii += 1 iBvals_trig = Bvals.I bezier_trig_trafos[og] = iBvals_trig # Bezier_points = [ [] for i in range(ndtrig) ] Bezier_points = [] ir = ngs.IntegrationRule([(i / og, j / og) for j in range(og + 1) for i in range(og + 1 - j)], [ 0, ] * (ndtrig)) vb = [ngs.VOL, ngs.BND][mesh.dim - 2] pts = mesh.MapToAllElements(ir, vb) pmat = ngs.CoefficientFunction(func1 if draw_surf else func0)(pts) timer3minmax.Start() funcmin = np.min(pmat[:, 3]) funcmax = np.max(pmat[:, 3]) pmin = np.min(pmat[:, 0:3], axis=0) pmax = np.max(pmat[:, 0:3], axis=0) mesh_center = (pmin + pmax) / 2 mesh_radius = np.linalg.norm(pmax - pmin) / 2 timer3minmax.Stop() pmat = pmat.reshape(mesh.GetNE(vb), len(ir), 4) BezierPnts = np.tensordot(iBvals_trig.NumPy(), pmat, axes=(1, 1)) timer3list.Start() for i in range(ndtrig): Bezier_points.append(encodeData(BezierPnts[i])) timer3list.Stop() if func2 and draw_surf: pmat = ngs.CoefficientFunction(func2)(pts) pmat = pmat.reshape(mesh.GetNE(vb), len(ir), 2) funcmin = min(funcmin, np.min(pmat)) funcmax = max(funcmax, np.max(pmat)) BezierPnts = np.tensordot(iBvals_trig.NumPy(), pmat, axes=(1, 1)) if og == 1: for i in range(ndtrig): Bezier_points.append(encodeData(BezierPnts[i])) else: BezierPnts = BezierPnts.transpose( (1, 0, 2)).reshape(mesh.GetNE(vb), len(ir) // 2, 4).transpose((1, 0, 2)) for i in range(ndtrig // 2): Bezier_points.append(encodeData(BezierPnts[i])) d['Bezier_trig_points'] = Bezier_points d['mesh_center'] = list(mesh_center) d['mesh_radius'] = mesh_radius timer3.Stop() timer4.Start() if mesh.dim == 3 and draw_vol: p0 = [] p1 = [] p2 = [] p3 = [] values = [] tets = [] if order3d == 1: ir = ngs.IntegrationRule([(1, 0, 0), (0, 1, 0), (0, 0, 1), (0, 0, 0)], [0] * 4) else: ir = ngs.IntegrationRule([(1, 0, 0), (0, 1, 0), (0, 0, 1), (0, 0, 0), (0.5, 0, 0), (0, 0.5, 0), (0, 0, 0.5), (0.5, 0.5, 0), (0.5, 0, 0.5), (0, 0.5, 0.5)], [0] * 10) pts = mesh.MapToAllElements(ir, ngs.VOL) pmat = func1(pts) if draw_vol else func0(pts) ne = mesh.GetNE(ngs.VOL) pmat = pmat.reshape(ne, len(ir), 4) funcmin = min(funcmin, np.min(pmat[:, :, 3])) funcmax = max(funcmax, np.max(pmat[:, :, 3])) points3d = [] for i in range(len(ir)): points3d.append(encodeData(pmat[:, i, :])) if func2 and draw_vol: pmat = func2(pts).reshape(ne, len(ir) // 2, 4) funcmin = min(funcmin, np.min(pmat)) funcmax = max(funcmax, np.max(pmat)) for i in range(len(ir) // 2): points3d.append(encodeData(pmat[:, i, :])) d['points3d'] = points3d if func: d['funcmin'] = funcmin d['funcmax'] = funcmax timer4.Stop() timer.Stop() return d
li_factor = sqrt(solubility_difference) * sqrt(concentration) return F * reaction_rate * li_factor mesh = ngs.Mesh('mesh.vol') n_lithium_space = ngs.H1(mesh, order=1) potential_space = ngs.H1(mesh, order=1, dirichlet='anode') V = ngs.FESpace([n_lithium_space, potential_space]) print(V.ndof) u, p = V.TrialFunction() v, q = V.TestFunction() # Coefficient functions cf_diffusivity = ngs.CoefficientFunction([diffusivity[mat] for mat in mesh.GetMaterials()]) cf_conductivity = ngs.CoefficientFunction([conductivity[mat] for mat in mesh.GetMaterials()]) cf_valence = ngs.CoefficientFunction([valence[mat] for mat in mesh.GetMaterials()]) 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)
def BuildRenderData(mesh, func, order=2, draw_surf=True, draw_vol=True, deformation=None, region=True, objects=[]): timer.Start() if isinstance(deformation, ngs.CoefficientFunction) and deformation.dim == 2: deformation = ngs.CoefficientFunction((deformation, 0.0)) #TODO: handle quads and non-smooth functions #TODO: subdivision d = {} d['ngsolve_version'] = ngs.__version__ d['mesh_dim'] = mesh.dim # order = order or mesh.GetCurveOrder() if (not func) and (mesh.GetCurveOrder() == 1) and (mesh.nv == len( mesh.ngmesh.Points())): order = 1 order2d = min(order, 3) order3d = min(order, 2) d['order2d'] = order2d d['order3d'] = order3d d['draw_vol'] = func and mesh.dim == 3 and draw_vol and mesh.ne > 0 d['draw_surf'] = func and draw_surf d['objects'] = [] for obj in objects: if isinstance(obj, dict): d['objects'].append(obj) else: d['objects'].append(obj._GetWebguiData()) if isinstance(deformation, bool): d['deformation'] = deformation deformation = None func0 = None func2 = None if func and func.is_complex: d['is_complex'] = True func1 = func[0].real func2 = ngs.CoefficientFunction((func[0].imag, 0.0)) d['funcdim'] = 2 elif func and func.dim > 1: func1 = func[0] func2 = ngs.CoefficientFunction( tuple(func[i] if i < func.dim else 0.0 for i in range(1, 3))) # max 3-dimensional functions d['funcdim'] = func.dim elif func: func1 = func d['funcdim'] = 1 else: # no function at all -> we are just drawing a mesh, eval mesh element index instead mats = mesh.GetMaterials() bnds = mesh.GetBoundaries() bbnds = mesh.GetBBoundaries() nmats = len(mesh.GetMaterials()) nbnds = len(mesh.GetBoundaries()) n = max(nmats, nbnds, len(bbnds)) func1 = ngs.CoefficientFunction(list(range(n))) n_regions = [0, 0, nmats, nbnds] d['mesh_regions_2d'] = n_regions[mesh.dim] d['mesh_regions_3d'] = nmats if mesh.dim == 3 else 0 d['names'] = bnds if mesh.dim == 3 else mats d['edge_names'] = bbnds if mesh.dim == 3 else bnds d['funcdim'] = 0 func0 = func1 if func0 is None: func0 = ngs.CoefficientFunction(0.0) func1 = ngs.CoefficientFunction((ngs.x, ngs.y, ngs.z, func1)) func0 = ngs.CoefficientFunction((ngs.x, ngs.y, ngs.z, func0)) if deformation is not None: func1 += ngs.CoefficientFunction((deformation, 0.0)) func0 += ngs.CoefficientFunction((deformation, 0.0)) d['show_wireframe'] = False d['show_mesh'] = False if order2d > 0: og = order2d d['show_wireframe'] = True d['show_mesh'] = True timer2.Start() timer3Bvals.Start() # transform point-values to Bernsteinbasis def Binomial(n, i): return math.factorial(n) / math.factorial(i) / math.factorial(n - i) def Bernstein(x, i, n): return Binomial(n, i) * x**i * (1 - x)**(n - i) Bvals = ngs.Matrix(og + 1, og + 1) for i in range(og + 1): for j in range(og + 1): Bvals[i, j] = Bernstein(i / og, j, og) iBvals = Bvals.I timer3Bvals.Stop() # print (Bvals) # print (iBvals) Bezier_points = [] # TODO: Quads ipts = [(i / og, 0) for i in range(og + 1)] + [ (0, i / og) for i in range(og + 1) ] + [(i / og, 1.0 - i / og) for i in range(og + 1)] ir_trig = ngs.IntegrationRule(ipts, [ 0, ] * len(ipts)) ipts = [(i / og, 0) for i in range(og + 1)] + [ (0, i / og) for i in range(og + 1) ] + [(i / og, 1.0) for i in range(og + 1)] + [(1.0, i / og) for i in range(og + 1)] ir_quad = ngs.IntegrationRule(ipts, [ 0, ] * len(ipts)) vb = [ngs.VOL, ngs.BND][mesh.dim - 2] if region and region.VB() == vb: vb = region cf = func1 if draw_surf else func0 timer2map.Start() pts = mesh.MapToAllElements( { ngs.ET.TRIG: ir_trig, ngs.ET.QUAD: ir_quad }, vb) timer2map.Stop() pmat = cf(pts) pmima = updatePMinMax(pmat) timermult.Start() pmat = pmat.reshape(-1, og + 1, 4) if False: BezierPnts = np.tensordot(iBvals.NumPy(), pmat, axes=(1, 1)) else: BezierPnts = np.zeros((og + 1, pmat.shape[0], 4)) for i in range(4): ngsmat = ngs.Matrix(pmat[:, :, i].transpose()) BezierPnts[:, :, i] = iBvals * ngsmat timermult.Stop() timer2list.Start() for i in range(og + 1): Bezier_points.append(encodeData(BezierPnts[i])) timer2list.Stop() if func2 and draw_surf: pmat = func2(pts) pmat = pmat.reshape(-1, og + 1, 2) timermult.Start() BezierPnts = np.tensordot(iBvals.NumPy(), pmat, axes=(1, 1)) timermult.Stop() timer2list.Start() for i in range(og + 1): Bezier_points.append(encodeData(BezierPnts[i])) timer2list.Stop() d['Bezier_points'] = Bezier_points ipts = [(i / og, 0) for i in range(og + 1)] ir_seg = ngs.IntegrationRule(ipts, [ 0, ] * len(ipts)) vb = [ngs.VOL, ngs.BND, ngs.BBND][mesh.dim - 1] if region and region.VB() == vb: vb = region pts = mesh.MapToAllElements(ir_seg, vb) pmat = func0(pts) pmima = updatePMinMax(pmat) pmat = pmat.reshape(-1, og + 1, 4) edge_data = np.tensordot(iBvals.NumPy(), pmat, axes=(1, 1)) edges = [] for i in range(og + 1): edges.append(encodeData(edge_data[i])) d['edges'] = edges timer2.Stop() timer3.Start() ndtrig = int((og + 1) * (og + 2) / 2) if og in bezier_trig_trafos.keys(): iBvals_trig = bezier_trig_trafos[og] else: def BernsteinTrig(x, y, i, j, n): return math.factorial(n)/math.factorial(i)/math.factorial(j)/math.factorial(n-i-j) \ * x**i*y**j*(1-x-y)**(n-i-j) Bvals = ngs.Matrix(ndtrig, ndtrig) ii = 0 for ix in range(og + 1): for iy in range(og + 1 - ix): jj = 0 for jx in range(og + 1): for jy in range(og + 1 - jx): Bvals[ii, jj] = BernsteinTrig(ix / og, iy / og, jx, jy, og) jj += 1 ii += 1 iBvals_trig = Bvals.I bezier_trig_trafos[og] = iBvals_trig # Bezier_points = [ [] for i in range(ndtrig) ] Bezier_points = [] ipts = [(i / og, j / og) for j in range(og + 1) for i in range(og + 1 - j)] ir_trig = ngs.IntegrationRule(ipts, [ 0, ] * len(ipts)) ipts = ([(i / og, j / og) for j in range(og + 1) for i in range(og + 1 - j)] + [(1 - i / og, 1 - j / og) for j in range(og + 1) for i in range(og + 1 - j)]) ir_quad = ngs.IntegrationRule(ipts, [ 0, ] * len(ipts)) vb = [ngs.VOL, ngs.BND][mesh.dim - 2] if region and region.VB() == vb: vb = region pts = mesh.MapToAllElements( { ngs.ET.TRIG: ir_trig, ngs.ET.QUAD: ir_quad }, vb) pmat = ngs.CoefficientFunction(func1 if draw_surf else func0)(pts) timer3minmax.Start() pmima = updatePMinMax(pmat, pmima) funcmin, funcmax = getMinMax(pmat[:, 3]) timer3minmax.Stop() pmin, pmax = [ngs.Vector(p) for p in zip(*pmima)] mesh_center = 0.5 * (pmin + pmax) mesh_radius = np.linalg.norm(pmax - pmin) / 2 pmat = pmat.reshape(-1, len(ir_trig), 4) if False: timer3multnumpy.Start() BezierPnts = np.tensordot(iBvals_trig.NumPy(), pmat, axes=(1, 1)) timer3multnumpy.Stop() else: timer3multngs.Start() BezierPnts = np.zeros((len(ir_trig), pmat.shape[0], 4)) for i in range(4): ngsmat = ngs.Matrix(pmat[:, :, i].transpose()) BezierPnts[:, :, i] = iBvals_trig * ngsmat timer3multngs.Stop() timer3list.Start() for i in range(ndtrig): Bezier_points.append(encodeData(BezierPnts[i])) timer3list.Stop() if func2 and draw_surf: pmat = ngs.CoefficientFunction(func2)(pts) pmat = pmat.reshape(-1, len(ir_trig), 2) funcmin, funcmax = getMinMax(pmat.flatten(), funcmin, funcmax) BezierPnts = np.tensordot(iBvals_trig.NumPy(), pmat, axes=(1, 1)) if og == 1: for i in range(ndtrig): Bezier_points.append(encodeData(BezierPnts[i])) else: BezierPnts = BezierPnts.transpose( (1, 0, 2)).reshape(-1, len(ir_trig) // 2, 4).transpose( (1, 0, 2)) for i in range(ndtrig // 2): Bezier_points.append(encodeData(BezierPnts[i])) d['Bezier_trig_points'] = Bezier_points d['mesh_center'] = list(mesh_center) d['mesh_radius'] = mesh_radius timer3.Stop() timer4.Start() if d['draw_vol']: p0 = [] p1 = [] p2 = [] p3 = [] values = [] tets = [] midpoint = lambda p0, p1: tuple( (0.5 * (p0[i] + p1[i]) for i in range(3))) def makeP2Tets(p1_tets): p2_tets = [] for tet in p1_tets: tet.append(midpoint(tet[0], tet[3])) tet.append(midpoint(tet[1], tet[3])) tet.append(midpoint(tet[2], tet[3])) tet.append(midpoint(tet[0], tet[1])) tet.append(midpoint(tet[0], tet[2])) tet.append(midpoint(tet[1], tet[2])) p2_tets.append(tet) return p2_tets # divide any element into tets p1_tets = {} p1_tets[ngs.ET.TET] = [[(1, 0, 0), (0, 1, 0), (0, 0, 1), (0, 0, 0)]] p1_tets[ngs.ET.PYRAMID] = [[(1, 0, 0), (0, 1, 0), (0, 0, 1), (0, 0, 0)], [(1, 0, 0), (0, 1, 0), (0, 0, 1), (1, 1, 0)]] p1_tets[ngs.ET.PRISM] = [[(1, 0, 0), (0, 1, 0), (0, 0, 1), (0, 0, 0)], [(0, 0, 1), (0, 1, 0), (0, 1, 1), (1, 0, 0)], [(1, 0, 1), (0, 1, 1), (1, 0, 0), (0, 0, 1)]] p1_tets[ngs.ET.HEX] = [[(1, 0, 0), (0, 1, 0), (0, 0, 1), (0, 0, 0)], [(0, 1, 1), (1, 1, 1), (1, 1, 0), (1, 0, 1)], [(1, 0, 1), (0, 1, 1), (1, 0, 0), (0, 0, 1)], [(0, 1, 1), (1, 1, 0), (0, 1, 0), (1, 0, 0)], [(0, 0, 1), (0, 1, 0), (0, 1, 1), (1, 0, 0)], [(1, 0, 1), (1, 1, 0), (0, 1, 1), (1, 0, 0)]] intrules = {} for eltype in p1_tets: points = p1_tets[eltype] if order3d > 1: points = makeP2Tets(points) intrules[eltype] = ngs.IntegrationRule(sum(points, [])) pts = mesh.MapToAllElements(intrules, ngs.VOL) pmat = func1(pts) np_per_tet = len(intrules[ngs.ET.TET]) ne = mesh.GetNE(ngs.VOL) pmat = pmat.reshape(-1, np_per_tet, 4) funcmin, funcmax = getMinMax(pmat[:, :, 3].flatten(), funcmin, funcmax) points3d = [] for i in range(np_per_tet): points3d.append(encodeData(pmat[:, i, :])) if func2: pmat = func2(pts).reshape(-1, np_per_tet // 2, 4) funcmin, funcmax = getMinMax(pmat.flatten(), funcmin, funcmax) for i in range(np_per_tet // 2): points3d.append(encodeData(pmat[:, i, :])) d['points3d'] = points3d if func: d['funcmin'] = funcmin d['funcmax'] = funcmax timer4.Stop() timer.Stop() return d
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