diff --git a/CMake/BuildPeleExe.cmake b/CMake/BuildPeleExe.cmake index 6f5899a79..ae5bf67f6 100644 --- a/CMake/BuildPeleExe.cmake +++ b/CMake/BuildPeleExe.cmake @@ -22,10 +22,10 @@ function(build_pele_exe pele_exe_name pele_physics_lib_name) target_include_directories(${pele_exe_name} PRIVATE ${CMAKE_SOURCE_DIR}/Source/Params/param_includes) #Adv and Aux Variables if (PELEC_NUM_ADV GREATER 0) - target_compile_definitions(${pelec_exe_name} PRIVATE NUM_ADV=${PELEC_NUM_ADV}) + target_compile_definitions(${pele_exe_name} PRIVATE NUM_ADV=${PELEC_NUM_ADV}) endif() if (PELEC_NUM_AUX GREATER 0) - target_compile_definitions(${pelec_exe_name} PRIVATE NUM_AUX=${PELEC_NUM_AUX}) + target_compile_definitions(${pele_exe_name} PRIVATE NUM_AUX=${PELEC_NUM_AUX}) endif() target_sources(${pele_exe_name} diff --git a/Docs/sphinx/Equations.rst b/Docs/sphinx/Equations.rst index 34a0f5584..88523c2ab 100644 --- a/Docs/sphinx/Equations.rst +++ b/Docs/sphinx/Equations.rst @@ -13,7 +13,7 @@ Equations Conservative system ------------------- -PeleC advances the following set of fully compressible equations for the conserved state vector: :math:`\mathbf{U} = (\rho, \rho \mathbf{u}, \rho E, \rho Y_k, \rho A_k, \rho B_k):` +PeleC advances the following set of fully compressible equations for the conserved state vector: :math:`\mathbf{U} = (\rho, \rho \mathbf{u}, \rho E, \rho Y_k, \rho A_k, B_k):` .. math:: @@ -28,7 +28,7 @@ PeleC advances the following set of fully compressible equations for the conserv \frac{\partial (\rho A_k)}{\partial t} &=& - \nabla \cdot (\rho \mathbf{u} A_k) + S_{{\rm ext},\rho A_k}, - \frac{\partial (\rho B_k)}{\partial t} &=& - \nabla \cdot (\rho \mathbf{u} B_k) + S_{{\rm ext},\rho B_k}. + \frac{\partial B_k}{\partial t} &=& S_{{\rm ext}, B_k}. Here :math:`\rho, \mathbf{u}, T`, and :math:`p` are the density, velocity, @@ -38,7 +38,7 @@ and chemical energy (species heats of formation) and is conserved across chemica :math:`Y_k` is the mass fraction of the :math:`k^{\rm th}` species, with associated production rate, :math:`\dot\omega_k`. Here :math:`\mathbf{g}` is the gravitational vector, and :math:`S_{{\rm ext},\rho}, \mathbf{S}_{{\rm ext},\rho\mathbf{u}}`, etc., are user-specified -source terms. :math:`A_k` is an advected quantity, i.e., a tracer. Also +source terms. :math:`A_k` is an advected quantity, i.e., a tracer. :math:`B_k` is spatially stationary quantity. Also :math:`\boldsymbol{\mathcal{F}}_{m}, \mathbf{\Pi}`, and :math:`\boldsymbol{\mathcal{Q}}` are the diffusive transport fluxes for species, momentum and heat. Note that the internal energy for species :math:`k` includes its heat of formation (and can therefore take on negative and @@ -95,7 +95,7 @@ The inviscid equations for primitive variables namely density, velocity, and pre && \quad\qquad\qquad\qquad+\ S_{{\rm ext},\rho E} - \mathbf{u}\cdot\left(\mathbf{S}_{{\rm ext},\rho\mathbf{u}} - \frac{\mathbf{u}}{2}S_{{\rm ext},\rho}\right)\Biggr] -The advected quantities appear as: +The advected and auxiliary quantities appear as: .. math:: @@ -105,8 +105,7 @@ The advected quantities appear as: \frac{\partial A_k}{\partial t} &=& -\mathbf{u}\cdot\nabla A_k + \frac{1}{\rho} ( S_{{\rm ext},\rho A_k} - A_k S_{{\rm ext},\rho} ), - \frac{\partial B_k}{\partial t} &=& -\mathbf{u}\cdot\nabla B_k + \frac{1}{\rho} - ( S_{{\rm ext},\rho B_k} - B_k S_{{\rm ext},\rho} ). + \frac{\partial B_k}{\partial t} &=& S_{{\rm ext}, B_k}. @@ -140,7 +139,7 @@ accounted for in the characteristic integration in the PPM algorithm. The sourc \nabla\cdot k_{\rm th} \nabla T + S_{{\rm ext},\rho E} \\ \frac{1}{\rho}S_{{\rm ext},\rho Y_k} \\ \frac{1}{\rho}S_{{\rm ext},\rho A_k} \\ - \frac{1}{\rho}S_{{\rm ext},\rho B_k} + S_{{\rm ext},B_k} \end{array}\right)^n, @@ -153,7 +152,7 @@ accounted for in the characteristic integration in the PPM algorithm. The sourc S_{\rho E} \\ S_{\rho Y_k} \\ S_{\rho A_k} \\ - S_{\rho B_k} + S_{ B_k} \end{array}\right)^n = \left(\begin{array}{c} @@ -162,5 +161,5 @@ accounted for in the characteristic integration in the PPM algorithm. The sourc \rho \mathbf{u} \cdot \mathbf{g} + \nabla\cdot k_{\rm th} \nabla T + S_{{\rm ext},\rho E} \\ S_{{\rm ext},\rho Y_k} \\ S_{{\rm ext},\rho A_k} \\ - S_{{\rm ext},\rho B_k} + S_{{\rm ext}, B_k} \end{array}\right)^n. diff --git a/Docs/sphinx/ebverification/FlowPastCylinder/README.rst b/Docs/sphinx/ebverification/FlowPastCylinder/README.rst index 0c1732e24..cdcf36b10 100644 --- a/Docs/sphinx/ebverification/FlowPastCylinder/README.rst +++ b/Docs/sphinx/ebverification/FlowPastCylinder/README.rst @@ -16,7 +16,7 @@ where :math:`\rho` is the density and :math:`\mu` is the dynamic viscosity. Domain definition ################################## -The cylinder with radius :math:`r=5` is centered at (0,0) on the upstream side of the domain as seen below. +The cylinder with radius :math:`r=0.5` [cm] is centered at (0,0) on the upstream side of the domain as seen below. .. image:: /ebverification/FlowPastCylinder/domain.png :width: 450pt diff --git a/Exec/RegTests/AuxQuantities/CMakeLists.txt b/Exec/RegTests/AuxQuantities/CMakeLists.txt new file mode 100644 index 000000000..478417540 --- /dev/null +++ b/Exec/RegTests/AuxQuantities/CMakeLists.txt @@ -0,0 +1,9 @@ +set(PELE_PHYSICS_EOS_MODEL GammaLaw) +set(PELE_PHYSICS_CHEMISTRY_MODEL Null) +set(PELE_PHYSICS_TRANSPORT_MODEL Constant) +set(PELE_PHYSICS_ENABLE_SOOT OFF) +set(PELE_PHYSICS_ENABLE_SPRAY OFF) +set(PELE_PHYSICS_SPRAY_FUEL_NUM 0) +set(PELEC_NUM_ADV 2) +set(PELEC_NUM_AUX 2) +include(BuildExeAndLib) diff --git a/Exec/RegTests/AuxQuantities/GNUmakefile b/Exec/RegTests/AuxQuantities/GNUmakefile new file mode 100644 index 000000000..da6af3421 --- /dev/null +++ b/Exec/RegTests/AuxQuantities/GNUmakefile @@ -0,0 +1,40 @@ +# AMReX +DIM = 2 +COMP = gnu +PRECISION = DOUBLE + +# Profiling +PROFILE = FALSE +TINY_PROFILE = FALSE +COMM_PROFILE = FALSE +TRACE_PROFILE = FALSE +MEM_PROFILE = FALSE +USE_GPROF = FALSE + +# Performance +USE_MPI = TRUE +USE_OMP = FALSE +USE_CUDA = FALSE +USE_HIP = FALSE +USE_SYCL = FALSE + +# Debugging +DEBUG = FALSE +FSANITIZER = FALSE +THREAD_SANITIZER = FALSE + +# PeleC +PELE_CVODE_FORCE_YCORDER = FALSE +PELE_USE_MAGMA = FALSE +PELE_COMPILE_AJACOBIAN = FALSE +Eos_Model := GammaLaw +Chemistry_Model := Null +Transport_Model := Constant +PELEC_NUM_AUX = 2 +PELEC_NUM_ADV = 2 + +# GNU Make +Bpack := ./Make.package +Blocs := . +PELE_HOME := ../../.. +include $(PELE_HOME)/Exec/Make.PeleC diff --git a/Exec/RegTests/AuxQuantities/Make.package b/Exec/RegTests/AuxQuantities/Make.package new file mode 100644 index 000000000..bdc32b025 --- /dev/null +++ b/Exec/RegTests/AuxQuantities/Make.package @@ -0,0 +1,3 @@ +CEXE_headers += prob.H +CEXE_headers += prob_parm.H +CEXE_sources += prob.cpp diff --git a/Exec/RegTests/AuxQuantities/README.md b/Exec/RegTests/AuxQuantities/README.md new file mode 100644 index 000000000..a62bf1788 --- /dev/null +++ b/Exec/RegTests/AuxQuantities/README.md @@ -0,0 +1,14 @@ +# Advected and auxiliary quantities + +This demonstrates the use of the advected and auxiliary quantities described in the PeleC model [equations](https://amrex-combustion.github.io/PeleC/Equations.html). The case introduces two advected and two auxiliary quantities into the domain. The auxiliary quantities experience simple exponential decay with a source term of $S_{ext,B_k} = -30 B_k$. + + +## Short case description + +| | description | +|:-------------------|:----------------------------------------------------| +| Problem definition | advected and auxiliaru quantities | +| EB geometry | embedded cylinder (optional) | +| EOS | GammaLaw | +| Multi-level | yes | +| Metric | numerical solutions for $B_k$ match theory | diff --git a/Exec/RegTests/AuxQuantities/auxquantities.inp b/Exec/RegTests/AuxQuantities/auxquantities.inp new file mode 100644 index 000000000..abef51822 --- /dev/null +++ b/Exec/RegTests/AuxQuantities/auxquantities.inp @@ -0,0 +1,83 @@ +# ------------------ INPUTS TO MAIN PROGRAM ------------------- +#max_step = 100 +stop_time = 0.1 + +# PROBLEM SIZE & GEOMETRY +geometry.is_periodic = 0 0 0 +geometry.coord_sys = 0 # 0 => cart +geometry.prob_lo = -2. -2. -2. +geometry.prob_hi = 10. 2. 2. +amr.n_cell = 96 32 8 + +# >>>>>>>>>>>>> BC KEYWORDS <<<<<<<<<<<<<<<<<<<<<< +# Interior, UserBC, Symmetry, SlipWall, NoSlipWall +# >>>>>>>>>>>>> BC KEYWORDS <<<<<<<<<<<<<<<<<<<<<< + +pelec.lo_bc = "Hard" "SlipWall" "FOExtrap" +pelec.hi_bc = "Hard" "SlipWall" "FOExtrap" + +# Problem setup +prob.p = 1013250. +prob.T = 100. +prob.Re = 100. +prob.Pr = 0.7 +prob.U = 100. +prob.aux_xy_lo = -1. +prob.aux_length = 1. +prob.aux_height = 2. +prob.aux_srcstrength = -30. + +# Add user specified source term(s) +pelec.add_ext_src = 1 + +# WHICH PHYSICS +pelec.do_hydro = 1 +pelec.do_mol = 0 +pelec.do_react = 0 +pelec.allow_negative_energy = 0 +pelec.diffuse_temp = 1 +pelec.diffuse_vel = 1 +pelec.diffuse_spec = 0 +pelec.diffuse_enth = 1 + +# TIME STEP CONTROL +pelec.dt_cutoff = 5.e-20 # level 0 timestep below which we halt +pelec.cfl = 0.7 # cfl number for hyperbolic system +pelec.init_shrink = 0.1 # scale back initial timestep +pelec.change_max = 1.05 # maximum increase in dt over successive steps + +# DIAGNOSTICS & VERBOSITY +pelec.sum_interval = 1 # timesteps between computing mass +pelec.v = 1 # verbosity in PeleC cpp files +amr.v = 1 # verbosity in Amr.cpp + +# REFINEMENT / REGRIDDING +amr.max_level = 1 # maximum level number allowed +amr.ref_ratio = 2 2 2 2 # refinement ratio +amr.regrid_int = 5 # how often to regrid +amr.blocking_factor = 8 # block factor in grid generation +amr.max_grid_size = 64 + +# TAGGING +tagging.refinement_indicators = adv_0 adv_1 +tagging.adv_0.field_name = rho_A_0 +tagging.adv_0.adjacent_difference_greater = 0.01 +tagging.adv_0.max_level = 1 +tagging.adv_1.field_name = rho_A_1 +tagging.adv_1.adjacent_difference_greater = 0.02 +tagging.adv_1.max_level = 1 + +# CHECKPOINT FILES +amr.checkpoint_files_output = 0 +amr.check_file = chk # root name of checkpoint file +amr.check_int = 10000 # number of timesteps between checkpoints + +# PLOTFILES +amr.plot_files_output = 1 +amr.plot_file = plt +amr.plot_int = 1000 +amr.derive_plot_vars= x_velocity y_velocity z_velocity + +# EB +ebd.boundary_grad_stencil_type = 0 +eb2.geom_type = "all_regular" diff --git a/Exec/RegTests/AuxQuantities/auxquantities_eb.inp b/Exec/RegTests/AuxQuantities/auxquantities_eb.inp new file mode 100644 index 000000000..9224414a9 --- /dev/null +++ b/Exec/RegTests/AuxQuantities/auxquantities_eb.inp @@ -0,0 +1,91 @@ +# ------------------ INPUTS TO MAIN PROGRAM ------------------- +#max_step = 1 +stop_time = 0.1 + +# PROBLEM SIZE & GEOMETRY +geometry.is_periodic = 0 0 0 +geometry.coord_sys = 0 # 0 => cart +geometry.prob_lo = -2. -2. -2. +geometry.prob_hi = 10. 2. 2. +amr.n_cell = 96 32 8 + +# >>>>>>>>>>>>> BC KEYWORDS <<<<<<<<<<<<<<<<<<<<<< +# Interior, UserBC, Symmetry, SlipWall, NoSlipWall +# >>>>>>>>>>>>> BC KEYWORDS <<<<<<<<<<<<<<<<<<<<<< + +pelec.lo_bc = "Hard" "SlipWall" "FOExtrap" +pelec.hi_bc = "Hard" "SlipWall" "FOExtrap" + +# Problem setup +prob.p = 1013250. +prob.T = 100. +prob.Re = 100. +prob.Pr = 0.7 +prob.U = 100. +prob.aux_xy_lo = -1. +prob.aux_length = 1. +prob.aux_height = 2. +prob.aux_srcstrength = -30. + +# Add user specified source term(s) +pelec.add_ext_src = 1 + +# WHICH PHYSICS +pelec.do_hydro = 1 +pelec.do_mol = 0 +pelec.do_react = 0 +pelec.allow_negative_energy = 0 +pelec.diffuse_temp = 1 +pelec.diffuse_vel = 1 +pelec.diffuse_spec = 0 +pelec.diffuse_enth = 1 + +# TIME STEP CONTROL +pelec.dt_cutoff = 5.e-20 # level 0 timestep below which we halt +pelec.cfl = 0.7 # cfl number for hyperbolic system +pelec.init_shrink = 0.1 # scale back initial timestep +pelec.change_max = 1.05 # maximum increase in dt over successive steps + +# DIAGNOSTICS & VERBOSITY +pelec.sum_interval = 1 # timesteps between computing mass +pelec.v = 1 # verbosity in PeleC cpp files +amr.v = 1 # verbosity in Amr.cpp + +# REFINEMENT / REGRIDDING +amr.max_level = 1 # maximum level number allowed +amr.ref_ratio = 2 2 2 2 # refinement ratio +amr.regrid_int = 5 # how often to regrid +amr.blocking_factor = 8 # block factor in grid generation +amr.max_grid_size = 64 + +# TAGGING +tagging.refinement_indicators = adv_0 adv_1 +tagging.adv_0.field_name = rho_A_0 +tagging.adv_0.adjacent_difference_greater = 0.01 +tagging.adv_0.max_level = 1 +tagging.adv_1.field_name = rho_A_1 +tagging.adv_1.adjacent_difference_greater = 0.02 +tagging.adv_1.max_level = 1 + +# CHECKPOINT FILES +amr.checkpoint_files_output = 0 +amr.check_file = chk # root name of checkpoint file +amr.check_int = 10000 # number of timesteps between checkpoints + +# PLOTFILES +amr.plot_files_output = 1 +amr.plot_file = plt +amr.plot_int = 1000 +amr.derive_plot_vars= x_velocity y_velocity z_velocity vfrac + +# EB +ebd.boundary_grad_stencil_type = 0 + +# for 2D (need a sphere): +eb2.geom_type = "sphere" +eb2.sphere_radius = 0.5 +eb2.sphere_center = 3 0 0 +eb2.sphere_has_fluid_inside = 0 +eb2.small_volfrac = 1.0e-4 +pelec.eb_boundary_T = 100. +pelec.eb_isothermal = 1 \ No newline at end of file diff --git a/Exec/RegTests/AuxQuantities/prob.H b/Exec/RegTests/AuxQuantities/prob.H new file mode 100644 index 000000000..029993eb6 --- /dev/null +++ b/Exec/RegTests/AuxQuantities/prob.H @@ -0,0 +1,280 @@ +#ifndef PROB_H +#define PROB_H + +#include +#include +#include +#include + +#include "mechanism.H" + +#include "PeleC.H" +#include "IndexDefines.H" +#include "Constants.H" +#include "PelePhysics.H" +#include "Tagging.H" +#include "ProblemSpecificFunctions.H" +#include "prob_parm.H" + +AMREX_GPU_DEVICE +AMREX_FORCE_INLINE +void +pc_initdata( + int i, + int j, + int k, + amrex::Array4 const& state, + amrex::GeometryData const& geomdata, + ProbParmDevice const& prob_parm) +{ + // Standard state variable initialization + const amrex::Real p = prob_parm.p; + amrex::Real rho = 0.0, eint = 0.0; + amrex::Real massfrac[NUM_SPECIES] = {0.0}; + for (int n = 0; n < NUM_SPECIES; n++) { + massfrac[n] = prob_parm.massfrac[n]; + } + auto eos = pele::physics::PhysicsType::eos(); + eos.PYT2RE(p, massfrac, prob_parm.T, rho, eint); + + state(i, j, k, URHO) = rho; + state(i, j, k, UMX) = rho * prob_parm.U; + state(i, j, k, UMY) = 0.0; + state(i, j, k, UMZ) = 0.0; + state(i, j, k, UEINT) = rho * eint; + state(i, j, k, UEDEN) = rho * (eint + 0.5 * (prob_parm.U * prob_parm.U)); + state(i, j, k, UTEMP) = prob_parm.T; + for (int n = 0; n < NUM_SPECIES; n++) { + state(i, j, k, UFS + n) = rho * prob_parm.massfrac[n]; + } + + // Initial AUX quantity + { +#if NUM_AUX > 0 + amrex::Real aux[NUM_AUX] = {0.0}; + + // Initial state for aux quantities + amrex::Real aux_0[NUM_AUX] = {0.0}; + for (int n = 0; n < NUM_AUX; n++) { + aux_0[n] = (n + 1) * prob_parm.aux_IC; + } + + // Current x,y,z locations + const amrex::Real* prob_lo = geomdata.ProbLo(); + const amrex::Real* dx = geomdata.CellSize(); + const amrex::Real x[AMREX_SPACEDIM] = {AMREX_D_DECL( + prob_lo[0] + static_cast(i + 0.5) * dx[0], + prob_lo[1] + static_cast(j + 0.5) * dx[1], + prob_lo[2] + static_cast(k + 0.5) * dx[2])}; + + // Create NUM_AUX boxes from (x_strt,y_strt) to (x_end,y_end) + for (int n = 0; n < NUM_AUX; n++) { + amrex::Real x_strt = prob_parm.aux_xy_lo + n * 4. * prob_parm.aux_length; + amrex::Real x_end = x_strt + prob_parm.aux_length; + amrex::Real y_strt = prob_parm.aux_xy_lo; + amrex::Real y_end = y_strt + prob_parm.aux_height; + if ((x[0] > x_strt) && (x[1] > y_strt)) { + if ((x[0] < x_end) && (x[1] < y_end)) { + aux[n] = aux_0[n]; + } + } + } + // Add to state variable + for (int n = 0; n < NUM_AUX; n++) { + state(i, j, k, UFX + n) = aux[n]; + } +#endif + } + + // Initial ADV quantity + { +#if NUM_ADV > 0 + amrex::Real adv[NUM_ADV] = {0.0}; + + // Initial state for adv quantities + amrex::Real adv_0[NUM_ADV] = {0.0}; + for (int n = 0; n < NUM_ADV; n++) { + adv_0[n] = (n + 1) * prob_parm.aux_IC; + } + + // Current locations + const amrex::Real* prob_lo = geomdata.ProbLo(); + const amrex::Real* dx = geomdata.CellSize(); + const amrex::Real x[AMREX_SPACEDIM] = {AMREX_D_DECL( + prob_lo[0] + static_cast(i + 0.5) * dx[0], + prob_lo[1] + static_cast(j + 0.5) * dx[1], + prob_lo[2] + static_cast(k + 0.5) * dx[2])}; + + amrex::Real adv_xy_lo = prob_parm.aux_xy_lo + prob_parm.aux_length; + for (int n = 0; n < NUM_ADV; n++) { + // Create NUM_ADV boxes from (x_strt,y_strt) to (x_end,y_end) + amrex::Real x_strt = adv_xy_lo + n * 4. * prob_parm.aux_length; + amrex::Real x_end = x_strt + prob_parm.aux_length; + amrex::Real y_strt = prob_parm.aux_xy_lo; + amrex::Real y_end = y_strt + prob_parm.aux_height; + if ((x[0] > x_strt) && (x[1] > y_strt)) { + if ((x[0] < x_end) && (x[1] < y_end)) { + adv[n] = adv_0[n]; + } + } + } + + // Add to state variable + for (int n = 0; n < NUM_ADV; n++) { + state(i, j, k, UFA + n) = rho * adv[n]; + } +#endif + } +} + +AMREX_GPU_DEVICE +AMREX_FORCE_INLINE +void +bcnormal( + const amrex::Real x[AMREX_SPACEDIM], + const amrex::Real s_inter[NVAR], + amrex::Real s_ext[NVAR], + const int idir, + const int sgn, + const amrex::Real /*time*/, + amrex::GeometryData const& geomdata, + ProbParmDevice const& prob_parm, + const amrex::GpuArray& /*turb_fluc*/) +{ + if (idir == 0) { + + amrex::Real rho = 0.0, u = 0.0, v = 0.0, w = 0.0, eint = 0.0, T = 0.0; + auto eos = pele::physics::PhysicsType::eos(); + + if (sgn == 1) { + + T = prob_parm.T; + amrex::Real p_inter = 0.0; + amrex::Real massfrac_inter[NUM_SPECIES] = {0.0}; + for (int n = 0; n < NUM_SPECIES; n++) { + massfrac_inter[n] = s_inter[UFS + n] / s_inter[URHO]; + } + + // Ghost state p_d = p_inter (dp/dx = 0) + eos.RTY2P(s_inter[URHO], s_inter[UTEMP], massfrac_inter, p_inter); + + // Ghost state rho and eint (constant T) + eos.PYT2RE(p_inter, massfrac_inter, T, rho, eint); + + // Ghost state for velocity + u = prob_parm.U; + v = 0.0; + w = 0.0; + + } else if (sgn == -1) { + + // Following Blazek p 279, eq. 8.23 + + // Interior state (point d) + const amrex::Real* prob_hi = geomdata.ProbHi(); + const amrex::Real* dx = geomdata.CellSize(); + const amrex::Real xd = prob_hi[0] - 0.5 * dx[0]; + const amrex::Real rho_inter = s_inter[URHO]; + const amrex::Real u_inter = s_inter[UMX] / rho_inter; + const amrex::Real v_inter = s_inter[UMY] / rho_inter; + const amrex::Real w_inter = s_inter[UMZ] / rho_inter; + const amrex::Real T_inter = s_inter[UTEMP]; + amrex::Real p_inter = 0.0, cs_inter = 0.0; + amrex::Real massfrac[NUM_SPECIES] = {0.0}; + for (int n = 0; n < NUM_SPECIES; n++) { + massfrac[n] = s_inter[UFS + n] / s_inter[URHO]; + } + eos.RTY2P(rho_inter, T_inter, massfrac, p_inter); + eos.RTY2Cs(rho_inter, T_inter, massfrac, cs_inter); + + // Boundary state (point b) + const amrex::Real xb = prob_hi[0]; + const amrex::Real pb = prob_parm.p; + const amrex::Real rhob = + s_inter[URHO] + (pb - p_inter) / (cs_inter * cs_inter); + const amrex::Real ub = u_inter + (p_inter - pb) / (rho_inter * cs_inter); + const amrex::Real vb = v_inter; + const amrex::Real wb = w_inter; + + // Ghost state (point a). Linear extrapolation from d and b + rho = (rhob - rho_inter) / (xb - xd) * (x[0] - xd) + rho_inter; + const amrex::Real p = (pb - p_inter) / (xb - xd) * (x[0] - xd) + p_inter; + + eos.RYP2E(rho, massfrac, p, eint); + eos.EY2T(eint, massfrac, T); + + u = (ub - u_inter) / (xb - xd) * (x[0] - xd) + u_inter; + v = (vb - v_inter) / (xb - xd) * (x[0] - xd) + v_inter; + w = (wb - w_inter) / (xb - xd) * (x[0] - xd) + w_inter; + } + + s_ext[URHO] = rho; + s_ext[UMX] = rho * u; + s_ext[UMY] = rho * v; + s_ext[UMZ] = rho * w; + s_ext[UEINT] = rho * eint; + s_ext[UEDEN] = rho * (eint + 0.5 * (u * u + v * v + w * w)); + s_ext[UTEMP] = T; + for (int n = 0; n < NUM_SPECIES; n++) { + s_ext[UFS + n] = rho * prob_parm.massfrac[n]; + } + } +} + +void pc_prob_close(); + +struct MyProblemSpecificFunctions : public DefaultProblemSpecificFunctions +{ + static void set_aux_names(amrex::Vector& a_aux_names) + { + a_aux_names.resize(NUM_AUX); +#if NUM_AUX > 0 + for (int n = 0; n < NUM_AUX; ++n) { + a_aux_names[n] = "B_" + std::to_string(n); + } +#endif + } + + static void set_adv_names(amrex::Vector& a_adv_names) + { + a_adv_names.resize(NUM_ADV); +#if NUM_ADV > 0 + for (int n = 0; n < NUM_ADV; ++n) { + a_adv_names[n] = "A_" + std::to_string(n); + } +#endif + } + + static void problem_modify_ext_sources( + amrex::Real /*time*/, + amrex::Real /*dt*/, + const amrex::MultiFab& state_old, + const amrex::MultiFab& state_new, + amrex::MultiFab& ext_src, + int /*ng*/, + amrex::GeometryData const& /*geomdata*/, + ProbParmDevice const& prob_parm) + { + /* Notes: ext_src contains sources from velocity forcing coming in + This function should add to rather than overwrite ext_src. + */ + + const amrex::IntVect ngs(0); + auto const& Sns = state_new.const_arrays(); + auto const& Farrs = ext_src.arrays(); + + amrex::ParallelFor( + state_old, ngs, + [=] AMREX_GPU_DEVICE(int nbx, int i, int j, int k) noexcept { + // Source terms for the auxiliarry quantities + amrex::Real Bn = 0.0; + for (int n = 0; n < NUM_AUX; n++) { + Bn = Sns[nbx](i, j, k, UFX + n); + Farrs[nbx](i, j, k, UFX + n) += prob_parm.aux_srcstrength * Bn; + } + }); + amrex::Gpu::synchronize(); + } +}; +using ProblemSpecificFunctions = MyProblemSpecificFunctions; +#endif diff --git a/Exec/RegTests/AuxQuantities/prob.cpp b/Exec/RegTests/AuxQuantities/prob.cpp new file mode 100644 index 000000000..130dea857 --- /dev/null +++ b/Exec/RegTests/AuxQuantities/prob.cpp @@ -0,0 +1,98 @@ +#include "prob.H" + +void +pc_prob_close() +{ +} + +extern "C" { +void +amrex_probinit( + const int* /*init*/, + const int* /*name*/, + const int* /*namelen*/, + const amrex::Real* problo, + const amrex::Real* probhi) +{ + + // Parse params + { + amrex::ParmParse pp("prob"); + pp.query("p", PeleC::h_prob_parm_device->p); + pp.query("T", PeleC::h_prob_parm_device->T); + pp.query("Re", PeleC::h_prob_parm_device->Re); + pp.query("U", PeleC::h_prob_parm_device->U); + pp.query("Pr", PeleC::h_prob_parm_device->Pr); + pp.query("aux_xy_lo", PeleC::h_prob_parm_device->aux_xy_lo); + pp.query("aux_length", PeleC::h_prob_parm_device->aux_length); + pp.query("aux_height", PeleC::h_prob_parm_device->aux_height); + pp.query("aux_srcstrength", PeleC::h_prob_parm_device->aux_srcstrength); + } + + // Characteristic lengths + amrex::Real L = (probhi[0] - problo[0]); + amrex::Real H = probhi[1] - problo[1]; + + amrex::Real cp = 0.0; + amrex::Real cs = 0.0; + PeleC::h_prob_parm_device->massfrac[0] = 1.0; + + auto eos = pele::physics::PhysicsType::eos(); + eos.PYT2RE( + PeleC::h_prob_parm_device->p, PeleC::h_prob_parm_device->massfrac.begin(), + PeleC::h_prob_parm_device->T, PeleC::h_prob_parm_device->rho, + PeleC::h_prob_parm_device->eint); + eos.RTY2Cs( + PeleC::h_prob_parm_device->rho, PeleC::h_prob_parm_device->T, + PeleC::h_prob_parm_device->massfrac.begin(), cs); + eos.TY2Cp( + PeleC::h_prob_parm_device->T, PeleC::h_prob_parm_device->massfrac.begin(), + cp); + + PeleC::h_prob_parm_device->Ma = PeleC::h_prob_parm_device->U / cs; + + // Transport properties + auto& trans_parm = PeleC::trans_parms.host_parm(); + trans_parm.const_bulk_viscosity = 0.0; + trans_parm.const_diffusivity = 0.0; + trans_parm.const_viscosity = PeleC::h_prob_parm_device->rho * + PeleC::h_prob_parm_device->U * H / + PeleC::h_prob_parm_device->Re; + trans_parm.const_conductivity = + trans_parm.const_viscosity * cp / PeleC::h_prob_parm_device->Pr; + PeleC::trans_parms.sync_to_device(); + + // Output IC + amrex::Print() << "\nGenerate ic.txt" << std::endl; + std::ofstream ofs("ic.txt", std::ofstream::out); + amrex::Print(ofs) + << "L = " << L << "\nH = " << H << "\np = " << PeleC::h_prob_parm_device->p + << "\nT = " << PeleC::h_prob_parm_device->T << "\ngamma = " << eos.gamma + << "\ncs = " << cs << "\nU = " << PeleC::h_prob_parm_device->U + << "\nrho = " << PeleC::h_prob_parm_device->rho + << "\nviscosity = " << trans_parm.const_viscosity + << "\nconductivity = " << trans_parm.const_conductivity + << "\nRe = " << PeleC::h_prob_parm_device->Re + << "\nMa = " << PeleC::h_prob_parm_device->Ma + << "\nPr = " << PeleC::h_prob_parm_device->Pr << "\nNUM_AUX = " << NUM_AUX + << "\naux_xy_lo = " << PeleC::h_prob_parm_device->aux_xy_lo + << "\naux_length = " << PeleC::h_prob_parm_device->aux_length + << "\naux_height = " << PeleC::h_prob_parm_device->aux_height << std::endl; + ofs.close(); +} +} + +void +PeleC::problem_post_timestep() +{ +} + +void +PeleC::problem_post_init() +{ +} + +void +PeleC::problem_post_restart() +{ +} diff --git a/Exec/RegTests/AuxQuantities/prob_parm.H b/Exec/RegTests/AuxQuantities/prob_parm.H new file mode 100644 index 000000000..e1888f4d7 --- /dev/null +++ b/Exec/RegTests/AuxQuantities/prob_parm.H @@ -0,0 +1,31 @@ +#ifndef PROB_PARM_H +#define PROB_PARM_H + +#include +#include +#include + +struct ProbParmDevice +{ + amrex::Real p = 1013250.0; + amrex::Real T = 300.0; + amrex::Real rho = 0.0; + amrex::Real eint = 0.0; + amrex::Real U = 0.0; + amrex::Real Re = 100.0; + amrex::Real Ma = 0.1; + amrex::Real Pr = 0.7; + amrex::Real aux_IC = 10.0; + amrex::Real aux_xy_lo = -1.5; + amrex::Real aux_length = 0.5; + amrex::Real aux_height = 1.0; + amrex::Real aux_srcstrength = 0.0; + amrex::GpuArray massfrac = {1.0}; +}; + +struct ProbParmHost +{ + ProbParmHost() = default; +}; + +#endif diff --git a/Exec/RegTests/CMakeLists.txt b/Exec/RegTests/CMakeLists.txt index 74696e353..1b83f36d6 100644 --- a/Exec/RegTests/CMakeLists.txt +++ b/Exec/RegTests/CMakeLists.txt @@ -37,6 +37,7 @@ if(NOT PELE_EXCLUDE_BUILD_IN_CI) endif() if(PELE_DIM EQUAL 2) add_subdirectory(EB-FlowPastCylinder) + add_subdirectory(AuxQuantities) endif() if(PELE_DIM EQUAL 3) add_subdirectory(EB-C7) diff --git a/Source/Godunov.H b/Source/Godunov.H index 2432770a0..f3060e81c 100644 --- a/Source/Godunov.H +++ b/Source/Godunov.H @@ -438,12 +438,6 @@ pc_cmpflx( const int qc = QFS + n; pc_cmpflx_passive(ustar, flxrho, ql(iv, qc), qr(iv, qc), flx(iv, UFS + n)); } -#if NUM_AUX > 0 - for (int n = 0; n < NUM_AUX; n++) { - const int qc = QFX + n; - pc_cmpflx_passive(ustar, flxrho, ql(iv, qc), qr(iv, qc), flx(iv, UFX + n)); - } -#endif #if NUM_LIN > 0 for (int n = 0; n < NUM_LIN; n++) { const int qc = QLIN + n; @@ -527,13 +521,6 @@ pc_transdo( iv, ivpn, ivpt, n, UFS, QFS, cdtdx, flxrho, true, qnormp, qnormm, flxx, qp, qm, no_cov_face, lo_face_not_covered, hi_face_not_covered); } -#if NUM_AUX > 0 - for (int n = 0; n < NUM_AUX; n++) { - pc_transdo_passive( - iv, ivpn, ivpt, n, UFX, QFX, cdtdx, flxrho, true, qnormp, qnormm, flxx, - qp, qm, no_cov_face, lo_face_not_covered, hi_face_not_covered); - } -#endif #if NUM_LIN > 0 for (int n = 0; n < NUM_LIN; n++) { pc_transdo_passive( @@ -752,14 +739,6 @@ pc_transdd( rrnewr, rrnewl, srcq, qnormp, qnormm, flxx, flxy, qp, qm, no_cov_face, lo_face_not_covered, hi_face_not_covered); } -#if NUM_AUX > 0 - for (int n = 0; n < NUM_AUX; n++) { - pc_transdd_passive( - iv, ivpn, ivpt0, ivpt1, n, UFX, QFX, cdtdx0, cdtdx1, hdt, rrr, rrl, - rrnewr, rrnewl, srcq, qnormp, qnormm, flxx, flxy, qp, qm, no_cov_face, - lo_face_not_covered, hi_face_not_covered); - } -#endif #if NUM_LIN > 0 for (int n = 0; n < NUM_LIN; n++) { pc_transdd_passive( @@ -942,12 +921,6 @@ pc_transd( qnormm, flxx, qp, qm, no_cov_face, lo_face_not_covered, hi_face_not_covered); } - for (int n = 0; n < NUM_AUX; n++) { - pc_transd_passive( - iv, ivpn, ivpt, n, UFX, QFX, cdtdx, hdt, flxrho, true, srcQ, qnormp, - qnormm, flxx, qp, qm, no_cov_face, lo_face_not_covered, - hi_face_not_covered); - } for (int n = 0; n < NUM_LIN; n++) { pc_transd_passive( iv, ivpn, ivpt, n, ULIN, QLIN, cdtdx, hdt, 0., false, srcQ, qnormp, @@ -1140,7 +1113,7 @@ pc_artif_visc( ((dir == 2) && (k == domhi + 1) && (bchi == amrex::PhysBCType::noslipwall)); #endif - for (int n = 0; n < NVAR; ++n) { + for (int n = 0; n < NVAR; n++) { if (n != UTEMP) { #if (AMREX_SPACEDIM == 2) bool is_tang_vel = (dir == 0 && n == UMY) || (dir == 1 && n == UMX); @@ -1155,6 +1128,11 @@ pc_artif_visc( } } flx(iv, UTEMP) = 0.0; +#if NUM_AUX > 0 + for (int n = 0; n < NUM_AUX; n++) { + flx(iv, UFX + n) = 0.0; + } +#endif } // Host Functions diff --git a/Source/Hydro.H b/Source/Hydro.H index bb2f13a6f..74172a63e 100644 --- a/Source/Hydro.H +++ b/Source/Hydro.H @@ -53,8 +53,7 @@ pc_srctoprim( } #if NUM_AUX > 0 for (int n = 0; n < NUM_AUX; n++) { - srcq(i, j, k, QFX + n) = - (src(i, j, k, UFX + n) - q(i, j, k, QFX + n) * srcrho) * rhoinv; + srcq(i, j, k, QFX + n) = src(i, j, k, UFX + n); } #endif #if NUM_LIN > 0 diff --git a/Source/MOL.H b/Source/MOL.H index 3e86c8359..df112c688 100644 --- a/Source/MOL.H +++ b/Source/MOL.H @@ -94,12 +94,6 @@ mol_slope( (qaux(iv, QC) * qaux(iv, QC)) : 0.0; } -#if NUM_AUX > 0 - for (int n = 0; n < NUM_AUX; n++) { - dlft[QFX + n] = flagArrayL ? q(iv, QFX + n) - q(ivm, QFX + n) : 0.0; - drgt[QFX + n] = flagArrayR ? q(ivp, QFX + n) - q(iv, QFX + n) : 0.0; - } -#endif #if NUM_LIN > 0 for (int n = 0; n < NUM_LIN; n++) { dlft[QLIN + n] = flagArrayL ? q(iv, QLIN + n) - q(ivm, QLIN + n) : 0.0; diff --git a/Source/MOL.cpp b/Source/MOL.cpp index 62efb6b44..46fbe5c64 100644 --- a/Source/MOL.cpp +++ b/Source/MOL.cpp @@ -102,13 +102,6 @@ pc_compute_hyp_mol_flux( qtempr[R_ADV + n] = q(iv, QFA + n) - 0.5 * dq(iv, QFA + n); } #endif -#if NUM_AUX > 0 - const int R_AUX = R_Y + NUM_SPECIES; - for (int n = 0; n < NUM_AUX; n++) { - qtempl[R_AUX + n] = q(ivm, QFX + n) + 0.5 * dq(ivm, QFX + n); - qtempr[R_AUX + n] = q(iv, QFX + n) - 0.5 * dq(iv, QFX + n); - } -#endif #if NUM_LIN > 0 const int R_LIN = R_Y + NUM_SPECIES + NUM_AUX; for (int n = 0; n < NUM_LIN; n++) { @@ -149,13 +142,6 @@ pc_compute_hyp_mol_flux( flux_tmp[UFA + n]); } #endif -#if NUM_AUX > 0 - for (int n = 0; n < NUM_AUX; n++) { - pc_cmpflx_passive( - ustar, flux_tmp[URHO], qtempl[R_AUX + n], qtempr[R_AUX + n], - flux_tmp[UFX + n]); - } -#endif #if NUM_LIN > 0 for (int n = 0; n < NUM_LIN; n++) { pc_cmpflx_passive( @@ -180,14 +166,6 @@ pc_compute_hyp_mol_flux( flux_tmp[UFA + n]); } #endif -#if NUM_AUX > 0 - for (int n = 0; n < NUM_AUX; n++) { - pc_lax_cmpflx_passive( - qtempl[R_UN], qtempr[R_UN], qtempl[R_RHO], qtempr[R_RHO], - qtempl[R_AUX + n], qtempr[R_AUX + n], maxeigval, - flux_tmp[UFX + n]); - } -#endif #if NUM_LIN > 0 for (int n = 0; n < NUM_LIN; n++) { pc_lax_cmpflx_passive( @@ -325,14 +303,6 @@ pc_compute_hyp_mol_flux_eb( flux_tmp[UFA + n]); } #endif -#if NUM_AUX > 0 - const int R_AUX = R_Y + NUM_SPECIES; - for (int n = 0; n < NUM_AUX; n++) { - pc_cmpflx_passive( - ustar, flux_tmp[URHO], qtempl[R_AUX + n], qtempr[R_AUX + n], - flux_tmp[UFX + n]); - } -#endif #if NUM_LIN > 0 const int R_LIN = R_Y + NUM_SPECIES + NUM_AUX; for (int n = 0; n < NUM_LIN; n++) { @@ -357,15 +327,6 @@ pc_compute_hyp_mol_flux_eb( flux_tmp[UFA + n]); } #endif -#if NUM_AUX > 0 - const int R_AUX = R_Y + NUM_SPECIES; - for (int n = 0; n < NUM_AUX; n++) { - pc_lax_cmpflx_passive( - qtempl[R_UN], qtempr[R_UN], qtempl[R_RHO], qtempr[R_RHO], - qtempl[R_AUX + n], qtempr[R_AUX + n], maxeigval, - flux_tmp[UFX + n]); - } -#endif #if NUM_LIN > 0 const int R_LIN = R_Y + NUM_SPECIES + NUM_AUX; for (int n = 0; n < NUM_LIN; n++) { diff --git a/Source/PLM.H b/Source/PLM.H index eabac5115..7c231e0f8 100644 --- a/Source/PLM.H +++ b/Source/PLM.H @@ -300,11 +300,6 @@ pc_plm_d( for (int n = 0; n < NUM_SPECIES; n++) { pc_plm_d_passive(iv, ivp, QFS + n, spzerom, spzerop, slope, q, qp, qm); } -#if NUM_AUX > 0 - for (int n = 0; n < NUM_AUX; n++) { - pc_plm_d_passive(iv, ivp, QFX + n, spzerom, spzerop, slope, q, qp, qm); - } -#endif #if NUM_LIN > 0 for (int n = 0; n < NUM_LIN; n++) { pc_plm_d_passive(iv, ivp, QLIN + n, spzerom, spzerop, slope, q, qp, qm); @@ -480,12 +475,6 @@ pc_plm_d_eb( pc_plm_d_eb_passive( iv, ivp, QFS + n, spzerom, spzerop, slope, q, qp, qm, area); } -#if NUM_AUX > 0 - for (int n = 0; n < NUM_AUX; n++) { - pc_plm_d_eb_passive( - iv, ivp, QFX + n, spzerom, spzerop, slope, q, qp, qm, area); - } -#endif #if NUM_LIN > 0 for (int n = 0; n < NUM_LIN; n++) { pc_plm_d_eb_passive( diff --git a/Source/Setup.cpp b/Source/Setup.cpp index f870d1621..468301014 100644 --- a/Source/Setup.cpp +++ b/Source/Setup.cpp @@ -347,7 +347,7 @@ PeleC::variableSetUp() cnt++; set_scalar_bc(bc, phys_bc); bcs[cnt] = bc; - name[cnt] = "rho_" + aux_names[i]; + name[cnt] = aux_names[i]; } #ifdef PELE_USE_SOOT diff --git a/Source/Utilities.H b/Source/Utilities.H index 3f1e3b5f0..9837e82aa 100644 --- a/Source/Utilities.H +++ b/Source/Utilities.H @@ -220,7 +220,7 @@ pc_ctoprim( } #if NUM_AUX > 0 for (int n = 0; n < NUM_AUX; n++) { - q(i, j, k, QFX + n) = u(i, j, k, UFX + n) / rho; + q(i, j, k, QFX + n) = u(i, j, k, UFX + n); } #endif // Handle passive variables that are not per unit mass diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt index 8d8dafb69..a57b2888e 100644 --- a/Tests/CMakeLists.txt +++ b/Tests/CMakeLists.txt @@ -255,7 +255,10 @@ add_test_r(eb-c10 EB-C10) add_test_rv(eb-c11 EB-C11) add_test_rv(eb-c12 EB-C12) if(PELE_DIM EQUAL 2) - add_test_r(eb-flowpastcylinder-re500 EB-FlowPastCylinder) + add_test_r(eb-flowpastcylinder-re500 EB-FlowPastCylinder) +endif() +if(PELE_DIM EQUAL 2) + add_test_r(auxquantities_eb AuxQuantities) endif() # add_test_r(eb-c14 EB-C14) # disable due to FPE in ghost cells add_test_r(eb-converging-nozzle EB-ConvergingNozzle)