diff --git a/examples/case_study_1/cases.py b/examples/case_study_1/cases.py index 4b1c59d5..f912a4b3 100644 --- a/examples/case_study_1/cases.py +++ b/examples/case_study_1/cases.py @@ -52,7 +52,7 @@ def get_cases(): cases_load_diversity = copy.deepcopy(cases) for ele in cases_load_diversity: ele['name'] = "{}_diverse_loads".format(ele["name"]) - ele['parameters'] = {'flo.kIntNor': 0.75} + ele['parameters'] = {'flo.kIntNor': 0.5} cases = cases + cases_load_diversity @@ -80,4 +80,4 @@ def get_result_file_name(name): case = get_case(name) model_name = (os.path.splitext(case['model'])[1])[1:] mat_name = "{}.mat".format( model_name ) - return os.path.join(name, mat_name) + return os.path.join("simulations", name, mat_name) diff --git a/examples/case_study_1/post_process.ipynb b/examples/case_study_1/post_process.ipynb index c5c4dafb..c8f62a2c 100644 --- a/examples/case_study_1/post_process.ipynb +++ b/examples/case_study_1/post_process.ipynb @@ -28,7 +28,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 1, "metadata": {}, "outputs": [], "source": [ @@ -50,7 +50,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 2, "metadata": {}, "outputs": [], "source": [ @@ -70,7 +70,8 @@ " if not os.path.exists(out_dir):\n", " os.makedirs(out_dir)\n", " figure.savefig(os.path.join(out_dir, '{}.pdf'.format(file_name)))\n", - " figure.savefig(os.path.join(out_dir, '{}.png'.format(file_name))) \n", + " figure.savefig(os.path.join(out_dir, '{}.png'.format(file_name)))\n", + " \n", "\n", "def configure_axes(axes):\n", " \"\"\" Configure the axis style\n", @@ -86,53 +87,95 @@ " \"\"\" Get the results for the case with name `case_name`\n", " \"\"\"\n", " # Make sure simulation was successful\n", - " dslog_name = os.path.join(case_name, \"dslog.txt\")\n", + " dslog_name = os.path.join(\"simulations\", case_name, \"dslog.txt\")\n", " with open(dslog_name) as dslog:\n", " if not \"Integration terminated successfully\" in dslog.read():\n", " raise Exception(\"Simulation failed. Check {}\".format(dslog_name))\n", " file_name = cases.get_result_file_name(case_name)\n", " return Reader(file_name, \"dymola\")\n", "\n", + "def get_partial_results(case_name, list_of_variables):\n", + " \"\"\" Get a dictionary with the variable names and the time series for `list_of_variables`\n", + " \"\"\"\n", + " reader = get_results(case_name)\n", + " d = dict()\n", + " read_time = True\n", + " for v in list_of_variables:\n", + " if read_time:\n", + " d['time'] = reader.values(v)[0]\n", + " read_time = False\n", + " d[v] = reader.values(v)[1]\n", + " return d\n", + "\n", + "\n", "# ---------------------------------------------------------------------------\n", "# helper functions and scripts\n", "\n", "def set_cases_and_initiate_plot():\n", - " cases = ['Base case', 'Guideline 36']\n", + " from matplotlib.gridspec import GridSpec\n", + " cases = ['Base\\ case', 'Guideline\\ 36']\n", " seasons = ['Winter', 'Spring', 'Summer']\n", " num_cases = len(cases)\n", " num_seasons = len(seasons)\n", " \n", - " fig, ax = plt.subplots(nrows=num_cases*num_seasons, ncols=1, figsize = (6.5,8.))\n", + " fig = plt.figure(figsize=(6.5,8.))\n", + " gs1 = GridSpec(80, 1)\n", + " gs1.update(left=0.1, right=0.9, hspace=0.05)\n", + " \n", + " ax = list()\n", + " ax.insert(0, fig.add_subplot(gs1[0:11,:]))\n", + " ax.insert(1, fig.add_subplot(gs1[12:23,:]))\n", + " ax.insert(2, fig.add_subplot(gs1[28:39,:]))\n", + " ax.insert(3, fig.add_subplot(gs1[40:51,:]))\n", + " ax.insert(4, fig.add_subplot(gs1[56:67,:]))\n", + " ax.insert(5, fig.add_subplot(gs1[68:79,:]))\n", + " \n", + " # fig, ax = plt.subplots(nrows=num_cases*num_seasons, ncols=1, figsize = (6.5,8.))\n", + " # fig, ax = plt.subplots(nrows=20, ncols=1, figsize = (6.5,8.))\n", " \n", " return cases, seasons, num_cases, num_seasons, fig, ax\n", "\n", "def set_up_labels(i, ax, cases, seasons, num_cases, num_seasons, x_axis_label, y_axis_label):\n", - " # Hide xtick labels and ticks on the upper case subplot (each basecase)\n", - " if i % 2 == 0:\n", - " hide_tick_labels(ax)\n", - "\n", - " # Print x axis title only below the lowest subplot\n", - " if i == num_cases*num_seasons - 1:\n", - " ax.set_xlabel(x_axis_label)\n", - " ax.set_ylabel(y_axis_label)\n", - " #ax.xaxis.set_ticks(np.arange(min(t)+0, 365, 1))\n", + " left, width = .01, .97\n", + " bottom, height = .01, .88\n", + " right = left + width\n", + " top = bottom + height\n", + " # Hide xtick labels and ticks on the upper case subplot (each basecase)\n", + " if i % 2 == 0:\n", + " hide_tick_labels(ax)\n", + "\n", + " # Print x axis title only below the lowest subplot\n", + " if i == num_cases*num_seasons - 1:\n", + " ax.set_xlabel(x_axis_label)\n", + " ax.set_ylabel(y_axis_label)\n", + " #ax.xaxis.set_ticks(np.arange(min(t)+0, 365, 1))\n", " \n", - " # Annotate case\n", - " if i % 2 == 0:\n", - " title_str = seasons[i % 3] + ' (upper: ' + cases[i % 2] + ', lower: ' + cases[(i-1) % 2] + ')'\n", - " ax.set_title(title_str, # mg assign appropriate season/case\n", - " verticalalignment = 'top',\n", - " horizontalalignment = 'center', \n", - " fontsize = 6, color = 'k')\n", - " \n", - " # Print legend only at the lower plot (g36 case)\n", - " if i % 2 == 1:\n", - " ax.legend(loc='center right', ncol=1)\n", - " configure_axes(ax)\n", - " \n", - " #plt.tight_layout(h_pad=0)\n", - " plt.tight_layout()\n", - " #plt.subplots_adjust(hspace = .2)\n", + " # Annotate case\n", + " title_str = r\"$\\it{\" + cases[i % 2] + \"}$\"\n", + " ax.text(left, top,\n", + " title_str, # mg assign appropriate season/case\n", + " verticalalignment = 'center',\n", + " horizontalalignment = 'left', \n", + " transform=ax.transAxes,\n", + " fontsize = 6, color = 'k',\n", + " bbox=dict(facecolor='white', alpha=0.75, edgecolor='none'))\n", + " \n", + " # Annotate case\n", + " # if i % 2 == 0:\n", + " # title_str = r\"$\\bf{\" + seasons[i/2] + \"}$\" + ' (upper: ' + r\"$\\it{\" + cases[i % 2] + \"}$\" + ', lower: ' + r\"$\\it{\" + cases[(i-1) % 2] + \"}$\" + ')'\n", + " # ax.set_title(title_str, # mg assign appropriate season/case\n", + " # verticalalignment = 'top',\n", + " # horizontalalignment = 'center', \n", + " # fontsize = 6, color = 'k')\n", + " \n", + " # Print legend only at the lower plot (g36 case)\n", + " if i % 2 == 1:\n", + " ax.legend(loc='center right', ncol=1)\n", + " configure_axes(ax)\n", + " \n", + " #plt.tight_layout(h_pad=0)\n", + " plt.tight_layout()\n", + " #plt.subplots_adjust(hspace = .2)\n", " \n", "def tem_conv_CtoF(T_in_degC):\n", " '''Converts temperature provided in degC to degF\n", @@ -168,11 +211,20 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 3, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Read short-term simulation results.\n" + ] + } + ], "source": [ - "# Cases and seasones combined\n", + "# Combining cases and seasons\n", + "# simulations without diverse loads\n", "winter_base = 0\n", "winter_g36 = 1\n", "spring_base = 2\n", @@ -180,17 +232,41 @@ "summer_base = 4\n", "summer_g36 = 5\n", "\n", - "r_all_cases_and_seasons = list()\n", + "r_all_without_diverse_loads = list()\n", + "\n", + "r_all_without_diverse_loads.insert(winter_base, Reader(cases.get_result_file_name('winter_base'), \"dymola\"))\n", + "r_all_without_diverse_loads.insert(winter_g36, Reader(cases.get_result_file_name('winter_g36'), \"dymola\"))\n", + "r_all_without_diverse_loads.insert(spring_base, Reader(cases.get_result_file_name('spring_base'), \"dymola\"))\n", + "r_all_without_diverse_loads.insert(spring_g36, Reader(cases.get_result_file_name('spring_g36'), \"dymola\"))\n", + "r_all_without_diverse_loads.insert(summer_base, Reader(cases.get_result_file_name('summer_base'), \"dymola\"))\n", + "r_all_without_diverse_loads.insert(summer_g36, Reader(cases.get_result_file_name('summer_g36'), \"dymola\"))\n", + "\n", + "# print(\"summer_g36 name: {}\".format(cases.get_result_file_name('summer_g36')))\n", + "\n", + "r_g36_noFreezeControl = get_results('winter_g36_noFreezeControl')\n", "\n", - "suffix = ''\n", - "#suffix = '_diverse_loads'\n", + "# simulations with diverse loads\n", + "winter_base_diverse_loads = 0\n", + "winter_g36_diverse_loads = 1\n", + "spring_base_diverse_loads = 2\n", + "spring_g36_diverse_loads = 3\n", + "summer_base_diverse_loads = 4\n", + "summer_g36_diverse_loads = 5\n", "\n", - "r_all_cases_and_seasons.insert(winter_base, Reader(cases.get_result_file_name('winter_base'+suffix), \"dymola\"))\n", - "r_all_cases_and_seasons.insert(winter_g36, Reader(cases.get_result_file_name('winter_g36'+suffix), \"dymola\"))\n", - "r_all_cases_and_seasons.insert(spring_base, Reader(cases.get_result_file_name('spring_base'+suffix), \"dymola\"))\n", - "r_all_cases_and_seasons.insert(spring_g36, Reader(cases.get_result_file_name('spring_g36'+suffix), \"dymola\"))\n", - "r_all_cases_and_seasons.insert(summer_base, Reader(cases.get_result_file_name('summer_base'+suffix), \"dymola\"))\n", - "r_all_cases_and_seasons.insert(summer_g36, Reader(cases.get_result_file_name('summer_g36'+suffix), \"dymola\"))" + "r_all_with_diverse_loads = list()\n", + "\n", + "r_all_with_diverse_loads.insert(winter_base_diverse_loads, Reader(cases.get_result_file_name('winter_base_diverse_loads'), \"dymola\"))\n", + "r_all_with_diverse_loads.insert(winter_g36_diverse_loads, Reader(cases.get_result_file_name('winter_g36_diverse_loads'), \"dymola\"))\n", + "r_all_with_diverse_loads.insert(spring_base_diverse_loads, Reader(cases.get_result_file_name('spring_base_diverse_loads'), \"dymola\"))\n", + "r_all_with_diverse_loads.insert(spring_g36_diverse_loads, Reader(cases.get_result_file_name('spring_g36_diverse_loads'), \"dymola\"))\n", + "r_all_with_diverse_loads.insert(summer_base_diverse_loads, Reader(cases.get_result_file_name('summer_base_diverse_loads'), \"dymola\"))\n", + "r_all_with_diverse_loads.insert(summer_g36_diverse_loads, Reader(cases.get_result_file_name('summer_g36_diverse_loads'), \"dymola\"))\n", + "\n", + "r_all = list()\n", + "# Combined simulation results\n", + "r_all = r_all_without_diverse_loads + r_all_with_diverse_loads\n", + "\n", + "print(\"Read short-term simulation results.\")\n" ] }, { @@ -200,6 +276,70 @@ "## Plot results" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Internal loads" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "def plot_internal_loads(reader):\n", + " ''' Main method that plots the results\n", + " '''\n", + " from buildingspy.io.outputfile import Reader\n", + " import matplotlib.pyplot as plt\n", + " import matplotlib\n", + " from matplotlib.gridspec import GridSpec\n", + " \n", + " font = {'family' : 'serif',\n", + " 'weight' : 'normal',\n", + " 'size' : 6}\n", + " matplotlib.rc('font', **font)\n", + " \n", + " plt.clf()\n", + " \n", + " time_scale=3600.\n", + " \n", + " \n", + " (t, fraInt1) = reader.values(\"flo.gai.y[1]\")\n", + " (t, fraInt2) = reader.values(\"flo.gai.y[2]\")\n", + " (t, fraInt3) = reader.values(\"flo.gai.y[3]\")\n", + " intLoa = fraInt1 + fraInt2 + fraInt3\n", + " t = t/time_scale\n", + " \n", + " # Plot figure\n", + " fig = plt.figure(figsize=(6.5, 2.5))\n", + " ax = fig.add_subplot(1, 1, 1)\n", + " ax.plot(t, intLoa, 'k', linewidth=0.5)\n", + " \n", + " #make_ticklabels_invisible(plt.gcf())\n", + " \n", + " # customize days to display\n", + "\n", + " ax.set_xlabel('time [h]')\n", + " ax.set_ylabel('internal loads [$\\mathrm{W/m^2}$]')\n", + " #ax.xaxis.set_ticks(np.arange(min(t)+0, 365, 1))\n", + "\n", + " ax.set_xlim([min(t), min(t)+24])\n", + " ax.set_xticks(range(24))\n", + " \n", + " ax.legend(loc='center right', ncol=1)\n", + "\n", + " configure_axes(ax)\n", + " \n", + " return plt\n", + "\n", + "# Create the plot for all seasons and cases\n", + "fig = plot_internal_loads(r_all_without_diverse_loads[winter_base])\n", + "save_plot(fig, \"internal_loads\")" + ] + }, { "cell_type": "markdown", "metadata": {}, @@ -211,7 +351,16 @@ "cell_type": "code", "execution_count": 5, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/usr/local/lib/python2.7/dist-packages/matplotlib/figure.py:1999: UserWarning: This figure includes Axes that are not compatible with tight_layout, so results might be incorrect.\n", + " warnings.warn(\"This figure includes Axes that are not compatible \"\n" + ] + } + ], "source": [ "def plot_room_temp(readers):\n", " ''' Main method that plots the results\n", @@ -219,6 +368,7 @@ " from buildingspy.io.outputfile import Reader\n", " import matplotlib.pyplot as plt\n", " import matplotlib\n", + " from matplotlib.gridspec import GridSpec\n", "\n", " # Optionally, change fonts to use LaTeX fonts\n", " #from matplotlib import rc\n", @@ -251,10 +401,7 @@ "\n", " TSetHea = reader.values(\"conVAVCor.TRooHeaSet\")[1]\n", " TSetCoo = reader.values(\"conVAVCor.TRooCooSet\")[1]\n", - "\n", - " # Generate figure and plot data\n", - " ax[i] = plt.subplot(num_cases*num_seasons, 1, i+1)\n", - "\n", + " \n", " ax[i].plot(t, TOut-273.15, 'k', label='$T_{out}$', linewidth=0.5)\n", " ax[i].plot(t, TRoo[0]-273.15, 'b', label='$T_{nor}$', linewidth=0.5)\n", " ax[i].plot(t, TRoo[1]-273.15, 'g', label='$T_{wes}$', linewidth=0.5)\n", @@ -265,6 +412,8 @@ " ax[i].patch.set_facecolor('mistyrose') \n", " ax[i].fill_between(t, TSetHea-273.15, y2=TSetCoo-273.15, color='white')\n", " \n", + " #make_ticklabels_invisible(plt.gcf())\n", + " \n", " # customize days to display\n", " ax[i].set_xlim([min(t)+5, min(t)+12])\n", " \n", @@ -273,11 +422,12 @@ " 'time [days]', 'temperature [$^\\circ$C]')\n", " \n", " add_secondary_yaxis_for_degF(ax[i], t, TOut)\n", + " \n", "\n", " return plt\n", "\n", "# Create the plot for all seasons and cases\n", - "fig = plot_room_temp(r_all_cases_and_seasons)\n", + "fig = plot_room_temp(r_all_without_diverse_loads)\n", "save_plot(fig, \"TRoom_all\")" ] }, @@ -285,7 +435,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "### VAV control" + "South and north zone temperature with and without diverse IHG:" ] }, { @@ -293,6 +443,88 @@ "execution_count": 6, "metadata": {}, "outputs": [], + "source": [ + "def plot_N_S_room_temp(readers):\n", + " ''' Main method that plots the results\n", + " '''\n", + " from buildingspy.io.outputfile import Reader\n", + " import matplotlib.pyplot as plt\n", + " import matplotlib\n", + "\n", + " # Optionally, change fonts to use LaTeX fonts\n", + " #from matplotlib import rc\n", + " #rc('text', usetex=True)\n", + " #rc('font', family='serif')\n", + " \n", + " font = {'family' : 'serif',\n", + " 'weight' : 'normal',\n", + " 'size' : 6}\n", + " matplotlib.rc('font', **font)\n", + " \n", + " plt.clf()\n", + " time_scale=86400.\n", + " \n", + " cases, seasons, num_cases, num_seasons, fig, ax = set_cases_and_initiate_plot()\n", + " \n", + " # Read results\n", + " for i in range(num_cases*num_seasons):\n", + " (t, TOut) = readers[i].values(\"weaBus.TDryBul\")\n", + " t = t/time_scale\n", + " \n", + " reader_without_diverse_IHG = readers[i]\n", + " reader_with_diverse_IHG = readers[i+6]\n", + " \n", + " TRoo_N_S = list()\n", + " TRoo_N_S.insert(0,reader_without_diverse_IHG.values(\"flo.nor.air.vol.T\")[1])\n", + " TRoo_N_S.insert(1,reader_with_diverse_IHG.values(\"flo.nor.air.vol.T\")[1])\n", + " TRoo_N_S.insert(2,reader_without_diverse_IHG.values(\"flo.sou.air.vol.T\")[1])\n", + " TRoo_N_S.insert(3,reader_with_diverse_IHG.values(\"flo.sou.air.vol.T\")[1])\n", + " \n", + " tWith = reader_with_diverse_IHG.values(\"flo.nor.air.vol.T\")[0]/time_scale\n", + " \n", + " TSetHea = reader_without_diverse_IHG.values(\"conVAVCor.TRooHeaSet\")[1]\n", + " TSetCoo = reader_without_diverse_IHG.values(\"conVAVCor.TRooCooSet\")[1]\n", + "\n", + " # Generate figure and plot data\n", + " # ax[i] = plt.subplot(num_cases*num_seasons, 1, i+1)\n", + "\n", + " ax[i].plot(t, TOut-273.15, 'k', label='$T_{out}$', linewidth=0.5)\n", + " ax[i].plot(t, TRoo_N_S[0]-273.15, 'b', label='$T_{nor}$', linewidth=0.5)\n", + " ax[i].plot(tWith, TRoo_N_S[1]-273.15, 'b', label='$T_{nor, -50\\%}$', linewidth=0.5, linestyle='--')\n", + " ax[i].plot(t, TRoo_N_S[2]-273.15, 'r', label='$T_{sou}$', linewidth=0.5)\n", + " ax[i].plot(tWith, TRoo_N_S[3]-273.15, 'r', label='$T_{sou, +50\\%}$', linewidth=0.5, linestyle='--')\n", + "\n", + " ax[i].patch.set_facecolor('mistyrose') \n", + " ax[i].fill_between(t, TSetHea-273.15, y2=TSetCoo-273.15, color='white')\n", + " \n", + " # customize days to display\n", + " ax[i].set_xlim([min(t)+5, min(t)+12])\n", + " \n", + " set_up_labels(i, ax[i], \n", + " cases, seasons, num_cases, num_seasons, \n", + " 'time [days]', 'temperature [$^\\circ$C]')\n", + " \n", + " add_secondary_yaxis_for_degF(ax[i], t, TOut)\n", + "\n", + " return plt\n", + "\n", + "# Create the plot for all seasons and cases\n", + "fig = plot_N_S_room_temp(r_all)\n", + "save_plot(fig, \"TRoom_with_without_div_IHG\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### VAV control" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [], "source": [ "def plot_vav(readers):\n", " ''' Main method that plots the results\n", @@ -301,7 +533,7 @@ " from buildingspy.io.outputfile import Reader\n", " import matplotlib.pyplot as plt\n", "\n", - " room_styles = ['k', 'b', 'g', 'r', 'c', 'g']\n", + " room_styles = ['b', 'k', 'r', 'g', 'c', 'g']\n", " room_names = ['nor', 'wes', 'sou', 'eas', 'cor'] \n", " plt.clf() \n", " time_scale=86400.\n", @@ -326,13 +558,14 @@ " \"{}.yVAV\".format(room_names[kRoo]))[1])\n", "\n", " # Generate figure and plot data\n", - " ax[i] = plt.subplot(num_cases*num_seasons, 1, i+1)\n", + " # ax[i] = plt.subplot(num_cases*num_seasons, 1, i+1)\n", "\n", " for iRoo in [0, 2]:\n", " ax[i].plot(t, yHea[iRoo], room_styles[iRoo], \\\n", " label='$y_{{hea,{name}}}$'.format(name=room_names[iRoo]), linewidth=0.25)\n", - " ax[i].plot(t, yVAV[iRoo], room_styles[iRoo+1], \\\n", - " label='$y_{{vav,{name}}}$'.format(name=room_names[iRoo]), linewidth=0.25)\n", + " ax[i].plot(t, yVAV[iRoo], room_styles[iRoo], \\\n", + " label='$y_{{vav,{name}}}$'.format(name=room_names[iRoo]), linewidth=0.25, linestyle=\"--\", \\\n", + " marker='^', markersize=1, markevery=200)\n", " \n", " # customize days to display\n", " ax[i].set_xlim([min(t)+5, min(t)+12])\n", @@ -344,7 +577,7 @@ " return plt\n", "\n", "# Create the plot for all seasons and cases\n", - "fig = plot_vav(r_all_cases_and_seasons)\n", + "fig = plot_vav(r_all_without_diverse_loads)\n", "save_plot(fig, \"vav_all\")" ] }, @@ -388,7 +621,7 @@ " TRet = reader.values(\"TRet.T\")[1]\n", " \n", " # Generate figure and plot data\n", - " ax[i] = plt.subplot(num_cases*num_seasons, 1, i+1)\n", + " # ax[i] = plt.subplot(num_cases*num_seasons, 1, i+1)\n", "\n", " ax[i].plot(t, TOut-273.15, 'gray', label='$T_{out}$', linewidth=0.25)\n", " ax[i].plot(t, TSup-273.15, 'r', label='$T_{sup}$', linewidth=0.25)\n", @@ -406,7 +639,7 @@ " return plt\n", "\n", "# Create the plot for all seasons and cases\n", - "fig = plot_ahu_temp(r_all_cases_and_seasons)\n", + "fig = plot_ahu_temp(r_all_without_diverse_loads)\n", "save_plot(fig, \"TAHU_all\")" ] }, @@ -419,21 +652,9 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 9, "metadata": {}, - "outputs": [ - { - "ename": "NameError", - "evalue": "name 'r_g36_noFreezeControl' is not defined", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", - "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[1;32m 63\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 64\u001b[0m \u001b[0;31m# Create the plots\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 65\u001b[0;31m \u001b[0mfig\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mplot_ahu_temp\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mr_all_cases_and_seasons\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mwinter_g36\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mr_g36_noFreezeControl\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 66\u001b[0m \u001b[0msave_plot\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mfig\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m\"TMixFre\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;31mNameError\u001b[0m: name 'r_g36_noFreezeControl' is not defined" - ] - } - ], + "outputs": [], "source": [ "def plot_ahu_temp(readers):\n", " ''' Main method that plots the results\n", @@ -466,12 +687,12 @@ "\n", " \n", " # Plot figure\n", - "\n", - " ax = plt.subplot(2, 1, 1)\n", + " fig = plt.figure(figsize=(6.5,4.))\n", + " ax = fig.add_subplot(2, 1, 1)\n", " ax.plot(t, TOut-273.15, 'gray', label='$T_{out}$', linewidth=0.25)\n", - " ax.plot(t, TSupNoFr-273.15, 'b', label='$T_{sup}$', linewidth=0.25)\n", - " ax.plot(tWith, TMixWith-273.15, 'g', label='$T_{mix,with}$', linewidth=0.5)\n", - " ax.plot(t, TMixNoFr-273.15, 'r', label='$T_{mix}$', linewidth=0.5)\n", + " ax.plot(t, TSupNoFr-273.15, 'k', label='$T_{sup}$', linewidth=0.25)\n", + " ax.plot(tWith, TMixWith-273.15, 'b', label='$T_{mix,with}$', linewidth=0.5)\n", + " ax.plot(t, TMixNoFr-273.15, 'b', label='$T_{mix}$', linewidth=0.5, linestyle=\"--\")\n", "\n", " #ax.set_xlabel('time [days]')\n", " ax.set_ylabel('temperature [$^\\circ$C]')\n", @@ -483,9 +704,9 @@ "\n", " configure_axes(ax)\n", "\n", - " ax = plt.subplot(2, 1, 2)\n", - " ax.plot(tWith, yEcoOutWith, 'g', label='$y_{eco,out,with}$', linewidth=0.25)\n", - " ax.plot(t, yEcoOutNoFr, 'r', label='$y_{eco,out,no}$', linewidth=0.25)\n", + " ax = fig.add_subplot(2, 1, 2)\n", + " ax.plot(tWith, yEcoOutWith, 'r', label='$y_{eco,out,with}$', linewidth=0.25)\n", + " ax.plot(t, yEcoOutNoFr, 'r', label='$y_{eco,out,no}$', linewidth=0.25, linestyle=\"--\")\n", " ax.set_xlabel('time [days]')\n", " ax.set_ylabel('$y_{eco,out}$ [$1$]')\n", " #ax.xaxis.set_ticks(np.arange(min(t)+0, 365, 1))\n", @@ -499,7 +720,7 @@ " return plt\n", "\n", "# Create the plots\n", - "fig = plot_ahu_temp(r_all_cases_and_seasons[winter_g36], r_g36_noFreezeControl)\n", + "fig = plot_ahu_temp([r_all_without_diverse_loads[winter_g36], r_g36_noFreezeControl])\n", "save_plot(fig, \"TMixFre\")" ] }, @@ -512,7 +733,7 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 10, "metadata": {}, "outputs": [], "source": [ @@ -540,16 +761,16 @@ " \n", " yFanSup = reader.values(\"fanSup.y\")[1]\n", " #yFanRet = reader.values(\"fanRet.y\")[1]\n", - " #yEcoOut = reader.values(\"eco.yOut\")[1]\n", - " #yEcoRet = reader.values(\"eco.yRet\")[1]\n", + " yEcoOut = reader.values(\"eco.yOut\")[1]\n", + " yEcoRet = reader.values(\"eco.yRet\")[1]\n", " \n", " # Generate figure and plot data\n", - " ax[i] = plt.subplot(num_cases*num_seasons, 1, i+1)\n", + " # ax[i] = plt.subplot(num_cases*num_seasons, 1, i+1)\n", "\n", " ax[i].plot(t, yFanSup, 'r', label='$y_{fan,sup}$', linewidth=0.25)\n", - " #ax[i].plot(t, yFanRet, 'g', label='$y_{fan,ret}$', linewidth=0.25)\n", - " #ax[i].plot(t, yEcoOut, 'g', label='$y_{eco,out}$', linewidth=0.25)\n", - " #ax[i].plot(t, yEcoRet, 'b', label='$y_{eco,ret}$', linewidth=0.25)\n", + " #ax[i].plot(t, yFanRet, 'b', label='$y_{fan,ret}$', linewidth=0.25, linestyle='--')\n", + " ax[i].plot(t, yEcoOut, 'b', label='$y_{eco,out}$', linewidth=0.25)\n", + " ax[i].plot(t, yEcoRet, 'g', label='$y_{eco,ret}$', linewidth=0.25, linestyle='--')\n", " \n", " ax[i].set_xlim([min(t)+5, min(t)+12])\n", " \n", @@ -560,7 +781,7 @@ " return plt\n", "\n", "# Create the plots\n", - "fig = plot_flow_signals(r_all_cases_and_seasons)\n", + "fig = plot_flow_signals(r_all_without_diverse_loads)\n", "save_plot(fig, \"flow_signals_all\")" ] }, @@ -573,7 +794,7 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 11, "metadata": { "scrolled": true }, @@ -641,15 +862,16 @@ " fanSupACH = mFanSup * conFacACH\n", " ecoACH = mEco * conFacACH\n", " \n", - " ax[i] = plt.subplot(num_cases*num_seasons, 1, i+1)\n", + " # ax[i] = plt.subplot(num_cases*num_seasons, 1, i+1)\n", "\n", - " ax[i].plot(t, fanSupACH, 'r', label='$\\dot m_{fan,sup}/V_{bui}$', linewidth=0.25)\n", + " ax[i].plot(t, fanSupACH, 'b', label='$\\dot V_{fan,sup}/V_{bui}$', linewidth=0.25)\n", "# ax[i].plot(t, mFanRet, 'g', label='$\\dot m_{fan,ret}/\\dot m_{0}$', linewidth=0.25)\n", - " ax[i].plot(t, ecoACH, 'g', label='$\\dot m_{eco,out}/V_{bui}$', linewidth=0.25)\n", + " ax[i].plot(t, ecoACH, 'r', label='$\\dot V_{eco,out}/V_{bui}$', linewidth=0.25)\n", "\n", " \n", " # customize days to display\n", " ax[i].set_xlim([min(t)+5, min(t)+12])\n", + " ax[i].set_ylim([0, 4])\n", " \n", " set_up_labels(i, ax[i], \n", " cases, seasons, num_cases, num_seasons, \n", @@ -658,7 +880,7 @@ " return plt\n", "\n", "# Create the plots\n", - "fig = plot_normalized_flow_rates(r_all_cases_and_seasons)\n", + "fig = plot_normalized_flow_rates(r_all_without_diverse_loads)\n", "save_plot(fig, \"normalized_flow_all\")" ] }, @@ -673,17 +895,52 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 12, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Clean up memory.\n" + ] + } + ], "source": [ "# Free up storage, then read new data\n", - "r_base = list()\n", - "r_g36 = list()\n", - "r_g36_annual=get_results('annual_g36')\n", - "print(\"Read annual G36\")\n", - "r_base_annual=get_results('annual_base')\n", - "print(\"Read annual base\")" + "r_all_without_diverse_loads = list()\n", + "r_all_with_diverse_loads = list()\n", + "r_all = list()\n", + "\n", + "print(\"Clean up memory.\")" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Read annual G36 without diverse loads\n", + "Read annual base without diverse loads\n", + "Read annual G36 with diverse loads\n", + "Read annual base with diverse loads\n" + ] + } + ], + "source": [ + "list_of_variables = ['res.EHea', \"res.ECooSen\", \"res.ECooLat\", \"res.EFan\", \"flo.sou.air.vol.T\", \"CPUtime\"]\n", + "r_g36_annual_without_diverse_loads=get_partial_results('annual_g36', list_of_variables)\n", + "print(\"Read annual G36 without diverse loads\")\n", + "r_base_annual_without_diverse_loads=get_partial_results('annual_base', list_of_variables)\n", + "print(\"Read annual base without diverse loads\")\n", + "r_g36_annual_with_diverse_loads=get_partial_results('annual_g36_diverse_loads', list_of_variables)\n", + "print(\"Read annual G36 with diverse loads\")\n", + "r_base_annual_with_diverse_loads=get_partial_results('annual_base_diverse_loads', list_of_variables)\n", + "print(\"Read annual base with diverse loads\")" ] }, { @@ -697,7 +954,27 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 14, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "dict" + ] + }, + "execution_count": 14, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "type(r_g36_annual_without_diverse_loads)\n" + ] + }, + { + "cell_type": "code", + "execution_count": 15, "metadata": {}, "outputs": [], "source": [ @@ -707,11 +984,28 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 16, "metadata": { "scrolled": true }, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + ".. table:: Heating, cooling, fan and total site energy, and savings of guideline 36 case versus base case.\n", + "\n", + " ===================================== ===================================== ====================================== ====================================== =====\n", + " :math:`E_{h} \\quad [kWh/(m^2\\,a)]` :math:`E_{c} \\quad [kWh/(m^2\\,a)]` :math:`E_{f} \\quad [kWh/(m^2\\,a)]` :math:`E_{tot} \\quad [kWh/(m^2\\,a)]` [%]\n", + " ===================================== ===================================== ====================================== ====================================== =====\n", + " 4.46 19.66 3.563 27.68 \n", + " 3.686 14.92 1.833 20.44 26.2 \n", + " ===================================== ===================================== ====================================== ====================================== =====\n", + " \n", + " \n" + ] + } + ], "source": [ "def plot_energy(r_base, r_g36):\n", " from buildingspy.io.outputfile import Reader\n", @@ -721,7 +1015,7 @@ "\n", " # Conversion to kWh/m2\n", " conv = 1/3600./1000.\n", - " readers = [r_base, r_g36]\n", + " results = [r_base, r_g36]\n", " width = 0.5 # the width of the bars: can also be len(x) sequence\n", "\n", " hea = [0., 0.]\n", @@ -734,11 +1028,12 @@ " \n", " idx = [0, 1]\n", " for i in idx:\n", - " hea[i] = readers[i].values('res.EHea')[1][-1] * conv / COPh\n", - " cooSen[i] = -readers[i].values('res.ECooSen')[1][-1] * conv / COPc\n", - " cooLat[i] = -readers[i].values('res.ECooLat')[1][-1] * conv / COPc\n", + " res_dic = results[i]\n", + " hea[i] = res_dic['res.EHea'][-1] * conv / COPh\n", + " cooSen[i] = -res_dic['res.ECooSen'][-1] * conv / COPc\n", + " cooLat[i] = -res_dic['res.ECooLat'][-1] * conv / COPc\n", " coo[i] = cooSen[i] + cooLat[i]\n", - " fan[i] = readers[i].values('res.EFan')[1][-1] * conv\n", + " fan[i] = res_dic['res.EFan'][-1] * conv\n", " cooLatBas[i] = hea[i] + cooSen[i]\n", " fanBas[i] = cooLatBas[i] + cooLat[i]\n", " \n", @@ -756,7 +1051,6 @@ " ('heating', 'sensible cooling', 'latent cooling', 'fan'), \\\n", " loc='upper right')\n", " \n", - " \n", " save_plot(plt, \"energy\")\n", " \n", " # Write result to console and file\n", @@ -785,38 +1079,121 @@ " fil.write(str)\n", " \n", " save_rst(str, \"site_energy\")\n", - "plot_energy(r_base_annual, r_g36_annual)" + "plot_energy(r_base_annual_without_diverse_loads, r_g36_annual_without_diverse_loads)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "### Diagnostic output" + "Plot energy use with diverse loads" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 17, "metadata": {}, "outputs": [], "source": [ - "print(\"Average outdoor air intake, base {} kg/s\".format(r_base_annual.mean('eco.port_Out.m_flow')))\n", - "print(\"Average outdoor air intake, G36 {} kg/s\".format(r_g36_annual.mean( 'eco.port_Out.m_flow')))\n", + "def plot_all_energy(r_base_without, r_g36_without, r_base_with, r_g36_with):\n", + " from buildingspy.io.outputfile import Reader\n", + " import matplotlib.pyplot as plt\n", + " \n", + " plt.clf() \n", + "\n", + " # Conversion to kWh/m2\n", + " conv = 1/3600./1000.\n", + " results = [r_base_without, r_g36_without, r_base_with, r_g36_with]\n", + " width = 0.5 # the width of the bars: can also be len(x) sequence\n", "\n", - "print(\"CPUtime, base {} h\".format(r_base_annual.values('CPUtime')[1][-1]/3600.))\n", - "print(\"CPUtime, G36 {} h\".format(r_g36_annual.values( 'CPUtime')[1][-1]/3600.))" + " hea = [0., 0., 0., 0.]\n", + " cooSen = [0., 0., 0., 0.]\n", + " cooLat = [0., 0., 0., 0.]\n", + " fan = [0., 0., 0., 0.]\n", + " cooLatBas = [0., 0., 0., 0.]\n", + " coo = [0, 0, 0., 0.]\n", + " fanBas = [0., 0., 0., 0.]\n", + " \n", + " idx = [0, 1, 2, 3]\n", + " for i in idx:\n", + " res_dic = results[i]\n", + " hea[i] = res_dic['res.EHea'][-1] * conv / COPh\n", + " cooSen[i] = -res_dic['res.ECooSen'][-1] * conv / COPc\n", + " cooLat[i] = -res_dic['res.ECooLat'][-1] * conv / COPc\n", + " coo[i] = cooSen[i] + cooLat[i]\n", + " fan[i] = res_dic['res.EFan'][-1] * conv\n", + " cooLatBas[i] = hea[i] + cooSen[i]\n", + " fanBas[i] = cooLatBas[i] + cooLat[i]\n", + " \n", + " \n", + " plt.figure(figsize=(5,3))\n", + "\n", + " p1 = plt.bar(idx, hea, width, color='r')\n", + " p2 = plt.bar(idx, cooSen, width, bottom=hea, color='g')\n", + " p3 = plt.bar(idx, cooLat, width, bottom=cooLatBas, color='b')\n", + " p4 = plt.bar(idx, fan, width, bottom=fanBas, color='k')\n", + " plt.ylabel('site electricity use [kWh/(m2 a)]')\n", + " plt.xticks([0, 1, 2, 3], ('base case', 'guideline 36', 'base case, $\\pm 50\\%$', 'guideline 36, $\\pm 50\\%$'))\n", + " #plt.yticks(np.arange(0, 81, 10))\n", + " plt.legend((p1[0], p2[0], p3[0], p4[0]), \\\n", + " ('heating', 'sensible cooling', 'latent cooling', 'fan'), \\\n", + " loc='upper right')\n", + " plt.grid(color='lightgrey', axis='y', linewidth=0.25)\n", + " for spine in plt.gca().spines.values():\n", + " spine.set_visible(False)\n", + " save_plot(plt, \"energy_all\")\n", + " \n", + "plot_all_energy(r_base_annual_without_diverse_loads, r_g36_annual_without_diverse_loads, \\\n", + " r_base_annual_with_diverse_loads, r_g36_annual_with_diverse_loads)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Diagnostic output" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 18, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "CPUtime, base 1.92556613498 h\n", + "CPUtime, G36 2.85120795356 h\n" + ] + } + ], + "source": [ + "print(\"CPUtime, base {} h\".format(r_base_annual_without_diverse_loads['CPUtime'][-1]/3600.))\n", + "print(\"CPUtime, G36 {} h\".format(r_g36_annual_without_diverse_loads['CPUtime'][-1]/3600.))" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "Text(0.5,1,u'South zone, base case')" + ] + }, + "execution_count": 19, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ - "(t, y) = r_base_annual.values('flo.sou.air.vol.T')\n", "plt.clf()\n", - "plt=Plotter.boxplot(t=t, y=y-273.15, increment=3600, nIncrement=24)\n", + "plt=Plotter.boxplot(t=r_base_annual_without_diverse_loads['time'], \\\n", + " y=r_base_annual_without_diverse_loads['flo.sou.air.vol.T']-273.15, \\\n", + " increment=3600, nIncrement=24)\n", "\n", "# Decorate, save and show the plot\n", "plt.xlabel('Time [h]') \n", @@ -837,9 +1214,20 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 20, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "168.0" + ] + }, + "execution_count": 20, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "2.8*60" ] diff --git a/examples/case_study_1/run_simulations.py b/examples/case_study_1/run_simulations.py index 7c7795ad..79dd4265 100755 --- a/examples/case_study_1/run_simulations.py +++ b/examples/case_study_1/run_simulations.py @@ -55,7 +55,7 @@ def _simulate(spec): wor_dir = create_working_directory() - out_dir = os.path.join(wor_dir, spec["name"]) + out_dir = os.path.join(wor_dir, "simulations", spec["name"]) # Update MODELICAPATH to get the right library version os.environ["MODELICAPATH"] = ":".join([spec['lib_dir'], out_dir]) @@ -84,7 +84,7 @@ def _simulate(spec): s.simulate() # Copy results back - res_des = os.path.join(CWD, spec["name"]) + res_des = os.path.join(CWD, "simulations", spec["name"]) if os.path.isdir(res_des): shutil.rmtree(res_des) print("Copying results to {}".format(res_des)) diff --git a/specification/fixLatex.py b/specification/fixLatex.py index d7f8c6ae..55bd8948 100755 --- a/specification/fixLatex.py +++ b/specification/fixLatex.py @@ -4,8 +4,8 @@ from io import open print(sys.version) -oldFil=os.path.join("build", "latex", "cdl_specification.tex") -newFil=os.path.join("build", "latex", "cdl_specification.tex-new") +oldFil=os.path.join("build", "latex", "cdl_report.tex") +newFil=os.path.join("build", "latex", "cdl_report.tex-new") def freplace(old, new): with open(oldFil, mode="rt", encoding="utf-8") as fin, open(newFil, mode="wt", encoding="utf-8") as fout: @@ -34,4 +34,3 @@ def freplace(old, new): freplace('\\begin{Verbatim}[', '\\begin{Verbatim}[fontsize=\\footnotesize, ') - diff --git a/specification/source/_static/bootstrap_custom.css b/specification/source/_static/bootstrap_custom.css index 897a356c..2c0aa4cc 100644 --- a/specification/source/_static/bootstrap_custom.css +++ b/specification/source/_static/bootstrap_custom.css @@ -115,7 +115,7 @@ h2 { } h3 { - margin: 1em 0 -0.3em 0; + margin: 1em 0 0.5em 0; font-size: 1em; } diff --git a/specification/source/_static/sphinxdoc.css b/specification/source/_static/sphinxdoc.css index d0d47715..9754068c 100644 --- a/specification/source/_static/sphinxdoc.css +++ b/specification/source/_static/sphinxdoc.css @@ -147,7 +147,7 @@ h2 { } h3 { - margin: 1em 0 -0.3em 0; + margin: 1em 0 0.5em 0 !important; font-size: 1em; } diff --git a/specification/source/conf.py b/specification/source/conf.py index 3b3551d4..16121b7a 100644 --- a/specification/source/conf.py +++ b/specification/source/conf.py @@ -273,7 +273,7 @@ # (source start file, target name, title, author, documentclass [howto/manual]). latex_documents = [ ('index', - 'cdl_specification.tex', + 'cdl_report.tex', u'Control Description Language', '', 'manual'), ] @@ -284,10 +284,13 @@ #'classoptions': ',openany' : remove blank pages in PDF. #'babel': '\\usepackage[english]{babel}' : suppress error message caused by undefined language. #'maketitle': '\\pagenumbering{gobble}\\maketitle' : switch off the page numbering in the tile and the index. +release = '' latex_elements = {'classoptions': ', openany', # remove blank pages in PDF. - 'releasename': 'Version', + 'releasename': '', 'babel': '\\usepackage[english]{babel}'} + + # 'fontpkg': '\\usepackage[scaled]{helvet}' # The name of an image file (relative to this directory) to place at the top of @@ -440,7 +443,19 @@ \belowcaptionskip=5pt -\pagestyle{fancy} +\pagestyle{normal} +\renewcommand{\chaptermark}[1]{\markboth{#1}{}} +\renewcommand{\sectionmark}[1]{\markright{\thesection\ #1}} +\fancyhf{} +\fancyhead[LE,RO]{\thepage} +\fancyhead[RE]{\leftmark} +\fancyhead[LO]{\rightmark} +\fancypagestyle{plain}{% + \fancyhead{} % get rid of headers + \renewcommand{\headrulewidth}{0pt} % and the line +} + + %%\fancyhf{} %%\rhead[LE,RO]{\thechapter .} %\lhead{Guides and tutorials} diff --git a/specification/source/example.rst b/specification/source/example.rst index 93a2ed2f..b47ce086 100644 --- a/specification/source/example.rst +++ b/specification/source/example.rst @@ -70,6 +70,24 @@ The physics implemented in the building model is further described in There is no moisture buffering in the envelope, but the room volume has a dynamic equation for the moisture content. +.. _sec_int_gai: + +Internal loads +.............. + +.. _fig_internal_loads: + +.. figure:: img/case_study1/results/internal_loads.* + :scale: 80% + + Internal load schedule. + +We use an internal load schedule as shown in +:numref:`fig_internal_loads`, of which +:math:`20\%` is radiant, +:math:`40\%` is convective sensible and +:math:`40\%` is latent. +Each zone has the same internal load per floor area. Multi-zone air exchange ....................... @@ -87,6 +105,7 @@ The multizone airflow models are further described in :cite:`Wetter2006:2`. + Control sequences ................. @@ -166,7 +185,7 @@ Our implementation differs from guideline 36 in the following points: Site electricity use .................... -To convert cooling and heating energy as transfered by the coil to site electricity +To convert cooling and heating energy as transferred by the coil to site electricity use, we apply the conversion factors from EnergyStar :cite:`EnergyStar2013`. Therefore, for an electric chiller, we assume an average coefficient of performance (COP) of :math:`3.2` and for a geothermal heat pump, we assume a COP of :math:`4.0`. @@ -206,9 +225,11 @@ according to guideline 36, part 5.B.3. Composite block that computes the zone air temperature setpoints for heating and cooling. - All simulations were done with Dymola 2018 FD01 beta3 using Ubuntu 16.04 64 bit. We used the Radau solver with a tolerance of :math:`10^{-6}`. +This solver adaptively changes the time step to control the integration error. +Also, the time step is adapted to properly simulate :term:`time events