示例#1
0
    def get_xdot(self, nlp_numerics_options, V, model):
        """ Get state derivates on all collocation nodes based on polynomials
        """

        scheme = nlp_numerics_options['collocation']['scheme']

        Vdot = struct_op.construct_Xdot_struct(nlp_numerics_options, model)

        # size of the finite elements
        h = 1. / self.__n_k

        store_derivatives = []

        # collect the derivatives
        for k in range(self.__n_k):

            tf = struct_op.calculate_tf(nlp_numerics_options, V, k)

            # For all collocation points
            for j in range(self.__d + 1):
                # get an expression for the state derivative at the collocation point
                xp_jk = self.__calculate_collocation_deriv(V, k, j)

                xdot = xp_jk / h / tf
                store_derivatives = cas.vertcat(store_derivatives, xdot)

        Xdot = Vdot(store_derivatives)

        return Xdot
示例#2
0
    def discretize_constraints(self, options, model, formulation, V, P):
        """Discretize dynamics and path constraints in a (possibly) parallelizable fashion

        @param options nlp options
        @param model awebox model
        @param formulation awebox formulation
        @param V decision variables
        @param P nlp parameters
        """

        # rearrange nlp variables
        self.__ms_nlp_vars(options, model, V, P)

        # implicit values of algebraic variables at interval nodes
        ms_z0 = self.__ms_z0

        # evaluate dynamics and constraint functions on all intervals
        if options['parallelization']['include']:

            # use function map for parallellization
            parallellization = options['parallelization']['type']
            F_map = self.__F.map('F_map', parallellization, self.__n_k, [], [])
            path_constraints_fun = model.constraints_fun.map(
                'constraints_map', parallellization, self.__n_k, [],
                [])  # notice that these are the model inequality constraints
            outputs_fun = model.outputs_fun.map('outputs_fun',
                                                parallellization, self.__n_k,
                                                [], [])

            # integrate
            ms_dynamics = F_map(x0=self.__ms_x, z0=self.__ms_z, p=self.__ms_p)
            ms_xf = ms_dynamics['xf']
            ms_qf = cas.horzcat(np.zeros(self.__dae.dae['quad'].size()),
                                ms_dynamics['qf'])
            ms_constraints = path_constraints_fun(
                self.__ms_vars,
                self.__ms_params)  # evaluate the model ineqs. at
            ms_outputs = outputs_fun(self.__ms_vars, self.__ms_params)

            # integrate quadrature outputs
            for i in range(self.__n_k):
                ms_qf[:, i + 1] = ms_qf[:, i + 1] + ms_qf[:, i]

        else:

            # initialize function evaluations
            ms_xf = []
            ms_qf = np.zeros(self.__dae.dae['quad'].size())
            ms_constraints = []
            ms_outputs = []

            # evaluate functions in for loop
            for i in range(self.__n_k):
                ms_dynamics = self.__F(x0=self.__ms_x[:, i],
                                       z0=self.__ms_z[:, i],
                                       p=self.__ms_p[:, i])
                ms_xf = cas.horzcat(ms_xf, ms_dynamics['xf'])
                ms_qf = cas.horzcat(ms_qf, ms_qf[:, -1] + ms_dynamics['qf'])
                ms_constraints = cas.horzcat(
                    ms_constraints,
                    model.constraints_fun(self.__ms_vars[:, i],
                                          self.__ms_params[:, i]))
                ms_outputs = cas.horzcat(
                    ms_outputs,
                    model.outputs_fun(self.__ms_vars[:, i],
                                      self.__ms_params[:, i]))

        # integral outputs and constraints
        Integral_outputs_list = self.__build_integral_outputs(
            ms_qf, model.integral_outputs)
        Integral_constraints_list = None

        # construct state derivative struct
        Xdot = struct_op.construct_Xdot_struct(options, model.variables_dict)
        Xdot = self.__fill_in_Xdot(Xdot)

        return ms_xf, ms_z0, self.__ms_vars, self.__ms_params, Xdot, ms_constraints, ms_outputs, Integral_outputs_list, Integral_constraints_list
