def apply_vsources_to_matrix(self, A): # NB: Does not modify matrix in-place. # Return value must be used, e.g: # A = circuit.apply_vsources_to_matrix(A, b) # Charge constraints for group, row in zip(self.groups, self.rows_charge): ds_group = np.sum([self.dss(self.int_bnd_ids[i]) for i in group]) # ds_group = np.sum([self.dss(self.int_bnd_ids[i], degree=1) for i in group]) a0 = self.eps0 * df.inner(self.mu, df.dot(df.grad(self.phi), self.n)) * ds_group A0 = df.assemble(a0) cols, vals = A0.getrow(0) B = df.Matrix() self.compiled.addrow(A, B, cols, vals, row, self.V) A = B # Potential constraints for vsource, row in zip(self.vsources, self.rows_potential): obj_a_id = vsource[0] obj_b_id = vsource[1] cols = [] vals = [] if obj_a_id != -1: dof_a = self.objects[obj_a_id].get_free_row() cols.append(dof_a) vals.append(-1.0) if obj_b_id != -1: dof_b = self.objects[obj_b_id].get_free_row() cols.append(dof_b) vals.append(+1.0) cols = np.array(cols, dtype=np.uintp) vals = np.array(vals) B = df.Matrix() self.compiled.addrow(A, B, cols, vals, row, self.V) A = B return A
def Transpose(A): """ Compute the matrix transpose """ Amat = dl.as_backend_type(A).mat() AT = PETSc.Mat() Amat.transpose(AT) rmap, cmap = Amat.getLGMap() AT.setLGMap(cmap, rmap) return dl.Matrix(dl.PETScMatrix(AT))
def MatPtAP(A, P): """ Compute the triple matrix product :math:`P^T A P`. """ Amat = dl.as_backend_type(A).mat() Pmat = dl.as_backend_type(P).mat() out = Amat.PtAP(Pmat, fill=1.0) _, out_map = Pmat.getLGMap() out.setLGMap(out_map, out_map) return dl.Matrix(dl.PETScMatrix(out))
def MatAtB(A, B): """ Compute the matrix-matrix product :math:`A^T B`. """ Amat = dl.as_backend_type(A).mat() Bmat = dl.as_backend_type(B).mat() out = Amat.transposeMatMult(Bmat) _, rmap = Amat.getLGMap() _, cmap = Bmat.getLGMap() out.setLGMap(rmap, cmap) return dl.Matrix(dl.PETScMatrix(out))
def MatMatMult(A, B): """ Compute the matrix-matrix product :math:`AB`. """ Amat = df.as_backend_type(A).mat() Bmat = df.as_backend_type(B).mat() out = Amat.matMult(Bmat) rmap, _ = Amat.getLGMap() _, cmap = Bmat.getLGMap() out.setLGMap(rmap, cmap) return df.Matrix(df.PETScMatrix(out))
def _setup_imex_problem(self): assert hasattr(self, "_parameters") assert hasattr(self, "_mesh") assert hasattr(self, "_Wh") assert hasattr(self, "_coefficients") assert hasattr(self, "_one") assert hasattr(self, "_omega") assert hasattr(self, "_v0") assert hasattr(self, "_v00") assert hasattr(self, "_T0") assert hasattr(self, "_T00") print " setup explicit imex problem..." #======================================================================= # retrieve imex coefficients a, b, c = self._imex_alpha, self._imex_beta, self._imex_gamma #======================================================================= # trial and test function (del_v, del_p, del_T) = dlfn.TestFunctions(self._Wh) (dv, dp, dT) = dlfn.TrialFunctions(self._Wh) # volume element dV = dlfn.Measure("dx", domain=self._mesh) # reference to time step timestep = self._timestep #======================================================================= from dolfin import dot, grad, inner # 1) lhs momentum equation lhs_momentum = a[0] / timestep * dot(dv, del_v) * dV \ + c[0] * self._coefficients[1] * a_op(dv, del_v) * dV\ - b_op(del_v, dp) * dV\ - b_op(dv, del_p) * dV # 2a) rhs momentum equation: time derivative rhs_momentum = -dot( a[1] / timestep * self._v0 + a[2] / timestep * self._v00, del_v) * dV # 2b) rhs momentum equation: nonlinear term nonlinear_term_velocity = b[0] * dot(grad(self._v0), self._v0) \ + b[1] * dot(grad(self._v00), self._v00) rhs_momentum -= dot(nonlinear_term_velocity, del_v) * dV # 2c) rhs momentum equation: linear term rhs_momentum -= self._coefficients[1] * inner( c[1] * grad(self._v0) + c[2] * grad(self._v00), grad(del_v)) * dV # 2d) rhs momentum equation: coriolis term if self._parameters.rotation is True: assert self._coefficients[0] != 0.0 print " adding rotation to the model..." # defining extrapolated velocity extrapolated_velocity = (self._one + self._omega) * self._v0 \ - self._omega * self._v00 # set Coriolis term if self._space_dim == 2: rhs_momentum -= self._coefficients[0] * ( -extrapolated_velocity[1] * del_v[0] + extrapolated_velocity[0] * del_v[1]) * dV elif self._space_dim == 3: from dolfin import cross coriolis_term = cross(self._rotation_vector, extrapolated_velocity) rhs_momentum -= self._coefficients[0] * dot( coriolis_term, del_v) * dV print " adding rotation to the model..." # 2e) rhs momentum equation: buoyancy term if self._parameters.buoyancy is True: assert self._coefficients[2] != 0.0 # defining extrapolated temperature extrapolated_temperature = ( self._one + self._omega) * self._T0 - self._omega * self._T00 # buoyancy term print " adding buoyancy to the model..." rhs_momentum -= self._coefficients[ 2] * extrapolated_temperature * dot(self._gravity, del_v) * dV #======================================================================= # 3) lhs energy equation lhs_energy = a[0] / timestep * dot(dT, del_T) * dV \ + self._coefficients[3] * a_op(dT, del_T) * dV # 4a) rhs energy equation: time derivative rhs_energy = -dot( a[1] / timestep * self._T0 + a[2] / timestep * self._T00, del_T) * dV # 4b) rhs energy equation: nonlinear term nonlinear_term_temperature = b[0] * dot(self._v0, grad(self._T0)) \ + b[1] * dot(self._v00, grad(self._T00)) rhs_energy -= nonlinear_term_temperature * del_T * dV # 4c) rhs energy equation: linear term rhs_energy -= self._coefficients[3] \ * dot(c[1] * grad(self._T0) + c[2] * grad(self._T00), grad(del_T)) * dV #======================================================================= # full problem self._lhs = lhs_momentum + lhs_energy self._rhs = rhs_momentum + rhs_energy if not hasattr(self, "_dirichlet_bcs"): self._setup_boundary_conditions() if self._parameters.use_assembler_method: # system assembler self._assembler = dlfn.SystemAssembler(self._lhs, self._rhs, bcs=self._dirichlet_bcs) self._system_matrix = dlfn.Matrix() self._system_rhs = dlfn.Vector() self._solver = dlfn.LUSolver(self._system_matrix) else: # linear problem problem = dlfn.LinearVariationalProblem(self._lhs, self._rhs, self._sol, bcs=self._dirichlet_bcs) self._solver = dlfn.LinearVariationalSolver(problem)
- a[2] * dot(T00, del_T) * dV \ - time_step * b[1] * c_operator(v0, T0, del_T) \ + time_step * b[2] * c_operator(v00, T00, del_T) lhs = lhs_momentum + lhs_energy #=============================================================================== # full problem lhs = lhs_momentum + lhs_energy rhs = rhs_momentum + rhs_energy if not use_assembler_method: # linear problem problem = dlfn.LinearVariationalProblem(lhs, rhs, sol, bcs=bcs) solver = dlfn.LinearVariationalSolver(problem) else: # system assembler assembler = dlfn.SystemAssembler(lhs, rhs, bcs=bcs) system_matrix = dlfn.Matrix() system_rhs = dlfn.Vector() solver = dlfn.LUSolver(system_matrix) #=============================================================================== def solve(step, time_step_ratio, update_coefficients, use_assembler_method): assert isinstance(step, int) and step >= 0 assert isinstance(time_step_ratio, float) and time_step_ratio > 0 assert isinstance(update_coefficients, bool) \ and isinstance(use_assembler_method, bool) if step == 0: # assign omega for initial Euler step omega.assign(0.) assert isinstance(omega, dlfn.Constant) # assemble system matrix / rhs if use_assembler_method: print " Assembling system (initial step)..."