def simulate(ti_controls, sampling_times, model_parameters): m = create_model(sampling_times) m.tau.fix(max(sampling_times)) # m.f_in.fix(ti_controls[0]) m.f_in.fix(0) m.T.fix(ti_controls[0]) m.theta0[1].fix(model_parameters[0]) m.theta1[1].fix(model_parameters[1]) m.theta0[2].fix(model_parameters[2]) m.theta1[2].fix(model_parameters[3]) m.c[0, "A"].fix(1) m.c[0, "B"].fix(0) m.c[0, "C"].fix(0) simulator = pod.Simulator(m, package="casadi") t, profile = simulator.simulate(integrator="idas") simulator.initialize_model() c = np.array([[m.c[t, i].value for t in m.t] for i in m.i]).T if False: plt.plot(t, profile) return c
def simulate_tvc(ti_controls, tv_controls, sampling_times, model_parameters): tau = np.max(sampling_times) normalized_sampling_times = sampling_times / tau model = create_model_tvc(normalized_sampling_times) """ fixing the control variables """ # time-invariant model.theta_0.fix(model_parameters[0]) model.theta_1.fix(model_parameters[1]) model.alpha_a.fix(model_parameters[2]) model.alpha_b.fix(0) model.nu.fix(model_parameters[3]) model.tau.fix(max(sampling_times)) model.ca[0].fix(ti_controls[0]) model.cb[0].fix(0) """ time-varying controls """ model.tvc[model.temp] = tv_controls[0] """ simulating """ simulator = pod.Simulator(model, package="casadi") simulator.simulate(integrator='idas', varying_inputs=model.tvc) simulator.initialize_model() discretizer = po.TransformationFactory("dae.collocation") discretizer.apply_to(model, nfe=10, ncp=3, scheme="LAGRANGE-RADAU") """" extracting results and returning it in appropriate format """ ca = np.array([model.ca[t].value for t in normalized_sampling_times]) cb = np.array([model.cb[t].value for t in normalized_sampling_times]) return np.array([ca, cb]).T
def pyomo_simulate(ti_controls, sampling_times, model_parameters): """ The simulation function to be passed on to the pydex.designer. The function takes in the pyomo model and simulator, nominal model parameter values, and experimental candidates. Returns the predictions at specified sampling times. Parameters: model : a Pyomo model instance simulator : a Pyomo simulator instance ti_controls : time-invariant controls of candidate (1D np.array) sampling_times : sampling time choices of candidate (1D np.array) model_parameters : nominal model parameter values (1D np.array) Return: responses : a 2D np.array with shapes N_spt by n_r, corresponding to the model's prediction on value of the n_r number of responses at all N_spt number of sampling times. """ """ fixing the control variables """ model = create_pyomo_model(sampling_times) # time-invariant model.beta.fix(model_parameters[0]) model.tau.fix(max(sampling_times)) model.ca[0].fix(ti_controls[0]) # no time-varying control for this example """ simulating """ simulator = pod.Simulator(model, "casadi") simulator.simulate(numpoints=100, integrator='idas') simulator.initialize_model() """" extracting results and returning it in appropriate format """ normalized_sampling_times = sampling_times / model.tau.value ca = np.array([model.ca[t].value for t in normalized_sampling_times]) return ca
def create_pyomo_model(): """ Creates a pyomo model. Return: model : the ConcreteModel instance. simulator : Pyomo.DAE's simulator object attached to the model. """ model = po.ConcreteModel() model.t = pod.ContinuousSet(bounds=(0, 1)) model.tau = po.Var() model.ca = po.Var(model.t, bounds=(0, 50)) # set of concentrations in reaction mixture model.dca_dt = pod.DerivativeVar(model.ca, wrt=model.t) model.beta = po.Var() # model parameters def _material_balance(m, t): return m.dca_dt[t] / m.tau == -m.beta * m.ca[t] model.material_balance = po.Constraint(model.t, rule=_material_balance) simulator = pod.Simulator(model, "casadi") return model, simulator
def simulate(ti_controls, sampling_times, model_parameters): norm_spt = sampling_times / np.max(sampling_times) model = create_model(norm_spt) """ fixing the control variables """ # time-invariant model.theta_0.fix(model_parameters[0]) model.theta_1.fix(model_parameters[1]) model.alpha_a.fix(model_parameters[2]) model.alpha_b.fix(0) model.nu.fix(model_parameters[3]) model.tau.fix(max(sampling_times)) model.ca[0].fix(ti_controls[0]) model.cb[0].fix(0) model.temp.fix(ti_controls[1]) # no time-varying control for this example """ simulating """ simulator = pod.Simulator(model, package="casadi") simulator.simulate(integrator='idas') simulator.initialize_model() """" extracting results and returning it in appropriate format """ ca = np.array([model.ca[t].value for t in norm_spt]) cb = np.array([model.cb[t].value for t in norm_spt]) return np.array([ca, cb]).T
def simulate(ti_controls, sampling_times, model_parameters): m = create_model(sampling_times) """ Fixing Control Variables """ # initial conditions m.s[0].fix(ti_controls[0]) m.i[0].fix(ti_controls[1]) m.r[0].fix(ti_controls[2]) # model parameters m.beta.fix(model_parameters[0]) m.gamma.fix(model_parameters[1]) simulator = pod.Simulator(m, package="casadi") t, profile = simulator.simulate(integrator="idas") simulator.initialize_model() t = [po.value(tt) for tt in m.t] s = [st.value for st in m.s.values()] i = [it.value for it in m.i.values()] r = [rt.value for rt in m.r.values()] y = np.asarray([s, i, r,]).T return y
def simulate_model(modelparameters): """simulating""" model = create_mdoel(modelparameters=modelparameters) simulator = pod.Simulator(model, package='casadi') results = simulator.simulate(integrator='idas') discretizer = po.TransformationFactory("dae.collocation") discretizer.apply_to(model, nfe=10, ncp=3, scheme="LAGRANGE-RADAU") simulator.initialize_model() rate = [model.reaction_rate[z].value for z in model.z] return results, rate
def simulate(ti_controls, sampling_times, model_parameters): model = create_model(sampling_times) # # initial conditions # model.y1[0].fix(1.6497) # model.y2[0].fix(8.2262) # model.y3[0].fix(0) # model.y4[0].fix(0) # initial conditions model.y1[0].fix(ti_controls[0]) model.y2[0].fix(ti_controls[1]) model.y3[0].fix(0) model.y4[0].fix(0) # # controls # model.x1.fix(ti_controls[0]) # model.x2.fix(ti_controls[1]) # model.x3.fix(ti_controls[2]) # model.x4.fix(ti_controls[3]) # constants model.x1.fix(340.15) model.x2.fix(0.0131) model.x3.fix(1.6497) model.x4.fix(8.2262) # model parameters model.k1.fix(model_parameters[0]) model.k2.fix(model_parameters[1]) model.k1r.fix(model_parameters[2]) model.beta1.fix(model_parameters[3]) model.beta2.fix(model_parameters[4]) # batch time model.tau.fix(300) simulator = pod.Simulator(model, package="casadi") simulator.simulate() simulator.initialize_model() # t = po.value(model.tau) * np.array([t for t in model.t]) y1 = np.array([po.value(model.y1[t]) for t in model.t]) y2 = np.array([po.value(model.y2[t]) for t in model.t]) y3 = np.array([po.value(model.y3[t]) for t in model.t]) y4 = np.array([po.value(model.y4[t]) for t in model.t]) return np.array([y1, y2, y3, y4]).T
def create_model(spt): model = po.ConcreteModel() model.t = pod.ContinuousSet(bounds=(0, 1), initialize=spt) model.tau = po.Var(bounds=(0, None)) model.cA = po.Var(model.t, bounds=(0, None)) model.cB = po.Var(model.t, bounds=(0, None)) model.dcAdt = pod.DerivativeVar(model.cA, wrt=model.t) model.dcBdt = pod.DerivativeVar(model.cB, wrt=model.t) model.nu = po.Var(bounds=(0, None)) model.alpha = po.Var(bounds=(0, None)) model.beta = po.Var(bounds=(0, None)) model.T = po.Var(bounds=(0, None)) model.theta_10 = po.Var() model.theta_11 = po.Var() model.theta_20 = po.Var() model.theta_21 = po.Var() model.theta_30 = po.Var() model.theta_31 = po.Var() def _A_mol_bal(m, t): k1 = po.exp(m.theta_10 + m.theta_11 * (m.T - 273.15) / m.T) k2 = po.exp(m.theta_20 + m.theta_21 * (m.T - 273.15) / m.T) k3 = po.exp(m.theta_30 + m.theta_31 * (m.T - 273.15) / m.T) r = k1 * m.cA[t]**m.alpha / (k2 + k3 * m.cA[t]**m.beta) return m.dcAdt[t] == m.tau * -r model.A_mol_bal = po.Constraint(model.t, rule=_A_mol_bal) def _B_mol_bal(m, t): k1 = po.exp(m.theta_10 + m.theta_11 * (m.T - 273.15) / m.T) k2 = po.exp(m.theta_20 + m.theta_21 * (m.T - 273.15) / m.T) k3 = po.exp(m.theta_30 + m.theta_31 * (m.T - 273.15) / m.T) r = k1 * m.cA[t]**m.alpha / (k2 + k3 * m.cA[t]**m.beta) return m.dcBdt[t] == m.tau * m.nu * r model.B_mol_bal = po.Constraint(model.t, rule=_B_mol_bal) simulator = pod.Simulator(model, package="casadi") return model, simulator
def simulate_dw(ti_controls, tv_controls, sampling_times, model_parameters): m = create_model_dw(sampling_times) m.p[0].fix(22) # 22 MPa - figure from first result of googling "pressure in ghawar field" m.T.fix(300) # 360 Kelvin - taken from (Bruno Stenger; Tony Pham; Nabeel Al-Afaleg; Paul Lawrence GeoArabia (2003) 8 (1): 9–42.) m.tau.fix(max(sampling_times)) # hours m.v.fix(model_parameters[0]) m.mu.fix(model_parameters[1]) m.rho.fix(model_parameters[2]) m.p_vac.fix(ti_controls[0]) m.L.fix(ti_controls[1]) m.R.fix(ti_controls[2]) # m.tvc = po.Suffix(direction=po.Suffix.LOCAL) simulator = pod.Simulator(m, package="casadi") t, profile = simulator.simulate( numpoints=101, integrator="idas", # varying_inputs=m.tvc, ) discretizer = po.TransformationFactory("dae.collocation") discretizer.apply_to(m, nfe=20, ncp=3) simulator.initialize_model() t = [po.value(t) * max(sampling_times) / 24 for t in m.t] p = [po.value(m.p[t]) for t in m.t] if True: fig = plt.figure() axes = fig.add_subplot(111) axes.plot(t, p) axes.set_xlabel("Time (Days)") axes.set_ylabel("Reservoir Pressure (MPa)") fig.tight_layout() return
def create_model(spt): """ defining the model """ norm_spt = spt / max(spt) model = po.ConcreteModel() model.t = pod.ContinuousSet(bounds=(0, 1), initialize=norm_spt) model.tau = po.Var() model.temp = po.Var() model.ca = po.Var(model.t, bounds=(0, 50)) model.cb = po.Var(model.t, bounds=(0, 50)) model.dca_dt = pod.DerivativeVar(model.ca, wrt=model.t) model.dcb_dt = pod.DerivativeVar(model.cb, wrt=model.t) model.theta_0 = po.Var() # model parameters model.theta_1 = po.Var() model.alpha_a = po.Var() model.alpha_b = po.Var() model.nu = po.Var() def _material_balance_a(m, t): k = po.exp(m.theta_0 + m.theta_1 * (m.temp - 273.15) / m.temp) return m.dca_dt[t] / m.tau == -k * (m.ca[t]**model.alpha_a) * ( model.cb[t]**model.alpha_b) model.material_balance_a = po.Constraint(model.t, rule=_material_balance_a) def _material_balance_b(m, t): k = po.exp(m.theta_0 + m.theta_1 * (m.temp - 273.15) / m.temp) return m.dcb_dt[t] / m.tau == m.nu * k * (m.ca[t]**model.alpha_a) * ( model.cb[t]**model.alpha_b) model.material_balance_b = po.Constraint(model.t, rule=_material_balance_b) simulator = pod.Simulator(model, package='casadi') return model, simulator
def simulate_tvc(ti_controls, tv_controls, sampling_times, model_parameters): tau = np.max(sampling_times) normalized_sampling_times = sampling_times / tau model = create_model_tvc(normalized_sampling_times) """ fixing the control variables """ # time-invariant model.theta_0.fix(model_parameters[0]) model.theta_1.fix(model_parameters[1]) model.alpha_a.fix(model_parameters[2]) model.alpha_b.fix(0) model.nu.fix(model_parameters[3]) model.tau.fix(max(sampling_times)) model.ca[0].fix(ti_controls[0]) model.cb[0].fix(0) """ time-varying controls """ model.tvc[model.temp] = tv_controls[0] """ ensuring pyomo returns state values at given sampling times """ # model.t.initialize = np.array(sampling_times) / model.tau.value # model.t.order_dict = {} # to suppress pyomo warnings for duplicate elements # model.t._constructed = False # needed so we can re-initialize the continuous set # model.t._data = {} # model.t._fe = [] # model.t.value_list = [] # model.t.value = [] # model.t.construct() # line that re-initializes the continuous set """ simulating """ simulator = pod.Simulator(model, package="casadi") simulator.simulate(integrator='idas', varying_inputs=model.tvc) simulator.initialize_model() discretizer = po.TransformationFactory("dae.collocation") discretizer.apply_to(model, nfe=10, ncp=3, scheme="LAGRANGE-RADAU") """" extracting results and returning it in appropriate format """ ca = np.array([model.ca[t].value for t in normalized_sampling_times]) cb = np.array([model.cb[t].value for t in normalized_sampling_times]) return np.array([ca, cb]).T
def simulate_hgp(ti_controls, tv_controls, sampling_times, model_parameters): m = create_model_hgp(sampling_times) m.p[0].fix(22) # 22 MPa - figure from first result of googling "pressure in ghawar field" m.T.fix(300) # 360 Kelvin - taken from (Bruno Stenger; Tony Pham; Nabeel Al-Afaleg; Paul Lawrence GeoArabia (2003) 8 (1): 9–42.) m.tau.fix(max(sampling_times)) # hours m.v.fix(model_parameters[0]) m.mu.fix(1000) m.L.fix(ti_controls[0]) m.R.fix(ti_controls[1]) m.tvc = po.Suffix(direction=po.Suffix.LOCAL) m.tvc[m.p_vac] = tv_controls[0] simulator = pod.Simulator(m, package="casadi") t, profile = simulator.simulate( numpoints=101, integrator="idas", varying_inputs=m.tvc, ) discretizer = po.TransformationFactory("dae.collocation") discretizer.apply_to(m, nfe=51, ncp=3) discretizer.reduce_collocation_points(m, var=m.p_vac, ncp=1, contset=m.t) simulator.initialize_model() t = [po.value(t) * max(sampling_times) for t in m.t] p = [po.value(m.p[t]) for t in m.t] a = [po.value(m.a[t]) for t in m.t] q = [po.value(m.q[t]) for t in m.t] if True: tau = max(sampling_times) swt = list(tv_controls[0].keys()) fig = plt.figure() axes = fig.add_subplot(111) axes.plot(t, p, label="Pressure in Reservoir (MPa)") axes.plot( [swt[0] * tau, swt[1] * tau, swt[1] * tau, swt[2] * tau, swt[2] * tau, swt[3] * tau, swt[3] * tau, tau], [tv_controls[0][0], tv_controls[0][0.0], tv_controls[0][0.25], tv_controls[0][0.25], tv_controls[0][0.50], tv_controls[0][0.50], tv_controls[0][0.75], tv_controls[0][0.75]], label="Outlet Pressure (MPa)" ) axes.set_xlabel("Time (Days)") axes.set_ylabel("Reservoir Pressure (MPa)") axes.legend() fig.tight_layout() fig2 = plt.figure() axes2 = fig2.add_subplot(111) axes2.plot(t, np.asarray(a) * 1e9, label="Accumulated Production") axes2.set_xlabel("Time (Days)") axes2.set_ylabel(r"Accumulated Production ($10^{9}$ Moles)") fig2.tight_layout() fig3 = plt.figure() axes3 = fig3.add_subplot(111) axes3.plot(t, np.asarray(q) * 1e9, label="Gas Flowrate") axes3.set_xlabel("Time (Days)") axes3.set_ylabel("Gas Flow Rate ($10^9$ Moles per Day)") fig3.tight_layout() print(f"Productivity: {po.value(m.a[1]) * 1e9 / max(sampling_times)} Billion moles per day") norm_spt = sampling_times / max(sampling_times) p = [po.value(m.p[t]) for t in norm_spt] p = np.asarray(p)[:, None] return p
model.k1r.fix(1.7291e8) model.beta1.fix(6.27e-8) model.beta2.fix(4.8626e-8) # estimated model parameters after step 8 and 11 if True: model.k1.fix(1.8934) model.k2.fix(2.7585) model.k1r.fix(1.7540e3) model.beta1.fix(6.1894e-3) model.beta2.fix(0.0048) # batch time model.tau.fix(300) simulator = pod.Simulator(model, package="casadi") tsim, profiles = simulator.simulate_pyomo(integrator="idas", numpoints=1000) simulator.initialize_model() t = po.value(model.tau) * np.array([t for t in model.t]) y1 = np.array([po.value(model.y1[t]) for t in model.t]) y2 = np.array([po.value(model.y2[t]) for t in model.t]) y3 = np.array([po.value(model.y3[t]) for t in model.t]) y4 = np.array([po.value(model.y4[t]) for t in model.t]) fig = plt.figure() axes1 = fig.add_subplot(121) axes1.plot(t, y1, label="$y_1$") axes1.plot(t, y4, label="$y_4$") axes1.plot(t, y3, label="$y_3$")
k = po.exp(m.theta_0 + m.theta_1 * (m.temp - 273.15) / m.temp) return m.dcb_dt[t] / m.tau == m.nu * k * (m.ca[t]**model.alpha_a) * ( model.cb[t]**model.alpha_b) model.material_balance_b = po.Constraint(model.t, rule=_material_balance_b) return model pre_exp_constant = 0.1 activ_energy = 5000 theta_0 = np.log(pre_exp_constant) - activ_energy / (8.314159 * 273.15) theta_1 = activ_energy / (8.314159 * 273.15) """ create a pyomo model """ model_1 = create_model() simulator_1 = pod.Simulator(model_1, package='casadi') """ create a designer """ designer_1 = Designer() """ pass pyomo model and simulator to designer """ designer_1.model = model_1 designer_1.simulator = simulator_1 """ overwrite the designer's simulate function """ designer_1.simulate = simulate """ specifying nominal model parameter """ theta_nom = np.array([theta_0, theta_1, 1, 0.5]) # value of theta_0, theta_1, alpha_a, nu designer_1.model_parameters = theta_nom # assigning it to the designer's theta """ creating experimental candidates, here, it is generated as a grid """ n_s_times = 200 # number of equally-spaced sampling time candidates n_c = 20**2 # grid resolution of control candidates generated
def create_simulator(model, package): return pod.Simulator(model, package=package)
return m.scipy_model[t] / m.tau == - k * (m.ca[t] ** model.alpha_a) * ( model.cb[t] ** model.alpha_b) model.material_balance_a = po.Constraint(model.t, rule=_material_balance_a) def _material_balance_b(m, t): k = po.exp(m.theta_0 + m.theta_1 * (m.temp - 273.15) / m.temp) return m.dcb_dt[t] / m.tau == m.nu * k * (m.ca[t] ** model.alpha_a) * ( model.cb[t] ** model.alpha_b) model.material_balance_b = po.Constraint(model.t, rule=_material_balance_b) return model model1 = create_model() simulator1 = pod.Simulator(model1, package="casadi") designer1 = Designer() designer1.model = model1 designer1.simulator = simulator1 designer1.simulate = simulate def info_matrix(tic, spt, mp): designer1.ti_controls_candidates = np.array([tic]) designer1.sampling_times_candidates = np.array([spt]) designer1.model_parameters = mp designer1.initialize() designer1._trim_fim = False efforts = np.array([[1] * spt.size]) return designer1.eval_fim(efforts, mp) def simul_d_opt(x):