<commit_before>{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Size Factors and Transport Conductance\n",
    "\n",
    "Consider an arbitrary pore network model such as the one shown below:\n",
    "\n",
    "<img src=\"https://user-images.githubusercontent.com/14086031/188179071-01413efc-ed04-4920-b9b1-d99288ced47b.png\" width=400px>\n",
    "\n",
    "For simulating transport in this network, we need to know lots of parameters such as pore sizes, physical properties, etc, but ultimately it comes down to knowing the conductance of the \"conduits\" in the network. For example, consider simulating Fickian diffusion in a pore network model under steady state conditions. Writing a mass balance around an arbitrary pore $i$, we have:\n",
    "\n",
    "$$\n",
    "\\sum_k^{Nb^i} m_{ik} = \\sum_k^{Nb^i} g_{ik} (c_i - c_k) = 0\n",
    "$$\n",
    "\n",
    "where $Nb^i$ is the number of neighboring pores to pore $i$, $m_{ik}$ is the mass flow rate from pore $i$ to pore $k$, and $g_{ik}$ is the overall conductance of the conduit containing pores $i$ and $k$, and the connecting throat $ik$. Writing the mass balance for each pore, we get a linear system of $N_p$ equations (where $N_p$ is the number of pores in the network), which we can solve for the pore concentrations using a linear solver.\n",
    "\n",
    "## Size Factors vs. Shape Factors\n",
    "\n",
    "Consider a conduit in a pore network model, as shown by the following figure (we assumed spherical pores and cylindrical throats, but this is not necessary):\n",
    "\n",
    "<img src=\"https://user-images.githubusercontent.com/14086031/187992821-94dee392-25a1-4fba-bce4-6ee8be8c22f2.png\" width=500px>\n",
    "\n",
    "where L is length, A is the cross-sectional area, and the subscripts $i$, $k$, and $ik$ denote pore $i$, pore $k$, and throat $ik$. Now consider diffusional mass transfer between pore $i$ and pore $k$ with a mass flow rate of $m_{ik}$, which can be described by the following equation:\n",
    "\n",
    "$$\n",
    "m_{ik} = g_{ik} \\cdot (c_i - c_k)\n",
    "$$\n",
    "\n",
    "where $g_{ik}$ is the diffusive conductance of the entire conduit, and $c_i$ and $c_k$ are the concentrations in pores $i$ and $k$, respectively. Note that the conduit $ik$ consists of pore $i$, throat $ik$, and pore $j$, which are connected in series. By electrical circuit analogy, the resistance (inverse of the conductance) of each element can be related to the overall resistance by the following equation:\n",
    "\n",
    "$$\n",
    "R_{ik} = R_i^p + R_k^p + R_{ik}^t\n",
    "$$\n",
    "\n",
    "where the superscripts $p$ and $t$ denote pore and throat resistances, respectively, and $R_{ik}$ is the resistance of the entire conduit. The equation above can be rewritten in form of conductance as follows:\n",
    "\n",
    "$$\n",
    "1/g_{ik} = 1/g_i^p + 1/g_k^p + 1/g_{ik}^t\n",
    "$$\n",
    "\n",
    "where $g_i^p$ and $g_k^p$ are the pore resistances, and $g_{ik}^t$ is the throat resistance.\n",
    "\n",
    "For simplicity, let's assume that the shape of the pores and throats are cylindrical as shown in the figure below:\n",
    "\n",
    "<img src=\"https://user-images.githubusercontent.com/14086031/188184909-079977ba-d9a8-4760-99f7-4019b4e8f2a9.png\" width=750px>\n",
    "\n",
    "Based on this assumption, the diffusive conductance of each element can be expressed as:\n",
    "\n",
    "$$\n",
    "g_i^p = D \\frac{\\pi d_i^2/4}{\\ell_i} \\quad , \\quad g_k^p = D \\frac{\\pi d_k^2/4}{\\ell_k} \\quad , \\quad g_{ik}^t = D \\frac{\\pi d_{ik}^2/4}{\\ell_{ik}}\n",
    "$$\n",
    "\n",
    "In reality, however, pores/throats are not cylindrical, and the diffusive conductance needs to be **corrected**. This correction factor is called the **shape factor** in the network modeling literature, as defined by the following equation:\n",
    "\n",
    "$$\n",
    "SF = \\frac{\\text{actual conductance}}{\\text{cylindrical conductance}}\n",
    "$$\n",
    "\n",
    ":::{warning}\n",
    "We used to use shape factors in the past, but they are not recommended, as me moved towards using the \"size factor\" instead.\n",
    ":::\n",
    "\n",
    "In OpenPNM, we used to follow this terminology, but because the shape factor depends on both geometrical and physical properties, we coined the term **size factor**, $\\mathcal{S}$ to decouple the geometric part of the conductance from its physical properties dependence, such that the diffusional mass flow rate becomes:\n",
    "\n",
    "$$\n",
    "m_{ik} = \\mathcal{S} \\cdot D \\cdot (c_i - c_k)\n",
    "$$\n",
    "\n",
    "where $D$ is the diffusivity. In other words, the size factor is the geometric part of the conductance, and so the conductance can be defined in terms of the size factor as:\n",
    "\n",
    "$$\n",
    "g = \\mathcal{S} \\cdot D\n",
    "$$\n",
    "\n",
    "OpenPNM has a number of built-in functions to calculate the size factor, which can be found under `openpnm.models.geometry.diffusive_size_factors`, and `openpnm.models.geometry.hydraulic_size_factors`. Let's inspect the available diffusive size factor models."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "spheres_and_cylinders\n",
      "circles_and_rectangles\n",
      "cones_and_cylinders\n",
      "intersecting_cones\n",
      "hybrid_cones_and_cylinders\n",
      "trapezoids_and_rectangles\n",
      "hybrid_trapezoids_and_rectangles\n",
      "intersecting_trapezoids\n",
      "pyramids_and_cuboids\n",
      "intersecting_pyramids\n",
      "hybrid_pyramids_and_cuboids\n",
      "cubes_and_cuboids\n",
      "squares_and_rectangles\n",
      "intersecting_trapezoids\n",
      "ncylinders_in_series\n"
     ]
    }
   ],
   "source": [
    "import openpnm as op\n",
    "diffusive_size_factors = op.models.geometry.diffusive_size_factors\n",
    "print(\"\\n\".join(diffusive_size_factors._funcs.__all__))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    ":::{note}\n",
    "Note that the diffusive size factor models can be used for any physics that involves molecular diffusion such as heat conduction, electron transport, etc, and therefore, it is not limited to *diffusive mass transport*. The hydraulic size factor models, however, are only applicable to the flow algorithms such as `StokesFlow`.\n",
    ":::"
   ]
  }
 ],
 "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.9.7"
  },
  "vscode": {
   "interpreter": {
    "hash": "b58bd5559424689280ce24ff6229e536533c877108d283a6d2846312dfd182d7"
   }<commit_msg>Update size factors example<commit_after>{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Size Factors and Transport Conductance\n",
    "\n",
    "Consider an arbitrary pore network model such as the one shown below:\n",
    "\n",
    "<img src=\"https://user-images.githubusercontent.com/14086031/188179071-01413efc-ed04-4920-b9b1-d99288ced47b.png\" width=400px>\n",
    "\n",
    "For simulating transport in this network, we need to know lots of parameters such as pore sizes, physical properties, etc, but ultimately it comes down to knowing the conductance of the \"conduits\" in the network. For example, consider simulating Fickian diffusion in a pore network model under steady state conditions. Writing a mass balance around an arbitrary pore $i$, we have:\n",
    "\n",
    "$$\n",
    "\\sum_k^{Nb^i} m_{ik} = \\sum_k^{Nb^i} g_{ik} (c_i - c_k) = 0\n",
    "$$\n",
    "\n",
    "where $Nb^i$ is the number of neighboring pores to pore $i$, $m_{ik}$ is the mass flow rate from pore $i$ to pore $k$, and $g_{ik}$ is the overall conductance of the conduit containing pores $i$ and $k$, and the connecting throat $ik$. Writing the mass balance for each pore, we get a linear system of $N_p$ equations (where $N_p$ is the number of pores in the network), which we can solve for the pore concentrations using a linear solver.\n",
    "\n",
    "## Size Factors vs. Shape Factors\n",
    "\n",
    "Consider a conduit in a pore network model, as shown by the following figure (we assumed spherical pores and cylindrical throats, but this is not necessary):\n",
    "\n",
    "<img src=\"https://user-images.githubusercontent.com/14086031/187992821-94dee392-25a1-4fba-bce4-6ee8be8c22f2.png\" width=500px>\n",
    "\n",
    "where L is length, A is the cross-sectional area, and the subscripts $i$, $k$, and $ik$ denote pore $i$, pore $k$, and throat $ik$. Now consider diffusional mass transfer between pore $i$ and pore $k$ with a mass flow rate of $m_{ik}$, which can be described by the following equation:\n",
    "\n",
    "$$\n",
    "m_{ik} = g_{ik} \\cdot (c_i - c_k)\n",
    "$$ (mass_flow_rate)\n",
    "\n",
    "where $g_{ik}$ is the overall conductance of the conduit containing pores $i$ and $k$, and the connecting throat $ik$. The overall conductance is a function of the pore sizes, throat sizes, and physical properties of the fluid. For example, the overall conductance can be written as:\n",
    "\n",
    "where $g_{ik}$ is the diffusive conductance of the entire conduit, and $c_i$ and $c_k$ are the concentrations in pores $i$ and $k$, respectively. Note that the conduit $ik$ consists of pore $i$, throat $ik$, and pore $j$, which are connected in series. By electrical circuit analogy, the resistance (inverse of the conductance) of each element can be related to the overall resistance by the following equation:\n",
    "\n",
    "$$\n",
    "R_{ik} = R_i^p + R_k^p + R_{ik}^t\n",
    "$$\n",
    "\n",
    "where the superscripts $p$ and $t$ denote pore and throat resistances, respectively, and $R_{ik}$ is the resistance of the entire conduit. The equation above can be rewritten in form of conductance as follows:\n",
    "\n",
    "$$\n",
    "1/g_{ik} = 1/g_i^p + 1/g_k^p + 1/g_{ik}^t\n",
    "$$ (resistors_in_series)\n",
    "\n",
    "where $g_{ik}$ is the overall conductance of the conduit containing pores $i$ and $k$, and the connecting throat $ik$. The equation above is the basis for calculating the overall conductance of a conduit in a pore network model. The pore and throat resistances can be calculated using the following equations:\n",
    "\n",
    "where $g_i^p$ and $g_k^p$ are the pore conductances, and $g_{ik}^t$ is the throat conductance.\n",
    "\n",
    "For simplicity, let's assume that the shape of the pores and throats are cylindrical as shown in the figure below:\n",
    "\n",
    "<img src=\"https://user-images.githubusercontent.com/14086031/188184909-079977ba-d9a8-4760-99f7-4019b4e8f2a9.png\" width=750px>\n",
    "\n",
    "Based on this assumption, the diffusive conductance of each element can be expressed as (more on how to derive these equations comes later):\n",
    "\n",
    "$$\n",
    "g_i^p = D \\frac{\\pi d_i^2/4}{\\ell_i} \\quad , \\quad g_k^p = D \\frac{\\pi d_k^2/4}{\\ell_k} \\quad , \\quad g_{ik}^t = D \\frac{\\pi d_{ik}^2/4}{\\ell_{ik}}\n",
    "$$\n",
    "\n",
    "In reality, however, pores/throats are not cylindrical, and the diffusive conductance needs to be **corrected**. This correction factor is called the **shape factor** in the network modeling literature, as defined by the following equation:\n",
    "\n",
    "$$\n",
    "SF = \\frac{\\text{actual conductance}}{\\text{cylindrical conductance}}\n",
    "$$\n",
    "\n",
    ":::{warning}\n",
    "We used to use shape factors in the past, but they are not recommended, as me moved towards using the \"size factor\" instead.\n",
    ":::\n",
    "\n",
    "In OpenPNM, we used to follow this terminology, but because the shape factor depends on both geometrical and physical properties, we coined the term **size factor**, $\\mathcal{S}$ to decouple the geometric part of the conductance from its physical properties dependence, such that the diffusional mass flow rate becomes:\n",
    "\n",
    "$$\n",
    "m_{ik} = \\mathcal{S} \\cdot D \\cdot (c_i - c_k)\n",
    "$$\n",
    "\n",
    "where $D$ is the diffusivity. In other words, the size factor is the geometric part of the conductance, and so the conductance can be defined in terms of the size factor as:\n",
    "\n",
    "$$\n",
    "g = \\mathcal{S} \\cdot D\n",
    "$$\n",
    "\n",
    "OpenPNM has a number of built-in functions to calculate the size factor, which can be found under `openpnm.models.geometry`, and `openpnm.models.geometry`. Let's inspect the available diffusive size factor models:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "spheres_and_cylinders\n",
      "circles_and_rectangles\n",
      "cones_and_cylinders\n",
      "intersecting_cones\n",
      "hybrid_cones_and_cylinders\n",
      "trapezoids_and_rectangles\n",
      "hybrid_trapezoids_and_rectangles\n",
      "intersecting_trapezoids\n",
      "pyramids_and_cuboids\n",
      "intersecting_pyramids\n",
      "hybrid_pyramids_and_cuboids\n",
      "cubes_and_cuboids\n",
      "squares_and_rectangles\n",
      "intersecting_trapezoids\n",
      "ncylinders_in_series\n"
     ]
    }
   ],
   "source": [
    "import openpnm as op\n",
    "diffusive_size_factors = op.models.geometry.diffusive_size_factors\n",
    "print(\"\\n\".join(diffusive_size_factors._funcs.__all__))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    ":::{note}\n",
    "Note that the diffusive size factor models can be used for any physics that involves molecular diffusion such as heat conduction, electron transport, etc, and therefore, it is not limited to *diffusive mass transport*. The hydraulic size factor models, however, are only applicable to the flow algorithms such as `StokesFlow`.\n",
    ":::"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Deriving the size factor for arbitrary geometries\n",
    "\n",
    "In this section, we will derive the equation for the size factor for arbitrary geometries, then we will apply it to the case of cylindrical pores and throats to retrieve the equations we used in the previous section.\n",
    "\n",
    "Consider the following conduit, which consists of a pore $i$, a throat $ik$, and a pore $k$:\n",
    "\n",
    "<img src=\"https://user-images.githubusercontent.com/14086031/187992821-94dee392-25a1-4fba-bce4-6ee8be8c22f2.png\" width=500px>\n",
    "\n",
    "Note that the choice of spheres and cylinders in the above figure is arbitrary and will not be taken into account in the derivation.\n",
    "\n",
    "### Diffusive size factor\n",
    "\n",
    "From the Fick's law of diffusion, the diffusive mass flow rate between pore $i$ and pore $k$ is given by (assuming that the transport begins at the center of pore $i$ and ends at the center of pore $k$):\n",
    "\n",
    "$$\n",
    "m_{ik} = -D \\cdot A(x) \\cdot \\frac{dc}{dx}\n",
    "$$\n",
    "\n",
    "where $A(x)$ is the cross-sectional area of the conduit at position $x$, and $dc/dx$ is the concentration gradient. Rearranging the equation above, we get:\n",
    "\n",
    "$$\n",
    "m_{ik} A(x) dx = -D \\cdot dc\n",
    "$$\n",
    "\n",
    "Integrating the above equation over the entire conduit, we get:\n",
    "\n",
    "$$\n",
    "m_{ik} \\int_{x_i}^{x_k} \\frac{dx}{A(x)} = -D \\int_{x_i}^{x_k} dc\n",
    "$$\n",
    "\n",
    "where $x_i$ and $x_k$ are the coordinates of the centers of pores $i$ and $k$, respectively. Note that $m_{ik}$ and $D$ are not a function of $x$, so they can be taken out of the integral. Since the conduit is connected in series, the above equation can be rewritten as:\n",
    "\n",
    "$$\n",
    "m_{ik} \\Bigg[ \\Big( \\int \\frac{dx}{A(x)} \\Big)_{\\text{pore 1}} + \\Big( \\int \\frac{dx}{A(x)} \\Big)_{\\text{throat}} + \\Big( \\int \\frac{dx}{A(x)} \\Big)_{\\text{pore 2}} \\Bigg] = D \\cdot (c_i - c_k)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "By comparing the above equation with equations {math:numref}`euler`, and {math:numref}`resistors_in_series`, the size factor for each element can be inferred as:\n",
    "\n",
    "$$\n",
    "g_{i}^p = \\int_{L_i} \\frac{dx}{A_i(x)} \\quad , \\quad g_{k}^p = \\int_{L_k} \\frac{dx}{A_k(x)} \\quad , \\quad g_{ik}^t = \\int_{L_{ik}} \\frac{dx}{A_{ik}(x)}\n",
    "$$"
   ]
  }
 ],
 "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.9.13"
  },
  "vscode": {
   "interpreter": {
    "hash": "b58bd5559424689280ce24ff6229e536533c877108d283a6d2846312dfd182d7"
   }
{'fraction_non_alphanumeric': 0.1564394158055764, 'fraction_numerical': 0.023725682618484095, 'mean_word_length': 3.2617466174661747, 'pattern_counts': {'":': 80, '<': 10, '<?xml version=': 0, '>': 10, 'https://': 7, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1696706', 'n_tokens_mistral': 6235, 'n_tokens_neox': 5776, 'n_words': 1991}