14 use mpi,
only : mpi_request_null, mpi_statuses_ignore
43 type(model_state_type),
target,
intent(inout) :: current_state
45 integer :: i, my_y_start, my_x_start
47 if (.not. is_component_enabled(current_state%options_database,
"diverr"))
then
48 call log_master_log(log_error,
"The FFT solver component requires the diverr component to be enabled")
51 pi=4.0_default_precision*atan(1.0_default_precision)
55 call init_halo_communication(current_state, get_single_field_per_halo_cell,
halo_swap_state, 1, .false.)
62 cos_x(i)=(2.0_default_precision/(current_state%global_grid%configuration%horizontal%dx*&
63 current_state%global_grid%configuration%horizontal%dx))&
64 *(cos(2.0_default_precision*
pi*real(((i-1)+(my_x_start-1))/2, kind=default_precision)/&
65 real(current_state%global_grid%size(X_INDEX), kind=default_precision))-1.0_default_precision)
72 cos_y(i)=(2.0_default_precision/(current_state%global_grid%configuration%horizontal%dy*&
73 current_state%global_grid%configuration%horizontal%dy))&
74 *(cos(2.0_default_precision*
pi*real(((i-1)+(my_y_start-1))/2, kind=default_precision)/&
75 real(current_state%global_grid%size(Y_INDEX), kind=default_precision))-1.0_default_precision)
78 current_state%psrce_x_hs_send_request=mpi_request_null
79 current_state%psrce_y_hs_send_request=mpi_request_null
80 current_state%psrce_x_hs_recv_request=mpi_request_null
81 current_state%psrce_y_hs_recv_request=mpi_request_null
87 type(model_state_type),
target,
intent(inout) :: current_state
89 integer :: start_loc(3), end_loc(3), i
92 start_loc(i)=current_state%local_grid%local_domain_start_index(i)
93 end_loc(i)=current_state%local_grid%local_domain_end_index(i)
97 current_state%local_grid%halo_size(x_index))
100 current_state%p%data=real(current_state%parallel%my_rank, kind=8) + 1.d0
103 call perform_forward_3dfft(current_state, current_state%p%data(start_loc(z_index):end_loc(z_index), &
104 start_loc(y_index):end_loc(y_index), start_loc(x_index):end_loc(x_index)),
pt)
106 #ifndef FFT_TEST_MODE
114 call perform_backwards_3dfft(current_state,
pt, current_state%p%data(start_loc(z_index):end_loc(z_index), &
115 start_loc(y_index):end_loc(y_index), start_loc(x_index):end_loc(x_index)))
118 if (current_state%parallel%my_rank == 1)
then
119 write(*,*) current_state%parallel%my_rank, current_state%p%data(:,3,3)
131 type(model_state_type),
target,
intent(inout) :: current_state
133 call finalise_pencil_fft(current_state%parallel%monc_communicator)
145 type(model_state_type),
target,
intent(inout) :: current_state
146 integer,
intent(in) :: y_halo_size, x_halo_size
148 integer :: ierr, combined_handles(2), i, j, k
150 combined_handles(1)=current_state%psrce_x_hs_recv_request
151 combined_handles(2)=current_state%psrce_y_hs_recv_request
152 call mpi_waitall(2, combined_handles, mpi_statuses_ignore, ierr)
154 do j=current_state%local_grid%local_domain_start_index(y_index), current_state%local_grid%local_domain_end_index(y_index)
155 do k=2,current_state%local_grid%size(z_index)
157 current_state%p%data(k,j,x_halo_size+1)=current_state%p%data(k,j,x_halo_size+1)-&
158 current_state%psrce_recv_buffer_x(k-1,j-x_halo_size)
161 if (j .gt. y_halo_size+1) current_state%p%data(k, j, x_halo_size+1)=current_state%p%data(k, j, x_halo_size+1)-&
162 current_state%global_grid%configuration%horizontal%cy * current_state%sv%data(k, j-1, x_halo_size+1)
168 do i=current_state%local_grid%local_domain_start_index(x_index), current_state%local_grid%local_domain_end_index(x_index)
169 do k=2,current_state%local_grid%size(z_index)
170 current_state%p%data(k,y_halo_size+1,i)=current_state%p%data(k,y_halo_size+1,i)-&
171 current_state%psrce_recv_buffer_y(k-1,i-y_halo_size)
176 combined_handles(1)=current_state%psrce_x_hs_send_request
177 combined_handles(2)=current_state%psrce_y_hs_send_request
178 call mpi_waitall(2, combined_handles, mpi_statuses_ignore, ierr)
189 type(model_state_type),
target,
intent(inout) :: current_state
190 real(kind=default_precision),
dimension(:,:,:),
intent(inout) :: pressure_term
191 integer,
intent(in) :: fourier_space_sizes(3)
193 integer :: i, j, k, j_start
194 real(kind=default_precision) :: b(fourier_space_sizes(z_index)), b1(fourier_space_sizes(z_index)), &
195 s(fourier_space_sizes(z_index)), s1(fourier_space_sizes(z_index)), cij
197 do i=1,fourier_space_sizes(x_index)
198 j_start=merge(3, 1, current_state%local_grid%start(y_index) ==1 .and. current_state%local_grid%start(x_index) == 1 &
200 do j=j_start,fourier_space_sizes(y_index)
203 b(2)=cij-current_state%global_grid%configuration%vertical%cza(2)
204 b1(2)=1.0_default_precision/b(2)
205 s1(2)=pressure_term(2,j,i)
207 do k=3,fourier_space_sizes(z_index)
208 b(k)=cij+current_state%global_grid%configuration%vertical%czg(k)
209 b1(k)=1.0_default_precision/(b(k)-current_state%global_grid%configuration%vertical%czh(k)*b1(k-1))
210 s1(k)=pressure_term(k,j,i)-current_state%global_grid%configuration%vertical%czb(k)*s1(k-1)*b1(k-1)
213 pressure_term(fourier_space_sizes(z_index),j,i)=s1(fourier_space_sizes(z_index))* b1(fourier_space_sizes(z_index))
215 do k=fourier_space_sizes(z_index)-1,2,-1
216 pressure_term(k,j,i)=(s1(k)-current_state%global_grid%configuration%vertical%cza(k)*&
217 pressure_term(k+1,j,i))*b1(k)
223 if (current_state%local_grid%start(y_index) == 1 .and. current_state%local_grid%start(x_index) == 1)
then
226 s(2)=pressure_term(2,j,i)
227 pressure_term(1,j,i)=0.0_default_precision
228 pressure_term(2,j,i)=0.0_default_precision
229 do k=3, fourier_space_sizes(z_index)
230 s(k)=pressure_term(k,j,i)
231 pressure_term(k,j,i)=(s(k-1)-current_state%global_grid%configuration%vertical%czg(k-1)*pressure_term(k-1,j,i)-&
232 current_state%global_grid%configuration%vertical%czb(k-1)*pressure_term(k-2,j,i))/&
233 current_state%global_grid%configuration%vertical%cza(k-1)
249 pid_location, current_page, source_data)
250 type(model_state_type),
intent(inout) :: current_state
251 integer,
intent(in) :: dim, pid_location, source_index
252 integer,
intent(inout) :: current_page(:)
253 type(neighbour_description_type),
intent(inout) :: neighbour_description
254 type(field_data_wrapper_type),
dimension(:),
intent(in),
optional :: source_data
256 call copy_field_to_buffer(current_state%local_grid, neighbour_description%send_halo_buffer, current_state%p%data, &
257 dim, source_index, current_page(pid_location))
259 current_page(pid_location)=current_page(pid_location)+1
268 neighbour_location, current_page, source_data)
269 type(model_state_type),
intent(inout) :: current_state
270 integer,
intent(in) :: dim, target_index, neighbour_location
271 integer,
intent(inout) :: current_page(:)
272 type(neighbour_description_type),
intent(inout) :: neighbour_description
273 type(field_data_wrapper_type),
dimension(:),
intent(in),
optional :: source_data
275 call copy_buffer_to_field(current_state%local_grid, neighbour_description%recv_halo_buffer, current_state%p%data, &
276 dim, target_index, current_page(neighbour_location))
278 current_page(neighbour_location)=current_page(neighbour_location)+1
285 type(model_state_type),
intent(inout) :: current_state
286 integer,
intent(in) :: halo_depth
287 logical,
intent(in) :: involve_corners
288 type(field_data_wrapper_type),
dimension(:),
intent(in),
optional :: source_data
290 call perform_local_data_copy_for_field(current_state%p%data, current_state%local_grid, &
291 current_state%parallel%my_rank, halo_depth, involve_corners)