Source code for rtctools.optimization.initial_state_estimation_mixin

from typing import List, Tuple, Union

from .goal_programming_mixin import Goal, GoalProgrammingMixin


class _MeasurementGoal(Goal):
    def __init__(self, state, measurement_id, max_deviation=1.0):
        self.__state = state
        self.__measurement_id = measurement_id

        self.function_nominal = max_deviation

    def function(self, optimization_problem, ensemble_member):
        op = optimization_problem
        return (
            op.state_at(self.__state, op.initial_time, ensemble_member) -
            op.timeseries_at(self.__measurement_id, op.initial_time, ensemble_member))

    order = 2
    priority = -2


class _SmoothingGoal(Goal):
    def __init__(self, state1, state2, max_deviation=1.0):
        self.__state1 = state1
        self.__state2 = state2

        self.function_nominal = max_deviation

    def function(self, optimization_problem, ensemble_member):
        op = optimization_problem
        return (
            op.state_at(self.__state1, op.initial_time, ensemble_member) -
            op.state_at(self.__state2, op.initial_time, ensemble_member))

    order = 2
    priority = -1


[docs]class InitialStateEstimationMixin(GoalProgrammingMixin): """ Adds initial state estimation to your optimization problem *using goal programming*. Before any other goals are evaluated, first, the deviation between initial state measurements and their respective model states is minimized in the least squares sense (1DVAR, priority -2). Secondly, the distance between pairs of states is minimized, again in the least squares sense, so that "smooth" initial guesses are provided for states without measurements (priority -1). .. note:: There are types of problems where, in addition to minimizing differences between states and measurements, it is advisable to perform a steady-state initialization using additional initial-time model equations. For hydraulic models, for instance, it is often helpful to require that the time-derivative of the flow variables vanishes at the initial time. """
[docs] def initial_state_measurements(self) -> List[Union[Tuple[str, str], Tuple[str, str, float]]]: """ List of pairs ``(state, measurement_id)`` or triples ``(state, measurement_id, max_deviation)``, relating states to measurement time series IDs. The default maximum deviation is ``1.0``. """ return []
[docs] def initial_state_smoothing_pairs(self) -> List[Union[Tuple[str, str], Tuple[str, str, float]]]: """ List of pairs ``(state1, state2)`` or triples ``(state1, state2, max_deviation)``, relating states the distance of which is to be minimized. The default maximum deviation is ``1.0``. """ return []
def goals(self): g = super().goals() for measurement in self.initial_state_measurements(): g.append(_MeasurementGoal(*measurement)) for smoothing_pair in self.initial_state_smoothing_pairs(): g.append(_SmoothingGoal(*smoothing_pair)) return g