! !//////////////////////////////////////////////////////////////////////// ! ! ! The Problem File contains user defined procedures ! that are used to "personalize" i.e. define a specific ! problem to be solved. These procedures include initial conditions, ! exact solutions (e.g. for tests), etc. and allow modifications ! without having to modify the main code. ! ! The procedures, *even if empty* that must be defined are ! ! UserDefinedSetUp ! UserDefinedInitialCondition(mesh) ! UserDefinedPeriodicOperation(mesh) ! UserDefinedFinalize(mesh) ! UserDefinedTermination ! !//////////////////////////////////////////////////////////////////////// ! #include "Includes.h" module ProblemFileFunctions implicit none abstract interface subroutine UserDefinedStartup_f end subroutine UserDefinedStartup_f SUBROUTINE UserDefinedFinalSetup_f(mesh & #if defined(FLOW) || defined(SCALAR) , thermodynamics_ & , dimensionless_ & , refValues_ & #endif #ifdef CAHNHILLIARD , multiphase_ & #endif ) USE HexMeshClass use FluidData IMPLICIT NONE CLASS(HexMesh) :: mesh #if defined(FLOW) || defined(SCALAR) type(Thermodynamics_t), intent(in) :: thermodynamics_ type(Dimensionless_t), intent(in) :: dimensionless_ type(RefValues_t), intent(in) :: refValues_ #endif #ifdef CAHNHILLIARD type(Multiphase_t), intent(in) :: multiphase_ #endif END SUBROUTINE UserDefinedFinalSetup_f subroutine UserDefinedInitialCondition_f(mesh & #if defined(FLOW) || defined(SCALAR) , thermodynamics_ & , dimensionless_ & , refValues_ & #endif #ifdef CAHNHILLIARD , multiphase_ & #endif ) use smconstants use physicsstorage use hexmeshclass use fluiddata implicit none class(hexmesh) :: mesh #if defined(FLOW) || defined(SCALAR) type(Thermodynamics_t), intent(in) :: thermodynamics_ type(Dimensionless_t), intent(in) :: dimensionless_ type(RefValues_t), intent(in) :: refValues_ #endif #ifdef CAHNHILLIARD type(Multiphase_t), intent(in) :: multiphase_ #endif end subroutine UserDefinedInitialCondition_f #if defined(FLOW) || defined(SCALAR) subroutine UserDefinedState_f(x, t, nHat, Q, thermodynamics_, dimensionless_, refValues_) use SMConstants use PhysicsStorage use FluidData implicit none real(kind=RP), intent(in) :: x(NDIM) real(kind=RP), intent(in) :: t real(kind=RP), intent(in) :: nHat(NDIM) real(kind=RP), intent(inout) :: Q(NCONS) type(Thermodynamics_t), intent(in) :: thermodynamics_ type(Dimensionless_t), intent(in) :: dimensionless_ type(RefValues_t), intent(in) :: refValues_ end subroutine UserDefinedState_f subroutine UserDefinedGradVars_f(x, t, nHat, Q, U, GetGradients, thermodynamics_, dimensionless_, refValues_) use SMConstants use PhysicsStorage use FluidData use VariableConversion, only: GetGradientValues_f implicit none real(kind=RP), intent(in) :: x(NDIM) real(kind=RP), intent(in) :: t real(kind=RP), intent(in) :: nHat(NDIM) real(kind=RP), intent(in) :: Q(NCONS) real(kind=RP), intent(inout) :: U(NGRAD) procedure(GetGradientValues_f) :: GetGradients type(Thermodynamics_t), intent(in) :: thermodynamics_ type(Dimensionless_t), intent(in) :: dimensionless_ type(RefValues_t), intent(in) :: refValues_ end subroutine UserDefinedGradVars_f subroutine UserDefinedNeumann_f(x, t, nHat, Q, U_x, U_y, U_z, flux, thermodynamics_, dimensionless_, refValues_) use SMConstants use PhysicsStorage use FluidData implicit none real(kind=RP), intent(in) :: x(NDIM) real(kind=RP), intent(in) :: t real(kind=RP), intent(in) :: nHat(NDIM) real(kind=RP), intent(in) :: Q(NCONS) real(kind=RP), intent(in) :: U_x(NGRAD) real(kind=RP), intent(in) :: U_y(NGRAD) real(kind=RP), intent(in) :: U_z(NGRAD) real(kind=RP), intent(inout) :: flux(NCONS) type(Thermodynamics_t), intent(in) :: thermodynamics_ type(Dimensionless_t), intent(in) :: dimensionless_ type(RefValues_t), intent(in) :: refValues_ end subroutine UserDefinedNeumann_f #endif ! !//////////////////////////////////////////////////////////////////////// ! SUBROUTINE UserDefinedPeriodicOperation_f(mesh, time, dt, Monitors) use SMConstants USE HexMeshClass use MonitorsClass IMPLICIT NONE CLASS(HexMesh) :: mesh REAL(KIND=RP) :: time REAL(KIND=RP) :: dt type(Monitor_t), intent(in) :: monitors END SUBROUTINE UserDefinedPeriodicOperation_f ! !//////////////////////////////////////////////////////////////////////// ! #if defined(FLOW) || defined(SCALAR) subroutine UserDefinedSourceTermNS_f(x, Q, time, S, thermodynamics_, dimensionless_, refValues_ & #ifdef CAHNHILLIARD ,multiphase_ & #endif ) use SMConstants USE HexMeshClass use FluidData use PhysicsStorage IMPLICIT NONE real(kind=RP), intent(in) :: x(NDIM) real(kind=RP), intent(in) :: Q(NCONS) real(kind=RP), intent(in) :: time real(kind=RP), intent(inout) :: S(NCONS) type(Thermodynamics_t), intent(in) :: thermodynamics_ type(Dimensionless_t), intent(in) :: dimensionless_ type(RefValues_t), intent(in) :: refValues_ #ifdef CAHNHILLIARD type(Multiphase_t), intent(in) :: multiphase_ #endif end subroutine UserDefinedSourceTermNS_f #endif ! !//////////////////////////////////////////////////////////////////////// ! SUBROUTINE UserDefinedFinalize_f(mesh, time, iter, maxResidual & #if defined(FLOW) || defined(SCALAR) , thermodynamics_ & , dimensionless_ & , refValues_ & #endif #ifdef CAHNHILLIARD , multiphase_ & #endif , monitors, & elapsedTime, & CPUTime ) use SMConstants USE HexMeshClass use FluidData use MonitorsClass IMPLICIT NONE CLASS(HexMesh) :: mesh REAL(KIND=RP) :: time integer :: iter real(kind=RP) :: maxResidual #if defined(FLOW) || defined(SCALAR) type(Thermodynamics_t), intent(in) :: thermodynamics_ type(Dimensionless_t), intent(in) :: dimensionless_ type(RefValues_t), intent(in) :: refValues_ #endif #ifdef CAHNHILLIARD type(Multiphase_t), intent(in) :: multiphase_ #endif type(Monitor_t), intent(in) :: monitors real(kind=RP), intent(in) :: elapsedTime real(kind=RP), intent(in) :: CPUTime END SUBROUTINE UserDefinedFinalize_f SUBROUTINE UserDefinedTermination_f implicit none END SUBROUTINE UserDefinedTermination_f end interface end module ProblemFileFunctions SUBROUTINE UserDefinedStartup ! ! -------------------------------- ! Called before any other routines ! -------------------------------- ! IMPLICIT NONE END SUBROUTINE UserDefinedStartup ! !//////////////////////////////////////////////////////////////////////// ! SUBROUTINE UserDefinedFinalSetup(mesh & #if defined(FLOW) || defined(SCALAR) , thermodynamics_ & , dimensionless_ & , refValues_ & #endif #ifdef CAHNHILLIARD , multiphase_ & #endif ) ! ! ---------------------------------------------------------------------- ! Called after the mesh is read in to allow mesh related initializations ! or memory allocations. ! ---------------------------------------------------------------------- ! USE HexMeshClass use PhysicsStorage use FluidData IMPLICIT NONE CLASS(HexMesh) :: mesh #if defined(FLOW) || defined(SCALAR) type(Thermodynamics_t), intent(in) :: thermodynamics_ type(Dimensionless_t), intent(in) :: dimensionless_ type(RefValues_t), intent(in) :: refValues_ #endif #ifdef CAHNHILLIARD type(Multiphase_t), intent(in) :: multiphase_ #endif END SUBROUTINE UserDefinedFinalSetup ! !//////////////////////////////////////////////////////////////////////// ! subroutine UserDefinedInitialCondition(mesh & #if defined(FLOW) || defined(SCALAR) , thermodynamics_ & , dimensionless_ & , refValues_ & #endif #ifdef CAHNHILLIARD , multiphase_ & #endif ) ! ! ------------------------------------------------ ! called to set the initial condition for the flow ! - by default it sets an uniform initial ! condition. ! ------------------------------------------------ ! use smconstants use physicsstorage use hexmeshclass use fluiddata implicit none class(hexmesh) :: mesh #if defined(FLOW) || defined(SCALAR) type(Thermodynamics_t), intent(in) :: thermodynamics_ type(Dimensionless_t), intent(in) :: dimensionless_ type(RefValues_t), intent(in) :: refValues_ #endif #ifdef CAHNHILLIARD type(Multiphase_t), intent(in) :: multiphase_ #endif ! ! --------------- ! local variables ! --------------- ! integer :: eid, i, j, k real(kind=RP) :: qq, u, v, w, p #if defined(NAVIERSTOKES) real(kind=RP) :: Q(NCONS), phi, theta #endif ! ! --------------------------------------- ! Navier-Stokes default initial condition ! --------------------------------------- ! #if defined(NAVIERSTOKES) associate ( gammaM2 => dimensionless_ % gammaM2, & gamma => thermodynamics_ % gamma ) theta = refvalues_ % AOAtheta*(pi/180.0_RP) phi = refvalues_ % AOAphi*(pi/180.0_RP) do eID = 1, mesh % no_of_elements associate( Nx => mesh % elements(eID) % Nxyz(1), & ny => mesh % elemeNts(eID) % nxyz(2), & Nz => mesh % elements(eID) % Nxyz(3) ) do k = 0, Nz; do j = 0, Ny; do i = 0, Nx qq = 1.0_RP u = qq*cos(theta)*cos(phi) v = qq*sin(theta)*cos(phi) w = qq*sin(phi) q(1) = 1.0_RP p = 1.0_RP/(gammaM2) q(2) = q(1)*u q(3) = q(1)*v q(4) = q(1)*w q(5) = p/(gamma - 1._RP) + 0.5_RP*q(1)*(u**2 + v**2 + w**2) mesh % elements(eID) % storage % q(:,i,j,k) = q end do; end do; end do end associate end do end associate #endif ! ! ------------------------------------------------------ ! Incompressible Navier-Stokes default initial condition ! ------------------------------------------------------ ! #if defined(INCNS) do eID = 1, mesh % no_of_elements associate( Nx => mesh % elements(eID) % Nxyz(1), & ny => mesh % elemeNts(eID) % nxyz(2), & Nz => mesh % elements(eID) % Nxyz(3) ) do k = 0, Nz; do j = 0, Ny; do i = 0, Nx mesh % elements(eID) % storage % q(:,i,j,k) = [1.0_RP, 1.0_RP,0.0_RP,0.0_RP,0.0_RP] end do; end do; end do end associate end do #endif ! ! --------------------------------------- ! Cahn-Hilliard default initial condition ! --------------------------------------- ! #ifdef CAHNHILLIARD call random_seed() do eid = 1, mesh % no_of_elements associate( Nx => mesh % elements(eid) % Nxyz(1), & Ny => mesh % elements(eid) % Nxyz(2), & Nz => mesh % elements(eid) % Nxyz(3) ) associate(e => mesh % elements(eID) % storage) call random_number(e % c) e % c = 2.0_RP * (e % c - 0.5_RP) end associate end associate end do #endif end subroutine UserDefinedInitialCondition #if defined(FLOW) || defined(SCALAR) subroutine UserDefinedState1(x, t, nHat, Q, thermodynamics_, dimensionless_, refValues_) use SMConstants use PhysicsStorage use FluidData implicit none real(kind=RP), intent(in) :: x(NDIM) real(kind=RP), intent(in) :: t real(kind=RP), intent(in) :: nHat(NDIM) real(kind=RP), intent(inout) :: Q(NCONS) type(Thermodynamics_t), intent(in) :: thermodynamics_ type(Dimensionless_t), intent(in) :: dimensionless_ type(RefValues_t), intent(in) :: refValues_ end subroutine UserDefinedState1 subroutine UserDefinedGradVars1(x, t, nHat, Q, U, GetGradients, thermodynamics_, dimensionless_, refValues_) use SMConstants use PhysicsStorage use FluidData use VariableConversion, only: GetGradientValues_f implicit none real(kind=RP), intent(in) :: x(NDIM) real(kind=RP), intent(in) :: t real(kind=RP), intent(in) :: nHat(NDIM) real(kind=RP), intent(in) :: Q(NCONS) real(kind=RP), intent(inout) :: U(NGRAD) procedure(GetGradientValues_f) :: GetGradients type(Thermodynamics_t), intent(in) :: thermodynamics_ type(Dimensionless_t), intent(in) :: dimensionless_ type(RefValues_t), intent(in) :: refValues_ end subroutine UserDefinedGradVars1 subroutine UserDefinedNeumann1(x, t, nHat, Q, U_x, U_y, U_z, flux, thermodynamics_, dimensionless_, refValues_) use SMConstants use PhysicsStorage use FluidData implicit none real(kind=RP), intent(in) :: x(NDIM) real(kind=RP), intent(in) :: t real(kind=RP), intent(in) :: nHat(NDIM) real(kind=RP), intent(in) :: Q(NCONS) real(kind=RP), intent(in) :: U_x(NGRAD) real(kind=RP), intent(in) :: U_y(NGRAD) real(kind=RP), intent(in) :: U_z(NGRAD) real(kind=RP), intent(inout) :: flux(NCONS) type(Thermodynamics_t), intent(in) :: thermodynamics_ type(Dimensionless_t), intent(in) :: dimensionless_ type(RefValues_t), intent(in) :: refValues_ end subroutine UserDefinedNeumann1 #endif ! !//////////////////////////////////////////////////////////////////////// ! SUBROUTINE UserDefinedPeriodicOperation(mesh, time, dt, Monitors) ! ! ---------------------------------------------------------- ! Called before every time-step to allow periodic operations ! to be performed ! ---------------------------------------------------------- ! use SMConstants USE HexMeshClass use MonitorsClass IMPLICIT NONE CLASS(HexMesh) :: mesh REAL(KIND=RP) :: time REAL(KIND=RP) :: dt type(Monitor_t), intent(in) :: monitors END SUBROUTINE UserDefinedPeriodicOperation ! !//////////////////////////////////////////////////////////////////////// ! #if defined(FLOW) || defined(SCALAR) subroutine UserDefinedSourceTermNS(x, Q, time, S, thermodynamics_, dimensionless_, refValues_ & #ifdef CAHNHILLIARD , multiphase_ & #endif ) ! ! -------------------------------------------- ! Called to apply source terms to the equation ! -------------------------------------------- ! use SMConstants USE HexMeshClass use PhysicsStorage use FluidData IMPLICIT NONE real(kind=RP), intent(in) :: x(NDIM) real(kind=RP), intent(in) :: Q(NCONS) real(kind=RP), intent(in) :: time real(kind=RP), intent(inout) :: S(NCONS) type(Thermodynamics_t), intent(in) :: thermodynamics_ type(Dimensionless_t), intent(in) :: dimensionless_ type(RefValues_t), intent(in) :: refValues_ #ifdef CAHNHILLIARD type(Multiphase_t), intent(in) :: multiphase_ #endif ! ! --------------- ! Local variables ! --------------- ! integer :: i, j, k, eID ! ! Usage example ! ------------- ! S(:) = x(1) + x(2) + x(3) + time end subroutine UserDefinedSourceTermNS #endif ! !//////////////////////////////////////////////////////////////////////// ! SUBROUTINE UserDefinedFinalize(mesh, time, iter, maxResidual & #if defined(FLOW) || defined(SCALAR) , thermodynamics_ & , dimensionless_ & , refValues_ & #endif #ifdef CAHNHILLIARD , multiphase_ & #endif , monitors, & elapsedTime, & CPUTime ) ! ! -------------------------------------------------------- ! Called after the solution computed to allow, for example ! error tests to be performed ! -------------------------------------------------------- ! use SMConstants USE HexMeshClass use PhysicsStorage use FluidData use MonitorsClass IMPLICIT NONE CLASS(HexMesh) :: mesh REAL(KIND=RP) :: time integer :: iter real(kind=RP) :: maxResidual #if defined(FLOW) || defined(SCALAR) type(Thermodynamics_t), intent(in) :: thermodynamics_ type(Dimensionless_t), intent(in) :: dimensionless_ type(RefValues_t), intent(in) :: refValues_ #endif #ifdef CAHNHILLIARD type(Multiphase_t), intent(in) :: multiphase_ #endif type(Monitor_t), intent(in) :: monitors real(kind=RP), intent(in) :: elapsedTime real(kind=RP), intent(in) :: CPUTime END SUBROUTINE UserDefinedFinalize ! !//////////////////////////////////////////////////////////////////////// ! SUBROUTINE UserDefinedTermination ! ! ----------------------------------------------- ! Called at the the end of the main driver after ! everything else is done. ! ----------------------------------------------- ! IMPLICIT NONE END SUBROUTINE UserDefinedTermination