示例#3
0
def discretize(nlp_numerics_options, model, formulation):

    # -----------------------------------------------------------------------------
    # discretization setup
    # -----------------------------------------------------------------------------
    nk = nlp_numerics_options['n_k']

    if nlp_numerics_options['discretization'] == 'direct_collocation':
        direct_collocation = True
        ms = False
        d = nlp_numerics_options['collocation']['d']
        scheme = nlp_numerics_options['collocation']['scheme']
        Collocation = collocation.Collocation(nk, d, scheme)
        Multiple_shooting = None

    elif nlp_numerics_options['discretization'] == 'multiple_shooting':
        direct_collocation = False
        ms = True
        Collocation = None
        dae = model.get_dae()
        Multiple_shooting = multiple_shooting.Multiple_shooting(
            nk, dae, nlp_numerics_options['integrator'])
        slacks = None

    # --------------------------------------
    # prepare model variables and dynamics
    # --------------------------------------
    variables = model.variables
    parameters = model.parameters
    variables_dict = model.variables_dict

    #---------------------------------------
    # prepare constraints structure
    #---------------------------------------
    form_constraints = formulation.constraints
    constraints_fun = formulation.constraints_fun  # initial, terminal and periodicity constraints
    path_constraints = model.constraints
    path_constraints_fun = model.constraints_fun
    g_struct = constraints.setup_constraint_structure(
        nlp_numerics_options, model,
        formulation)  # empty struct for collocated constraints

    #-------------------------------------------
    # DISCRETIZE VARIABLES, CREATE NLP PARAMETERS
    #-------------------------------------------
    V = setup_nlp_v(nlp_numerics_options, model, formulation, Collocation)
    P = setup_nlp_p(V, model)
    if direct_collocation:
        Xdot = Collocation.get_xdot(nlp_numerics_options, V, model)

    # construct time grids for this nlp
    time_grids = construct_time_grids(nlp_numerics_options)

    # ---------------------------------------
    # prepare outputs structure
    # ---------------------------------------
    outputs = model.outputs
    outputs_fun = model.outputs_fun

    [form_outputs, form_outputs_dict
     ] = performance.collect_performance_outputs(nlp_numerics_options, model,
                                                 V)
    form_outputs_fun = cas.Function('form_outputs_fun', [V, P],
                                    [form_outputs.cat])

    Outputs_struct = setup_output_structure(nlp_numerics_options, outputs,
                                            form_outputs)

    #-------------------------------------------
    # COLLOCATE CONSTRAINTS, OUTPUTS
    #-------------------------------------------

    # prepare listing of outputs and constraints
    Outputs_list = []
    g_list = []
    g_bounds = {'lb': [], 'ub': []}

    # extract model.parameters from V
    param_at_time = parameters(cas.vertcat(P['theta0'], V['phi']))
    xi = V['xi']  #TODO: don't hard code!

    # parallellize constraints on collocation nodes
    if direct_collocation:
        [
            coll_dynamics, coll_constraints, coll_outputs,
            Integral_outputs_list, Integral_constraint_list
        ] = Collocation.collocate_constraints(nlp_numerics_options, model,
                                              formulation, V, P, Xdot)

    # parallellize constraints on interval nodes
    if ms:
        [
            ms_xf, ms_z0, Xdot, ms_constraints, ms_outputs,
            Integral_outputs_list, Integral_constraint_list
        ] = Multiple_shooting.discretize_constraints(nlp_numerics_options,
                                                     model, formulation, V, P)

    # Construct list of constraints (+ bounds) and outputs
    for kdx in range(nk):

        # time constant of the following interval
        tf = struct_op.calculate_tf(nlp_numerics_options, V, kdx)

        if kdx == 0:

            # extract initial (reference) variables
            var_initial = struct_op.get_variables_at_time(
                nlp_numerics_options, V, Xdot, model, 0)
            var_ref_initial = struct_op.get_var_ref_at_time(
                nlp_numerics_options, P, V, Xdot, model, 0)

            # add initial constraints
            [g_list, g_bounds] = constraints.append_initial_constraints(
                g_list, g_bounds, form_constraints, constraints_fun,
                var_initial, var_ref_initial, xi)

        if (ms) or (direct_collocation and scheme != 'radau'):

            # at each interval node, algebraic constraints should be satisfied
            [g_list, g_bounds] = constraints.append_algebraic_constraints(
                g_list, g_bounds, dae.z(ms_z0[:, kdx]), V, kdx)

            # at each interval node, path constraints should be satisfied
            if 'us' in list(V.keys()):  # slack path constraints
                slacks = V['us', kdx]

            [g_list, g_bounds] = constraints.append_path_constraints(
                g_list, g_bounds, path_constraints, ms_constraints[:, kdx],
                slacks)

            # compute outputs for this time interval
            Outputs_list.append(ms_outputs[:, kdx])

        if direct_collocation:

            # add constraints and outputs on collocation nodes
            for ddx in range(d):

                # at each (except for first node) collocation point dynamics should meet
                [g_list,
                 g_bounds] = constraints.append_collocation_constraints(
                     g_list, g_bounds, coll_dynamics[:, kdx * d + ddx])

                # at each (except for first node) collocation node, path constraints should be satisfied
                [g_list, g_bounds] = constraints.append_path_constraints(
                    g_list, g_bounds, path_constraints,
                    coll_constraints[:, kdx * d + ddx])

                # compute outputs for this time interval
                Outputs_list.append(coll_outputs[:, kdx * d + ddx])

            # endpoint should match next start point
            [g_list, g_bounds] = Collocation.append_continuity_constraint(
                g_list, g_bounds, V, kdx)

        elif ms:

            # endpoint should match next start point
            [g_list,
             g_bounds] = Multiple_shooting.append_continuity_constraint(
                 g_list, g_bounds, ms_xf, V, kdx)

    # extract terminal (reference) variables
    var_terminal = struct_op.get_variables_at_final_time(
        nlp_numerics_options, V, Xdot, model)
    var_ref_terminal = struct_op.get_var_ref_at_final_time(
        nlp_numerics_options, P, Xdot, model)

    # add terminal and periodicity constraints
    [g_list, g_bounds] = constraints.append_terminal_constraints(
        g_list, g_bounds, form_constraints, constraints_fun, var_terminal,
        var_ref_terminal, xi)
    [g_list, g_bounds] = constraints.append_periodic_constraints(
        g_list, g_bounds, form_constraints, constraints_fun, var_initial,
        var_terminal)

    if direct_collocation:
        [g_list, g_bounds] = constraints.append_integral_constraints(
            nlp_numerics_options, g_list, g_bounds, Integral_constraint_list,
            form_constraints, constraints_fun, V, Xdot, model,
            formulation.integral_constants)

    Outputs_list.append(form_outputs_fun(V, P))

    # Create Outputs struct and function
    Outputs = Outputs_struct(cas.vertcat(*Outputs_list))
    Outputs_fun = cas.Function('Outputs_fun', [V, P], [Outputs.cat])

    # Create Integral outputs struct and function
    Integral_outputs_struct = setup_integral_output_structure(
        nlp_numerics_options, model.integral_outputs)
    Integral_outputs = Integral_outputs_struct(
        cas.vertcat(*Integral_outputs_list))
    Integral_outputs_fun = cas.Function('Integral_outputs_fun', [V, P],
                                        [Integral_outputs.cat])

    # Create g struct and functions and g_bounds vectors
    [g, g_fun, g_jacobian_fun,
     g_bounds] = constraints.create_constraint_outputs(g_list, g_bounds,
                                                       g_struct, V, P)

    Xdot_struct = struct_op.construct_Xdot_struct(nlp_numerics_options, model)
    Xdot_fun = cas.Function('Xdot_fun', [V], [Xdot])

    return V, P, Xdot_struct, Xdot_fun, g_struct, g_fun, g_jacobian_fun, g_bounds, Outputs_struct, Outputs_fun, Integral_outputs_struct, Integral_outputs_fun, time_grids, Collocation, Multiple_shooting
