dns-hit3d-fdm/m_force.f90
ignis c8d81aaf92 model spectrum written after generating velocity
tp_field
convdt is now based on absolute maximum
sumwrate calculation is moved
omp private += i,j,k
model_e_spec
mpi_init_thread
file_units and tar_lo
kolmogorov scales
2014-05-17 15:40:19 +09:00

292 lines
8.4 KiB
Fortran

module m_force
use m_parameters
implicit none
integer*4 :: n_forced_nodes, n_forced_nodes_total
! coordinated of the forced nodes
integer, allocatable :: ifn(:), jfn(:), kfn(:), k_shell(:)
contains
subroutine m_force_init
use m_parameters
use x_fftw
implicit none
integer :: i, j, k, n, n_shell
real*8 :: dissi_spec(kmax)
real*8 :: eps_v_temp,eta_temp,uvar_temp,sctmp_temp,x_length_temp,u_prime_temp,tau_eta_temp
! if flow is not forced, return
if (flow_type .ne. 1) return
if (task.ne.'hydro') return
select case (force_type)
case (1:2)
if (force_type == 1) then
! Machiels forcing (see article in PRL #79(18) p.3411)
write(out,*) "Forcing #1: Machiels forcing - setting up"
else
! Fully Controlled Deterministic Forcing Scheme (FC-DFS)
write(out,*) "Forcing #2: FC-DFS - setting up"
end if
call flush(out)
! find out how many nodes are we forcing and book them
n_forced_nodes = 0
n_forced_nodes_total = 0
do k = 1,nz
do j = 1,ny
do i = 1,nx
n_shell = nint(sqrt(real(akx(i)**2 + aky(k)**2 + akz(j)**2, 4)))
if (n_shell .gt. 0 .and. n_shell .le. kfmax) then
n_forced_nodes = n_forced_nodes + 1
end if
end do
end do
end do
! reducing to the master process to find out the total number of forced nodes
!!$ write(out,*) 'before reducing'; call flush(out)
count = 1
call MPI_REDUCE(n_forced_nodes, n_forced_nodes_total, count, &
MPI_INTEGER4,MPI_SUM,0,MPI_COMM_TASK,mpi_err)
! writing out the # of forced nodes
write(out,'(a40,3x,i10)') 'Number of forced nodes for this process:',n_forced_nodes
if (myid.eq.0) write(out,'(a40,3x,i10)') ' total number:',n_forced_nodes_total
call flush(out)
! allocating arrays for the coordinates of the forced nodes
allocate(ifn(n_forced_nodes), jfn(n_forced_nodes), kfn(n_forced_nodes), &
k_shell(n_forced_nodes))
! filling up the arrays
n = 0
do k = 1,nz
do j = 1,ny
do i = 1,nx
n_shell = nint(sqrt(real(akx(i)**2 + aky(k)**2 + akz(j)**2, 4)))
if (n_shell .gt. 0 .and. n_shell .le. kfmax) then
n = n + 1
ifn(n) = i
jfn(n) = j
kfn(n) = k
k_shell(n) = n_shell
end if
end do
end do
end do
! Restarting setup
allocate(model_e_spec(kmax)) ; model_e_spec=zip
k0=(SQRT(two*PI))/t_length
model_A=16.0*(SQRT(two/PI))*(t_u_prime**2.0)/k0
do i=1,kmax
k=real(i,8)
model_e_spec(i)=model_A*((k/k0)**4.0)*exp(-2.0*((k/k0)**2.0))
enddo
!!$ ! writing out the nodes
!!$ do n = 1,n_forced_nodes
!!$ write(out,"(3i4)") ifn(n),jfn(n),kfn(n)
!!$ end do
!!$ call flush(out)
case default
write(out,*) 'WRONG FORCE TYPE:',force_type
write(out,*) 'STOPPING'
call flush(out)
stop
end select
return
end subroutine m_force_init
!================================================================================
subroutine force_velocity
! adding forcing to the arrays wrk(:,:,:,1:3) that already contain the RHS for velocities
use m_openmpi
use m_io
use m_parameters
use m_fields
use m_work
use x_fftw
use m_stats
implicit none
integer :: i, j, k, n_shell, n
real*8 :: fac, fac2
real*8 :: kk
real*8 :: mean_eps,tau_f
real*8 :: kfmax8
real*8 :: F_k(kmax),ff_k(kmax),eps_f(kmax)
real*8 :: alpha,sum_F_Em,sum_F_Es
real*8 :: energy_model
select case (force_type)
case (1)
! Machiels forcing (see article in PRL #79(18) p.3411)
! write(out,*) "Machiels forcing"; call flush(out)
e_spec = zip
e_spec1 = zip
hits = 0
hits1 = 0
! need this normalization factor because the FFT is unnormalized
fac = one / real(nx*ny*nz_all)**2
! assembling the total energy in each shell
do k = 1,nz
do j = 1,ny
do i = 1,nx
n_shell = nint(sqrt(real(akx(i)**2 + aky(k)**2 + akz(j)**2, 4)))
if (n_shell .gt. 0 .and. n_shell .le. kfmax) then
fac2 = fac * (fields(i,j,k,1)**2 + fields(i,j,k,2)**2 + fields(i,j,k,3)**2)
if (akx(i).eq.0.d0) fac2 = fac2 * 0.5d0
e_spec1(n_shell) = e_spec1(n_shell) + fac2
end if
end do
end do
end do
! reducing the number of hits and energy to two arrays on master node
count = kfmax
call MPI_REDUCE(e_spec1,e_spec,count,MPI_REAL8,MPI_SUM,0,MPI_COMM_TASK,mpi_err)
! getting the total energy in the region [0:kfmax] by integrating the spectrum
if (myid.eq.0) energy = sum(e_spec(1:kfmax))
! broadcasting the current energy in the forcing range of wavenumbers
count = 1
call MPI_BCAST(energy,count,MPI_REAL8,0,MPI_COMM_TASK,mpi_err)
! now applying the forcing to the RHS for velocities (wrk(:,:,:,1:3))
fac = FAMP / energy
do n = 1,n_forced_nodes
n_shell = k_shell(n)
i = ifn(n)
j = jfn(n)
k = kfn(n)
wrk(i,j,k,1) = wrk(i,j,k,1) + fac * fields(i,j,k,1)
wrk(i,j,k,2) = wrk(i,j,k,2) + fac * fields(i,j,k,2)
wrk(i,j,k,3) = wrk(i,j,k,3) + fac * fields(i,j,k,3)
end do
!------------------------------------------------------------------------
! case (2)
! New forcing scheme added by ksj and edited by J. Kwon, 2014
! Ref. Flow, Turbulence and Combustion 73: 133-167, 2004
! by L. Guichard, J. Reveillon and R. Hauguel
! ------------------------------------------------------------------------
case (2)
! Fully Controlled Deterministic Forcing Scheme (FC-DFS)
e_spec = zip
e_spec1 = zip
hits = 0
hits1 = 0
! need this normalization factor because the FFT is unnormalized
fac = one / real(nx*ny*nz_all)**2
! assembling the total energy in each shell
do k = 1,nz
do j = 1,ny
do i = 1,nx
n_shell = nint(sqrt(real(akx(i)**2 + aky(k)**2 + akz(j)**2, 4)))
if (n_shell .gt. 0 .and. n_shell .le. kmax) then
fac2 = fac * (fields(i,j,k,1)**2 + fields(i,j,k,2)**2 + fields(i,j,k,3)**2)
if (akx(i).eq.0.d0) fac2 = fac2 * 0.5d0
e_spec1(n_shell) = e_spec1(n_shell) + fac2
end if
end do
end do
end do
! reducing the number of hits and energy to two arrays on master node
count = kmax
call MPI_REDUCE(e_spec1,e_spec,count,MPI_REAL8,MPI_SUM,0,MPI_COMM_TASK,mpi_err)
count = kmax
call MPI_BCAST(e_spec,count,MPI_REAL8,0,MPI_COMM_TASK,mpi_err)
! getting the total energy by integrating the spectrum
energy = sum(e_spec(1:kmax))
mean_eps = zip
tau_f = zip
eps_f = zip
F_k = zip
ff_k = zip
energy_model = sum(model_e_spec(1:kmax))
do i = 1,kmax
eps_f(i) = e_spec(i) * real(i**2,8) * two * nu
end do
mean_eps = sum(eps_f(1:kmax))
tau_f=c_f*sqrt(nu/mean_eps)
kfmax8=real(kfmax,8)
do i=1,kfmax
kk=real(i,8)
F_k(i)=(1.-exp(-((kk-kfmax8)**2.)/(delta_k**2.)))/(1.-exp(-(kfmax8**2.)/(delta_k**2.)))
enddo
sum_F_Em=zip
sum_F_Es=zip
do i=1,kfmax
sum_F_Em=sum_F_Em+F_k(i)*model_e_spec(i)
sum_F_Es=sum_F_Es+F_k(i)*e_spec(i)
enddo
alpha=(energy_model-energy+tau_f*mean_eps+sum_F_Es)/sum_F_Em
do i=1,kfmax
ff_k(i)=F_k(i)/(two*e_spec(i))*(alpha*model_e_spec(i)-e_spec(i))
enddo
do n = 1,n_forced_nodes
n_shell = k_shell(n)
i = ifn(n)
j = jfn(n)
k = kfn(n)
wrk(i,j,k,1) = wrk(i,j,k,1) + ff_k(n_shell)/tau_f * fields(i,j,k,1)
wrk(i,j,k,2) = wrk(i,j,k,2) + ff_k(n_shell)/tau_f * fields(i,j,k,2)
wrk(i,j,k,3) = wrk(i,j,k,3) + ff_k(n_shell)/tau_f * fields(i,j,k,3)
end do
case default
write(out,*) "WRONG FORCE_TYPE:",force_type
stop
end select
return
end subroutine force_velocity
end module m_force