示例#1
0
    def F(self, snes: PETSc.SNES, x: PETSc.Vec, b: PETSc.Vec):
        """Assemble the residual F into the vector b.

        Parameters
        ==========
        snes: the snes object
        x: Vector containing the latest solution.
        b: Vector to assemble the residual into.
        """
        # We need to assign the vector to the function

        x.ghostUpdate(addv=PETSc.InsertMode.INSERT,
                      mode=PETSc.ScatterMode.FORWARD)
        x.copy(self.u.vector)
        self.u.vector.ghostUpdate(addv=PETSc.InsertMode.INSERT,
                                  mode=PETSc.ScatterMode.FORWARD)

        # Zero the residual vector
        # import pdb; pdb.set_trace()
        with b.localForm() as b_local:
            b_local.set(0.0)
        assemble_vector(b, self.F_form)

        # Apply boundary conditions
        apply_lifting(b, [self.J_form], [self.bcs], [x], -1.0)
        b.ghostUpdate(addv=PETSc.InsertMode.ADD,
                      mode=PETSc.ScatterMode.REVERSE)
        set_bc(b, self.bcs, x, -1.0)
示例#2
0
    def form(self, x: PETSc.Vec):
        """This function is called before the residual or Jacobian is
        computed. This is usually used to update ghost values.

        Parameters
        ----------
        x
            The vector containing the latest solution
        """
        x.ghostUpdate(addv=PETSc.InsertMode.INSERT, mode=PETSc.ScatterMode.FORWARD)
示例#3
0
def _(b: PETSc.Vec,
      L: typing.List[FormMetaClass],
      a,
      bcs: typing.List[DirichletBCMetaClass] = [],
      x0: typing.Optional[PETSc.Vec] = None,
      scale: float = 1.0,
      constants_L=None,
      coeffs_L=None,
      constants_a=None,
      coeffs_a=None) -> PETSc.Vec:
    """Assemble linear forms into a monolithic vector. The vector is not
    zeroed and it is not finalised, i.e. ghost values are not
    accumulated.

    """
    maps = [(form.function_spaces[0].dofmap.index_map,
             form.function_spaces[0].dofmap.index_map_bs) for form in L]
    if x0 is not None:
        x0_local = _cpp.la.petsc.get_local_vectors(x0, maps)
        x0_sub = x0_local
    else:
        x0_local = []
        x0_sub = [None] * len(maps)

    constants_L = [form and _pack_constants(form)
                   for form in L] if constants_L is None else constants_L
    coeffs_L = [{} if form is None else _pack_coefficients(form)
                for form in L] if coeffs_L is None else coeffs_L
    constants_a = [[form and _pack_constants(form) for form in forms]
                   for forms in a] if constants_a is None else constants_a
    coeffs_a = [[{} if form is None else _pack_coefficients(form)
                 for form in forms]
                for forms in a] if coeffs_a is None else coeffs_a

    bcs1 = _bcs_by_block(_extract_spaces(a, 1), bcs)
    b_local = _cpp.la.petsc.get_local_vectors(b, maps)
    for b_sub, L_sub, a_sub, const_L, coeff_L, const_a, coeff_a in zip(
            b_local, L, a, constants_L, coeffs_L, constants_a, coeffs_a):
        _cpp.fem.assemble_vector(b_sub, L_sub, const_L, coeff_L)
        _cpp.fem.apply_lifting(b_sub, a_sub, const_a, coeff_a, bcs1, x0_local,
                               scale)

    _cpp.la.petsc.scatter_local_vectors(b, b_local, maps)
    b.ghostUpdate(addv=PETSc.InsertMode.ADD, mode=PETSc.ScatterMode.REVERSE)

    bcs0 = _bcs_by_block(_extract_spaces(L), bcs)
    offset = 0
    b_array = b.getArray(readonly=False)
    for submap, bc, _x0 in zip(maps, bcs0, x0_sub):
        size = submap[0].size_local * submap[1]
        _cpp.fem.set_bc(b_array[offset:offset + size], bc, _x0, scale)
        offset += size

    return b
 def update(self, solver: dolfinx.nls.petsc.NewtonSolver, dx: PETSc.Vec,
            x: PETSc.Vec):
     # We need to use a vector created on the MPC's space to update ghosts
     self.u_mpc.vector.array = x.array_r
     self.u_mpc.vector.axpy(-1.0, dx)
     self.u_mpc.vector.ghostUpdate(addv=PETSc.InsertMode.INSERT,
                                   mode=PETSc.ScatterMode.FORWARD)
     self.mpc.homogenize(self.u_mpc.vector)
     self.mpc.backsubstitution(self.u_mpc.vector)
     x.array = self.u_mpc.vector.array_r
     x.ghostUpdate(addv=PETSc.InsertMode.INSERT,
                   mode=PETSc.ScatterMode.FORWARD)
    def F(self, x: PETSc.Vec, F: PETSc.Vec):
        with F.localForm() as F_local:
            F_local.set(0.0)
        dolfinx_mpc.assemble_vector(self._L, self.mpc, b=F)

        # Apply boundary condition
        dolfinx_mpc.apply_lifting(F, [self._a],
                                  bcs=[self.bcs],
                                  constraint=self.mpc,
                                  x0=[x],
                                  scale=-1.0)
        F.ghostUpdate(addv=PETSc.InsertMode.ADD,
                      mode=PETSc.ScatterMode.REVERSE)
        dolfinx.fem.petsc.set_bc(F, self.bcs, x, -1.0)
