Ejemplo n.º 1
0
  def solve(self, var, b):
    timer = backend.Timer("Matrix-free solver")
    solver = backend.PETScKrylovSolver(*self.solver_parameters)
    solver.parameters.update(self.parameters)

    x = backend.Function(self.fn_space)
    if b.data is None:
      backend.info_red("Warning: got zero RHS for the solve associated with variable %s" % var)
      return adjlinalg.Vector(x)

    if isinstance(b.data, backend.Function):
      rhs = b.data.vector().copy()
    else:
      rhs = backend.assemble(b.data)

    if var.type in ['ADJ_TLM', 'ADJ_ADJOINT']:
      self.bcs = [backend.homogenize(bc) for bc in self.bcs if isinstance(bc, backend.cpp.DirichletBC)] + [bc for bc in self.bcs if not isinstance(bc, backend.DirichletBC)]

    for bc in self.bcs:
      bc.apply(rhs)

    if self.operators[1] is not None: # we have a user-supplied preconditioner
      solver.set_operators(self.data, self.operators[1])
      solver.solve(backend.down_cast(x.vector()), backend.down_cast(rhs))
    else:
      solver.solve(self.data, backend.down_cast(x.vector()), backend.down_cast(rhs))

    timer.stop()
    return adjlinalg.Vector(x)
Ejemplo n.º 2
0
    def solve(self, var, b):
        timer = backend.Timer("Matrix-free solver")
        solver = backend.PETScKrylovSolver(*self.solver_parameters)
        solver.parameters.update(self.parameters)

        x = backend.Function(self.fn_space)
        if b.data is None:
            backend.info_red(
                "Warning: got zero RHS for the solve associated with variable %s"
                % var)
            return adjlinalg.Vector(x)

        if isinstance(b.data, backend.Function):
            rhs = b.data.vector().copy()
        else:
            rhs = backend.assemble(b.data)

        if var.type in ['ADJ_TLM', 'ADJ_ADJOINT']:
            self.bcs = [
                utils.homogenize(bc)
                for bc in self.bcs if isinstance(bc, backend.cpp.DirichletBC)
            ] + [
                bc
                for bc in self.bcs if not isinstance(bc, backend.DirichletBC)
            ]

        for bc in self.bcs:
            bc.apply(rhs)

        if self.operators[
                1] is not None:  # we have a user-supplied preconditioner
            solver.set_operators(self.data, self.operators[1])
            solver.solve(backend.down_cast(x.vector()), backend.down_cast(rhs))
        else:
            solver.solve(self.data, backend.down_cast(x.vector()),
                         backend.down_cast(rhs))

        timer.stop()
        return adjlinalg.Vector(x)
Ejemplo n.º 3
0
def down_cast(*args, **kwargs):
  """When a form is assembled, the information about its nonlinear dependencies is lost,
  and it is no longer easy to manipulate. Therefore, dolfin_adjoint overloads the :py:func:`dolfin.down_cast`
  function to *attach the form to the returned object*. This lets the automatic annotation work,
  even when the user calls the lower-level :py:data:`solve(A, x, b)`.
  """
  dc = backend.down_cast(*args, **kwargs)

  if hasattr(args[0], 'form'):
    dc.form = args[0].form

  if hasattr(args[0], 'function'):
    dc.function = args[0].function

  if hasattr(args[0], 'bcs'):
    dc.bcs = args[0].bcs

  return dc
Ejemplo n.º 4
0
def down_cast(*args, **kwargs):
    """When a form is assembled, the information about its nonlinear dependencies is lost,
    and it is no longer easy to manipulate. Therefore, dolfin_adjoint overloads the :py:func:`dolfin.down_cast`
    function to *attach the form to the returned object*. This lets the automatic annotation work,
    even when the user calls the lower-level :py:data:`solve(A, x, b)`.
    """
    dc = backend.down_cast(*args, **kwargs)

    if hasattr(args[0], 'form'):
        dc.form = args[0].form

    if hasattr(args[0], 'function'):
        dc.function = args[0].function

    if hasattr(args[0], 'bcs'):
        dc.bcs = args[0].bcs

    return dc