예제 #1
0
        def derivative_outer_action(
            dependencies, values, variable, contraction_vector, hermitian, input, coefficient, context
        ):
            dolfin_variable = values[dependencies.index(variable)].data
            dolfin_values = [val.data for val in values]
            expressions.update_expressions(frozen_expressions)
            constant.update_constants(frozen_constants)

            current_form = backend.replace(eq_lhs, dict(zip(diag_coeffs, dolfin_values)))

            deriv = backend.derivative(current_form, dolfin_variable)
            args = ufl.algorithms.extract_arguments(deriv)
            deriv = backend.replace(deriv, {args[2]: contraction_vector.data})  # contract over the outer index

            # Assemble the G-matrix now, so that we can apply the Dirichlet BCs to it
            if len(ufl.algorithms.extract_arguments(ufl.algorithms.expand_derivatives(coefficient * deriv))) == 0:
                return adjlinalg.Vector(None)

            G = coefficient * deriv

            if hermitian:
                output = backend.action(backend.adjoint(G), input.data)
            else:
                output = backend.action(G, input.data)

            return adjlinalg.Vector(output)
예제 #2
0
    def diag_assembly_cb(dependencies, values, hermitian, coefficient, context):
        """This callback must conform to the libadjoint Python block assembly
        interface. It returns either the form or its transpose, depending on
        the value of the logical hermitian."""

        assert coefficient == 1

        value_coeffs = [v.data for v in values]
        expressions.update_expressions(frozen_expressions)
        constant.update_constants(frozen_constants)
        eq_l = backend.replace(eq_lhs, dict(zip(diag_coeffs, value_coeffs)))

        kwargs = {"cache": eq_l in caching.assembled_fwd_forms}  # should we cache our matrices on the way backwards?

        if hermitian:
            # Homogenise the adjoint boundary conditions. This creates the adjoint
            # solution associated with the lifted discrete system that is actually solved.
            adjoint_bcs = [utils.homogenize(bc) for bc in eq_bcs if isinstance(bc, backend.DirichletBC)] + [
                bc for bc in eq_bcs if not isinstance(bc, backend.DirichletBC)
            ]
            if len(adjoint_bcs) == 0:
                adjoint_bcs = None
            else:
                adjoint_bcs = misc.uniq(adjoint_bcs)

            kwargs["bcs"] = adjoint_bcs
            kwargs["solver_parameters"] = solver_parameters
            kwargs["adjoint"] = True

            if initial_guess:
                kwargs["initial_guess"] = value_coeffs[dependencies.index(initial_guess_var)]

            if replace_map:
                kwargs["replace_map"] = dict(zip(diag_coeffs, value_coeffs))

            return (
                matrix_class(
                    backend.adjoint(eq_l, reordered_arguments=ufl.algorithms.extract_arguments(eq_l)), **kwargs
                ),
                adjlinalg.Vector(None, fn_space=u.function_space()),
            )
        else:

            kwargs["bcs"] = misc.uniq(eq_bcs)
            kwargs["solver_parameters"] = solver_parameters
            kwargs["adjoint"] = False

            if initial_guess:
                kwargs["initial_guess"] = value_coeffs[dependencies.index(initial_guess_var)]

            if replace_map:
                kwargs["replace_map"] = dict(zip(diag_coeffs, value_coeffs))

            return (matrix_class(eq_l, **kwargs), adjlinalg.Vector(None, fn_space=u.function_space()))
