Пример #1
0
    def _ad_convert_type(self, value, options=None):
        options = {} if options is None else options
        riesz_representation = options.get("riesz_representation", "l2")

        if riesz_representation == "l2":
            return create_overloaded_object(
                compat.function_from_vector(self.function_space(),
                                            value,
                                            cls=backend.Function))
        elif riesz_representation == "L2":
            ret = compat.create_function(self.function_space())
            u = backend.TrialFunction(self.function_space())
            v = backend.TestFunction(self.function_space())
            M = backend.assemble(backend.inner(u, v) * backend.dx)
            compat.linalg_solve(M, ret.vector(), value)
            return ret
        elif riesz_representation == "H1":
            ret = compat.create_function(self.function_space())
            u = backend.TrialFunction(self.function_space())
            v = backend.TestFunction(self.function_space())
            M = backend.assemble(
                backend.inner(u, v) * backend.dx +
                backend.inner(backend.grad(u), backend.grad(v)) * backend.dx)
            compat.linalg_solve(M, ret.vector(), value)
            return ret
        elif callable(riesz_representation):
            return riesz_representation(value)
        else:
            raise NotImplementedError("Unknown Riesz representation %s" %
                                      riesz_representation)
Пример #2
0
 def sub(self, i, deepcopy=False, **kwargs):
     from .function_assigner import FunctionAssigner, FunctionAssignerBlock
     annotate = annotate_tape(kwargs)
     if deepcopy:
         ret = create_overloaded_object(
             backend.Function.sub(self, i, deepcopy, **kwargs))
         if annotate:
             fa = FunctionAssigner(ret.function_space(),
                                   self.function_space())
             block = FunctionAssignerBlock(fa, Enlist(self))
             tape = get_working_tape()
             tape.add_block(block)
             block.add_output(ret.block_variable)
     else:
         extra_kwargs = {}
         if annotate:
             extra_kwargs = {
                 "block_class": FunctionSplitBlock,
                 "_ad_floating_active": True,
                 "_ad_args": [self, i],
                 "_ad_output_args": [i],
                 "output_block_class": FunctionMergeBlock,
                 "_ad_outputs": [self],
             }
         ret = compat.create_function(self, i, **extra_kwargs)
     return ret
Пример #3
0
 def split(self, deepcopy=False, **kwargs):
     from .function_assigner import FunctionAssigner, FunctionAssignerBlock
     ad_block_tag = kwargs.pop("ad_block_tag", None)
     annotate = annotate_tape(kwargs)
     num_sub_spaces = backend.Function.function_space(self).num_sub_spaces()
     if not annotate:
         if deepcopy:
             ret = tuple(
                 create_overloaded_object(
                     backend.Function.sub(self, i, deepcopy, **kwargs))
                 for i in range(num_sub_spaces))
         else:
             ret = tuple(
                 compat.create_function(self, i)
                 for i in range(num_sub_spaces))
     elif deepcopy:
         ret = []
         fs = []
         for i in range(num_sub_spaces):
             f = create_overloaded_object(
                 backend.Function.sub(self, i, deepcopy, **kwargs))
             fs.append(f.function_space())
             ret.append(f)
         fa = FunctionAssigner(fs, self.function_space())
         block = FunctionAssignerBlock(fa,
                                       Enlist(self),
                                       ad_block_tag=ad_block_tag)
         tape = get_working_tape()
         tape.add_block(block)
         for output in ret:
             block.add_output(output.block_variable)
         ret = tuple(ret)
     else:
         ret = tuple(
             compat.create_function(self,
                                    i,
                                    block_class=FunctionSplitBlock,
                                    _ad_floating_active=True,
                                    _ad_args=[self, i],
                                    _ad_output_args=[i],
                                    output_block_class=FunctionMergeBlock,
                                    _ad_outputs=[self])
             for i in range(num_sub_spaces))
     return ret