def test_pointsource_vector_fs(mesh, point): """Tests point source when given constructor PointSource(V, point, mag) with a vector for a vector function space that isn't placed at a node for 1D, 2D and 3D. Global points given to constructor from rank 0 processor. """ rank = MPI.rank(mesh.mpi_comm()) V = VectorFunctionSpace(mesh, "CG", 1) v = TestFunction(V) b = assemble(dot(Constant([0.0]*mesh.geometry().dim()), v)*dx) if rank == 0: ps = PointSource(V, point, 10.0) else: ps = PointSource(V, []) ps.apply(b) # Checks array sums to correct value b_sum = b.sum() assert round(b_sum - 10.0*V.num_sub_spaces()) == 0 # Checks point source is added to correct part of the array v2d = vertex_to_dof_map(V) for v in vertices(mesh): if near(v.midpoint().distance(point), 0.0): for spc_idx in range(V.num_sub_spaces()): ind = v2d[v.index()*V.num_sub_spaces() + spc_idx] if ind < len(b.get_local()): assert np.round(b.get_local()[ind] - 10.0) == 0
def test_nullspace_check(mesh, degree): V = VectorFunctionSpace(mesh, ('Lagrange', degree)) u, v = TrialFunction(V), TestFunction(V) mesh.geometry.coord_mapping = fem.create_coordinate_map(mesh) E, nu = 2.0e2, 0.3 mu = E / (2.0 * (1.0 + nu)) lmbda = E * nu / ((1.0 + nu) * (1.0 - 2.0 * nu)) def sigma(w, gdim): return 2.0 * mu * ufl.sym(grad(w)) + lmbda * ufl.tr( grad(w)) * ufl.Identity(gdim) a = inner(sigma(u, mesh.geometry.dim), grad(v)) * dx # Assemble matrix and create compatible vector A = assemble_matrix(a) A.assemble() # Create null space basis and test null_space = build_elastic_nullspace(V) assert null_space.in_nullspace(A, tol=1.0e-8) null_space.orthonormalize() assert null_space.in_nullspace(A, tol=1.0e-8) # Create incorrect null space basis and test null_space = build_broken_elastic_nullspace(V) assert not null_space.in_nullspace(A, tol=1.0e-8) null_space.orthonormalize() assert not null_space.in_nullspace(A, tol=1.0e-8)
def f(self, u, lmbda): v = TestFunction(self.V) ufun = Function(self.V) ufun.vector()[:] = u out = self.a * u - lmbda * assemble(exp(ufun) * v * dx) DirichletBC(self.V, ufun, "on_boundary").apply(out) return out
def __init__(self, form, Space, bcs=[], name="x", matvec=[None, None], method="default", solver_type="cg", preconditioner_type="default"): Function.__init__(self, Space, name=name) self.form = form self.method = method self.bcs = bcs self.matvec = matvec self.trial = trial = TrialFunction(Space) self.test = test = TestFunction(Space) Mass = inner(trial, test) * dx() self.bf = inner(form, test) * dx() self.rhs = Vector(self.vector()) if method.lower() == "default": self.A = A_cache[(Mass, tuple(bcs))] self.sol = Solver_cache[(Mass, tuple(bcs), solver_type, preconditioner_type)] elif method.lower() == "lumping": assert Space.ufl_element().degree() < 2 self.A = A_cache[(Mass, tuple(bcs))] ones = Function(Space) ones.vector()[:] = 1. self.ML = self.A * ones.vector() self.ML.set_local(1. / self.ML.array())
def __init__(self, Th, N): self.N = N mesh = UnitSquareMesh(Th, Th) self.V = FunctionSpace(mesh, "Lagrange", 1) u = TrialFunction(self.V) v = TestFunction(self.V) self.a = lambda k: k * inner(grad(u), grad(v)) * dx
def les_update(nut_, nut_form, A_mass, At, u_, dt, bc_ksgs, bt, ksgs_sol, KineticEnergySGS, CG1, ksgs, delta, **NS_namespace): p, q = TrialFunction(CG1), TestFunction(CG1) Ck = KineticEnergySGS["Ck"] Ce = KineticEnergySGS["Ce"] Sij = sym(grad(u_)) assemble((dt * inner(dot(u_, 0.5 * grad(p)), q) * dx + inner((dt * Ce * sqrt(ksgs) / delta) * 0.5 * p, q) * dx + inner(dt * Ck * sqrt(ksgs) * delta * grad(0.5 * p), grad(q)) * dx), tensor=At) assemble((dt * 2 * Ck * delta * sqrt(ksgs) * inner(Sij, grad(u_)) * q * dx), tensor=bt) bt.axpy(1.0, A_mass * ksgs.vector()) bt.axpy(-1.0, At * ksgs.vector()) At.axpy(1.0, A_mass, True) # Solve for ksgs bc_ksgs.apply(At, bt) ksgs_sol.solve(At, ksgs.vector(), bt) ksgs.vector().set_local(ksgs.vector().array().clip(min=1e-7)) ksgs.vector().apply("insert") # Update nut_ nut_()
def test_krylov_solver_lu(): mesh = UnitSquareMesh(MPI.comm_world, 12, 12) V = FunctionSpace(mesh, ("Lagrange", 1)) u, v = TrialFunction(V), TestFunction(V) a = inner(u, v) * dx L = inner(1.0, v) * dx A = assemble_matrix(a) A.assemble() b = assemble_vector(L) b.ghostUpdate(addv=PETSc.InsertMode.ADD, mode=PETSc.ScatterMode.REVERSE) norm = 13.0 solver = PETScKrylovSolver(mesh.mpi_comm()) solver.set_options_prefix("test_lu_") PETScOptions.set("test_lu_ksp_type", "preonly") PETScOptions.set("test_lu_pc_type", "lu") solver.set_from_options() x = A.createVecRight() solver.set_operator(A) solver.solve(x, b) # *Tight* tolerance for LU solves assert round(x.norm(PETSc.NormType.N2) - norm, 12) == 0
def amg_solve(N, method): # Elasticity parameters E = 1.0e9 nu = 0.3 mu = E / (2.0 * (1.0 + nu)) lmbda = E * nu / ((1.0 + nu) * (1.0 - 2.0 * nu)) # Stress computation def sigma(v): return 2.0 * mu * sym(grad(v)) + lmbda * tr(sym( grad(v))) * Identity(2) # Define problem mesh = UnitSquareMesh(MPI.comm_world, N, N) V = VectorFunctionSpace(mesh, 'Lagrange', 1) bc0 = Function(V) with bc0.vector().localForm() as bc_local: bc_local.set(0.0) def boundary(x, only_boundary): return [only_boundary] * x.shape(0) bc = DirichletBC(V.sub(0), bc0, boundary) u = TrialFunction(V) v = TestFunction(V) # Forms a, L = inner(sigma(u), grad(v)) * dx, dot(ufl.as_vector( (1.0, 1.0)), v) * dx # Assemble linear algebra objects A = assemble_matrix(a, [bc]) A.assemble() b = assemble_vector(L) apply_lifting(b, [a], [[bc]]) b.ghostUpdate(addv=PETSc.InsertMode.ADD, mode=PETSc.ScatterMode.REVERSE) set_bc(b, [bc]) # Create solution function u = Function(V) # Create near null space basis and orthonormalize null_space = build_nullspace(V, u.vector()) # Attached near-null space to matrix A.set_near_nullspace(null_space) # Test that basis is orthonormal assert null_space.is_orthonormal() # Create PETSC smoothed aggregation AMG preconditioner, and # create CG solver solver = PETScKrylovSolver("cg", method) # Set matrix operator solver.set_operator(A) # Compute solution and return number of iterations return solver.solve(u.vector(), b)
def M_inv_diag(self, domain = "all"): """ Returns the inverse lumped mass matrix for the vector function space. The result ist cached. .. note:: This method requires the PETSc Backend to be enabled. *Returns* :class:`dolfin.Matrix` the matrix """ if not self._M_inv_diag.has_key(domain): v = TestFunction(self.VectorFunctionSpace()) u = TrialFunction(self.VectorFunctionSpace()) mass_form = inner(v, u) * self.dx(domain) mass_action_form = action(mass_form, Constant((1.0, 1.0, 1.0))) diag = assemble(mass_action_form) as_backend_type(diag).vec().reciprocal() result = assemble(inner(v, u) * dP) result.zero() result.set_diagonal(diag) self._M_inv_diag[domain] = result return self._M_inv_diag[domain]
def dP(self, domain = "all"): """ Convenience wrapper for integral-point measure. If the mesh does not contain any cell domains, the measure for the whole mesh is returned. *Arguments* domain (:class:`string` / :class:`int`) name or ID of domain *Returns* :class:`dolfin:Measure` the measure """ if not self.mesh_has_domains(): return Measure('dP', self.mesh) if not self._dP.has_key(domain): v = TestFunction(self.FunctionSpace()) values = assemble(v*self.dx(domain)).array() # TODO improve this? markers = ((np.sign(np.ceil(values) - 0.5) + 1.0) / 2.0).astype(np.uint64) vertex_domains = MeshFunction('size_t', self.mesh, 0) vertex_domains.array()[:] = markers self._dP[domain] = Measure('dP', self.mesh)[vertex_domains](1) return self._dP[domain]
def initial_conditions(self): "Return initial conditions for v and s as a dolfin.GenericFunction." n = self.num_states() # (Maximal) Number of states in MultiCellModel VS = VectorFunctionSpace(self.mesh(), "DG", 0, n+1) vs = Function(VS) markers = self.markers() u = TrialFunction(VS) v = TestFunction(VS) dy = Measure("dx", domain=self.mesh(), subdomain_data=markers) # Define projection into multiverse a = inner(u, v)*dy() Ls = list() for (k, model) in enumerate(self.models()): ic = model.initial_conditions() # Extract initial conditions n_k = model.num_states() # Extract number of local states i_k = self.keys()[k] # Extract domain index of cell model k L_k = sum(ic[j]*v[j]*dy(i_k) for j in range(n_k)) Ls.append(L_k) L = sum(Ls) solve(a == L, vs) return vs
def _step( dt, u, p0, u_bcs, p_bcs, rho, mu, time_step_method, f, rotational_form=False, verbose=True, tol=1.0e-10, ): '''Incremental pressure correction scheme scheme as described in section 3.4 of An overview of projection methods for incompressible flows; Guermond, Miev, Shen; Comput. Methods Appl. Mech. Engrg. 195 (2006), <http://www.math.tamu.edu/~guermond/PUBLICATIONS/guermond_minev_shen_CMAME_2006.pdf>. ''' # dt is a Constant() function assert dt.values()[0] > 0.0 assert mu.values()[0] > 0.0 # Define trial and test functions v = TestFunction(u[0].function_space()) # Create functions # Define coefficients with Message('Computing tentative velocity'): ui, alpha = _compute_tentative_velocity(u, p0, f, u_bcs, time_step_method, rho, mu, dt, v, tol=1.0e-10) with Message('Computing pressure'): p1 = _compute_pressure(p0, alpha, rho, dt, mu, div_ui=div(ui), p_bcs=p_bcs, rotational_form=rotational_form, tol=tol, verbose=verbose) with Message('Computing velocity correction'): u1 = _compute_velocity_correction(ui, u, u_bcs, p1, p0, v, mu, rho, dt, rotational_form, tol, verbose) return u1, p1
def assign_initial_conditions(self, function): function_space = function.function_space() markers = self.markers() u = TrialFunction(function_space) v = TestFunction(function_space) dy = Measure("dx", domain=self.mesh(), subdomain_data=markers) # Define projection into multiverse a = inner(u, v) * dy() Ls = list() for k, model in enumerate(self.models()): ic = model.initial_conditions() # Extract initial conditions n_k = model.num_states() # Extract number of local states i_k = self.keys()[k] # Extract domain index of cell model k L_k = sum(ic[j] * v[j] * dy(i_k) for j in range(n_k + 1)) # include v and s Ls.append(L_k) L = sum(Ls) # solve(a == L, function) # really inaccurate params = df.KrylovSolver.default_parameters() params["absolute_tolerance"] = 1e-14 params["relative_tolerance"] = 1e-14 params["nonzero_initial_guess"] = True solver = df.KrylovSolver() solver.update_parameters(params) A, b = df.assemble_system(a, L) solver.set_operator(A) solver.solve(function.vector(), b)
def test_lhs_rhs_simple(): """Test taking lhs/rhs of DOLFIN specific forms (constants without cell). """ mesh = RectangleMesh.create(MPI.comm_world, [Point(0, 0), Point(2, 1)], [3, 5], CellType.Type.triangle) V = FunctionSpace(mesh, "CG", 1) f = Constant(2.0) g = Constant(3.0) v = TestFunction(V) u = TrialFunction(V) F = inner(g * grad(f * v), grad(u)) * dx + f * v * dx a, L = system(F) Fl = lhs(F) Fr = rhs(F) assert (Fr) a0 = inner(grad(v), grad(u)) * dx n = assemble(a).norm("frobenius") # noqa nl = assemble(Fl).norm("frobenius") # noqa n0 = 6.0 * assemble(a0).norm("frobenius") # noqa assert round(n - n0, 7) == 0 assert round(n - nl, 7) == 0
def assert_solves( mesh: Mesh, diffusion: Coefficient, convection: Optional[Coefficient], reaction: Optional[Coefficient], source: Coefficient, exact: Coefficient, l2_tol: Optional[float] = 1.0e-8, h1_tol: Optional[float] = 1.0e-6, ): eafe_matrix = eafe_assemble(mesh, diffusion, convection, reaction) pw_linears = FunctionSpace(mesh, "Lagrange", 1) test_function = TestFunction(pw_linears) rhs_vector = assemble(source * test_function * dx) bc = DirichletBC(pw_linears, exact, lambda _, on_bndry: on_bndry) bc.apply(eafe_matrix, rhs_vector) solution = Function(pw_linears) solver = LUSolver(eafe_matrix, "default") solver.parameters["symmetric"] = False solver.solve(solution.vector(), rhs_vector) l2_err: float = errornorm(exact, solution, "l2", 3) assert l2_err <= l2_tol, f"L2 error too large: {l2_err} > {l2_tol}" h1_err: float = errornorm(exact, solution, "H1", 3) assert h1_err <= h1_tol, f"H1 error too large: {h1_err} > {h1_tol}"
def test_krylov_solver_lu(): mesh = UnitSquareMesh(MPI.comm_world, 12, 12) V = FunctionSpace(mesh, ("Lagrange", 1)) u, v = TrialFunction(V), TestFunction(V) a = inner(u, v) * dx L = inner(1.0, v) * dx A = assemble_matrix(a) A.assemble() b = assemble_vector(L) b.ghostUpdate(addv=PETSc.InsertMode.ADD, mode=PETSc.ScatterMode.REVERSE) norm = 13.0 solver = PETSc.KSP().create(mesh.mpi_comm()) solver.setOptionsPrefix("test_lu_") opts = PETSc.Options("test_lu_") opts["ksp_type"] = "preonly" opts["pc_type"] = "lu" solver.setFromOptions() x = A.createVecRight() solver.setOperators(A) solver.solve(b, x) # *Tight* tolerance for LU solves assert x.norm(PETSc.NormType.N2) == pytest.approx(norm, abs=1.0e-12)
def set_solver_alpha_snes2(self): V = self.alpha.function_space() denergy = derivative(self.energy, self.alpha, TestFunction(V)) ddenergy = derivative(denergy, self.alpha, TrialFunction(V)) self.lb = self.alpha_init # interpolate(Constant("0."), V) ub = interpolate(Constant("1."), V) self.problem_alpha = NonlinearVariationalProblem(denergy, self.alpha, self.bcs_alpha, J=ddenergy) self.problem_alpha.set_bounds(self.lb, ub) self.problem_alpha.lb = self.lb # set up the solver solver = NonlinearVariationalSolver(self.problem_alpha) snes_solver_parameters_bounds = { "nonlinear_solver": "snes", "snes_solver": { "linear_solver": "mumps", "maximum_iterations": 300, "report": True, "line_search": "basic", "method": "vinewtonrsls", "absolute_tolerance": 1e-5, "relative_tolerance": 1e-5, "solution_tolerance": 1e-5 } } solver.parameters.update(snes_solver_parameters_bounds) #solver.solve() self.solver = solver
def expr2function(self, expr, function): """ Convert an expression into a function. How this is done is determined by the parameters (assemble, project or interpolate). """ space = function.function_space() if self.params.expr2function == "assemble": # Compute average values of expr for each cell and place in a DG0 space test = TestFunction(space) scale = 1.0 / CellVolume(space.mesh()) assemble(scale*inner(expr, test)*dx, tensor=function.vector()) return function elif self.params.expr2function == "project": # TODO: Avoid superfluous function creation with fenics-dev/1.5 by using: #project(expr, space, function=function) function.assign(project(expr, space)) return function elif self.params.expr2function == "interpolate": # TODO: Need interpolation with code generated from expr, waiting for uflacs work. function.interpolate(expr) # Currently only works if expr is a single Function return function else: error("No action selected, need to choose either assemble, project or interpolate.")
def stokes(self): P2 = VectorElement("CG", self.mesh.ufl_cell(), 2) P1 = FiniteElement("CG", self.mesh.ufl_cell(), 1) TH = P2 * P1 VQ = FunctionSpace(self.mesh, TH) mf = self.mf self.no_slip = Constant((0., 0)) self.topflow = Expression(("-x[0] * (x[0] - 1.0) * 6.0 * m", "0.0"), m=self.U_m, degree=2) bc0 = DirichletBC(VQ.sub(0), self.topflow, mf, self.bc_dict["top"]) bc1 = DirichletBC(VQ.sub(0), self.no_slip, mf, self.bc_dict["left"]) bc2 = DirichletBC(VQ.sub(0), self.no_slip, mf, self.bc_dict["bottom"]) bc3 = DirichletBC(VQ.sub(0), self.no_slip, mf, self.bc_dict["right"]) # bc4 = DirichletBC(VQ.sub(1), Constant(0), mf, self.bc_dict["top"]) bcs = [bc0, bc1, bc2, bc3] vup = TestFunction(VQ) up = TrialFunction(VQ) # the solution will be in here: up_ = Function(VQ) u, p = split(up) # Trial vu, vp = split(vup) # Test u_, p_ = split(up_) # Function holding the solution F = self.mu*inner(grad(vu), grad(u))*dx - inner(div(vu), p)*dx \ - inner(vp, div(u))*dx + dot(self.g*self.rho, vu)*dx solve(lhs(F) == rhs(F), up_, bcs=bcs) self.u_.assign(project(u_, self.V)) self.p_.assign(project(p_, self.Q)) return
def les_setup(u_, mesh, Smagorinsky, CG1Function, nut_krylov_solver, bcs, **NS_namespace): """ Set up for solving Smagorinsky-Lilly LES model. """ DG = FunctionSpace(mesh, "DG", 0) CG1 = FunctionSpace(mesh, "CG", 1) # Compute cell size and put in delta dim = mesh.geometry().dim() delta = Function(DG) delta.vector().zero() delta.vector().set_local( assemble(TestFunction(DG) * dx).array()**(1. / dim)) delta.vector().apply('insert') # Set up Smagorinsky form Sij = sym(grad(u_)) magS = sqrt(2 * inner(Sij, Sij)) nut_form = Smagorinsky['Cs']**2 * delta**2 * magS bcs_nut = derived_bcs(CG1, bcs['u0'], u_) nut_ = CG1Function(nut_form, mesh, method=nut_krylov_solver, bcs=bcs_nut, bounded=True, name="nut") return dict(Sij=Sij, nut_=nut_, delta=delta, bcs_nut=bcs_nut)
def solve(self, mesh, num=5): """ Solve for num eigenvalues based on the mesh. """ # conforming elements V = FunctionSpace(mesh, "CG", self.degree) u = TrialFunction(V) v = TestFunction(V) # weak formulation a = inner(grad(u), grad(v)) * dx b = u * v * ds A = PETScMatrix() B = PETScMatrix() A = assemble(a, tensor=A) B = assemble(b, tensor=B) # find eigenvalues eigensolver = SLEPcEigenSolver(A, B) eigensolver.parameters["spectral_transform"] = "shift-and-invert" eigensolver.parameters["problem_type"] = "gen_hermitian" eigensolver.parameters["spectrum"] = "smallest real" eigensolver.parameters["spectral_shift"] = 1.0E-10 eigensolver.solve(num + 1) # extract solutions lst = [ eigensolver.get_eigenpair(i) for i in range(1, eigensolver.get_number_converged()) ] for k in range(len(lst)): u = Function(V) u.vector()[:] = lst[k][2] lst[k] = (lst[k][0], u) # pair (eigenvalue,eigenfunction) return np.array(lst)
def eigenvalues(V, bcs): # Define the bilinear forms on the right and the left hand sides u = TrialFunction(V) v = TestFunction(V) a = inner(curl(u), curl(v)) * dx b = inner(u, v) * dx # Assemble into PERSc matrices dummy = v[0] * dx A = PETScMatrix() assemble_system(a, dummy, bcs, A_tensor=A) B = PETScMatrix() assemble_system(b, dummy, bcs, A_tensor=B) [bc.zero(B) for bc in bcs] solver = SLEPcEigenSolver(A, B) solver.parameters["solver"] = "krylov-schur" solver.parameters["problem_type"] = "gen_hermitian" solver.parameters["spectrum"] = "target magnitude" solver.parameters["spectral_transform"] = "shift-and-invert" solver.parameters["spectral_shift"] = 5.5 neigs = 12 solver.solve(neigs) # Return the computed eigenvalues in a sorted array computed_eigenvalues = [] for i in range(min(neigs, solver.get_number_converged())): r, _ = solver.get_eigenvalue(i) # ignore the imaginary part computed_eigenvalues.append(r) return np.sort(np.array(computed_eigenvalues))
def test_local_assembler_1D(): mesh = UnitIntervalMesh(MPI.comm_world, 20) V = FunctionSpace(mesh, 'CG', 1) u = TrialFunction(V) v = TestFunction(V) c = Cell(mesh, 0) a_scalar = Constant(1) * dx(domain=mesh) a_vector = v * dx a_matrix = u * v * dx A_scalar = assemble_local(a_scalar, c) A_vector = assemble_local(a_vector, c) A_matrix = assemble_local(a_matrix, c) assert isinstance(A_scalar, float) assert numpy.isclose(A_scalar, 0.05) assert isinstance(A_vector, numpy.ndarray) assert A_vector.shape == (2, ) assert numpy.isclose(A_vector[0], 0.025) assert numpy.isclose(A_vector[1], 0.025) assert isinstance(A_matrix, numpy.ndarray) assert A_matrix.shape == (2, 2) assert numpy.isclose(A_matrix[0, 0], 1 / 60) assert numpy.isclose(A_matrix[0, 1], 1 / 120) assert numpy.isclose(A_matrix[1, 0], 1 / 120) assert numpy.isclose(A_matrix[1, 1], 1 / 60)
def __init__(self, form, mesh, bcs=[], name="CG1", method={}, bounded=False): solver_type = method.get('solver_type', 'cg') preconditioner_type = method.get('preconditioner_type', 'default') solver_method = method.get('method', 'default') self.bounded = bounded Space = FunctionSpace(mesh, "CG", 1) OasisFunction.__init__(self, form, Space, bcs=bcs, name=name, method=solver_method, solver_type=solver_type, preconditioner_type=preconditioner_type) if solver_method.lower() == "weightedaverage": from fenicstools import compiled_gradient_module DG = FunctionSpace(mesh, 'DG', 0) self.A = assemble( TrialFunction(DG) * self.test * dx()) # Cannot use cache. Matrix will be modified self.dg = dg = Function(DG) compiled_gradient_module.compute_DG0_to_CG_weight_matrix( self.A, dg) self.bf_dg = inner(form, TestFunction(DG)) * dx()
def test_local_assembler_on_facet_integrals(): mesh = UnitSquareMesh(MPI.comm_world, 4, 4, 'right') Vdgt = FunctionSpace(mesh, 'DGT', 1) v = TestFunction(Vdgt) x = SpatialCoordinate(mesh) w = (1.0 + x[0]**2.2 + 1. / (0.1 + x[1]**3)) * 300 # Define form that tests that the correct + and - values are used L = w('-') * v('+') * dS # Compile form. This is collective L = Form(L) # Get global cell 10. This will return a cell only on one of the # processes c = get_cell_at(mesh, 5 / 12, 1 / 3, 0) if c: # Assemble locally on the selected cell b_e = assemble_local(L, c) # Compare to values from phonyx (fully independent # implementation) b_phonyx = numpy.array( [266.55210302, 266.55210302, 365.49000122, 365.49000122, 0.0, 0.0]) error = sum((b_e - b_phonyx)**2)**0.5 error = float(error) # MPI.max does strange things to numpy.float64 else: error = 0.0 error = MPI.max(MPI.comm_world, float(error)) assert error < 1e-8
def __init__(self, ui, time_step_method, rho, mu, u, p0, dt, bcs, f, my_dx): super(TentativeVelocityProblem, self).__init__() W = ui.function_space() v = TestFunction(W) self.bcs = bcs r = SpatialCoordinate(ui.function_space().mesh())[0] def me(uu, ff): return _momentum_equation(uu, v, p0, ff, rho, mu, my_dx) self.F0 = rho * dot(ui - u[0], v) / dt * 2 * pi * r * my_dx if time_step_method == "forward euler": self.F0 += me(u[0], f[0]) elif time_step_method == "backward euler": self.F0 += me(ui, f[1]) else: assert ( time_step_method == "crank-nicolson" ), "Unknown time stepper '{}'".format( time_step_method ) self.F0 += 0.5 * (me(u[0], f[0]) + me(ui, f[1])) self.jacobian = derivative(self.F0, ui) self.reset_sparsity = True return
def test_krylov_solver_norm_type(): """Check setting of norm type used in testing for convergence by PETScKrylovSolver """ norm_type = (PETScKrylovSolver.norm_type.default_norm, PETScKrylovSolver.norm_type.natural, PETScKrylovSolver.norm_type.preconditioned, PETScKrylovSolver.norm_type.none, PETScKrylovSolver.norm_type.unpreconditioned) for norm in norm_type: # Solve a system of equations mesh = UnitSquareMesh(4, 4) V = FunctionSpace(mesh, "Lagrange", 1) u, v = TrialFunction(V), TestFunction(V) a = u * v * dx L = Constant(1.0) * v * dx A, b = assemble(a), assemble(L) solver = PETScKrylovSolver("cg") solver.parameters["maximum_iterations"] = 2 solver.parameters["error_on_nonconvergence"] = False solver.set_norm_type(norm) solver.set_operator(A) solver.solve(b.copy(), b) solver.get_norm_type() if norm is not PETScKrylovSolver.norm_type.default_norm: assert solver.get_norm_type() == norm
def df_dlmbda(self, u, lmbda): v = TestFunction(self.V) ufun = Function(self.V) ufun.vector()[:] = u out = -assemble(exp(ufun) * v * dx) self.bc.apply(out) return out
def test_krylov_solver_options_prefix(pushpop_parameters): "Test set/get PETScKrylov solver prefix option" # Set backend parameters["linear_algebra_backend"] = "PETSc" # Prefix prefix = "test_foo_" # Create solver and set prefix solver = PETScKrylovSolver() solver.set_options_prefix(prefix) # Check prefix (pre solve) assert solver.get_options_prefix() == prefix # Solve a system of equations mesh = UnitSquareMesh(4, 4) V = FunctionSpace(mesh, "Lagrange", 1) u, v = TrialFunction(V), TestFunction(V) a, L = u * v * dx, Constant(1.0) * v * dx A, b = assemble(a), assemble(L) solver.set_operator(A) solver.solve(b.copy(), b) # Check prefix (post solve) assert solver.get_options_prefix() == prefix
def __init__(self, V, **kwargs): # Call parent ParametrizedProblem.__init__( self, os.path.join("test_eim_approximation_16_tempdir", expression_type, basis_generation, "mock_problem")) # Minimal subset of a ParametrizedDifferentialProblem self.V = V self._solution = Function(V) self.components = ["u", "s", "p"] # Parametrized function to be interpolated x = SpatialCoordinate(V.mesh()) mu = SymbolicParameters(self, V, (-1., -1.)) self.f00 = 1. / sqrt( pow(x[0] - mu[0], 2) + pow(x[1] - mu[1], 2) + 0.01) self.f01 = 1. / sqrt( pow(x[0] - mu[0], 4) + pow(x[1] - mu[1], 4) + 0.01) # Inner product f = TrialFunction(self.V) g = TestFunction(self.V) self.inner_product = assemble(inner(f, g) * dx) # Collapsed vector and space self.V0 = V.sub(0).collapse() self.V00 = V.sub(0).sub(0).collapse() self.V1 = V.sub(1).collapse()
def compute_norm(mesh, degree): "Solve on given mesh file and degree of function space." # Create function space V = FunctionSpace(mesh, "Lagrange", degree) # Define variational problem v = TestFunction(V) u = TrialFunction(V) f = Expression("sin(x[0])", degree=degree) g = Expression("x[0]*x[1]", degree=degree) a = inner(grad(u), grad(v)) * dx + inner(u, v) * dx L = inner(f, v) * dx - inner(g, v) * ds # Compute solution w = Function(V) solve(a == L, w, petsc_options={"ksp_type": "preonly", "pc_type": "lu"}) # # A, b = fem.assembling.assemble_system(a, L) # solver = PETScKrylovSolver(MPI.comm_world) # PETScOptions.set("ksp_type", "preonly") # PETScOptions.set("pc_type", "lu") # solver.set_from_options() # solver.set_operator(A) # solver.solve(w.vector(), b) # Return norm of solution vector return w.vector().norm(cpp.la.Norm.l2)