def subdomain_interpolate(pairs, V, reduce='last'): '''(f, chi), V -> Function fh in V such that fh|chi is f''' array = lambda f: f.vector().get_local() fs, chis = zip(*pairs) fs = np.column_stack([array(interpolate(f, V)) for f in fs]) x = np.column_stack([array(interpolate(Expression('x[%d]' % i, degree=1), V)) for i in range(V.mesh().geometry().dim())]) chis = [CompiledSubDomain(chi, tol=1E-10) for chi in chis] is_masked = np.column_stack([map(lambda xi, chi=chi: not chi.inside(xi, False), x) for chi in chis]) fs = mask.masked_array(fs, is_masked) if reduce == 'avg': values = np.mean(fs, axis=1) elif reduce == 'max': values = np.choose(np.argmax(fs, axis=1), fs.T) elif reduce == 'min': values = np.choose(np.argmin(fs, axis=1), fs.T) elif reduce == 'first': choice = [row.tolist().index(False) for row in is_masked] values = np.choose(choice, fs.T) elif reduce == 'last': choice = np.array([row[::-1].tolist().index(False) for row in is_masked], dtype=int) nsubs = len(chis) values = np.choose(nsubs-1-choice, fs.T) else: raise ValueError fh = Function(V) fh.vector().set_local(values) return fh
def les_setup(u_, mesh, dt, krylov_solvers, V, assemble_matrix, CG1Function, nut_krylov_solver, bcs, **NS_namespace): """ Set up for solving the Germano Dynamic LES model applying scale dependent Lagrangian Averaging. """ # The setup is 99% equal to DynamicLagrangian, hence use its les_setup dyn_dict = DynamicLagrangian.les_setup(**vars()) # Add scale dep specific parameters JQN = Function(dyn_dict["CG1"]) JQN.vector()[:] += 1E-32 JNN = Function(dyn_dict["CG1"]) JNN.vector()[:] += 1. dim = dyn_dict["dim"] CG1 = dyn_dict["CG1"] Qij = [Function(CG1) for i in range(dim * dim)] Nij = [Function(CG1) for i in range(dim * dim)] # Update and return dict dyn_dict.update(JQN=JQN, JNN=JNN, Qij=Qij, Nij=Nij) return dyn_dict
def test_save_and_read_function(tempdir): filename = os.path.join(tempdir, "function.h5") mesh = UnitSquareMesh(MPI.comm_world, 10, 10) Q = FunctionSpace(mesh, ("CG", 3)) F0 = Function(Q) F1 = Function(Q) def E(values, x): values[:, 0] = x[:, 0] F0.interpolate(E) # Save to HDF5 File hdf5_file = HDF5File(mesh.mpi_comm(), filename, "w") hdf5_file.write(F0, "/function") hdf5_file.close() # Read back from file hdf5_file = HDF5File(mesh.mpi_comm(), filename, "r") F1 = hdf5_file.read_function(Q, "/function") F0.vector().axpy(-1.0, F1.vector()) assert F0.vector().norm() < 1.0e-12 hdf5_file.close()
def test_save_and_checkpoint_vector(tempdir, encoding, fe_degree, fe_family, mesh_tdim, mesh_n): if invalid_config(encoding): pytest.skip("XDMF unsupported in current configuration") if invalid_fe(fe_family, fe_degree): pytest.skip("Trivial finite element") filename = os.path.join(tempdir, "u2_checkpoint.xdmf") mesh = mesh_factory(mesh_tdim, mesh_n) FE = VectorElement(fe_family, mesh.ufl_cell(), fe_degree) V = FunctionSpace(mesh, FE) u_in = Function(V) u_out = Function(V) if mesh.geometry.dim == 1: u_out.interpolate(Expression(("x[0]", ), degree=1)) elif mesh.geometry.dim == 2: u_out.interpolate(Expression(("x[0]*x[1]", "x[0]"), degree=2)) elif mesh.geometry.dim == 3: u_out.interpolate(Expression(("x[0]*x[1]", "x[0]", "x[2]"), degree=2)) with XDMFFile(mesh.mpi_comm(), filename, encoding=encoding) as file: file.write_checkpoint(u_out, "u_out", 0) with XDMFFile(mesh.mpi_comm(), filename) as file: u_in = file.read_checkpoint(V, "u_out", 0) u_in.vector().axpy(-1.0, u_out.vector()) assert u_in.vector().norm(cpp.la.Norm.l2) < 1.0e-12
def transfer_vertex_function(mesh_fine, mesh_foo_coarse, output=VertexFunction): ''' Assuming that mesh_fine is created by meshing around the mesh underlying mesh_foo_coarse this function interpolates the data from mesh_foo_coarse ''' assert isinstance(mesh_fine, EmbeddedMesh) mesh_fine = mesh_fine.mesh # FIXME: remove when EmbeddedMesh <: Mesh assert mesh_fine.topology().dim() == 1 and mesh_fine.geometry().dim() > 1 mesh = mesh_foo_coarse.mesh() assert mesh.topology().dim() == 1 and mesh.geometry().dim() > 1 # The strategy here is to interpolate into a CG1 function on mesh_fine # and then turn it to vertex function. NOTE: consider CG1 as function # for it is easier to get e.g. DG0 (midpoint values) out of it Vf = FunctionSpace(mesh_fine, 'CG', 1) assert mesh_foo_coarse.cpp_value_type() == 'double' assert mesh_foo_coarse.dim() == 0 mesh_coarse = mesh_foo_coarse.mesh() Vc = FunctionSpace(mesh, 'CG', 1) fc = Function(Vc) # Fill the data fc.vector().set_local(mesh_foo_coarse.array()[dof_to_vertex_map(Vc)]) fc.vector().apply('insert') ff = interpolate(fc, Vf) if output == Function: return ff # Combe back to vertex function vertex_foo = VertexFunction('double', mesh_fine, 0.0) vertex_foo.set_values(ff.vector().array()[vertex_to_dof_map(Vf)]) return vertex_foo
def test_taylor_hood_cube(): pytest.xfail("Problem with Mixed Function Spaces") meshc = UnitCubeMesh(MPI.comm_world, 2, 2, 2) meshf = UnitCubeMesh(MPI.comm_world, 3, 4, 5) Ve = VectorElement("CG", meshc.ufl_cell(), 2) Qe = FiniteElement("CG", meshc.ufl_cell(), 1) Ze = MixedElement([Ve, Qe]) Zc = FunctionSpace(meshc, Ze) Zf = FunctionSpace(meshf, Ze) z = Expression( ("x[0]*x[1]", "x[1]*x[2]", "x[2]*x[0]", "x[0] + 3*x[1] + x[2]"), degree=2) zc = interpolate(z, Zc) zf = interpolate(z, Zf) mat = PETScDMCollection.create_transfer_matrix(Zc, Zf) Zuc = Function(Zf) mat.mult(zc.vector(), Zuc.vector()) Zuc.vector().update_ghost_values() diff = Function(Zf) diff.assign(Zuc - zf) assert diff.vector().norm("l2") < 1.0e-12
def test_save_3d_tensor(tempdir, encoding): filename = os.path.join(tempdir, "u3t.xdmf") mesh = UnitCubeMesh(MPI.comm_world, 4, 4, 4) u = Function(TensorFunctionSpace(mesh, ("Lagrange", 2))) u.vector().set(1.0 + (1j if has_petsc_complex else 0)) with XDMFFile(mesh.mpi_comm(), filename, encoding=encoding) as file: file.write(u)
def test_save_and_read_function(tempdir): filename = os.path.join(tempdir, "function.h5") mesh = UnitSquareMesh(MPI.comm_world, 10, 10) Q = FunctionSpace(mesh, ("CG", 3)) F0 = Function(Q) F1 = Function(Q) @function.expression.numba_eval def expr_eval(values, x, cell_idx): values[:, 0] = x[:, 0] E = Expression(expr_eval) F0.interpolate(E) # Save to HDF5 File hdf5_file = HDF5File(mesh.mpi_comm(), filename, "w") hdf5_file.write(F0, "/function") hdf5_file.close() # Read back from file hdf5_file = HDF5File(mesh.mpi_comm(), filename, "r") F1 = hdf5_file.read_function(Q, "/function") F0.vector().axpy(-1.0, F1.vector()) assert F0.vector().norm(dolfin.cpp.la.Norm.l2) < 1.0e-12 hdf5_file.close()
def restart_conditions(spaces, loadables): # loadables[restart_time0][solution_name] = [(t0, Lt0)] # will load Lt0 # loadables[restart_time0][solution_name] = [(t0, Lt0), (t1, Lt1)] # will interpolate to restart_time functions = {} for t in loadables: functions[t] = dict() for solution_name in loadables[t]: assert len(loadables[t][solution_name]) in [1, 2] if len(loadables[t][solution_name]) == 1: f = loadables[t][solution_name][0][1]() elif len(loadables[t][solution_name]) == 2: # Interpolate t0, Lt0 = loadables[t][solution_name][0] t1, Lt1 = loadables[t][solution_name][1] assert t0 <= t <= t1 if Lt0.function is not None: # The copy-function raise a PETSc-error in parallel #f = Function(Lt0()) f0 = Lt0() f = Function(f0.function_space()) f.vector().axpy(1.0, f0.vector()) del f0 df = Lt1().vector() df.axpy(-1.0, f.vector()) f.vector().axpy((t - t0) / (t1 - t0), df) else: f0 = Lt0() f1 = Lt1() datatype = type(f0) if not issubclass(datatype, Iterable): f0 = [f0] f1 = [f1] f = [] for _f0, _f1 in zip(f0, f1): val = _f0 + (t - t0) / (t1 - t0) * (_f1 - _f0) f.append(val) if not issubclass(datatype, Iterable): f = f[0] else: f = datatype(f) if solution_name in spaces: space = spaces[solution_name] if space != f.function_space(): #from fenicstools import interpolate_nonmatching_mesh #f = interpolate_nonmatching_mesh(f, space) try: f = interpolate(f, space) except: f = project(f, space) functions[t][solution_name] = f return functions
def test_scalar_p1_scaled_mesh(): # Make coarse mesh smaller than fine mesh meshc = UnitCubeMesh(MPI.comm_world, 2, 2, 2) meshc.geometry.points *= 0.9 meshf = UnitCubeMesh(MPI.comm_world, 3, 4, 5) Vc = FunctionSpace(meshc, "CG", 1) Vf = FunctionSpace(meshf, "CG", 1) u = Expression("x[0] + 2*x[1] + 3*x[2]", degree=1) uc = interpolate(u, Vc) uf = interpolate(u, Vf) mat = PETScDMCollection.create_transfer_matrix(Vc, Vf).mat() Vuc = Function(Vf) mat.mult(uc.vector().vec(), Vuc.vector().vec()) diff = Vuc.vector() diff.vec().axpy(-1, uf.vector().vec()) assert diff.norm(Norm.l2) < 1.0e-12 # Now make coarse mesh larger than fine mesh meshc.geometry.points *= 1.5 uc = interpolate(u, Vc) mat = PETScDMCollection.create_transfer_matrix(Vc, Vf).mat() mat.mult(uc.vector().vec(), Vuc.vector().vec()) diff = Vuc.vector() diff.vec().axpy(-1, uf.vector().vec()) assert diff.norm(Norm.l2) < 1.0e-12
def make_function(V, coefs): '''A function in V with coefs''' f = Function(V) f.vector().set_local(coefs) # FIXME: parallel return f
def test_save_and_read_function_timeseries(tempdir): filename = os.path.join(tempdir, "function.h5") mesh = UnitSquareMesh(MPI.comm_world, 10, 10) Q = FunctionSpace(mesh, ("CG", 3)) F0 = Function(Q) F1 = Function(Q) t = 0.0 @function.expression.numba_eval def expr_eval(values, x, cell_idx): values[:, 0] = t * x[:, 0] E = Expression(expr_eval) F0.interpolate(E) # Save to HDF5 File hdf5_file = HDF5File(mesh.mpi_comm(), filename, "w") for t in range(10): F0.interpolate(E) hdf5_file.write(F0, "/function", t) hdf5_file.close() # Read back from file hdf5_file = HDF5File(mesh.mpi_comm(), filename, "r") for t in range(10): F1.interpolate(E) vec_name = "/function/vector_%d" % t F0 = hdf5_file.read_function(Q, vec_name) # timestamp = hdf5_file.attributes(vec_name)["timestamp"] # assert timestamp == t F0.vector().axpy(-1.0, F1.vector()) assert F0.vector().norm(cpp.la.Norm.l2) < 1.0e-12 hdf5_file.close()
def cyclic3D(u): """ Symmetrize with respect to (xyz) cycle. """ try: nrm = np.linalg.norm(u.vector()) V = u.function_space() assert V.mesh().topology().dim() == 3 mesh1 = Mesh(V.mesh()) mesh1.coordinates()[:, :] = mesh1.coordinates()[:, [1, 2, 0]] W1 = FunctionSpace(mesh1, 'CG', 1) # testing if symmetric bc = DirichletBC(V, 1, DomainBoundary()) test = Function(V) bc.apply(test.vector()) test = interpolate(Function(W1, test.vector()), V) assert max(test.vector()) - min(test.vector()) < 1.1 v1 = interpolate(Function(W1, u.vector()), V) mesh2 = Mesh(mesh1) mesh2.coordinates()[:, :] = mesh2.coordinates()[:, [1, 2, 0]] W2 = FunctionSpace(mesh2, 'CG', 1) v2 = interpolate(Function(W2, u.vector()), V) pr = project(u + v1 + v2) assert np.linalg.norm(pr.vector()) / nrm > 0.01 return pr except: print "Cyclic symmetrization failed!" return u
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 test_vector_p1_3d(): meshc = UnitCubeMesh(MPI.comm_world, 2, 3, 4) meshf = UnitCubeMesh(MPI.comm_world, 3, 4, 5) Vc = VectorFunctionSpace(meshc, ("CG", 1)) Vf = VectorFunctionSpace(meshf, ("CG", 1)) @function.expression.numba_eval def expr_eval(values, x, cell_idx): values[:, 0] = x[:, 0] + 2.0 * x[:, 1] values[:, 1] = 4.0 * x[:, 0] values[:, 2] = 3.0 * x[:, 2] + x[:, 0] u = Expression(expr_eval, shape=(3, )) uc = interpolate(u, Vc) uf = interpolate(u, Vf) mat = PETScDMCollection.create_transfer_matrix(Vc._cpp_object, Vf._cpp_object) Vuc = Function(Vf) mat.mult(uc.vector(), Vuc.vector()) diff = Vuc.vector() diff.axpy(-1, uf.vector()) assert diff.norm() < 1.0e-12
def test_taylor_hood_cube(): pytest.xfail("Problem with Mixed Function Spaces") meshc = UnitCubeMesh(MPI.comm_world, 2, 2, 2) meshf = UnitCubeMesh(MPI.comm_world, 3, 4, 5) Ve = VectorElement("CG", meshc.ufl_cell(), 2) Qe = FiniteElement("CG", meshc.ufl_cell(), 1) Ze = MixedElement([Ve, Qe]) Zc = FunctionSpace(meshc, Ze) Zf = FunctionSpace(meshf, Ze) @function.expression.numba_eval def expr_eval(values, x, cell_idx): values[:, 0] = x[:, 0] * x[:, 1] values[:, 1] = x[:, 1] * x[:, 2] values[:, 2] = x[:, 2] * x[:, 0] values[:, 3] = x[:, 0] + 3.0 * x[:, 1] + x[:, 2] z = Expression(expr_eval, shape=(4, )) zc = interpolate(z, Zc) zf = interpolate(z, Zf) mat = PETScDMCollection.create_transfer_matrix(Zc, Zf) Zuc = Function(Zf) mat.mult(zc.vector(), Zuc.vector()) Zuc.vector().update_ghost_values() diff = Function(Zf) diff.assign(Zuc - zf) assert diff.vector().norm("l2") < 1.0e-12
def cyclic3D(u): """ Symmetrize with respect to (xyz) cycle. """ try: nrm = np.linalg.norm(u.vector()) V = u.function_space() assert V.mesh().topology().dim() == 3 mesh1 = Mesh(V.mesh()) mesh1.coordinates()[:, :] = mesh1.coordinates()[:, [1, 2, 0]] W1 = FunctionSpace(mesh1, 'CG', 1) # testing if symmetric bc = DirichletBC(V, 1, DomainBoundary()) test = Function(V) bc.apply(test.vector()) test = interpolate(Function(W1, test.vector()), V) assert max(test.vector()) - min(test.vector()) < 1.1 v1 = interpolate(Function(W1, u.vector()), V) mesh2 = Mesh(mesh1) mesh2.coordinates()[:, :] = mesh2.coordinates()[:, [1, 2, 0]] W2 = FunctionSpace(mesh2, 'CG', 1) v2 = interpolate(Function(W2, u.vector()), V) pr = project(u+v1+v2) assert np.linalg.norm(pr.vector())/nrm > 0.01 return pr except: print "Cyclic symmetrization failed!" return u
def test_pointsource_matrix_second_constructor(mesh, point): """Tests point source when given different constructor PointSource(V1, V2, point, mag) with a matrix and when placed at a node for 1D, 2D and 3D. Global points given to constructor from rank 0 processor. Currently only implemented if V1=V2. """ V1 = FunctionSpace(mesh, "CG", 1) V2 = FunctionSpace(mesh, "CG", 1) rank = MPI.rank(mesh.mpi_comm()) u, v = TrialFunction(V1), TestFunction(V2) w = Function(V1) A = assemble(Constant(0.0)*u*v*dx) if rank == 0: ps = PointSource(V1, V2, point, 10.0) else: ps = PointSource(V1, V2, []) ps.apply(A) # Checks array sums to correct value a_sum = MPI.sum(mesh.mpi_comm(), np.sum(A.array())) assert round(a_sum - 10.0) == 0 # Checks point source is added to correct part of the array A.get_diagonal(w.vector()) v2d = vertex_to_dof_map(V1) for v in vertices(mesh): if near(v.midpoint().distance(point), 0.0): ind = v2d[v.index()] if ind < len(A.array()): assert np.round(w.vector()[ind] - 10.0) == 0
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 = KrylovSolver(solver_type, preconditioner_type) self.sol.parameters["preconditioner"]["structure"] = "same" self.sol.parameters["error_on_nonconvergence"] = False self.sol.parameters["monitor_convergence"] = False self.sol.parameters["report"] = False 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 les_setup(u_, mesh, dt, krylov_solvers, V, assemble_matrix, CG1Function, nut_krylov_solver, bcs, **NS_namespace): """ Set up for solving the Germano Dynamic LES model applying scale dependent Lagrangian Averaging. """ # The setup is 99% equal to DynamicLagrangian, hence use its les_setup dyn_dict = DynamicLagrangian.les_setup(**vars()) # Add scale dep specific parameters JQN = Function(dyn_dict["CG1"]) JQN.vector()[:] += 1E-32 JNN = Function(dyn_dict["CG1"]) JNN.vector()[:] += 1. dim = dyn_dict["dim"] CG1 = dyn_dict["CG1"] Qij = [Function(CG1) for i in range(dim * dim)] Nij = [Function(CG1) for i in range(dim * dim)] # Update and return dict dyn_dict.update(JQN=JQN, JNN=JNN, Qij=Qij, Nij=Nij) return dyn_dict
def test_interpolation_old(V, W, mesh): class F0(UserExpression): def eval(self, values, x): values[:, 0] = 1.0 class F1(UserExpression): def eval(self, values, x): values[:, 0] = 1.0 values[:, 1] = 1.0 values[:, 2] = 1.0 def value_shape(self): return (3, ) # Scalar interpolation f0 = F0(degree=0) f = Function(V) f = interpolate(f0, V) assert round(f.vector().norm(cpp.la.Norm.l1) - mesh.num_vertices(), 7) == 0 # Vector interpolation f1 = F1(degree=0) f = Function(W) f.interpolate(f1) assert round(f.vector().norm(cpp.la.Norm.l1) - 3 * mesh.num_vertices(), 7) == 0
def cell_chi(f, marker=1): ''' Let f be a facet function. Build a DG0 function which is such that cell connected to f == marker are 1 and are 0 otherwise. ''' assert f.mesh().topology().dim() == 2 assert f.dim() == 1 mesh = f.mesh() mesh.init(1, 2) f2c = mesh.topology()(1, 2) V = FunctionSpace(mesh, 'DG', 0) dm = V.dofmap() first, last = dm.ownership_range() n = last - first is_local = lambda i, f=first, l=last: f <= i + f < l chi = Function(V) values = chi.vector().get_local() for facet in SubsetIterator(f, marker): fi = facet.index() for c in f2c(fi): dofs = filter(is_local, dm.cell_dofs(c)) values[dofs] = 1. # Sync chi.vector().set_local(values) as_backend_type(chi.vector()).update_ghost_values() return chi
def test_pointsource_matrix_second_constructor(mesh, point): """Tests point source when given different constructor PointSource(V1, V2, point, mag) with a matrix and when placed at a node for 1D, 2D and 3D. Global points given to constructor from rank 0 processor. Currently only implemented if V1=V2. """ V1 = FunctionSpace(mesh, "CG", 1) V2 = FunctionSpace(mesh, "CG", 1) rank = MPI.rank(mesh.mpi_comm()) u, v = TrialFunction(V1), TestFunction(V2) w = Function(V1) A = assemble(Constant(0.0) * u * v * dx) if rank == 0: ps = PointSource(V1, V2, point, 10.0) else: ps = PointSource(V1, V2, []) ps.apply(A) # Checks array sums to correct value a_sum = MPI.sum(mesh.mpi_comm(), np.sum(A.array())) assert round(a_sum - 10.0) == 0 # Checks point source is added to correct part of the array A.get_diagonal(w.vector()) v2d = vertex_to_dof_map(V1) for v in vertices(mesh): if near(v.midpoint().distance(point), 0.0): ind = v2d[v.index()] if ind < len(A.array()): assert np.round(w.vector()[ind] - 10.0) == 0
def ic_eval(self): exact_solution_expression.t = 0. solution = Function(*exact_solution.vector().get_local().shape) solution.vector()[:] = project(exact_solution_expression, V).vector().get_local() solution_array = solution.vector() solution_array[[0, 1, min_dof_0_2pi, max_dof_0_2pi]] = solution_array[[min_dof_0_2pi, max_dof_0_2pi, 0, 1]] return solution
def basis_functions_matrix_mul_online_matrix(basis_functions_matrix, online_matrix, BasisFunctionsMatrixType): space = basis_functions_matrix.space assert isinstance(space, FunctionSpace) output = BasisFunctionsMatrixType(space) assert isinstance(online_matrix.M, dict) j = 0 for col_component_name in basis_functions_matrix._components_name: for _ in range(online_matrix.M[col_component_name]): assert len(online_matrix[:, j]) == sum( len(functions_list) for functions_list in basis_functions_matrix._components) output_j = Function(space) i = 0 for row_component_name in basis_functions_matrix._components_name: for fun_i in basis_functions_matrix._components[ row_component_name]: output_j.vector().add_local(fun_i.vector().get_local() * online_matrix[i, j]) i += 1 output_j.vector().apply("add") output.enrich(output_j) j += 1 return output
def dmd(functions, dmd_object, dt=1, modal_analysis=[]): ''' Dynamic mode decomposition: J. Fluid Mech. (2010), vol. 656, pp. 5-28 (idea) On dynamic mode decomposition: theory and application; Tu, J. H et al. (implement) DMD of (ordered, dt-equispaced) snapshots. dmd_object is the configured DMDBase instance. ''' assert all(isinstance(f, Function) for f in functions) # Wrap for pydmd X = np.array([f.vector().get_local() for f in functions]).T # Rely on pydmd dmd_object.fit(X) dmd_object.original_time['dt'] = dt V = functions[0].function_space() eigs = dmd_object.eigs modes = [] # NOTE: unlike with pod where the basis was only real here the # modes might have complex components so ... for x in dmd_object.modes.T: f_real = Function(V) f_real.vector().set_local(x.real) f_imag = Function(V) f_imag.vector().set_local(x.imag) modes.append(ComplexFunction(f_real, f_imag)) if len(modal_analysis): return eigs, modes, dmd_object.dynamics[modal_analysis] return eigs, modes
def step(self, u1, u0, t, dt, tol=1.0e-10, verbose=True, maxiter=1000, krylov='gmres', preconditioner='ilu' ): v = TestFunction(self.problem.V) L0, b0 = self.problem.get_system(t) L1, b1 = self.problem.get_system(t + dt) Lu0 = Function(self.problem.V) L0.mult(u0.vector(), Lu0.vector()) rhs = assemble(u0 * v * self.problem.dx_multiplier * self.problem.dx) rhs.axpy(-dt * 0.5, Lu0.vector()) rhs.axpy(+dt * 0.5, b0 + b1) A = self.M + 0.5 * dt * L1 # Apply boundary conditions. for bc in self.problem.get_bcs(t + dt): bc.apply(A, rhs) solver = KrylovSolver(krylov, preconditioner) solver.parameters['relative_tolerance'] = tol solver.parameters['absolute_tolerance'] = 0.0 solver.parameters['maximum_iterations'] = maxiter solver.parameters['monitor_convergence'] = verbose solver.set_operator(A) solver.solve(u1.vector(), rhs) return
def direct_solve(A, b, W, which='umfpack'): '''inv(A)*b''' print 'Solving system of size %d' % A.size(0) # NOTE: umfpack sometimes blows up, MUMPS produces crap more often than not if isinstance(W, list): wh = ii_Function(W) LUSolver(which).solve(A, wh.vector(), b) print('|b-Ax| from direct solver', (A * wh.vector() - b).norm('linf')) return wh wh = Function(W) LUSolver(which).solve(A, wh.vector(), b) print('|b-Ax| from direct solver', (A * wh.vector() - b).norm('linf')) if isinstance( W.ufl_element(), (ufl.VectorElement, ufl.TensorElement)) or W.num_sub_spaces() == 1: return ii_Function([W], [wh]) # Now get components Wblock = serialize_mixed_space(W) wh = wh.split(deepcopy=True) return ii_Function(Wblock, wh)
def step(self, u1, u0, t, dt, tol=1.0e-10, maxiter=100, verbose=True ): v = TestFunction(self.problem.V) L, b = self.problem.get_system(t) Lu0 = Function(self.problem.V) L.mult(u0.vector(), Lu0.vector()) rhs = assemble(u0 * v * self.problem.dx_multiplier * self.problem.dx) rhs.axpy(dt, -Lu0.vector() + b) A = self.M # Apply boundary conditions. for bc in self.problem.get_bcs(t + dt): bc.apply(A, rhs) # Both Jacobi-and AMG-preconditioners are order-optimal for the mass # matrix, Jacobi is a little more lightweight. solver = KrylovSolver('cg', 'jacobi') solver.parameters['relative_tolerance'] = tol solver.parameters['absolute_tolerance'] = 0.0 solver.parameters['maximum_iterations'] = maxiter solver.parameters['monitor_convergence'] = verbose solver.set_operator(A) solver.solve(u1.vector(), rhs) return
def test_WeightedGradient(): mesh = UnitSquareMesh(4, 4) V = FunctionSpace(mesh, 'CG', 1) u = interpolate(Expression("x[0]+2*x[1]"), V) wx = weighted_gradient_matrix(mesh, 0) du = Function(V) du.vector()[:] = wx * u.vector() nose.tools.assert_almost_equal(du.vector().min(), 1.) wy = weighted_gradient_matrix(mesh, 1) du.vector()[:] = wy * u.vector() nose.tools.assert_almost_equal(du.vector().min(), 2.) mesh = UnitCubeMesh(4, 4, 4) V = FunctionSpace(mesh, 'CG', 1) u = interpolate(Expression("x[0]+2*x[1]+3*x[2]"), V) du = Function(V) wx = weighted_gradient_matrix(mesh, (0, 1, 2)) du.vector()[:] = wx[0] * u.vector() nose.tools.assert_almost_equal(du.vector().min(), 1.) du.vector()[:] = wx[1] * u.vector() nose.tools.assert_almost_equal(du.vector().min(), 2.) du.vector()[:] = wx[2] * u.vector() nose.tools.assert_almost_equal(du.vector().min(), 3.) #if __name__ == '__main__': #nose.run(defaultTest=__name__)
def test_save_and_checkpoint_scalar(tempdir, encoding, fe_degree, fe_family, mesh_tdim, mesh_n): if invalid_fe(fe_family, fe_degree): pytest.skip("Trivial finite element") filename = os.path.join(tempdir, "u1_checkpoint.xdmf") mesh = mesh_factory(mesh_tdim, mesh_n) FE = FiniteElement(fe_family, mesh.ufl_cell(), fe_degree) V = FunctionSpace(mesh, FE) u_in = Function(V) u_out = Function(V) if has_petsc_complex: u_out.interpolate(Expression("x[0] + j*x[0]", degree=1)) else: u_out.interpolate(Expression("x[0]", degree=1)) with XDMFFile(mesh.mpi_comm(), filename, encoding=encoding) as file: file.write_checkpoint(u_out, "u_out", 0) with XDMFFile(mesh.mpi_comm(), filename) as file: u_in = file.read_checkpoint(V, "u_out", 0) u_in.vector().axpy(-1.0, u_out.vector()) assert u_in.vector().norm(cpp.la.Norm.l2) < 1.0e-12
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 curvilinear_coordinate_1d(mb, p0=0, function=None): "Returns parametrization of a curve" # edge-to-vertex connectivity EE = np.zeros((mb.num_cells(), mb.num_vertices()), dtype=bool) for e in edges(mb): EE[e.index(), e.entities(0)] = True # vertex-to-vertex connectivity (via edges) PP = EE.T @ EE np.fill_diagonal(PP, False) mmap = -np.ones(PP.shape[0], dtype=int) # order vertices mmap[0] = p0 for k in range(PP.shape[0] - 1): neig = np.where(PP[mmap[k], :])[0] mmap[k + 1] = neig[1] if neig[0] in mmap else neig[0] # cumulative length of edges l = np.linalg.norm(np.diff(mb.coordinates()[mmap, :], axis=0), axis=1) s = np.r_[0, np.cumsum(l)] if function is None: P1e = FiniteElement("CG", mb.ufl_cell(), 1) Ve = FunctionSpace(mb, P1e) function = Function(Ve) function.vector()[vertex_to_dof_map(Ve)[mmap]] = s return function else: Ve = function.function_space() function.vector()[vertex_to_dof_map(Ve)[mmap]] = s
class WSS(Field): def add_fields(self): return [DynamicViscosity()] def before_first_compute(self, get): u = get("Velocity") V = u.function_space() spaces = SpacePool(V.mesh()) degree = V.ufl_element().degree() if degree <= 1: Q = spaces.get_grad_space(V, shape=(spaces.d,)) else: if degree > 2: cbc_warning("Unable to handle higher order WSS space. Using CG1.") Q = spaces.get_space(1,1) Q_boundary = spaces.get_space(Q.ufl_element().degree(), 1, boundary=True) self.v = TestFunction(Q) self.tau = Function(Q, name="WSS_full") self.tau_boundary = Function(Q_boundary, name="WSS") local_dofmapping = mesh_to_boundarymesh_dofmap(spaces.BoundaryMesh, Q, Q_boundary) self._keys = np.array(local_dofmapping.keys(), dtype=np.intc) self._values = np.array(local_dofmapping.values(), dtype=np.intc) self._temp_array = np.zeros(len(self._keys), dtype=np.float_) Mb = assemble(inner(TestFunction(Q_boundary), TrialFunction(Q_boundary))*dx) self.solver = create_solver("gmres", "jacobi") self.solver.set_operator(Mb) self.b = Function(Q_boundary).vector() self._n = FacetNormal(V.mesh()) def compute(self, get): u = get("Velocity") mu = get("DynamicViscosity") if isinstance(mu, (float, int)): mu = Constant(mu) n = self._n T = -mu*dot((grad(u) + grad(u).T), n) Tn = dot(T, n) Tt = T - Tn*n tau_form = dot(self.v, Tt)*ds() assemble(tau_form, tensor=self.tau.vector()) #self.b[self._keys] = self.tau.vector()[self._values] # FIXME: This is not safe!!! get_set_vector(self.b, self._keys, self.tau.vector(), self._values, self._temp_array) # Ensure proper scaling self.solver.solve(self.tau_boundary.vector(), self.b) return self.tau_boundary
def cm1dvelocity(img: np.array, vel: np.array, alpha0: float, alpha1: float) -> np.array: """Computes the source for a L2-H1 mass conserving flow for a 1D image sequence and a given velocity. Takes a one-dimensional image sequence and a velocity, and returns a minimiser of the L2-H1 mass conservation functional with spatio-temporal regularisation. Args: img (np.array): A 1D image sequence of shape (m, n), where m is the number of time steps and n is the number of pixels. vel (np.array): A 1D image sequence of shape (m, n). alpha0 (float): The spatial regularisation parameter. alpha1 (float): The temporal regularisation parameter. Returns: k: A source array of shape (m, n). """ # Create mesh. [m, n] = img.shape mesh = UnitSquareMesh(m - 1, n - 1) # Define function space and functions. V = FunctionSpace(mesh, 'CG', 1) k = TrialFunction(V) w = TestFunction(V) # Convert image to function. f = Function(V) f.vector()[:] = dh.img2funvec(img) # Convert velocity to function. v = Function(V) v.vector()[:] = dh.img2funvec(vel) # Define derivatives of data. ft = Function(V) ftv = np.diff(img, axis=0) * (m - 1) ftv = np.concatenate((ftv, ftv[-1, :].reshape(1, n)), axis=0) ft.vector()[:] = dh.img2funvec(ftv) fx = Function(V) fxv = np.gradient(img, 1 / (n - 1), axis=1) fx.vector()[:] = dh.img2funvec(fxv) # Define weak formulation. A = k * w * dx + alpha0 * k.dx(1) * w.dx(1) * dx + alpha1 * k.dx(0) * w.dx( 0) * dx b = (ft + v.dx(1) * f + v * fx) * w * dx # Compute solution. k = Function(V) solve(A == b, k) # Convert back to array. k = dh.funvec2img(k.vector().get_local(), m, n) return k
def dense_initial_guess(): solution = Function(*exact_solution.vector().get_local().shape) solution.vector()[:] = sparse_initial_guess().vector().get_local() solution_array = solution.vector() solution_array[[0, 1, min_dof_0_2pi, max_dof_0_2pi]] = solution_array[[ min_dof_0_2pi, max_dof_0_2pi, 0, 1 ]] return solution
def test_WeightedGradient(V2): expr = "+".join(["%d*x[%d]" % (i+1,i) for i in range(2)]) u = interpolate(Expression(expr, degree=3), V2) du = Function(V2) wx = weighted_gradient_matrix(V2.mesh(), tuple(range(2))) for i in range(2): du.vector()[:] = wx[i] * u.vector() assert round(du.vector().min() - (i+1), 7) == 0
def apply_sqrtM(self, vect): """Compute M^{1/2}.vect from Vector() vect""" sqrtMv = Function(self.Vm) for ii in range(self.Vm.dim()): r, c, rx, cx = self.eigsolM.get_eigenpair(ii) RX = Vector(rx) sqrtMv.vector().axpy(np.sqrt(r)*np.dot(rx.array(), vect.array()), RX) return sqrtMv.vector()
def test_WeightedGradient(V2): expr = "+".join(["%d*x[%d]" % (i+1,i) for i in range(2)]) u = interpolate(Expression(expr, degree=3), V2) du = Function(V2) wx = weighted_gradient_matrix(V2.mesh(), tuple(range(2))) for i in range(2): du.vector()[:] = wx[i] * u.vector() assert round(du.vector().min() - (i+1), 7) == 0
def assert_backend(self, r, j, problem_wrapper, result_backend): result_builtin = self.evaluate_builtin(r, j, problem_wrapper) error = Function(self.V) error.vector().add_local(+ result_backend.vector().get_local()) error.vector().add_local(- result_builtin.vector().get_local()) error.vector().apply("add") relative_error = error.vector().norm("l2")/result_builtin.vector().norm("l2") assert isclose(relative_error, 0., atol=1e-12)
def test_save_2d_vector(tempdir, encoding): filename = os.path.join(tempdir, "u_2dv.xdmf") mesh = UnitSquareMesh(MPI.comm_world, 16, 16) V = VectorFunctionSpace(mesh, ("Lagrange", 2)) u = Function(V) u.vector().set(1.0 + (1j if has_petsc_complex else 0)) with XDMFFile(mesh.mpi_comm(), filename, encoding=encoding) as file: file.write(u)
def test_WeightedGradient(V, mesh): dim = mesh.topology().dim() expr = "+".join(["%d*x[%d]" % (i+1,i) for i in range(dim)]) u = interpolate(Expression(expr), V) du = Function(V) wx = weighted_gradient_matrix(mesh, tuple(range(dim))) for i in range(dim): du.vector()[:] = wx[i] * u.vector() assert round(du.vector().min() - (i+1), 7) == 0
def vector2Function(x,Vh, **kwargs): """ Wrap a finite element vector :code:`x` into a finite element function in the space :code:`Vh`. :code:`kwargs` is optional keywords arguments to be passed to the construction of a dolfin :code:`Function`. """ fun = Function(Vh,**kwargs) fun.vector().zero() fun.vector().axpy(1., x) return fun
def les_setup(u_, mesh, KineticEnergySGS, assemble_matrix, CG1Function, nut_krylov_solver, bcs, **NS_namespace): """ Set up for solving the Kinetic Energy SGS-model. """ DG = FunctionSpace(mesh, "DG", 0) CG1 = FunctionSpace(mesh, "CG", 1) dim = mesh.geometry().dim() delta = Function(DG) delta.vector().zero() delta.vector().axpy(1.0, assemble(TestFunction(DG)*dx)) delta.vector().set_local(delta.vector().array()**(1./dim)) delta.vector().apply('insert') Ck = KineticEnergySGS["Ck"] ksgs = interpolate(Constant(1E-7), CG1) bc_ksgs = DirichletBC(CG1, 0, "on_boundary") A_mass = assemble_matrix(TrialFunction(CG1)*TestFunction(CG1)*dx) nut_form = Ck * delta * sqrt(ksgs) bcs_nut = derived_bcs(CG1, bcs['u0'], u_) nut_ = CG1Function(nut_form, mesh, method=nut_krylov_solver, bcs=bcs_nut, bounded=True, name="nut") At = Matrix() bt = Vector(nut_.vector()) ksgs_sol = KrylovSolver("bicgstab", "additive_schwarz") ksgs_sol.parameters["preconditioner"]["structure"] = "same_nonzero_pattern" ksgs_sol.parameters["error_on_nonconvergence"] = False ksgs_sol.parameters["monitor_convergence"] = False ksgs_sol.parameters["report"] = False del NS_namespace return locals()
def assemble_solution(self, t): # returns Womersley sol for time t if self.tc is not None: self.tc.start('assembleSol') sol = Function(self.solutionSpace) dofs2 = self.solutionSpace.sub(2).dofmap().dofs() # gives field of indices corresponding to z axis sol.assign(Constant(("0.0", "0.0", "0.0"))) # QQ not needed sol.vector()[dofs2] += self.factor * self.bessel_parabolic.vector().array() # parabolic part of sol for idx in range(8): # add modes of Womersley sol sol.vector()[dofs2] += self.factor * cos(self.coefs_exp[idx] * pi * t) * self.bessel_real[idx].vector().array() sol.vector()[dofs2] += self.factor * -sin(self.coefs_exp[idx] * pi * t) * self.bessel_complex[idx].vector().array() if self.tc is not None: self.tc.end('assembleSol') return sol
def test1(): # setup meshes P = 0.3 ref1 = 4 ref2 = 14 mesh1 = UnitSquare(2, 2) mesh2 = UnitSquare(2, 2) # refinement loops for level in range(ref1): mesh1 = refine(mesh1) for level in range(ref2): # mark and refine markers = CellFunction("bool", mesh2) markers.set_all(False) # randomly refine mesh for i in range(mesh2.num_cells()): if random() <= P: markers[i] = True mesh2 = refine(mesh2, markers) # create joint meshes mesh1j, parents1 = create_joint_mesh([mesh2], mesh1) mesh2j, parents2 = create_joint_mesh([mesh1], mesh2) # evaluate errors joint meshes ex1 = Expression("sin(2*A*x[0])*sin(2*A*x[1])", A=10) V1 = FunctionSpace(mesh1, "CG", 1) V2 = FunctionSpace(mesh2, "CG", 1) V1j = FunctionSpace(mesh1j, "CG", 1) V2j = FunctionSpace(mesh2j, "CG", 1) f1 = interpolate(ex1, V1) f2 = interpolate(ex1, V2) # interpolate on respective joint meshes f1j = interpolate(f1, V1j) f2j = interpolate(f2, V2j) f1j1 = interpolate(f1j, V1) f2j2 = interpolate(f2j, V2) # evaluate error with regard to original mesh e1 = Function(V1) e2 = Function(V2) e1.vector()[:] = f1.vector() - f1j1.vector() e2.vector()[:] = f2.vector() - f2j2.vector() print "error on V1:", norm(e1, "L2") print "error on V2:", norm(e2, "L2") plot(f1j, title="f1j") plot(f2j, title="f2j") plot(mesh1, title="mesh1") plot(mesh2, title="mesh2") plot(mesh1j, title="joint mesh from mesh1") plot(mesh2j, title="joint mesh from mesh2", interactive=True)
def comp_cont_error(v, fpbc, Q): """Compute the L2 norm of the residual of the continuity equation Bv = g """ q = TrialFunction(Q) divv = assemble(q*div(v)*dx) conRhs = Function(Q) conRhs.vector().set_local(fpbc) ContEr = norm(conRhs.vector() - divv) return ContEr
def symmetrize(u, d, sym): """ Symmetrize function u. """ if len(d) == 3: # three dimensions -> cycle XYZ return cyclic3D(u) elif len(d) >= 4: # four dimensions -> rotations in 2D return rotational(u, d[-1]) nrm = np.linalg.norm(u.vector()) V = u.function_space() mesh = Mesh(V.mesh()) # test if domain is symmetric using function equal 0 inside, 1 on boundary # extrapolation will force large values if not symmetric since the flipped # domain is different bc = DirichletBC(V, 1, DomainBoundary()) test = Function(V) bc.apply(test.vector()) if len(d) == 2: # two dimensions given: swap dimensions mesh.coordinates()[:, d] = mesh.coordinates()[:, d[::-1]] else: # one dimension given: reflect mesh.coordinates()[:, d[0]] *= -1 # FIXME functionspace takes a long time to construct, maybe copy? W = FunctionSpace(mesh, 'CG', 1) try: # testing test = interpolate(Function(W, test.vector()), V) # max-min should be around 1 if domain was symmetric # may be slightly above due to boundary approximation assert max(test.vector()) - min(test.vector()) < 1.1 v = interpolate(Function(W, u.vector()), V) if sym: # symmetric pr = project(u+v) else: # antisymmetric pr = project(u-v) # small solution norm most likely means that symmetrization gives # trivial function assert np.linalg.norm(pr.vector())/nrm > 0.01 return pr except: # symmetrization failed for some reason print "Symmetrization " + str(d) + " failed!" return u
def solve_alpha_M_beta_F(self, alpha, beta, b, t): """Solve :code:`alpha * M * u + beta * F(u, t) = b` with Dirichlet conditions. """ matrix = alpha * self.M + beta * self.A # See above for float conversion right_hand_side = -float(beta) * self.b.copy() if b: right_hand_side += b for bc in self.dirichlet_bcs: bc.apply(matrix, right_hand_side) # TODO proper preconditioner for convection if self.convection: # Use HYPRE-Euclid instead of ILU for parallel computation. # However, this PC sometimes fails. # solver = KrylovSolver('gmres', 'hypre_euclid') # Fallback: solver = LUSolver() else: solver = KrylovSolver("gmres", "hypre_amg") solver.parameters["relative_tolerance"] = 1.0e-13 solver.parameters["absolute_tolerance"] = 0.0 solver.parameters["maximum_iterations"] = 100 solver.parameters["monitor_convergence"] = True solver.set_operator(matrix) u = Function(self.Q) solver.solve(u.vector(), right_hand_side) return u
def __setstate__(self, d): """pickling restore""" # mesh verts = d['coordinates'] elems = d['cells'] dim = verts.shape[1] mesh = Mesh() ME = MeshEditor() ME.open(mesh, dim, dim) ME.init_vertices(verts.shape[0]) ME.init_cells(elems.shape[0]) for i, v in enumerate(verts): ME.add_vertex(i, v[0], v[1]) for i, c in enumerate(elems): ME.add_cell(i, c[0], c[1], c[2]) ME.close() # function space if d['num_subspaces'] > 1: V = VectorFunctionSpace(mesh, d['family'], d['degree']) else: V = FunctionSpace(mesh, d['family'], d['degree']) # vector v = Function(V) v.vector()[:] = d['array'] self._fefunc = v
def __init__(self, V): u = Function(V) u.assign(Constant('1.0')) self.one = u.vector() self.Mdiag = self.one.copy() self.Mdiag2 = self.one.copy() self.invMdiag = self.one.copy()
def PETScToNLiter(x,FS): n = len(FS) IS = common.IndexSet(FS) u = {} for i in range(n): v = Function(FS.values()[i]) v.vector()[:] = x.getSubVector(IS.values()[i]).array if FS.keys()[i] == 'Pressure': ones = Function(FS['Pressure']) ones.vector()[:] = 1 vv = Function(FS['Pressure']) vv.vector()[:] = v.vector().array() - assemble(v*dx)/assemble(ones*dx) u[FS.keys()[i]] = vv else: u[FS.keys()[i]] = v return u
class Logarithm(MetaField): def compute(self, get): u = get(self.valuename) if u == None: return if isinstance(u, Function): if not hasattr(self, "u"): self.u = Function(u) self.u.vector()[:] = log(u.vector().array()) m = min(u.vector().array()[u.vector().array()!=0]) self.u.vector()[u.vector().array()==0] = log(m) else: self.u = log(u) return self.u
def get_coarse_level_extensions(self, M_fine): if self.verbosity >= 3: print0(pid+" calculating coarse matrices extensions") timer = Timer("Coarse matrices extensions") Mx_fun = Function(self.problem.V_fine) Mx_vec = Mx_fun.vector() M_fine.mult(self.vec_fine, Mx_vec) # M11 xtMx = MPI_sum0( numpy.dot(self.vec_fine.get_local(), Mx_vec.get_local()) ) # Mi1 PtMx_fun = interpolate(Mx_fun, self.problem.V_coarse) PtMx = PtMx_fun.vector().get_local() # M1j if self.problem.sym: PtMtx = PtMx else: self.A_fine.transpmult(self.vec_fine, Mx_vec) PtMx_fun = interpolate(Mx_fun, self.problem.V_coarse) PtMtx = PtMx_fun.vector().get_local() return xtMx, PtMtx, PtMx
def visualize(self, it=0): var = "cell_powers" try: should_vis = divmod(it, self.parameters["visualization"][var])[1] == 0 except ZeroDivisionError: should_vis = False if should_vis: if not self.up_to_date[var]: self.calculate_cell_powers() else: qfun = Function(self.DD.V0) qfun.vector()[:] = self.E qfun.rename("q", "Power") self.vis_files["cell_powers"] << (qfun, float(it)) var = "flux" try: should_vis = divmod(it, self.parameters["visualization"][var])[1] == 0 except ZeroDivisionError: should_vis = False if should_vis: if not self.up_to_date[var]: self.update_phi() for g in xrange(self.DD.G): self.vis_files["flux"][g] << (self.phi_mg[g], float(it))
class StreamFunction(Field): def before_first_compute(self, get): u = get("Velocity") assert len(u) == 2, "Can only compute stream function for 2D problems" V = u.function_space() spaces = SpacePool(V.mesh()) degree = V.ufl_element().degree() V = spaces.get_space(degree, 0) psi = TrialFunction(V) self.q = TestFunction(V) a = dot(grad(psi), grad(self.q))*dx() self.bc = DirichletBC(V, Constant(0), DomainBoundary()) self.A = assemble(a) self.L = Vector() self.bc.apply(self.A) self.solver = KrylovSolver(self.A, "cg") self.psi = Function(V) def compute(self, get): u = get("Velocity") assemble(dot(u[1].dx(0)-u[0].dx(1), self.q)*dx(), tensor=self.L) self.bc.apply(self.L) self.solver.solve(self.psi.vector(), self.L) #solve(self.A, self.psi.vector(), self.L) return self.psi
def montecarlo(self, V, interface, **kwargs): import _hybridmc as core dims = kwargs.get("Omega") bc = DirichletBC(V, 1.0, interface) coords, keys = tools.get_boundary_coords(bc) dim = len(dims) nof_nodes = len(coords) / dim D = np.array(dims, dtype=np.float_) node_coord = np.array(coords, dtype=np.float_) f = kwargs.get("f") q = kwargs.get("q") walks = kwargs.get("walks", 5000) btol = kwargs.get("btol", 1e-13) threads = kwargs.get("threads", 6) mpi_workers = kwargs.get("mpi_workers", 0) OpenCL = kwargs.get("OpenCL", False) if OpenCL and not core.opencl: print "**** WARNING **** : Module %s compiled without OpenCL supprt. Recompile with -DOPENCL_SUPPORT" % ( __name__ ) print "**** WARNING **** : Running multithread CPU version" OpenCL = False if not OpenCL: f = Expression(f) q = Expression(q) value = core.montecarlo(D, dim, node_coord, nof_nodes, f, q, walks, btol, threads, mpi_workers) est = Function(V) est.vector()[keys] = value mcbc = DirichletBC(V, est, interface) return mcbc, est
def field(self, state, x = None, lump = True, rhs_func = None): """ Returns the effective-field contribution for a given state. This method uses a projection method to retrieve the field from the RHS-form given by the :code:`form_rhs` method. It should be overriden for better performance. *Arguments* state (:class:`State`) the simulation state x (:class:`dolfin.Vector`) the vector to store the result or :code:`None` *Returns* :class:`dolfin.Function` the effective-field contribution """ # TODO set particular solver # TODO use caching for mass matrix if rhs_func is None: w = TestFunction(state.VectorFunctionSpace()) b = assemble(self.form_rhs(state, w) / Constant(Constants.gamma) * state.dx('magnetic')) else: b = rhs_func(state) # Optional mass lumping if x is None: result = Function(state.VectorFunctionSpace()) else: result = Function(state.VectorFunctionSpace(), x) if lump: A = state.M_inv_diag('magnetic') A.mult(b, result.vector()) else: w = TestFunction(state.VectorFunctionSpace()) h = TrialFunction(state.VectorFunctionSpace()) A = assemble(inner(w, h) * state.dx('magnetic')) solve(A, result.vector(), b) return result
def les_setup(u_, mesh, Wale, bcs, CG1Function, nut_krylov_solver, **NS_namespace): """Set up for solving Wale LES model """ DG = FunctionSpace(mesh, "DG", 0) CG1 = FunctionSpace(mesh, "CG", 1) delta = Function(DG) delta.vector().zero() delta.vector().axpy(1.0, assemble(TestFunction(DG)*dx)) Gij = grad(u_) Sij = sym(Gij) Skk = tr(Sij) dim = mesh.geometry().dim() Sd = sym(Gij*Gij) - 1./3.*Identity(mesh.geometry().dim())*Skk*Skk nut_form = Wale['Cw']**2 * pow(delta, 2./dim) * pow(inner(Sd, Sd), 1.5) / (Max(pow(inner(Sij, Sij), 2.5) + pow(inner(Sd, Sd), 1.25), 1e-6)) ff = FacetFunction("size_t", mesh, 0) bcs_nut = derived_bcs(CG1, bcs['u0'], u_) nut_ = CG1Function(nut_form, mesh, method=nut_krylov_solver, bcs=bcs_nut, name='nut', bounded=True) return dict(Sij=Sij, Sd=Sd, Skk=Skk, nut_=nut_, delta=delta, bcs_nut=bcs_nut)
def test11(self): """ Check diagonal content of K """ kd = get_diagonal(self.K) bi = Function(self.V) for index, ii in enumerate(kd): b = bi.vector().copy() b[index] = 1.0 Kb = (self.K*b).inner(b) self.assertTrue(abs(ii - Kb)/abs(Kb) < 1e-16)