Solver: CDIFS
Description: A vortex dipole is a 2D vortex pair that is self-propelling
References: R. Verzicco, P. Orlandi, A finite-difference scheme for three-dimensional incompressible flows in cylindrical coordinates, J. Comput. Phys. 123 (1996) 402–414 O. Desjardins, et al, High order conservative finite difference scheme for variable desnity low Mach number turbulent flows, J. Comput. Phys. 227 (2008) 7125-7159
| Type | Attributes | Name | Initial | |||
|---|---|---|---|---|---|---|
| type(block_obj) | :: | block |
Block object manages the Cartesian grid |
|||
| type(parallel_obj) | :: | parallel |
Utility that handles parallel (MPI) functions |
|||
| type(parser_obj) | :: | parser |
Utility that parses input files |
Bessel function J0(x).
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| real(kind=wp), | intent(in) | :: | x |
Bessel function J1(x).
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| real(kind=wp), | intent(in) | :: | x |
Defines boundary conditions.
Builds and writes block file.
Builds and writes initial flow field.
program main !>-------------------------------------------------------------------------- ! Program: Vortex Dipole ! Author: Mohamed Houssem Kasbaoui ! ! Solver: CDIFS ! ! Description: A vortex dipole is a 2D vortex pair that is self-propelling ! ! References: ! R. Verzicco, P. Orlandi, A finite-difference scheme for ! three-dimensional incompressible flows in cylindrical coordinates, ! J. Comput. Phys. 123 (1996) 402–414 ! O. Desjardins, et al, High order conservative finite difference scheme ! for variable desnity low Mach number turbulent flows, J. Comput. Phys. ! 227 (2008) 7125-7159 ! -------------------------------------------------------------------------- use leapKinds use leapParser use leapParallel use leapBlock use leapEulerian implicit none type(parallel_obj) :: parallel !! Utility that handles parallel (MPI) functions type(parser_obj) :: parser !! Utility that parses input files type(block_obj) :: block !! Block object manages the Cartesian grid ! Initialize parser call parser%Initialize() ! Parse input file call parser%ParseFile() ! Initialize parallel environment call parallel%Initialize() ! Set the block info call SetUpCaseBlock() ! Set the initial fields call SetUpCaseFields() ! Set boundary conditions call SetUpCaseBCS() ! Free up data call block%Finalize() call parser%Finalize() call parallel%Finalize() contains subroutine SetUpCaseBlock() !> Builds and writes block file. implicit none ! Work variables character(str64) :: filename real(wp) :: L(3) integer :: N(3) integer :: ngc integer :: Nb(3) real(wp) :: xlo(3) real(wp) :: xhi(3) integer :: ilo(3) integer :: ihi(3) ! Get info from parser call parser%Get("Block file", filename) call parser%Get("Domain size", L ) call parser%Get("Grid points", N ) call parser%Get("Ghost cells", ngc ) call parser%Get("Partition", Nb ) ! Domain extents xlo=-0.5_wp*L ; xhi= 0.5_wp*L ilo=[1,1,1] ; ihi=N ! Initialize the main block call block%Initialize(ngc,parallel) ! Setup the domain periodicity call block%SetPeriodicity([.true.,.true.,.true.]) ! Create a uniform block call block%SetupUniformGrid(xlo,xhi,ilo,ihi) ! Partition block for parallel initializations call block%Partition(Nb) ! Write block to disk call block%Write(filename) return end subroutine SetUpCaseBlock subroutine SetUpCaseFields() !> Builds and writes initial flow field. implicit none ! Work variables type(Eulerian_set) :: fields type(eulerian_obj_r) :: V(3) type(eulerian_obj_r) :: P character(str64) :: filename real(wp) :: L(3) real(wp) :: r real(wp) :: a real(wp) :: Vd real(wp) :: Vr, Vt real(wp) :: costheta real(wp) :: sintheta real(wp) :: rho real(wp) :: mu real(wp) :: Rey integer :: i,j,k real(wp),parameter :: twoPi=8.0_wp*atan(1.0_wp) ! Bessel firt root and constant C real(wp),parameter :: a1 = 3.8317059702075123115_wp real(wp) :: C ! Get info from parser call parser%Get("Fields IC file", filename) call parser%Get("Domain size", L ) call parser%Get("Dipole radius", a ) call parser%Get("Dipole velocity", Vd ) call parser%Get("Fluid density", rho ) call parser%Get("Fluid viscosity", mu ) ! Initialize fields container call fields%Initialize(block,parallel) ! Add fields to container (this will allocate data) call fields%Add('V1', 1, V(1)) call fields%Add('V2', 2, V(2)) call fields%Add('V3', 3, V(3)) call fields%Add('P', 0, P ) associate (lo => block%lo, hi=> block%hi, & x =>block%x , y =>block%y, z => block%z, & xm=>block%xm, ym=>block%ym, zm=> block%zm) V(1) = 0.0_wp V(2) = 0.0_wp V(3) = 0.0_wp P = 0.0_wp ! Compute the constant C = 2.0_wp/J0(a1) do k=lo(3),hi(3) do j=lo(2),hi(2) do i=lo(1),hi(1) ! U - velocity r = sqrt((x(i))**2+(ym(j))**2) costheta= x (i)/(r+epsilon(1.0_wp)) sintheta= ym(j)/(r+epsilon(1.0_wp)) if ((r/a).le.1.0_wp) then r = a1*r/a Vr = Vd * ( C*J1(r)/(r+epsilon(1.0_wp)) - 1.0_WP ) * costheta Vt = Vd * ( 1.0_WP - C*(J0(r)-J1(r)/(r+epsilon(1.0_wp))) ) * sintheta else Vr = - Vd/(r/a)**2 * costheta Vt = - Vd/(r/a)**2 * sintheta end if V(1)%cell(i,j,k) = Vr*costheta-Vt*sintheta ! V - velocity r = sqrt((xm(i))**2+(y(j))**2) costheta= xm(i)/(r+epsilon(1.0_wp)) sintheta= y (j)/(r+epsilon(1.0_wp)) if ((r/a).le.1.0_wp) then r = a1*r/a Vr = Vd * ( C*J1(r)/(r+epsilon(1.0_wp)) - 1.0_WP ) * costheta Vt = Vd * ( 1.0_WP - C*(J0(r)-J1(r)/(r+epsilon(1.0_wp))) ) * sintheta else Vr = - Vd/(r/a)**2 * costheta Vt = - Vd/(r/a)**2 * sintheta end if V(2)%cell(i,j,k) = Vr*sintheta+Vt*costheta end do end do end do end associate ! Write some info to stdout if (parallel%RankIsRoot()) then ! Reynolds number Rey = rho*Vd*a/(mu+epsilon(1.0_wp)) write(*,*) "Reynolds number = ", Rey end if ! Write data to disk call fields%SetWriteFileName(filename) call fields%Write(0,0.0_wp) ! Clear data call fields%Finalize() return end subroutine SetUpCaseFields subroutine SetUpCaseBCS() !> Defines boundary conditions. use leapBC implicit none ! Work variables type(bc_set) :: bcs ! Initialize utility that handles boundary conditions call bcs%Initialize(block,parallel) ! Fully-periodic, nothing to do ! Write boundary conditions call bcs%Write(0,0.0_wp) ! Clear data call bcs%Finalize() return end subroutine SetUpCaseBCS pure function J0(x) result(val) !> Bessel function J0(x). implicit none real(wp), intent(in) :: x real(wp) :: val ! work variables real(wp) :: ax,xx,z,y real(wp), parameter :: r(6) = [ 57568490574.0_wp,-13362590354.0_wp, 651619640.7_wp,& -11214424.18_wp, 77392.33017_wp, -184.9052456_wp] real(wp), parameter :: s(6) = [ 57568490411.0_wp, 1029532985.0_wp, 9494680.718_wp, & 59272.64853_wp, 267.8532712_wp, 1.0_wp] real(wp), parameter :: p(5) = [ 1.0_wp,-0.1098628627E-2_wp, 0.2734510407E-4_wp,& -0.2073370639E-5_wp, 0.2093887211E-6_wp] real(wp), parameter :: q(5) = [-.1562499995E-1_wp,.1430488765E-3_wp,-.6911147651E-5_wp,& .7621095161E-6_wp,-.934945152E-7_wp] if (abs(x).lt.8.0_wp) then y = x**2 val = (r(1)+y*(r(2)+y*(r(3)+y*(r(4)+y*(r(5)+y*r(6)))))) / & (s(1)+y*(s(2)+y*(s(3)+y*(s(4)+y*(s(5)+y*s(6)))))) else ax = abs(x) z = 8.0_wp/ax y = z**2 xx = ax-.785398164_wp val = sqrt(.636619772_wp/ax)*(cos(xx)*(p(1)+y*(p(2)+y*(p(3)+y*(p(4)+y*p(5))))) - & z*sin(xx)*(q(1)+y*(q(2)+y*(q(3)+y*(q(4)+y*q(5)))))) end if return end function J0 pure function J1(x) result(val) !> Bessel function J1(x). implicit none real(wp), intent(in) :: x real(wp) :: val ! work variables real(wp) :: ax,xx,z,y real(wp), parameter :: r(6) = [ 72362614232.0_wp,-7895059235.0_wp, 242396853.1_wp, & -2972611.439_wp, 15704.48260_wp, -30.16036606_wp] real(wp), parameter :: s(6) = [144725228442.0_wp, 2300535178.0_wp, 18583304.74_wp, & 99447.43394_wp, 376.9991397_wp, 1.0_wp] real(wp), parameter :: p(5) = [1.0_wp, 0.183105E-2_wp, -0.3516396496E-4_wp, & 0.2457520174E-5_wp, -0.240337019E-6_wp] real(wp), parameter :: q(5) = [ .04687499995_wp,-.2002690873E-3_wp,.8449199096E-5_wp,& -.88228987E-6_wp,.105787412E-6_wp] if (abs(x).lt.8.0_wp) then y = x**2 val = x*(r(1)+y*(r(2)+y*(r(3)+y*(r(4)+y*(r(5)+y*r(6)))))) / & (s(1)+y*(s(2)+y*(s(3)+y*(s(4)+y*(s(5)+y*s(6)))))) else ax = abs(x) z = 8.0_wp/ax y = z**2 xx = ax-2.356194491_wp val = sqrt(.636619772_wp/ax)*(cos(xx)*(p(1)+y*(p(2)+y*(p(3)+y*(p(4)+y*p(5))))) - & z*sin(xx)*(q(1)+y*(q(2)+y*(q(3)+y*(q(4)+y*q(5))))))*sign(1.0_wp,x) end if return end function J1 end program main