def __call__(self, m_array): ''' An implementation of the reduced functional evaluation that accepts the control values as an array of scalars ''' # In case the annotation is not reused, we need to reset any prior annotation of the adjointer before reruning the forward model. if not self.replays_annotation: solving.adj_reset() # We move in control space, so we also need to reset the factorisation cache adj_reset_cache() # Now its time to update the control values using the given array m = self.rf.controls.__class__([p.data() for p in self.controls]) self.set_local(m, m_array) return self.__base_call__(m)
def __call__(self, value): """ Evaluates the reduced functional for the given control value. Args: value: The point in control space where to perform the Taylor test. Must be of the same type as the Control (e.g. Function, Constant or lists of latter). Returns: float: The functional value. """ # Make sure we do not annotate # Reset any cached data in dolfin-adjoint adj_reset_cache() #: The control values at which the reduced functional is to be evaluated. value = enlist(value) # Call callback self.eval_cb_pre(delist(value, list_type=self.controls)) # Update the control values on the tape ListControl(self.controls).update(value) # Check if the result is already cached if self.cache: hash = value_hash(value) if hash in self._cache["functional_cache"]: # Found a cache info_green("Got a functional cache hit") return self._cache["functional_cache"][hash] # Replay the annotation and evaluate the functional func_value = 0. for i in range(adjointer.equation_count): (fwd_var, output) = adjointer.get_forward_solution(i) if isinstance(output.data, Function): output.data.rename(str(fwd_var), "a Function from dolfin-adjoint") # Call callback self.replay_cb(fwd_var, output.data, delist(value, list_type=self.controls)) # Check if we checkpointing is active and if yes # record the exact same checkpoint variables as # in the initial forward run if adjointer.get_checkpoint_strategy() != None: if str(fwd_var) in mem_checkpoints: storage = libadjoint.MemoryStorage(output, cs=True) storage.set_overwrite(True) adjointer.record_variable(fwd_var, storage) if str(fwd_var) in disk_checkpoints: storage = libadjoint.MemoryStorage(output) adjointer.record_variable(fwd_var, storage) storage = libadjoint.DiskStorage(output, cs=True) storage.set_overwrite(True) adjointer.record_variable(fwd_var, storage) if not str(fwd_var) in mem_checkpoints and not str( fwd_var) in disk_checkpoints: storage = libadjoint.MemoryStorage(output) storage.set_overwrite(True) adjointer.record_variable(fwd_var, storage) # No checkpointing, so we record everything else: storage = libadjoint.MemoryStorage(output) storage.set_overwrite(True) adjointer.record_variable(fwd_var, storage) if i == adjointer.timestep_end_equation(fwd_var.timestep): func_value += adjointer.evaluate_functional( self.functional, fwd_var.timestep) if adjointer.get_checkpoint_strategy() != None: adjointer.forget_forward_equation(i) self.current_func_value = func_value # Call callback self.eval_cb_post(self.scale * func_value, delist(value, list_type=self.controls)) if self.cache: # Add result to cache info_red("Got a functional cache miss") self._cache["functional_cache"][hash] = self.scale * func_value return self.scale * func_value
def __call__(self, value): """ Evaluates the reduced functional for the given control value. Args: value: The point in control space where to perform the Taylor test. Must be of the same type as the Control (e.g. Function, Constant or lists of latter). Returns: float: The functional value. """ # Make sure we do not annotate # Reset any cached data in dolfin-adjoint adj_reset_cache() #: The control values at which the reduced functional is to be evaluated. value = enlist(value) # Call callback self.eval_cb_pre(delist(value, list_type=self.controls)) # Update the control values on the tape ListControl(self.controls).update(value) # Check if the result is already cached if self.cache: hash = value_hash(value) if hash in self._cache["functional_cache"]: # Found a cache info_green("Got a functional cache hit") return self._cache["functional_cache"][hash] # Replay the annotation and evaluate the functional func_value = 0. for i in range(adjointer.equation_count): (fwd_var, output) = adjointer.get_forward_solution(i) if isinstance(output.data, Function): output.data.rename(str(fwd_var), "a Function from dolfin-adjoint") # Call callback self.replay_cb(fwd_var, output.data, delist(value, list_type=self.controls)) # Check if we checkpointing is active and if yes # record the exact same checkpoint variables as # in the initial forward run if adjointer.get_checkpoint_strategy() != None: if str(fwd_var) in mem_checkpoints: storage = libadjoint.MemoryStorage(output, cs = True) storage.set_overwrite(True) adjointer.record_variable(fwd_var, storage) if str(fwd_var) in disk_checkpoints: storage = libadjoint.MemoryStorage(output) adjointer.record_variable(fwd_var, storage) storage = libadjoint.DiskStorage(output, cs = True) storage.set_overwrite(True) adjointer.record_variable(fwd_var, storage) if not str(fwd_var) in mem_checkpoints and not str(fwd_var) in disk_checkpoints: storage = libadjoint.MemoryStorage(output) storage.set_overwrite(True) adjointer.record_variable(fwd_var, storage) # No checkpointing, so we record everything else: storage = libadjoint.MemoryStorage(output) storage.set_overwrite(True) adjointer.record_variable(fwd_var, storage) if i == adjointer.timestep_end_equation(fwd_var.timestep): func_value += adjointer.evaluate_functional(self.functional, fwd_var.timestep) if adjointer.get_checkpoint_strategy() != None: adjointer.forget_forward_equation(i) self.current_func_value = func_value # Call callback self.eval_cb_post(self.scale * func_value, delist(value, list_type=self.controls)) if self.cache: # Add result to cache info_red("Got a functional cache miss") self._cache["functional_cache"][hash] = self.scale*func_value return self.scale*func_value