def step(self, u0, t, dt, bcs1, tol=1.0e-10, verbose=True ): u1 = Function(self.problem.V) u1.interpolate(u0) return u1
def __init__(self, nut, u, Space, bcs=[], name=""): Function.__init__(self, Space, name=name) dim = Space.mesh().geometry().dim() test = TestFunction(Space) self.bf = [inner(inner(grad(nut), u.dx(i)), test)*dx for i in range(dim)]
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 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 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 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 __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 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 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 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 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 __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 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))
def readV(self, functionspaces_V): # Solutions: self.V = functionspaces_V['V'] self.test = TestFunction(self.V) self.trial = TrialFunction(self.V) self.u0 = Function(self.V) # u(t-Dt) self.u1 = Function(self.V) # u(t) self.u2 = Function(self.V) # u(t+Dt) self.rhs = Function(self.V) self.sol = Function(self.V) # Parameters: self.Vl = functionspaces_V['Vl'] self.lam = Function(self.Vl) self.Vr = functionspaces_V['Vr'] self.rho = Function(self.Vr) if functionspaces_V.has_key('Vm'): self.Vm = functionspaces_V['Vm'] self.mu = Function(self.Vm) self.elastic = True assert(False) else: self.elastic = False self.weak_k = inner(self.lam*nabla_grad(self.trial), \ nabla_grad(self.test))*dx self.weak_m = inner(self.rho*self.trial,self.test)*dx
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())
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 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 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 BTdot(self, uin): """Compute B^T.uin as a np.array uin must be a np.array""" isarray(uin) u = Function(self.V) out = u.vector() for ii, bb in enumerate(self.B): out += bb*uin[ii] return out.array()
def test01(self): """ Check diagonal content of M """ md = get_diagonal(self.M) bi = Function(self.V) for index, ii in enumerate(md): b = bi.vector().copy() b[index] = 1.0 Mb = (self.M*b).inner(b) self.assertTrue(abs(ii - Mb)/abs(Mb) < 1e-16)
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)
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 _compute_time_errors(problem, method, mesh_sizes, Dt, plot_error=False): mesh_generator, solution, ProblemClass, cell_type = problem() # Translate data into FEniCS expressions. fenics_sol = Expression(smp.printing.ccode(solution['value']), degree=solution['degree'], t=0.0, cell=cell_type ) # Compute the problem errors = {'theta': numpy.empty((len(mesh_sizes), len(Dt)))} # Create initial state. # Deepcopy the expression into theta0. Specify the cell to allow for # more involved operations with it (e.g., grad()). theta0 = Expression(fenics_sol.cppcode, degree=solution['degree'], t=0.0, cell=cell_type ) for k, mesh_size in enumerate(mesh_sizes): mesh = mesh_generator(mesh_size) V = FunctionSpace(mesh, 'CG', 1) theta_approx = Function(V) theta0p = project(theta0, V) stepper = method(ProblemClass(V)) if plot_error: error = Function(V) for j, dt in enumerate(Dt): # TODO We are facing a little bit of a problem here, being the # fact that the time stepper only accept elements from V as u0. # In principle, though, this isn't necessary or required. We # could allow for arbitrary expressions here, but then the API # would need changing for problem.lhs(t, u). # Think about this. stepper.step(theta_approx, theta0p, 0.0, dt, tol=1.0e-12, verbose=False ) fenics_sol.t = dt # # NOTE # When using errornorm(), it is quite likely to see a good part # of the error being due to the spatial discretization. Some # analyses "get rid" of this effect by (sometimes implicitly) # projecting the exact solution onto the discrete function # space. errors['theta'][k][j] = errornorm(fenics_sol, theta_approx) if plot_error: error.assign(project(fenics_sol - theta_approx, V)) plot(error, title='error (dt=%e)' % dt) interactive() return errors, stepper.name, stepper.order
def __init__(self, u, name="Assigned Vector Function"): self.u = u assert isinstance(u, ListTensor) V = u[0].function_space() mesh = V.mesh() family = V.ufl_element().family() degree = V.ufl_element().degree() constrained_domain = V.dofmap().constrained_domain Vv = VectorFunctionSpace(mesh, family, degree, constrained_domain=constrained_domain) Function.__init__(self, Vv, name=name) self.fa = [FunctionAssigner(Vv.sub(i), V) for i, _u in enumerate(u)]
def load_precomputed_bessel_functions(self, PS): """ loads precomputed Bessel functions (modes of analytic solution) """ f = HDF5File(mpi_comm_world(), 'precomputed/precomputed_' + self.precomputed_filename + '.hdf5', 'r') temp = toc() fce = Function(PS) f.read(fce, "parab") self.bessel_parabolic = fce.copy(deepcopy=True) for i in range(8): f.read(fce, "real%d" % i) self.bessel_real.append(fce.copy(deepcopy=True)) f.read(fce, "imag%d" % i) self.bessel_complex.append(fce.copy(deepcopy=True)) print("Loaded partial solution functions. Time: %f" % (toc() - temp))
def plot(self, **kwargs): func = self._fefunc # fix a bug in the fenics plot function that appears when # the maximum difference between data values is very small # compared to the magnitude of the data values = func.vector().array() diff = max(values) - min(values) magnitude = max(abs(values)) if diff < magnitude * 1e-8: logger.warning("PLOT: function values differ only by tiny amount -> plotting as constant") func = Function(func.function_space()) func.vector()[:] = values[0] plot(func, **kwargs)
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 initialize(self, V, Q, PS, D): super(Problem, self).initialize(V, Q, PS, D) print("IC type: " + self.ic) print("Velocity scale factor = %4.2f" % self.factor) reynolds = 728.761 * self.factor # TODO modify by nu_factor print("Computing with Re = %f" % reynolds) self.v_in = Function(V) print('Initializing error control') self.load_precomputed_bessel_functions(PS) self.solution = self.assemble_solution(0.0) # set constants for self.area = assemble(interpolate(Expression("1.0"), Q) * self.dsIn) # inflow area # womersley = steady + e^iCt, e^iCt has average 0 self.pg_normalization_factor.append(womersleyBC.average_analytic_pressure_grad(self.factor)) self.p_normalization_factor.append(norm( interpolate(womersleyBC.average_analytic_pressure_expr(self.factor), self.pSpace), norm_type='L2')) self.vel_normalization_factor.append(norm( interpolate(womersleyBC.average_analytic_velocity_expr(self.factor), self.vSpace), norm_type='L2')) # print('Normalisation factors (vel, p, pg):', self.vel_normalization_factor[0], self.p_normalization_factor[0], # self.pg_normalization_factor[0]) one = (interpolate(Expression('1.0'), Q)) self.outflow_area = assemble(one*self.dsOut) print('Outflow area:', self.outflow_area)
def test_mpi_dependent_jiting(): # FIXME: Not a proper unit test... from dolfin import Expression, UnitSquareMesh, Function, TestFunction, \ Form, FunctionSpace, dx, CompiledSubDomain, SubSystemsManager # Init petsc (needed to initalize petsc and slepc collectively on # all processes) SubSystemsManager.init_petsc() try: import mpi4py.MPI as mpi except: return try: import petsc4py.PETSc as petsc except: return # Set communicator and get process information comm = mpi.COMM_WORLD group = comm.Get_group() size = comm.Get_size() # Only consider parallel runs if size == 1: return rank = comm.Get_rank() group_comm_0 = petsc.Comm(comm.Create(group.Incl(range(1)))) group_comm_1 = petsc.Comm(comm.Create(group.Incl(range(1, 2)))) if size > 2: group_comm_2 = petsc.Comm(comm.Create(group.Incl(range(2, size)))) if rank == 0: e = Expression("4", mpi_comm=group_comm_0, degree=0) elif rank == 1: e = Expression("5", mpi_comm=group_comm_1, degree=0) domain = CompiledSubDomain("on_boundary", mpi_comm=group_comm_1, degree=0) else: mesh = UnitSquareMesh(group_comm_2, 2, 2) V = FunctionSpace(mesh, "P", 1) u = Function(V) v = TestFunction(V) Form(u * v * dx)
def test_multi_ps_matrix_node_local(mesh): """Tests point source when given constructor PointSource(V, V, point, mag) with a matrix when points placed at 3 node for 1D, 2D and 3D. Local points given to constructor. """ V = FunctionSpace(mesh, "CG", 1) u, v = TrialFunction(V), TestFunction(V) w = Function(V) A = assemble(Constant(0.0) * u * v * dx) source = [] point_coords = mesh.coordinates()[0] source.append((Point(point_coords), 10.0)) ps = PointSource(V, source) ps.apply(A) # Checks matrix sums to correct value. A.get_diagonal(w.vector()) size = MPI.size(mesh.mpi_comm()) a_sum = MPI.sum(mesh.mpi_comm(), np.sum(A.array())) assert round(a_sum - size * 10.0) == 0
def test_p4_parallel_2d(): mesh = UnitSquareMesh(MPI.comm_world, 5, 8) Q = FunctionSpace(mesh, ("CG", 4)) F = Function(Q) @function.expression.numba_eval def x0(values, x, cell_idx): values[:, 0] = x[:, 0] F.interpolate(Expression(x0)) # Generate random points in this mesh partition (one per cell) x = numpy.zeros(3) for c in Cells(mesh): x[0] = random() x[1] = random() * (1 - x[0]) x[2] = 1 - x[0] - x[1] p = Point(0.0, 0.0) for i, v in enumerate(VertexRange(c)): p += v.point() * x[i] p = p.array()[:2] assert numpy.isclose(F(p)[0], p[0])
def test_xdmf_timeseries_write_to_closed_hdf5_using_with(tempdir): mesh = UnitCubeMesh(MPI.comm_world, 2, 2, 2) V = FunctionSpace(mesh, ("CG", 1)) u = Function(V) filename = os.path.join(tempdir, "time_series_closed_append.xdmf") with XDMFFile(mesh.mpi_comm(), filename) as xdmf: xdmf.write(u, float(0.0)) xdmf.write(u, float(1.0)) xdmf.close() with xdmf: xdmf.write(u, float(2.0))
def read_h5_function(h5_file, times, V): ''' Read in function in V from h5_file:/VisualisationVector/times ''' gdim = V.mesh().geometry().dim() assert gdim > 1 if isinstance(times, str): times = [times] reorder = data_reordering(V) functions = [] # Read the functions with h5py.File(h5_file, 'r') as h5: group = h5.get('VisualisationVector') for key in times: f = Function(V) # What to fill data = group[key].value f.vector().set_local(reorder(data)) functions.append(f) return functions
def test_scalar_conditions(R): c = Function(R) c.vector()[:] = 1.5 # Float conversion does not interfere with boolean ufl expressions assert isinstance(lt(c, 3), ufl.classes.LT) assert not isinstance(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_save_3d_vector_series(tempdir, encoding): if invalid_config(encoding): pytest.skip("XDMF unsupported in current configuration") filename = os.path.join(tempdir, "u_3D.xdmf") mesh = UnitCubeMesh(MPI.comm_world, 2, 2, 2) u = Function(VectorFunctionSpace(mesh, "Lagrange", 2)) with XDMFFile(mesh.mpi_comm(), filename, encoding=encoding) as file: u.vector()[:] = 1.0 file.write(u, 0.1) u.vector()[:] = 2.0 file.write(u, 0.2) u.vector()[:] = 3.0 file.write(u, 0.3)
def test_mixed_parallel(): mesh = UnitSquareMesh(MPI.comm_world, 5, 8) V = VectorElement("Lagrange", triangle, 4) Q = FiniteElement("Lagrange", triangle, 5) W = FunctionSpace(mesh, Q * V) F = Function(W) F.interpolate(Expression(("x[0]", "x[1]", "sin(x[0] + x[1])"), degree=5)) # Generate random points in this mesh partition (one per cell) x = numpy.zeros(3) for c in Cells(mesh): x[0] = random() x[1] = random() * (1 - x[0]) x[2] = (1 - x[0] - x[1]) p = Point(0.0, 0.0) for i, v in enumerate(VertexRange(c)): p += v.point() * x[i] p = p.array()[:2] val = F(p) assert numpy.allclose(val[0], p[0]) assert numpy.isclose(val[1], p[1]) assert numpy.isclose(val[2], numpy.sin(p[0] + p[1]))
def CladdingR_solver(FC_mesh, FC_facets, FC_fs, FC_info, D_post, R_path): FC_fi, FC_fo = FC_fs h, Tfc_inner, Tb, FC_Tave = FC_info # Reading mesh data stored in .xdmf files. mesh = Mesh() with XDMFFile(FC_mesh) as infile: infile.read(mesh) mvc = MeshValueCollection("size_t", mesh, 1) with XDMFFile(FC_facets) as infile: infile.read(mvc, "name_to_read") mf = cpp.mesh.MeshFunctionSizet(mesh, mvc) #File("Circle_facet.pvd").write(mf) # Mesh data print('CladdingRod_mesh data\n', 'Number of cells: ', mesh.num_cells(), '\n Number of nodes: ', mesh.num_vertices()) # Define variational problem V = FunctionSpace(mesh, 'P', 1) u = Function(V) v = TestFunction(V) # Define boundary conditions base on pygmsh mesh mark bc = DirichletBC(V, Constant(Tfc_inner), mf, FC_fi) ds = Measure("ds", domain=mesh, subdomain_data=mf, subdomain_id=FC_fo) # Variational formulation # Klbda_ZrO2 = 18/1000 # W/(m K) --> Nuclear reactor original source # Klbda_ZrO2 = Constant(K_ZrO2(FC_Tave)) F = K_ZrO2(u) * dot(grad(u), grad(v)) * dx + h * (u - Tb) * v * ds # Compute solution du = TrialFunction(V) Gain = derivative(F, u, du) solve(F==0, u, bc, J=Gain, \ solver_parameters={"newton_solver": {"linear_solver": "lu", "relative_tolerance": 1e-9}}, \ form_compiler_parameters={"cpp_optimize": True, "representation": "uflacs", "quadrature_degree" : 2} ) # mumps # Save solution if D_post: fU_out = XDMFFile(os.path.join(R_path, 'FuelCladding', 'u.xdmf')) fU_out.write_checkpoint(u, "T", 0, XDMFFile.Encoding.HDF5, False) fU_out.close()
def test_raises(meshes_p1): mesh1, mesh2 = meshes_p1[:2] # Wrong FE family V = VectorFunctionSpace(mesh2, "Discontinuous Lagrange", 1) c = Function(V) with pytest.raises(RuntimeError): get_coordinates(c, mesh2.geometry()) with pytest.raises(RuntimeError): set_coordinates(mesh2.geometry(), c) # Wrong value rank V = FunctionSpace(mesh2, "Lagrange", 1) c = Function(V) with pytest.raises(RuntimeError): get_coordinates(c, mesh2.geometry()) with pytest.raises(RuntimeError): set_coordinates(mesh2.geometry(), c) # Wrong value shape V = VectorFunctionSpace(mesh2, "Lagrange", mesh2.geometry().degree(), dim=mesh2.geometry().dim() - 1) c = Function(V) with pytest.raises(RuntimeError): get_coordinates(c, mesh2.geometry()) with pytest.raises(RuntimeError): set_coordinates(mesh2.geometry(), c) # Non-matching degree V = VectorFunctionSpace(mesh2, "Lagrange", mesh2.geometry().degree() + 1) c = Function(V) with pytest.raises(RuntimeError): get_coordinates(c, mesh2.geometry()) with pytest.raises(RuntimeError): set_coordinates(mesh2.geometry(), c)
class PetscMatVec: def __init__(self, W, A, bc, PrecondTmult): self.A = A self.IS = MO.IndexSet(W) self.bc = bc self.W = W self.PrecondTmult = PrecondTmult def create(self, A): self.u_k = Function(self.W['velocity']) self.p_k = Function(self.W['pressure']) self.b_k = Function(self.W['magnetic']) self.r_k = Function(self.W['multiplier']) def mult(self, A, x, y): self.u_k.vector()[:] = x.getSubVector(self.IS['velocity']).array self.p_k.vector()[:] = x.getSubVector(self.IS['pressure']).array self.b_k.vector()[:] = x.getSubVector(self.IS['magnetic']).array self.r_k.vector()[:] = x.getSubVector(self.IS['multiplier']).array aVec, L_M, L_NS, Bt, CoupleT = forms.MHDmatvec(mesh, W, Laplacian, Laplacian,u_k,b_k,self.u_k,self.b_k,self.p_k,self.r_k, params,"Full","CG", SaddlePoint = "No") u = assemble(aVec) for bc in self.bc: bc.apply(u) y.array = u.array() def getMatrix(self,matrix): if matrix == 'Ct': return self.PrecondTmult['Ct'] elif matrix == 'Bt': return self.PrecondTmult['Bt'] elif matrix == 'BC': return self.PrecondTmult['BC']
def cmscr1d_img_pb(img: np.array, alpha0: float, alpha1: float, alpha2: float, alpha3: float, beta: float, deriv='mesh') \ -> (np.array, np.array, float, float, bool): """Computes the L2-H1 mass conserving flow with source for a 1D image sequence with spatio-temporal and convective regularisation with periodic spatial boundary. Args: img (np.array): 1D image sequence of shape (m, n), where m is the number of time steps and n is the number of pixels. alpha0 (float): The spatial regularisation parameter for v. alpha1 (float): The temporal regularisation parameter for v. alpha2 (float): The spatial regularisation parameter for k. alpha3 (float): The temporal regularisation parameter for k. beta (float): The convective regularisation parameter. deriv (str): Specifies how to approximate pertial derivatives. When set to 'mesh' it uses FEniCS built in function. Returns: v (np.array): A velocity array of shape (m, n). k (np.array): A source array of shape (m, n). res (float): The residual. fun (float): The function value. converged (bool): True if Newton's method converged. """ # Check for valid arguments. valid = {'mesh'} if deriv not in valid: raise ValueError("Argument 'deriv' must be one of %r." % valid) # Create mesh. m, n = img.shape mesh = UnitSquareMesh(m - 1, n - 1) # Define function space. V = dh.create_function_space(mesh, 'periodic') W = dh.create_vector_function_space(mesh, 'periodic') # Convert array to function. f = Function(V) f.vector()[:] = dh.img2funvec_pb(img) # Compute partial derivatives. ft, fx = f.dx(0), f.dx(1) # Compute velocity. v, k, res, fun, converged = cmscr1d_weak_solution(W, f, ft, fx, alpha0, alpha1, alpha2, alpha3, beta) # Convert back to array and return. v = dh.funvec2img(v.vector().get_local(), m, n) k = dh.funvec2img(k.vector().get_local(), m, n) return v, k, res, fun, converged
def test_cffi_expression(V): code_h = """ void eval(double* values, int num_points, int value_size, const double* x, int gdim); """ code_c = """ void eval(double* values, int num_points, int value_size, const double* x, int gdim) { for (int i = 0; i < num_points; ++i) values[i*value_size + 0] = x[i*gdim + 0] + x[i*gdim + 1]; } """ module = "_expr_eval" + str(MPI.comm_world.rank) # Build the kernel ffi = cffi.FFI() ffi.set_source(module, code_c) ffi.cdef(code_h) ffi.compile() # Import the compiled kernel kernel_mod = importlib.import_module(module) ffi, lib = kernel_mod.ffi, kernel_mod.lib # Get pointer to the compiled function eval_ptr = ffi.cast("uintptr_t", ffi.addressof(lib, "eval")) # Handle C func address by hand f1 = Function(V) f1.interpolate(int(eval_ptr)) def expr_eval2(values, x): values[:, 0] = x[:, 0] + x[:, 1] f2 = Function(V) f2.interpolate(expr_eval2) assert (f1.vector() - f2.vector()).norm() < 1.0e-12
class TimeDerivative(MetaField): r"""Compute the time derivative of a Field :math:`F` through an explicit difference formula: .. math :: F'(t_n) \approx \frac{F(t_n)-F(t_{n-1})}{t_n-t_{n-1}} """ def compute(self, get): u1 = get(self.valuename) u0 = get(self.valuename, -1) t1 = get("t") t0 = get("t", -1) dt = t1 - t0 if dt == 0: dt = 1e-14 # Avoid zero-division if isinstance(u0, Function): # Create function to hold result first time, # assuming u1 and u0 are Functions in same space if not hasattr(self, "_du"): self._du = Function(u0.function_space()) # Compute finite difference derivative # FIXME: Validate this, not tested! self._du.vector().zero() self._du.vector().axpy(+1.0 / dt, u1.vector()) self._du.vector().axpy(-1.0 / dt, u0.vector()) return self._du elif hasattr(u0, "__len__"): du = [(x1 - x0) / dt for x0, x1 in zip(u0, u1)] du = type(u0)(du) return du else: # Assuming scalar value du = (u1 - u0) / dt return du
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 get_eigenpair(self,i): u_r = Function(self.V) u_im = Function(self.V) v_r, v_i = self.K.createVecs() eig = self.E.getEigenpair(i, v_r, v_i) if self.bcs: self.projector.scatter(vec_from=v_r, vec_to=u_r.vector().vec()) self.projector.scatter(vec_from=v_i, vec_to=u_im.vector().vec()) return eig, u_r, u_im
def interpolate_ic(time: Sequence[float], data: np.ndarray, receiving_function: df.Function, boundaries: Iterable[np.ndarray], wavespeed: float = 1.0) -> None: mixed_func_space = receiving_function.function_space() mesh = mixed_func_space.mesh() V = df.FunctionSpace(mesh, "CG", 1) # TODO: infer this somehow class InitialConditionInterpolator(df.UserExpression): def __init__(self, **kwargs): super().__init__(kwargs) self._ic_func = None self._nearest_edge_interpolator = NearestEdgeTree(boundaries) def set_interpolator(self, interpolation_function): self._ic_func = interpolation_function def eval(self, value, x): _, r = self._nearest_edge_interpolator.query(x) value[0] = self._ic_func(r / wavespeed) # TODO: 1D for now # value[0] = r # value[0] = self._ic_func(x[0]/wavespeed) # TODO: 1D for now ic_interpolator = InitialConditionInterpolator() # Copy functions to be able to assign to them subfunction_copy = receiving_function.split(deepcopy=True) for i, f in enumerate(subfunction_copy): # from IPython import embed; embed() # assert False ic_interpolator.set_interpolator( lambda x: np.interp(x, time, data[i, :])) assigner = df.FunctionAssigner(mixed_func_space.sub(i), V) assigner.assign(receiving_function.sub(i), df.project(ic_interpolator, V))
def FuelR_solver(FR_mesh, FR_facets, FR_f, FRod_info, D_post, R_path): Qv, Tfr_outer, FR_Tave = FRod_info # Reading mesh data stored in .xdmf files. mesh = Mesh() with XDMFFile(FR_mesh) as infile: infile.read(mesh) mvc = MeshValueCollection("size_t", mesh, 1) with XDMFFile(FR_facets) as infile: infile.read(mvc, "name_to_read") mf = cpp.mesh.MeshFunctionSizet(mesh, mvc) #File("Circle_facet.pvd").write(mf) # Mesh data print('FuelRod_mesh data\n', 'Number of cells: ', mesh.num_cells(), '\n Number of nodes: ', mesh.num_vertices()) # Define variational problem V = FunctionSpace(mesh, 'P', 1) u = Function(V) v = TestFunction(V) f = Constant(Qv) # Define boundary conditions base on pygmsh mesh mark bc = DirichletBC(V, Constant(Tfr_outer), mf, FR_f) # Variational formulation # Klbda_UO2 = Constant(K_UO2(FR_Tave)) F = K_UO2(u) * dot(grad(u), grad(v)) * dx - f * v * dx # Compute solution du = TrialFunction(V) Gain = derivative(F, u, du) solve(F==0, u, bc, J=Gain, \ solver_parameters={"newton_solver": {"linear_solver": "lu", "relative_tolerance": 1e-9}}, \ form_compiler_parameters={"cpp_optimize": True, "representation": "uflacs", "quadrature_degree" : 2} ) # mumps # Save solution if D_post: fU_out = XDMFFile(os.path.join(R_path, 'FuelRod', 'u.xdmf')) fU_out.write_checkpoint(u, "T", 0, XDMFFile.Encoding.HDF5, False) fU_out.close()
def apply_bc_and_block_bc_vector_non_linear(rhs, block_rhs, block_bcs, block_V): if block_bcs is None: return (None, None) N = len(block_bcs) assert N in (1, 2) if N == 1: function = Function(block_V[0]) [bc.apply(rhs, function.vector()) for bc in block_bcs[0]] block_function = BlockFunction(block_V) block_bcs.apply(block_rhs, block_function.block_vector()) return (function, block_function) else: function1 = Function(block_V[0]) [bc1.apply(rhs[0], function1.vector()) for bc1 in block_bcs[0]] function2 = Function(block_V[1]) [bc2.apply(rhs[1], function2.vector()) for bc2 in block_bcs[1]] block_function = BlockFunction(block_V) block_bcs.apply(block_rhs, block_function.block_vector()) return ((function1, function2), block_function)
def _compute_time_errors(problem, method, mesh_sizes, Dt, plot_error=False): mesh_generator, solution, ProblemClass, _ = problem() # Translate data into FEniCS expressions. fenics_sol = Expression(sympy.printing.ccode(solution), degree=MAX_DEGREE, t=0.0) # Compute the problem errors = numpy.empty((len(mesh_sizes), len(Dt))) # Create initial state. # Deepcopy the expression into theta0. Specify the cell to allow for # more involved operations with it (e.g., grad()). theta0 = Expression(fenics_sol.cppcode, degree=MAX_DEGREE, t=0.0) for k, mesh_size in enumerate(mesh_sizes): mesh = mesh_generator(mesh_size) # Choose the function space such that the exact solution can be # represented as well as possible. V = FunctionSpace(mesh, 'CG', 4) theta_approx = Function(V) theta0p = project(theta0, V) stepper = method(ProblemClass(V)) if plot_error: error = Function(V) for j, dt in enumerate(Dt): # TODO We are facing a little bit of a problem here, being the fact # that the time stepper only accept elements from V as u0. In # principle, though, this isn't necessary or required. We could # allow for arbitrary expressions here, but then the API would need # changing for problem.lhs(t, u). Think about this. theta_approx.assign(stepper.step(theta0p, 0.0, dt)) fenics_sol.t = dt # NOTE # When using errornorm(), it is quite likely to see a good part of # the error being due to the spatial discretization. Some analyses # "get rid" of this effect by (sometimes implicitly) projecting the # exact solution onto the discrete function space. errors[k][j] = errornorm(fenics_sol, theta_approx) if plot_error: error.assign(project(fenics_sol - theta_approx, V)) plot(error, title='error (dt={:e})'.format(dt)) plt.show() return errors
def __init__(self, V, **kwargs): # Call parent ParametrizedProblem.__init__(self, os.path.join("test_eim_approximation_12_tempdir", expression_type, basis_generation, "mock_problem")) # Minimal subset of a ParametrizedDifferentialProblem self.V = V self._solution = Function(V) self.components = ["u"] # Parametrized function to be interpolated x = SpatialCoordinate(V.mesh()) mu = SymbolicParameters(self, V, (1., )) self.f = (1-x[0])*cos(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(f*g*dx)
def overlap_error_norms(self, u1, u2): V12 = self.VO B1 = self.B1 B2 = self.B2 u12 = Function(V12) u21 = Function(V12) u12.vector()[:] = B1 * u1.vector() u21.vector()[:] = B2 * u2.vector() error = ((u12 - u21)**2) * dx L2 = assemble(error) semi_error = inner(grad(u12) - grad(u21), grad(u12) - grad(u21)) * dx H1 = L2 + assemble(semi_error) return L2, H1
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)) @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
def initialize(self, V, Q, PS, D): super(Problem, self).initialize(V, Q, PS, D) print("IC type: " + self.ic) print("Velocity scale factor = %4.2f" % self.factor) reynolds = 728.761 * self.factor / self.args.nufactor print("Computing with Re = %f" % reynolds) self.v_in = Function(V) print('Initializing error control') self.load_precomputed_bessel_functions(PS) self.solution = self.assemble_solution(0.0) # set constants for self.area = assemble( interpolate(Expression("1.0", degree=1), Q) * self.dsIn) # inflow area # womersley = steady + e^iCt, e^iCt has average 0 self.pg_normalization_factor.append( womersleyBC.average_analytic_pressure_grad(self.factor)) self.p_normalization_factor.append( norm(interpolate( womersleyBC.average_analytic_pressure_expr(self.factor), self.pSpace), norm_type='L2')) self.vel_normalization_factor.append( norm(interpolate( womersleyBC.average_analytic_velocity_expr(self.factor), self.vSpace), norm_type='L2')) one = (interpolate(Expression('1.0', degree=1), Q)) self.outflow_area = assemble(one * self.dsOut) print('Outflow area:', self.outflow_area)
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)) @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] * x[:, 1] u = Expression(expr_eval, shape=(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 hess(self, x, y=None, apply_bcs=True, **kwargs): """Evaluate the Hessian matrix of the Lagrangian at (x,y). :parameters: :x: NumPy ``array`` or Dolfin ``Expression`` :y: Numpy ``array`` or Dolfin ``Expression`` :apply_bcs: apply boundary conditions to ``x`` prior to evaluation. If ``x`` and/or ``y`` are ``Expression``s, they must defined on the appropriate function spaces, by, e.g., declaring it as:: Expression('x[0]*sin(x[1])', element=pdenlp.function_space.ufl_element()) where ``pdenlp`` is a ``PDENPLModel`` instance. """ obj_weight = kwargs.get('obj_weight', 1.0) if self.__objective_hessian is None: self.compile_objective_hessian() self.assign_vector(x, apply_bcs=apply_bcs) H = obj_weight * assemble(self.__objective_hessian) if self.ncon > 0 and y is not None: if self.__constraint_jacobian is None: self.compile_constraint_jacobian() v = Function(self.__dual_function_space) v.vector()[:] = -y # ∑ⱼ yⱼ Hⱼ(u) may be viewed as the directional derivative # of J(.) with respect to u in the direction y. H += assemble(derivative(self.__constraint_jacobian, self.__u, v)) return H
def control_array(self): """A serialized representation of the farm based on the controls. :returns: A serialized representation of the farm based on the controls. :rtype: numpy.ndarray """ if self._turbine_specification.smeared: m = Function(self._turbine_function_space) else: raise NotImplementedError( "Don't know how to produce a control array for this type of farm" ) return m
def __init__(self, mesh0=UnitCubeMesh(8, 8, 8), params={}): parameters['form_compiler']['representation'] = 'uflacs' parameters['form_compiler']['optimize'] = True parameters['form_compiler']['quadrature_degree'] = 4 self.mesh0 = Mesh(mesh0) self.mesh = Mesh(mesh0) if not 'C1' in params: params['C1'] = 100 self.params = params self.b = Constant((0.0, 0.0, 0.0)) self.h = Constant((0.0, 0.0, 0.0)) self.C0 = FunctionSpace(self.mesh0, "Lagrange", 2) self.V0 = VectorFunctionSpace(self.mesh0, "Lagrange", 1) self.W0 = TensorFunctionSpace(self.mesh0, "Lagrange", 1) self.C = FunctionSpace(self.mesh, "Lagrange", 2) self.V = VectorFunctionSpace(self.mesh, "Lagrange", 1) self.W = TensorFunctionSpace(self.mesh, "Lagrange", 1) self.G = project(Identity(3), self.W0) self.ut = Function(self.V0) self.du = TestFunction(self.V0) self.w = TrialFunction(self.V0) self.n0 = FacetNormal(self.mesh0) self.v = Function(self.V) self.t = 0.0
def vector2Function(x, Vh, **kwargs): """ Wrap a finite element vector x into a finite element function in the space Vh. kwargs is optional keywords arguments to be passed to the construction of a dolfin Function """ fun = Function(Vh, **kwargs) fun.vector().zero() fun.vector().axpy(1., x) return fun
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