示例#6
0
def _(b: PETSc.Vec, L: typing.Union[Form, cpp.fem.Form]) -> PETSc.Vec:
    """Assemble linear form into an existing vector.

    The vector must already have the correct size and parallel layout
    and wll be zeroed. The returned vector is finalised, i.e. ghost
    values accumulated across MPI processes.

    """
    L_cpp = _create_cpp_form(L)
    with b.localForm() as b_local:
        b_local.set(0.0)
    cpp.fem.assemble_vector(b, L_cpp)
    b.ghostUpdate(addv=PETSc.InsertMode.ADD, mode=PETSc.ScatterMode.REVERSE)
    return b
示例#7
0
    def homogenize(self, vector: _PETSc.Vec) -> None:
        """
        For a vector, homogenize (set to zero) the vector components at
        the multi-point constraint slave DoF indices. This is particularly useful
        for nonlinear problems.

        Parameters
        ----------
        vector
            The input vector
        """
        with vector.localForm() as vector_local:
            self._cpp_object.homogenize(vector_local.array_w)
        vector.ghostUpdate(addv=_PETSc.InsertMode.INSERT, mode=_PETSc.ScatterMode.FORWARD)
示例#8
0
    def backsubstitution(self, vector: _PETSc.Vec) -> None:
        """
        For a vector, impose the multi-point constraint by backsubstiution.
        This function is used after solving the reduced problem to obtain the values
        at the slave degrees of freedom

        Parameters
        ----------
        vector
            The input vector
        """
        # Unravel data from constraint
        with vector.localForm() as vector_local:
            self._cpp_object.backsubstitution(vector_local.array_w)
        vector.ghostUpdate(addv=_PETSc.InsertMode.INSERT, mode=_PETSc.ScatterMode.FORWARD)
示例#9
0
文件: problem.py 项目: RuruX/dolfinx
 def F(self, x: PETSc.Vec, b: PETSc.Vec):
     """Assemble the residual F into the vector b.
     Parameters
     ----------
     x
         The vector containing the latest solution
     b
         Vector to assemble the residual into
     """
     # Reset the residual vector
     with b.localForm() as b_local:
         b_local.set(0.0)
     fem.assemble_vector(b, self._L)
     # Apply boundary condition
     fem.apply_lifting(b, [self._a], [self.bcs], [x], -1.0)
     b.ghostUpdate(addv=PETSc.InsertMode.ADD, mode=PETSc.ScatterMode.REVERSE)
     fem.set_bc(b, self.bcs, x, -1.0)
示例#10
0
def _(b: PETSc.Vec,
      L: typing.List[typing.Union[Form, cpp.fem.Form]],
      a,
      bcs: typing.List[DirichletBC] = [],
      x0: typing.Optional[PETSc.Vec] = None,
      scale: float = 1.0) -> PETSc.Vec:
    """Assemble linear forms into a monolithic vector. The vector is not
    zeroed and it is not finalised, i.e. ghost values are not
    accumulated.

    """
    maps = [
        form.function_spaces[0].dofmap.index_map
        for form in _create_cpp_form(L)
    ]
    if x0 is not None:
        x0_local = cpp.la.get_local_vectors(x0, maps)
        x0_sub = x0_local
    else:
        x0_local = []
        x0_sub = [None] * len(maps)

    bcs1 = cpp.fem.bcs_cols(_create_cpp_form(a), bcs)
    b_local = cpp.la.get_local_vectors(b, maps)
    for b_sub, L_sub, a_sub, bc in zip(b_local, L, a, bcs1):
        cpp.fem.assemble_vector(b_sub, _create_cpp_form(L_sub))
        cpp.fem.apply_lifting(b_sub, _create_cpp_form(a_sub), bc, x0_local,
                              scale)

    cpp.la.scatter_local_vectors(b, b_local, maps)
    b.ghostUpdate(addv=PETSc.InsertMode.ADD, mode=PETSc.ScatterMode.REVERSE)

    bcs0 = cpp.fem.bcs_rows(_create_cpp_form(L), bcs)
    offset = 0
    b_array = b.getArray(readonly=False)
    for submap, bc, _x0 in zip(maps, bcs0, x0_sub):
        size = submap.size_local * submap.block_size
        cpp.fem.set_bc(b_array[offset:offset + size], bc, _x0, scale)
        offset += size

    return b