{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "\n",
    "from functions.pressure_conversion import pressure_conversion\n",
    "from Ausgleichsbecken.Ausgleichsbecken_class_file import Ausgleichsbecken_class\n",
    "from Regler.Regler_class_file import PI_controller_class"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "# define reservoir constants\n",
    "initial_level               = 5.        # m\n",
    "initial_influx              = 1.       # m³/s\n",
    "initial_outflux             = 0.        # m³/s\n",
    "initial_pipeline_pressure   = 5.\n",
    "initial_pressure_unit       = 'mWS'\n",
    "conversion_pressure_unit    = 'mWS'\n",
    "\n",
    "area_base                   = 1.        # m²\n",
    "area_outflux                = 0.5       # m²\n",
    "critical_level_low          = 0.        # m\n",
    "critical_level_high         = 10.       # m\n",
    "simulation_timestep         = 0.001     # s\n",
    "\n",
    "# for while loop\n",
    "total_min_level             = 0.01      # m\n",
    "total_max_time              = 200       # s"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "# define controller constants\n",
    "target_level = 4.5  # m\n",
    "Kp = 0.15\n",
    "Ti = 20\n",
    "\n",
    "deadband_range = 0.1 # m\n",
    "deadband_lo = target_level-deadband_range\n",
    "deadband_hi = target_level+deadband_range\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "# define pressure modulation function\n",
    "d_ppfun_max = +0.001\n",
    "d_pp_fun_max_unit = 'mWS'\n",
    "d_ppfun_min = -0.001\n",
    "d_pp_fun_min_unit = 'mWS'\n",
    "\n",
    "d_pp_max,_ = pressure_conversion(d_ppfun_max,d_pp_fun_max_unit,'Pa')\n",
    "d_pp_min,_ = pressure_conversion(d_ppfun_min,d_pp_fun_min_unit,'Pa')\n",
    "\n",
    "pp_fun_max = +1.1*target_level\n",
    "pp_fun_max_unit = 'mWS'\n",
    "pp_fun_min = +0.5*target_level\n",
    "pp_fun_min_unit = 'mWS'\n",
    "\n",
    "pp_max,_ = pressure_conversion(pp_fun_max,pp_fun_max_unit,'Pa')\n",
    "pp_min,_ = pressure_conversion(pp_fun_min,pp_fun_min_unit,'Pa')\n",
    "\n",
    "\n",
    "def pipe_pressure_fun(p,control_variable,d_pp_max=d_pp_max,d_pp_min=d_pp_min):\n",
    "    cv = control_variable\n",
    "    if cv >= 0:\n",
    "        return_val = p+cv*d_pp_max\n",
    "    else:\n",
    "        return_val = p-cv*d_pp_min\n",
    "\n",
    "    if return_val > pp_max:\n",
    "        return_val = pp_max\n",
    "    elif return_val < pp_min:\n",
    "        return_val = pp_min\n",
    "    \n",
    "    return return_val\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "c = PI_controller_class(target_level,Kp,Ti,simulation_timestep)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "V = Ausgleichsbecken_class(area_base, area_outflux, critical_level_low, critical_level_high,simulation_timestep)\n",
    "V.set_initial_level(initial_level) \n",
    "V.set_influx(initial_influx)\n",
    "V.set_outflux(initial_outflux)\n",
    "\n",
    "converted_pressure,_ = pressure_conversion(initial_pipeline_pressure,input_unit = initial_pressure_unit, target_unit = 'Pa')\n",
    "V.pressure = converted_pressure\n",
    "\n",
    "time_vec        = np.arange(0,total_max_time,simulation_timestep)\n",
    "outflux_vec     = np.empty_like(time_vec)\n",
    "outflux_vec[0]  = initial_outflux\n",
    "level_vec       = np.empty_like(time_vec)\n",
    "level_vec[0]    = initial_level"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "i_max = -1\n",
    "\n",
    "pressure_vec = np.full_like(time_vec,V.pressure)\n",
    "\n",
    "for i in range(np.size(time_vec)-1):\n",
    "    # update to include p_halfstep\n",
    "\n",
    "    if time_vec[i] >= 25 and time_vec[i] < 35:\n",
    "        V.influx = 1+(4-1)/10*(time_vec[i]-25)\n",
    "\n",
    "    if time_vec[i] >= 70 and time_vec[i] < 100:\n",
    "        V.influx = 4-(4-0.2)/30*(time_vec[i]-70)\n",
    "\n",
    "\n",
    "    c.calculate_error(V.level)\n",
    "\n",
    "    if abs(c.error) > deadband_range:\n",
    "        cv = c.get_control_variable()\n",
    "        V.pressure = pipe_pressure_fun(V.pressure,cv)\n",
    "\n",
    "    pressure_vec[i+1] = V.pressure\n",
    "    V.e_RK_4()\n",
    "    V.level = V.update_level(V.timestep)\n",
    "    V.set_volume()\n",
    "    outflux_vec[i+1] = V.outflux\n",
    "    level_vec[i+1]   = V.level\n",
    "    if V.level < total_min_level:\n",
    "        i_max = i\n",
    "        break\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "b67e1ad42a2e4b9f932b947588eac3e9",
       "version_major": 2,
       "version_minor": 0
      },
      "image/png": "[encoded data, 105176 characters]",
      "text/html": [
       "\n",
       "            <div style=\"display: inline-block;\">\n",
       "                <div class=\"jupyter-widgets widget-label\" style=\"text-align: center;\">\n",
       "                    Figure\n",
       "                </div>\n",
       "                <img src='data:image/png;base64,[encoded data, 105176 characters]' width=640.0/>\n",
       "            </div>\n",
       "        "
      ],
      "text/plain": [
       "Canvas(toolbar=Toolbar(toolitems=[('Home', 'Reset original view', 'home', 'home'), ('Back', 'Back to previous …"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "%matplotlib widget\n",
    "\n",
    "fig1, (ax1, ax2, ax3, ax4) = plt.subplots(4, 1)\n",
    "fig1.set_figheight(10)\n",
    "fig1.suptitle('Ausgleichsbecken')\n",
    "\n",
    "ax1.plot(time_vec[:i_max],level_vec[:i_max], label='Water level')\n",
    "ax1.set_ylabel(r'$h$ ['+V.level_unit+']')\n",
    "ax1.set_xlabel(r'$t$ ['+V.time_unit+']')\n",
    "ax1.legend()\n",
    "\n",
    "ax2.plot(time_vec[:i_max],outflux_vec[:i_max], label='Outflux')\n",
    "ax2.set_ylabel(r'$Q_{out}$ ['+V.flux_unit+']')\n",
    "ax2.set_xlabel(r'$t$ ['+V.time_unit+']')\n",
    "ax2.legend()\n",
    "\n",
    "ax3.plot(time_vec[:i_max],pressure_conversion(pressure_vec[:i_max],'Pa',conversion_pressure_unit)[0], label='Pipeline pressure at reservoir')\n",
    "ax3.set_ylabel(r'$p_{pipeline}$ ['+conversion_pressure_unit+']')\n",
    "ax3.set_xlabel(r'$t$ ['+V.time_unit+']')\n",
    "ax3.legend()\n",
    "\n",
    "# plt.subplots_adjust(left=0.2, bottom=0.2)\n",
    "ax4.set_axis_off()\n",
    "cell_text = np.array([[initial_level, V.level_unit], \\\n",
    "            [initial_influx, V.flux_unit], \\\n",
    "            [initial_outflux, V.flux_unit], \\\n",
    "            [simulation_timestep, V.time_unit], \\\n",
    "            [area_base, V.area_unit], \\\n",
    "            [area_outflux, V.area_unit]])\n",
    "\n",
    "row_labels =['initial_level', \\\n",
    "            'initial_influx', \\\n",
    "            'initial_outflux', \\\n",
    "            'simulation_timestep', \\\n",
    "            'area_base', \\\n",
    "            'area_outflux']\n",
    "\n",
    "plt.table(cellText=cell_text, \\\n",
    "            cellLoc='center', \\\n",
    "            colWidths=[0.3,0.1,0.3], \\\n",
    "            rowLabels=row_labels, \\\n",
    "            loc = 1, \\\n",
    "            rowLoc='left', \\\n",
    "            fontsize = 15.)\n",
    "\n",
    "fig1.tight_layout()            "
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3.8.13 ('Georg_DT_Slot3')",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.13"
  },
  "orig_nbformat": 4,
  "vscode": {
   "interpreter": {
    "hash": "84fb123bdc47ab647d3782661abcbe80fbb79236dd2f8adf4cef30e8755eb2cd"
   }
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
