def transpose_operators(operators):
  out = [None, None]

  for i in range(2):
    op = operators[i]

    if op is None:
      out[i] = None
    elif isinstance(op, dolfin.cpp.GenericMatrix):
      out[i] = op.__class__()
      dolfin.assemble(dolfin.adjoint(op.form), tensor=out[i])

      if hasattr(op, 'bcs'):
        adjoint_bcs = [dolfin.homogenize(bc) for bc in op.bcs if isinstance(bc, dolfin.cpp.DirichletBC)] + [bc for bc in op.bcs if not isinstance(bc, dolfin.DirichletBC)]
        [bc.apply(out[i]) for bc in adjoint_bcs]

    elif isinstance(op, dolfin.Form) or isinstance(op, ufl.form.Form):
      out[i] = dolfin.adjoint(op)

      if hasattr(op, 'bcs'):
        out[i].bcs = [dolfin.homogenize(bc) for bc in op.bcs if isinstance(bc, dolfin.cpp.DirichletBC)] + [bc for bc in op.bcs if not isinstance(bc, dolfin.DirichletBC)]

    elif isinstance(op, AdjointKrylovMatrix):
      pass

    else:
      print "op.__class__: ", op.__class__
      raise libadjoint.exceptions.LibadjointErrorNotImplemented("Don't know how to transpose anything else!")

  return out
    def solve(self, var, b):

      if reuse_factorization is False:
        return adjlinalg.Matrix.solve(self, var, b)

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

      if var.type in ['ADJ_FORWARD', 'ADJ_TLM']:
        solver = lu_solvers[idx]
        if solver is None:
          A = assembly.assemble(self.data); [bc.apply(A) for bc in bcs]
          lu_solvers[idx] = LUSolver(A)
          lu_solvers[idx].parameters["reuse_factorization"] = True
        solver = lu_solvers[idx]

      else:
        if adj_lu_solvers[idx] is None:
          A = assembly.assemble(self.data); [bc.apply(A) for bc in bcs]
          adj_lu_solvers[idx] = LUSolver(A)
          adj_lu_solvers[idx].parameters["reuse_factorization"] = True

        solver = adj_lu_solvers[idx]

      x = adjlinalg.Vector(dolfin.Function(self.test_function().function_space()))

      if b.data is None:
        # This means we didn't get any contribution on the RHS of the adjoint system. This could be that the
        # simulation ran further ahead than when the functional was evaluated, or it could be that the
        # functional is set up incorrectly.
        dolfin.info_red("Warning: got zero RHS for the solve associated with variable %s" % var)
      else:
        if isinstance(b.data, dolfin.Function):
          b_vec = b.data.vector().copy()
        else:
          b_vec = dolfin.assemble(b.data)

        [bc.apply(b_vec) for bc in bcs]
        solver.solve(x.data.vector(), b_vec, annotate=False)

      return x
Exemple #3
0
    v1, v2 = df.split(v)

    # Initial Guesses
    u1_i = df.Expression("x[0]")
    u2_i = df.Expression("1-x[0]")

    # Impose boundary conditions for the solution to the nonlinear system
    bc = [
        df.DirichletBC(V2.sub(0), df.Constant(0.0), left_boundary),
        df.DirichletBC(V2.sub(0), df.Constant(1.0), right_boundary),
        df.DirichletBC(V2.sub(1), df.Constant(1.0), left_boundary),
        df.DirichletBC(V2.sub(1), df.Constant(0.0), right_boundary)
    ]

    # Make homogeneous version of BCs for the update
    bch = df.homogenize(bc)

    # Set the initial guess
    u.interpolate(df.Expression(("u1_i", "u2_i"), u1_i=u1_i, u2_i=u2_i))

    # Allocate Newton update function
    u_inc = df.Function(V2)

    # Extract grid points
    xg = mesh.coordinates()

    # Nonlinear coefficient 1
    q1 = ufl.operators.exp(a * u1)

    # Nonlinear coefficient 2
    q2 = ufl.operators.exp(a * u2)
