Ejemplo n.º 1
0
class AlgebraicBlock(ModelElementBlock):

    __var = VariableNames()

    def __init__(self, *args, **kwargs):
        super().__init__(class_name='model_algebraic')

    @property
    def fixed(self):

        fix_from_traj = []
        for alg in self.algebraics.values():
            if alg.data is not None:
                fix_from_traj.append(
                    [self.__var.algebraic, alg.name, alg.data])

        return fix_from_traj

    @property
    def steps(self):

        steps = {}
        for alg in self.algebraics.values():
            if alg.step is not None:
                steps[alg.name] = alg

        return steps
Ejemplo n.º 2
0
    def __init__(self, reaction_models):

        #super(MultipleExperimentsEstimator, self).__init__()
        self.reaction_models = reaction_models
        self.experiments = list(self.reaction_models.keys())
        self._idx_to_variable = dict()

        self.variances = {
            name: model.variances
            for name, model in self.reaction_models.items()
        }
        self.make_sublist()

        self._n_meas_times = 0
        self._n_meas_lambdas = 0
        self._n_actual = 0
        self._n_params = 0

        self._spectra_given = True
        self._concentration_given = False

        self.global_params = None
        self.parameter_means = False

        self.__var = VariableNames()
Ejemplo n.º 3
0
    def __init__(self, model):
        """It takes in a standard Kipet/Pyomo model, rewrites it and calls 
        fe_factory. More information on fe_factory is included in that class
        description.
    
        Args:
            model (ConcreteModel): Pyomo model passed from KIPET
        
        """
        super(FESimulator, self).__init__(model)

        # KIPET variables
        self.__var = VariableNames()

        self.p_sim = PyomoSimulator(model)
        self.model = self.p_sim.model
        self.param_dict = {}
        self.param_name = self.__var.model_parameter

        # setattr(self.model, 'test_var', Var(self.model.alltime,
        #                                       [0],
        #                                       initialize=1.0))
        # print(self.model.test_var.display())

        self.c_sim = self.model.clone()

        # Check all parameters are fixed before simulating
        for param_obj in getattr(self.model,
                                 self.__var.model_parameter).values():
            if not param_obj.fixed:
                param_obj.fixed = True
        # Build the parameter dictionary in the format that fe_factory uses
        model_var = self.__var.model_parameter

        for k, v in getattr(self.model, model_var).items():
            self.param_dict[model_var, k] = v.value

        #Build the initial condition dictionary in the format that fe_factory uses
        vars_to_init = [
            self.__var.concentration_model,
            self.__var.state_model,
        ]

        self.ics_ = {}
        for var in vars_to_init:
            self._var_init(var)
Ejemplo n.º 4
0
    def __init__(self, model):
        """Simulator constructor.

        Note:
            Makes a shallow copy to the model. Changes applied to
            the model within the simulator are applied to the original
            model passed to the simulator

        Args:
            model (Pyomo model)
        """
        self.__var = VariableNames()

        super(PyomoSimulator, self).__init__(model)
        self._alltimes = sorted(
            self.model.alltime)  #added for special structure CS
        #self._times = sorted(self.model.time)
        self._n_alltimes = len(self._alltimes)  #added for special structure CS
        #self._n_times = len(self._times)
        self._meas_times = sorted(self.model.meas_times)
        self._allmeas_times = sorted(self.model.allmeas_times)
        self._ipopt_scaled = False
        self._spectra_given = hasattr(self.model, self.__var.spectra_data)
        self._concentration_given = hasattr(
            self.model, self.__var.concentration_measured) or hasattr(
                self.model, self.__var.user_defined) or hasattr(
                    self.model, self.__var.state)
        self._conplementary_states_given = hasattr(self.model,
                                                   self.__var.state)
        self._absorption_given = hasattr(
            self.model, self.__var.spectra_species
        )  # added for special case of absorption data available but not concentration data CS
        self._huplc_given = hasattr(self.model, 'Chat')
        self._smoothparam_given = hasattr(self.model,
                                          self.__var.smooth_parameter)

        # creates scaling factor suffix
        if not hasattr(self.model, 'scaling_factor'):
            self.model.scaling_factor = Suffix(direction=Suffix.EXPORT)
