1 module module_coarsening
7 subroutine prolongation( &
8 ifds
, ifde
, kfds
, kfde
, jfds
, jfde
, & ! fire grid dimensions
9 ifms
, ifme
, kfms
, kfme
, jfms
, jfme
, & ! memory dimensions
10 ifps
, ifpe
, kfps
, kfpe
, jfps
, jfpe
, & ! fire patch bounds
11 ifts
, ifte
, kfts
, kfte
, jfts
, jfte
, & ! tile dimensions
12 ifcds
, ifcde
, kfcds
,kfcde
, jfcds
,jfcde
, & ! coarse grid domain
13 ifcms
, ifcme
, kfcms
,kfcme
, jfcms
,jfcme
, & ! coarse grid dimensions
14 ifcps
, ifcpe
, kfcps
,kfcpe
, jfcps
,jfcpe
, & ! coarse grid dimensions
15 ifcts
, ifcte
, kfcts
,kfcte
, jfcts
,jfcte
, & ! coarse grid tile
16 u
,uc
,cr_x
,cr_y
,icl_z
,X
,Y
,Z
)
18 ! Multiply by the prolongation matrix: u = u + P*uc
20 ! uc coarse grid vector
21 ! cr_x, cr_y coarsening factor in horizontal directions x and y
22 ! icl_z 1D array, indices of coarse grid in the z directions
23 ! X,Y,Z grid coordinates
30 integer, intent(in
):: &
31 ifds
, ifde
, kfds
, kfde
, jfds
, jfde
, & ! fire grid dimensions
32 ifms
, ifme
, kfms
, kfme
, jfms
, jfme
, & ! memory dimensions
33 ifps
, ifpe
, kfps
, kfpe
, jfps
, jfpe
, & ! fire patch bounds
34 ifts
, ifte
, kfts
, kfte
, jfts
, jfte
, & ! tile dimensions
35 ifcds
, ifcde
, kfcds
,kfcde
, jfcds
,jfcde
, & ! coarse grid domain
36 ifcms
, ifcme
, kfcms
,kfcme
, jfcms
,jfcme
, & ! coarse grid dimensions
37 ifcps
, ifcpe
, kfcps
,kfcpe
, jfcps
,jfcpe
, & ! coarse grid dimensions
38 ifcts
, ifcte
, kfcts
,kfcte
, jfcts
,jfcte
! coarse grid tile
40 real, intent(in
), dimension(ifms
:ifme
,kfms
:kfme
,jfms
:jfme
):: X
,Y
,Z
!spatial grid
41 real, intent(in
), dimension(ifcms
:ifcme
,kfcms
:kfcme
,jfcms
:jfcme
):: uc
! coarse vector
43 integer, intent(in
):: cr_x
, cr_y
, & ! coarsening factors in the horizonal directions
44 icl_z(kfcts
:kfcte
) ! indices of coarse grid in the vertical direction
46 real, intent(inout
), dimension(ifms
:ifme
,kfms
:kfme
,jfms
:jfme
):: u
! fine grid interpolant
49 integer :: i
,j
,k
,ic
,jc
,kc
,ifc
,jfc
,kfc
,ifs
,ife
,jfs
,jfe
,kfs
,kfe
54 ! zero the output to ready for contributions
55 ! u(ifts:ifte,kfts:kfte,jfts:jfte) = 0.
57 if ((icl_z(kfcts
) .ne
. kfts
) .or
. (icl_z(kfcte
) .ne
. kfte
)) then
58 call crash('vertical corsening must include all domain')
61 do kc
=kfcts
,kfcte
! loop over coarse layers
62 kfc
=icl_z(kc
); ! the fine grid number of the coarse layer
64 kfs
=icl_z(kc
-1)+1 ! from above previous coarse
66 kfs
=kfc
! itself, there is no previous fine layer
69 kfe
=icl_z(kc
+1)-1 ! up to under next layer
71 kfe
=kfc
! itself, there is no next layer
73 !print *,'vertical coarse layer ',kc,' at ',kfc,' contributes to layers ',kfs,':',kfe
75 ! really needs to be made fine point oriented and draw from coarse points
77 jfc
=cr_y
*(jc
-jfcds
)+jfds
! fine grid index of the coarse point
78 jfs
=max(jfc
-cr_y
+1,jfds
) ! start support
79 jfe
=min(jfc
+cr_y
-1,jfde
) ! end support
80 if (jfc
> jfde
) then ! after end of domain not divisible by coarse ratio
82 elseif (jfc
> jfde
- cr_y
.and
. jfc
< jfde
)then ! just before end of domain not divisible by coarse ratio
85 !print *,'coarse y ',jc,' at j ',jfc,' contributes to ',jfs,':',jfe
87 ifc
=cr_y
*(ic
-ifcds
)+ifds
! fine grid index of the coarse point
88 ifs
=max(ifc
-cr_y
+1,ifds
) ! start support
89 ife
=min(ifc
+cr_y
-1,ifde
) ! end support
90 if (ifc
> ifde
) then ! after end of domain not divisible by coarse ratio
92 elseif (ifc
> ifde
- cr_x
.and
. ifc
< ifde
)then ! just before end of domain not divisible by coarse ratio
95 !print *,'coarse x ',ic,' at i ',ifc,' contributes to ',ifs,':',ife
99 qi
=(X(i
,k
,j
)-X(ife
+1,k
,j
))/(X(ifc
,k
,j
)-X(ife
+1,k
,j
))
101 qi
=(X(i
,k
,j
)-X(ifs
-1,k
,j
))/(X(ifc
,k
,j
)-X(ifs
-1,k
,j
))
106 qj
=(Y(i
,k
,j
)-Y(i
,k
,jfe
+1))/(Y(i
,k
,jfc
)-Y(i
,k
,jfe
+1))
108 qj
=(Y(i
,k
,j
)-Y(i
,k
,jfs
-1))/(Y(i
,k
,jfc
)-Y(i
,k
,jfs
-1))
113 qk
=(Z(i
,k
,j
)-Z(i
,kfe
+1,j
))/(Z(i
,kfc
,j
)-Z(i
,kfe
+1,j
))
115 qk
=(Z(i
,k
,j
)-Z(i
,kfs
-1,j
))/(Z(i
,kfc
,j
)-Z(i
,kfs
-1,j
))
119 u(i
,k
,j
) = u(i
,k
,j
) + qi
*qk
*qj
*uc(ic
,kc
,jc
);
127 end subroutine prolongation
129 subroutine restriction( &
130 ifds
, ifde
, kfds
, kfde
, jfds
, jfde
, & ! fire domain bounds
131 ifms
, ifme
, kfms
, kfme
, jfms
, jfme
, & ! fire memory bounds
132 ifps
, ifpe
, kfps
, kfpe
, jfps
, jfpe
, & ! fire patch bounds
133 ifts
, ifte
, kfts
, kfte
, jfts
,jfte
, & ! fire tile bounds
134 ifcds
, ifcde
, kfcds
,kfcde
, jfcds
,jfcde
, & ! coarse grid domain
135 ifcms
, ifcme
, kfcms
,kfcme
, jfcms
,jfcme
, & ! coarse grid dimensions
136 ifcps
, ifcpe
, kfcps
,kfcpe
, jfcps
,jfcpe
, & ! coarse grid dimensions
137 ifcts
, ifcte
, kfcts
,kfcte
, jfcts
,jfcte
, & ! coarse grid tile
138 uc
,u
,cr_x
,cr_y
,icl_z
,X
,Y
,Z
)
140 ! Multiply by the prolongation matrix transpose
143 ! cr_x, cr_y coarsening factor in horizontal directions x and y
144 ! icl_z 1D array, indices of coarse grid in the z directions
145 ! X,Y,Z grid coordinates
147 ! uc coarse grid vector
152 integer, intent(in
):: &
153 ifds
, ifde
, kfds
, kfde
, jfds
, jfde
, & ! fire domain bounds
154 ifms
, ifme
, kfms
, kfme
, jfms
, jfme
, & ! fire memory bounds
155 ifps
, ifpe
, kfps
, kfpe
, jfps
, jfpe
, & ! fire patch bounds
156 ifts
, ifte
, kfts
, kfte
, jfts
,jfte
, & ! fire tile boundss ifcds, ifcde, kfcds,kfcde, jfcds,jfcde, & ! coarse grid domain
157 ifcds
, ifcde
, kfcds
,kfcde
, jfcds
,jfcde
, & ! coarse grid domain
158 ifcms
, ifcme
, kfcms
,kfcme
, jfcms
,jfcme
, & ! coarse grid dimensions
159 ifcps
, ifcpe
, kfcps
,kfcpe
, jfcps
,jfcpe
, & ! coarse grid dimensions
160 ifcts
, ifcte
, kfcts
,kfcte
, jfcts
,jfcte
! coarse grid tile
162 real, intent(in
), dimension(ifms
:ifme
,kfms
:kfme
,jfms
:jfme
):: X
,Y
,Z
!spatial grid
163 real, intent(out
), dimension(ifcms
:ifcme
,kfcms
:kfcme
,jfcms
:jfcme
):: uc
! coarse vector
165 integer, intent(in
):: cr_x
, cr_y
, & ! coarsening factors in the horizonal directions
166 icl_z(kfcts
:kfcte
) ! indices of coarse grid in the vertical direction
168 real, intent(in
), dimension(ifms
:ifme
,kfms
:kfme
,jfms
:jfme
):: u
! fine grid interpolant
171 integer :: i
,j
,k
,ic
,jc
,kc
,ifc
,jfc
,kfc
,ifs
,ife
,jfs
,jfe
,kfs
,kfe
176 ! zero the output to ready for contributions
177 uc(ifcts
:ifcte
,kfcts
:kfcte
,jfcts
:jfcte
) = 0.
179 if ((icl_z(kfcts
) .ne
. kfts
) .or
. (icl_z(kfcte
) .ne
. kfte
)) then
180 call crash('vertical corsening must include all domain')
183 do kc
=kfcts
,kfcte
! loop over coarse layers
184 kfc
=icl_z(kc
); ! the fine grid number of the coarse layer
186 kfs
=icl_z(kc
-1)+1 ! from above previous coarse
188 kfs
=kfc
! itself, there is no previous fine layer
191 kfe
=icl_z(kc
+1)-1 ! up to under next layer
193 kfe
=kfc
! itself, there is no next layer
195 !print *,'vertical coarse layer ',kc,' at ',kfc,' contributes to layers ',kfs,':',kfe
197 ! really needs to be made fine point oriented and draw from coarse points
199 jfc
=cr_y
*(jc
-jfcds
)+jfds
! fine grid index of the coarse point
200 jfs
=max(jfc
-cr_y
+1,jfds
) ! start support
201 jfe
=min(jfc
+cr_y
-1,jfde
) ! end support
202 if (jfc
> jfde
) then ! after end of domain not divisible by coarse ratio
204 elseif (jfc
> jfde
- cr_y
.and
. jfc
< jfde
)then ! just before end of domain not divisible by coarse ratio
207 !print *,'coarse y ',jc,' at j ',jfc,' contributes to ',jfs,':',jfe
209 ifc
=cr_y
*(ic
-ifcds
)+ifds
! fine grid index of the coarse point
210 ifs
=max(ifc
-cr_y
+1,ifds
) ! start support
211 ife
=min(ifc
+cr_y
-1,ifde
) ! end support
212 if (ifc
> ifde
) then ! after end of domain not divisible by coarse ratio
214 elseif (ifc
> ifde
- cr_x
.and
. ifc
< ifde
)then ! just before end of domain not divisible by coarse ratio
217 !print *,'coarse x ',ic,' at i ',ifc,' contributes to ',ifs,':',ife
221 qi
=(X(i
,k
,j
)-X(ife
+1,k
,j
))/(X(ifc
,k
,j
)-X(ife
+1,k
,j
))
223 qi
=(X(i
,k
,j
)-X(ifs
-1,k
,j
))/(X(ifc
,k
,j
)-X(ifs
-1,k
,j
))
228 qj
=(Y(i
,k
,j
)-Y(i
,k
,jfe
+1))/(Y(i
,k
,jfc
)-Y(i
,k
,jfe
+1))
230 qj
=(Y(i
,k
,j
)-Y(i
,k
,jfs
-1))/(Y(i
,k
,jfc
)-Y(i
,k
,jfs
-1))
235 qk
=(Z(i
,k
,j
)-Z(i
,kfe
+1,j
))/(Z(i
,kfc
,j
)-Z(i
,kfe
+1,j
))
237 qk
=(Z(i
,k
,j
)-Z(i
,kfs
-1,j
))/(Z(i
,kfc
,j
)-Z(i
,kfs
-1,j
))
241 uc(ic
,kc
,jc
) = uc(ic
,kc
,jc
) + u(i
,k
,j
)*qi
*qk
*qj
249 end subroutine restriction
251 subroutine coarsening_icl(cr_x
,cr_y
,icl_z
,dx
,dy
,dz
,A
,minaspect
,maxaspect
)
252 ! decide on coarsening
254 ! dx,dy mesh spacings, scalar
255 ! dz verticl element size, vector
256 ! A matrix size (3,3), only diagonal used
258 ! cr_x,cr_y horizontal coarsening factors in directions x and y
259 ! icl_z coarse indices in direction z, allocated here
263 real,intent(in
):: dx
,dy
,dz(:),A(:,:)
264 real,intent(in
):: minaspect
,maxaspect
265 integer,intent(out
):: cr_x
,cr_y
266 integer,pointer,intent(out
):: icl_z(:)
269 real:: dxy
,crit
,hzcavg
,arat
270 integer, allocatable
:: icl3(:)
271 integer:: nc3
,newlcl
,lcl
,i
,n3
275 dxy
=min(dx
,dy
) ! horizontal step
277 print *,'coarsening_icl in: dx=',dx
,' dy=',dy
,' n3=',n3
,' dz=',dz
278 print *,'coarsening_icl in: A=',A
,' minaspect=',minaspect
,' maxaspect=',maxaspect
279 arat
= A(3,3)/min(A(1,1),A(2,2)) ! scaled vertical penalty
280 ! decide on horizontal coarsening factors
281 crit
=(dz(1)/dxy
)/arat
283 if (crit
> minaspect
) then
290 hzcavg
=sqrt(real(cr_x
*cr_y
));
291 print *,'horizontal coarsening factors ',cr_x
,cr_y
, ' because weighted height is ', crit
294 lcl
=1 ! last coarse level
298 newlcl
=lcl
+1 ! next coarse level by 1
299 if (lcl
+2 <= n3
) then
300 crit
= ((dz(lcl
)+dz(lcl
+1))/(dxy
*hzcavg
))/arat
301 if (crit
< maxaspect
) then
302 newlcl
=lcl
+2 ! next coarse level by 2
308 else ! at the top already
317 call crash('coarsening_icl: number of coarse layers is 0')
319 print *,'vertical coarse layers ',icl_z
321 end subroutine coarsening_icl
323 subroutine coarsening_hzc2icl(icl_x
, icl_y
, cr_x
, cr_y
, n_x
, n_y
)
324 ! translate horizontal coarsening factors to index vectors
327 ! cr_x, cr_y coarsening factors in x and y
328 ! n_x, n_y fine mesh size in x and y
330 ! icl_x, icl_y fine indices of coarse grid lines
335 integer, intent(in
)::cr_x
, cr_y
, n_x
, n_y
336 integer, intent(out
), pointer, dimension(:) :: icl_x
, icl_y
339 integer :: nc_x
, nc_y
342 nc_x
= min(n_x
,n_x
/cr_x
+ 1)
343 nc_y
= min(n_y
,n_y
/cr_y
+ 1)
345 allocate(icl_x(nc_x
))
346 allocate(icl_y(nc_y
))
349 icl_x(i
)=1+cr_x
*(i
-1) ! every second node
351 icl_x(nc_x
)=n_x
! last coarse is last fine
354 icl_y(i
)=1+cr_y
*(i
-1) ! every second node
356 icl_y(nc_y
)=n_y
! last coarse is last fine
358 end subroutine coarsening_hzc2icl
360 subroutine coarsening_grid(l
, &
361 ifds
, ifde
, kfds
, kfde
, jfds
, jfde
, & ! fire grid dimensions
362 ifms
, ifme
, kfms
, kfme
, jfms
, jfme
, & ! memory dimensions
363 ifps
, ifpe
, kfps
, kfpe
, jfps
, jfpe
, & ! fire patch bounds
364 ifts
, ifte
, kfts
, kfte
, jfts
, jfte
, & ! tile dimensions
365 ifcds
, ifcde
, kfcds
,kfcde
, jfcds
,jfcde
, & ! coarse grid domain
366 ifcms
, ifcme
, kfcms
,kfcme
, jfcms
,jfcme
, & ! coarse grid dimensions
367 ifcps
, ifcpe
, kfcps
,kfcpe
, jfcps
,jfcpe
, & ! coarse grid dimensions
368 ifcts
, ifcte
, kfcts
,kfcte
, jfcts
,jfcte
, & ! coarse grid tile
369 icl_x
, icl_y
, icl_z
, &
370 X
, Y
, Z
, X_coarse
, Y_coarse
, Z_coarse
)
372 ! compute coarse grid coordinates arrays on one tile
375 integer,intent(in
)::l
! fine level, coarse is l+1
376 integer, intent(in
):: &
377 ifds
, ifde
, kfds
, kfde
, jfds
, jfde
, & ! fire grid dimensions
378 ifms
, ifme
, kfms
, kfme
, jfms
, jfme
, & ! memory dimensions
379 ifps
, ifpe
, kfps
, kfpe
, jfps
, jfpe
, & ! fire patch bounds
380 ifts
, ifte
, kfts
, kfte
, jfts
, jfte
, & ! tile dimensions
381 ifcds
, ifcde
, kfcds
,kfcde
, jfcds
,jfcde
, & ! coarse grid domain
382 ifcms
, ifcme
, kfcms
,kfcme
, jfcms
,jfcme
, & ! coarse grid dimensions
383 ifcps
, ifcpe
, kfcps
,kfcpe
, jfcps
,jfcpe
, & ! coarse grid dimensions
384 ifcts
, ifcte
, kfcts
,kfcte
, jfcts
,jfcte
! coarse grid tile
386 integer, intent(in
):: icl_x(ifcts
:),icl_y(jfcts
:),icl_z(kfcts
:) ! leaving upper bound to be passed on
387 real, dimension(ifms
:ifme
,kfms
:kfme
,jfms
:jfme
), intent(in
):: X
,Y
,Z
!spatial grid
388 real, intent(out
), dimension(ifcms
:ifcme
,kfcms
:kfcme
,jfcms
:jfcme
):: X_coarse
, Y_coarse
, Z_coarse
! coarse vector
391 integer::ic
,jc
,kc
,ie
,je
,ke
395 ie
= snode(ifcte
,ifcde
,+1)
396 je
= snode(jfcte
,jfcde
,+1)
397 ke
= snode(kfcte
,kfcde
,+1)
402 X_coarse(ic
,kc
,jc
) = X(icl_x(ic
),icl_z(kc
),icl_y(jc
))
403 Y_coarse(ic
,kc
,jc
) = Y(icl_x(ic
),icl_z(kc
),icl_y(jc
))
404 Z_coarse(ic
,kc
,jc
) = Z(icl_x(ic
),icl_z(kc
),icl_y(jc
))
409 end subroutine coarsening_grid
411 end module module_coarsening