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)
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
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