Ejemplo n.º 5
0
"""
Helper functions for making KIPET models
"""
from kipet.top_level.variable_names import VariableNames

__var = VariableNames()


def step_fun(model,
             time_var,
             num='0',
             coeff=1,
             time=1e-3,
             fixed=True,
             switch=False,
             M=1,
             eta=1e-2,
             constant=0.5):
    """This formulates the step functions for KIPET using a sigmoidal function
    
    Args:
        model: The ConcreteModel using the step function
        
        time_var (float): Time point for step
        
        num (str): The name of the step function
        
        coeff (float): Coefficient for the step size
        
        time (float): The time for the step change (init if not fixed)
        
Ejemplo n.º 6
0
    def __init__(self,
                 model_orig,
                 src_mod,
                 init_con=None,
                 param_name=None,
                 param_values=None,
                 inputs=None,
                 inputs_sub=None,
                 jump_times=None,
                 jump_states=None):
        """
        The `the paran name` might be a list of strings or a single string
          corresponding to the parameters of the model.
        The `param_values` dictionary needs to be declared with the following 
        syntax: `param_dict["P", "k0"] = 49.7796`
        
        Where the first key corresponds to one of the parameter names, and the
        second to the corresponding index (if any).
        
        A similar structure is expected for the initial conditions and inputs.

        The `inputs` and `input_sub` parameters are in place depending of 
        whether there is a single index input or a multiple index input.

        Note that if the user does not provide correct information to 
        fe_factory; an exception will be thrown because of the n_var and m_eqn
        check for simulation.

        Once the constructor is called, one can initialize the model with the 
        following sintax: `self.load_initial_conditions(init_cond=ics_dict)`

        Finally, to run the initialization and automatic data patching to tgt
        model use: `self.run()`

        If a given finite element problem fails, we do will try once again with
        relaxed options. It is recommended to go back and check the model for 
        better understanding of the issue.

        Finally, an explicit function of time on the right hand side is 
        prohibited. Please put this information into an input (fixed variable)
        instead.

        Args:
            tgt_mod (ConcreteModel): The originall fully discretized model 
                that we want to patch the information to.
            
            src_mod (ConcreteModel): The undiscretized reference model.
            
            init_con (str): The initial constraint name (corresponds to a 
                Constraint object).
            
            param_name (list): The param name list. (Each element must 
                correspond to a pyomo Var)
            
            param_values (dict): The corresponding values: 
                `param_dict["param_name", "param_index"] = 49.7796`
                
            inputs (dict): The input dictionary. Use this dictonary for single
                index (time) inputs
            inputs_sub (dict): The multi-index dictionary. Use this dictionary
                for multi-index inputs.
        
        """
        # This is a huge __init__ ==> offload to methods
        self.__var = VariableNames()

        self.ip = SolverFactory('ipopt')
        self.ip.options['halt_on_ampl_error'] = 'yes'
        self.ip.options['print_user_options'] = 'yes'

        self.model_orig = model_orig
        self.model_ref = src_mod.clone()

        time_index = None
        for i in self.model_ref.component_objects(ContinuousSet):
            time_index = i
            break
        if time_index is None:
            raise Exception('no continuous_set')

        self.time_set = time_index.name

        model_original_time_set = getattr(self.model_orig, self.time_set)
        self.ncp = model_original_time_set.get_discretization_info()['ncp']
        fe_l = model_original_time_set.get_finite_elements()

        self.fe_list = [fe_l[i + 1] - fe_l[i] for i in range(0, len(fe_l) - 1)]
        self.nfe = len(self.fe_list)

        #: Re-construct the model with [0,1] time domain
        times = getattr(self.model_ref, self.time_set)
        change_continuous_set(times, [0, 1])

        for var in self.model_ref.component_objects(Var):
            var.clear()
            var.reconstruct()

        for con in self.model_ref.component_objects(Constraint):
            con.clear()
            con.construct()

        # self.model_ref.display(filename="selfmoddisc0.txt")
        #: Discretize
        d = TransformationFactory('dae.collocation')
        d.apply_to(self.model_ref,
                   nfe=1,
                   ncp=self.ncp,
                   scheme='LAGRANGE-RADAU')

        #: Find out the differential variables
        self.dvs_names = []
        self.dvar_names = []

        for con in self.model_ref.component_objects(Constraint):
            name = con.name
            namel = name.split('_', 1)
            if len(namel) > 1:
                if namel[1] == "disc_eq":
                    realname = getattr(self.model_ref, namel[0])
                    self.dvar_names.append(namel[0])
                    self.dvs_names.append(realname.get_state_var().name)
        self.model_ref.h_i = Param(times, mutable=True,
                                   default=1.0)  #: Length of finite element

        #: Modify the collocation equations to introduce h_i (the length of finite element)
        for i in self.dvar_names:
            con = getattr(self.model_ref, i + '_disc_eq')
            dv = getattr(self.model_ref, i)
            e_dict = {}
            fun_tup = True
            for k in con.keys():
                if isinstance(k, tuple):
                    pass
                else:
                    k = (k, )
                    fun_tup = False
                e = con[k].expr.args[0]
                e_dict[k] = e * self.model_ref.h_i[k[0]] + dv[k] * (
                    1 - self.model_ref.h_i[k[0]]
                ) == 0.0  #: As long as you don't clone
            if fun_tup:
                self.model_ref.add_component(
                    i + "_deq_aug",
                    Constraint(con.index_set(),
                               rule=lambda m, *j: e_dict[j]
                               if j[0] > 0.0 else Constraint.Skip))
            else:
                self.model_ref.add_component(
                    i + "_deq_aug",
                    Constraint(con.index_set(),
                               rule=lambda m, j: e_dict[j]
                               if j > 0.0 else Constraint.Skip))
            self.model_ref.del_component(con)

        #: Sets for iteration
        #: Differential variables
        self.remaining_set = {}
        for i in self.dvs_names:
            dv = getattr(self.model_ref, i)
            if dv.index_set().name == times.name:  #: Just time set
                #print(i, 'here')
                self.remaining_set[i] = None
                continue
            #set_i = dv._implicit_subsets  #: More than just time set
            #set_i = dv._index._implicit_subsets #Update for pyomo 5.6.8 KH.L
            set_i = identify_member_sets(dv)
            # set_i = identify_member_sets(dv.index_set())
            #print(f'set_i = {set_i}')
            remaining_set = set_i[1]
            for s in set_i[2:]:
                remaining_set *= s
            if isinstance(remaining_set, list):
                self.remaining_set[i] = remaining_set
            else:
                self.remaining_set[i] = []
                self.remaining_set[i].append(remaining_set)
        #: Algebraic variables
        self.weird_vars = []  #:Not indexed by time
        self.remaining_set_alg = {}
        # with open('model_check.txt', 'w') as f5:
        #     self.model_ref.pprint(ostream = f5)
        for av in self.model_ref.component_objects(Var):

            # print(av.name)
            if av.name in self.dvs_names:
                continue
            if av.index_set().name == times.name:  #: Just time set
                self.remaining_set_alg[av.name] = None
                continue
            #set_i = av._implicit_subsets
            #set_i = av._index._implicit_subsets #Update for pyomo 5.6.8 KH.L
            set_i = identify_member_sets(av)
            if set_i is None or not times in set_i:
                self.weird_vars.append(av.name)  #: Not indexed by time!
                continue  #: if this happens we might be in trouble
            remaining_set = set_i[1]  #: Index by time and others
            for s in set_i[2:]:
                if s.name == times.name:
                    self.remaining_set_alg[av.name] = None
                    continue
                else:
                    remaining_set *= s
            if isinstance(remaining_set, list):
                self.remaining_set_alg[av.name] = remaining_set
            else:
                self.remaining_set_alg[av.name] = []
                self.remaining_set_alg[av.name].append(remaining_set)

        if init_con is not None:  #: Delete the initial conditions (we use .fix() instead)
            ic = getattr(self.model_ref, init_con)
            self.model_ref.del_component(ic)

        if isinstance(param_name, list):  #: Time independent parameters
            if param_values:
                if isinstance(param_values, dict):
                    for pname in param_name:
                        p = getattr(self.model_ref, pname)
                        for key in p.keys():
                            try:
                                val = param_values[pname, key]
                                p[key].set_value(val)
                            except KeyError:
                                raise Exception(
                                    "Missing a key of the param_values\n"
                                    "Please provide all the required keys.\n"
                                    "missing: {}".format(key))
                            p[key].fix()
                else:
                    Exception(
                        "Arg param_values should be provided in a dictionary")
            else:
                Exception(
                    "Arg param_values should be provided in a dictionary")
        elif isinstance(param_name, str):
            if param_values:
                if isinstance(param_values, dict):
                    p = getattr(self.model_ref, param_name)
                    for key in p.keys():
                        try:
                            val = param_values[param_name, key]
                            p[key].set_value(val)
                        except KeyError:
                            raise Exception(
                                "Missing a key of the param_values\n"
                                "Please provide all the required keys.\n"
                                "missing: {}".format(key))
                        p[key].fix()
        elif not param_name:
            pass
        else:
            raise Exception("wrong type for param_name")

        #: Fix initial conditions
        for i in self.dvs_names:
            dv = getattr(self.model_ref, i)
            if self.remaining_set[i] is None:
                dv[0].fix()
            for rs in self.remaining_set[i]:
                for k in rs:
                    k = k if isinstance(k, tuple) else (k, )
                    dv[(0, ) + k].fix()

        self.inputs = None
        self.input_remaining_set = {}

        #: Check if inputs are declared
        # if self.inputs is not None:
        #     if not isinstance(inputs, dict) or isinstance(inputs, str):
        #         raise Exception("Must be a dict or str")
        #     if isinstance(inputs, str):
        #         self.inputs = [self.inputs]
        #     for i in self.inputs:
        #         p = getattr(self.model_ref, i)
        #         p.fix()
        #         if p.index_set().name == times.name:  #: Only time-set
        #             self.input_remaining_set[i] = None
        #             continue
        #         #set_i = p._implicit_subsets
        #         #set_i = p._index._implicit_subsets #Update for pyomo 5.6.8 KH.L
        #         set_i = identify_member_sets(p)
        #         if not times in set_i:
        #             raise RuntimeError("{} is not by index by time, this can't be an input".format(i))
        #         remaining_set = set_i[1]
        #         for s in set_i[2:]:
        #             if s.name == times.name:  #: would this ever happen?
        #                 continue
        #             else:
        #                 remaining_set *= s
        #         if isinstance(remaining_set, list):
        #             self.input_remaining_set[i] = remaining_set
        #         else:
        #             self.input_remaining_set[i] = []
        #             self.input_remaining_set[i].append(remaining_set)

        #self.inputs_sub = None
        # inputs_sub['some_var'] = ['index0', 'index1', ('index2a', 'index2b')]

        self.inputs_sub = inputs_sub
        #print(times.name)
        #print([i.name for i in get_index_sets(getattr(self.model_ref, 'Dose'))])

        #print(times.display())

        if self.inputs_sub is not None:
            for key in self.inputs_sub.keys():
                model_var_obj = getattr(self.model_ref, key)

                # This finds the index of the set
                # if identify_member_sets(model_var_obj) is None:
                #     raise RuntimeError("This variable is does not have multiple indices"
                #                         "Pass {} as part of the inputs keyarg instead.".format(key))
                # elif model_var_obj.index_set().name == times.name:
                #     raise RuntimeError("This variable is indexed over time"
                #                         "Pass {} as part of the inputs keyarg instead.".format(key))
                # else:
                #     if times not in identify_member_sets(model_var_obj):
                #         raise RuntimeError("{} is not indexed over time; it can not be an input".format(key))

                for k in self.inputs_sub[key]:
                    if isinstance(k, str) or isinstance(k, int) or isinstance(
                            k, tuple):
                        k = (k, ) if not isinstance(k, tuple) else k
                    else:
                        raise RuntimeError("{} is not a valid index".format(k))

                    for t in times:
                        model_var_obj[(t, ) + k].fix()

        if hasattr(self.model_ref, self.__var.time_step_change):
            for time_step in getattr(self.model_ref,
                                     self.__var.time_step_change):
                getattr(self.model_ref,
                        self.__var.time_step_change)[time_step].fix()

        if hasattr(self.model_ref, self.__var.model_constant):
            for param, obj in getattr(self.model_ref,
                                      self.__var.model_constant).items():
                obj.fix()

        # : Check n vars and m equations
        (n, m) = reconcile_nvars_mequations(self.model_ref)
        if n != m:
            raise Exception("Inconsistent problem; n={}, m={}".format(n, m))
        self.jump = False
Ejemplo n.º 7
0
class Comp():

    var = VariableNames()

    def __init__(self, model, constant_info=None):

        self._model = model
        self._model_vars = self.var.model_vars
        self._rate_vars = self.var.rate_vars
        self.constant_info = constant_info
        self.var_dict = {}
        self.var_unit_dict = {}
        self.assign_vars()
        self.assign_rate_vars()

    def assign_vars(self):
        """Digs through and assigns the variables as top-level attributes
        
        """
        list_of_vars = self._model_vars

        for mv in list_of_vars:
            if hasattr(self._model, mv):
                mv_obj = getattr(self._model, mv)
                index_sets = get_index_sets(mv_obj)

                dim = len(index_sets)
                if dim > 1:
                    indx = 1
                else:
                    indx = 0

                comp_set = list(index_sets[indx].keys())
                for comp in comp_set:

                    comp = str(comp)
                    if isinstance(comp, str):
                        if isinstance(comp[0], int):
                            comp.insert(0, 'y')

                        comp_name = comp
                        for k, v in string_replace_dict.items():
                            comp_name.replace(k, v)

                    self.var_dict[comp_name] = ModalVar(
                        comp_name, comp_name, mv, self._model)

                    if dim > 1:
                        setattr(self, comp_name, mv_obj[0, comp])
                    else:
                        setattr(self, comp_name, mv_obj[comp])

    def assign_rate_vars(self):

        for mv in self._rate_vars:
            if hasattr(self._model, mv):

                mv_obj = getattr(self._model, mv)
                index_sets = get_index_sets(mv_obj)
                comp_set = list(index_sets[-1].keys())
                dim = len(index_sets)

                for comp in comp_set:

                    if isinstance(comp, str):
                        comp_name = comp
                        comp_name.replace(' ', '_')
                    elif isinstance(comp, int):
                        comp_name = f'y{comp}'

                    comp_name = f'd{comp_name}dt'
                    self.var_dict[comp_name] = ModalVar(
                        comp_name, str(comp), mv, self._model)
                    if dim > 1:
                        setattr(self, comp_name, mv_obj[0, comp])
                    else:
                        setattr(self, comp_name, mv_obj[comp])

    def _id(self, comp):

        id_ = id(getattr(self, comp))
        print(id_)
        return id_

    @property
    def get_var_list(self):

        return list(self.var_dict.keys())


# class Comp_Check():

#     var = VariableNames()

#     def __init__(self, model, param_list):

#         self._model = model
#         self._param_list = param_list
#         self.var_dict = {}
#         self.assign_params_for_units_check()

#     def assign_params_for_units_check(self):
#         """Digs through and assigns the variables as top-level attributes

#         """
#         m = self._model
#         for var in self._param_list:
#             if hasattr(m, var):
#                 var_obj = getattr(m, var)
#                 self.var_dict[var] = var_obj
#                 setattr(self, var, var_obj)

# def get_unit_model(element_dict, set_up_model):
#     """Takes a ReactionModel instance and returns a Comp_Check object
#     representing the model's varialbes with units
#     """
#     unit_model = ConcreteModel()
#     new_params = set()
#     for elem, comp_block in element_dict.items():
#         if len(comp_block) > 0:
#             for comp in comp_block:

#                 new_params.add(comp.name)
#                 m_units = comp.units
#                 if m_units is None:
#                     m_units = str(1)
#                 else:
#                     m_units = getattr(u, str(m_units))

#                 print(m_units)
#                 print(type(m_units))
#                 setattr(unit_model, comp.name, Var(initialize=1, units=m_units))

#     c_units = Comp_Check(unit_model, list(new_params))

#     return c_units