示例#4
0
def discretize(nlp_options, model, formulation):

    # -----------------------------------------------------------------------------
    # discretization setup
    # -----------------------------------------------------------------------------
    nk = nlp_options['n_k']

    direct_collocation = (
        nlp_options['discretization'] == 'direct_collocation')
    multiple_shooting = (nlp_options['discretization'] == 'multiple_shooting')

    if direct_collocation:
        d = nlp_options['collocation']['d']
        scheme = nlp_options['collocation']['scheme']
        Collocation = coll_module.Collocation(nk, d, scheme)

        dae = None
        Multiple_shooting = None

        V = var_struct.setup_nlp_v(nlp_options, model, Collocation)
        P = setup_nlp_p(V, model)

        Xdot = Collocation.get_xdot(nlp_options, V, model)
        [coll_outputs, Integral_outputs_list, Integral_constraint_list
         ] = Collocation.collocate_outputs_and_integrals(
             nlp_options, model, formulation, V, P, Xdot)

        ms_xf = None
        ms_z0 = None
        ms_vars = None
        ms_params = None

    if multiple_shooting:
        dae = model.get_dae()
        Multiple_shooting = ms_module.Multiple_shooting(
            nk, dae, nlp_options['integrator'])
        Collocation = None

        V = var_struct.setup_nlp_v(nlp_options, model)
        P = setup_nlp_p(V, model)

        [
            ms_xf, ms_z0, ms_vars, ms_params, Xdot, _, ms_outputs,
            Integral_outputs_list, Integral_constraint_list
        ] = Multiple_shooting.discretize_constraints(nlp_options, model,
                                                     formulation, V, P)

    #-------------------------------------------
    # DISCRETIZE VARIABLES, CREATE NLP PARAMETERS
    #-------------------------------------------

    # construct time grids for this nlp
    time_grids = construct_time_grids(nlp_options)

    # ---------------------------------------
    # PREPARE OUTPUTS STRUCTURE
    # ---------------------------------------
    outputs = model.outputs

    form_outputs, _ = performance.collect_performance_outputs(
        nlp_options, model, V)
    form_outputs_fun = cas.Function('form_outputs_fun', [V, P],
                                    [form_outputs.cat])

    Outputs_struct = setup_output_structure(nlp_options, outputs, form_outputs)

    #-------------------------------------------
    # COLLOCATE OUTPUTS
    #-------------------------------------------

    # prepare listing of outputs and constraints
    Outputs_list = []

    # Construct outputs
    if multiple_shooting:
        for kdx in range(nk):
            # compute outputs for this time interval
            Outputs_list.append(ms_outputs[:, kdx])

    if direct_collocation:
        for kdx in range(nk):
            # add outputs on collocation nodes
            for ddx in range(d):
                # compute outputs for this time interval
                Outputs_list.append(coll_outputs[:, kdx * d + ddx])

    Outputs_list.append(form_outputs_fun(V, P))

    # Create Outputs struct and function
    Outputs = Outputs_struct(cas.vertcat(*Outputs_list))
    Outputs_fun = cas.Function('Outputs_fun', [V, P], [Outputs.cat])

    # Create Integral outputs struct and function
    Integral_outputs_struct = setup_integral_output_structure(
        nlp_options, model.integral_outputs)
    Integral_outputs = Integral_outputs_struct(
        cas.vertcat(*Integral_outputs_list))
    Integral_outputs_fun = cas.Function('Integral_outputs_fun', [V, P],
                                        [Integral_outputs.cat])

    Xdot_struct = struct_op.construct_Xdot_struct(nlp_options,
                                                  model.variables_dict)
    Xdot_fun = cas.Function('Xdot_fun', [V], [Xdot])

    # -------------------------------------------
    # GET CONSTRAINTS
    # -------------------------------------------
    ocp_cstr_list = constraints.get_constraints(nlp_options, V, P, Xdot, model,
                                                dae, formulation,
                                                Integral_constraint_list,
                                                Collocation, Multiple_shooting,
                                                ms_z0, ms_xf, ms_vars,
                                                ms_params, Outputs)

    return V, P, Xdot_struct, Xdot_fun, ocp_cstr_list, Outputs_struct, Outputs_fun, Integral_outputs_struct, Integral_outputs_fun, time_grids, Collocation, Multiple_shooting