예제 #3
0
    def diag_action_cb(dependencies, values, hermitian, coefficient, input, context):
        value_coeffs = [v.data for v in values]
        expressions.update_expressions(frozen_expressions)
        constant.update_constants(frozen_constants)
        eq_l = backend.replace(eq_lhs, dict(zip(diag_coeffs, value_coeffs)))

        if hermitian:
            eq_l = backend.adjoint(eq_l)

        output = coefficient * backend.action(eq_l, input.data)

        return adjlinalg.Vector(output)
        def __call__(self, dependencies, values):

            expressions.update_expressions(self.frozen_expressions)
            constant.update_constants(self.frozen_constants)

            coeffs = [x for x in ufl.algorithms.extract_coefficients(self.scheme.rhs_form()) if hasattr(x, 'function_space')]
            for (coeff, value) in zip(coeffs, values):
                coeff.assign(value.data)

            self.scheme.t().assign(self.time)
            self.solver.step(self.dt)

            # FIXME: This form should actually be from before the solve.
            out = adjlinalg.Vector(self.scheme.solution())
            out.nonlinear_form = -self.dt*self.scheme.rhs_form()
            out.nonlinear_u = self.scheme.solution()
            out.nonlinear_bcs = []
            out.nonlinear_J = ufl.derivative(out.nonlinear_form, out.nonlinear_u)

            return out
        def derivative_action(self, dependencies, values, variable, contraction_vector, hermitian):
            expressions.update_expressions(self.frozen_expressions)
            constant.update_constants(self.frozen_constants)

            if not hermitian:
                if self.solver not in caching.pis_fwd_to_tlm:
                    dolfin.info_blue("No TLM solver, creating ... ")
                    creation_timer = dolfin.Timer("to_adm")
                    if contraction_vector.data is not None:
                        tlm_scheme = self.scheme.to_tlm(contraction_vector.data)
                    else:
                        tlm_scheme = self.scheme.to_tlm(dolfin.Function(self.fn_space))

                    creation_time = creation_timer.stop()
                    dolfin.info_red("TLM creation time: %s" % creation_time)

                    tlm_solver = dolfin.PointIntegralSolver(tlm_scheme)
                    tlm_solver.parameters.update(self.solver.parameters)
                    caching.pis_fwd_to_tlm[self.solver] = tlm_solver
                else:
                    tlm_solver = caching.pis_fwd_to_tlm[self.solver]
                    tlm_scheme = tlm_solver.scheme()
                    if contraction_vector.data is not None:
                        tlm_scheme.contraction.assign(contraction_vector.data)
                    else:
                        tlm_scheme.contraction.vector().zero()

                coeffs = [
                    x
                    for x in ufl.algorithms.extract_coefficients(tlm_scheme.rhs_form())
                    if hasattr(x, "function_space")
                ]
                for (coeff, value) in zip(coeffs, values):
                    coeff.assign(value.data)
                tlm_scheme.t().assign(self.time)

                tlm_solver.step(self.dt)

                return adjlinalg.Vector(tlm_scheme.solution())

            else:
                if self.solver not in caching.pis_fwd_to_adj:
                    dolfin.info_blue("No ADM solver, creating ... ")
                    creation_timer = dolfin.Timer("to_adm")
                    if contraction_vector.data is not None:
                        adm_scheme = self.scheme.to_adm(contraction_vector.data)
                    else:
                        adm_scheme = self.scheme.to_adm(dolfin.Function(self.fn_space))
                    creation_time = creation_timer.stop()
                    dolfin.info_red("ADM creation time: %s" % creation_time)

                    adm_solver = dolfin.PointIntegralSolver(adm_scheme)
                    adm_solver.parameters.update(self.solver.parameters)
                    caching.pis_fwd_to_adj[self.solver] = adm_solver
                else:
                    adm_solver = caching.pis_fwd_to_adj[self.solver]
                    adm_scheme = adm_solver.scheme()
                    if contraction_vector.data is not None:
                        adm_scheme.contraction.assign(contraction_vector.data)
                    else:
                        adm_scheme.contraction.vector().zero()

                coeffs = [
                    x
                    for x in ufl.algorithms.extract_coefficients(adm_scheme.rhs_form())
                    if hasattr(x, "function_space")
                ]
                for (coeff, value) in zip(coeffs, values):
                    coeff.assign(value.data)
                adm_scheme.t().assign(self.time)

                adm_solver.step(self.dt)

                return adjlinalg.Vector(adm_scheme.solution())