<jupyter_start><jupyter_text>Cooling Tank ModelThis notebook describes the optimization of the tank model described in `tank_model.py`. This model was developed in the fmdtools package, and requires its installation to simulate.<jupyter_code>import sys
sys.path.append('../')
import numpy as np
import scipy as sp
import time
import itertools
import random
from scipy.optimize import minimize
import pandas as pd

import fmdtools.faultsim.propagate as propagate
import fmdtools.resultdisp as rd
from tank_model import Tank
from fmdtools.modeldef import SampleApproach

import matplotlib.pyplot as plt<jupyter_output><empty_output><jupyter_text>Simulation Verifying the nominal state:In the nominal state, no change in system state should occurs.<jupyter_code>mdl = Tank()
endresults, resgraph, mdlhist = propagate.nominal(mdl)
mdlhist.keys()
rd.graph.show(resgraph)
rd.plot.mdlhistvals(mdlhist)<jupyter_output><empty_output><jupyter_text>What happens under component faults?Here we model a leak of the tank. As shown, the coolant leaks until there is no more coolant left in the tank. While this results in a warning signal, the default contingency management policy is to take no actions to alleviate the condition.<jupyter_code>endresults, resgraph, mdlhist = propagate.one_fault(mdl,'Store_Coolant','Leak', time=3)

fig = rd.plot.mdlhistvals(mdlhist, fault='Leak', time=3, fxnflowvals={'Store_Coolant':['level', 'net_flow'], 'Tank_Sig':['indicator'], 'Valve1_Sig':['action']}, returnfig = True, legend=False) #,
#fig.axes[3].remove()
fig.set_figheight(8)
fig.set_figwidth(8)
fig.subplots_adjust(top = 0.9, wspace=0.1, hspace=0.3)
#add graph view to figure
graph_fig, graph_ax = rd.graph.show(resgraph,faultscen='Leak', time=3, retfig=True)
graph_ax.figure = fig
fig.axes.append(graph_ax)
fig.add_axes(graph_ax)
graph_ax.set_position([0.7,0.16,0.55,0.6])
graph_ax.margins(0.3)
fig
fig.savefig('tank_behavior.pdf', format="pdf", bbox_inches = 'tight', pad_inches = 0.0)<jupyter_output><empty_output><jupyter_text>Full set of modesThe tank leak mode will not be the only mode considered, but also leak and blockage faults in the Imput/Output blocks.<jupyter_code>app_joint_faults = SampleApproach(mdl)
endclasses, mdlhists = propagate.approach(mdl, app_joint_faults)
fmea_tab = rd.tabulate.simplefmea(endclasses)
fmea_tab
print(fmea_tab.to_latex(float_format="%.2g"))<jupyter_output>\begin{tabular}{lrrr}
\toprule
{} &    rate &    cost &  expected cost \\
\midrule
Import\_Coolant Leak, t=0     & 1.7e-06 & 2.1e+06 &        3.5e+05 \\
Import\_Coolant Blockage, t=0 & 1.7e-06 & 2.1e+06 &        3.5e+05 \\
Store\_Coolant Leak, t=0      & 1.7e-06 &   1e+06 &        1.7e+05 \\
Export\_Coolant Leak, t=0     & 1.7e-06 &   1e+06 &        1.7e+05 \\
Export\_Coolant Blockage, t=0 & 1.7e-06 &   1e+05 &        1.7e+04 \\
\bottomrule
\end{tabular}<jupyter_text>OptimizationHere we compare the optimization of the response of this system using bilevel and alternating architectures<jupyter_code>from tank_opt import *<jupyter_output><empty_output><jupyter_text>alternating optimization structure<jupyter_code>result_alt, llargs_alt, fhist_alt, thist_alt = alternating_opt()
result_bi, llargs_bi = bilevel_opt()
fig = plt.figure()
plt.plot(thist_alt, fhist_alt, label="Alternating")
plt.plot(llargs_bi['thist'],llargs_bi['fhist'], label="Bilevel")
plt.legend()
plt.title("Optimization of Tank Problem")
plt.grid()
plt.ylabel("$C_D+C_R$")
#plt.yscale("log")
plt.xlabel("Computational Time (s)")
fig.savefig('tank_optimization.pdf', format="pdf", bbox_inches = 'tight', pad_inches = 0.0)
x_to_totcost3(result_bi['x'],llargs_bi['ll_optx'][0],llargs_bi['ll_optx'][1])
x_to_totcost3(result_alt['x'],llargs_alt['ll_optx'][0],llargs_alt['ll_optx'][1])
result_bi['x']
result_alt['x']
llargs_bi['fhist'][-1]
tab = pd.DataFrame(columns = ["$x_t$", "$x_l$", "$f^*$", "time"])
tab.loc['Bilevel'] = list(result_bi['x']) +  [result_bi['fun'], llargs_bi['thist'][-1]]
tab.loc['Alternating'] = list(result_alt['x']) + [result_alt['fun'], thist_alt[-1]]
tab
print(tab.to_latex(float_format="%.2g" ))
llargs_bi['ll_optx'] - llargs_alt['ll_optx'] 
opt_policy_bi = {"iv":[a-1 for a,b,c in np.ndindex((3,3,3))], "tank":[b-1 for a,b,c in np.ndindex((3,3,3))],"ov":[c-1 for a,b,c in np.ndindex((3,3,3))], "iv_act":[int(i) for i in llargs_bi['ll_optx'][0]], "ov_act":[int(i) for i in llargs_bi['ll_optx'][1]]}
opt_policy_alt = {"iv":[a-1 for a,b,c in np.ndindex((3,3,3))], "tank":[b-1 for a,b,c in np.ndindex((3,3,3))],"ov":[c-1 for a,b,c in np.ndindex((3,3,3))], "iv_act":[int(i) for i in llargs_alt['ll_optx'][0]], "ov_act":[int(i) for i in llargs_alt['ll_optx'][1]]}
opttab = pd.DataFrame(opt_policy_bi)
opttab
print(opttab.to_latex(index=False))<jupyter_output>\begin{tabular}{rrrrr}
\toprule
 iv &  tank &  ov &  iv\_act &  ov\_act \\
