diff --git a/extern/cooling/isrf_1000Go_grains.h5 b/extern/cooling/isrf_1000Go_grains.h5 new file mode 100644 index 000000000..76247e217 Binary files /dev/null and b/extern/cooling/isrf_1000Go_grains.h5 differ diff --git a/regression/quokka-tests.ini b/regression/quokka-tests.ini index 1849cce4d..49bf951ca 100644 --- a/regression/quokka-tests.ini +++ b/regression/quokka-tests.ini @@ -90,3 +90,20 @@ compareParticles = 1 particleTypes = tracer_particles testSrcTree = . ignore_return_code = 1 + +[ShockCloud-GPU] +buildDir = . +target = shock_cloud +inputFile = tests/ShockCloud_64_regression.in +dim = 3 +cmakeSetupOpts = -DAMReX_GPU_BACKEND=CUDA +restartTest = 0 +useMPI = 1 +numprocs = 1 +compileTest = 0 +doVis = 1 +visVar = temperature +compareParticles = 1 +particleTypes = tracer_particles +testSrcTree = . +ignore_return_code = 1 diff --git a/src/NSCBC_inflow.hpp b/src/NSCBC_inflow.hpp index 6b4f0c929..a7acc4a67 100644 --- a/src/NSCBC_inflow.hpp +++ b/src/NSCBC_inflow.hpp @@ -166,8 +166,6 @@ AMREX_GPU_DEVICE AMREX_FORCE_INLINE void setInflowX1LowerLowOrder(const amrex::I amrex::Box const &box = geom.Domain(); const auto &domain_lo = box.loVect3d(); const int ilo = domain_lo[0]; - const Real dx = geom.CellSize(0); - const Real Lx = geom.prob_domain.length(0); constexpr int N = HydroSystem::nvar_; /// x1 lower boundary -- subsonic inflow diff --git a/src/NSCBC_outflow.hpp b/src/NSCBC_outflow.hpp index e39ba6307..15ddd32f0 100644 --- a/src/NSCBC_outflow.hpp +++ b/src/NSCBC_outflow.hpp @@ -370,7 +370,6 @@ AMREX_GPU_DEVICE AMREX_FORCE_INLINE void setOutflowBoundaryLowOrder(const amrex: const int im1 = (SIDE == BoundarySide::Lower) ? ibr + 1 : ibr - 1; const int im2 = (SIDE == BoundarySide::Lower) ? ibr + 2 : ibr - 2; const int im3 = (SIDE == BoundarySide::Lower) ? ibr + 3 : ibr - 3; - const Real dx = geom.CellSize(static_cast(DIR)); // compute primitive vars quokka::valarray Q_i{}; diff --git a/src/ShockCloud/CMakeLists.txt b/src/ShockCloud/CMakeLists.txt index 5d3bb12d3..f80ea5f6f 100644 --- a/src/ShockCloud/CMakeLists.txt +++ b/src/ShockCloud/CMakeLists.txt @@ -1,10 +1,8 @@ if (AMReX_SPACEDIM GREATER_EQUAL 3) add_executable(shock_cloud cloud.cpp ${QuokkaObjSources}) - add_executable(test_grackle_cooling test_grackle_cooling.cpp ${QuokkaObjSources}) if(AMReX_GPU_BACKEND MATCHES "CUDA") setup_target_for_cuda_compilation(shock_cloud) - setup_target_for_cuda_compilation(test_grackle_cooling) endif(AMReX_GPU_BACKEND MATCHES "CUDA") endif(AMReX_SPACEDIM GREATER_EQUAL 3) diff --git a/src/ShockCloud/boundary_conditions.ipynb b/src/ShockCloud/boundary_conditions.ipynb new file mode 100644 index 000000000..2aefa6415 --- /dev/null +++ b/src/ShockCloud/boundary_conditions.ipynb @@ -0,0 +1,812 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Shock jump conditions" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "from sympy import *\n", + "init_printing(use_unicode=True)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The Euler equations in 1D are:\n", + "\n", + "$\\partial_t \\vec{U} + \\partial_x \\vec{F}(\\vec{U}) = 0$,\n", + "\n", + "where $\\vec{U} = [\\rho, u, P]$.\n", + "\n", + "Using the weak form of the Euler equations, and assuming a steady state on the left state $U_L$ and right side $U_R$ of the shock, we can obtain a jump discontinuity solution:\n", + "\n", + "$u_s (\\vec{U}_L - \\vec{U}_R) = {\\vec{F}(\\vec{U}_L) - \\vec{F}(\\vec{U}_R)}$\n", + "\n", + "where $u_s$ is the speed that the discontinuity travels (i.e., the shock speed).\n", + "\n", + "*A crucial simplification is obtained by working in the shock tube frame, where (by definition) $u_R = 0$.*" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAACgAAABLCAYAAAACnsWZAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAEBUlEQVRoBe2a3U0cMRSFF8RzRDZSCth0QJIKAh3kpwJCB0E8wRsiHZAOktABSQUIOoACIgWhVJDzzfrOeAfPjNeehSjylcz1z/W9Z47tWdvD2uHh4dZkMrlUCsnZ0dHRu1DDWHXyfy1fs5A/ta1teA2flcfYlxu/sKL8ScDvjureUu8DPBXihwC0gEcxvyxUqKA6qu4BpDJZ5NSY+C0nL5ROVJf9wOvJiLyOAsIcvpDeV2Kq7CudKx+cW17XwWw2QIH4qCib0mcWTfk75SmfWl2qzgaowKzyqwCAC9VtC+xmoC26agyA24p2G4ho84/2ZMkCGMnONBmdOmYBVH8Lzpzrkkcf4i5gVv/MMik6l8HQ3DMcxi7vxWTJAuheJwQPDaPV2WJJApkF0EX8IT0LRDcGaU+WMQB+V/RXAQQvVXflsRwwGa7KBigA/NjfSlc/7oRUnuF9r7RLOUf83UyOH9hic/BamkWBfqNy6BdGTfEyCkABuVPIvfiw8ZbZQxwfKs2yAEzjrelVGGy4SMsVBtN4a3oVBhsu0nKFwTTeml6FwYaLtFxhMI23plfUflD7vS114YaAjSi75Jkrc6Qkv+v2hMqOK7FD/EEAuLVCfirNKCtxi8WpjXPJSmSQQYGAPS6CENi6UV19k6Uyt7KflGpRO2wDHs2ZhR035xROevSnLUpiGPQBAfZryzOBJwpaaZfnqHmuRN89ADnNTRg3XtHXcgB8ooSYnpfcXznj6SfSsIG0z7ncJ9+ZXWUx/8N8bdvSwm1E6JhKm8lzywDwjyuYtra2BgiMVIC9RoB/88qWpR4Wa3EPCbih4+gv67RhmQhNwAVGFJDbVQAvzCnVz1THkLOYqhtY5bm3vlT5qXS0RAGUU4Ix/xieShwIgHH+DbEK29XKd/1Z6W27ubOev1EA1R/2ECa7rVjegTsqhy6HmA4127JhjrIwALnAtsq9EguQgNyzXKF7Pc4beaD2PGPRLM0giyRGCFgz0tdBD2Hzr21PfTVFZMOrhvKgrA9ZyBHzD2f2su7sIluG395xB66v2R8rw1BjsyUdmhpmW+veIZYTbqwOnDUBp0r3Pl2ZN7WxKKqFYXWm1cbU4JJpKRkCyE+a/7O2lPMxjAeHeIwgOT4KwBz26FsY/O8Z7H3NLPP0es+VL+7LEFbbirnyxb1mIzHDTqfapbT622aA9mTJeg9qeNnpDMl0yKCvPQugHFvwvo1ozEN0YswF2OnYa+BokCy5AENzz8AYu+WLuzHSpTl7zAKNxmD7bBIw7a7KHWI8c5QMXWWwvS9f3GEoRmCrfHGPYerBbcZYJCsFXQDm0vvPM+ifSa61fWo/8KP+ozdgAMjGsuufcmzTie2qxA5bQf9/AVFzKbuXGLjzAAAAAElFTkSuQmCC", + "text/latex": [ + "$\\displaystyle \\left[\\begin{matrix}0\\\\p_{R}\\\\0\\end{matrix}\\right]$" + ], + "text/plain": [ + "⎡ 0 ⎤\n", + "⎢ ⎥\n", + "⎢p_R⎥\n", + "⎢ ⎥\n", + "⎣ 0 ⎦" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "rho_R = Symbol('rho_R')\n", + "u_R = 0\n", + "p_R = Symbol('p_R')\n", + "gamma = Symbol('gamma')\n", + "e_R = p_R / (rho_R * (gamma - 1))\n", + "E_R = rho_R * (e_R + u_R**2 / 2)\n", + "U_R = Matrix([rho_R, rho_R*u_R, E_R])\n", + "\n", + "F_R = Matrix([rho_R*u_R,\n", + " rho_R*u_R**2 + p_R,\n", + " (E_R + p_R)*u_R])\n", + "F_R" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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", + "text/latex": [ + "$\\displaystyle \\left[\\begin{matrix}\\rho_{L} u_{L}\\\\p_{L} + \\rho_{L} u_{L}^{2}\\\\u_{L} \\left(p_{L} + \\rho_{L} \\left(\\frac{p_{L}}{\\rho_{L} \\left(\\gamma - 1\\right)} + \\frac{u_{L}^{2}}{2}\\right)\\right)\\end{matrix}\\right]$" + ], + "text/plain": [ + "⎡ ρ_L⋅u_L ⎤\n", + "⎢ ⎥\n", + "⎢ 2 ⎥\n", + "⎢ p_L + ρ_L⋅u_L ⎥\n", + "⎢ ⎥\n", + "⎢ ⎛ ⎛ 2⎞⎞⎥\n", + "⎢ ⎜ ⎜ p_L u_L ⎟⎟⎥\n", + "⎢u_L⋅⎜p_L + ρ_L⋅⎜─────────── + ────⎟⎟⎥\n", + "⎣ ⎝ ⎝ρ_L⋅(γ - 1) 2 ⎠⎠⎦" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "rho_L = Symbol('rho_L')\n", + "M = Symbol('M')\n", + "u_L = Symbol('u_L')\n", + "p_L = Symbol('p_L')\n", + "e_L = p_L / (rho_L * (gamma - 1))\n", + "E_L = rho_L * (e_L + u_L**2 / 2)\n", + "U_L = Matrix([rho_L, rho_L*u_L, E_L])\n", + "\n", + "F_L = Matrix([rho_L*u_L,\n", + " rho_L*u_L**2 + p_L,\n", + " (E_L + p_L)*u_L])\n", + "F_L" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now, we want to obtain the left (post-shock) state $U_L$ in terms of the pre-shock state $U_R$ and the Mach number $\\mathcal{M}$, which is defined as $\\mathcal{M} = u_s / c_R$." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "M = Symbol('M')\n", + "c_R = sqrt(gamma * p_R / rho_R)\n", + "u_s = M * c_R" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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", + "text/latex": [ + "$\\displaystyle \\rho_{L} = \\frac{M \\rho_{R} \\sqrt{\\frac{\\gamma p_{R}}{\\rho_{R}}}}{M \\sqrt{\\frac{\\gamma p_{R}}{\\rho_{R}}} - u_{L}}$" + ], + "text/plain": [ + " _______ \n", + " ╱ γ⋅p_R \n", + " M⋅ρ_R⋅ ╱ ───── \n", + " ╲╱ ρ_R \n", + "ρ_L = ───────────────────\n", + " _______ \n", + " ╱ γ⋅p_R \n", + " M⋅ ╱ ───── - u_L\n", + " ╲╱ ρ_R " + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "rho_L_sol1 = solveset(Eq(u_s * (U_L[0] - U_R[0]), F_L[0] - F_R[0]), rho_L).args[0]\n", + "Eq(rho_L, rho_L_sol1)" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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", + "text/latex": [ + "$\\displaystyle \\rho_{L} = \\frac{p_{L} - p_{R}}{u_{L} \\left(M \\sqrt{\\frac{\\gamma p_{R}}{\\rho_{R}}} - u_{L}\\right)}$" + ], + "text/plain": [ + " p_L - p_R \n", + "ρ_L = ─────────────────────────\n", + " ⎛ _______ ⎞\n", + " ⎜ ╱ γ⋅p_R ⎟\n", + " u_L⋅⎜M⋅ ╱ ───── - u_L⎟\n", + " ⎝ ╲╱ ρ_R ⎠" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "rho_L_sol2 = solveset(Eq(u_s * (U_L[1] - U_R[1]), F_L[1] - F_R[1]), rho_L).args[0]\n", + "Eq(rho_L, rho_L_sol2)" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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", + "text/latex": [ + "$\\displaystyle \\rho_{L} = \\frac{2 \\left(- M p_{L} \\sqrt{\\frac{\\gamma p_{R}}{\\rho_{R}}} + M p_{R} \\sqrt{\\frac{\\gamma p_{R}}{\\rho_{R}}} + \\gamma p_{L} u_{L}\\right)}{u_{L}^{2} \\left(M \\gamma \\sqrt{\\frac{\\gamma p_{R}}{\\rho_{R}}} - M \\sqrt{\\frac{\\gamma p_{R}}{\\rho_{R}}} - \\gamma u_{L} + u_{L}\\right)}$" + ], + "text/plain": [ + " ⎛ _______ _______ ⎞\n", + " ⎜ ╱ γ⋅p_R ╱ γ⋅p_R ⎟\n", + " 2⋅⎜- M⋅p_L⋅ ╱ ───── + M⋅p_R⋅ ╱ ───── + γ⋅p_L⋅u_L⎟\n", + " ⎝ ╲╱ ρ_R ╲╱ ρ_R ⎠\n", + "ρ_L = ───────────────────────────────────────────────────────\n", + " ⎛ _______ _______ ⎞ \n", + " 2 ⎜ ╱ γ⋅p_R ╱ γ⋅p_R ⎟ \n", + " u_L ⋅⎜M⋅γ⋅ ╱ ───── - M⋅ ╱ ───── - γ⋅u_L + u_L⎟ \n", + " ⎝ ╲╱ ρ_R ╲╱ ρ_R ⎠ " + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "rho_L_sol3 = solveset(Eq(u_s * (U_L[2] - U_R[2]), F_L[2] - F_R[2]), rho_L).args[0]\n", + "Eq(rho_L, rho_L_sol3)" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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", + "text/latex": [ + "$\\displaystyle u_{L} = \\frac{M \\sqrt{\\frac{\\gamma p_{R}}{\\rho_{R}}} \\left(\\rho_{L} - \\rho_{R}\\right)}{\\rho_{L}}$" + ], + "text/plain": [ + " _______ \n", + " ╱ γ⋅p_R \n", + " M⋅ ╱ ───── ⋅(ρ_L - ρ_R)\n", + " ╲╱ ρ_R \n", + "u_L = ─────────────────────────\n", + " ρ_L " + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "u_L_sol1 = solveset(Eq(u_s * (U_L[0] - U_R[0]), F_L[0] - F_R[0]), u_L).args[0]\n", + "Eq(u_L, u_L_sol1)" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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", + "text/latex": [ + "$\\displaystyle u_{L} = \\frac{M \\sqrt{\\frac{\\gamma p_{R}}{\\rho_{R}}}}{2} - \\frac{\\sqrt{\\frac{\\rho_{L} \\left(M^{2} \\gamma p_{R} \\rho_{L} - 4 \\rho_{R} \\left(p_{L} - p_{R}\\right)\\right)}{\\rho_{R}}}}{2 \\rho_{L}}$" + ], + "text/plain": [ + " ________________________________________\n", + " _______ ╱ ⎛ 2 ⎞ \n", + " ╱ γ⋅p_R ╱ ρ_L⋅⎝M ⋅γ⋅p_R⋅ρ_L - 4⋅ρ_R⋅(p_L - p_R)⎠ \n", + " M⋅ ╱ ───── ╱ ────────────────────────────────────── \n", + " ╲╱ ρ_R ╲╱ ρ_R \n", + "u_L = ───────────── - ─────────────────────────────────────────────\n", + " 2 2⋅ρ_L " + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "u_L_sol2 = solveset(Eq(u_s * (U_L[1] - U_R[1]), F_L[1] - F_R[1]), u_L).args[0]\n", + "Eq(u_L, u_L_sol2)" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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", + "text/latex": [ + "$\\displaystyle p_{L} = M \\rho_{L} u_{L} \\sqrt{\\frac{\\gamma p_{R}}{\\rho_{R}}} + p_{R} - \\rho_{L} u_{L}^{2}$" + ], + "text/plain": [ + " _______ \n", + " ╱ γ⋅p_R 2\n", + "p_L = M⋅ρ_L⋅u_L⋅ ╱ ───── + p_R - ρ_L⋅u_L \n", + " ╲╱ ρ_R " + ] + }, + "execution_count": 10, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "p_L_sol1 = solveset(Eq(u_s * (U_L[1] - U_R[1]), F_L[1] - F_R[1]), p_L).args[0]\n", + "Eq(p_L, p_L_sol1)\n" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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", + "text/latex": [ + "$\\displaystyle p_{L} = \\frac{- M \\gamma \\rho_{L} u_{L}^{2} \\sqrt{\\frac{\\gamma p_{R}}{\\rho_{R}}} + 2 M p_{R} \\sqrt{\\frac{\\gamma p_{R}}{\\rho_{R}}} + M \\rho_{L} u_{L}^{2} \\sqrt{\\frac{\\gamma p_{R}}{\\rho_{R}}} + \\gamma \\rho_{L} u_{L}^{3} - \\rho_{L} u_{L}^{3}}{2 \\left(M \\sqrt{\\frac{\\gamma p_{R}}{\\rho_{R}}} - \\gamma u_{L}\\right)}$" + ], + "text/plain": [ + " _______ _______ ______\n", + " 2 ╱ γ⋅p_R ╱ γ⋅p_R 2 ╱ γ⋅p_R\n", + " - M⋅γ⋅ρ_L⋅u_L ⋅ ╱ ───── + 2⋅M⋅p_R⋅ ╱ ───── + M⋅ρ_L⋅u_L ⋅ ╱ ─────\n", + " ╲╱ ρ_R ╲╱ ρ_R ╲╱ ρ_R \n", + "p_L = ────────────────────────────────────────────────────────────────────────\n", + " ⎛ _______ ⎞ \n", + " ⎜ ╱ γ⋅p_R ⎟ \n", + " 2⋅⎜M⋅ ╱ ───── - γ⋅u_L⎟ \n", + " ⎝ ╲╱ ρ_R ⎠ \n", + "\n", + "_ \n", + " 3 3\n", + " + γ⋅ρ_L⋅u_L - ρ_L⋅u_L \n", + " \n", + "─────────────────────────\n", + " \n", + " \n", + " \n", + " " + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "p_L_sol2 = solveset(Eq(u_s * (U_L[2] - U_R[2]), F_L[2] - F_R[2]), p_L).args[0]\n", + "Eq(p_L, p_L_sol2)\n" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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", + "text/latex": [ + "$\\displaystyle u_{L} = \\frac{p_{L} - p_{R}}{M \\rho_{R} \\sqrt{\\frac{\\gamma p_{R}}{\\rho_{R}}}}$" + ], + "text/plain": [ + " p_L - p_R \n", + "u_L = ─────────────────\n", + " _______\n", + " ╱ γ⋅p_R \n", + " M⋅ρ_R⋅ ╱ ───── \n", + " ╲╱ ρ_R " + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# write u_L in terms of U_R and p_L\n", + "u_L_sol_new1 = solveset(Eq(rho_L_sol1, rho_L_sol2), u_L).args[0].args[0]\n", + "Eq(u_L, u_L_sol_new1)" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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", + "text/latex": [ + "$\\displaystyle p_{L} = \\frac{M^{2} \\gamma p_{R} \\rho_{L} - M^{2} \\gamma p_{R} \\rho_{R} + p_{R} \\rho_{L}}{\\rho_{L}}$" + ], + "text/plain": [ + " 2 2 \n", + " M ⋅γ⋅p_R⋅ρ_L - M ⋅γ⋅p_R⋅ρ_R + p_R⋅ρ_L\n", + "p_L = ─────────────────────────────────────\n", + " ρ_L " + ] + }, + "execution_count": 13, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# write p_L in terms of U_R and rho_L\n", + "p_L_sol_new1 = solveset(Eq(u_L_sol1, u_L_sol2), p_L).args[2].args[0]\n", + "Eq(p_L, p_L_sol_new1)\n" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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", + "text/latex": [ + "$\\displaystyle \\rho_{L} = \\frac{2 \\gamma p_{R} \\rho_{R}}{2 M^{2} \\gamma p_{R} - M \\gamma \\rho_{R} u_{L} \\sqrt{\\frac{\\gamma p_{R}}{\\rho_{R}}} - 3 M \\rho_{R} u_{L} \\sqrt{\\frac{\\gamma p_{R}}{\\rho_{R}}} + \\gamma \\rho_{R} u_{L}^{2} + \\rho_{R} u_{L}^{2}}$" + ], + "text/plain": [ + " 2⋅γ⋅p_R⋅ρ_R \n", + "ρ_L = ────────────────────────────────────────────────────────────────────────\n", + " _______ _______ \n", + " 2 ╱ γ⋅p_R ╱ γ⋅p_R \n", + " 2⋅M ⋅γ⋅p_R - M⋅γ⋅ρ_R⋅u_L⋅ ╱ ───── - 3⋅M⋅ρ_R⋅u_L⋅ ╱ ───── + γ⋅ρ_R⋅u\n", + " ╲╱ ρ_R ╲╱ ρ_R \n", + "\n", + " \n", + "──────────────\n", + " \n", + " 2 2\n", + "_L + ρ_R⋅u_L \n", + " " + ] + }, + "execution_count": 14, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# write rho_L in terms of U_R and u_L\n", + "rho_L_sol_new1 = solveset(Eq(p_L_sol1, p_L_sol2), rho_L).args[0]\n", + "Eq(rho_L, rho_L_sol_new1)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We finally obtain:" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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", + "text/latex": [ + "$\\displaystyle p_{L} = \\frac{p_{R} \\left(2 M^{2} \\gamma - \\gamma + 1\\right)}{\\gamma + 1}$" + ], + "text/plain": [ + " ⎛ 2 ⎞\n", + " p_R⋅⎝2⋅M ⋅γ - γ + 1⎠\n", + "p_L = ────────────────────\n", + " γ + 1 " + ] + }, + "execution_count": 15, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# substitute everything\n", + "p_L_sol_final = simplify(solveset(Eq(p_L, p_L_sol_new1.subs(rho_L, rho_L_sol_new1).subs(u_L, u_L_sol_new1)), p_L).args[0])\n", + "p_L_lambda = lambdify([M, p_R, gamma], p_L_sol_final)\n", + "Eq(p_L, p_L_sol_final)" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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", + "text/latex": [ + "$\\displaystyle u_{L} = \\frac{2 \\sqrt{\\frac{\\gamma p_{R}}{\\rho_{R}}} \\left(M^{2} - 1\\right)}{M \\left(\\gamma + 1\\right)}$" + ], + "text/plain": [ + " _______ \n", + " ╱ γ⋅p_R ⎛ 2 ⎞\n", + " 2⋅ ╱ ───── ⋅⎝M - 1⎠\n", + " ╲╱ ρ_R \n", + "u_L = ──────────────────────\n", + " M⋅(γ + 1) " + ] + }, + "execution_count": 16, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# back substitute\n", + "u_L_sol_final = simplify(u_L_sol_new1.subs(p_L, p_L_sol_final))\n", + "u_L_lambda = lambdify([M, rho_R, p_R, gamma], u_L_sol_final)\n", + "Eq(u_L, u_L_sol_final)" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAL4AAAAzCAYAAAApWrKbAAAACXBIWXMAAA7EAAAOxAGVKw4bAAALVUlEQVR4Ae2c65HUOBDHh60JANgMIAPYzWDJALgIWDI4im98oyADuAgWyAAuAh4ZQAjcZMD9fxq1Srbl53g8Go+7SiO51Xq1ulstWeNbf/78WS0wDgdevXp1WzW99LXd8/Ez4TfjtLDUMhYH1mNVtNTjOPBGQv7ceKH0O6W/K9w33BLnwYGzPLoxm15cS9ivotG8UfqecA8i3MGT6o+tRgfvy64dGDqWRfB35XyxPNb+WxGV15ME5W/1KCtF3JFDGBbG1AtunbqPL6Zdi2NPFMxSPxHuUxMXPaOx5vjuXxRuUmWEg+ax4ixcHfXjsfpzqfiF4qMB9RdF/ajwUOnKfkk4BH+j+H3XQZ28j++Z9V4xjEUwGt0A0TEJl57BKAmCXwFPR30PK5kHQKg/buOtOIv+tLHA9/cf0f1WuFConRfRvlX4rvBBoaIYqbZOXvBhipgFUz8rYPXbrDOT4EDl6oSe+rD2SQu1LT35L/1hsz0ZiD/wE1eksyW2zqkMAsxKvFK6i3vG2BhjOFygbB2c1WWcGJ4JQoh/KQTBLvNAE4Bb9EHB6MskTBJC/0LxIwWWXyYe3KHhqfrRWwB37DSrDGHv4MfGGDu1twj+dkqwzAg9G9OkkCofPDR3FWAuK0QBPA2W553SDwhK40+zXB8M1A9cLvo+d2CMT7sMct2F6IRofmqsdRaDTSq+JFYfSLk5nNlTnjiAyjQuv8pnBWFZ3yigYKwYYwrqI9WZ6q/QzpVAMXATaBs69i70xYHv37cYZ3mZxfSdsbaubCcv+JpMJtsE1QkbOIUgeEojGMZMGLsS7gdxDMLdiZ+7pFUGgbut2CmHYpSA/vSuq6E93Lekf6/2UGT6gAuHsDNWNpXOv1YMsHrVKs6WJItfDBf8a4WTF3xxCEbZpJqw46KYEmDBV5p4s4AxPVmDQXUiZOXjTtwtFOFKwfq14ll43CZilJD+0Ddcr1/KbzqihK7ibqkMSo91j5WM1eazAsL+g1g0oR9K5wyMkTG1wrqVYv4E+PfOmvuJZsQx866FfwtSMXiEqOLfkz8AsKxlgbW2aSeA2v6igBCyGhVcJz1zlMe+ooAPhbfKsYmeLYnixZbd8OBYCVjVUEA3fsssx7QNXRmvZ5RyVdMvlCrVdqKaziiMVYFvdSUXwa9yBgFxR5qaGAQjfpllk7uzBVTd1MUk4WLEYG1UXCkRXSqk2sbSXcSVdEmrD0mBFp7TqHMFlNBWwdoqRZdUOOHhH4qabKe2wuEZKFpKwSs1nlUwJ4TQhGBBzb+3kTPRTJazHIrjice/RyhSQmnlu8ZYO6xeeaL+Eh7XJW7X6kQpCquN6MAh9M+MKBGjGG48ibwmFG5YrPhNtDnkMUbG2grrVop5EyA05YlF4MBfa9LLlgp8yuIK3Rsqdak9FJFQebuqPKwvE4tS4oaQZmXCzYl9dKEq4JS5gm1HnLeTZEWBxU8ZjEonT9riixvPJTRlRn0VHqEqKIToEEjwBYur596gupwAqyAT5cDjuDZBn1IrCorCSsCRKnsSAsrQ9qZZJM5Xx03qCzd9C+yJ3hQw8KumHQxGincV8nUFcwIICQ4ChiBjPXF12Bi6Da7SMC6cowuPwOHDQg+4t7KKd/mDCXUC1GU3CxFgTljqJg43K6w2osPlYlPJWMobZKEKgABD1wc4WarrS596BtOqfeuz8eujcBgqTp1svuL6ba5iXDK9TmJnjhTTak8TlIdwxQJWeB6JNQgx/j2TWHan6ppgUst+PFZ8U1fA8GqHtlYK7ojS8C1xm3VtKb57tvpbO0/l2kXL6scYw9yVaeLnU3d1Yl5MmUaIO00QnfKTintULsNk//Y0V56OxxTwkip5+lImVj30r+wClsm6PKOUrYrZpaIONKx6jLETLILfiU3jEUmoEGAE9muXWkWPK2RvXV/68lb0tRK4PO72ouJaYVWe2xMopu02YEUaYy/Du4eUS9LWfq98Pybc1s5trXu1sBCPwQE7by9b72TdmkxcoaQ7pDx88MoJULKiLRLXAb8ZwW4CXKK2fUNT+anzMAydVjPr2GLxjRPTxd/UlLuyPF2T25YkzLgdnBrZhrquC72EqK6SKfB+LKnTucbmk389VGX4eFgHGMXSGE45lF5g4cDRc6Di6kjo2SBwlOW03ivB2LcFV6q37n5HE1P3cb+jqb0lb6YcKFh8CSN3K/g2THgpojSbsf8UWJ6DX6o0qwLKQRle9nwVLumLKm+BhQNZcaBs8YfcFuQYrfN56xSjV3+Wz8NNwegjbiMIvrfgWPcPpfFg2YHUWzxOB8Iq4Kgy+NFYbmXQjaULGXMgCL76iNUecltw0AmAhHPx8TMWjLl3LRZ8LHvBeks4uZ9CqJwV+zz4UygDoguo/CCF6VL3QrNwoI0DTvAlhLg4HFuG+xkex8uOptuCvDWsfVvY1vix5nvevPT9tzehu1xaO1ZWhH4fG0/M4mPtgcG3BbfF3b0SlOhCjBi0Elg9mcfLV5GrE3RUPDHBZ5M65LZgyl3BEr6u8uVwGCkhf9xgD2MKzvXfwn37cu+Uz9tN3mlsFFDi+PuY18rniqwpN3Tg+tx+VJHDgfo6W55obO6lq+cuV0S4yIdRDwc0JvgIRKMg+EpcxAT7Z5t4w3Omz2UhhCUbUH+4vDTm9zFReK4eHC3MlScaF0LP/yvCfSSlMUz8Uy28i1rrwfz7PrcF+V8ogP9P7NwbxShEaJCMXED9hCHcOETJwwu6mv5hJRyoXEG5QQpXvgWIIvDvqGBRXOHMf9TfbHmivjFPvW5cenYj5AVPRHVh7Vnh2LO6v2mulbBJrkyw8iqgCmpvC1aI80LASMbIZtzGXOmhZxDvMmBgK09Ej7Kz0lVOvoTLHXLmCcaU0BcY00/Nyx2FTVSYueTP8yjTrzM9sGQf5LZg1KkpkqN8HzPuKEzUMwpC3TGTY7Kc03PkiTNuDfPhlAlXhwlrtWw5z17Pvu36fUzXnBd6llDn2vnnleJwvKs0KwGKgYLA41y/STkZT8SDvYJ4Xnd9xu1Lle/cUSz+7EGDRfDs+zlOMD0ujF3PCKn57ibMSZ/dl+XNM5soTnJgKn/c+K3gQDh8Su4+IfC4h/SB5xgoe5CVQu1OzpN44FOm/fww3vDnGnz8UwDzZRmrWWSE1ZTALX+REMb0Kf6gRJQxZXI0Ku82VV6ocv8mZTzGvfMkxcQJcWxqP2leMEAOTkXw8WWdNVfsvjig0WMBDDiDd0xRDB6h5gQoCaJp+4ATq0dqyQXHSsBKcmVtKp0E5dOPfxWcYiaJqsimT5TE1FPzJG47pDXGujtbdyFSfuGExhfs/L8MXz8nboX5OBXBD4z2iY1id6QphiCk8TsMLCEweN+jOoNl2Va1/RWeKx7nCiiXWdmYpJCGXoipTov2ypPCwKIHjTEl2CvhmRdOYJK8jKqoTaosRuau4soR+1ltqZlkaNC4NAWXRM8IHUx1llRxLIQwCQFN+vfKGwMO+k3KTHkyBl9DHRojinNfcbD0SjPnGJ3V7AVfY4x9WcYMIOgXCrg4sbUnL0UPfkw4H7OyAXWlxnhongwYRrqI5hRjd6k4bGY9JcrgDiDW6aKzwvJ2ubxc8pYaJhSE3jOMVaDWvx+JMzcj1TO0mhx5MnQshXKaQyw6m1m+6cP+IYawr5qt4GvQDB7NZ3nD1Zn6+5gxw+M0f+TfpxsVt1VIZ8yTQj93fMBoIfz492UIfC/82bxMtTyPzwGETyH4neO3MI8axSNW5J02t02cOAUfv2n8k+ZpMvGt4430pO0fWWOcMhH2ArN1dfbCrd0r5cRo3/uH3XuZQQ0yEoOPk7t0f7H4Xbg0Hg1XFPY6oeN1dd41LYI/7fwmX9ZM24WlNTjwP/dHioHb9TmwAAAAAElFTkSuQmCC", + "text/latex": [ + "$\\displaystyle \\rho_{L} = \\frac{M^{2} \\rho_{R} \\left(\\gamma + 1\\right)}{M^{2} \\gamma - M^{2} + 2}$" + ], + "text/plain": [ + " 2 \n", + " M ⋅ρ_R⋅(γ + 1)\n", + "ρ_L = ──────────────\n", + " 2 2 \n", + " M ⋅γ - M + 2 " + ] + }, + "execution_count": 17, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# back substitute\n", + "rho_L_sol_final = simplify(rho_L_sol_new1.subs(u_L, u_L_sol_final))\n", + "rho_L_lambda = lambdify([M, rho_R, gamma], rho_L_sol_final)\n", + "Eq(rho_L, rho_L_sol_final)" + ] + }, + { + "cell_type": "code", + "execution_count": 65, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "const Real x0 = std::pow(M, 2);\n", + "const Real x1 = gamma + 1;\n", + "const Real x2 = gamma*x0;\n", + "const Real x3 = 1.0/x1;\n", + "const Real x4 = std::sqrt(gamma*p_R/rho_R);\n", + "const Real rho_L = rho_R*x0*x1/(-x0 + x2 + 2);\n", + "const Real u_L = 2*x3*x4*(x0 - 1)/M;\n", + "const Real P_L = p_R*x3*(-gamma + 2*x2 + 1);\n", + "const Real v_shock = M*x4;\n" + ] + } + ], + "source": [ + "## cxxcode\n", + "vars = ['rho_L', 'u_L', 'P_L', 'v_shock']\n", + "exprs = [rho_L_sol_final, u_L_sol_final, p_L_sol_final, u_s]\n", + "\n", + "optim_exprs = cse(exprs)\n", + "expr1 = optim_exprs[0]\n", + "expr2 = optim_exprs[1]\n", + "for var, expr in expr1:\n", + " print(\"const Real \" + cxxcode(expr, assign_to=var))\n", + "for var, expr in zip(vars, expr2):\n", + " print(\"const Real \" + cxxcode(expr, assign_to=var))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Converting between parameterizations\n", + "\n", + "We want convert between (pre-shock, right-side) background density $\\rho_R$, background pressure $p_R$ and wind velocity $v_{\\text{wind}}$ and Mach number $\\mathcal{M}$.\n", + "\n", + "That is:\n", + "\n", + "$\\rho_{bg} = \\rho_{R}$,\n", + "\n", + "$p_{bg} = p_R$,\n", + "\n", + "and\n", + "\n", + "$v_{\\text{wind}} = u_L$." + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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", + "text/latex": [ + "$\\displaystyle \\left\\{\\frac{u_{L} \\left(\\gamma + 1\\right)}{4 \\sqrt{\\frac{\\gamma p_{R}}{\\rho_{R}}}} - \\frac{\\sqrt{\\frac{16 \\gamma p_{R}}{\\rho_{R}} + u_{L}^{2} \\left(\\gamma + 1\\right)^{2}}}{4 \\sqrt{\\frac{\\gamma p_{R}}{\\rho_{R}}}}, \\frac{u_{L} \\left(\\gamma + 1\\right)}{4 \\sqrt{\\frac{\\gamma p_{R}}{\\rho_{R}}}} + \\frac{\\sqrt{\\frac{16 \\gamma p_{R}}{\\rho_{R}} + u_{L}^{2} \\left(\\gamma + 1\\right)^{2}}}{4 \\sqrt{\\frac{\\gamma p_{R}}{\\rho_{R}}}}\\right\\} \\setminus \\left\\{0\\right\\}$" + ], + "text/plain": [ + "⎧ __________________________ _________\n", + "⎪ ╱ 16⋅γ⋅p_R 2 2 ╱ 16⋅γ⋅p_R\n", + "⎪ ╱ ──────── + u_L ⋅(γ + 1) ╱ ────────\n", + "⎪ u_L⋅(γ + 1) ╲╱ ρ_R u_L⋅(γ + 1) ╲╱ ρ_R \n", + "⎨───────────── - ──────────────────────────────, ───────────── + ─────────────\n", + "⎪ _______ _______ _______ \n", + "⎪ ╱ γ⋅p_R ╱ γ⋅p_R ╱ γ⋅p_R \n", + "⎪4⋅ ╱ ───── 4⋅ ╱ ───── 4⋅ ╱ ───── 4⋅ ╱\n", + "⎩ ╲╱ ρ_R ╲╱ ρ_R ╲╱ ρ_R ╲╱ \n", + "\n", + "_________________⎫ \n", + " 2 2 ⎪ \n", + " + u_L ⋅(γ + 1) ⎪ \n", + " ⎪ \n", + "─────────────────⎬ \\ {0}\n", + " _______ ⎪ \n", + "╱ γ⋅p_R ⎪ \n", + " ───── ⎪ \n", + " ρ_R ⎭ " + ] + }, + "execution_count": 18, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "v_wind = Symbol(r'v_{\\text{wind}}')\n", + "rho_bg = Symbol(r'\\rho_{bg}')\n", + "p_bg = Symbol(r'p_{bg}')\n", + "Mach_solve = solveset(Eq(u_L, u_L_sol_final), M)\n", + "Mach_solve" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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", + "text/latex": [ + "$\\displaystyle M = \\frac{v_{\\text{wind}} \\left(\\gamma + 1\\right)}{4 \\sqrt{\\frac{\\gamma p_{bg}}{\\rho_{bg}}}} + \\frac{\\sqrt{v_{\\text{wind}}^{2} \\left(\\gamma + 1\\right)^{2} + \\frac{16 \\gamma p_{bg}}{\\rho_{bg}}}}{4 \\sqrt{\\frac{\\gamma p_{bg}}{\\rho_{bg}}}}$" + ], + "text/plain": [ + " _________________________________________\n", + " ╱ 2 2 16⋅γ⋅p_{bg} \n", + " ╱ v_{\\text{wind}} ⋅(γ + 1) + ─────────── \n", + " v_{\\text{wind}}⋅(γ + 1) ╲╱ \\rho_{bg} \n", + "M = ─────────────────────── + ─────────────────────────────────────────────\n", + " ___________ ___________ \n", + " ╱ γ⋅p_{bg} ╱ γ⋅p_{bg} \n", + " 4⋅ ╱ ───────── 4⋅ ╱ ───────── \n", + " ╲╱ \\rho_{bg} ╲╱ \\rho_{bg} " + ] + }, + "execution_count": 19, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# use positive root (only physical solution)\n", + "Mach_sol = Mach_solve.args[0].args[1].subs(u_L, v_wind).subs(rho_R, rho_bg).subs(p_R, p_bg)\n", + "compute_mach_number = lambdify([v_wind, rho_bg, p_bg, gamma], Mach_sol)\n", + "Eq(M, Mach_sol)" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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", + "text/latex": [ + "$\\displaystyle M = 1.42225795167899$" + ], + "text/plain": [ + "M = 1.42225795167899" + ] + }, + "execution_count": 28, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# numerical example\n", + "\n", + "import numpy as np\n", + "mH = 1.673533e-24 # H mass (g)\n", + "kB = 1.380649e-16 # Boltzmann constant (cgs)\n", + "gamma_bg = 5./3. # assume gamma is constant\n", + "\n", + "v_wind_kms = 200. # km/s\n", + "nH_bg = 1.0e-3 # cm^-3\n", + "rho_bg = nH_bg * mH # mu = 1 for OOM estimate\n", + "P_bg = 1.0e4 # K cm^-3\n", + "\n", + "# compute Mach number of shock\n", + "Mach_shock = compute_mach_number(v_wind_kms * 1.0e5, nH_bg * mH, P_bg * kB, 5./3.)\n", + "Eq(M, Mach_shock)" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAGIAAAARCAYAAAAmE3lhAAAACXBIWXMAAA7EAAAOxAGVKw4bAAADZUlEQVRYCe2Y61EUQRCAD4oAKMgAMlCIQMgANQIkAy3/8Y/CDJAIVDKQDBAykAykyOD8vmV7q3duuZs7C7Wu6Kq5fmz3TE8/ZvZ2ZTwej5YRjo+Pt9jXh3ZvO+A7eeQ3raxDyE5b5hd4m3GK7LZTaIlavdIu+Gn2K8uYCDZsEs7A+0UQ3sPvI79M8mvoE2QXysDrIGXqdcmArtJzjiGYZb86ZLQEMiv8KO+DQNgd94xvIUf2Dnod3CRBObQ68mfyArIqvQftyd8a+2VNxB7h+EkArO4MdoKBt2OE14yJowrZFWMv2dfqYTYIM+2XNREG/JZAWt1DEAkyYd4dJcSR5HOhVu9Be/J3pv2aNm3mbT8vqmv4z8oD4G3nQ/BjGwvV/wLjpxU4BC8U8vyGEckY0gvZRq1eGJS41r5JBMYfMfCN4gD6nNElApkJOgA/tjkeLwbM6TlstcwDBnFuX7AxCR5J8Sa10S46rbhMVq1eO90EqrJfax30TBR8yyhbVdnQOTrC1iB6KZpAL7grZJ/AVYBu70KtMlpcya6+mMc/9Dcrl6vVe2y6TTvCszQC/Qb+pNA22KWsUcHukmGlebHNXaXFOk/G4pud5z6zj2XB5fWjiv1fUauX7TNdZb+Kc01rgg24rZiPJVtZWffeDV2CHTPtean/V3n25dHqWd/9p9AB+GbfkO6vhJDlCz9kWTdkcbnnZw1du44dEWC15IWVe+TodHSMbAkmcKEjhnmf9I5gfv3fBnedAG1xjcAGzwJqeGUJoiOiwGr10hQ9cqZ9ToQOlQHvqh3Hrayv4PtYAtpjSQiHH7jKX+wXSmDN9K1vu+C4nMPM5ETXe2/E5414Ln7J8KUg9lqrl+fI9Ez71aTda692Izs61OpYWeFYmNkN98h7tvHwX2H8sajcvH/e/NTRDWRH8M0+wCbkDtx0PvQIeh3kXXkoLyCr1XO9McPPIR3U2OeOsHLOMbJCvKQMrpXhBzC/0XxhlNB1TH6AvpvZAS/UKXmuBenv2JkMu7iEKKyQxx53Ebhv8St8n1sPmyjKHzF5wlPX+aOPfizsp1srLFq9WRfeZPohreyg5NczmSOQj6Ysn0kT5MH7AbltvvWchJkh7Cnko6n3YBpDkD2q3rY6doRkcxyBTVDvVdGHzzA9Ar8BRWCJ/3OY4W0AAAAASUVORK5CYII=", + "text/latex": [ + "$\\displaystyle u_{L} = 200.0$" + ], + "text/plain": [ + "u_L = 200.0" + ] + }, + "execution_count": 24, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# compute post-shock fluid velocity in km/s\n", + "Eq(u_L, u_L_lambda(Mach_shock, nH_bg * mH, P_bg * kB, 5./3.) / 1.0e5)" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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", + "text/latex": [ + "$\\displaystyle u_{s} = 527.384360142785$" + ], + "text/plain": [ + "uₛ = 527.384360142785" + ] + }, + "execution_count": 26, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# compute shock velocity in km/s\n", + "u_s_lambda = lambdify([M, rho_R, p_R, gamma], u_s)\n", + "Eq(Symbol('u_s'), u_s_lambda(Mach_shock, nH_bg * mH, P_bg * kB, 5./3.) / 1.0e5)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "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.5" + }, + "orig_nbformat": 4 + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/src/ShockCloud/cloud.cpp b/src/ShockCloud/cloud.cpp index 524e5d5c9..3e6c3a277 100644 --- a/src/ShockCloud/cloud.cpp +++ b/src/ShockCloud/cloud.cpp @@ -6,19 +6,30 @@ /// \file cloud.cpp /// \brief Implements a shock-cloud problem with radiative cooling. /// -#include +#include "AMReX.H" +#include "AMReX_Array.H" #include "AMReX_BC_TYPES.H" #include "AMReX_BLassert.H" #include "AMReX_Geometry.H" #include "AMReX_GpuDevice.H" +#include "AMReX_GpuQualifiers.H" #include "AMReX_IntVect.H" +#include "AMReX_MFParallelFor.H" #include "AMReX_MultiFab.H" +#include "AMReX_ParmParse.H" #include "AMReX_REAL.H" -#include "AMReX_TableData.H" +#include "AMReX_Reduce.H" +#include "AMReX_SPACE.H" +#include "EOS.hpp" +#include "NSCBC_inflow.hpp" +#include "NSCBC_outflow.hpp" #include "RadhydroSimulation.hpp" +#include "TabulatedCooling.hpp" +#include "fundamental_constants.H" #include "hydro_system.hpp" +#include "physics_info.hpp" #include "radiation_system.hpp" using amrex::Real; @@ -26,261 +37,761 @@ using amrex::Real; struct ShockCloud { }; // dummy type to allow compile-type polymorphism via template specialization -constexpr double seconds_in_year = 3.154e7; - -template <> struct quokka::EOS_Traits { - static constexpr double gamma = 5. / 3.; // default value - static constexpr double mean_molecular_weight = 1.0; - static constexpr double boltzmann_constant = C::k_B; -}; +constexpr double seconds_in_year = 3.1536e7; // s == 1 yr +constexpr double parsec_in_cm = 3.086e18; // cm == 1 pc +constexpr double solarmass_in_g = 1.99e33; // g == 1 Msun +constexpr double keV_in_ergs = 1.60218e-9; // ergs == 1 keV +constexpr double m_H = C::m_p + C::m_e; // mass of hydrogen atom template <> struct Physics_Traits { - // cell-centred static constexpr bool is_hydro_enabled = true; - static constexpr int numMassScalars = 0; // number of mass scalars - static constexpr int numPassiveScalars = numMassScalars + 0; // number of passive scalars static constexpr bool is_radiation_enabled = false; - // face-centred static constexpr bool is_mhd_enabled = false; + static constexpr int numMassScalars = 0; + static constexpr int numPassiveScalars = numMassScalars + 3; static constexpr int nGroups = 1; // number of radiation groups }; -template <> struct SimulationData { - std::unique_ptr> table_data; +template <> struct quokka::EOS_Traits { + static constexpr double gamma = 5. / 3.; + static constexpr double mean_molecular_weight = C::m_u; + static constexpr double boltzmann_constant = C::k_B; }; -constexpr Real Tgas0 = 1.0e7; // K -constexpr Real nH0 = 1.0e-4; // cm^-3 -constexpr Real nH1 = 1.0e-1; // cm^-3 -constexpr Real R_cloud = 5.0 * 3.086e18; // cm [5 pc] -constexpr Real M0 = 2.0; // Mach number of shock - -constexpr Real P0 = nH0 * Tgas0 * C::k_B; // erg cm^-3 -constexpr Real rho0 = nH0 * (C::m_p + C::m_e); // g cm^-3 -constexpr Real rho1 = nH1 * (C::m_p + C::m_e); - -// perturbation parameters -const int kmin = 0; -const int kmax = 16; -Real const A = 0.05 / kmax; - -template <> void RadhydroSimulation::preCalculateInitialConditions() +// global variables +namespace { - // generate random phases - amrex::Array tlo{kmin, kmin, kmin}; - amrex::Array thi{kmax, kmax, kmax}; - userData_.table_data = std::make_unique>(tlo, thi); - - amrex::TableData h_table_data(tlo, thi, amrex::The_Pinned_Arena()); - auto const &h_table = h_table_data.table(); - - // Initialize data on the hostcd - // 64-bit Mersenne Twister (do not use 32-bit version for sampling doubles!) - std::mt19937_64 rng(1); // NOLINT - std::uniform_real_distribution sample_phase(0., 2.0 * M_PI); - for (int j = tlo[0]; j <= thi[0]; ++j) { - for (int i = tlo[1]; i <= thi[1]; ++i) { - for (int k = tlo[2]; k <= thi[2]; ++k) { - h_table(i, j, k) = sample_phase(rng); - } - } - } - - // Copy data to GPU memory - userData_.table_data->copy(h_table_data); - amrex::Gpu::streamSynchronize(); -} - -template <> void RadhydroSimulation::setInitialConditionsOnGrid(quokka::grid grid_elem) +// Problem properties (set inside problem_main()) +bool sharp_cloud_edge = false; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables) +bool do_frame_shift = true; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables) + +// Cloud parameters (set inside problem_main()) +AMREX_GPU_MANAGED Real rho0 = NAN; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables) +AMREX_GPU_MANAGED Real rho1 = NAN; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables) +AMREX_GPU_MANAGED Real P0 = NAN; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables) +AMREX_GPU_MANAGED Real R_cloud = NAN; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables) +AMREX_GPU_MANAGED Real cloud_relpos_x = 0.5; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables) + +// cloud-tracking variables needed for Dirichlet boundary condition +AMREX_GPU_MANAGED Real shock_crossing_time = 0; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables) +AMREX_GPU_MANAGED Real rho_wind = 0; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables) +AMREX_GPU_MANAGED Real v_wind = 0; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables) +AMREX_GPU_MANAGED Real P_wind = 0; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables) +AMREX_GPU_MANAGED Real delta_vx = 0; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables) +} // namespace + +template <> void RadhydroSimulation::setInitialConditionsOnGrid(quokka::grid grid) { - // set initial conditions - amrex::GpuArray const dx = grid_elem.dx_; - amrex::GpuArray prob_lo = grid_elem.prob_lo_; - amrex::GpuArray prob_hi = grid_elem.prob_hi_; - const amrex::Box &indexRange = grid_elem.indexRange_; - const amrex::Array4 &state_cc = grid_elem.array_; - auto const &phase_table = userData_.table_data->const_table(); - - Real const Lx = (prob_hi[0] - prob_lo[0]); - - Real const x0 = prob_lo[0] + 0.5 * (prob_hi[0] - prob_lo[0]); - Real const y0 = prob_lo[1] + 0.8 * (prob_hi[1] - prob_lo[1]); + amrex::GpuArray const dx = grid.dx_; + amrex::GpuArray prob_lo = grid.prob_lo_; + amrex::GpuArray prob_hi = grid.prob_hi_; + + Real const x0 = prob_lo[0] + cloud_relpos_x * (prob_hi[0] - prob_lo[0]); + Real const y0 = prob_lo[1] + 0.5 * (prob_hi[1] - prob_lo[1]); Real const z0 = prob_lo[2] + 0.5 * (prob_hi[2] - prob_lo[2]); + const bool sharp_cloud_edge = ::sharp_cloud_edge; + + const amrex::Box &indexRange = grid.indexRange_; + auto const &state = grid.array_; + amrex::ParallelFor(indexRange, [=] AMREX_GPU_DEVICE(int i, int j, int k) { Real const x = prob_lo[0] + (i + static_cast(0.5)) * dx[0]; Real const y = prob_lo[1] + (j + static_cast(0.5)) * dx[1]; Real const z = prob_lo[2] + (k + static_cast(0.5)) * dx[2]; Real const R = std::sqrt(std::pow(x - x0, 2) + std::pow(y - y0, 2) + std::pow(z - z0, 2)); - // compute perturbations - Real delta_rho = 0; - for (int ki = kmin; ki < kmax; ++ki) { - for (int kj = kmin; kj < kmax; ++kj) { - for (int kk = kmin; kk < kmax; ++kk) { - if ((ki == 0) && (kj == 0) && (kk == 0)) { - continue; - } - Real const kx = 2.0 * M_PI * static_cast(ki) / Lx; - Real const ky = 2.0 * M_PI * static_cast(kj) / Lx; - Real const kz = 2.0 * M_PI * static_cast(kk) / Lx; - delta_rho += A * std::sin(x * kx + y * ky + z * kz + phase_table(ki, kj, kk)); - } + Real rho = NAN; + Real C = NAN; + + if (sharp_cloud_edge) { + if (R < R_cloud) { + rho = rho1; // cloud density + C = 1.0; // concentration is unity inside the cloud + } else { + rho = rho0; // background density + C = 0.0; // concentration is zero outside the cloud } + } else { + const Real h_smooth = R_cloud / 20.; + const Real ramp = 0.5 * (1. - std::tanh((R - R_cloud) / h_smooth)); + rho = ramp * (rho1 - rho0) + rho0; + C = ramp * 1.0; // concentration is unity inside the cloud } - AMREX_ALWAYS_ASSERT(delta_rho > -1.0); - Real rho = rho0 * (1.0 + delta_rho); // background density - if (R < R_cloud) { - rho = rho1 * (1.0 + delta_rho); // cloud density - } + AMREX_ALWAYS_ASSERT(rho > 0.); + AMREX_ALWAYS_ASSERT(C >= 0.); + AMREX_ALWAYS_ASSERT(C <= 1.); + Real const xmom = 0; Real const ymom = 0; Real const zmom = 0; - Real const Eint = (quokka::EOS_Traits::gamma - 1.) * P0; + Real const Eint = P0 / (quokka::EOS_Traits::gamma - 1.); Real const Egas = RadSystem::ComputeEgasFromEint(rho, xmom, ymom, zmom, Eint); - state_cc(i, j, k, HydroSystem::density_index) = rho; - state_cc(i, j, k, HydroSystem::x1Momentum_index) = xmom; - state_cc(i, j, k, HydroSystem::x2Momentum_index) = ymom; - state_cc(i, j, k, HydroSystem::x3Momentum_index) = zmom; - state_cc(i, j, k, HydroSystem::energy_index) = Egas; - state_cc(i, j, k, HydroSystem::internalEnergy_index) = Eint; + state(i, j, k, RadSystem::gasDensity_index) = rho; + state(i, j, k, RadSystem::x1GasMomentum_index) = xmom; + state(i, j, k, RadSystem::x2GasMomentum_index) = ymom; + state(i, j, k, RadSystem::x3GasMomentum_index) = zmom; + state(i, j, k, RadSystem::gasEnergy_index) = Egas; + state(i, j, k, RadSystem::gasInternalEnergy_index) = Eint; + state(i, j, k, RadSystem::scalar0_index) = C; + state(i, j, k, RadSystem::scalar0_index + 1) = C * rho; // cloud partial density + state(i, j, k, RadSystem::scalar0_index + 2) = (1.0 - C) * rho; // non-cloud partial density }); } template <> AMREX_GPU_DEVICE AMREX_FORCE_INLINE void AMRSimulation::setCustomBoundaryConditions(const amrex::IntVect &iv, amrex::Array4 const &consVar, int /*dcomp*/, int /*numcomp*/, amrex::GeometryData const &geom, - const Real /*time*/, const amrex::BCRec * /*bcr*/, - int /*bcomp*/, int /*orig_comp*/) + const Real time, const amrex::BCRec * /*bcr*/, int /*bcomp*/, + int /*orig_comp*/) { - auto [i, j, k] = iv.dim3(); + auto [i, j, k] = iv.toArray(); amrex::Box const &box = geom.Domain(); + const auto &domain_lo = box.loVect3d(); const auto &domain_hi = box.hiVect3d(); - const int jhi = domain_hi[1]; - - if (j >= jhi) { - // x2 upper boundary -- constant - // compute downstream shock conditions from rho0, P0, and M0 - constexpr Real gamma = quokka::EOS_Traits::gamma; - constexpr Real rho2 = rho0 * (gamma + 1.) * M0 * M0 / ((gamma - 1.) * M0 * M0 + 2.); - constexpr Real P2 = P0 * (2. * gamma * M0 * M0 - (gamma - 1.)) / (gamma + 1.); - Real const v2 = -M0 * std::sqrt(gamma * P2 / rho2); - - Real const rho = rho2; - Real const xmom = 0; - Real const ymom = rho2 * v2; - Real const zmom = 0; - Real const Eint = (gamma - 1.) * P2; - Real const Egas = RadSystem::ComputeEgasFromEint(rho, xmom, ymom, zmom, Eint); - - consVar(i, j, k, HydroSystem::density_index) = rho; - consVar(i, j, k, HydroSystem::x1Momentum_index) = xmom; - consVar(i, j, k, HydroSystem::x2Momentum_index) = ymom; - consVar(i, j, k, HydroSystem::x3Momentum_index) = zmom; - consVar(i, j, k, HydroSystem::energy_index) = Egas; - consVar(i, j, k, HydroSystem::internalEnergy_index) = Eint; + const int ilo = domain_lo[0]; + const int ihi = domain_hi[0]; + + const Real delta_vx = ::delta_vx; + const Real rho_wind = ::rho_wind; + const Real v_wind = ::v_wind; + const Real P_wind = ::P_wind; + + if (i < ilo) { + // x1 lower boundary + Real const rho = rho_wind; + Real const vx = v_wind - delta_vx; + Real const Eint = quokka::EOS::ComputeEintFromPres(rho, P_wind); + Real const T_wind = quokka::EOS::ComputeTgasFromEint(rho, Eint); + amrex::GpuArray::nscalars_> scalars{0, 0, rho}; + + if (time < 0.1 * ::shock_crossing_time) { + // Shock boundary condition [all primitive variables specified] + Real const xmom = rho_wind * vx; + Real const ymom = 0; + Real const zmom = 0; + Real const Egas = RadSystem::ComputeEgasFromEint(rho, xmom, ymom, zmom, Eint); + consVar(i, j, k, RadSystem::gasDensity_index) = rho; + consVar(i, j, k, RadSystem::x1GasMomentum_index) = xmom; + consVar(i, j, k, RadSystem::x2GasMomentum_index) = ymom; + consVar(i, j, k, RadSystem::x3GasMomentum_index) = zmom; + consVar(i, j, k, RadSystem::gasEnergy_index) = Egas; + consVar(i, j, k, RadSystem::gasInternalEnergy_index) = Eint; + consVar(i, j, k, RadSystem::scalar0_index) = scalars[0]; + consVar(i, j, k, RadSystem::scalar0_index + 1) = scalars[1]; // cloud partial density + consVar(i, j, k, RadSystem::scalar0_index + 2) = scalars[2]; // non-cloud partial density + } else { + // Subsonic inflow boundary condition [all *except one* primitive variable specified] + NSCBC::setInflowX1LowerLowOrder(iv, consVar, geom, T_wind, vx, 0, 0, scalars); + } + } else if (i > ihi) { + // x1 upper boundary -- NSCBC subsonic outflow + // (For this boundary condition, we must specify the pressure at the boundary.) + + if (time < 1.1 * ::shock_crossing_time) { + // before the shock hits the boundary, set the boundary pressure to the background pressure P0. + NSCBC::setOutflowBoundaryLowOrder(iv, consVar, geom, ::P0); + } else { + // shock has passed, so we set the boundary pressure to the wind pressure P_wind. + NSCBC::setOutflowBoundaryLowOrder(iv, consVar, geom, P_wind); + } } } -template <> void RadhydroSimulation::ComputeDerivedVar(int lev, std::string const &dname, amrex::MultiFab &mf, const int ncomp_cc_in) const +template <> void RadhydroSimulation::computeAfterTimestep() { - // compute derived variables and save in 'mf' - if (dname == "temperature") { - const int ncomp = ncomp_cc_in; - auto tables = grackleTables_.const_tables(); - - for (amrex::MFIter iter(mf); iter.isValid(); ++iter) { - const amrex::Box &indexRange = iter.fabbox(); // include ghosts - auto const &output = mf.array(iter); - auto const &state = state_new_cc_[lev].const_array(iter); - - amrex::ParallelFor(indexRange, [=] AMREX_GPU_DEVICE(int i, int j, int k) noexcept { - Real const rho = state(i, j, k, HydroSystem::density_index); - Real const x1Mom = state(i, j, k, HydroSystem::x1Momentum_index); - Real const x2Mom = state(i, j, k, HydroSystem::x2Momentum_index); - Real const x3Mom = state(i, j, k, HydroSystem::x3Momentum_index); - Real const Egas = state(i, j, k, HydroSystem::energy_index); - Real const Eint = RadSystem::ComputeEintFromEgas(rho, x1Mom, x2Mom, x3Mom, Egas); - Real const Tgas = quokka::GrackleLikeCooling::ComputeTgasFromEgas(rho, Eint, quokka::EOS_Traits::gamma, tables); - - output(i, j, k, ncomp) = Tgas; + const amrex::Real dt_coarse = dt_[0]; + const amrex::Real time = tNew_[0]; + + // perform Galilean transformation (velocity shift to center-of-mass frame) + if (::do_frame_shift && (time >= ::shock_crossing_time)) { + + // N.B. must weight by passive scalar of cloud, since the background has + // non-negligible momentum! + int const nc = 1; // number of components in temporary MF + int const ng = 0; // number of ghost cells in temporary MF + amrex::MultiFab temp_mf(boxArray(0), DistributionMap(0), nc, ng); + + // compute x-momentum + amrex::MultiFab::Copy(temp_mf, state_new_cc_[0], HydroSystem::x1Momentum_index, 0, nc, ng); + amrex::MultiFab::Multiply(temp_mf, state_new_cc_[0], HydroSystem::scalar0_index, 0, nc, ng); + const Real xmom = temp_mf.sum(0); + + // compute cloud mass within simulation box + amrex::MultiFab::Copy(temp_mf, state_new_cc_[0], HydroSystem::density_index, 0, nc, ng); + amrex::MultiFab::Multiply(temp_mf, state_new_cc_[0], HydroSystem::scalar0_index, 0, nc, ng); + const Real cloud_mass = temp_mf.sum(0); + + // compute center-of-mass velocity of the cloud + const Real vx_cm = xmom / cloud_mass; + + // save cumulative position, velocity offsets in simulationMetadata_ + const Real delta_x_prev = std::get(simulationMetadata_["delta_x"]); + const Real delta_vx_prev = std::get(simulationMetadata_["delta_vx"]); + const Real delta_x = delta_x_prev + dt_coarse * delta_vx_prev; + const Real delta_vx = delta_vx_prev + vx_cm; + simulationMetadata_["delta_x"] = delta_x; + simulationMetadata_["delta_vx"] = delta_vx; + ::delta_vx = delta_vx; + + const Real v_wind = ::v_wind; + amrex::Print() << "[Cloud Tracking] Delta x = " << (delta_x / parsec_in_cm) << " pc," + << " Delta vx = " << (delta_vx / 1.0e5) << " km/s," + << " Inflow velocity = " << ((v_wind - delta_vx) / 1.0e5) << " km/s\n"; + + // If we are moving faster than the wind, we should abort the simulation. + // (otherwise, the boundary conditions become inconsistent.) + AMREX_ALWAYS_ASSERT(delta_vx < v_wind); + + // subtract center-of-mass y-velocity on each level + // N.B. must update both y-momentum *and* energy! + for (int lev = 0; lev <= finest_level; ++lev) { + auto const &mf = state_new_cc_[lev]; + auto const &state = state_new_cc_[lev].arrays(); + amrex::ParallelFor(mf, [=] AMREX_GPU_DEVICE(int box, int i, int j, int k) noexcept { + Real const rho = state[box](i, j, k, HydroSystem::density_index); + Real const xmom = state[box](i, j, k, HydroSystem::x1Momentum_index); + Real const ymom = state[box](i, j, k, HydroSystem::x2Momentum_index); + Real const zmom = state[box](i, j, k, HydroSystem::x3Momentum_index); + Real const E = state[box](i, j, k, HydroSystem::energy_index); + Real const KE = 0.5 * (xmom * xmom + ymom * ymom + zmom * zmom) / rho; + Real const Eint = E - KE; + Real const new_xmom = xmom - rho * vx_cm; + Real const new_KE = 0.5 * (new_xmom * new_xmom + ymom * ymom + zmom * zmom) / rho; + + state[box](i, j, k, HydroSystem::x1Momentum_index) = new_xmom; + state[box](i, j, k, HydroSystem::energy_index) = Eint + new_KE; }); } + amrex::Gpu::streamSynchronizeAll(); } } -template <> void RadhydroSimulation::ErrorEst(int lev, amrex::TagBoxArray &tags, Real /*time*/, int /*ngrow*/) +template <> void RadhydroSimulation::ComputeDerivedVar(int lev, std::string const &dname, amrex::MultiFab &mf, const int ncomp_in) const { - // tag cells for refinement - const Real eta_threshold = 0.1; // gradient refinement threshold - const Real q_min = std::sqrt(rho0 * rho1); // minimum density for refinement + // compute derived variables and save in 'mf' - for (amrex::MFIter mfi(state_new_cc_[lev]); mfi.isValid(); ++mfi) { - const amrex::Box &box = mfi.validbox(); - const auto state = state_new_cc_[lev].const_array(mfi); - const auto tag = tags.array(mfi); - const int nidx = HydroSystem::density_index; + if (dname == "temperature") { + const int ncomp = ncomp_in; + auto tables = cloudyTables_.const_tables(); + auto const &output = mf.arrays(); + auto const &state = state_new_cc_[lev].const_arrays(); + + amrex::ParallelFor(mf, mf.nGrowVect(), [=] AMREX_GPU_DEVICE(int bx, int i, int j, int k) noexcept { + Real const rho = state[bx](i, j, k, HydroSystem::density_index); + Real const x1Mom = state[bx](i, j, k, HydroSystem::x1Momentum_index); + Real const x2Mom = state[bx](i, j, k, HydroSystem::x2Momentum_index); + Real const x3Mom = state[bx](i, j, k, HydroSystem::x3Momentum_index); + Real const Egas = state[bx](i, j, k, HydroSystem::energy_index); + Real const Eint = RadSystem::ComputeEintFromEgas(rho, x1Mom, x2Mom, x3Mom, Egas); + Real const Tgas = ComputeTgasFromEgas(rho, Eint, HydroSystem::gamma_, tables); + output[bx](i, j, k, ncomp) = Tgas; + }); - amrex::ParallelFor(box, [=] AMREX_GPU_DEVICE(int i, int j, int k) noexcept { - Real const q = state(i, j, k, nidx); + } else if (dname == "c_s") { + const int ncomp = ncomp_in; + auto tables = cloudyTables_.const_tables(); + auto const &output = mf.arrays(); + auto const &state = state_new_cc_[lev].const_arrays(); + + amrex::ParallelFor(mf, mf.nGrowVect(), [=] AMREX_GPU_DEVICE(int bx, int i, int j, int k) noexcept { + Real const rho = state[bx](i, j, k, HydroSystem::density_index); + Real const x1Mom = state[bx](i, j, k, HydroSystem::x1Momentum_index); + Real const x2Mom = state[bx](i, j, k, HydroSystem::x2Momentum_index); + Real const x3Mom = state[bx](i, j, k, HydroSystem::x3Momentum_index); + Real const Egas = state[bx](i, j, k, HydroSystem::energy_index); + Real const Eint = RadSystem::ComputeEintFromEgas(rho, x1Mom, x2Mom, x3Mom, Egas); + Real const Tgas = quokka::TabulatedCooling::ComputeTgasFromEgas(rho, Eint, HydroSystem::gamma_, tables); + Real const mu = quokka::TabulatedCooling::ComputeMMW(rho, Eint, HydroSystem::gamma_, tables); + Real const cs = std::sqrt(HydroSystem::gamma_ * C::k_B * Tgas / (mu * m_H)); + output[bx](i, j, k, ncomp) = cs / 1.0e5; // km/s + }); - Real const q_xplus = state(i + 1, j, k, nidx); - Real const q_xminus = state(i - 1, j, k, nidx); - Real const q_yplus = state(i, j + 1, k, nidx); - Real const q_yminus = state(i, j - 1, k, nidx); - Real const q_zplus = state(i, j, k + 1, nidx); - Real const q_zminus = state(i, j, k - 1, nidx); + } else if (dname == "nH") { + const int ncomp = ncomp_in; + auto const &output = mf.arrays(); + auto const &state = state_new_cc_[lev].const_arrays(); - Real const del_x = std::max(std::abs(q_xplus - q), std::abs(q - q_xminus)); - Real const del_y = std::max(std::abs(q_yplus - q), std::abs(q - q_yminus)); - Real const del_z = std::max(std::abs(q_zplus - q), std::abs(q - q_zminus)); + amrex::ParallelFor(mf, mf.nGrowVect(), [=] AMREX_GPU_DEVICE(int bx, int i, int j, int k) noexcept { + Real const rho = state[bx](i, j, k, HydroSystem::density_index); + Real const nH = (quokka::TabulatedCooling::cloudy_H_mass_fraction * rho) / m_H; + output[bx](i, j, k, ncomp) = nH; + }); - Real const gradient_indicator = std::max({del_x, del_y, del_z}) / q; + } else if (dname == "pressure") { + const int ncomp = ncomp_in; + auto tables = cloudyTables_.const_tables(); + auto const &output = mf.arrays(); + auto const &state = state_new_cc_[lev].const_arrays(); + + amrex::ParallelFor(mf, mf.nGrowVect(), [=] AMREX_GPU_DEVICE(int bx, int i, int j, int k) noexcept { + Real const rho = state[bx](i, j, k, HydroSystem::density_index); + Real const x1Mom = state[bx](i, j, k, HydroSystem::x1Momentum_index); + Real const x2Mom = state[bx](i, j, k, HydroSystem::x2Momentum_index); + Real const x3Mom = state[bx](i, j, k, HydroSystem::x3Momentum_index); + Real const Egas = state[bx](i, j, k, HydroSystem::energy_index); + Real const Eint = RadSystem::ComputeEintFromEgas(rho, x1Mom, x2Mom, x3Mom, Egas); + Real const Tgas = ComputeTgasFromEgas(rho, Eint, HydroSystem::gamma_, tables); + Real const mu = ComputeMMW(rho, Egas, HydroSystem::gamma_, tables); + Real const ndens = rho / (mu * m_H); + output[bx](i, j, k, ncomp) = ndens * Tgas; // [K cm^-3] + }); - if ((gradient_indicator > eta_threshold) && (q > q_min)) { - tag(i, j, k) = amrex::TagBox::SET; - } + } else if (dname == "entropy") { + const int ncomp = ncomp_in; + auto tables = cloudyTables_.const_tables(); + auto const &output = mf.arrays(); + auto const &state = state_new_cc_[lev].const_arrays(); + + amrex::ParallelFor(mf, mf.nGrowVect(), [=] AMREX_GPU_DEVICE(int bx, int i, int j, int k) noexcept { + Real const rho = state[bx](i, j, k, HydroSystem::density_index); + Real const x1Mom = state[bx](i, j, k, HydroSystem::x1Momentum_index); + Real const x2Mom = state[bx](i, j, k, HydroSystem::x2Momentum_index); + Real const x3Mom = state[bx](i, j, k, HydroSystem::x3Momentum_index); + Real const Egas = state[bx](i, j, k, HydroSystem::energy_index); + Real const Eint = RadSystem::ComputeEintFromEgas(rho, x1Mom, x2Mom, x3Mom, Egas); + Real const Tgas = ComputeTgasFromEgas(rho, Eint, HydroSystem::gamma_, tables); + Real const mu = ComputeMMW(rho, Egas, HydroSystem::gamma_, tables); + Real const ndens = rho / (mu * m_H); + Real const K_cgs = C::k_B * Tgas * std::pow(ndens, -2. / 3.); // ergs cm^2 + Real const K_keV_cm2 = K_cgs / keV_in_ergs; // convert to units of keV cm^2 + output[bx](i, j, k, ncomp) = K_keV_cm2; + }); + + } else if (dname == "mass") { + const int ncomp = ncomp_in; + auto const &output = mf.arrays(); + auto const &state = state_new_cc_[lev].const_arrays(); + auto const dx = geom[lev].CellSizeArray(); + const Real dvol = dx[0] * dx[1] * dx[2]; + + amrex::ParallelFor(mf, mf.nGrowVect(), [=] AMREX_GPU_DEVICE(int bx, int i, int j, int k) noexcept { + Real const rho = state[bx](i, j, k, HydroSystem::density_index); + output[bx](i, j, k, ncomp) = rho * dvol; + }); + + } else if (dname == "cloud_fraction") { + const int ncomp = ncomp_in; + auto const &output = mf.arrays(); + auto const &state = state_new_cc_[lev].const_arrays(); + + amrex::ParallelFor(mf, mf.nGrowVect(), [=] AMREX_GPU_DEVICE(int bx, int i, int j, int k) noexcept { + // cloud partial density + Real const rho_cloud = state[bx](i, j, k, HydroSystem::scalar0_index + 1); + // non-cloud partial density + Real const rho_bg = state[bx](i, j, k, HydroSystem::scalar0_index + 2); + + // NOTE: rho_cloud + rho_bg only equals hydro rho up to truncation error! + output[bx](i, j, k, ncomp) = rho_cloud / (rho_cloud + rho_bg); + }); + + } else if (dname == "cooling_length") { + const int ncomp = ncomp_in; + auto tables = cloudyTables_.const_tables(); + auto const &output = mf.arrays(); + auto const &state = state_new_cc_[lev].const_arrays(); + + amrex::ParallelFor(mf, mf.nGrowVect(), [=] AMREX_GPU_DEVICE(int bx, int i, int j, int k) noexcept { + // compute cooling length in parsec + Real const rho = state[bx](i, j, k, HydroSystem::density_index); + Real const x1Mom = state[bx](i, j, k, HydroSystem::x1Momentum_index); + Real const x2Mom = state[bx](i, j, k, HydroSystem::x2Momentum_index); + Real const x3Mom = state[bx](i, j, k, HydroSystem::x3Momentum_index); + Real const Egas = state[bx](i, j, k, HydroSystem::energy_index); + Real const Eint = RadSystem::ComputeEintFromEgas(rho, x1Mom, x2Mom, x3Mom, Egas); + Real const l_cool = ComputeCoolingLength(rho, Eint, HydroSystem::gamma_, tables); + output[bx](i, j, k, ncomp) = l_cool / parsec_in_cm; + }); + + } else if (dname == "lab_velocity_x") { + const int ncomp = ncomp_in; + auto const &output = mf.arrays(); + auto const &state = state_new_cc_[lev].const_arrays(); + const Real delta_vx = ::delta_vx; + + amrex::ParallelFor(mf, mf.nGrowVect(), [=] AMREX_GPU_DEVICE(int bx, int i, int j, int k) noexcept { + // compute observer velocity in km/s + Real const rho = state[bx](i, j, k, HydroSystem::density_index); + Real const x1Mom = state[bx](i, j, k, HydroSystem::x1Momentum_index); + Real const vx = x1Mom / rho; + Real const vx_lab = vx + delta_vx; + output[bx](i, j, k, ncomp) = vx_lab / 1.0e5; // km/s + }); + + } else if (dname == "velocity_mag") { + const int ncomp = ncomp_in; + auto const &output = mf.arrays(); + auto const &state = state_new_cc_[lev].const_arrays(); + + amrex::ParallelFor(mf, mf.nGrowVect(), [=] AMREX_GPU_DEVICE(int bx, int i, int j, int k) noexcept { + // compute simulation-frame |v| in km/s + Real const rho = state[bx](i, j, k, HydroSystem::density_index); + Real const x1Mom = state[bx](i, j, k, HydroSystem::x1Momentum_index); + Real const x2Mom = state[bx](i, j, k, HydroSystem::x2Momentum_index); + Real const x3Mom = state[bx](i, j, k, HydroSystem::x3Momentum_index); + Real const v1 = x1Mom / rho; + Real const v2 = x2Mom / rho; + Real const v3 = x3Mom / rho; + output[bx](i, j, k, ncomp) = std::sqrt(v1 * v1 + v2 * v2 + v3 * v3) / 1.0e5; // km/s }); } + amrex::Gpu::streamSynchronizeAll(); } -auto problem_main() -> int +AMREX_GPU_DEVICE AMREX_FORCE_INLINE auto ComputeCellTemp(int i, int j, int k, amrex::Array4 const &state, amrex::Real gamma, + quokka::TabulatedCooling::cloudyGpuConstTables const &tables) { - // Problem parameters - const double CFL_number = 0.25; - const double max_time = 2.0e6 * seconds_in_year; // 2 Myr - const int max_timesteps = 1e5; + // return cell temperature + Real const rho = state(i, j, k, HydroSystem::density_index); + Real const x1Mom = state(i, j, k, HydroSystem::x1Momentum_index); + Real const x2Mom = state(i, j, k, HydroSystem::x2Momentum_index); + Real const x3Mom = state(i, j, k, HydroSystem::x3Momentum_index); + Real const Egas = state(i, j, k, HydroSystem::energy_index); + Real const Eint = RadSystem::ComputeEintFromEgas(rho, x1Mom, x2Mom, x3Mom, Egas); + return quokka::TabulatedCooling::ComputeTgasFromEgas(rho, Eint, gamma, tables); +} - // Problem initialization - constexpr int ncomp_cc = Physics_Indices::nvarTotal_cc; - amrex::Vector BCs_cc(ncomp_cc); - for (int n = 0; n < ncomp_cc; ++n) { - BCs_cc[n].setLo(0, amrex::BCType::int_dir); // periodic - BCs_cc[n].setHi(0, amrex::BCType::int_dir); +template <> auto RadhydroSimulation::ComputeStatistics() -> std::map +{ + // compute scalar statistics + std::map stats; + + // save time + const Real t_cc = std::get(simulationMetadata_["t_cc"]); + const Real time = tNew_[0]; + stats["t_over_tcc"] = time / t_cc; + + // save cloud position, velocity + const Real dx_cgs = std::get(simulationMetadata_["delta_x"]); + const Real dvx_cgs = std::get(simulationMetadata_["delta_vx"]); + const Real v_wind = ::v_wind; + + stats["delta_x"] = dx_cgs / parsec_in_cm; // pc + stats["delta_vx"] = dvx_cgs / 1.0e5; // km/s + stats["inflow_vx"] = (v_wind - dvx_cgs) / 1.0e5; // km/s + + // save total simulation mass + const Real sim_mass = amrex::volumeWeightedSum(amrex::GetVecOfConstPtrs(state_new_cc_), HydroSystem::density_index, geom, ref_ratio); + const Real sim_partialcloud_mass = + amrex::volumeWeightedSum(amrex::GetVecOfConstPtrs(state_new_cc_), HydroSystem::scalar0_index + 1, geom, ref_ratio); + const Real sim_partialwind_mass = + amrex::volumeWeightedSum(amrex::GetVecOfConstPtrs(state_new_cc_), HydroSystem::scalar0_index + 2, geom, ref_ratio); + + stats["sim_mass"] = sim_mass / solarmass_in_g; + stats["sim_partialcloud_mass"] = sim_partialcloud_mass / solarmass_in_g; + stats["sim_partialwind_mass"] = sim_partialwind_mass / solarmass_in_g; + + // compute cloud mass according to temperature threshold + auto tables = cloudyTables_.const_tables(); + + const Real M_cl_1e4 = computeVolumeIntegral([=] AMREX_GPU_DEVICE(int i, int j, int k, amrex::Array4 const &state) noexcept { + Real const T = ComputeCellTemp(i, j, k, state, HydroSystem::gamma_, tables); + Real const rho = state(i, j, k, HydroSystem::density_index); + Real const result = (T < 1.0e4) ? rho : 0.0; + return result; + }); + const Real M_cl_8000 = computeVolumeIntegral([=] AMREX_GPU_DEVICE(int i, int j, int k, amrex::Array4 const &state) noexcept { + Real const T = ComputeCellTemp(i, j, k, state, HydroSystem::gamma_, tables); + Real const rho = state(i, j, k, HydroSystem::density_index); + Real const result = (T < 8000.) ? rho : 0.0; + return result; + }); + const Real M_cl_9000 = computeVolumeIntegral([=] AMREX_GPU_DEVICE(int i, int j, int k, amrex::Array4 const &state) noexcept { + Real const T = ComputeCellTemp(i, j, k, state, HydroSystem::gamma_, tables); + Real const rho = state(i, j, k, HydroSystem::density_index); + Real const result = (T < 9000.) ? rho : 0.0; + return result; + }); + const Real M_cl_11000 = computeVolumeIntegral([=] AMREX_GPU_DEVICE(int i, int j, int k, amrex::Array4 const &state) noexcept { + Real const T = ComputeCellTemp(i, j, k, state, HydroSystem::gamma_, tables); + Real const rho = state(i, j, k, HydroSystem::density_index); + Real const result = (T < 1.1e4) ? rho : 0.0; + return result; + }); + const Real M_cl_12000 = computeVolumeIntegral([=] AMREX_GPU_DEVICE(int i, int j, int k, amrex::Array4 const &state) noexcept { + Real const T = ComputeCellTemp(i, j, k, state, HydroSystem::gamma_, tables); + Real const rho = state(i, j, k, HydroSystem::density_index); + Real const result = (T < 1.2e4) ? rho : 0.0; + return result; + }); - BCs_cc[n].setLo(1, amrex::BCType::foextrap); // extrapolate - BCs_cc[n].setHi(1, amrex::BCType::ext_dir); // Dirichlet + stats["cloud_mass_1e4"] = M_cl_1e4 / solarmass_in_g; + stats["cloud_mass_8000"] = M_cl_8000 / solarmass_in_g; + stats["cloud_mass_9000"] = M_cl_9000 / solarmass_in_g; + stats["cloud_mass_11000"] = M_cl_11000 / solarmass_in_g; + stats["cloud_mass_12000"] = M_cl_12000 / solarmass_in_g; + + const Real origM_cl_1e4 = computeVolumeIntegral([=] AMREX_GPU_DEVICE(int i, int j, int k, amrex::Array4 const &state) noexcept { + Real const T = ComputeCellTemp(i, j, k, state, HydroSystem::gamma_, tables); + Real const rho_cloud = state(i, j, k, HydroSystem::scalar0_index + 1); + Real const result = (T < 1.0e4) ? rho_cloud : 0.0; + return result; + }); + const Real origM_cl_8000 = computeVolumeIntegral([=] AMREX_GPU_DEVICE(int i, int j, int k, amrex::Array4 const &state) noexcept { + Real const T = ComputeCellTemp(i, j, k, state, HydroSystem::gamma_, tables); + Real const rho_cloud = state(i, j, k, HydroSystem::scalar0_index + 1); + Real const result = (T < 8000.) ? rho_cloud : 0.0; + return result; + }); + const Real origM_cl_9000 = computeVolumeIntegral([=] AMREX_GPU_DEVICE(int i, int j, int k, amrex::Array4 const &state) noexcept { + Real const T = ComputeCellTemp(i, j, k, state, HydroSystem::gamma_, tables); + Real const rho_cloud = state(i, j, k, HydroSystem::scalar0_index + 1); + Real const result = (T < 9000.) ? rho_cloud : 0.0; + return result; + }); + const Real origM_cl_11000 = computeVolumeIntegral([=] AMREX_GPU_DEVICE(int i, int j, int k, amrex::Array4 const &state) noexcept { + Real const T = ComputeCellTemp(i, j, k, state, HydroSystem::gamma_, tables); + Real const rho_cloud = state(i, j, k, HydroSystem::scalar0_index + 1); + Real const result = (T < 1.1e4) ? rho_cloud : 0.0; + return result; + }); + const Real origM_cl_12000 = computeVolumeIntegral([=] AMREX_GPU_DEVICE(int i, int j, int k, amrex::Array4 const &state) noexcept { + Real const T = ComputeCellTemp(i, j, k, state, HydroSystem::gamma_, tables); + Real const rho_cloud = state(i, j, k, HydroSystem::scalar0_index + 1); + Real const result = (T < 1.2e4) ? rho_cloud : 0.0; + return result; + }); - BCs_cc[n].setLo(2, amrex::BCType::int_dir); - BCs_cc[n].setHi(2, amrex::BCType::int_dir); - } + stats["cloud_mass_1e4_original"] = origM_cl_1e4 / solarmass_in_g; + stats["cloud_mass_8000_original"] = origM_cl_8000 / solarmass_in_g; + stats["cloud_mass_9000_original"] = origM_cl_9000 / solarmass_in_g; + stats["cloud_mass_11000_original"] = origM_cl_11000 / solarmass_in_g; + stats["cloud_mass_12000_original"] = origM_cl_12000 / solarmass_in_g; + + // compute cloud mass according to passive scalar threshold + const Real M_cl_scalar_01 = computeVolumeIntegral([=] AMREX_GPU_DEVICE(int i, int j, int k, amrex::Array4 const &state) noexcept { + Real const C = state(i, j, k, HydroSystem::scalar0_index); + Real const rho = state(i, j, k, HydroSystem::density_index); + Real const result = (C > 0.1) ? rho : 0.0; + return result; + }); + const Real M_cl_scalar_01_09 = computeVolumeIntegral([=] AMREX_GPU_DEVICE(int i, int j, int k, amrex::Array4 const &state) noexcept { + Real const C = state(i, j, k, HydroSystem::scalar0_index); + Real const rho = state(i, j, k, HydroSystem::density_index); + Real const result = ((C > 0.1) && (C < 0.9)) ? rho : 0.0; + return result; + }); - RadhydroSimulation sim(BCs_cc); + stats["cloud_mass_scalar_01"] = M_cl_scalar_01 / solarmass_in_g; + stats["cloud_mass_scalar_01_09"] = M_cl_scalar_01_09 / solarmass_in_g; - // Standard PPM gives unphysically enormous temperatures when used for - // this problem (e.g., ~1e14 K or higher), but can be fixed by - // reconstructing the temperature instead of the pressure - sim.reconstructionOrder_ = 3; // PLM - sim.densityFloor_ = 1.0e-2 * rho0; // density floor (to prevent vacuum) + // compute cloud mass according to cloud fraction threshold + const Real M_cl_fraction_01 = computeVolumeIntegral([=] AMREX_GPU_DEVICE(int i, int j, int k, amrex::Array4 const &state) noexcept { + Real const rho_cloud = state(i, j, k, HydroSystem::scalar0_index + 1); + Real const rho_bg = state(i, j, k, HydroSystem::scalar0_index + 2); + Real const C_frac = rho_cloud / (rho_cloud + rho_bg); - sim.cflNumber_ = CFL_number; - sim.maxTimesteps_ = max_timesteps; + Real const rho = state(i, j, k, HydroSystem::density_index); + Real const result = (C_frac > 0.1) ? rho : 0.0; + return result; + }); + const Real M_cl_fraction_01_09 = computeVolumeIntegral([=] AMREX_GPU_DEVICE(int i, int j, int k, amrex::Array4 const &state) noexcept { + Real const rho_cloud = state(i, j, k, HydroSystem::scalar0_index + 1); + Real const rho_bg = state(i, j, k, HydroSystem::scalar0_index + 2); + Real const C_frac = rho_cloud / (rho_cloud + rho_bg); + + Real const rho = state(i, j, k, HydroSystem::density_index); + Real const result = ((C_frac > 0.1) && (C_frac < 0.9)) ? rho : 0.0; + return result; + }); + + stats["cloud_mass_fraction_01"] = M_cl_fraction_01 / solarmass_in_g; + stats["cloud_mass_fraction_01_09"] = M_cl_fraction_01_09 / solarmass_in_g; + + return stats; +} + +template <> auto RadhydroSimulation::ComputeProjections(const int dir) const -> std::unordered_map> +{ + std::unordered_map> proj; + + // compute (total) density projection + proj["nH"] = computePlaneProjection( + [=] AMREX_GPU_DEVICE(int i, int j, int k, amrex::Array4 const &state) noexcept { + Real const rho = state(i, j, k, HydroSystem::density_index); + return (quokka::TabulatedCooling::cloudy_H_mass_fraction * rho) / m_H; + }, + dir); + + // compute cloud partial density projection + proj["nH_cloud"] = computePlaneProjection( + [=] AMREX_GPU_DEVICE(int i, int j, int k, amrex::Array4 const &state) noexcept { + // partial cloud density + Real const rho_cloud = state(i, j, k, HydroSystem::scalar0_index + 1); + return (quokka::TabulatedCooling::cloudy_H_mass_fraction * rho_cloud) / m_H; + }, + dir); + + // compute non-cloud partial density projection + proj["nH_wind"] = computePlaneProjection( + [=] AMREX_GPU_DEVICE(int i, int j, int k, amrex::Array4 const &state) noexcept { + // partial wind density + Real const rho_wind = state(i, j, k, HydroSystem::scalar0_index + 2); + return (quokka::TabulatedCooling::cloudy_H_mass_fraction * rho_wind) / m_H; + }, + dir); + + return proj; +} + +template <> void RadhydroSimulation::ErrorEst(int lev, amrex::TagBoxArray &tags, Real /*time*/, int /*ngrow*/) +{ + // tag cells for refinement + const int Ncells_per_lcool = 10; + + amrex::GpuArray dx = geom[lev].CellSizeArray(); + const Real min_dx = std::min({AMREX_D_DECL(dx[0], dx[1], dx[2])}); + const Real resolved_length = static_cast(Ncells_per_lcool) * min_dx; + + auto tables = cloudyTables_.const_tables(); + const auto state = state_new_cc_[lev].const_arrays(); + const auto tag = tags.arrays(); + + amrex::ParallelFor(state_new_cc_[lev], [=] AMREX_GPU_DEVICE(int bx, int i, int j, int k) noexcept { + Real const rho = state[bx](i, j, k, HydroSystem::density_index); + Real const x1Mom = state[bx](i, j, k, HydroSystem::x1Momentum_index); + Real const x2Mom = state[bx](i, j, k, HydroSystem::x2Momentum_index); + Real const x3Mom = state[bx](i, j, k, HydroSystem::x3Momentum_index); + Real const Egas = state[bx](i, j, k, HydroSystem::energy_index); + Real const Eint = RadSystem::ComputeEintFromEgas(rho, x1Mom, x2Mom, x3Mom, Egas); + Real const l_cool = ComputeCoolingLength(rho, Eint, HydroSystem::gamma_, tables); + + if (l_cool < resolved_length) { + tag[bx](i, j, k) = amrex::TagBox::SET; + } + }); + amrex::Gpu::streamSynchronize(); +} + +auto problem_main() -> int +{ + // Problem initialization + constexpr int nvars = RadhydroSimulation::nvarTotal_cc_; + amrex::Vector boundaryConditions(nvars); + for (int n = 0; n < nvars; ++n) { + boundaryConditions[n].setLo(0, amrex::BCType::ext_dir); // Dirichlet + boundaryConditions[n].setHi(0, amrex::BCType::ext_dir); // NSCBC outflow + + boundaryConditions[n].setLo(1, amrex::BCType::int_dir); // periodic + boundaryConditions[n].setHi(1, amrex::BCType::int_dir); + + boundaryConditions[n].setLo(2, amrex::BCType::int_dir); + boundaryConditions[n].setHi(2, amrex::BCType::int_dir); + } + RadhydroSimulation sim(boundaryConditions); + + // Read problem parameters + amrex::ParmParse const pp; + Real nH_bg = NAN; + Real nH_cloud = NAN; + Real P_over_k = NAN; + Real M0 = NAN; + Real max_t_cc = NAN; + + // use a sharp cloud edge? + int sharp_cloud_edge = 0; + pp.query("sharp_cloud_edge", sharp_cloud_edge); + ::sharp_cloud_edge = sharp_cloud_edge == 1; + + // do frame shifting to follow cloud center-of-mass? + int do_frame_shift = 1; + pp.query("do_frame_shift", do_frame_shift); + ::do_frame_shift = do_frame_shift == 1; + + // background gas H number density + pp.query("nH_bg", nH_bg); // cm^-3 + + // cloud H number density + pp.query("nH_cloud", nH_cloud); // cm^-3 + + // background gas pressure + pp.query("P_over_k", P_over_k); // K cm^-3 + + // cloud radius + pp.query("R_cloud_pc", ::R_cloud); // pc + ::R_cloud *= parsec_in_cm; // convert to cm + + // cloud position (relative to box length) + pp.query("cloud_relpos_x", ::cloud_relpos_x); // dimensionless + + // (pre-shock) Mach number + pp.query("Mach_shock", M0); // dimensionless + + // simulation end time (in number of cloud-crushing times) + pp.query("max_t_cc", max_t_cc); // dimensionless + + // compute background pressure + // (pressure equilibrium should hold *before* the shock enters the box) + ::P0 = P_over_k * C::k_B; // erg cm^-3 + amrex::Print() << fmt::format("Pressure = {} K cm^-3\n", P_over_k); + + // compute mass density of background, cloud + ::rho0 = nH_bg * m_H / quokka::TabulatedCooling::cloudy_H_mass_fraction; // g cm^-3 + ::rho1 = nH_cloud * m_H / quokka::TabulatedCooling::cloudy_H_mass_fraction; // g cm^-3 + + AMREX_ALWAYS_ASSERT(!std::isnan(::rho0)); + AMREX_ALWAYS_ASSERT(!std::isnan(::rho1)); + AMREX_ALWAYS_ASSERT(!std::isnan(::P0)); + + // check temperature of cloud, background + constexpr Real gamma = HydroSystem::gamma_; + auto tables = sim.cloudyTables_.const_tables(); + const Real Eint_bg = ::P0 / (gamma - 1.); + const Real Eint_cl = ::P0 / (gamma - 1.); + const Real T_bg = ComputeTgasFromEgas(rho0, Eint_bg, gamma, tables); + const Real T_cl = ComputeTgasFromEgas(rho1, Eint_cl, gamma, tables); + amrex::Print() << fmt::format("T_bg = {} K\n", T_bg); + amrex::Print() << fmt::format("T_cl = {} K\n", T_cl); + + // compute shock jump conditions from rho0, P0, and M0 + const Real x0 = M0 * M0; + const Real x1 = gamma + 1; + const Real x2 = gamma * x0; + const Real x3 = 1.0 / x1; + const Real x4 = std::sqrt(gamma * ::P0 / ::rho0); + const Real rho_post = ::rho0 * x0 * x1 / (-x0 + x2 + 2); + const Real v_wind = 2 * x3 * x4 * (x0 - 1) / M0; + const Real P_post = ::P0 * x3 * (-gamma + 2 * x2 + 1); + const Real v_shock = M0 * x4; + + const Real Eint_post = P_post / (gamma - 1.); + const Real T_post = ComputeTgasFromEgas(rho_post, Eint_post, gamma, tables); + amrex::Print() << fmt::format("T_wind = {} K\n", T_post); + + ::v_wind = v_wind; // set global variables + ::rho_wind = rho_post; + ::P_wind = P_post; + amrex::Print() << fmt::format("v_wind = {} km/s\n", v_wind / 1.0e5); + amrex::Print() << fmt::format("P_wind = {} K cm^-3\n", P_post / C::k_B); + amrex::Print() << fmt::format("v_shock = {} km/s\n", v_shock / 1.0e5); + + // compute shock-crossing time + ::shock_crossing_time = sim.geom[0].ProbLength(0) / v_shock; + amrex::Print() << fmt::format("shock crossing time = {} Myr\n", ::shock_crossing_time / (1.0e6 * seconds_in_year)); + + // compute cloud-crushing time + const Real chi = rho1 / rho0; + const Real t_cc = std::sqrt(chi) * R_cloud / v_shock; + amrex::Print() << fmt::format("t_cc = {} Myr\n", t_cc / (1.0e6 * seconds_in_year)) << "\n"; + + // compute maximum simulation time + const double max_time = max_t_cc * t_cc; + + // set simulation parameters sim.stopTime_ = max_time; - sim.plotfileInterval_ = 100; - sim.checkpointInterval_ = 2000; + sim.pressureFloor_ = 1.0e-3 * ::P0; // set pressure floor + + // set metadata + sim.simulationMetadata_["delta_x"] = 0._rt; + sim.simulationMetadata_["delta_vx"] = 0._rt; + sim.simulationMetadata_["rho_wind"] = rho_wind; + sim.simulationMetadata_["v_wind"] = v_wind; + sim.simulationMetadata_["P_wind"] = P_wind; + sim.simulationMetadata_["M0"] = M0; + sim.simulationMetadata_["t_cc"] = t_cc; // Set initial conditions sim.setInitialConditions(); diff --git a/src/ShockCloud/test_grackle_cooling.cpp b/src/ShockCloud/test_grackle_cooling.cpp deleted file mode 100644 index 3fc20a992..000000000 --- a/src/ShockCloud/test_grackle_cooling.cpp +++ /dev/null @@ -1,109 +0,0 @@ -//============================================================================== -// TwoMomentRad - a radiation transport library for patch-based AMR codes -// Copyright 2020 Benjamin Wibking. -// Released under the MIT license. See LICENSE file included in the GitHub repo. -//============================================================================== -/// \file cloud.cpp -/// \brief Implements a shock-cloud problem with radiative cooling. -/// - -// uncomment this to debug the root-finding code (does NOT work on GPU!) -// #define BOOST_MATH_INSTRUMENT - -#include "AMReX_ParmParse.H" -#include "EOS.hpp" -#include "GrackleLikeCooling.hpp" -#include "ODEIntegrate.hpp" - -using amrex::Real; -using namespace quokka::GrackleLikeCooling; - -struct ShockCloud { -}; // dummy type to allow compile-type polymorphism via template specialization - -template <> struct quokka::EOS_Traits { - static constexpr double gamma = 5. / 3.; // default value -}; - -auto problem_main() -> int -{ - // Problem parameters - const Real rho = 2.27766918428822386e-22; // g cm^-3; - const Real Eint = 1.11777608454088878e-11; // erg cm^-3 - const Real dt = 1.92399749834457487e8; // s - - // Read Cloudy tables - grackle_tables cloudyTables; - std::string filename; - amrex::ParmParse pp("cooling"); - pp.query("grackle_data_file", filename); - readGrackleData(filename, cloudyTables); - auto tables = cloudyTables.const_tables(); - - const Real T = ComputeTgasFromEgas(rho, Eint, quokka::EOS_Traits::gamma, tables); - - const Real rhoH = rho * cloudy_H_mass_fraction; - const Real nH = rhoH / (C::m_p + C::m_e); - const Real log_nH = std::log10(nH); - - const Real C = (quokka::EOS_Traits::gamma - 1.) * Eint / (C::k_B * (rho / (C::m_p + C::m_e))); - const Real mu = interpolate2d(log_nH, std::log10(T), tables.log_nH, tables.log_Tgas, tables.meanMolWeight); - const Real relerr = std::abs((C * mu - T) / T); - - const Real n_e = (rho / (C::m_p + C::m_e)) * (1.0 - mu * (X + Y / 4. + Z / mean_metals_A)) / (mu - (electron_mass_cgs / (C::m_p + C::m_e))); - - printf("\nrho = %.17e, Eint = %.17e, mu = %f, Tgas = %e, relerr = %e\n", rho, Eint, mu, T, relerr); - printf("n_e = %e, n_e/n_H = %e\n", n_e, n_e / nH); - - const Real reltol_floor = 0.01; - const Real rtol = 1.0e-4; // not recommended to change this - constexpr Real T_floor = 100.0; // K - const Real gamma = quokka::EOS_Traits::gamma; - - ODEUserData user_data{rho, gamma, tables}; - quokka::valarray y = {Eint}; - quokka::valarray abstol = {reltol_floor * ComputeEgasFromTgas(rho, T_floor, gamma, tables)}; - - // do integration with RK2 (Heun's method) - int nsteps = 0; - rk_adaptive_integrate(user_rhs, 0, y, dt, &user_data, rtol, abstol, nsteps); - - // check if integration failed - if (nsteps >= maxStepsODEIntegrate) { - Real T = ComputeTgasFromEgas(rho, Eint, quokka::EOS_Traits::gamma, tables); - Real Edot = cloudy_cooling_function(rho, T, tables); - Real t_cool = Eint / Edot; - printf("max substeps exceeded! rho = %g, Eint = %g, T = %g, cooling " - "time = %g\n", - rho, Eint, T, t_cool); - } else { - Real T = ComputeTgasFromEgas(rho, Eint, quokka::EOS_Traits::gamma, tables); - Real Edot = cloudy_cooling_function(rho, T, tables); - Real t_cool = Eint / Edot; - printf("success! rho = %g, Eint = %g, T = %g, cooling time = %g\n", rho, Eint, T, t_cool); - } - -#if 0 - // compute Field length - auto lambda_F = [=] (Real nH0, Real T0) { - const Real rho0 = nH0 * hydrogen_mass_cgs_ / cloudy_H_mass_fraction; // g cm^-3 - const Real Edot = cloudy_cooling_function(rho0, T0, tables); - const Real ln_L = 29.7 + std::log(std::pow(nH0, -1./2.) * (T0 / 1.0e6)); - const Real conductivity = 1.84e-5 * std::pow(T0, 5./2.) / ln_L; - const Real l = std::sqrt( conductivity * T0 / std::abs(Edot) ); - return std::make_pair(Edot, l); - }; - - auto [Edot0, l0] = lambda_F(1.0, 4.0e5); - amrex::Print() << "Edot(nH = 1.0, T = 4e5) = " << Edot0 << "\n"; - amrex::Print() << "lambda_F = " << (l0 / 3.086e18) << " pc\n\n"; - - auto [Edot1, l1] = lambda_F(0.1, 4.0e5); - amrex::Print() << "Edot(nH = 0.1, T = 4e5) = " << Edot1 << "\n"; - amrex::Print() << "lambda_F = " << (l1 / 3.086e18) << " pc\n\n"; -#endif - - // Cleanup and exit - int status = 0; - return status; -} diff --git a/tests/ShockCloud_128.in b/tests/ShockCloud_128.in deleted file mode 100644 index 21cb1afe0..000000000 --- a/tests/ShockCloud_128.in +++ /dev/null @@ -1,57 +0,0 @@ -# ***************************************************************** -# Problem size and geometry -# ***************************************************************** -geometry.prob_lo = 0.0 0.0 0.0 -geometry.prob_hi = 4.9376e+20 4.9376e+20 4.9376e+20 # 160 x 160 x 160 pc -geometry.is_periodic = 1 0 1 - -# ***************************************************************** -# VERBOSITY -# ***************************************************************** -amr.v = 1 # verbosity in Amr - -# ***************************************************************** -# Resolution and refinement -# ***************************************************************** -amr.n_cell = 128 128 128 -amr.max_level = 1 # number of levels = max_level + 1 -amr.blocking_factor = 32 # grid size must be divisible by this -amr.max_grid_size = 128 - -do_reflux = 1 -do_subcycle = 1 - -cooling.enabled = 1 -cooling.cooling_table_type = grackle -cooling.hdf5_data_file = "../extern/grackle_data_files/input/CloudyData_UVB=HM2012.h5" -temperature_floor = 100 - -derived_vars = temperature -ascent_interval = 10 - -quokka.diagnostics = slice_z hist_temp - -quokka.slice_z.type = DiagFramePlane # Diagnostic type -quokka.slice_z.file = slicez_plt # Output file prefix (must end in "plt") -quokka.slice_z.normal = 2 # Plane normal (0 == x, 1 == y, 2 == z) -quokka.slice_z.center = 2.4688e20 # Coordinate in the normal direction -quokka.slice_z.int = 10 # Output cadence (in number of coarse steps) -quokka.slice_z.interpolation = Linear # (Optional, default: Linear) Interpolation type: Linear, Quadratic -quokka.slice_z.field_names = gasDensity \ - gasInternalEnergy temperature # List of variables included in output - -quokka.hist_temp.type = DiagPDF # Diagnostic type -quokka.hist_temp.file = PDFTemp # Output file prefix -quokka.hist_temp.int = 10 # Output cadence (in number of coarse steps) -quokka.hist_temp.weight_by = mass # (Optional) Weight by: mass, volume, cell_counts -#quokka.hist_temp.filters = dense # (Optional) List of filters -#quokka.hist_temp.dense.field_name = gasDensity # Filter field -#quokka.hist_temp.dense.value_greater = 1e-25 # Filters: value_greater, value_less, value_inrange - -quokka.hist_temp.var_names = temperature gasDensity # Variable(s) of interest (compute a N-D histogram) -quokka.hist_temp.temperature.nBins = 20 # temperature: Number of bins -quokka.hist_temp.temperature.log_spaced_bins = 1 # temperature: (Optional, default: 0) Use log-spaced bins -quokka.hist_temp.temperature.range = 1e3 1e7 # temperature: (Optional) Specify the min/max of the bins -quokka.hist_temp.gasDensity.nBins = 5 # gasDensity: Number of bins -quokka.hist_temp.gasDensity.log_spaced_bins = 1 # gasDensity: (Optional, default: 0) Use log-spaced bins -quokka.hist_temp.gasDensity.range = 1e-29 1e-23 # gasDensity: (Optional) Specify the min/max of the bins diff --git a/tests/ShockCloud_32.in b/tests/ShockCloud_32.in new file mode 100644 index 000000000..f5824d1f2 --- /dev/null +++ b/tests/ShockCloud_32.in @@ -0,0 +1,143 @@ +# ***************************************************************** +# Problem size and geometry +# ***************************************************************** +geometry.prob_lo = 0.0 0.0 0.0 +geometry.prob_hi = 2.4688e+21 6.172e+20 6.172e+20 # 800 x 200 x 200 pc +geometry.is_periodic = 0 1 1 + +# ***************************************************************** +# VERBOSITY +# ***************************************************************** +amr.v = 1 # verbosity in Amr + +# ***************************************************************** +# Resolution and refinement +# ***************************************************************** +amr.n_cell = 128 32 32 +amr.max_level = 0 # number of levels = max_level + 1 +amr.blocking_factor = 16 # grid size must be divisible by this +amr.max_grid_size = 64 + +# ***************************************************************** +# Quokka options +# ***************************************************************** +do_reflux = 1 +do_subcycle = 1 + +cfl = 0.2 +hydro.abort_on_fofc_failure = 1 +hydro.reconstruction_order = 3 +#hydro.artificial_viscosity_coefficient = 0.1 + +density_floor = 1.0e-28 # g cm^{-3} +temperature_floor = 100 # K + +sharp_cloud_edge = 1 +do_frame_shift = 1 + +#max_walltime = 0:00:30 +max_timesteps = 100000 +max_t_cc = 20.0 + +plotfile_interval = 200 +checkpoint_interval = 1000 +ascent_interval = 200 + +statistics_interval = 200 +projection_interval = 200 +projection.dirs = x z + +derived_vars = pressure entropy nH temperature cooling_length \ + cloud_fraction lab_velocity_x mass velocity_mag c_s + +cooling.enabled = 1 +cooling.read_tables_even_if_disabled = 1 +cooling.cooling_table_type = cloudy_cooling_tools +cooling.hdf5_data_file = "./isrf_1000Go_grains.h5" + +nH_bg = 0.003356403333 # cm^-3 +nH_cloud = 1.006921e+00 # cm^-3 +P_over_k = 1.304005e+04 # K cm^-3 + +R_cloud_pc = 16.09084149928867 # pc +cloud_relpos_x = 0.25 # fraction +Mach_shock = 1.888892847795999 + +do_tracers = 1 # enable tracer particles + +quokka.diagnostics = slice_z hist1 hist2 hist3 hist4 + +## z-slice output + +quokka.slice_z.type = DiagFramePlane # Diagnostic type (others may be added in the future) +quokka.slice_z.file = slicez_plt # Output file prefix (should end in "plt") +quokka.slice_z.normal = 2 # Plane normal (0 == x, 1 == y, 2 == z) +quokka.slice_z.center = 3.086e20 # Coordinate in the normal direction +quokka.slice_z.int = 200 # Output interval (in number of coarse steps) +quokka.slice_z.interpolation = Linear # Interpolation type: Linear or Quadratic (default: Linear) +quokka.slice_z.field_names = gasDensity pressure entropy nH temperature cooling_length \ + cloud_fraction lab_velocity_x mass velocity_mag c_s + +## Histogram 1 output + +quokka.hist1.type = DiagPDF +quokka.hist1.file = PDFTempDens +quokka.hist1.int = 20 +quokka.hist1.weight_by = mass +quokka.hist1.var_names = temperature nH + +quokka.hist1.temperature.nBins = 50 +quokka.hist1.temperature.log_spaced_bins = 1 +quokka.hist1.temperature.range = 1e2 1e8 + +quokka.hist1.nH.nBins = 50 +quokka.hist1.nH.log_spaced_bins = 1 +quokka.hist1.nH.range = 1e-3 1e3 + +## Histogram 2 output + +quokka.hist2.type = DiagPDF +quokka.hist2.file = PDFPressureEntropy +quokka.hist2.int = 20 +quokka.hist2.weight_by = mass +quokka.hist2.var_names = pressure entropy + +quokka.hist2.pressure.nBins = 50 +quokka.hist2.pressure.log_spaced_bins = 1 +quokka.hist2.pressure.range = 1e3 1e6 + +quokka.hist2.entropy.nBins = 50 +quokka.hist2.entropy.log_spaced_bins = 1 +quokka.hist2.entropy.range = 1e-4 1e2 + +## Histogram 3 output + +quokka.hist3.type = DiagPDF +quokka.hist3.file = PDFVelocityTemp +quokka.hist3.int = 20 +quokka.hist3.weight_by = mass +quokka.hist3.var_names = lab_velocity_x temperature + +quokka.hist3.lab_velocity_x.nBins = 100 +quokka.hist3.lab_velocity_x.log_spaced_bins = 0 +quokka.hist3.lab_velocity_x.range = 0.0 400.0 + +quokka.hist3.temperature.nBins = 9 +quokka.hist3.temperature.log_spaced_bins = 1 +quokka.hist3.temperature.range = 1e1 1e10 + +## Histogram 4 output + +quokka.hist4.type = DiagPDF +quokka.hist4.file = PDFVelocityDens +quokka.hist4.int = 20 +quokka.hist4.weight_by = mass +quokka.hist4.var_names = lab_velocity_x nH + +quokka.hist4.lab_velocity_x.nBins = 100 +quokka.hist4.lab_velocity_x.log_spaced_bins = 0 +quokka.hist4.lab_velocity_x.range = 0.0 400.0 + +quokka.hist4.nH.nBins = 6 +quokka.hist4.nH.log_spaced_bins = 1 +quokka.hist4.nH.range = 1e-3 1e3 diff --git a/tests/ShockCloud_512.in b/tests/ShockCloud_512.in deleted file mode 100644 index 1e5176bc3..000000000 --- a/tests/ShockCloud_512.in +++ /dev/null @@ -1,55 +0,0 @@ -# ***************************************************************** -# Problem size and geometry -# ***************************************************************** -geometry.prob_lo = 0.0 0.0 0.0 -geometry.prob_hi = 4.9376e+20 4.9376e+20 4.9376e+20 # 160 x 160 x 160 pc -geometry.is_periodic = 1 0 1 - -# ***************************************************************** -# VERBOSITY -# ***************************************************************** -amr.v = 1 # verbosity in Amr - -# ***************************************************************** -# Resolution and refinement -# ***************************************************************** -amr.n_cell = 512 512 512 -amr.max_level = 1 # number of levels = max_level + 1 -amr.blocking_factor = 32 # grid size must be divisible by this -amr.max_grid_size = 128 - -do_reflux = 1 -do_subcycle = 1 - -cooling.enabled = 1 -cooling.cooling_table_type = grackle -cooling.hdf5_data_file = "../extern/grackle_data_files/input/CloudyData_UVB=HM2012.h5" -temperature_floor = 100 - -derived_vars = temperature - -quokka.diagnostics = slice_z hist_temp - -quokka.slice_z.type = DiagFramePlane # Diagnostic type -quokka.slice_z.file = slicez_plt # Output file prefix (must end in "plt") -quokka.slice_z.normal = 2 # Plane normal (0 == x, 1 == y, 2 == z) -quokka.slice_z.center = 2.4688e20 # Coordinate in the normal direction -quokka.slice_z.int = 10 # Output cadence (in number of coarse steps) -quokka.slice_z.interpolation = Linear # (Optional, default is Linear) Interpolation type: Linear or Quadratic -quokka.slice_z.field_names = gasDensity gasInternalEnergy temperature # List of variables included in output - -quokka.hist_temp.type = DiagPDF # Diagnostic type -quokka.hist_temp.file = PDFTemp # Output file prefix -quokka.hist_temp.int = 10 # Output cadence (in number of coarse steps) -quokka.hist_temp.weight_by = mass # (Optional) Weight by: mass, volume, cell_counts -#quokka.hist_temp.filters = dense # (Optional) List of filters -#quokka.hist_temp.dense.field_name = gasDensity # Filter field -#quokka.hist_temp.dense.value_greater = 1e-25 # Filters: value_greater, value_less, value_inrange - -quokka.hist_temp.var_names = temperature gasDensity # Variable(s) of interest (compute a N-D histogram) -quokka.hist_temp.temperature.nBins = 20 # temperature: Number of bins -quokka.hist_temp.temperature.log_spaced_bins = 1 # temperature: (Optional, default: 0) Use log-spaced bins -quokka.hist_temp.temperature.range = 1e3 1e7 # temperature: (Optional) Specify the min/max of the bins -quokka.hist_temp.gasDensity.nBins = 5 # gasDensity: Number of bins -quokka.hist_temp.gasDensity.log_spaced_bins = 1 # gasDensity: (Optional, default: 0) Use log-spaced bins -quokka.hist_temp.gasDensity.range = 1e-29 1e-23 # gasDensity: (Optional) Specify the min/max of the bins diff --git a/tests/ShockCloud_64.in b/tests/ShockCloud_64.in new file mode 100644 index 000000000..b6a5ad717 --- /dev/null +++ b/tests/ShockCloud_64.in @@ -0,0 +1,131 @@ +# ***************************************************************** +# Problem size and geometry +# ***************************************************************** +geometry.prob_lo = 0.0 0.0 0.0 +geometry.prob_hi = 2.4688e+21 6.172e+20 6.172e+20 # 800 x 200 x 200 pc +geometry.is_periodic = 0 1 1 + +# ***************************************************************** +# VERBOSITY +# ***************************************************************** +amr.v = 1 # verbosity in Amr + +# ***************************************************************** +# Resolution and refinement +# ***************************************************************** +amr.n_cell = 256 64 64 +amr.max_level = 0 # number of levels = max_level + 1 +amr.blocking_factor = 16 # grid size must be divisible by this +amr.max_grid_size = 64 + +# ***************************************************************** +# Quokka options +# ***************************************************************** +cfl = 0.3 +do_reflux = 1 +do_subcycle = 1 +max_walltime = 6:00:00 +max_timesteps = 20000 +max_t_cc = 20.0 + +checkpoint_interval = 500 +plotfile_interval = 200 +projection_interval = 20 +projection.dirs = x z +ascent_interval = 20 +statistics_interval = 20 +derived_vars = pressure entropy nH temperature cooling_length \ + cloud_fraction lab_velocity_x mass velocity_mag c_s + +cooling.enabled = 1 +cooling.read_tables_even_if_disabled = 1 +cooling.cooling_table_type = cloudy_cooling_tools +cooling.hdf5_data_file = "./isrf_1000Go_grains.h5" +temperature_floor = 100 + +sharp_cloud_edge = 1 +do_frame_shift = 1 +nH_bg = 3.356403e-03 # cm^-3 +nH_cloud = 1.006921e+00 # cm^-3 +P_over_k = 1.304005e+04 # K cm^-3 +R_cloud_pc = 16.09084149928867 # pc +Mach_shock = 1.888892847795999 + +do_tracers = 1 # enable tracer particles + +quokka.diagnostics = slice_z hist1 hist2 hist3 hist4 + +## z-slice output + +quokka.slice_z.type = DiagFramePlane # Diagnostic type (others may be added in the future) +quokka.slice_z.file = slicez_plt # Output file prefix (should end in "plt") +quokka.slice_z.normal = 2 # Plane normal (0 == x, 1 == y, 2 == z) +quokka.slice_z.center = 3.086e20 # Coordinate in the normal direction +quokka.slice_z.int = 200 # Output interval (in number of coarse steps) +quokka.slice_z.interpolation = Linear # Interpolation type: Linear or Quadratic (default: Linear) +quokka.slice_z.field_names = gasDensity pressure entropy nH temperature cooling_length \ + cloud_fraction lab_velocity_x mass velocity_mag c_s + +## Histogram 1 output + +quokka.hist1.type = DiagPDF +quokka.hist1.file = PDFTempDens +quokka.hist1.int = 20 +quokka.hist1.weight_by = mass +quokka.hist1.var_names = temperature nH + +quokka.hist1.temperature.nBins = 50 +quokka.hist1.temperature.log_spaced_bins = 1 +quokka.hist1.temperature.range = 1e2 1e8 + +quokka.hist1.nH.nBins = 50 +quokka.hist1.nH.log_spaced_bins = 1 +quokka.hist1.nH.range = 1e-3 1e3 + +## Histogram 2 output + +quokka.hist2.type = DiagPDF +quokka.hist2.file = PDFPressureEntropy +quokka.hist2.int = 20 +quokka.hist2.weight_by = mass +quokka.hist2.var_names = pressure entropy + +quokka.hist2.pressure.nBins = 50 +quokka.hist2.pressure.log_spaced_bins = 1 +quokka.hist2.pressure.range = 1e3 1e6 + +quokka.hist2.entropy.nBins = 50 +quokka.hist2.entropy.log_spaced_bins = 1 +quokka.hist2.entropy.range = 1e-4 1e2 + +## Histogram 3 output + +quokka.hist3.type = DiagPDF +quokka.hist3.file = PDFVelocityTemp +quokka.hist3.int = 20 +quokka.hist3.weight_by = mass +quokka.hist3.var_names = lab_velocity_x temperature + +quokka.hist3.lab_velocity_x.nBins = 100 +quokka.hist3.lab_velocity_x.log_spaced_bins = 0 +quokka.hist3.lab_velocity_x.range = 0.0 400.0 + +quokka.hist3.temperature.nBins = 9 +quokka.hist3.temperature.log_spaced_bins = 1 +quokka.hist3.temperature.range = 1e1 1e10 + +## Histogram 4 output + +quokka.hist4.type = DiagPDF +quokka.hist4.file = PDFVelocityDens +quokka.hist4.int = 20 +quokka.hist4.weight_by = mass +quokka.hist4.var_names = lab_velocity_x nH + +quokka.hist4.lab_velocity_x.nBins = 100 +quokka.hist4.lab_velocity_x.log_spaced_bins = 0 +quokka.hist4.lab_velocity_x.range = 0.0 400.0 + +quokka.hist4.nH.nBins = 6 +quokka.hist4.nH.log_spaced_bins = 1 +quokka.hist4.nH.range = 1e-3 1e3 diff --git a/tests/ShockCloud_64_regression.in b/tests/ShockCloud_64_regression.in new file mode 100644 index 000000000..577117142 --- /dev/null +++ b/tests/ShockCloud_64_regression.in @@ -0,0 +1,49 @@ +# ***************************************************************** +# Problem size and geometry +# ***************************************************************** +geometry.prob_lo = 0.0 0.0 0.0 +geometry.prob_hi = 2.4688e+21 6.172e+20 6.172e+20 # 800 x 200 x 200 pc +geometry.is_periodic = 0 1 1 + +# ***************************************************************** +# VERBOSITY +# ***************************************************************** +amr.v = 1 # verbosity in Amr + +# ***************************************************************** +# Resolution and refinement +# ***************************************************************** +amr.n_cell = 256 64 64 +amr.max_level = 0 # number of levels = max_level + 1 +amr.blocking_factor = 32 # grid size must be divisible by this +amr.max_grid_size = 128 + +# ***************************************************************** +# Quokka options +# ***************************************************************** +cfl = 0.3 +do_reflux = 1 +do_subcycle = 1 +max_timesteps = 20000 +max_t_cc = 20.0 + +checkpoint_interval = -1 +plotfile_interval = 20000 +derived_vars = pressure entropy nH temperature cooling_length \ + cloud_fraction lab_velocity_x mass velocity_mag c_s + +cooling.enabled = 1 +cooling.read_tables_even_if_disabled = 1 +cooling.cooling_table_type = cloudy_cooling_tools +cooling.hdf5_data_file = "/home/bwibking/regression-tests/quokka/extern/cooling/isrf_1000Go_grains.h5" +temperature_floor = 100 + +sharp_cloud_edge = 1 +do_frame_shift = 1 +nH_bg = 3.356403e-03 # cm^-3 +nH_cloud = 1.006921e+00 # cm^-3 +P_over_k = 1.304005e+04 # K cm^-3 +R_cloud_pc = 16.09084149928867 # pc +Mach_shock = 1.888892847795999 + +do_tracers = 1 # enable tracer particles diff --git a/tests/ascent_actions.yaml b/tests/ascent_actions.yaml deleted file mode 100644 index 95f667cd5..000000000 --- a/tests/ascent_actions.yaml +++ /dev/null @@ -1,30 +0,0 @@ -- - action: "add_pipelines" - pipelines: - pl1: - f2: - type: "slice" - params: - point: - x: 0.5 - y: 0.5 - z: 0.5 - normal: - x: 0.0 - y: 0.0 - z: 1.0 -- - action: "add_scenes" - scenes: - s1: - plots: - p1: - type: "pseudocolor" - field: "gasDensity" - pipeline: "pl1" - renders: - r1: - image_prefix: "dens%05d" - annotations: "true" - camera: - zoom: 1.5