{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "dfad842a-3891-400f-bbec-1959db1f0ded",
   "metadata": {},
   "source": [
    "# My first Jupyter Notebook\n",
    "\n",
    "The goal of this notebook is to calcuate the molar volume of a gas using the van der Waals equation of state.\n",
    "\n",
    "$$ (P + a/V^2)(V-b) = RT$$\n",
    "\n",
    "$$ f(V) = RT - (P +a/V^2)(V-b) $$\n",
    "\n",
    "$ V $ is the molar volume (m^3/mol)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 81,
   "id": "3517ba18-e223-47d5-bc9a-d97f4dde4843",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[0.00488274]\n"
     ]
    }
   ],
   "source": [
    "import scipy.optimize as opt\n",
    "\n",
    "\"\"\"\n",
    "Constants for the vdW equation for CO2\n",
    "\"\"\"\n",
    "\n",
    "a = 0.3658    # Pa m^6/mol^2\n",
    "b = 4.286e-5  # m^3/mol\n",
    "\n",
    "\"\"\"\n",
    "Other parameters\n",
    "\"\"\"\n",
    "\n",
    "R = 8.314   # J/mol.K  R = the ideal gas constant\n",
    "\n",
    "P = 5e5     # Pa, pressure\n",
    "T = 300     # K, temperature\n",
    "\n",
    "def vdW(V):\n",
    "    x = R*T - (P + a/V**2)*(V-b)\n",
    "    return x\n",
    "\n",
    "V_vdw = opt.fsolve(vdW, R*T/P)\n",
    "\n",
    "print(V_vdw)\n",
    "# has units of mol/m3"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0036f5cc-4c1b-4ac2-bd9c-fbd501ec8850",
   "metadata": {},
   "source": [
    "We are going to compare the vdW volume to the one predicted by the ideal gas"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 82,
   "id": "86b52e50-7e13-4f9c-866a-84fc1cb6e673",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0.0049884\n",
      "[-0.02118087]\n"
     ]
    }
   ],
   "source": [
    "V_ideal = R*T/P\n",
    "print(V_ideal)\n",
    "print((V_vdw-V_ideal)/V_ideal)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "75391bd7-7390-4ffc-9c1b-c7425f92fb76",
   "metadata": {},
   "source": [
    "---\n",
    "# Additional calculations for the homework:\n",
    "\n",
    "1. What is the molar volume of CO2 for 150K, 200K, 250K, and 350K calculated using the van der Waals equation?\n",
    "2. Make a plot of the molar volume of CO2 using the van der Waals equation between 150K and 350K"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 83,
   "id": "ca417379-e444-4ae2-99e4-048319282dfc",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[0.00221285 0.00313854 0.0040198  0.00488274 0.00573607]\n",
      "[0.0024942 0.0033256 0.004157  0.0049884 0.0058198]\n",
      "[-0.11280207 -0.0562481  -0.03300422 -0.02118087 -0.01438723]\n"
     ]
    }
   ],
   "source": [
    "# First, we'll need numpy\n",
    "\n",
    "import numpy as np\n",
    "\n",
    "# then make an array of temperatures\n",
    "\n",
    "T = np.array([150, 200, 250, 300, 350])\n",
    "\n",
    "# and caculate (now an array) of molar volumes\n",
    "\n",
    "V_ideal = R*T/P\n",
    "V_vdw = opt.fsolve(vdW, R*T/P)\n",
    "\n",
    "print(V_vdw)\n",
    "print(V_ideal)\n",
    "print((V_vdw-V_ideal)/V_ideal)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0e365e83-d431-4ab3-b0a3-f80b78658952",
   "metadata": {},
   "source": [
    "We can make a table of the results:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 84,
   "id": "a717f6d6-4a99-46d0-af7c-d99e3d996177",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[ 1.50000000e+02  2.21284907e-03  2.49420000e-03 -1.12802074e-01]\n",
      " [ 2.00000000e+02  3.13854133e-03  3.32560000e-03 -5.62480969e-02]\n",
      " [ 2.50000000e+02  4.01980148e-03  4.15700000e-03 -3.30042156e-02]\n",
      " [ 3.00000000e+02  4.88274136e-03  4.98840000e-03 -2.11808682e-02]\n",
      " [ 3.50000000e+02  5.73606922e-03  5.81980000e-03 -1.43872263e-02]]\n"
     ]
    }
   ],
   "source": [
    "# Transpose and stack the arrays\n",
    "\n",
    "# First I have to reshape the array into a 1x5 array:\n",
    "T = T.reshape(1,5)\n",
    "V_vdw = V_vdw.reshape(1,5)\n",
    "V_ideal = V_ideal.reshape(1,5)\n",
    "\n",
    "# I'll also include the differences\n",
    "V_diff = (V_vdw-V_ideal)/V_ideal\n",
    "V_diff = V_diff.reshape(1,5)\n",
    "\n",
    "# Now we're ready to transpose the array\n",
    "table = np.hstack((T.T, V_vdw.T, V_ideal.T, V_diff.T))\n",
    "\n",
    "# and print the table\n",
    "print(table)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "92fad8ed-b458-4c89-80f9-31da065969ac",
   "metadata": {},
   "source": [
    "What would happen if we printed the table without transposed arrays?"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 85,
   "id": "0d689b0e-f0c9-4f4e-96ce-5c6224374430",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[150 200 250 300 350]] [[0.00221285 0.00313854 0.0040198  0.00488274 0.00573607]] [[0.0024942 0.0033256 0.004157  0.0049884 0.0058198]] [[-0.11280207 -0.0562481  -0.03300422 -0.02118087 -0.01438723]]\n",
      "\n",
      "[[ 1.50000000e+02  2.00000000e+02  2.50000000e+02  3.00000000e+02\n",
      "   3.50000000e+02  2.21284907e-03  3.13854133e-03  4.01980148e-03\n",
      "   4.88274136e-03  5.73606922e-03  2.49420000e-03  3.32560000e-03\n",
      "   4.15700000e-03  4.98840000e-03  5.81980000e-03 -1.12802074e-01\n",
      "  -5.62480969e-02 -3.30042156e-02 -2.11808682e-02 -1.43872263e-02]]\n"
     ]
    }
   ],
   "source": [
    "print(T, V_vdw, V_ideal, V_diff)\n",
    "print()\n",
    "print(np.hstack((T, V_vdw, V_ideal, V_diff)))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "520b17ef-813f-4ace-b2c7-416c3d205164",
   "metadata": {},
   "source": [
    "This makes one long row array!\n",
    "\n",
    "Next, we'll make a plot."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 86,
   "id": "2c33c8eb-3eb2-49b1-99a1-0249d216efa8",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Make many more points for T\n",
    "\n",
    "T = np.arange(150, 450, 1)\n",
    "\n",
    "# Recalculate V_vdw and V_ideal for those points\n",
    "\n",
    "V_vdw = opt.fsolve(vdW, R*T/P)\n",
    "V_ideal = R*T/P\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 87,
   "id": "15bf663f-0c1f-4870-87b9-bbaf9b2f38b5",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<matplotlib.legend.Legend at 0x10843f500>"
      ]
     },
     "execution_count": 87,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "[encoded data, 52392 characters]",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# Create a figure. We need to load matplotlib\n",
    "\n",
    "import matplotlib.pyplot as plt\n",
    "\n",
    "fig, ax = plt.subplots()\n",
    "plt.title('Molar volume versus temperature of CO2, van der Waals EOS')\n",
    "ax.plot(T,V_vdw, label='V_vdw')\n",
    "ax.plot(T,V_ideal, label='V_ideal')\n",
    "ax.set(xlabel='Temperature, K',ylabel='Molar volume, m^3/mol')\n",
    "ax.legend(loc='best')\n",
    "#plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "fd7a68ed-ba69-4eb0-ae59-e949f57645bb",
   "metadata": {},
   "source": [
    "Let's plot the difference between the vdw and ideal equations of state?"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 88,
   "id": "a501cef5-3fb4-4c0f-a162-67028ff898aa",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[Text(0.5, 0, 'Temperature, K'), Text(0, 0.5, 'Molar volume, m^3/mol')]"
      ]
     },
     "execution_count": 88,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "[encoded data, 42496 characters]",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "fig, ax = plt.subplots()\n",
    "plt.title('Difference between real and ideal molar volume calculations, CO2')\n",
    "ax.plot(T,V_ideal-V_vdw)\n",
    "ax.set(xlabel='Temperature, K',ylabel='Molar volume, m^3/mol')\n",
    "#ax.legend(loc='best')\n",
    "#plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1676e828-98e8-48a1-ade0-ef7942eb6080",
   "metadata": {},
   "source": [
    "The molar volume of the van der Waals EOS is lower than the ideal gas volume. As a percentage,"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 89,
   "id": "61136f86-ea20-4f04-a2ff-8efae9d49f9a",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[Text(0.5, 0, 'Temperature, K'), Text(0, 0.5, 'Molar volume, m^3/mol')]"
      ]
     },
     "execution_count": 89,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "[encoded data, 41308 characters]",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "fig, ax = plt.subplots()\n",
    "plt.title('Fraction difference between real and ideal molar volume calculations, CO2')\n",
    "ax.plot(T,(V_ideal-V_vdw)/V_vdw)\n",
    "ax.set(xlabel='Temperature, K',ylabel='Molar volume, m^3/mol')\n",
    "#ax.legend(loc='best')\n",
    "#plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cb3f0057-b222-43ef-997e-2837b352e8f8",
   "metadata": {},
   "source": [
    "As the temperature increases from 150K to 450K, the difference between the real and ideal properties changes from over 10% to less than 1%. The fluid becomes more ideal as the temeprature increases (at this pressure)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "8ec9c46e-5cf0-40f6-9146-21caf531c46c",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "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.12.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