示例#5
0
def get_strength_constraint(options, V, Outputs, model):

    n_k = options['n_k']
    d = options['collocation']['d']

    comparison_labels = options['induction']['comparison_labels']
    wake_nodes = options['induction']['vortex_wake_nodes']
    rings = wake_nodes - 1
    kite_nodes = model.architecture.kite_nodes

    strength_scale = tools.get_strength_scale(options)

    Xdot = struct_op.construct_Xdot_struct(options, model.variables_dict)(0.)

    cstr_list = cstr_op.ConstraintList()

    any_vor = any(label[:3] == 'vor' for label in comparison_labels)
    if any_vor:

        for kite in kite_nodes:
            for ring in range(rings):
                wake_node = ring

                for ndx in range(n_k):
                    for ddx in range(d):

                        local_name = 'vortex_strength_' + str(kite) + '_' + str(ring) + '_' + str(ndx) + '_' + str(ddx)

                        variables = struct_op.get_variables_at_time(options, V, Xdot, model.variables, ndx, ddx)
                        wg_local = tools.get_ring_strength(variables, kite, ring)

                        ndx_shed = n_k - 1 - wake_node
                        ddx_shed = d - 1

                        # working out:
                        # n_k = 3
                        # if ndx = 0 and ddx = 0 -> shed: wn >= n_k
                        #     wn: 0 sheds at ndx = 2, ddx = -1 : unshed,    period = 0
                        #     wn: 1 sheds at ndx = 1, ddx = -1 : unshed,    period = 0
                        #     wn: 2 sheds at ndx = 0, ddx = -1 : unshed,    period = 0
                        #     wn: 3 sheds at ndx = -1, ddx = -1 : SHED      period = 1
                        #     wn: 4 sheds at ndx = -2,                      period = 1
                        #     wn: 5 sheds at ndx = -3                       period = 1
                        #     wn: 6 sheds at ndx = -4                       period = 2
                        # if ndx = 1 and ddx = 0 -> shed: wn >= n_k - ndx
                        #     wn: 0 sheds at ndx = 2, ddx = -1 : unshed,
                        #     wn: 1 sheds at ndx = 1, ddx = -1 : unshed,
                        #     wn: 2 sheds at ndx = 0, ddx = -1 : SHED,
                        #     wn: 3 sheds at ndx = -1, ddx = -1 : SHED
                        # if ndx = 0 and ddx = -1 -> shed:
                        #     wn: 0 sheds at ndx = 2, ddx = -1 : unshed,
                        #     wn: 1 sheds at ndx = 1, ddx = -1 : unshed,
                        #     wn: 2 sheds at ndx = 0, ddx = -1 : SHED,
                        #     wn: 3 sheds at ndx = -1, ddx = -1 : SHED

                        already_shed = False
                        if (ndx > ndx_shed):
                            already_shed = True
                        elif ((ndx == ndx_shed) and (ddx == ddx_shed)):
                            already_shed = True

                        if already_shed:

                            # working out:
                            # n_k = 3
                            # period_0 -> wn 0, wn 1, wn 2 -> floor(ndx_shed / n_k)
                            # period_1 -> wn 3, wn 4, wn 5

                            period_number = int(np.floor(float(ndx_shed)/float(n_k)))
                            ndx_shed_w_periodicity = ndx_shed - period_number * n_k

                            gamma_val = Outputs['coll_outputs', ndx_shed_w_periodicity, ddx_shed, 'aerodynamics', 'circulation' + str(kite)]
                            wg_ref = 1. * gamma_val / strength_scale
                        else:
                            wg_ref = 0.

                        local_resi = (wg_local - wg_ref)

                        local_cstr = cstr_op.Constraint(expr = local_resi,
                                                        name = local_name,
                                                        cstr_type='eq')
                        cstr_list.append(local_cstr)

    return cstr_list