\midrule
 -1 &    -1 &  -1 &      -1 &       0 \\
 -1 &    -1 &   0 &      -1 &      -1 \\
 -1 &    -1 &   1 &       0 &       0 \\
 -1 &     0 &  -1 &       1 &       1 \\
 -1 &     0 &   0 &       1 &       0 \\
 -1 &     0 &   1 &       0 &       1 \\
 -1 &     1 &  -1 &      -1 &      -1 \\
 -1 &     1 &   0 &       0 &       1 \\
 -1 &     1 &   1 &      -1 &      -1 \\
  0 &    -1 &  -1 &       0 &       0 \\
  0 &    -1 &   0 &       1 &      -1 \\
  0 &    -1 &   1 &       1 &       0 \\
  0 &     0 &  -1 &      -1 &       0 \\
  0 &     0 &   0 &       0 &       0 \\
  0 &     0 &   1 &       0 &       0 \\
  0 &     1 &  -1 &       0 &      -1 \\
  0 &     1 &   0 &       0 &      -1 \\
  0 &     1 &   1 &      -1 &      -1 \\
  1 &    -1 &  -1 &       0 &      -1 \\
  1 &    -1 &   0 &      -1 &       0 \\
  1 &    -1 &   1 &      -1 &       1 \\
  1 &     0 &  -1 &      -1 &       0 \\
  1 &     0 & [...]
{'fraction_non_alphanumeric': 0.16573719065876613, 'fraction_numerical': 0.04217497385848728, 'mean_word_length': 3.161711385061639, 'pattern_counts': {'":': 10, '<': 23, '<?xml version=': 0, '>': 23, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 11, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '6', 'dir': 'jupyter-structured-clean-dedup', 'id': '326352', 'license': 'MIT', 'n_tokens_mistral': 2366, 'n_tokens_neox': 2277, 'n_words': 503, 'path': 'Cooling Tank Problem/Tank Optimization.ipynb', 'repo_name': 'DesignEngrLab/resil_opt_examples', 'size': '5738'}