Exemple #4
0
    v1, v2 = df.split(v)

    # Initial Guesses
    u1_i = df.Expression("x[0]")
    u2_i = df.Expression("1-x[0]")

    # Impose boundary conditions for the solution to the nonlinear system
    bc = [
        df.DirichletBC(V2.sub(0), df.Constant(0.0), left_boundary),
        df.DirichletBC(V2.sub(0), df.Constant(1.0), right_boundary),
        df.DirichletBC(V2.sub(1), df.Constant(1.0), left_boundary),
        df.DirichletBC(V2.sub(1), df.Constant(0.0), right_boundary),
    ]

    # Make homogeneous version of BCs for the update
    bch = df.homogenize(bc)

    # Set the initial guess
    u.interpolate(df.Expression(("u1_i", "u2_i"), u1_i=u1_i, u2_i=u2_i))

    # Allocate Newton update function
    u_inc = df.Function(V2)

    # Extract grid points
    xg = mesh.coordinates()

    # Nonlinear coefficient 1
    q1 = ufl.operators.exp(a * u1)

    # Nonlinear coefficient 2
    q2 = ufl.operators.exp(a * u2)
        def solve(self, var, b):
          if self.adjoint:
            operators = transpose_operators(self.operators)
          else:
            operators = self.operators

          solver = dolfin.KrylovSolver(*solver_parameters)
          solver.parameters.update(parameters)

          if self.adjoint:
            # swap nullspaces
            (nsp_, tnsp_) = (tnsp, nsp)
          else:
            (nsp_, tnsp_) = (nsp, tnsp)

          if nsp_ is not None:
            solver.set_nullspace(nsp_)
          if tnsp_ is not None and hasattr(solver, 'set_transpose_nullspace'):
            solver.set_transpose_nullspace(tnsp_)

          x = dolfin.Function(fn_space)
          if self.initial_guess is not None and var.type == 'ADJ_FORWARD':
            x.vector()[:] = self.initial_guess.vector()

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

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

          # This is really hideous. Sorry.
          if isinstance(b.data, dolfin.Function):
            rhs = b.data.vector().copy()
            [bc.apply(rhs) for bc in self.bcs]

            if assemble_system: # if we called assemble_system, rather than assemble
              v = dolfin.TestFunction(fn_space)
              (A, rhstmp) = dolfin.assemble_system(operators[0], dolfin.inner(b.data, v)*dolfin.dx, self.bcs)
              if has_preconditioner:
                (P, rhstmp) = dolfin.assemble_system(operators[1], dolfin.inner(b.data, v)*dolfin.dx, self.bcs)
                solver.set_operators(A, P)
              else:
                solver.set_operator(A)
            else: # we called assemble
              A = dolfin.assemble(operators[0])
              [bc.apply(A) for bc in self.bcs]
              if has_preconditioner:
                P = dolfin.assemble(operators[1])
                [bc.apply(P) for bc in self.bcs]
                solver.set_operators(A, P)
              else:
                solver.set_operator(A)
          else:

            if assemble_system: # if we called assemble_system, rather than assemble
              (A, rhs) = dolfin.assemble_system(operators[0], b.data, self.bcs)
              if has_preconditioner:
                (P, rhstmp) = dolfin.assemble_system(operators[1], b.data, self.bcs)
                solver.set_operators(A, P)
              else:
                solver.set_operator(A)
            else: # we called assemble
              A = dolfin.assemble(operators[0])
              rhs = dolfin.assemble(b.data)
              [bc.apply(A) for bc in self.bcs]
              [bc.apply(rhs) for bc in self.bcs]
              if has_preconditioner:
                P = dolfin.assemble(operators[1])
                [bc.apply(P) for bc in self.bcs]
                solver.set_operators(A, P)
              else:
                solver.set_operator(A)

          if tnsp_ is not None:
            tnsp_.orthogonalize(rhs)

          solver.solve(x.vector(), rhs)
          return adjlinalg.Vector(x)
        def solve(self, var, b):
          if self.adjoint:
            operators = transpose_operators(self.operators)
          else:
            operators = self.operators

          solver = dolfin.LinearSolver(*solver_parameters)
          solver.parameters.update(parameters)

          if nsp is not None and self.adjoint is False:
            solver.set_nullspace(nsp)
          if nsp is not None and self.adjoint:
            # maybe add a LinearSolver.set_adjoint_nullspace?
            dolfin.info_red("Warning: setting nullspace for adjoint solve to be the same for the forward solve. May not be the actual basis for the nullspace.")
            solver.set_nullspace(nsp)

          x = dolfin.Function(fn_space)
          if self.initial_guess is not None and var.type == 'ADJ_FORWARD':
            x.vector()[:] = self.initial_guess.vector()

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

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

          # This is really hideous. Sorry.
          if isinstance(b.data, dolfin.Function):
            rhs = b.data.vector().copy()
            [bc.apply(rhs) for bc in self.bcs]

            if assemble_system: # if we called assemble_system, rather than assemble
              v = dolfin.TestFunction(fn_space)
              (A, rhstmp) = dolfin.assemble_system(operators[0], dolfin.inner(b.data, v)*dolfin.dx, self.bcs)
              if has_preconditioner:
                (P, rhstmp) = dolfin.assemble_system(operators[1], dolfin.inner(b.data, v)*dolfin.dx, self.bcs)
                solver.set_operators(A, P)
              else:
                solver.set_operator(A)
            else: # we called assemble
              A = dolfin.assemble(operators[0])
              [bc.apply(A) for bc in self.bcs]
              if has_preconditioner:
                P = dolfin.assemble(operators[1])
                [bc.apply(P) for bc in self.bcs]
                solver.set_operators(A, P)
              else:
                solver.set_operator(A)
          else:

            if assemble_system: # if we called assemble_system, rather than assemble
              (A, rhs) = dolfin.assemble_system(operators[0], b.data, self.bcs)
              if has_preconditioner:
                (P, rhstmp) = dolfin.assemble_system(operators[1], b.data, self.bcs)
                solver.set_operators(A, P)
              else:
                solver.set_operator(A)
            else: # we called assemble
              A = dolfin.assemble(operators[0])
              rhs = dolfin.assemble(b.data)
              [bc.apply(A) for bc in self.bcs]
              [bc.apply(rhs) for bc in self.bcs]
              if has_preconditioner:
                P = dolfin.assemble(operators[1])
                [bc.apply(P) for bc in self.bcs]
                solver.set_operators(A, P)
              else:
                solver.set_operator(A)

          solver.solve(x.vector(), rhs)
          return adjlinalg.Vector(x)