{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Conjugate Heat Transfer\n",
    "\n",
    "In this example we go over how to set up and perform a Conjugate Heat Transfer (CHT) simulation using Flow360 Python API. CHT is used to predict thermal interaction between a solid body and a fluid domain. We will go through creating a project, defining simulation settings, as well as post-processing the surface heat transfer results.\n",
    "\n",
    "![CHT mesh](figures/CHT_mesh.png)\n",
    "\n",
    "**Note:** The settings in this example are by no means a validation setup; they are crafted to showcase the capabilities of Flow360 and we have intentionally reduced node count and example FC cost. For rigorous validation, modify the settings as needed."
   ],
   "id": "f1c2a005"
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 1. Setup and Imports\n",
    "\n",
    "First, we import the required modules from `flow360` library."
   ],
   "id": "6ab5fdda"
  },
  {
   "cell_type": "code",
   "metadata": {},
   "source": [
    "import flow360 as fl\n",
    "from flow360 import u\n",
    "from flow360.examples import TutorialCHTSolver"
   ],
   "execution_count": 1,
   "outputs": [],
   "id": "2cc68150"
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 2. Project Initialization\n",
    "\n",
    "A `Project` in Flow360 acts as a container for simulations and their related data. In this instance, the project is initialized directly from a pre-existing volume mesh file."
   ],
   "id": "f8ee27b5"
  },
  {
   "cell_type": "code",
   "metadata": {},
   "source": [
    "TutorialCHTSolver.get_files()\n",
    "\n",
    "project = fl.Project.from_volume_mesh(\n",
    "    TutorialCHTSolver.mesh_filename, name=\"Conjugate Heat Transfer\"\n",
    ")\n",
    "\n",
    "volume_mesh = project.volume_mesh"
   ],
   "execution_count": 2,
   "outputs": [
    {
     "output_type": "display_data",
     "data": {
      "text/html": [
       "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"color: #7fbfbf; text-decoration-color: #7fbfbf\">[11:11:19] </span><span style=\"color: #008080; text-decoration-color: #008080\">INFO</span>: VolumeMesh successfully submitted:                                                                \n",
       "<span style=\"color: #7fbfbf; text-decoration-color: #7fbfbf\">           </span>        type   = Volume Mesh                                                                            \n",
       "<span style=\"color: #7fbfbf; text-decoration-color: #7fbfbf\">           </span>        name   = CHT results from Python                                                                \n",
       "<span style=\"color: #7fbfbf; text-decoration-color: #7fbfbf\">           </span>        id     = vm-<span style=\"color: #ffff00; text-decoration-color: #ffff00\">8d68a03b-3db8-4913-abe5-e457188fa9ea</span>                                                \n",
       "<span style=\"color: #7fbfbf; text-decoration-color: #7fbfbf\">           </span>        status = uploaded                                                                               \n",
       "<span style=\"color: #7fbfbf; text-decoration-color: #7fbfbf\">           </span>                                                                                                        \n",
       "</pre>\n"
      ],
      "text/plain": [
       "\u001b[2;36m[11:11:19]\u001b[0m\u001b[2;36m \u001b[0m\u001b[36mINFO\u001b[0m: VolumeMesh successfully submitted:                                                                \n",
       "\u001b[2;36m           \u001b[0m        type   = Volume Mesh                                                                            \n",
       "\u001b[2;36m           \u001b[0m        name   = CHT results from Python                                                                \n",
       "\u001b[2;36m           \u001b[0m        id     = vm-\u001b[93m8d68a03b-3db8-4913-abe5-e457188fa9ea\u001b[0m                                                \n",
       "\u001b[2;36m           \u001b[0m        status = uploaded                                                                               \n",
       "\u001b[2;36m           \u001b[0m                                                                                                        \n"
      ]
     },
     "metadata": {}
    }
   ],
   "id": "575744d8"
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 3. Simulation Parameters Definition\n",
    "\n",
    "All parameters for the simulation exist within the `SimulationParams` object. In order to better focus on `Solid` model definition, we will define it a bit further down below.\n",
    "\n",
    "Before that, we need to specify our `Fluid` domain solver settings and boundary conditions, operating condition of our simulation, as well as post-processing information such as reference geometry dimensions and outputs we want to get from the solver."
   ],
   "id": "eead6719"
  },
  {
   "cell_type": "code",
   "metadata": {},
   "source": [
    "with fl.SI_unit_system:\n",
    "    params = fl.SimulationParams(\n",
    "        reference_geometry=fl.ReferenceGeometry(\n",
    "            moment_center=[0, 0, 0] * fl.u.m,\n",
    "            moment_length=[1, 1, 1] * fl.u.m,\n",
    "            area=1 * fl.u.m**2,\n",
    "        ),\n",
    "        operating_condition=fl.AerospaceCondition.from_mach(mach=0.1),\n",
    "        time_stepping=fl.Steady(\n",
    "            max_steps=10000, CFL=fl.RampCFL(initial=1, final=100, ramp_steps=1000)\n",
    "        ),\n",
    "        models=[\n",
    "            fl.Fluid(\n",
    "                navier_stokes_solver=fl.NavierStokesSolver(\n",
    "                    absolute_tolerance=1e-9,\n",
    "                    linear_solver=fl.LinearSolver(max_iterations=35),\n",
    "                    order_of_accuracy=2,\n",
    "                    kappa_MUSCL=-1,\n",
    "                ),\n",
    "                turbulence_model_solver=fl.SpalartAllmaras(\n",
    "                    absolute_tolerance=1e-8,\n",
    "                    linear_solver=fl.LinearSolver(max_iterations=25),\n",
    "                    equation_evaluation_frequency=4,\n",
    "                    order_of_accuracy=2,\n",
    "                ),\n",
    "            ),\n",
    "            fl.Wall(\n",
    "                surfaces=volume_mesh[\"fluid/centerbody\"],\n",
    "            ),\n",
    "            fl.Freestream(\n",
    "                surfaces=volume_mesh[\"fluid/farfield\"],\n",
    "            ),\n",
    "        ],\n",
    "        outputs=[\n",
    "            fl.VolumeOutput(\n",
    "                output_format=[\"paraview\", \"tecplot\"],\n",
    "                output_fields=[\n",
    "                    \"primitiveVars\",\n",
    "                    \"T\",\n",
    "                    \"Cp\",\n",
    "                    \"Mach\",\n",
    "                ],\n",
    "            ),\n",
    "            fl.SurfaceOutput(\n",
    "                surfaces=volume_mesh[\"*\"],\n",
    "                output_format=[\"paraview\", \"tecplot\"],\n",
    "                output_fields=[\"primitiveVars\", \"T\", \"Cp\", \"Cf\", \"CfVec\"],\n",
    "            ),\n",
    "            fl.SliceOutput(\n",
    "                entities=[\n",
    "                    fl.Slice(\n",
    "                        name=\"slice_x\",\n",
    "                        normal=(1, 0, 0),\n",
    "                        origin=(0.35, 0, 0),\n",
    "                    ),\n",
    "                    fl.Slice(\n",
    "                        name=\"slice_y\",\n",
    "                        normal=(0, 1, 0),\n",
    "                        origin=(0, 0, 0),\n",
    "                    ),\n",
    "                ],\n",
    "                output_fields=[\"T\", \"Mach\"],\n",
    "            ),\n",
    "        ],\n",
    "    )"
   ],
   "execution_count": 3,
   "outputs": [
    {
     "output_type": "display_data",
     "data": {
      "text/html": [
       "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"color: #7fbfbf; text-decoration-color: #7fbfbf\">[11:11:50] </span><span style=\"color: #008080; text-decoration-color: #008080\">INFO</span>: using: SI unit system for unit inference.                                                         \n",
       "</pre>\n"
      ],
      "text/plain": [
       "\u001b[2;36m[11:11:50]\u001b[0m\u001b[2;36m \u001b[0m\u001b[36mINFO\u001b[0m: using: SI unit system for unit inference.                                                         \n"
      ]
     },
     "metadata": {}
    }
   ],
   "id": "65c97ba5"
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Solid Model\n",
    "\n",
    "The `Solid` model is used in CHT analysis. Its parameters define the thermal behavior of the solid body:\n",
    "- `entities`: Specifies which mesh regions are to be treated as solid. Here, the \"solid\" entity from the volume mesh is selected.\n",
    "- `heat_equation_solver`: Configures the numerical solver for the heat equation within the solid. Parameters such as tolerance and linear solver iterations can be adjusted to control convergence.\n",
    "- `material`: Defines the thermal properties of the solid material. `SolidMaterial` class requires a name and `thermal_conductivity`.\n",
    "- `volumetric_heat_source`: Allows for the specification of an internal heat generation rate within the solid's volume, specified in Watts per cubic meter.\n",
    "\n",
    "For solid surfaces not coupled with the fluid, an adiabatic condition is applied using a `Wall` boundary with a specified zero `HeatFlux`."
   ],
   "id": "c4decba1"
  },
  {
   "cell_type": "code",
   "metadata": {},
   "source": [
    "with fl.SI_unit_system:\n",
    "    models = [\n",
    "        fl.Solid(\n",
    "            entities=volume_mesh[\"solid\"],\n",
    "            heat_equation_solver=fl.HeatEquationSolver(\n",
    "                absolute_tolerance=1e-11,\n",
    "                linear_solver=fl.LinearSolver(\n",
    "                    max_iterations=25,\n",
    "                    absolute_tolerance=1e-12,\n",
    "                ),\n",
    "                equation_evaluation_frequency=10,\n",
    "            ),\n",
    "            material=fl.SolidMaterial(\n",
    "                name=\"copper\",\n",
    "                thermal_conductivity=398 * fl.u.W / (fl.u.m * fl.u.K),\n",
    "            ),\n",
    "            volumetric_heat_source=5e3 * fl.u.W / (0.01257 * fl.u.m**3),\n",
    "        ),\n",
    "        fl.Wall(\n",
    "            surfaces=volume_mesh[\"solid/adiabatic\"],\n",
    "            heat_spec=fl.HeatFlux(0 * fl.u.W / fl.u.m**2),\n",
    "        ),\n",
    "    ]\n",
    "\n",
    "params.models.extend(models)"
   ],
   "execution_count": 4,
   "outputs": [
    {
     "output_type": "display_data",
     "data": {
      "text/html": [
       "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"color: #7fbfbf; text-decoration-color: #7fbfbf\">           </span><span style=\"color: #008080; text-decoration-color: #008080\">INFO</span>: using: SI unit system for unit inference.                                                         \n",
       "</pre>\n"
      ],
      "text/plain": [
       "\u001b[2;36m          \u001b[0m\u001b[2;36m \u001b[0m\u001b[36mINFO\u001b[0m: using: SI unit system for unit inference.                                                         \n"
      ]
     },
     "metadata": {}
    }
   ],
   "id": "479871ae"
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 4. Case Execution\n",
    "\n",
    "We run the simulation by using `project.run_case()`. The script then calls `case.wait()` to wait until the simulation is finished on the Flow360 platform."
   ],
   "id": "5ab12091"
  },
  {
   "cell_type": "code",
   "metadata": {},
   "source": [
    "case = project.run_case(params=params, name=\"Steady CHT\")\n",
    "\n",
    "case.wait()"
   ],
   "execution_count": 5,
   "outputs": [
    {
     "output_type": "display_data",
     "data": {
      "text/html": [
       "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"color: #7fbfbf; text-decoration-color: #7fbfbf\">           </span><span style=\"color: #008080; text-decoration-color: #008080\">INFO</span>: using: SI unit system for unit inference.                                                         \n",
       "</pre>\n"
      ],
      "text/plain": [
       "\u001b[2;36m          \u001b[0m\u001b[2;36m \u001b[0m\u001b[36mINFO\u001b[0m: using: SI unit system for unit inference.                                                         \n"
      ]
     },
     "metadata": {}
    },
    {
     "output_type": "display_data",
     "data": {
      "text/html": [
       "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"color: #7fbfbf; text-decoration-color: #7fbfbf\">[11:11:52] </span><span style=\"color: #008080; text-decoration-color: #008080\">INFO</span>: Successfully submitted:                                                                           \n",
       "<span style=\"color: #7fbfbf; text-decoration-color: #7fbfbf\">           </span>        type   = Case                                                                                   \n",
       "<span style=\"color: #7fbfbf; text-decoration-color: #7fbfbf\">           </span>        name   = CHT case from Python                                                                   \n",
       "<span style=\"color: #7fbfbf; text-decoration-color: #7fbfbf\">           </span>        id     = case-<span style=\"color: #ffff00; text-decoration-color: #ffff00\">a12053be-2867-4159-8e28-1ba088a05062</span>                                              \n",
       "<span style=\"color: #7fbfbf; text-decoration-color: #7fbfbf\">           </span>        status = pending                                                                                \n",
       "<span style=\"color: #7fbfbf; text-decoration-color: #7fbfbf\">           </span>                                                                                                        \n",
       "</pre>\n"
      ],
      "text/plain": [
       "\u001b[2;36m[11:11:52]\u001b[0m\u001b[2;36m \u001b[0m\u001b[36mINFO\u001b[0m: Successfully submitted:                                                                           \n",
       "\u001b[2;36m           \u001b[0m        type   = Case                                                                                   \n",
       "\u001b[2;36m           \u001b[0m        name   = CHT case from Python                                                                   \n",
       "\u001b[2;36m           \u001b[0m        id     = case-\u001b[93ma12053be-2867-4159-8e28-1ba088a05062\u001b[0m                                              \n",
       "\u001b[2;36m           \u001b[0m        status = pending                                                                                \n",
       "\u001b[2;36m           \u001b[0m                                                                                                        \n"
      ]
     },
     "metadata": {}
    }
   ],
   "id": "9a8b20d0"
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 5. Results Post-Processing\n",
    "\n",
    "Upon completion, results can be accessed via the `case.results` attribute. Various data, such as surface heat transfer, can be retrieved."
   ],
   "id": "41e40b72"
  },
  {
   "cell_type": "code",
   "metadata": {},
   "source": [
    "results = case.results\n",
    "\n",
    "surface_heat_transfer = results.surface_heat_transfer.as_dataframe()\n",
    "print(surface_heat_transfer)"
   ],
   "execution_count": 6,
   "outputs": [
    {
     "output_type": "display_data",
     "data": {
      "text/html": [
       "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"color: #7fbfbf; text-decoration-color: #7fbfbf\">[11:20:04] </span><span style=\"color: #008080; text-decoration-color: #008080\">INFO</span>: Saved to                                                                                          \n",
       "<span style=\"color: #7fbfbf; text-decoration-color: #7fbfbf\">           </span><span style=\"color: #800080; text-decoration-color: #800080\">/var/folders/qk/mywsrvps5gl_f3yjx2k1v1xm0000gn/T/tmprcsk4uyf/</span><span style=\"color: #ff00ff; text-decoration-color: #ff00ff\">c2da6cbc-1e41-4e8e-bdea-ce5549440fcc.csv</span>   \n",
       "</pre>\n"
      ],
      "text/plain": [
       "\u001b[2;36m[11:20:04]\u001b[0m\u001b[2;36m \u001b[0m\u001b[36mINFO\u001b[0m: Saved to                                                                                          \n",
       "\u001b[2;36m           \u001b[0m\u001b[35m/var/folders/qk/mywsrvps5gl_f3yjx2k1v1xm0000gn/T/tmprcsk4uyf/\u001b[0m\u001b[95mc2da6cbc-1e41-4e8e-bdea-ce5549440fcc.csv\u001b[0m   \n"
      ]
     },
     "metadata": {}
    },
    {
     "output_type": "stream",
     "text": [
      "      physical_step  pseudo_step  fluid/Interface_solid_HeatTransferRate  \\\n",
      "0                 0            0                               -0.000111   \n",
      "1                 0           10                               -0.000144   \n",
      "2                 0           20                               -0.000109   \n",
      "3                 0           30                               -0.000118   \n",
      "4                 0           40                               -0.000105   \n",
      "...             ...          ...                                     ...   \n",
      "996               0         9960                               -0.000074   \n",
      "997               0         9970                               -0.000074   \n",
      "998               0         9980                               -0.000074   \n",
      "999               0         9990                               -0.000074   \n",
      "1000              0         9999                               -0.000074   \n",
      "\n",
      "      fluid/centerbody_HeatTransferRate  totalHeatFlux  \n",
      "0                             -0.000296            0.0  \n",
      "1                             -0.000140            0.0  \n",
      "2                             -0.000096            0.0  \n",
      "3                             -0.000068            0.0  \n",
      "4                             -0.000051            0.0  \n",
      "...                                 ...            ...  \n",
      "996                           -0.000001            0.0  \n",
      "997                           -0.000001            0.0  \n",
      "998                           -0.000001            0.0  \n",
      "999                           -0.000001            0.0  \n",
      "1000                          -0.000001            0.0  \n",
      "\n",
      "[1001 rows x 5 columns]\n"
     ],
     "name": "stdout"
    }
   ],
   "id": "589add76"
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "flow360",
   "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.11.13"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
