Exemple #1
0
    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
Exemple #2
0
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))
Exemple #3
0
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))
Exemple #4
0
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))
Exemple #5
0
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)..."