92 = 2.50662827463100050241576528481104525300698674
98 REAL(C_DOUBLE),
POINTER :: mass2d(:,:)
99 COMPLEX(C_DOUBLE_COMPLEX),
POINTER &
101 REAL,
DIMENSION(:,:,:),
POINTER :: fmass2d_real
102 INTEGER(C_INTPTR_T) :: local_joff
103 REAL,
DIMENSION(:),
POINTER :: kx
104 REAL,
DIMENSION(:),
POINTER :: ky
106 REAL,
DIMENSION(:),
POINTER :: joff, jrem
108 LOGICAL :: calc_fmass2d
110 INTEGER(C_INTPTR_T) :: c_inum, c_jnum
111 INTEGER(C_INTPTR_T) :: alloc_local, local_jnum
112 TYPE(c_ptr) :: mass2d_pointer
113 TYPE(c_ptr) :: fmass2d_pointer
151 CLASS(gravity_sboxspectral),
INTENT(INOUT) :: this
152 CLASS(mesh_base),
INTENT(IN) :: Mesh
153 CLASS(physics_base),
INTENT(IN) :: Physics
154 TYPE(Dict_TYP),
POINTER :: config,IO
156 INTEGER :: gravity_number
157 INTEGER :: err, valwrite, i
158 #if defined(HAVE_FFTW) && defined(PARALLEL) 159 INTEGER(C_INTPTR_T) :: C_INUM,C_JNUM
160 INTEGER(C_INTPTR_T) :: alloc_local, local_JNUM, local_joff
164 CALL this%InitGravity(mesh,physics,
"shearingbox spectral solver",config,io)
167 #if !defined(HAVE_FFTW) 168 CALL this%Error(
"InitGravity_sboxspectral", &
169 "No fftw package could be loaded.")
171 CALL getattr(config,
"order", this%order, 2)
180 IF (mesh%ROTSYM.NE.0) &
181 CALL this%Error(
"InitGravity_sboxspectral", &
182 "Rotational symmetry not supported.")
185 IF (mesh%NDIMS.EQ.1) &
186 CALL this%Error(
"InitGravity_sboxspectral", &
187 "Only 2D (shearingsheet) and 3D (shearingbox) simulations allowed with this module.")
190 SELECT TYPE (phys => physics)
194 CALL this%Error(
"InitGravity_sboxspectral", &
195 "Physics modules with density necessary for this module.")
199 IF(.NOT.(mod(mesh%JMAX-mesh%JMIN+1,2)==0))
THEN 200 CALL this%Error(
"InitGravity_sboxspectral", &
201 "The spectral poisson solver needs an even number of "// &
202 "cells in the phi direction due to the discrete cosinus "// &
210 CALL mpi_comm_size(mpi_comm_world, nprocs, err)
211 IF (nprocs.GT.1 .AND. mesh%shear_dir.EQ.2)
THEN 212 CALL this%Error(
"InitGravity_sboxspectral", &
213 "Execution of the parallel Fourier solver is only possible with pencil "// &
214 "decomposition. The first dimension should be fully accessible by the "//&
215 "first core. The shear thereto needs to vary along the second " // &
216 "dimension. In order to achieve this set the boundaries accordingly. "// &
217 "Check InitBoundary where the shear direction is set.")
219 IF (mesh%dims(1).GT.1 .AND. mesh%shear_dir.EQ.1)
THEN 220 CALL this%Error(
"InitGravity_sboxspectral", &
221 "The first dimension needs to be fully accessible by each process. "// &
222 "Please change domain decomposition to pencil decompositon. " // &
223 "This needs to be done during initialization. In the Mesh dictionary " // &
224 "use the key 'decompositon' and the value (/ 1,-1, 1/) to force decomposition " // &
225 "along second direction")
229 this%phi(mesh%IGMIN:mesh%IGMAX,mesh%JGMIN:mesh%JGMAX,mesh%KGMIN:mesh%KGMAX), &
230 #if !defined(PARALLEL) 231 this%mass2D(mesh%IMIN:mesh%IMAX,mesh%JMIN:mesh%JMAX), &
232 this%Fmass2D(mesh%IMIN:mesh%IMAX/2+1,mesh%JMIN:mesh%JMAX), &
236 this%Fmass2D_real(mesh%IMIN:mesh%IMAX+2,mesh%JMIN:mesh%JMAX,mesh%KMIN:mesh%KMAX), &
237 this%kx(mesh%INUM), &
238 this%ky(mesh%JNUM), &
239 this%joff(mesh%IMIN:mesh%IMAX), &
240 this%jrem(mesh%IMIN:mesh%IMAX), &
241 this%den_ip(mesh%IMIN:mesh%IMAX,mesh%JMIN:mesh%JMAX,mesh%KMIN:mesh%KMAX), &
244 CALL this%Error(
"InitGravity_sboxspectral",
"Memory allocation failed.")
250 #if defined(PARALLEL) 251 this%alloc_local = fftw_mpi_local_size_2d(c_jnum, c_inum, &
252 mpi_comm_world, this%local_JNUM, this%local_joff)
253 this%mass2D_pointer = fftw_alloc_real(2*this%alloc_local)
254 this%Fmass2D_pointer = fftw_alloc_complex(this%alloc_local)
255 call c_f_pointer(this%mass2D_pointer,this%mass2D, &
256 [2*(c_inum/2+1),this%local_JNUM])
257 call c_f_pointer(this%Fmass2D_pointer,this%Fmass2D, &
258 [c_inum/2+1,this%local_JNUM])
266 #if !defined(PARALLEL) 267 this%plan_r2c = fftw_plan_dft_r2c_2d(mesh%JMAX-mesh%JMIN+1, &
268 mesh%IMAX-mesh%IMIN+1,this%mass2D, &
269 this%Fmass2D,fftw_measure)
270 this%plan_c2r = fftw_plan_dft_c2r_2d(mesh%JMAX-mesh%JMIN+1, &
271 mesh%IMAX-mesh%IMIN+1, this%Fmass2D, &
272 this%mass2D, fftw_measure)
273 IF ((.NOT. c_associated(this%plan_r2c)) .OR. (.NOT. c_associated(this%plan_c2r)))
THEN 274 CALL this%Error(
"InitGravity_sboxspectral",
"FFT plan could not be created.")
276 #elif defined(PARALLEL) 277 this%plan_r2c = fftw_mpi_plan_dft_r2c_2d(c_jnum,c_inum, &
278 this%mass2D,this%Fmass2D, &
279 mpi_comm_world, fftw_measure)
280 this%plan_c2r = fftw_mpi_plan_dft_c2r_2d(c_jnum,c_inum, &
281 this%Fmass2D,this%mass2D, &
282 mpi_comm_world, fftw_measure)
287 this%mass2D(:,:) = 0.
288 this%Fmass2D(:,:) = cmplx(0.,0)
289 this%Fmass2D_real(:,:,:) = 0.
298 this%kx = cshift((/(i-(mesh%INUM+1)/2,i=0,mesh%INUM-1)/), &
299 +(mesh%INUM+1)/2)*2.*pi/(mesh%XMAX-mesh%XMIN)
300 this%ky = cshift((/(i-(mesh%JNUM+1)/2,i=0,mesh%JNUM-1)/), &
301 +(mesh%JNUM+1)/2)*2.*pi/(mesh%YMAX-mesh%YMIN)
304 IF(mesh%shear_dir.EQ.2)
THEN 305 this%shiftconst = mesh%Q*mesh%OMEGA*(mesh%xmax-mesh%xmin)/mesh%dy
306 ELSE IF (mesh%shear_dir.EQ.1)
THEN 307 this%shiftconst = mesh%Q*mesh%OMEGA*(mesh%ymax-mesh%ymin)/mesh%dx
309 CALL this%Error(
"InitGravity_sboxspectral", &
310 "Either WE_shear or SN_shear need to be applied.")
315 CALL getattr(config,
"output/phi", valwrite, 0)
316 IF (valwrite .EQ. 1) &
317 CALL setattr(io,
"phi", &
318 this%phi(mesh%IMIN:mesh%IMAX,mesh%JMIN:mesh%JMAX,mesh%KMIN:mesh%KMAX))
320 this%calc_Fmass2D = .false.
321 CALL getattr(config,
"output/Fmass2D", valwrite, 0)
322 IF (valwrite .EQ. 1)
THEN 323 CALL setattr(io,
"Fmass2D_real", &
324 this%Fmass2D_real(mesh%IMIN:mesh%IMAX+2,mesh%JMIN:mesh%JMAX,mesh%KMIN:mesh%KMAX))
325 this%calc_Fmass2D = .true.
341 CLASS(gravity_sboxspectral),
INTENT(INOUT) :: this
342 CLASS(mesh_base),
INTENT(IN) :: Mesh
343 CLASS(physics_base),
INTENT(IN) :: Physics
344 CLASS(fluxes_base),
INTENT(IN) :: Fluxes
345 CLASS(marray_compound),
INTENT(INOUT) :: pvar
346 REAL,
INTENT(IN) :: time,dt
353 CALL this%CalcPotential(mesh,physics,time,pvar)
355 IF (this%order.EQ.2)
THEN 357 DO k = mesh%KMIN,mesh%KMAX
359 DO j = mesh%JMIN,mesh%JMAX
361 DO i = mesh%IMIN,mesh%IMAX
363 this%accel%data4d(i,j,k,1) = -1.0*(this%phi(i+1,j,k)-this%phi(i-1,j,k))/ &
364 (2*mesh%dlx%data3d(i,j,k))
365 this%accel%data4d(i,j,k,2) = -1.0*(this%phi(i,j+1,k)-this%phi(i,j-1,k))/ &
366 (2*mesh%dly%data3d(i,j,k))
370 ELSE IF (this%order.EQ.4)
THEN 374 DO k = mesh%KMIN,mesh%KMAX
376 DO j = mesh%JMIN,mesh%JMAX
378 DO i = mesh%IMIN,mesh%IMAX
380 this%accel%data4d(i,j,k,1) = -1.0*(w1*this%phi(i-2,j,k)-w2*this%phi(i-1,j,k)+ &
381 w2*this%phi(i+1,j,k)-w1*this%phi(i+2,j,k))/ &
382 (mesh%dlx%data3d(i,j,k))
383 this%accel%data4d(i,j,k,2) = -1.0*(w1*this%phi(i,j-2,k)-w2*this%phi(i,j-1,k)+ &
384 w2*this%phi(i,j+1,k)-w1*this%phi(i,j+2,k)) / &
385 (mesh%dly%data3d(i,j,k))
390 CALL this%Error(
"InitGravity_sboxspectral", &
391 "The chosen order approximation does not exist (only 2 and 3).")
436 CLASS(gravity_sboxspectral),
INTENT(INOUT) :: this
437 CLASS(mesh_base),
INTENT(IN) :: Mesh
438 CLASS(physics_base),
INTENT(IN) :: Physics
439 REAL,
INTENT(IN) :: time
440 CLASS(marray_compound),
INTENT(INOUT) :: pvar
444 REAL :: joff2,jrem2,delt,time0
447 INTEGER :: status(MPI_STATUS_SIZE),ierror,ier
448 REAL :: mpi_buf(Mesh%IMIN:Mesh%IMAX,Mesh%GJNUM,Mesh%KMIN:Mesh%KMAX)
456 CALL mpi_comm_size(mpi_comm_world, nprocs, ier)
459 IF (mesh%OMEGA .EQ. 0)
THEN 461 ELSE IF (mesh%shear_dir.EQ.2)
THEN 462 time0 = nint(time*mesh%Q*mesh%OMEGA*(mesh%xmax-mesh%xmin)/ &
463 (mesh%ymax-mesh%ymin))*(mesh%ymax-mesh%ymin)/(mesh%Q*mesh%OMEGA &
464 *(mesh%xmax-mesh%xmin))
465 ELSE IF (mesh%shear_dir.EQ.1)
THEN 466 time0 = nint(time*mesh%Q*mesh%OMEGA*(mesh%ymax-mesh%ymin)/ &
467 (mesh%xmax-mesh%xmin))*(mesh%xmax-mesh%xmin)/(mesh%Q*mesh%OMEGA &
468 *(mesh%ymax-mesh%ymin))
473 SELECT TYPE(p => pvar)
475 CALL this%FieldShift(mesh,physics,delt, &
476 p%density%data3d(mesh%IGMIN:mesh%IGMAX,mesh%JGMIN:mesh%JGMAX,mesh%KGMIN:mesh%KGMAX), &
477 this%den_ip(mesh%IMIN:mesh%IMAX,mesh%JMIN:mesh%JMAX,mesh%KMIN:mesh%KMAX))
479 CALL this%Error(
"gravity_sboxspectral::CalcPotential",
"unsupported state vector")
483 #if defined(PARALLEL) 484 this%mass2D(1:mesh%INUM,1:this%local_JNUM) = &
485 reshape(this%den_ip(mesh%IMIN:mesh%IMAX,mesh%JMIN:mesh%JMAX,mesh%KMIN:mesh%KMAX), (/ mesh%INUM,mesh%JNUM/nprocs /))
487 this%mass2D(1:mesh%INUM,1:mesh%JNUM/nprocs) = &
488 reshape(this%den_ip(mesh%IMIN:mesh%IMAX,mesh%JMIN:mesh%JMAX,mesh%KMIN:mesh%KMAX), (/ mesh%INUM,mesh%JNUM/nprocs /))
494 CALL ftrace_region_begin(
"forward_fft")
500 CALL this%FFT_Forward(mesh,physics)
504 CALL ftrace_region_end(
"forward_fft")
508 IF (mesh%dx .GT. mesh%dy)
THEN 509 k2max = 0.5*pi**2/(mesh%dx**2)
511 k2max = 0.5*pi**2/(mesh%dy**2)
514 IF (mesh%shear_dir.EQ.2)
THEN 516 DO j = mesh%JMIN,mesh%JMAX
518 DO i = mesh%IMIN,mesh%IMAX/2+1
519 k2 = (this%kx(i) + mesh%Q*mesh%OMEGA*this%ky(j)*delt)**2 + this%ky(j)**2
521 IF ((k2 .LT. k2max) .AND. (k2 .GT. 0))
THEN 522 this%Fmass2D(i,j-this%local_joff) = -2.*pi*physics%Constants%GN* &
523 this%Fmass2D(i,j-this%local_joff)/ko
525 this%Fmass2D(i,j-this%local_joff) = 0.0
529 ELSE IF (mesh%shear_dir.EQ.1)
THEN 531 DO j = mesh%JMIN,mesh%JMAX
533 DO i = mesh%IMIN,mesh%IMAX/2+1
534 k2 = this%kx(i)**2 + (this%ky(j)-mesh%Q*mesh%OMEGA*this%kx(i)*delt)**2
536 IF ((k2 .LT. k2max) .AND. (k2 .GT. 0))
THEN 537 this%Fmass2D(i,j-this%local_joff) = -2.*pi*physics%Constants%GN* &
538 this%Fmass2D(i,j-this%local_joff)/ko
540 this%Fmass2D(i,j-this%local_joff) = 0.0
548 CALL ftrace_region_begin(
"backward_fft")
554 CALL this%FFT_Backward(mesh,physics)
557 CALL ftrace_region_end(
"backward_fft")
562 DO k = mesh%KMIN,mesh%KMAX
564 DO j = mesh%JMIN,mesh%JMAX
566 DO i = mesh%IMIN,mesh%IMAX
567 this%phi(i,j,k) = this%mass2D(i,j-this%local_joff)/ &
568 (mesh%JNUM*mesh%INUM)
574 CALL this%FieldShift(mesh,physics,-delt, &
575 this%phi(mesh%IGMIN:mesh%IGMAX,mesh%JGMIN:mesh%JGMAX,mesh%KGMIN:mesh%KGMAX), &
576 this%den_ip(mesh%IMIN:mesh%IMAX,mesh%JMIN:mesh%JMAX,mesh%KMIN:mesh%KMAX))
579 DO k = mesh%KMIN,mesh%KMAX
581 DO j = mesh%JMIN,mesh%JMAX
583 DO i = mesh%IMIN,mesh%IMAX
584 this%phi(i,j,k) = this%den_ip(i,j,k)
590 IF(mesh%shear_dir.EQ.2)
THEN 594 this%phi(mesh%IMIN:mesh%IMAX,mesh%JMIN-j,mesh%KMIN:mesh%KMAX) = this%phi(mesh%IMIN:mesh%IMAX,mesh%JMAX-j+1,mesh%KMIN:mesh%KMAX)
595 this%phi(mesh%IMIN:mesh%IMAX,mesh%JMAX+j,mesh%KMIN:mesh%KMAX) = this%phi(mesh%IMIN:mesh%IMAX,mesh%JMIN+j-1,mesh%KMIN:mesh%KMAX)
597 joff2 = -this%shiftconst*delt
598 jrem2 = joff2 - floor(joff2)
602 this%phi(mesh%IMIN-i,mesh%JMIN:mesh%JMAX,mesh%KMIN:mesh%KMAX) = this%phi(mesh%IMAX-i+1,mesh%JMIN:mesh%JMAX,mesh%KMIN:mesh%KMAX)
604 this%phi(mesh%IMIN-i,mesh%JMIN:mesh%JMAX,mesh%KMIN:mesh%KMAX) = &
605 cshift(this%phi(mesh%IMIN-i,mesh%JMIN:mesh%JMAX,mesh%KMIN:mesh%KMAX),floor(joff2))
607 this%phi(mesh%IMIN-i,mesh%JMAX+1,:) = this%phi(mesh%IMIN-i,mesh%JMIN,:)
608 DO k=mesh%KMIN,mesh%KMAX
609 DO j=mesh%JMIN,mesh%JMAX
610 this%phi(mesh%IMIN-i,j,k) = &
611 (1.0 - jrem2)*this%phi(mesh%IMIN-i,j,k) + jrem2*this%phi(mesh%IMIN-i,j+1,k)
615 joff2 = this%shiftconst*delt
616 jrem2 = joff2 - floor(joff2)
620 this%phi(mesh%IMAX+i,mesh%JMIN:mesh%JMAX,mesh%KMIN:mesh%KMAX) = this%phi(mesh%IMIN+i-1,mesh%JMIN:mesh%JMAX,mesh%KMIN:mesh%KMAX)
622 this%phi(mesh%IMAX+i,mesh%JMIN:mesh%JMAX,mesh%KMIN:mesh%KMAX) = &
623 cshift(this%phi(mesh%IMAX+i,mesh%JMIN:mesh%JMAX,mesh%KMIN:mesh%KMAX),floor(joff2))
625 this%phi(mesh%IMAX+i,mesh%JMAX+1,:) = this%phi(mesh%IMAX+i,mesh%JMIN,:)
626 DO k=mesh%KMIN,mesh%KMAX
627 DO j=mesh%JMIN,mesh%JMAX
628 this%phi(mesh%IMAX+i,j,k) = &
629 (1.0 - jrem2)*this%phi(mesh%IMAX+i,j,k) + jrem2*this%phi(mesh%IMAX+i,j+1,k)
636 ELSE IF(mesh%shear_dir.EQ.1)
THEN 640 this%phi(mesh%IMIN-i,mesh%JMIN:mesh%JMAX,mesh%KMIN:mesh%KMAX) = this%phi(mesh%IMAX-i+1,mesh%JMIN:mesh%JMAX,mesh%KMIN:mesh%KMAX)
641 this%phi(mesh%IMAX+i,mesh%JMIN:mesh%JMAX,mesh%KMIN:mesh%KMAX) = this%phi(mesh%IMIN+i-1,mesh%JMIN:mesh%JMAX,mesh%KMIN:mesh%KMAX)
644 IF(mesh%dims(2).GT.1)
THEN 645 mpi_buf(mesh%IMIN:mesh%IMAX,1:mesh%GJNUM,mesh%KMIN:mesh%KMAX) = &
646 this%phi(mesh%IMIN:mesh%IMAX,mesh%JMAX-mesh%GJNUM+1:mesh%JMAX,mesh%KMIN:mesh%KMAX)
647 CALL mpi_sendrecv_replace(&
649 2*(mesh%IMAX-mesh%IMIN+1), &
651 mesh%neighbor(north), 53+north, &
652 mesh%neighbor(south), mpi_any_tag, &
653 mesh%comm_cart, status, ierror)
654 this%phi(mesh%IMIN:mesh%IMAX,mesh%JGMIN:mesh%JMIN-1,mesh%KMIN:mesh%KMAX) = &
655 mpi_buf(mesh%IMIN:mesh%IMAX,1:mesh%GJNUM,mesh%KMIN:mesh%KMAX)
657 mpi_buf(mesh%IMIN:mesh%IMAX,1:mesh%GJNUM,mesh%KMIN:mesh%KMAX) = &
658 this%phi(mesh%IMIN:mesh%IMAX,mesh%JMIN:mesh%JMIN+mesh%GJNUM-1,mesh%KMIN:mesh%KMAX)
659 CALL mpi_sendrecv_replace(&
661 2*(mesh%IMAX-mesh%IMIN+1), &
663 mesh%neighbor(south), 53+south, &
664 mesh%neighbor(north), mpi_any_tag, &
665 mesh%comm_cart, status, ierror)
666 this%phi(mesh%IMIN:mesh%IMAX,mesh%JMAX+1:mesh%JGMAX,mesh%KMIN:mesh%KMAX) = &
667 mpi_buf(mesh%IMIN:mesh%IMAX,1:mesh%GJNUM,mesh%KMIN:mesh%KMAX)
672 this%phi(mesh%IMIN:mesh%IMAX,mesh%JMIN-j,mesh%KMIN:mesh%KMAX) = this%phi(mesh%IMIN:mesh%IMAX,mesh%JMAX-j+1,mesh%KMIN:mesh%KMAX)
673 this%phi(mesh%IMIN:mesh%IMAX,mesh%JMAX+j,mesh%KMIN:mesh%KMAX) = this%phi(mesh%IMIN:mesh%IMAX,mesh%JMIN+j-1,mesh%KMIN:mesh%KMAX)
679 IF (mesh%mycoords(2).EQ.0)
THEN 685 this%phi(mesh%IMIN:mesh%IMAX,mesh%JMIN-j,mesh%KMIN:mesh%KMAX) = this%phi(mesh%IMIN:mesh%IMAX,mesh%JMAX-j+1,mesh%KMIN:mesh%KMAX)
687 joff2 = this%shiftconst*delt
688 jrem2 = joff2 - floor(joff2)
690 this%phi(mesh%IMIN:mesh%IMAX,mesh%JMIN-j,mesh%KMIN:mesh%KMAX) = &
691 cshift(this%phi(mesh%IMIN:mesh%IMAX,mesh%JMIN-j,mesh%KMIN:mesh%KMAX),floor(joff2))
693 this%phi(mesh%IMAX+1,mesh%JMIN-j,:) = this%phi(mesh%IMIN,mesh%JMIN-j,:)
694 DO k = mesh%KMIN,mesh%KMAX
695 DO i=mesh%IMIN,mesh%IMAX
696 this%phi(i,mesh%JMIN-j,k) = &
697 (1.0 - jrem2)*this%phi(i,mesh%JMIN-j,k) + jrem2*this%phi(i+1,mesh%JMIN-j,k)
706 IF (mesh%mycoords(2).EQ.mesh%dims(2)-1)
THEN 711 this%phi(mesh%IMIN:mesh%IMAX,mesh%JMAX+j,mesh%KMIN:mesh%KMAX) = this%phi(mesh%IMIN:mesh%IMAX,mesh%JMIN+j-1,mesh%KMIN:mesh%KMAX)
714 joff2 = -this%shiftconst*delt
715 jrem2 = joff2 - floor(joff2)
717 this%phi(mesh%IMIN:mesh%IMAX,mesh%JMAX+j,mesh%KMIN:mesh%KMAX) = &
718 cshift(this%phi(mesh%IMIN:mesh%IMAX,mesh%JMAX+j,mesh%KMIN:mesh%KMAX),floor(joff2))
720 this%phi(mesh%IMAX+1,mesh%JMAX+j,:) = this%phi(mesh%IMIN,mesh%JMAX+j,:)
721 DO k = mesh%KMIN,mesh%KMAX
722 DO i = mesh%IMIN,mesh%IMAX
723 this%phi(i,mesh%JMAX+j,k) = &
724 (1.0 - jrem2)*this%phi(i,mesh%JMAX+j,k) + jrem2*this%phi(i+1,mesh%JMAX+j,k)
739 CLASS(gravity_sboxspectral),
INTENT(INOUT):: this
740 CLASS(mesh_base),
INTENT(IN) :: Mesh
741 CLASS(physics_base),
INTENT(IN) :: Physics
745 INTEGER :: nprocs,status(MPI_STATUS_SIZE)
750 CALL mpi_comm_size(mpi_comm_world, nprocs, ier)
754 CALL ftrace_region_begin(
"forward FFT")
757 #if !defined(PARALLEL) 758 CALL fftw_execute_dft_r2c(this%plan_r2c, this%mass2D, this%Fmass2D)
760 CALL fftw_mpi_execute_dft_r2c(this%plan_r2c,this%mass2D, this%Fmass2D)
763 IF (this%calc_Fmass2D)
THEN 765 DO k = mesh%KMIN,mesh%KMAX
767 DO j = mesh%JMIN,mesh%JMAX
769 DO i = mesh%IMIN,mesh%IMAX/2+1
770 this%Fmass2D_real(2*i-1,j,k) =
REAL(
REAL(this%Fmass2D(i,j-this%local_joff)))
771 this%Fmass2D_real(2*i,j,k) =
REAL(AIMAG(this%Fmass2D(i,j-this%local_joff)))
778 CALL ftrace_region_end(
"foward FFT")
788 CLASS(gravity_sboxspectral),
INTENT(INOUT) :: this
789 CLASS(mesh_base),
INTENT(IN) :: Mesh
790 CLASS(physics_base),
INTENT(IN) :: Physics
793 INTEGER :: nprocs,status(MPI_STATUS_SIZE)
798 CALL mpi_comm_size(mpi_comm_world, nprocs, ier)
801 #if defined(PARALLEL) 802 CALL fftw_mpi_execute_dft_c2r(this%plan_c2r,this%Fmass2D, this%mass2D)
804 CALL fftw_execute_dft_c2r(this%plan_c2r, this%Fmass2D, this%mass2D)
841 CLASS(gravity_sboxspectral),
INTENT(INOUT) :: this
842 CLASS(mesh_base),
INTENT(IN) :: Mesh
843 CLASS(physics_base),
INTENT(IN) :: Physics
844 CLASS(marray_compound),
INTENT(INOUT) :: pvar
845 TYPE(marray_base),
INTENT(INOUT) :: bccsound,h_ext,height
853 DO k=mesh%KGMIN,mesh%KGMAX
855 DO j=mesh%JGMIN,mesh%JGMAX
857 DO i=mesh%IGMIN,mesh%IGMAX
858 cs2 = bccsound%data3d(i,j,k)*bccsound%data3d(i,j,k)
859 p = -
sqrttwopi*physics%Constants%GN*pvar%data4d(i,j,k,physics%DENSITY) &
861 q = cs2/mesh%OMEGA**2.
863 height%data3d(i,j,k) = p+sqrt(q+p*p)
874 CLASS(gravity_sboxspectral),
INTENT(IN) :: this
875 CLASS(mesh_base),
INTENT(IN) :: Mesh
878 CALL this%Info(
" FFT-Package: FFTW " // &
879 #if defined(PARALLEL) 884 CALL this%Info(
" .. done initializing")
898 SUBROUTINE fieldshift(this,Mesh,Physics,delt,field,mass2D)
901 CLASS(gravity_sboxspectral),
INTENT(INOUT) :: this
902 CLASS(mesh_base),
INTENT(IN) :: Mesh
903 CLASS(physics_base),
INTENT(IN) :: Physics
904 REAL,
DIMENSION(Mesh%IGMIN:Mesh%IGMAX,Mesh%JGMIN:Mesh%JGMAX,Mesh%KGMIN:Mesh%KGMAX), &
906 #if defined(PARALLEL) 907 REAL,
DIMENSION(1:Mesh%INUM,1:this%local_JNUM), &
908 INTENT(OUT) :: mass2D
910 REAL,
DIMENSION(Mesh%IMIN:Mesh%IMAX,Mesh%JMIN:Mesh%JMAX), &
911 INTENT(OUT) :: mass2D
914 INTEGER :: i,j,k,local_joff
917 local_joff = this%local_joff
919 IF (mesh%shear_dir.EQ.1)
THEN 921 DO k = mesh%KMIN,mesh%KMAX
923 DO j = mesh%JMIN,mesh%JMAX
924 this%joff(j) = mesh%Q*mesh%OMEGA*mesh%bcenter(mesh%IMIN,j,k,2)* &
926 this%jrem(j) = this%joff(j) - floor(this%joff(j))
928 DO i = mesh%IMIN,mesh%IMAX
929 mass2d(i,j-local_joff) = &
930 (1.0-this%jrem(j))*field(1+modulo(i-1+floor(this%joff(j)), &
931 mesh%IMAX-mesh%IMIN+1),j,k) + this%jrem(j)*field(1+modulo(i+ &
932 floor(this%joff(j)),mesh%IMAX-mesh%IMIN+1),j,k)
936 ELSE IF (mesh%shear_dir.EQ.2)
THEN 938 DO k = mesh%KMIN,mesh%KMAX
940 DO i = mesh%IMIN,mesh%IMAX
941 this%joff(i) = -mesh%Q*mesh%OMEGA*mesh%bcenter(i,mesh%JMIN,k,1)* &
943 this%jrem(i) = this%joff(i) - floor(this%joff(i))
945 DO j = mesh%JMIN,mesh%JMAX
947 DO i = mesh%IMIN,mesh%IMAX
949 (1.0-this%jrem(i))*field(i,1+modulo(j-1+floor(this%joff(i)), &
950 mesh%JMAX-mesh%JMIN+1),k) + this%jrem(i)*field(i,1+modulo(j+ &
951 floor(this%joff(i)),mesh%JMAX-mesh%JMIN+1),k)
962 CLASS(gravity_sboxspectral),
INTENT(INOUT) :: this
965 CALL fftw_destroy_plan(this%plan_r2c)
966 CALL fftw_destroy_plan(this%plan_c2r)
967 #if defined(PARALLEL) 968 CALL fftw_free(this%mass2D_pointer)
969 CALL fftw_free(this%Fmass2D_pointer)
971 DEALLOCATE(this%mass2D,this%Fmass2D)
subroutine calcdiskheight_single(this, Mesh, Physics, pvar, bccsound, h_ext, height)
Compute disk pressure scale height for geometrically thin self-gravitating shearingsheet.
subroutine finalize(this)
Destructor of common class.
real, parameter sqrttwopi
integer, save default_mpi_real
default real type for MPI
2D poisson solver using spectral methods for direct integration
Poisson solver via spectral methods within the shearingsheet.
derived class for compound of mesh arrays
base class for mesh arrays
subroutine fieldshift(this, Mesh, Physics, delt, field, mass2D)
Shifts the whole field to the next periodic point.
subroutine initgravity_sboxspectral(this, Mesh, Physics, config, IO)
Constructor of gravity sboxspectral module.
subroutine updategravity_single(this, Mesh, Physics, Fluxes, pvar, time, dt)
Calculates the acceleration from potential.
subroutine fft_backward(this, Mesh, Physics)
Calculates the FFT backward transformation.
generic gravity terms module providing functionaly common to all gravity terms
subroutine calcpotential(this, Mesh, Physics, time, pvar)
Computes the potential with FFT method within a shearingsheet.
physics module for 1D,2D and 3D isothermal Euler equations
Dictionary for generic data types.
subroutine infogravity(this, Mesh)
Prints out information.
base module for numerical flux functions
subroutine fft_forward(this, Mesh, Physics)
Calculates the FFT forward.