コード例 #1
0
def interpolate(v, V, annotate=None, name=None):
    '''The interpolate call changes Function data, and so it too must be annotated so that the
    adjoint and tangent linear models may be constructed automatically by libadjoint.

    To disable the annotation of this function, just pass :py:data:`annotate=False`. This is useful in
    cases where the interpolation is known to be irrelevant or diagnostic for the purposes of the adjoint
    computation (such as interpolating fields to other function spaces for the purposes of
    visualisation).'''

    out = backend.interpolate(v, V)
    if name is not None:
        out.adj_name = name

    to_annotate = utils.to_annotate(annotate)

    if isinstance(v, backend.Function) and to_annotate:
        rhsdep = adjglobals.adj_variables[v]
        if adjglobals.adjointer.variable_known(rhsdep):
            rhs = InterpolateRHS(v, V)
            identity_block = utils.get_identity_block(V)

            solving.register_initial_conditions(zip(rhs.coefficients(),rhs.dependencies()), linear=True)

            dep = adjglobals.adj_variables.next(out)

            if backend.parameters["adjoint"]["record_all"]:
                adjglobals.adjointer.record_variable(dep, libadjoint.MemoryStorage(adjlinalg.Vector(out)))

            initial_eq = libadjoint.Equation(dep, blocks=[identity_block], targets=[dep], rhs=rhs)
            cs = adjglobals.adjointer.register_equation(initial_eq)

            solving.do_checkpoint(cs, dep, rhs)

    return out
コード例 #2
0
ファイル: interpolation.py プロジェクト: vpuri3/pyadjoint
def interpolate(*args, **kwargs):
    """Interpolation is overloaded to ensure that the returned Function object is overloaded.
    We are not able to annotate the interpolation call at the moment.

    """
    output = backend.interpolate(*args, **kwargs)
    return create_overloaded_object(output)
コード例 #3
0
ファイル: expression.py プロジェクト: vpuri3/pyadjoint
    def evaluate_adj_component(self,
                               inputs,
                               adj_inputs,
                               block_variable,
                               idx,
                               prepared=None):
        adj_inputs = adj_inputs[0]
        c = block_variable.output
        if c not in self.expression.user_defined_derivatives:
            return None

        for key in self.expression._ad_attributes_dict:
            if key not in self.expression.ad_ignored_attributes:
                setattr(self.expression.user_defined_derivatives[c], key,
                        self.expression._ad_attributes_dict[key])

        adj_output = None
        for adj_pair in adj_inputs:
            adj_input = adj_pair[0]
            V = adj_pair[1]
            if adj_output is None:
                adj_output = 0.0

            interp = backend.interpolate(
                self.expression.user_defined_derivatives[c], V)
            if isinstance(c, (backend.Constant, AdjFloat)):
                adj_output += adj_input.inner(interp.vector())
            else:
                vec = adj_input * interp.vector()
                adj_func = backend.Function(V, vec)

                num_sub_spaces = V.num_sub_spaces()
                if num_sub_spaces > 1:
                    for i in range(num_sub_spaces):
                        adj_output += backend.interpolate(
                            adj_func.sub(i), c.function_space()).vector()
                else:
                    adj_output += backend.interpolate(
                        adj_func, c.function_space()).vector()
        return adj_output
コード例 #4
0
def interpolate(v, V, annotate=None, name=None):
    '''The interpolate call changes Function data, and so it too must be annotated so that the
    adjoint and tangent linear models may be constructed automatically by libadjoint.

    To disable the annotation of this function, just pass :py:data:`annotate=False`. This is useful in
    cases where the interpolation is known to be irrelevant or diagnostic for the purposes of the adjoint
    computation (such as interpolating fields to other function spaces for the purposes of
    visualisation).'''

    out = backend.interpolate(v, V)
    out = utils.function_to_da_function(out)
    if name is not None:
        out.adj_name = name

    to_annotate = utils.to_annotate(annotate)

    if to_annotate:
        if isinstance(v, backend.Function):
            rhsdep = adjglobals.adj_variables[v]
            if adjglobals.adjointer.variable_known(rhsdep):
                rhs = InterpolateRHS(v, V)
                identity_block = utils.get_identity_block(V)

                solving.register_initial_conditions(zip(
                    rhs.coefficients(), rhs.dependencies()),
                                                    linear=True)

                dep = adjglobals.adj_variables.next(out)

                if backend.parameters["adjoint"]["record_all"]:
                    adjglobals.adjointer.record_variable(
                        dep, libadjoint.MemoryStorage(adjlinalg.Vector(out)))

                initial_eq = libadjoint.Equation(dep,
                                                 blocks=[identity_block],
                                                 targets=[dep],
                                                 rhs=rhs)
                cs = adjglobals.adjointer.register_equation(initial_eq)

                solving.do_checkpoint(cs, dep, rhs)

        elif annotate is not None:
            outvar = adjglobals.adj_variables[out]
            solving.register_initial_conditions([
                [out, outvar],
            ], linear=True)

    return out