示例#6
0
def get_fixing_constraint(options, V, Outputs, model):

    n_k = options['n_k']

    comparison_labels = options['induction']['comparison_labels']
    wake_nodes = options['induction']['vortex_wake_nodes']
    kite_nodes = model.architecture.kite_nodes
    wingtips = ['ext', 'int']

    Xdot = struct_op.construct_Xdot_struct(options, model.variables_dict)(0.)

    cstr_list = cstr_op.ConstraintList()

    any_vor = any(label[:3] == 'vor' for label in comparison_labels)
    if any_vor:

        for kite in kite_nodes:
            for tip in wingtips:
                for wake_node in range(wake_nodes):
                    local_name = 'wake_fixing_' + str(kite) + '_' + str(tip) + '_' + str(wake_node)

                    if wake_node < n_k:

                        # working out:
                        # n_k = 3
                        # wn:0, n_k-1=2
                        # wn:1, n_k-2=1
                        # wn:2=n_k-1, n_k-3=0
                        # ... switch to periodic fixing

                        reverse_index = n_k - 1 - wake_node
                        variables_at_shed = struct_op.get_variables_at_time(options, V, Xdot, model.variables,
                                                                            reverse_index, -1)

                        wx_local = tools.get_wake_node_position_si(options, variables_at_shed, kite, tip, wake_node)
                        wingtip_pos = Outputs[
                            'coll_outputs', reverse_index, -1, 'aerodynamics', 'wingtip_' + tip + str(kite)]

                        local_resi = wx_local - wingtip_pos

                        local_cstr = cstr_op.Constraint(expr = local_resi,
                                                        name = local_name,
                                                        cstr_type='eq')
                        cstr_list.append(local_cstr)

                    else:

                        # working out:
                        # n_k = 3
                        # wn:0, n_k-1=2
                        # wn:1, n_k-2=1
                        # wn:2=n_k-1, n_k-3=0
                        # ... switch to periodic fixing
                        # wn:3 at ndx = 0 must be equal to -> wn:0 at ndx = -1, ddx = -1
                        # wn:4 at ndx = 0 must be equal to -> wn:1 at ndx = -1, ddx = -1

                        variables_at_initial = struct_op.get_variables_at_time(options, V, Xdot, model.variables, 0)
                        variables_at_final = struct_op.get_variables_at_time(options, V, Xdot, model.variables, -1, -1)

                        upstream_node = wake_node - n_k
                        wx_local = tools.get_wake_node_position_si(options, variables_at_initial, kite, tip, wake_node)
                        wx_upstream = tools.get_wake_node_position_si(options, variables_at_final, kite, tip, upstream_node)

                        local_resi = wx_local - wx_upstream
                        local_cstr = cstr_op.Constraint(expr = local_resi,
                                                        name = local_name,
                                                        cstr_type='eq')
                        cstr_list.append(local_cstr)

    return cstr_list
