def _solveTangentProblem(self, dstate, m_hat, x): """ The predictor step for the parameter continuation algorithm. """ state_fun = vector2Function(x[STATE], self.Vh[STATE]) statel_fun = vector2Function(x[STATE], self.Vh[STATE]) param_fun = vector2Function(x[PARAMETER], self.Vh[PARAMETER]) param_hat_fun = vector2Function(m_hat, self.Vh[PARAMETER]) x_test = [ dl.TestFunction(self.Vh[STATE]), dl.TestFunction(self.Vh[PARAMETER]) ] x_trial = [ dl.TrialFunction(self.Vh[STATE]), dl.TrialFunction(self.Vh[PARAMETER]) ] res = self.model.residual(state_fun, x_test[STATE], dl.Constant(0.), param_fun, None, statel_fun, True) Aform = dl.derivative(res, state_fun, x_trial[STATE]) + dl.derivative( res, statel_fun, x_trial[STATE]) b_form = dl.derivative(res, param_fun, param_hat_fun) A, b = dl.assemble_system(Aform, b_form, self.bcs0, form_compiler_parameters=self.fcp) solver = dl.PETScLUSolver() solver.set_operator(A) solver.solve(dstate, -b)
def __init__(self, model, particle, variation, kernel, options, comm): self.model = model self.particle = particle # number of particles self.variation = variation self.kernel = kernel self.options = options self.comm = comm self.rank = comm.Get_rank() self.nproc = comm.Get_size() self.save_kernel = options["save_kernel"] self.type_Hessian = options["type_Hessian"] self.ncalls = 0 self.gls = GlobalLocalSwitch(self.model, self.particle, self.options, self.comm) if not self.options["is_projection"]: if self.particle.number_particles_all == 1: z_trial = dl.TrialFunction(self.gls.Vh_Local) z_test = dl.TestFunction(self.gls.Vh_Local) self.Hessian = dl.assemble(z_trial * z_test * dl.dx) else: z_vec = [None] * particle.number_particles_all c_vec = [None] * particle.number_particles_all for n in range(particle.number_particles_all): z_trial = dl.TrialFunction(self.gls.Vh_Global.sub(0)) z_test = dl.TestFunction(self.gls.Vh_Global.sub(0)) z_vec[n] = z_trial c_vec[n] = z_test z_vec = dl.as_vector(z_vec) c_vec = dl.as_vector(c_vec) self.Hessian = dl.assemble(dl.dot(c_vec, z_vec) * dl.dx)
def __init__(self, parameters, mesh_name, facet_name, bc_dict={ "obstacle": 2, "channel_walls": 1, "inlet": 3, "outlet": 4 }): """ Create the required function spaces, functions and boundary conditions for a channel flow problem """ self.bc_dict = bc_dict self.mesh = df.Mesh() with df.XDMFFile(mesh_name) as infile: infile.read(self.mesh) mvc = df.MeshValueCollection("size_t", self.mesh, self.mesh.topology().dim() - 1) with df.XDMFFile(facet_name) as infile: infile.read(mvc, "name_to_read") self.mf = mf = df.cpp.mesh.MeshFunctionSizet(self.mesh, mvc) self.V = V = df.VectorFunctionSpace(self.mesh, 'P', parameters["degree velocity"]) self.Q = Q = df.FunctionSpace(self.mesh, 'P', parameters["degree pressure"]) self.rho = df.Constant(parameters["density [kg/m3]"]) self.mu = df.Constant(parameters["viscosity [Pa*s]"]) self.dt = df.Constant(parameters["dt [s]"]) self.g = df.Constant((0, 0)) self.vu, self.vp = df.TestFunction(V), df.TestFunction(Q) self.u_, self.p_ = df.Function(V), df.Function(Q) self.u_1, self.p_1 = df.Function(V), df.Function(Q) self.u_k, self.p_k = df.Function(V), df.Function(Q) self.u, self.p = df.TrialFunction(V), df.TrialFunction(Q) # unknown! self.U_m = U_m = parameters["velocity [m/s]"] x = [0, .41 / 2] # center of the channel Ucenter = 4. * U_m * x[1] * (.41 - x[1]) / (.41 * .41) U0_str = "4.*U_m*x[1]*(.41-x[1])/(.41*.41)" self.U_mean = np.mean(2 / 3 * Ucenter) U0 = df.Expression((U0_str, "0"), U_m=U_m, degree=2) bc0 = df.DirichletBC(V, df.Constant((0, 0)), mf, bc_dict["obstacle"]) bc1 = df.DirichletBC(V, df.Constant((0, 0)), mf, bc_dict["channel_walls"]) bc2 = df.DirichletBC(V, U0, mf, bc_dict["inlet"]) bc3 = df.DirichletBC(Q, df.Constant(0), mf, bc_dict["outlet"]) self.bcu = [bc0, bc1, bc2] self.bcp = [bc3] self.ds_ = df.Measure("ds", domain=self.mesh, subdomain_data=mf) return
def setUp(self): mesh = dl.UnitSquareMesh(10, 10) self.mpi_rank = dl.MPI.rank(mesh.mpi_comm()) self.mpi_size = dl.MPI.size(mesh.mpi_comm()) Vh1 = dl.FunctionSpace(mesh, 'Lagrange', 1) uh, vh = dl.TrialFunction(Vh1), dl.TestFunction(Vh1) mh, test_mh = dl.TrialFunction(Vh1), dl.TestFunction(Vh1) ## Set up B ndim = 2 ntargets = 200 np.random.seed(seed=1) targets = np.random.uniform(0.1, 0.9, [ntargets, ndim]) B = assemblePointwiseObservation(Vh1, targets) ## Set up Asolver alpha = dl.Constant(1.0) varfA = ufl.inner(ufl.grad(uh), ufl.grad(vh))*ufl.dx +\ alpha*ufl.inner(uh,vh)*ufl.dx A = dl.assemble(varfA) Asolver = PETScKrylovSolver(A.mpi_comm(), "cg", amg_method()) Asolver.set_operator(A) Asolver.parameters["maximum_iterations"] = 100 Asolver.parameters["relative_tolerance"] = 1e-12 ## Set up C varfC = ufl.inner(mh, vh) * ufl.dx C = dl.assemble(varfC) self.Hop = Hop(B, Asolver, C) ## Set up RHS Matrix M. varfM = ufl.inner(mh, test_mh) * ufl.dx self.M = dl.assemble(varfM) self.Minv = PETScKrylovSolver(self.M.mpi_comm(), "cg", amg_method()) self.Minv.set_operator(self.M) self.Minv.parameters["maximum_iterations"] = 100 self.Minv.parameters["relative_tolerance"] = 1e-12 myRandom = Random(self.mpi_rank, self.mpi_size) x_vec = dl.Vector(mesh.mpi_comm()) self.Hop.init_vector(x_vec, 1) k_evec = 10 p_evec = 50 self.Omega = MultiVector(x_vec, k_evec + p_evec) self.k_evec = k_evec myRandom.normal(1., self.Omega)
def setup_fnc_spaces(self): """ Call me again if the mesh is modified, like after adaptive meshing. """ # Linear Lagrange triangles for the velocity. self.v_fnc_space = dfn.FunctionSpace(self.mesh, "CG", 1) self.v = dfn.TrialFunction(self.v_fnc_space) self.vt = dfn.TestFunction(self.v_fnc_space) # We use piecewise constant discontinuous elements so that # no matrix inversion is required in order to update the stress self.S_fnc_space = dfn.VectorFunctionSpace(self.mesh, "DG", 0) self.S = dfn.TrialFunction(self.S_fnc_space) self.St = dfn.TestFunction(self.S_fnc_space)
def __init__(self, adjoint = False): self.dt = dol.Constant(0) self.uold = dol.interpolate(self.u0_expr, self.V) self.u0 = dol.interpolate(self.u0_expr, self.V) self.unew = dol.Function(self.V) self.ulow = dol.Function(self.V) self.v = dol.TestFunction(self.V) self.utrial = dol.TrialFunction(self.V) if adjoint: self.zold = dol.interpolate(self.z0_expr, self.V) self.z0 = dol.interpolate(self.z0_expr, self.V) self.znew = dol.Function(self.V) self.ztrial = dol.TrialFunction(self.V)
def testblockdiagonal(): mesh = dl.UnitSquareMesh(40, 40) V1 = dl.FunctionSpace(mesh, "Lagrange", 2) test1, trial1 = dl.TestFunction(V1), dl.TrialFunction(V1) V2 = dl.FunctionSpace(mesh, "Lagrange", 2) test2, trial2 = dl.TestFunction(V2), dl.TrialFunction(V2) V1V2 = createMixedFS(V1, V2) test12, trial12 = dl.TestFunction(V1V2), dl.TrialFunction(V1V2) bd = BlockDiagonal(V1, V2, mesh.mpi_comm()) mpirank = dl.MPI.rank(mesh.mpi_comm()) if mpirank == 0: print 'mass+mass' M1 = dl.assemble(dl.inner(test1, trial1) * dl.dx) M2 = dl.assemble(dl.inner(test1, trial2) * dl.dx) M12bd = bd.assemble(M1, M2) M12 = dl.assemble(dl.inner(test12, trial12) * dl.dx) diff = M12bd - M12 nn = diff.norm('frobenius') if mpirank == 0: print '\nnn={}'.format(nn) if mpirank == 0: print 'mass+2ndD' D2 = dl.assemble( dl.inner(dl.nabla_grad(test1), dl.nabla_grad(trial2)) * dl.dx) M1D2bd = bd.assemble(M1, D2) tt1, tt2 = test12 tl1, tl2 = trial12 M1D2 = dl.assemble( dl.inner(tt1, tl1) * dl.dx + dl.inner(dl.nabla_grad(tt2), dl.nabla_grad(tl2)) * dl.dx) diff = M1D2bd - M1D2 nn = diff.norm('frobenius') if mpirank == 0: print 'nn={}'.format(nn) if mpirank == 0: print 'wM+wM' u11 = dl.interpolate(dl.Expression("x[0]*x[1]", degree=10), V1) u22 = dl.interpolate(dl.Expression("11+x[0]+x[1]", degree=10), V2) M1 = dl.assemble(dl.inner(u11 * test1, trial1) * dl.dx) M2 = dl.assemble(dl.inner(u22 * test1, trial2) * dl.dx) M12bd = bd.assemble(M1, M2) ua, ub = dl.interpolate(dl.Expression(("x[0]*x[1]", "11+x[0]+x[1]"),\ degree=10), V1V2) M12 = dl.assemble( dl.inner(ua * tt1, tl1) * dl.dx + dl.inner(ub * tt2, tl2) * dl.dx) diff = M12bd - M12 nn = diff.norm('frobenius') if mpirank == 0: print 'nn={}'.format(nn)
def get_initial_conditions(self,rho_solute=const.rhom): """ Set the initial condition at the end of melting (melting can be solved analytically """ # --- Initial states --- # # ice temperature self.u0_i = dolfin.Function(self.ice_V) T,lam,self.R_melt,self.t_melt = analyticalMelt(np.exp(self.ice_coords[:,0])*self.R_melt,self.T_inf,self.Q_initialize,R_target=self.R_melt) self.u0_i.vector()[:] = T/abs(self.T_inf) # solution temperature self.u0_s = dolfin.Function(self.sol_V) T,lam,self.R_melt,self.t_melt = analyticalMelt(np.exp(self.sol_coords[:,0])*self.R_melt,self.T_inf,self.Q_initialize,R_target=self.R_melt) self.u0_s.vector()[:] = T/abs(self.T_inf) # solution concentration self.u0_c = dolfin.interpolate(dolfin.Constant(self.C_init),self.sol_V) # --- Time Array --- # # Now that we have the melt-out time, we can define the time array self.ts = np.arange(self.t_melt,self.t_final+self.dt,self.dt)/self.t0 self.dt /= self.t0 # Define the ethanol source self.source_timing = self.ts[np.argmin(abs(self.ts-self.source_timing/self.t0))] if 'gaussian_source' in self.flags: self.source_duration /= self.t0 self.source = self.source_mass_final/(self.source_duration*np.sqrt(np.pi))*np.exp(-((self.ts-self.source_timing)/self.source_duration)**2.) else: self.source = np.zeros_like(self.ts) self.source[np.argmin(abs(self.ts-self.source_timing))] = self.source_mass_final/self.dt # --- Define the test and trial functions --- # self.u_i = dolfin.TrialFunction(self.ice_V) self.v_i = dolfin.TestFunction(self.ice_V) self.T_i = dolfin.Function(self.ice_V) self.u_s = dolfin.TrialFunction(self.sol_V) self.v_s = dolfin.TestFunction(self.sol_V) self.T_s = dolfin.Function(self.sol_V) self.C = dolfin.Function(self.sol_V) self.Tf = Tf_depression(self.C,linear=True)/abs(self.T_inf) self.Tf_wall = dolfin.project(self.Tf,self.sol_V).vector()[self.sol_idx_wall] # Get the updated solution properties self.rhos = dolfin.project(dolfin.Expression('C + rhow*(1.-C/rho)',degree=1,C=self.C,rhow=const.rhow,rho=rho_solute),self.sol_V) self.cs = dolfin.project(dolfin.Expression('ce*(C/rho) + cw*(1.-C/rho)',degree=1,C=self.C,cw=const.cw,ce=const.ce,rho=rho_solute),self.sol_V) self.ks = dolfin.project(dolfin.Expression('ke*(C/rho) + kw*(1.-C/rho)',degree=1,C=self.C,kw=const.kw,ke=const.ke,rho=rho_solute),self.sol_V) self.rhos_wall = self.rhos.vector()[self.sol_idx_wall] self.cs_wall = self.cs.vector()[self.sol_idx_wall] self.ks_wall = self.ks.vector()[self.sol_idx_wall] self.flags.append('get_ic')
def setUp(self): mesh = dl.UnitSquareMesh(10, 10) self.mpi_rank = dl.MPI.rank(mesh.mpi_comm()) self.mpi_size = dl.MPI.size(mesh.mpi_comm()) Vh1 = dl.FunctionSpace(mesh, 'Lagrange', 1) uh, vh = dl.TrialFunction(Vh1), dl.TestFunction(Vh1) mh = dl.TrialFunction(Vh1) # Define B ndim = 2 ntargets = 10 np.random.seed(seed=1) targets = np.random.uniform(0.1, 0.9, [ntargets, ndim]) B = assemblePointwiseObservation(Vh1, targets) # Define Asolver alpha = dl.Constant(0.1) varfA = dl.inner(dl.nabla_grad(uh), dl.nabla_grad(vh))*dl.dx +\ alpha*dl.inner(uh,vh)*dl.dx A = dl.assemble(varfA) Asolver = dl.PETScKrylovSolver(A.mpi_comm(), "cg", amg_method()) Asolver.set_operator(A) Asolver.parameters["maximum_iterations"] = 100 Asolver.parameters["relative_tolerance"] = 1e-12 # Define M varfC = dl.inner(mh, vh) * dl.dx C = dl.assemble(varfC) self.J = J_op(B, Asolver, C) self.k_evec = 10 p_evec = 50 myRandom = Random(self.mpi_rank, self.mpi_size) x_vec = dl.Vector(C.mpi_comm()) C.init_vector(x_vec, 1) self.Omega = MultiVector(x_vec, self.k_evec + p_evec) myRandom.normal(1., self.Omega) y_vec = dl.Vector(C.mpi_comm()) B.init_vector(y_vec, 0) self.Omega_adj = MultiVector(y_vec, self.k_evec + p_evec) myRandom.normal(1., self.Omega_adj)
def delta_dg(mesh, expr): CG = df.FunctionSpace(mesh, "CG", 1) DG = df.FunctionSpace(mesh, "DG", 0) CG3 = df.VectorFunctionSpace(mesh, "CG", 1) DG3 = df.VectorFunctionSpace(mesh, "DG", 0) m = df.interpolate(expr, DG3) n = df.FacetNormal(mesh) u_dg = df.TrialFunction(DG) v_dg = df.TestFunction(DG) u3 = df.TrialFunction(CG3) v3 = df.TestFunction(CG3) a = u_dg * df.inner(v3, n) * df.ds - u_dg * df.div(v3) * df.dx mm = m.vector().array() mm.shape = (3, -1) K = df.assemble(a).array() L3 = df.assemble(df.dot(v3, df.Constant([1, 1, 1])) * df.dx).array() f = np.dot(K, mm[0]) / L3 fun1 = df.Function(CG3) fun1.vector().set_local(f) df.plot(fun1) a = df.div(u3) * v_dg * df.dx A = df.assemble(a).array() L = df.assemble(v_dg * df.dx).array() h = np.dot(A, f) / L fun = df.Function(DG) fun.vector().set_local(h) df.plot(fun) res = [] for x in xs: res.append(fun(x, 5, 0.5)) """ fun2 =df.interpolate(fun, df.VectorFunctionSpace(mesh, "CG", 1)) file = df.File('field2.pvd') file << fun2 """ return res
def _get_rtmass(self,output_petsc=True): """ Get the square root of assembled mass matrix M using lumping. --credit to: Umberto Villa """ test = df.TestFunction(self.V) V_deg = self.V.ufl_element().degree() try: V_q_fe = df.FiniteElement('Quadrature',self.V.mesh().ufl_cell(),2*V_deg,quad_scheme='default') V_q = df.FunctionSpace(self.V.mesh(),V_q_fe) except: print('Use FiniteElement in specifying FunctionSpace after version 1.6.0!') V_q = df.FunctionSpace(self.V.mesh(), 'Quadrature', 2*self.V._FunctionSpace___degree) trial_q = df.TrialFunction(V_q) test_q = df.TestFunction(V_q) M_q = df.PETScMatrix() df.assemble(trial_q*test_q*df.dx,tensor=M_q,form_compiler_parameters={'quadrature_degree': 2*V_deg}) ones = df.interpolate(df.Constant(1.), V_q).vector() dM_q = M_q*ones M_q.zero() dM_q_2fill = ones.array() / np.sqrt(dM_q.array() ) dM_q.set_local( dM_q_2fill ) M_q.set_diagonal(dM_q) mixedM = df.PETScMatrix() df.assemble(trial_q*test*df.dx,tensor=mixedM,form_compiler_parameters={'quadrature_degree': 2*V_deg}) if output_petsc and df.has_petsc4py(): rtM = df.PETScMatrix(df.as_backend_type(mixedM).mat().matMult(df.as_backend_type(M_q).mat())) else: rtM = sps.csr_matrix(mixedM.array()*dM_q_2fill) csr_trim0(rtM,1e-12) return rtM
def __init__(self, simulation, u_conv): """ Given a velocity in DG, e.g DG2, produce a velocity in DGT0, i.e. a constant on each facet """ V = u_conv[0].function_space() V_dgt0 = dolfin.FunctionSpace(V.mesh(), 'DGT', 0) u = dolfin.TrialFunction(V_dgt0) v = dolfin.TestFunction(V_dgt0) ndim = simulation.ndim w = u_conv w_new = dolfin.as_vector( [dolfin.Function(V_dgt0) for _ in range(ndim)]) dot, avg, dS, ds = dolfin.dot, dolfin.avg, dolfin.dS, dolfin.ds a = dot(avg(u), avg(v)) * dS + dot(u, v) * ds L = [] for d in range(ndim): L.append(avg(w[d]) * avg(v) * dS + w[d] * v * ds) self.lhs = [dolfin.Form(Li) for Li in L] self.A = dolfin.assemble(a) self.solver = dolfin.PETScKrylovSolver('cg') self.velocity = simulation.data['u_conv_dgt0'] = w_new
def test_basic_interior_facet_assembly(): ghost_mode = dolfin.cpp.mesh.GhostMode.none if (dolfin.MPI.size(dolfin.MPI.comm_world) > 1): ghost_mode = dolfin.cpp.mesh.GhostMode.shared_facet mesh = dolfin.RectangleMesh( dolfin.MPI.comm_world, [numpy.array([0.0, 0.0, 0.0]), numpy.array([1.0, 1.0, 0.0])], [5, 5], cell_type=dolfin.cpp.mesh.CellType.Type.triangle, ghost_mode=ghost_mode) V = dolfin.function.FunctionSpace(mesh, ("DG", 1)) u, v = dolfin.TrialFunction(V), dolfin.TestFunction(V) a = ufl.inner(ufl.avg(u), ufl.avg(v)) * ufl.dS A = dolfin.fem.assemble_matrix(a) A.assemble() assert isinstance(A, PETSc.Mat) L = ufl.conj(ufl.avg(v)) * ufl.dS b = dolfin.fem.assemble_vector(L) b.assemble() assert isinstance(b, PETSc.Vec)
def linear_solver(self, phi_k): # cast params as constant functions so that, if they are set to 0, FEniCS still understand # what is being integrated mu, M = Constant(self.physics.mu), Constant(self.physics.M) lam = Constant(self.physics.lam) mn, mf = Constant(self.mn), Constant(self.mf) D = self.physics.D # boundary condition Dirichlet_bc = self.get_Dirichlet_bc() # trial and test function phi = d.TrialFunction(self.fem.S) v = d.TestFunction(self.fem.S) # r^(D-1) rD = Expression('pow(x[0],D-1)', D=D, degree=self.fem.func_degree) # bilinear form a and linear form L a = - inner( grad(phi), grad(v) ) * rD * dx + ( (mu/mn)**2 \ - 3.*lam*(mf/mn)**2*phi_k**2 ) * phi * v * rD * dx L = ((mn**(D - 2.) / (mf * M)) * self.source.rho - 2. * lam * (mf / mn)**2 * phi_k**3) * v * rD * dx # define a vector with the solution sol = d.Function(self.fem.S) # solve linearised system pde = d.LinearVariationalProblem(a, L, sol, Dirichlet_bc) solver = d.LinearVariationalSolver(pde) solver.solve() return sol
def assembleA(self, x, assemble_adjoint=False, assemble_rhs=False): """ Assemble the matrices and rhs for the forward/adjoint problems """ trial = dl.TrialFunction(self.Vh[STATE]) test = dl.TestFunction(self.Vh[STATE]) c = vector2Function(x[PARAMETER], self.Vh[PARAMETER]) Avarf = dl.inner( dl.exp(c) * dl.nabla_grad(trial), dl.nabla_grad(test)) * dl.dx if not assemble_adjoint: bform = dl.inner(self.f, test) * dl.dx Matrix, rhs = dl.assemble_system(Avarf, bform, self.bc) else: # Assemble the adjoint of A (i.e. the transpose of A) s = vector2Function(x[STATE], self.Vh[STATE]) bform = dl.inner(dl.Constant(0.), test) * dl.dx Matrix, _ = dl.assemble_system(dl.adjoint(Avarf), bform, self.bc0) Bu = -(self.B * x[STATE]) Bu += self.u_o rhs = dl.Vector() self.B.init_vector(rhs, 1) self.B.transpmult(Bu, rhs) rhs *= 1.0 / self.noise_variance if assemble_rhs: return Matrix, rhs else: return Matrix
def run_model(kappa,forcing,function_space,boundary_conditions=None): """ Solve complex valued Helmholtz equation by solving coupled system, one for the real part of the solution one for the imaginary part. """ mesh = function_space.mesh() kappa_sq = kappa**2 if boundary_conditions==None: bndry_obj = dl.CompiledSubDomain("on_boundary") boundary_conditions = [['dirichlet',bndry_obj,[0,0]]] num_bndrys = len(boundary_conditions) boundaries = mark_boundaries(mesh,boundary_conditions) dirichlet_bcs = collect_dirichlet_boundaries( function_space,boundary_conditions,boundaries) # To express integrals over the boundary parts using ds(i), we must first # redefine the measure ds in terms of our boundary markers: ds = dl.Measure('ds', domain=mesh, subdomain_data=boundaries) #dx = dl.Measure('dx', domain=mesh) dx = dl.dx (pr, pi) = dl.TrialFunction(function_space) (vr, vi) = dl.TestFunction(function_space) # real part bilinear_form = kappa_sq*(pr*vr - pi*vi)*dx bilinear_form += (-dl.inner(dl.nabla_grad(pr),dl.nabla_grad(vr))+ dl.inner(dl.nabla_grad(pi),dl.nabla_grad(vi)))*dx # imaginary part bilinear_form += kappa_sq*(pr*vi + pi*vr)*dx bilinear_form += -(dl.inner(dl.nabla_grad(pr),dl.nabla_grad(vi))+ dl.inner(dl.nabla_grad(pi),dl.nabla_grad(vr)))*dx for ii in range(num_bndrys): if (boundary_conditions[ii][0]=='robin'): alpha_real, alpha_imag = boundary_conditions[ii][3] bilinear_form -= alpha_real*(pr*vr-pi*vi)*ds(ii) bilinear_form -= alpha_imag*(pr*vi+pi*vr)*ds(ii) forcing_real,forcing_imag=forcing rhs = (forcing_real*vr+forcing_real*vi+forcing_imag*vr-forcing_imag*vi)*dx for ii in range(num_bndrys): if ((boundary_conditions[ii][0]=='robin') or (boundary_conditions[ii][0]=='neumann')): beta_real, beta_imag=boundary_conditions[ii][2] # real part of robin boundary conditions rhs+=(beta_real*vr - beta_imag*vi)*ds(ii) # imag part of robin boundary conditions rhs+=(beta_real*vi + beta_imag*vr)*ds(ii) # compute solution p = dl.Function(function_space) #solve(a == L, p) dl.solve(bilinear_form == rhs, p, bcs=dirichlet_bcs) return p
def solve_initial_pressure(w_NSp, p, q, u, v, bcs_NSp, M_, g_, phi_, rho_, rho_e_, V_, drho, sigma_bar, eps, grav, dveps, enable_PF, enable_EC): V = u.function_space() grad_p = df.TrialFunction(V) grad_p_out = df.Function(V) F_grad_p = (df.dot(grad_p, v) * df.dx - rho_ * df.dot(grav, v) * df.dx) if enable_PF: F_grad_p += -drho * M_ * df.inner(df.grad(u), df.outer(df.grad(g_), v)) * df.dx F_grad_p += -sigma_bar * eps * df.inner( df.outer(df.grad(phi_), df.grad(phi_)), df.grad(v)) * df.dx if enable_EC and rho_e_ != 0: F_grad_p += rho_e_ * df.dot(df.grad(V_), v) * df.dx if enable_PF and enable_EC: F_grad_p += dveps * df.dot(df.grad(phi_), v) * df.dot( df.grad(V_), df.grad(V_)) * df.dx info_red("Solving initial grad_p...") df.solve(df.lhs(F_grad_p) == df.rhs(F_grad_p), grad_p_out) F_p = (df.dot(df.grad(q), df.grad(p)) * df.dx - df.dot(df.grad(q), grad_p_out) * df.dx) info_red("Solving initial p...") df.solve(df.lhs(F_p) == df.rhs(F_p), w_NSp, bcs_NSp)
def get_initial_conditions(self,melt_velocity=-1./3600.): """ Set the initial condition to no melted ice and all at the bulk ice temperature Parameters ---------- melt_velocity: float velocity of the downgoing drill (m/s) """ # --- Initial states --- # # ice temperature self.u0_i = dolfin.interpolate(dolfin.Constant(self.Tstar),self.ice_V) # the upward velocity is equal to negative the melt rate (the mesh is Lagrangian following the drill) self.velocity = dolfin.Expression('melt',melt=melt_velocity*self.t0,degree=1) # --- Time Array --- # # Now that we have the melt-out time, we can define the time array self.ts = np.arange(0.,self.t_final+self.dt,self.dt)/self.t0 self.dt /= self.t0 # --- Define the test and trial functions --- # self.u_i = dolfin.TrialFunction(self.ice_V) self.v_i = dolfin.TestFunction(self.ice_V) self.T_i = dolfin.Function(self.ice_V) self.flags.append('get_ic')
def solveFwd(self, state, x): """ Solve the possibly nonlinear forward problem: Given :math:`m`, find :math:`u` such that .. math:: \\delta_p F(u, m, p;\\hat{p}) = 0,\\quad \\forall \\hat{p}.""" self.n_calls["forward"] += 1 if self.solver is None: self.solver = self._createLUSolver() if self.is_fwd_linear: u = dl.TrialFunction(self.Vh[STATE]) m = vector2Function(x[PARAMETER], self.Vh[PARAMETER]) p = dl.TestFunction(self.Vh[ADJOINT]) res_form = self.varf_handler(u, m, p) A_form = ufl.lhs(res_form) b_form = ufl.rhs(res_form) A, b = dl.assemble_system(A_form, b_form, bcs=self.bc) self.solver.set_operator(A) self.solver.solve(state, b) else: u = vector2Function(x[STATE], self.Vh[STATE]) m = vector2Function(x[PARAMETER], self.Vh[PARAMETER]) p = dl.TestFunction(self.Vh[ADJOINT]) res_form = self.varf_handler(u, m, p) dl.solve(res_form == 0, u, self.bc) state.zero() state.axpy(1., u.vector())
def make_mass_matrix_unlumped(function_space_V): V = function_space_V u_trial = dl.TrialFunction(V) v_test = dl.TestFunction(V) mass_form = u_trial * v_test * dl.dx M = dl.assemble(mass_form) return M
def solve(self, vkscale=1., lscale=1., sscale=1.): """This approach only works for small grids since the memory requirements rapidly become prohibitive. (nl, nk, nv) = (8, 45, 40) is just barely doable on my laptop. If the memory is available, computation time is not significant. """ D = d.Function(self.tensor_space) # diffusion tensor Q = d.Function(self.scalar_space) # source term u = d.TrialFunction(self.scalar_space) # u is my 'f' v = d.TestFunction(self.scalar_space) soln = d.Function(self.scalar_space) a = d.dot(d.dot(D, d.grad(u)), d.grad(v)) * d.dx L = Q * v * d.dx equation = (a == L) soln = d.Function(self.scalar_space) bc = d.DirichletBC(self.scalar_space, d.Constant(0), direct_boundary) dbuf = np.zeros(D.vector().size()).reshape((-1, 3, 3)) dbuf[:,0,0] = self.D_VV * vkscale dbuf[:,1,0] = self.D_VK * vkscale dbuf[:,0,1] = self.D_VK * vkscale dbuf[:,1,1] = self.D_KK * vkscale dbuf[:,2,2] = self.D_LL * lscale D.vector()[:] = dbuf.reshape((-1,)) Q.vector()[:] = self.source_term * sscale d.solve(equation, soln, bc) return self.to_cube(soln.vector().array())
def _init_forms(self): logger.debug("Initialize forms mechanics problem") # Displacement and hydrostatic_pressure u, p = dolfin.split(self.state) v, q = dolfin.split(self.state_test) # Some mechanical quantities F = dolfin.variable(kinematics.DeformationGradient(u)) J = kinematics.Jacobian(F) dx = self.geometry.dx internal_energy = (self.material.strain_energy(F, ) + self.material.compressibility(p, J)) self._virtual_work = dolfin.derivative( internal_energy * dx, self.state, self.state_test, ) external_work = self._external_work(u, v) if external_work is not None: self._virtual_work += external_work self._set_dirichlet_bc() self._jacobian = dolfin.derivative( self._virtual_work, self.state, dolfin.TrialFunction(self.state_space), ) self._init_solver()
def test_custom_mesh_loop_cffi_rank2(set_vals): """Test numba assembler for bilinear form""" mesh = dolfin.generation.UnitSquareMesh(dolfin.MPI.comm_world, 64, 64) V = dolfin.FunctionSpace(mesh, ("Lagrange", 1)) # Test against generated code and general assembler u, v = dolfin.TrialFunction(V), dolfin.TestFunction(V) a = inner(u, v) * dx A0 = dolfin.fem.assemble_matrix(a) A0.assemble() A0.zeroEntries() start = time.time() dolfin.fem.assemble_matrix(A0, a) end = time.time() print("Time (C++, pass 2):", end - start) A0.assemble() # Unpack mesh and dofmap data c = mesh.topology.connectivity(2, 0).connections() pos = mesh.topology.connectivity(2, 0).pos() geom = mesh.geometry.points dofs = V.dofmap().dof_array A1 = A0.copy() for i in range(2): A1.zeroEntries() start = time.time() assemble_matrix_cffi(A1.handle, (c, pos), geom, dofs, set_vals, PETSc.InsertMode.ADD_VALUES) end = time.time() print("Time (Numba, pass {}): {}".format(i, end - start)) A1.assemble() assert (A1 - A0).norm() == pytest.approx(0.0)
def __init__(self, Vh, dX, bc, form=None): """ Constructor: - Vh: the finite element space for the state variable. - dX: the integrator on subdomain X where observation are presents. E.g. dX = dl.dx means observation on all \Omega and dX = dl.ds means observations on all \partial \Omega. - bc: If the forward problem imposes Dirichlet boundary conditions u = u_D on \Gamma_D; bc is a dl.DirichletBC object that prescribes homogeneuos Dirichlet conditions u = 0 on \Gamma_D. - form: if form = None we compute the L^2(X) misfit: \int_X (u - ud)^2 dX, otherwise the integrand specified in form will be used. """ if form is None: u, v = dl.TrialFunction(Vh), dl.TestFunction(Vh) self.W = dl.assemble(dl.inner(u, v) * dX) else: self.W = dl.assemble(form) if bc is not None: Wt = Transpose(self.W) self.bc.zero(Wt) self.W = Transpose(Wt) self.bc.zero(self.W) self.d = dl.Vector() self.W.init_vector(self.d, 1) self.noise_variance = 0
def __init__(self,V,sigma=1.25,s=0.0625,mean=None,rel_tol=1e-10,max_iter=100,**kwargs): self.V=V self.dim=V.dim() self.dof_coords=get_dof_coords(V) self.sigma=sigma self.s=s self.mean=mean self.mpi_comm=kwargs['mpi_comm'] if 'mpi_comm' in kwargs else df.mpi_comm_world() # mass matrix and its inverse M_form=df.inner(df.TrialFunction(V),df.TestFunction(V))*df.dx self.M=df.PETScMatrix() df.assemble(M_form,tensor=self.M) self.Msolver = df.PETScKrylovSolver("cg", "jacobi") self.Msolver.set_operator(self.M) self.Msolver.parameters["maximum_iterations"] = max_iter self.Msolver.parameters["relative_tolerance"] = rel_tol self.Msolver.parameters["error_on_nonconvergence"] = True self.Msolver.parameters["nonzero_initial_guess"] = False # square root of mass matrix self.rtM=self._get_rtmass() # kernel matrix and its square root self.K=self._get_ker() self.rtK = _get_sqrtm(self.K,'K') # set solvers for op in ['K']: operator=getattr(self, op) solver=self._set_solver(operator,op) setattr(self, op+'solver', solver) if mean is None: self.mean=df.Vector() self.init_vector(self.mean,0)
def custom_newton_solver(self): V = self.my_function_space_cls.V F = self.my_var_prob_cls.F #self.u = my_function_space_cls.u du = df.TrialFunction(V) #TrialFunctions --> wrong, without 's' Jac = df.derivative(F, self.u, du) absolute_tol = 1E-5 relative_tol = 9E-2 u_inc = df.Function(V) nIter = 0 relative_residual = 1 CONVERGED = True MAX_ITER = 5000 while relative_residual > relative_tol and nIter < MAX_ITER and CONVERGED: nIter += 1 A, b = df.assemble_system(Jac, -(F), []) df.solve(A, u_inc.vector(), b) #df.solve(F == 0, u_inc.vector(), [], J=Jac, solver_parameters={'newton_solver' : {'linear_solver' : 'mumps'}}) relative_residual = u_inc.vector().norm('l2') #a = df.assemble(F) residual = b.norm('l2') lmbda = 0.8 self.u.vector()[:] += lmbda * u_inc.vector() if residual > 1000: CONVERGED = False print("Did not converge after {} Iterations".format(nIter)) elif residual < absolute_tol: CONVERGED = False print("converged after {} Iterations".format(nIter)) print('{0:2d} {1:3.2E} {2:5e}'.format(nIter, relative_residual, residual))
def test_basic_assembly(): mesh = dolfin.generation.UnitSquareMesh(dolfin.MPI.comm_world, 12, 12) V = dolfin.FunctionSpace(mesh, ("Lagrange", 1)) u, v = dolfin.TrialFunction(V), dolfin.TestFunction(V) a = 1.0 * inner(u, v) * dx L = inner(1.0, v) * dx # Initial assembly A = dolfin.fem.assemble(a) b = dolfin.fem.assemble(L) assert isinstance(A, dolfin.cpp.la.PETScMatrix) assert isinstance(b, dolfin.cpp.la.PETScVector) # Second assembly A = dolfin.fem.assemble(A, a) b = dolfin.fem.assemble(b, L) assert isinstance(A, dolfin.cpp.la.PETScMatrix) assert isinstance(b, dolfin.cpp.la.PETScVector) # Function as coefficient f = dolfin.Function(V) a = f * inner(u, v) * dx A = dolfin.fem.assemble(a) assert isinstance(A, dolfin.cpp.la.PETScMatrix)
def get_distance_function(config, domains): V = dolfin.FunctionSpace(config.domain.mesh, "CG", 1) v = dolfin.TestFunction(V) d = dolfin.TrialFunction(V) sol = dolfin.Function(V) s = dolfin.interpolate(Constant(1.0), V) domains_func = dolfin.Function(dolfin.FunctionSpace(config.domain.mesh, "DG", 0)) domains_func.vector().set_local(domains.array().astype(numpy.float)) def boundary(x): eps_x = config.params["turbine_x"] eps_y = config.params["turbine_y"] min_val = 1 for e_x, e_y in [(-eps_x, 0), (eps_x, 0), (0, -eps_y), (0, eps_y)]: try: min_val = min(min_val, domains_func((x[0] + e_x, x[1] + e_y))) except RuntimeError: pass return min_val == 1.0 bc = dolfin.DirichletBC(V, 0.0, boundary) # Solve the diffusion problem with a constant source term log(INFO, "Solving diffusion problem to identify feasible area ...") a = dolfin.inner(dolfin.grad(d), dolfin.grad(v)) * dolfin.dx L = dolfin.inner(s, v) * dolfin.dx dolfin.solve(a == L, sol, bc) return sol
def __init__(me, function_space_V, initial_points=None): me.V = function_space_V me.N = me.V.dim() u_trial = dl.TrialFunction(me.V) v_test = dl.TestFunction(me.V) mass_form = u_trial * v_test * dl.dx me.M = dl.assemble(mass_form) me.constant_one_function = dl.interpolate(dl.Constant(1.0), me.V) me.NPPSS = NeumannPoissonSolver(me.V) me.solve_neumann_poisson = me.NPPSS.solve me.solve_neumann_point_source = me.NPPSS.solve_point_source me.points = list() me.impulse_responses = list() me.solve_S = lambda x: np.nan me.eta = np.zeros(me.num_pts) me.mu = np.nan me.smooth_basis = list() me.weighting_functions = list() if initial_points is not None: me.add_points(initial_points)
def __init__(self, V, kappa): ''' Parameters ---------- V : dolfin.FunctionSpace Function space. kappa : float Filter diffusivity constant. ''' if not isinstance(V, dolfin.FunctionSpace): raise TypeError( 'Parameter `V` must be of type `dolfin.FunctionSpace`.') v = dolfin.TestFunction(V) f = dolfin.TrialFunction(V) x = V.mesh().coordinates() l = (x.max(0) - x.min(0)).min() k = Constant(float(kappa) * l**2) a_M = f * v * dx a_D = k * dot(grad(f), grad(v)) * dx A = assemble(a_M + a_D) self._M = assemble(a_M) self.solver = dolfin.LUSolver(A, "mumps") self.solver.parameters["symmetric"] = True