コード例 #5
0
    def derivative_action(self, dependencies, values, variable, contraction_vector, hermitian):
        if not hermitian:
            return adjlinalg.Vector(backend.interpolate(contraction_vector.data, self.V))
        else:
#      For future reference, the transpose action of the interpolation operator
#      is (in pseudocode!):
#
#      for target_dof in target:
#        figure out what element it lives in, to compute src_dofs
#        for src_dof in src_dofs:
#          basis = the value of the basis function of src_dof at the node of target_dof
#
#          # all of the above is exactly the same as the forward interpolation.
#          # forward interpolation would do:
#          # target_coefficients[target_dof] += basis * src_coefficients[src_dof]
#
#          # but the adjoint action is:
#          src_coefficients[src_dof] += basis * target_coefficients[target_dof]

            raise libadjoint.exceptions.LibadjointErrorNotImplemented("Can't transpose an interpolation operator yet, sorry!")
コード例 #6
0
    def derivative_action(self, dependencies, values, variable,
                          contraction_vector, hermitian):
        if not hermitian:
            return adjlinalg.Vector(
                backend.interpolate(contraction_vector.data, self.V))
        else:
            #      For future reference, the transpose action of the interpolation operator
            #      is (in pseudocode!):
            #
            #      for target_dof in target:
            #        figure out what element it lives in, to compute src_dofs
            #        for src_dof in src_dofs:
            #          basis = the value of the basis function of src_dof at the node of target_dof
            #
            #          # all of the above is exactly the same as the forward interpolation.
            #          # forward interpolation would do:
            #          # target_coefficients[target_dof] += basis * src_coefficients[src_dof]
            #
            #          # but the adjoint action is:
            #          src_coefficients[src_dof] += basis * target_coefficients[target_dof]

            raise libadjoint.exceptions.LibadjointErrorNotImplemented(
                "Can't transpose an interpolation operator yet, sorry!")
コード例 #7
0
ファイル: expression.py プロジェクト: vpuri3/pyadjoint
    def evaluate_hessian_component(self,
                                   inputs,
                                   hessian_inputs,
                                   adj_inputs,
                                   block_variable,
                                   idx,
                                   relevant_dependencies,
                                   prepared=None):
        hessian_inputs = hessian_inputs[0]
        adj_inputs = adj_inputs[0]
        c1 = block_variable.output

        if c1 not in self.expression.user_defined_derivatives:
            return None

        first_deriv = self.expression.user_defined_derivatives[c1]
        for key in self.expression._ad_attributes_dict:
            if key not in self.expression.ad_ignored_attributes:
                setattr(first_deriv, key,
                        self.expression._ad_attributes_dict[key])

        hessian_output = None
        for _, bo2 in relevant_dependencies:
            c2 = bo2.output
            tlm_input = bo2.tlm_value

            if tlm_input is None:
                continue

            if c2 not in first_deriv.user_defined_derivatives:
                continue

            second_deriv = first_deriv.user_defined_derivatives[c2]
            for key in self.expression._ad_attributes_dict:
                if key not in self.expression.ad_ignored_attributes:
                    setattr(second_deriv, key,
                            self.expression._ad_attributes_dict[key])

            for adj_pair in adj_inputs:
                adj_input = adj_pair[0]
                V = adj_pair[1]

                if hessian_output is None:
                    hessian_output = 0.0

                # TODO: Seems we can only project and not interpolate ufl.algebra.Product in dolfin.
                #       Consider the difference and which actually makes sense here.
                interp = backend.project(tlm_input * second_deriv, V)
                if isinstance(c1, (backend.Constant, AdjFloat)):
                    hessian_output += adj_input.inner(interp.vector())
                else:
                    vec = adj_input * interp.vector()
                    hessian_func = backend.Function(V, vec)

                    num_sub_spaces = V.num_sub_spaces()
                    if num_sub_spaces > 1:
                        for i in range(num_sub_spaces):
                            hessian_output += backend.interpolate(
                                hessian_func.sub(i),
                                c1.function_space()).vector()
                    else:
                        hessian_output += backend.interpolate(
                            hessian_func, c1.function_space()).vector()

        for hessian_pair in hessian_inputs:
            if hessian_output is None:
                hessian_output = 0.0
            hessian_input = hessian_pair[0]
            V = hessian_pair[1]

            interp = backend.interpolate(first_deriv, V)
            if isinstance(c1, (backend.Constant, AdjFloat)):
                hessian_output += hessian_input.inner(interp.vector())
            else:
                vec = hessian_input * interp.vector()
                hessian_func = backend.Function(V, vec)

                num_sub_spaces = V.num_sub_spaces()
                if num_sub_spaces > 1:
                    for i in range(num_sub_spaces):
                        hessian_output += backend.interpolate(
                            hessian_func.sub(i), c1.function_space()).vector()
                else:
                    hessian_output += backend.interpolate(
                        hessian_func, c1.function_space()).vector()
        return hessian_output
コード例 #8
0
 def __call__(self, dependencies, values):
     return adjlinalg.Vector(backend.interpolate(values[0].data, self.V))
コード例 #9
0
 def __call__(self, dependencies, values):
     return adjlinalg.Vector(backend.interpolate(values[0].data, self.V))