示例#7
0
    def discretize_constraints(self, options, model, formulation, V, P):
        """Discretize dynamics and path constraints in a (possibly) parallelizable fashion

        @param options nlp options
        @param model awebox model
        @param formulation awebox formulation
        @param V decision variables
        @param P nlp parameters
        """

        # rearrange nlp variables
        self.__ms_nlp_vars(options, model, V, P)

        # implicit values ofalgebraic variables at interval nodes
        ms_z0 = self.__ms_z0

        # evaluate dynamics and constraint functions on all intervals
        if options['parallelization']['include']:

            # use function map for parallellization
            parallellization = options['parallelization']['type']
            F_map = self.__F.map('F_map', parallellization, self.__n_k, [], [])
            path_constraints_fun = model.constraints_fun.map(
                'constraints_map', parallellization, self.__n_k, [], [])
            outputs_fun = model.outputs_fun.map('outputs_fun',
                                                parallellization, self.__n_k,
                                                [], [])

            # integrate
            ms_dynamics = F_map(x0=self.__ms_x, z0=self.__ms_z, p=self.__ms_p)
            ms_xf = ms_dynamics['xf']
            ms_qf = cas.horzcat(np.zeros(self.__dae.dae['quad'].size()),
                                ms_dynamics['qf'])
            ms_constraints = path_constraints_fun(self.__ms_vars,
                                                  self.__ms_params)
            ms_outputs = outputs_fun(self.__ms_vars, self.__ms_params)

            # integrate quadrature outputs
            for i in range(self.__n_k):
                ms_qf[:, i + 1] = ms_qf[:, i + 1] + ms_qf[:, i]

            # extract formulation information
            # constraints_fun_ineq = formulation.constraints_fun['integral']['inequality'].map('integral_constraints_map_ineq', 'serial', N_coll, [], [])
            # constraints_fun_eq = formulation.constraints_fun['integral']['equality'].map('integral_constraints_map_eq', 'serial', N_coll, [], [])

            # integral_constraints = OrderedDict()
            # integral_constraints['inequality'] = constraints_fun_ineq(coll_vars, coll_params)
            # integral_constraints['equality'] = constraints_fun_eq(coll_vars, coll_params)

        else:

            # initialize function evaluations
            ms_xf = []
            ms_qf = np.zeros(self.__dae.dae['quad'].size())
            ms_constraints = []
            ms_outputs = []
            # integral_constraints = OrderedDict()
            # integral_constraints['inequality'] = []
            # integral_constraints['equality'] = []

            # evaluate functions in for loop
            for i in range(self.__n_k):
                ms_dynamics = self.__F(x0=self.__ms_x[:, i],
                                       z0=self.__ms_z[:, i],
                                       p=self.__ms_p[:, i])
                ms_xf = cas.horzcat(ms_xf, ms_dynamics['xf'])
                ms_qf = cas.horzcat(ms_qf, ms_qf[:, -1] + ms_dynamics['qf'])
                ms_constraints = cas.horzcat(
                    ms_constraints,
                    model.constraints_fun(self.__ms_vars[:, i],
                                          self.__ms_params[:, i]))
                ms_outputs = cas.horzcat(
                    ms_outputs,
                    model.outputs_fun(self.__ms_vars[:, i],
                                      self.__ms_params[:, i]))
                # integral_constraints['inequality'] = cas.horzcat(integral_constraints['inequality'], formulation.constraints_fun['integral']['inequality'](coll_vars[:,i],coll_params[:,i]))
                # integral_constraints['equality'] = cas.horzcat(integral_constraints['equality'], formulation.constraints_fun['integral']['equality'](coll_vars[:,i],coll_params[:,i]))

        # integral outputs and constraints
        Integral_outputs_list = self.__build_integral_outputs(
            ms_qf, model.integral_outputs)
        # Integral_constraints_list = []
        # for kdx in range(self.__n_k):
        #     tf = struct_op.calculate_tf(options, V, kdx)
        #     Integral_constraints_list += [self.__integrate_integral_constraints(integral_constraints, kdx, tf)]
        Integral_constraints_list = None

        # construct state derivative struct
        Xdot = struct_op.construct_Xdot_struct(options, model)
        Xdot = self.__fill_in_Xdot(Xdot)

        return ms_xf, ms_z0, Xdot, ms_constraints, ms_outputs, Integral_outputs_list, Integral_constraints_list