def initialize_data(self): """ Extract required objects for defining error control forms. This will be stored and reused. """ # Developer's note: The UFL-FFC-DOLFIN--PyDOLFIN toolchain for # error control is quite fine-tuned. In particular, the order # of coefficients in forms is (and almost must be) used for # their assignment. This means that the order in which these # coefficients are defined matters and should be considered # fixed. # Primal trial element space self._V = self.u.function_space() # Primal test space == Dual trial space Vhat = self.weak_residual.arguments()[0].function_space() # Discontinuous version of primal trial element space self._dV = tear(self._V) # Extract cell and geometric dimension mesh = self._V.mesh() dim = mesh.topology().dim() # Function representing improved dual E = increase_order(Vhat) self._Ez_h = Function(E) # Function representing cell bubble function B = FunctionSpace(mesh, "B", dim + 1) self._b_T = Function(B) self._b_T.vector()[:] = 1.0 # Function representing strong cell residual self._R_T = Function(self._dV) # Function representing cell cone function C = FunctionSpace(mesh, "DG", dim) self._b_e = Function(C) # Function representing strong facet residual self._R_dT = Function(self._dV) # Function for discrete dual on primal test space self._z_h = Function(Vhat) # Piecewise constants for assembling indicators self._DG0 = FunctionSpace(mesh, "DG", 0)
def test_ref_count(pushpop_parameters): "Test petsc4py reference counting" parameters["linear_algebra_backend"] = "PETSc" mesh = UnitSquareMesh(3, 3) V = FunctionSpace(mesh, "P", 1) # Check u and x own the vector u = Function(V) x = as_backend_type(u.vector()).vec() assert x.refcount == 2 # Check decref del u gc.collect() # destroy u assert x.refcount == 1 # Check incref vec = PETScVector(x) assert x.refcount == 2
def deformation_vector(): n1 = (1 + x1[0] * sin(2 * pi * x1[1])) * VolumeNormal(multimesh.part(1)) S_sm = VectorFunctionSpace(multimesh.part(1), "CG", 1) # Note removing 0 dirichlet at dI introduces problems with the change in # the cut cell and overlap cell part. We do not have any way of describing # this movement bcs = [ DirichletBC(S_sm, n1, mfs[1], 2), DirichletBC(S_sm, Constant((0, 0)), mfs[1], 1) ] u, v = TrialFunction(S_sm), TestFunction(S_sm) a = inner(grad(u), grad(v)) * dx l = inner(Constant((0., 0.)), v) * dx n = Function(S_sm) solve(a == l, n, bcs=bcs) S = MultiMeshVectorFunctionSpace(multimesh, "CG", 1) s = MultiMeshFunction(S) s.assign_part(1, n) return s
def _test_get_set_coordinates(mesh): # Get coords V = FunctionSpace(mesh, mesh.ufl_coordinate_element()) c = Function(V) get_coordinates(c, mesh.geometry()) # Check correctness of got coords _check_coords(mesh, c) # Backup and zero coords coords = mesh.coordinates() coords_old = coords.copy() coords[:] = 0.0 assert np.all(mesh.coordinates() == 0.0) # Set again to old value set_coordinates(mesh.geometry(), c) # Check assert np.all(mesh.coordinates() == coords_old)
def __init__(self, V, **kwargs): # Call parent ParametrizedProblem.__init__(self, os.path.join("test_eim_approximation_14_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., )) self.f00 = (1-x[0])*cos(3*pi*mu[0]*(1+x[0]))*exp(-mu[0]*(1+x[0])) self.f01 = (1-x[0])*sin(3*pi*mu[0]*(1+x[0]))*exp(-mu[0]*(1+x[0])) # 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(self, get): u = get(self.valuename) if u is None: return None if not isinstance(u, Function): cbc_warning("Do not understand how to handle datatype %s" %str(type(u))) return None #if not hasattr(self, "restriction_map"): if not hasattr(self, "keys"): V = u.function_space() element = V.ufl_element() family = element.family() degree = element.degree() if LooseVersion(dolfin_version()) > LooseVersion("1.6.0"): rank = len(u.ufl_shape) else: rank = u.rank() if rank == 0: FS = FunctionSpace(self.submesh, family, degree) elif rank == 1: FS = VectorFunctionSpace(self.submesh, family, degree) elif rank == 2: FS = TensorFunctionSpace(self.submesh, family, degree, symmetry={}) self.u = Function(FS) #self.restriction_map = restriction_map(V, FS) rmap = restriction_map(V, FS) self.keys = np.array(rmap.keys(), dtype=np.intc) self.values = np.array(rmap.values(), dtype=np.intc) self.temp_array = np.zeros(len(self.keys), dtype=np.float_) # The simple __getitem__, __setitem__ has been removed in dolfin 1.5.0. # The new cbcpost-method get_set_vector should be compatible with 1.4.0 and 1.5.0. #self.u.vector()[self.keys] = u.vector()[self.values] get_set_vector(self.u.vector(), self.keys, u.vector(), self.values, self.temp_array) return self.u
def load_microstructure(h5file, fgroup, mesh, geo, include_sheets=True): if h5file.has_dataset(fgroup): # Get fibers fiber_attrs = h5file.attributes(fgroup) fspace = fiber_attrs["space"] if fspace is None: # Assume quadrature 4 family = "Quadrature" order = 4 else: family, order = fspace.split("_") namesstr = fiber_attrs["names"] if namesstr is None: names = ["fiber"] else: names = namesstr.split(":") # Check that these fibers exists for name in names: fsubgroup = fgroup + "/{}".format(name) if not h5file.has_dataset(fsubgroup): msg = ("H5File does not have dataset {}").format(fsubgroup) # FIXME: implement logger # logger.warning(msg) elm = VectorElement(family=family, cell=mesh.ufl_cell(), degree=int(order), quad_scheme="default") V = FunctionSpace(mesh, elm) attrs = ["f0", "s0", "n0"] for i, name in enumerate(names): func = Function(V, name=name) fsubgroup = fgroup + "/{}".format(name) h5file.read(func, fsubgroup) setattr(geo, attrs[i], func)
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)) @function.expression.numba_eval def expr_eval(values, x, cell_idx): values[:, 0] = x[:, 0] + 2.0 * x[:, 1] + 3.0 * x[:, 2] u = Expression(expr_eval) 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 # Now make coarse mesh larger than fine mesh meshc.geometry.points *= 1.5 uc = interpolate(u, Vc) mat = PETScDMCollection.create_transfer_matrix(Vc._cpp_object, Vf._cpp_object) mat.mult(uc.vector(), Vuc.vector()) diff = Vuc.vector() diff.axpy(-1, uf.vector()) assert diff.norm() < 1.0e-12
def MeasureFunction(averaged): '''Get measure of the averaging shape as a function on the 1d surface''' # Get space on 1d mesh for the measure V = averaged.function_space() # 3d one # Want the measure in scalar space if V.ufl_element().value_shape(): V = V.sub(0).collapse() mesh_1d = averaged.average_['mesh'] # Finally TV = average_space(V, mesh_1d) TV_coordinates = TV.tabulate_dof_coordinates().reshape((TV.dim(), -1)) TV_dm = TV.dofmap() visited = np.zeros(TV.dim(), dtype=bool) mesh_x = mesh_1d.coordinates() shape = averaged.average_['shape'] values = np.empty(TV.dim(), dtype=float) for cell in cells(mesh_1d): # Get the tangent (normal of the plane which cuts the virtual # surface to yield the bdry curve v0, v1 = mesh_x[cell.entities(0)] n = v0 - v1 # Where to dofs = TV_dm.cell_dofs(cell.index()) for seen, dof in zip(visited[dofs], dofs): if not seen: x = TV_coordinates[dof] # Values sum up to the measure of the hypersurface values[dof] = sum(shape.quadrature(x, n).weights) visited[dof] = True assert np.all(visited) # Wrap as a function m = Function(TV) m.vector().set_local(values) return m
def big_error_norms(self, u, overlap_subdomain): V = FunctionSpace(self.mesh, "Lagrange", self.p) uu = Function(V) uu.vector()[:] = u.vector() # uu.vector()[:] = u.vector() overlap_marker = MeshFunction('size_t', self.mesh, self.mesh.topology().dim()) overlap_subdomain.mark(overlap_marker, 1) dxo = Measure('dx', subdomain_data=overlap_marker) error = (uu**2) * dxo semi_error = inner(grad(uu), grad(uu)) * dxo L2 = assemble(error) H1 = L2 + assemble(semi_error) SH = H1 - L2 return L2, H1, SH
def read_vtu_function(vtus, V): '''Read in functions in V from VTUs files''' # NOTE: this would much easier with (py)vtk but that is not part of # the FEniCS stack so ... gdim = V.mesh().geometry().dim() assert gdim > 1 if isinstance(vtus, str): vtus = [vtus] reorder = data_reordering(V) npoints, ncells = V.mesh().num_vertices(), V.mesh().num_cells() functions = [] for vtu in vtus: f = Function(V) data = read_vtu_point_data(vtu, npoints, ncells) f.vector().set_local(reorder(data)) functions.append(f) return functions
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 eikonal_1d(mb, p0=0, function=None): "Compute distance from p0 on set of edges" # 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) # initial solution is inf everywhere sol = np.empty(PP.shape[0]) sol.fill(np.inf) # initial conditions active = deque([p0]) sol[p0] = 0.0 # fast marching on edges x = mb.coordinates() while active: curr = active.pop() neig = np.where(PP[curr, :])[0] ll = sol[curr] + np.linalg.norm(x[neig, :] - x[curr, :], axis=1) up = neig[ll < sol[neig]] active.extend(up) sol[neig] = np.minimum(sol[neig], ll) # return solution 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)] = sol return function else: Ve = function.function_space() function.vector()[vertex_to_dof_map(Ve)] = sol
def STD(series): """std of a series. NOTE: this is a sort of copy-paste coding of RMS; maybe rather put in RMS with a STD flag?""" # first, compute the mean mean = Mean(series) # get the square of the field of the mean mean_vector = mean.vector() mvs = as_backend_type(mean_vector).vec() # the mean squared, to be used for computing the RMS mvs.pointwiseMult(mvs, mvs) # now, compute the STD # for this, follow the example of RMS std = Function(series.V) # NOTE: for efficiency we stay away from Interpreter and all is in PETSc layer x = as_backend_type( std.vector()).vec() # PETSc.Vec, stores the final output y = x.copy() # Stores the current working field # Integrate dts = np.diff(series.times) f_vectors = [as_backend_type(f.vector()).vec() for f in series.functions] for dt, (f0, f1) in zip(dts, zip(f_vectors[:-1], f_vectors[1:])): y.pointwiseMult(f0, f0) # y = f0**2 x.axpy(dt / 2., y) # x += dt / 2 * y y.pointwiseMult(f1, f1) # y = f1**2 x.axpy(dt / 2., y) # x += dt / 2 * y x.axpy( -dt, mvs ) # x += -dt * mvs NOTE: no factor 2, as adding 2 dt / 2 to compensate # Time interval scaling x /= dts.sum() # sqrt x.sqrtabs() return std
def run_test(): q = 3 Nxy = 100 tf = 0.1 h = 1. / Nxy mesh = UnitSquareMesh(Nxy, Nxy, "crossed") V = FunctionSpace(mesh, 'Lagrange', q) Vl = FunctionSpace(mesh, 'Lagrange', 1) Dt = h / (q * 10.) u0_expr = Expression(\ '100*pow(x[i]-.25,2)*pow(x[i]-0.75,2)*(x[i]<=0.75)*(x[i]>=0.25)', i=0) Wave = AcousticWave({'V': V, 'Vl': Vl, 'Vr': Vl}) Wave.lump = True Wave.timestepper = 'backward' Wave.update({'lambda':1.0, 'rho':1.0, 't0':0.0, 'tf':tf, 'Dt':Dt,\ 'u0init':interpolate(u0_expr, V), 'utinit':Function(V)}) K = Wave.K u = Wave.u0 u.vector()[:] = 1.0 b = Wave.u1 for ii in range(100): K * u.vector() (K * u.vector()).array() b.vector()[:] = (K * u.vector()).array() b.vector()[:] = 0.0 b.vector().axpy(1.0, K * u.vector()) b.vector()[:] = (K * u.vector()).array() + (K * u.vector()).array() b.vector()[:] = (K * u.vector() + K * u.vector()).array() b.vector()[:] = 2.*u.vector().array() + u.vector().array() + \ Dt*u.vector().array() b.vector()[:] = 0.0 b.vector().axpy(2.0, u.vector()) b.vector().axpy(1.0, u.vector()) b.vector().axpy(Dt, u.vector()) b.assign(u) b.vector().zero()
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 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) # Compute cell size and put in delta delta = Function(DG) delta.vector().zero() delta.vector().axpy(1.0, assemble(TestFunction(DG)*dx)) # Set up Wale form 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 test_vector_p2_2d(): meshc = UnitSquareMesh(MPI.comm_world, 5, 4) meshf = UnitSquareMesh(MPI.comm_world, 5, 8) Vc = VectorFunctionSpace(meshc, ("CG", 2)) Vf = VectorFunctionSpace(meshf, ("CG", 2)) def u(values, x): values[:, 0] = x[:, 0] + 2.0 * x[:, 1] values[:, 1] = 4.0 * x[:, 0] * x[:, 1] 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_scalar_p2(): meshc = UnitCubeMesh(MPI.comm_world, 2, 2, 2) meshf = UnitCubeMesh(MPI.comm_world, 3, 4, 5) Vc = FunctionSpace(meshc, ("CG", 2)) Vf = FunctionSpace(meshf, ("CG", 2)) def u(values, x): values[:, 0] = x[:, 0] + 2.0 * x[:, 1] + 3.0 * x[:, 2] 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 solve(self, opt): """ This procedure implements a first-order semi-Lagrangian time-stepping scheme to solve a parabolic second-order PDE in non-variational form - du/dt - (a : D^2 u + b * D u + c * u ) = - f <==> - du/dt - (a : D^2 u + b * D u + c * u - f ) = 0 """ if hasattr(self, 'dt'): opt["timeSteps"] *= opt["timeStepFactor"] nt = opt["timeSteps"] Tspace = np.linspace(self.T[1], self.T[0], nt + 1) self.dt = (self.T[1] - self.T[0]) / nt self.u_np1 = Function(self.V) if opt["saveSolution"]: file_u = File('./pvd/u.pvd') print('Setting final time conditions') assign(self.u, project(self.u_T, self.V)) if opt["saveSolution"]: file_u << self.u for i, s in enumerate(Tspace[1:]): print('Iteration {}/{}:\t t = {}'.format(i + 1, nt, s)) self.iter = i # Update time in coefficient functions self.updateTime(s) assign(self.u_np1, self.u) # Solve problem for current time step super().solve(opt) if opt["saveSolution"]: file_u << self.u
def __init__(self, Th, callback_type): # Create mesh and define function space mesh = UnitSquareMesh(Th, Th) self.V = FunctionSpace(mesh, "Lagrange", 1) # Define variational problem du = TrialFunction(self.V) v = TestFunction(self.V) self.u = Function(self.V) self.r = lambda u, g: inner(grad(u), grad(v))*dx + inner(u + u**3, v)*dx - g*v*dx self.j = lambda u, r: derivative(r, u, du) # Define initial guess self.initial_guess_expression = Expression("0.1 + 0.9*x[0]*x[1]", element=self.V.ufl_element()) # Define callback function depending on callback type assert callback_type in ("form callbacks", "tensor callbacks") if callback_type == "form callbacks": def callback(arg): return arg elif callback_type == "tensor callbacks": def callback(arg): return assemble(arg) self.callback_type = callback_type self.callback = callback
def compute_mu(constant=True): """ Compute mu as according to arxiv paper https://arxiv.org/pdf/1509.08601.pdf """ mu_min=Constant(1) mu_max=Constant(500) if constant: return mu_max else: V = FunctionSpace(self.mesh, "CG",1) u, v = TrialFunction(V), TestFunction(V) a = inner(grad(u),grad(v))*dx l = Constant(0)*v*dx bcs = [] for marker in self.move_dict["Fixed"]: bcs.append(DirichletBC(V, mu_min, self.mf, marker)) for marker in self.move_dict["Deform"]: bcs.append(DirichletBC(V, mu_max, self.mf, marker)) mu = Function(V) solve(a==l, mu, bcs=bcs) return mu
def exact_eigensolve(A, B, V, params): '''A direct solver intended to run in serial''' assert A.comm.size == 1 A = csr_matrix(A.getValuesCSR()[::-1], shape=A.size) B = csr_matrix(B.getValuesCSR()[::-1], shape=B.size) eigw, eigv = eigh(A.todense(), B.todense()) sort_idx = np.argsort(eigw) # Fall back to 10 eigenpair nev = params.get('-eps_type', 10) eigw = eigw[sort_idx[:nev]] eigv = (eigv.T)[sort_idx[:nev]] eigenpairs = [] for w, v in zip(eigw, eigv): f = Function(V) f.vector().set_local(v) eigenpairs.append((w, f)) return eigenpairs
def __init__(self, W, components=None): if components is None: self.functions = list(map(Function, W)) else: assert len(components) == len(W) # Functions them selves if hasattr(first(components), 'function_space'): assert [ c.function_space() == Wi for c, Wi in zip(components, W) ] self.functions = components # The components can be vectors in that case else: # Dim check assert all(c.size() == Wi.dim() for c, Wi in zip(components, W)) # Create self.functions = [ Function(Wi, c) for c, Wi in zip(components, W) ] self._W = W
def RMS(series): '''sqrt(1/(T - t0)\int_{t0}^{t1}f^2(t)dt''' # Again by applying simpson rms = Function(series.V) # NOTE: for efficiency we stay away from Interpreter and all is in PETSc layer x = as_backend_type(rms.vector()).vec() # PETSc.Vec y = x.copy() # Stores fi**2 # Integrate dts = np.diff(series.times) f_vectors = [as_backend_type(f.vector()).vec() for f in series.functions] for dt, (f0, f1) in zip(dts, zip(f_vectors[:-1], f_vectors[1:])): y.pointwiseMult(f0, f0) # y = f0**2 x.axpy(dt / 2., y) # (f0**2+f1**2)*dt/2 y.pointwiseMult(f1, f1) # y = f1**2 x.axpy(dt / 2., y) # Time interval scaling x /= dts.sum() # sqrt x.sqrtabs() return rms
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 NLtol(x, u, FS, Type=None): IS = common.IndexSet(FS) if Type == 'Update': v = x.getSubVector(IS['Velocity']).array p = x.getSubVector(IS['Pressure']).array pa = Function(FS['Pressure']) pa.vector()[:] = p ones = Function(FS['Pressure']) ones.vector()[:] = (0 * p + 1) pp = Function(FS['Pressure']) pp.vector( )[:] = pa.vector().array() - assemble(pa * dx) / assemble(ones * dx) vnorm = norm(v) pnorm = norm(pp.vector().array()) V = [vnorm, pnorm] eps = PrintFuncs.NormPrint(V, Type) x.axpy(1.0, u) return x, eps else: vcurrent = x.getSubVector(IS['Velocity']).array pcurrent = x.getSubVector(IS['Pressure']).array vprev = u.getSubVector(IS['Velocity']).array pprev = u.getSubVector(IS['Pressure']).array pa = Function(FS['Pressure']) pa.vector()[:] = pcurrent ones = Function(FS['Pressure']) ones.vector()[:] = (0 * pcurrent + 1) pp = Function(FS['Pressure']) pp.vector( )[:] = pa.vector().array() - assemble(pa * dx) / assemble(ones * dx) vnorm = norm(vcurrent - vprev) pnorm = norm(pp.vector().array() - pprev) V = [vnorm, pnorm] eps = PrintFuncs.NormPrint(V, Type) return x, eps
def main(solver, N: int, dt: float, T: float, theta: float) -> Tuple[float, float, float, float, float]: # Create cardiac model mesh = UnitSquareMesh(N, N) time = Constant(0.0) cell_model = NoCellModel() ac_str = "cos(t)*cos(2*pi*x[0])*cos(2*pi*x[1]) + 4*pow(pi, 2)*cos(2*pi*x[0])*cos(2*pi*x[1])*sin(t)" stimulus = Expression(ac_str, t=time, degree=5) ps = solver.default_parameters() ps["Chi"] = 1.0 ps["Cm"] = 1.0 _solver = solver(mesh, time, 1.0, 1.0, stimulus, parameters=ps) # Define exact solution (Note: v is returned at end of time # interval(s), u is computed at somewhere in the time interval # depending on theta) v_exact = Expression("cos(2*pi*x[0])*cos(2*pi*x[1])*sin(t)", t=T, degree=5) u_exact = Expression("-cos(2*pi*x[0])*cos(2*pi*x[1])*sin(t)/2.0", t=T - (1 - theta) * dt, degree=5) # Define initial condition(s) vs0 = Function(_solver.V) vs_, *_ = _solver.solution_fields() vs_.assign(vs0) # Solve for _, (vs_, vur) in _solver.solve(0, T, dt): continue # Compute errors v, u, *_ = vur.split(deepcopy=True) v_error = errornorm(v_exact, v, "L2", degree_rise=5) u_error = errornorm(u_exact, u, "L2", degree_rise=5) return v_error, u_error, mesh.hmin(), dt, T
def test_scalar_conditions(R): c = Function(R) c.vector().set(1.5) # Float conversion does not interfere with boolean ufl expressions assert isinstance(ufl.lt(c, 3), ufl.classes.LT) assert not isinstance(ufl.lt(c, 3), bool) # Float conversion is not implicit in boolean Python expressions assert isinstance(c < 3, ufl.classes.LT) assert not isinstance(c < 3, bool) # == is used in ufl to compare equivalent representations, # <,> result in LT/GT expressions, bool conversion is illegal # Note that 1.5 < 0 == False == 1.5 < 1, but that is not what we # compare here: assert not (c < 0) == (c < 1) # This protects from "if c < 0: ..." misuse: with pytest.raises(ufl.UFLException): bool(c < 0) with pytest.raises(ufl.UFLException): not c < 0
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)) def u(values, x): values[:, 0] = x[:, 0] + 2.0 * x[:, 1] values[:, 1] = 4.0 * x[:, 0] values[:, 2] = 3.0 * x[:, 2] + x[:, 0] 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