|
80 | 80 | my_dz = dz_ |
81 | 81 | end procedure |
82 | 82 |
|
83 | | - module procedure laplacian |
84 | | - integer i, j, k |
85 | | - real, allocatable :: halo_west(:,:), halo_east(:,:) |
86 | | - |
87 | | - call_assert(allocated(rhs%s_)) |
88 | | - call_assert(allocated(halo_x)) |
89 | | - |
90 | | - allocate(laplacian_rhs%s_(my_nx, ny, nz)) |
91 | | - halo_west = merge(halo_x(west,:,:), rhs%s_(1,:,:), me/=1) ! conditionally use halo value |
92 | | - i = my_internal_west |
93 | | - call_assert_describe(i+1<=my_nx, "laplacian: westernmost subdomain too small") |
94 | | - ! Compute Laplacians throughout the low-x boundary subdomain using non-allocatable associations: |
95 | | - associate( laplacian_phi => laplacian_rhs%s_, inbox => halo_west, phi=>rhs%s_) |
96 | | -#if HAVE_2018_LOCALITY_SPECIFIERS |
97 | | - do concurrent(j=2:ny-1, k=2:nz-1) & |
98 | | - default(none) shared(laplacian_phi, inbox, phi, dx_, dy_, dz_, i) !Fortran 2018 loacality specifiers |
99 | | -#else |
100 | | - do concurrent(j=2:ny-1, k=2:nz-1) |
101 | | -#endif |
102 | | - laplacian_phi(i,j,k) = (inbox(j,k ) - 2*phi(i,j,k) + phi(i+1,j ,k ))/dx_**2 + & |
103 | | - (phi(i,j-1,k ) - 2*phi(i,j,k) + phi(i ,j+1,k ))/dy_**2 + & |
104 | | - (phi(i,j ,k-1) - 2*phi(i,j,k) + phi(i ,j ,k+1))/dz_**2 |
105 | | - end do |
106 | | - end associate |
107 | | - ! Compute Laplacians throughout non-boundary subdomains with non-allocatable associations: |
108 | | - associate(laplacian_phi => laplacian_rhs%s_, phi=>rhs%s_) |
109 | | -#if HAVE_2018_LOCALITY_SPECIFIERS |
110 | | - do concurrent(i=my_internal_west+1:my_internal_east-1, j=2:ny-1, k=2:nz-1) & |
111 | | - default(none) shared(laplacian_phi, phi, dx_, dy_, dz_) ! Fortran 2018 locality specifiers |
112 | | -#else |
113 | | - do concurrent(i=my_internal_west+1:my_internal_east-1, j=2:ny-1, k=2:nz-1) |
114 | | -#endif |
115 | | - laplacian_phi(i,j,k) = (phi(i-1,j ,k ) - 2*phi(i,j,k) + phi(i+1,j ,k ))/dx_**2 + & |
116 | | - (phi(i ,j-1,k ) - 2*phi(i,j,k) + phi(i ,j+1,k ))/dy_**2 + & |
117 | | - (phi(i ,j ,k-1) - 2*phi(i,j,k) + phi(i ,j ,k+1))/dz_**2 |
118 | | - end do |
119 | | - end associate |
120 | | - |
121 | | - halo_east = merge(halo_x(east,:,:), rhs%s_(my_nx,:,:), me/=num_subdomains) !conditionally use halo value |
122 | | - i = my_internal_east |
123 | | - call_assert_describe(i-1>0, "laplacian: easternmost subdomain too small") |
124 | | - ! Compute Laplacians throughout the high-x boundary subdomain using non-allocatable associations: |
125 | | - associate(laplacian_phi => laplacian_rhs%s_, inbox => halo_east, phi=>rhs%s_) |
126 | | -#if HAVE_2018_LOCALITY_SPECIFIERS |
127 | | - do concurrent(j=2:ny-1, k=2:nz-1) & ! compute Laplacian in low-x boundary subdomain |
128 | | - default(none) shared(laplacian_phi, inbox, phi, dx_, dy_, dz_, i) ! Fortran 2018 locality specifiers |
129 | | -#else |
130 | | - do concurrent(j=2:ny-1, k=2:nz-1) ! compute Laplacian in low-x boundary subdomain |
131 | | -#endif |
132 | | - laplacian_phi(i,j,k) = (phi(i-1,j ,k ) - 2*phi(i,j,k) + inbox( j ,k ))/dx_**2 + & |
133 | | - (phi(i ,j-1,k ) - 2*phi(i,j,k) + phi(i ,j+1,k ))/dy_**2 + & |
134 | | - (phi(i ,j ,k-1) - 2*phi(i,j,k) + phi(i ,j ,k+1))/dz_**2 |
135 | | - end do |
136 | | - end associate |
137 | | - |
138 | | - laplacian_rhs%s_(:, 1,:) = 0. ! low-y boundary |
139 | | - laplacian_rhs%s_(:,ny,:) = 0. ! high-y boundary |
140 | | - laplacian_rhs%s_(:,:, 1) = 0. ! low-z boundary |
141 | | - laplacian_rhs%s_(:,:,nz) = 0. ! high-z boundary |
142 | | - |
143 | | - if (me==1) laplacian_rhs%s_(1,:,:) = 0. ! low-x boundary |
144 | | - if (me==num_subdomains) laplacian_rhs%s_(my_nx,:,:) = 0. ! high-x boundary |
145 | | - end procedure |
146 | | - |
147 | 83 | module procedure multiply |
148 | 84 | call_assert(allocated(rhs%s_)) |
149 | 85 | product%s_ = lhs * rhs%s_ |
|
0 commit comments