PLUME-MoM-TSM  1.0
VolcanicPlumeModel
geometry_2d.f90
Go to the documentation of this file.
1 !*********************************************************************
3 !
6 !*********************************************************************
7 MODULE geometry_2d
8 
9  USE variables, ONLY : wp , sp
10  USE parameters_2d, ONLY : verbose_level
11 
12  IMPLICIT NONE
13 
15  REAL(wp), ALLOCATABLE :: x_comp(:)
16 
18  REAL(wp), ALLOCATABLE :: x_stag(:)
19 
21  REAL(wp), ALLOCATABLE :: y_comp(:)
22 
24  REAL(wp), ALLOCATABLE :: y_stag(:)
25 
27  REAL(wp), ALLOCATABLE :: grid_output(:,:)
28 
29  INTEGER, ALLOCATABLE :: source_cell(:,:)
30  LOGICAL, ALLOCATABLE :: sourcee(:,:)
31  LOGICAL, ALLOCATABLE :: sourcew(:,:)
32  LOGICAL, ALLOCATABLE :: sources(:,:)
33  LOGICAL, ALLOCATABLE :: sourcen(:,:)
34 
35  REAL(wp), ALLOCATABLE :: dist_sourcee(:,:)
36  REAL(wp), ALLOCATABLE :: dist_sourcew(:,:)
37  REAL(wp), ALLOCATABLE :: dist_sources(:,:)
38  REAL(wp), ALLOCATABLE :: dist_sourcen(:,:)
39 
40  REAL(wp), ALLOCATABLE :: sourcee_vect_x(:,:)
41  REAL(wp), ALLOCATABLE :: sourcee_vect_y(:,:)
42 
43  REAL(wp), ALLOCATABLE :: sourcew_vect_x(:,:)
44  REAL(wp), ALLOCATABLE :: sourcew_vect_y(:,:)
45 
46  REAL(wp), ALLOCATABLE :: sources_vect_x(:,:)
47  REAL(wp), ALLOCATABLE :: sources_vect_y(:,:)
48 
49  REAL(wp), ALLOCATABLE :: sourcen_vect_x(:,:)
50  REAL(wp), ALLOCATABLE :: sourcen_vect_y(:,:)
51 
52  REAL(wp) :: pi_g
53 
55 
56  REAL(wp) :: dx
57  REAL(wp) :: x0
58  REAL(wp) :: xn
59  REAL(wp) :: dy
60  REAL(wp) :: y0
61  REAL(wp) :: yn
62  REAL(wp) :: dx2
63  REAL(wp) :: dy2
64  INTEGER :: comp_cells_x
65  INTEGER :: comp_interfaces_x
66  INTEGER :: comp_cells_y
67  INTEGER :: comp_interfaces_y
68  REAL(wp) :: cell_size
69  INTEGER :: comp_cells_xy
70 
71  INTEGER :: j_source , k_source
72  INTEGER :: j_source_w , k_source_s
73 
74  REAL(wp), ALLOCATABLE :: cell_fract(:,:)
75  REAL(wp), ALLOCATABLE :: dx_rel(:,:)
76  REAL(wp), ALLOCATABLE :: dy_rel(:,:)
77 
78  REAL(wp), ALLOCATABLE :: upwind_dist(:,:)
79  REAL(wp), ALLOCATABLE :: crosswind_dist(:,:)
80 
81 CONTAINS
82 
83  !******************************************************************************
85  !
88  !******************************************************************************
89 
90  SUBROUTINE init_grid
91 
92  USE parameters_2d, ONLY: eps_sing
93 
94  IMPLICIT none
95 
96  INTEGER j,k
97 
100 
101  ALLOCATE( x_comp(comp_cells_x) )
102  ALLOCATE( x_stag(comp_interfaces_x) )
103  ALLOCATE( y_comp(comp_cells_y) )
104  ALLOCATE( y_stag(comp_interfaces_y) )
105 
107 
108  ! cell where are equations are solved
110 
111 
112  ALLOCATE( sourcee(comp_cells_x,comp_cells_y) )
113  ALLOCATE( sourcew(comp_cells_x,comp_cells_y) )
114  ALLOCATE( sourcen(comp_cells_x,comp_cells_y) )
115  ALLOCATE( sources(comp_cells_x,comp_cells_y) )
116 
121 
130 
132 
133  WRITE(*,*) 'init_grid: dx = ',dx
134  WRITE(*,*) 'init_grid: dy = ',dy
135 
136  IF ( comp_cells_x .GT. 1 ) THEN
137 
138  dx = cell_size
139 
140  ELSE
141 
142  dx = 1.0_wp
143 
144  END IF
145 
146 
147  IF ( comp_cells_y .GT. 1 ) THEN
148 
149  dy = cell_size
150 
151  ELSE
152 
153  dy = 1.0_wp
154 
155  END IF
156 
157  xn = x0 + comp_cells_x * dx
158  yn = y0 + comp_cells_y * dy
159 
160  dx2 = dx / 2.0_wp
161  dy2 = dy / 2.0_wp
162 
163 
164  IF ( wp .EQ. sp ) THEN
165 
166  eps_sing=min(min( dx ** 4.0_wp,dy ** 4.0_wp ),1.0e-6_wp)
167 
168  ELSE
169 
170  eps_sing=min(min( dx ** 4.0_wp,dy ** 4.0_wp ),1.0e-10_wp)
171 
172  END IF
173 
174  IF ( verbose_level .GE. 1 ) WRITE(*,*) 'eps_sing = ',eps_sing
175 
176  DO j=1,comp_interfaces_x
177 
178  x_stag(j) = x0 + (j-1) * dx
179 
180  END DO
181 
182  DO k=1,comp_interfaces_y
183 
184  y_stag(k) = y0 + (k-1) * dy
185 
186  END DO
187 
188  DO j=1,comp_cells_x
189 
190  x_comp(j) = 0.5_wp * ( x_stag(j) + x_stag(j+1) )
191 
192  END DO
193 
194  DO k=1,comp_cells_y
195 
196  y_comp(k) = 0.5_wp * ( y_stag(k) + y_stag(k+1) )
197 
198  END DO
199 
201  ALLOCATE( dx_rel(comp_cells_x,comp_cells_y) )
202  ALLOCATE( dy_rel(comp_cells_x,comp_cells_y) )
203 
206 
207  RETURN
208 
209  END SUBROUTINE init_grid
210 
211  SUBROUTINE deallocate_grid
213  DEALLOCATE( x_comp )
214  DEALLOCATE( x_stag )
215  DEALLOCATE( y_comp )
216  DEALLOCATE( y_stag )
217 
218  DEALLOCATE( source_cell )
219 
220  DEALLOCATE( sourcee )
221  DEALLOCATE( sourcew )
222  DEALLOCATE( sourcen )
223  DEALLOCATE( sources )
224 
225  DEALLOCATE( dist_sourcee )
226  DEALLOCATE( dist_sourcew )
227  DEALLOCATE( dist_sourcen )
228  DEALLOCATE( dist_sources )
229 
230  DEALLOCATE( sourcee_vect_x )
231  DEALLOCATE( sourcee_vect_y )
232  DEALLOCATE( sourcew_vect_x )
233  DEALLOCATE( sourcew_vect_y )
234  DEALLOCATE( sources_vect_x )
235  DEALLOCATE( sources_vect_y )
236  DEALLOCATE( sourcen_vect_x )
237  DEALLOCATE( sourcen_vect_y )
238 
239  DEALLOCATE( grid_output )
240 
241  DEALLOCATE( cell_fract )
242  DEALLOCATE( dx_rel )
243  DEALLOCATE( dy_rel )
244 
245  DEALLOCATE( upwind_dist )
246  DEALLOCATE( crosswind_dist )
247 
248 
249  END SUBROUTINE deallocate_grid
250 
251 
252  SUBROUTINE init_source
254  USE parameters_2d, ONLY : x_source , y_source , r_source
255 
256  IMPLICIT NONE
257 
258  INTEGER :: j,k
259 
260  REAL(wp) :: total_source
261 
262  j_source = floor( ( x_source - x0 ) / cell_size )
263  k_source = floor( ( y_source - y0 ) / cell_size )
264 
265  j_source_w = floor( ( x_source - r_source - x0 ) / cell_size )
266  k_source_s = floor( ( y_source - r_source - y0 ) / cell_size )
267 
268  ! cell where are equations are solved
270 
271  sourcee(1:comp_cells_x,1:comp_cells_y) = .false.
272  sourcew(1:comp_cells_x,1:comp_cells_y) = .false.
273  sourcen(1:comp_cells_x,1:comp_cells_y) = .false.
274  sources(1:comp_cells_x,1:comp_cells_y) = .false.
275 
280 
281  total_source = 0.0_wp
282 
283  DO k = 2,comp_cells_y-1
284 
285  DO j = 2,comp_cells_x-1
286 
287  IF ( ( x_comp(j) - x_source )**2 + ( y_comp(k) - y_source )**2 .LE. &
288  r_source**2 ) THEN
289 
290  ! cells where equations are not solved
291  source_cell(j,k) = 1
292 
293  ! check on west cell
294  IF ( ( x_comp(j-1) - x_source )**2 + ( y_comp(k) - y_source )**2 &
295  .GE. r_source**2 ) THEN
296 
297  ! cells where radial source boundary condition are applied
298  source_cell(j-1,k) = 2
299  sourcee(j-1,k) = .true.
300  dist_sourcee(j-1,k) = sqrt( ( x_stag(j) - x_source )**2 &
301  + ( y_comp(k) - y_source )**2 )
302 
303  sourcee_vect_x(j-1,k) = ( x_stag(j) - x_source ) * r_source &
304  / dist_sourcee(j-1,k)**2
305 
306  sourcee_vect_y(j-1,k) = ( y_comp(k) - y_source ) * r_source &
307  / dist_sourcee(j-1,k)**2
308 
309  total_source = total_source + dx * abs( sourcee_vect_x(j-1,k) )
310 
311  ELSEIF ( ( x_comp(j+1) - x_source )**2 + ( y_comp(k)-y_source )**2 &
312  .GE. r_source**2 ) THEN
313  ! check on east cell
314 
315  ! cells where radial source boundary condition are applied
316  source_cell(j+1,k) = 2
317  sourcew(j+1,k) = .true.
318  dist_sourcew(j+1,k) = sqrt( ( x_stag(j+1) - x_source )**2 &
319  + ( y_comp(k) - y_source )**2 )
320 
321  sourcew_vect_x(j+1,k) = ( x_stag(j+1) - x_source ) * r_source &
322  / dist_sourcew(j+1,k)**2
323 
324  sourcew_vect_y(j+1,k) = ( y_comp(k) - y_source ) * r_source &
325  / dist_sourcew(j+1,k)**2
326 
327  total_source = total_source + dx * abs( sourcew_vect_x(j+1,k) )
328 
329  END IF
330 
331  ! check on south cell
332  IF ( ( x_comp(j) - x_source )**2 + ( y_comp(k-1) - y_source )**2 &
333  .GE. r_source**2 ) THEN
334 
335  ! cells where radial source boundary condition are applied
336  source_cell(j,k-1) = 2
337  sourcen(j,k-1) = .true.
338  dist_sourcen(j,k-1) = sqrt( ( x_comp(j) - x_source )**2 &
339  + ( y_stag(k) - y_source )**2 )
340 
341  sourcen_vect_x(j,k-1) = ( x_comp(j) - x_source ) * r_source &
342  / dist_sourcen(j,k-1)**2
343 
344  sourcen_vect_y(j,k-1) = ( y_stag(k) - y_source ) * r_source &
345  / dist_sourcen(j,k-1)**2
346 
347  total_source = total_source + dy * abs( sourcen_vect_y(j,k-1) )
348 
349  ELSEIF ( ( x_comp(j)-x_source )**2 + ( y_comp(k+1) - y_source )**2 &
350  .GE. r_source**2 ) THEN
351 
352  ! cells where radial source boundary condition are applied
353  source_cell(j,k+1) = 2
354  sources(j,k+1) = .true.
355  dist_sources(j,k+1) = sqrt( ( x_comp(j) - x_source )**2 &
356  + ( y_stag(k+1) - y_source )**2 )
357 
358  sources_vect_x(j,k+1) = ( x_comp(j) - x_source ) * r_source &
359  / dist_sources(j,k+1)**2
360 
361  sources_vect_y(j,k+1) = ( y_stag(k+1) - y_source ) * r_source &
362  / dist_sources(j,k+1)**2
363 
364  total_source = total_source + dy * abs( sources_vect_y(j,k+1) )
365 
366  END IF
367 
368  END IF
369 
370  END DO
371 
372  END DO
373 
374  RETURN
375 
376  END SUBROUTINE init_source
377 
378  !-----------------------------------------------------------------------------
380  !
388  !-----------------------------------------------------------------------------
389 
390  SUBROUTINE interp_1d_scalar(x1, f1, x2, f2)
391  IMPLICIT NONE
392 
393  REAL(wp), INTENT(IN), DIMENSION(:) :: x1, f1
394  REAL(wp), INTENT(IN) :: x2
395  REAL(wp), INTENT(OUT) :: f2
396  INTEGER :: n, n1x, t
397  REAL(wp) :: grad , rel_pos
398 
399  n1x = SIZE(x1)
400 
401  !
402  ! ... locate the grid points near the topographic points
403  ! ... and interpolate linearly the profile
404  !
405  t = 1
406 
407  search:DO n = 1, n1x-1
408 
409  rel_pos = ( x2 - x1(n) ) / ( x1(n+1) - x1(n) )
410 
411  IF ( ( rel_pos .GE. 0.0_wp ) .AND. ( rel_pos .LE. 1.0_wp ) ) THEN
412 
413  grad = ( f1(n+1)-f1(n) ) / ( x1(n+1)-x1(n) )
414  f2 = f1(n) + ( x2-x1(n) ) * grad
415 
416  EXIT search
417 
418  ELSEIF ( rel_pos .LT. 0.0_wp ) THEN
419 
420  f2 = f1(n)
421 
422  ELSE
423 
424  f2 = f1(n+1)
425 
426  END IF
427 
428  END DO search
429 
430  RETURN
431 
432  END SUBROUTINE interp_1d_scalar
433 
434  !-----------------------------------------------------------------------------
436  !
446  !-----------------------------------------------------------------------------
447 
448  SUBROUTINE interp_2d_scalar(x1, y1, f1, x2, y2, f2)
449  IMPLICIT NONE
450 
451  REAL(wp), INTENT(IN), DIMENSION(:,:) :: x1, y1, f1
452  REAL(wp), INTENT(IN) :: x2, y2
453  REAL(wp), INTENT(OUT) :: f2
454 
455  INTEGER :: ix , iy
456  REAL(wp) :: alfa_x , alfa_y
457 
458  IF ( size(x1,1) .GT. 1 ) THEN
459 
460  ix = floor( ( x2 - x1(1,1) ) / ( x1(2,1) - x1(1,1) ) ) + 1
461  ix = min( ix , SIZE(x1,1)-1 )
462  alfa_x = ( x1(ix+1,1) - x2 ) / ( x1(ix+1,1) - x1(ix,1) )
463 
464  ELSE
465 
466  ix = 1
467  alfa_x = 0.0_wp
468 
469  END IF
470 
471  IF ( size(x1,2) .GT. 1 ) THEN
472 
473  iy = floor( ( y2 - y1(1,1) ) / ( y1(1,2) - y1(1,1) ) ) + 1
474  iy = min( iy , SIZE(x1,2)-1 )
475  alfa_y = ( y1(1,iy+1) - y2 ) / ( y1(1,iy+1) - y1(1,iy) )
476 
477  ELSE
478 
479  iy = 1
480  alfa_y = 0.0_wp
481 
482  END IF
483 
484  IF ( size(x1,1) .EQ. 1 ) THEN
485 
486  f2 = alfa_y * f1(ix,iy) + ( 1.0_wp - alfa_y ) * f1(ix,iy+1)
487 
488  ELSEIF ( size(x1,2) .EQ. 1 ) THEN
489 
490  f2 = alfa_x * f1(ix,iy) + ( 1.0_wp - alfa_x ) * f1(ix+1,iy)
491 
492  ELSE
493 
494  f2 = alfa_x * ( alfa_y * f1(ix,iy) + ( 1.0_wp - alfa_y ) * f1(ix,iy+1) ) &
495  + ( 1.0_wp - alfa_x ) * ( alfa_y * f1(ix+1,iy) + ( 1.0_wp - alfa_y )&
496  * f1(ix+1,iy+1) )
497 
498  END IF
499 
500  END SUBROUTINE interp_2d_scalar
501 
502  !-----------------------------------------------------------------------------
504  !
515  !-----------------------------------------------------------------------------
516 
517  SUBROUTINE interp_2d_scalarb(x1, y1, f1, x2, y2, f2)
518  IMPLICIT NONE
519 
520  REAL(wp), INTENT(IN), DIMENSION(:) :: x1, y1
521  REAL(wp), INTENT(IN), DIMENSION(:,:) :: f1
522  REAL(wp), INTENT(IN) :: x2, y2
523  REAL(wp), INTENT(OUT) :: f2
524 
525  INTEGER :: ix , iy
526  REAL(wp) :: alfa_x , alfa_y
527 
528  IF ( size(x1) .GT. 1 ) THEN
529 
530  ix = floor( ( x2 - x1(1) ) / ( x1(2) - x1(1) ) ) + 1
531  ix = max(0,min( ix , SIZE(x1)-1 ))
532  alfa_x = ( x1(ix+1) - x2 ) / ( x1(ix+1) - x1(ix) )
533 
534  ELSE
535 
536  ix = 1
537  alfa_x = 0.0_wp
538 
539  END IF
540 
541  IF ( size(y1) .GT. 1 ) THEN
542 
543  iy = floor( ( y2 - y1(1) ) / ( y1(2) - y1(1) ) ) + 1
544  iy = max(1,min( iy , SIZE(y1)-1 ))
545  alfa_y = ( y1(iy+1) - y2 ) / ( y1(iy+1) - y1(iy) )
546 
547  ELSE
548 
549  iy = 1
550  alfa_y = 0.0_wp
551 
552  END IF
553 
554  IF ( ( alfa_x .LT. 0.0_wp ) .OR. ( alfa_x .GT. 1.0_wp ) &
555  .OR. ( alfa_y .LT. 0.0_wp ) .OR. ( alfa_y .GT. 1.0_wp ) ) THEN
556 
557  f2 = 0.0_wp
558  RETURN
559 
560  END IF
561 
562 
563  IF ( size(x1) .EQ. 1 ) THEN
564 
565  f2 = alfa_y * f1(ix,iy) + ( 1.0_wp - alfa_y ) * f1(ix,iy+1)
566 
567  ELSEIF ( size(y1) .EQ. 1 ) THEN
568 
569  f2 = alfa_x * f1(ix,iy) + ( 1.0_wp - alfa_x ) * f1(ix+1,iy)
570 
571  ELSE
572 
573  f2 = alfa_x * ( alfa_y * f1(ix,iy) + ( 1.0_wp - alfa_y ) * f1(ix,iy+1) ) &
574  + ( 1.0_wp - alfa_x ) * ( alfa_y * f1(ix+1,iy) + ( 1.0_wp - alfa_y )&
575  * f1(ix+1,iy+1) )
576 
577  END IF
578 
579  RETURN
580 
581  END SUBROUTINE interp_2d_scalarb
582 
583  !-----------------------------------------------------------------------------
585  !
595  !-----------------------------------------------------------------------------
596 
597  SUBROUTINE interp_2d_slope(x1, y1, f1, x2, y2, f_x, f_y)
598  IMPLICIT NONE
599 
600  REAL(wp), INTENT(IN), DIMENSION(:,:) :: x1, y1, f1
601  REAL(wp), INTENT(IN) :: x2, y2
602  REAL(wp), INTENT(OUT) :: f_x , f_y
603 
604  INTEGER :: ix , iy
605  REAL(wp) :: alfa_x , alfa_y
606  REAL(wp) :: f_x1 , f_x2 , f_y1 , f_y2
607 
608 
609  IF ( size(x1,1) .GT. 1 ) THEN
610 
611  ix = floor( ( x2 - x1(1,1) ) / ( x1(2,1) - x1(1,1) ) ) + 1
612  ix = min( ix , SIZE(x1,1)-1 )
613  alfa_x = ( x1(ix+1,1) - x2 ) / ( x1(ix+1,1) - x1(ix,1) )
614 
615  ELSE
616 
617  ix = 1
618  alfa_x = 1.0_wp
619 
620  END IF
621 
622  IF ( size(x1,2) .GT. 1 ) THEN
623 
624  iy = floor( ( y2 - y1(1,1) ) / ( y1(1,2) - y1(1,1) ) ) + 1
625  iy = min( iy , SIZE(x1,2)-1 )
626  alfa_y = ( y1(1,iy+1) - y2 ) / ( y1(1,iy+1) - y1(1,iy) )
627 
628  ELSE
629 
630  iy = 1
631  alfa_y = 1.0_wp
632 
633  END IF
634 
635  f_x1 = 0.0_wp
636  f_x2 = 0.0_wp
637 
638  IF ( size(x1,1) .GT. 1 ) THEN
639 
640  f_x1 = ( f1(ix+1,iy) - f1(ix,iy) ) / ( x1(2,1) - x1(1,1) )
641 
642  IF ( size(x1,2) .GT. 1 ) THEN
643 
644  f_x2 = ( f1(ix+1,iy+1) - f1(ix,iy+1) ) / ( x1(2,1) - x1(1,1) )
645 
646  END IF
647 
648  END IF
649 
650  f_x = alfa_y * f_x1 + ( 1.0_wp - alfa_y ) * f_x2
651 
652  f_y1 = 0.0_wp
653  f_y2 = 0.0_wp
654 
655  IF ( size(x1,2) .GT. 1 ) THEN
656 
657  f_y1 = ( f1(ix,iy+1) - f1(ix,iy) ) / ( y1(1,2) - y1(1,1) )
658 
659  IF ( size(x1,1) .GT. 1 ) THEN
660 
661  f_y2 = ( f1(ix+1,iy+1) - f1(ix+1,iy) ) / ( y1(1,2) - y1(1,1) )
662 
663  END IF
664 
665  END IF
666 
667  f_y = alfa_x * f_y1 + ( 1.0_wp - alfa_x ) * f_y2
668 
669 
670  RETURN
671 
672  END SUBROUTINE interp_2d_slope
673 
674  !-----------------------------------------------------------------------------
676  !
689  !-----------------------------------------------------------------------------
690 
691  SUBROUTINE regrid_scalar(xin, yin, fin, xl, xr , yl, yr, fout)
692  IMPLICIT NONE
693 
694  REAL(wp), INTENT(IN), DIMENSION(:) :: xin, yin
695  REAL(wp), INTENT(IN), DIMENSION(:,:) :: fin
696  REAL(wp), INTENT(IN) :: xl, xr , yl , yr
697  REAL(wp), INTENT(OUT) :: fout
698 
699  INTEGER :: ix , iy
700  INTEGER :: ix1 , ix2 , iy1 , iy2
701  REAL(wp) :: alfa_x , alfa_y
702  REAL(wp) :: dXin , dYin
703 
704  INTEGER nXin,nYin
705 
706  nxin = size(xin)-1
707  nyin = size(yin)-1
708 
709  dxin = xin(2) - xin(1)
710  dyin = yin(2) - yin(1)
711 
712  ix1 = max(1,ceiling( ( xl - xin(1) ) / dxin ))
713  ix2 = min(nxin,ceiling( ( xr -xin(1) ) / dxin )+1)
714 
715  iy1 = max(1,ceiling( ( yl - yin(1) ) / dyin ))
716  iy2 = min(nyin,ceiling( ( yr - yin(1) ) / dyin ) + 1)
717 
718  fout = 0.0_wp
719 
720  DO ix=ix1,ix2-1
721 
722  alfa_x = ( min(xr,xin(ix+1)) - max(xl,xin(ix)) ) / ( xr - xl )
723 
724  DO iy=iy1,iy2-1
725 
726  alfa_y = ( min(yr,yin(iy+1)) - max(yl,yin(iy)) ) / ( yr - yl )
727 
728  fout = fout + alfa_x * alfa_y * fin(ix,iy)
729 
730  END DO
731 
732  END DO
733 
734  END SUBROUTINE regrid_scalar
735 
736  !******************************************************************************
738  !
753  !******************************************************************************
754 
755  SUBROUTINE limit( v , z , limiter , slope_lim )
757  USE parameters_2d, ONLY : theta
758 
759  IMPLICIT none
760 
761  REAL(wp), INTENT(IN) :: v(3)
762  REAL(wp), INTENT(IN) :: z(3)
763  INTEGER, INTENT(IN) :: limiter
764 
765  REAL(wp), INTENT(OUT) :: slope_lim
766 
767  REAL(wp) :: a , b , c
768 
769  REAL(wp) :: sigma1 , sigma2
770 
771  a = ( v(3) - v(2) ) / ( z(3) - z(2) )
772  b = ( v(2) - v(1) ) / ( z(2) - z(1) )
773  c = ( v(3) - v(1) ) / ( z(3) - z(1) )
774 
775  SELECT CASE (limiter)
776 
777  CASE ( 0 )
778 
779  slope_lim = 0.0_wp
780 
781  CASE ( 1 )
782 
783  ! minmod
784  slope_lim = minmod(a,b)
785 
786  CASE ( 2 )
787 
788  ! superbee
789  sigma1 = minmod( a , 2.0_wp*b )
790  sigma2 = minmod( 2.0_wp*a , b )
791  slope_lim = maxmod( sigma1 , sigma2 )
792 
793  CASE ( 3 )
794 
795  ! generalized minmod
796  slope_lim = minmod( c , theta * minmod( a , b ) )
797 
798  CASE ( 4 )
799 
800  ! monotonized central-difference (MC, LeVeque p.112)
801  slope_lim = minmod( c , 2.0 * minmod( a , b ) )
802 
803  CASE ( 5 )
804 
805  ! centered
806  slope_lim = c
807 
808  CASE (6)
809 
810  ! backward
811  slope_lim = a
812 
813  CASE (7)
814 
815  !forward
816  slope_lim = b
817 
818  END SELECT
819 
820  END SUBROUTINE limit
821 
822 
823  REAL(wp) FUNCTION minmod(a,b)
825  IMPLICIT none
826 
827  REAL(wp) :: a , b , sa , sb
828 
829  IF ( a*b .EQ. 0.0_wp ) THEN
830 
831  minmod = 0.0_wp
832 
833  ELSE
834 
835  sa = a / abs(a)
836  sb = b / abs(b)
837 
838  minmod = 0.5_wp * ( sa+sb ) * min( abs(a) , abs(b) )
839 
840  END IF
841 
842  END FUNCTION minmod
843 
844  REAL(wp) function maxmod(a,b)
846  IMPLICIT none
847 
848  REAL(wp) :: a , b , sa , sb
849 
850  IF ( a*b .EQ. 0.0_wp ) THEN
851 
852  maxmod = 0.0_wp
853 
854  ELSE
855 
856  sa = a / abs(a)
857  sb = b / abs(b)
858 
859  maxmod = 0.5_wp * ( sa+sb ) * max( abs(a) , abs(b) )
860 
861  END IF
862 
863  END function maxmod
864 
865  SUBROUTINE compute_cell_fract
868 
869  IMPLICIT NONE
870 
871  REAL(wp), ALLOCATABLE :: x_subgrid(:) , y_subgrid(:)
872 
873  REAL(wp) :: r_rel
874 
875  INTEGER, ALLOCATABLE :: check_subgrid(:)
876 
877  INTEGER n_points , n_points2
878 
879  REAL(wp) :: source_area
880  REAL(wp) :: delta_x , delta_y
881 
882  INTEGER :: h ,j, k
883 
884 
885  j_source = floor( ( x_source - x0 ) / cell_size )
886  k_source = floor( ( y_source - y0 ) / cell_size )
887 
888  j_source_w = floor( ( x_source - r_source - x0 ) / cell_size )
889  k_source_s = floor( ( y_source - r_source - y0 ) / cell_size )
890 
891  n_points = 200
892  n_points2 = n_points**2
893 
894  ALLOCATE( x_subgrid(n_points2) )
895  ALLOCATE( y_subgrid(n_points2) )
896  ALLOCATE( check_subgrid(n_points2) )
897 
898  x_subgrid = 0.0_wp
899  y_subgrid = 0.0_wp
900 
901  DO h = 1,n_points
902 
903  x_subgrid(h:n_points2:n_points) = dble(h)
904  y_subgrid((h-1)*n_points+1:h*n_points) = dble(h)
905 
906  END DO
907 
908  x_subgrid = ( 2.0_wp * x_subgrid - 1.0_wp ) / ( 2.0_wp * dble(n_points) )
909  y_subgrid = ( 2.0_wp * y_subgrid - 1.0_wp ) / ( 2.0_wp * dble(n_points) )
910 
911  x_subgrid = ( x_subgrid - 0.5_wp ) * dx
912  y_subgrid = ( y_subgrid - 0.5_wp ) * dy
913 
914  DO j=1,comp_cells_x
915 
916  DO k=1,comp_cells_y
917 
918  IF ( ( x_stag(j+1) .LT. ( x_source - r_source ) ) .OR. &
919  ( x_stag(j) .GT. ( x_source + r_source ) ) .OR. &
920  ( y_stag(k+1) .LT. ( y_source - r_source ) ) .OR. &
921  ( y_stag(k) .GT. ( y_source + r_source ) ) ) THEN
922 
923  cell_fract(j,k) = 0.0_wp
924 
925  ELSE
926 
927  check_subgrid = 0
928 
929  WHERE ( ( x_comp(j) + x_subgrid - x_source )**2 &
930  + ( y_comp(k) + y_subgrid - y_source )**2 < r_source**2 )
931 
932  check_subgrid = 1
933 
934  END WHERE
935 
936  cell_fract(j,k) = REAL(sum(check_subgrid))/n_points2
937 
938  delta_x = x_comp(j) - x_source
939  delta_y = y_comp(k) - y_source
940  r_rel = min( 1.0_wp , sqrt( delta_x**2 + delta_y**2 ) / r_source )
941 
942  dx_rel(j,k) = delta_x / sqrt( delta_x**2 + delta_y**2 ) * r_rel * dr_dz
943  dy_rel(j,k) = delta_y / sqrt( delta_x**2 + delta_y**2 ) * r_rel * dr_dz
944 
945  END IF
946 
947  ENDDO
948 
949  ENDDO
950 
951  source_area = dx*dy*sum(cell_fract)
952 
953  IF ( verbose_level .GE. 0 ) THEN
954 
955  WRITE(*,*) 'Source area =',source_area,' Error =',abs( 1.0_wp - &
956  dx*dy*sum(cell_fract) / ( 4.0_wp*atan(1.0_wp)*r_source**2 ) )
957 
958  END IF
959 
960  DEALLOCATE( x_subgrid )
961  DEALLOCATE( y_subgrid )
962  DEALLOCATE( check_subgrid )
963 
964  RETURN
965 
966  END SUBROUTINE compute_cell_fract
967 
968 
969 END MODULE geometry_2d
real(wp), dimension(:,:), allocatable sourcew_vect_x
Definition: geometry_2d.f90:43
real(wp) pi_g
Definition: geometry_2d.f90:52
real(wp), dimension(:,:), allocatable sourcew_vect_y
Definition: geometry_2d.f90:44
integer, parameter sp
Definition: variables.f90:17
real(wp), dimension(:,:), allocatable sources_vect_x
Definition: geometry_2d.f90:46
integer comp_cells_x
Number of control volumes x in the comp. domain.
Definition: geometry_2d.f90:64
real(wp) cell_size
Definition: geometry_2d.f90:68
real(wp) dy2
Half y Control volumes size.
Definition: geometry_2d.f90:63
integer n_topography_profile_y
Definition: geometry_2d.f90:54
real(wp) r_source
Parameters.
integer comp_cells_y
Number of control volumes y in the comp. domain.
Definition: geometry_2d.f90:66
logical, dimension(:,:), allocatable sourcee
Definition: geometry_2d.f90:30
logical, dimension(:,:), allocatable sourcew
Definition: geometry_2d.f90:31
real(wp) x0
Left of the physical domain.
Definition: geometry_2d.f90:57
real(wp), dimension(:,:), allocatable cell_fract
Definition: geometry_2d.f90:74
real(wp), dimension(:,:), allocatable sourcee_vect_x
Definition: geometry_2d.f90:40
subroutine regrid_scalar(xin, yin, fin, xl, xr, yl, yr, fout)
Scalar regrid (2D)
integer n_topography_profile_x
Definition: geometry_2d.f90:54
real(wp) yn
Top of the physical domain.
Definition: geometry_2d.f90:61
real(wp) function minmod(a, b)
integer comp_interfaces_y
Number of interfaces (comp_cells_y+1)
Definition: geometry_2d.f90:67
real(wp), dimension(:,:), allocatable dist_sourcee
Definition: geometry_2d.f90:35
integer j_source
Definition: geometry_2d.f90:71
real(wp), dimension(:), allocatable x_comp
Location of the centers (x) of the control volume of the domain.
Definition: geometry_2d.f90:15
real(wp) function maxmod(a, b)
integer j_source_w
Definition: geometry_2d.f90:72
real(wp), dimension(:,:), allocatable dist_sources
Definition: geometry_2d.f90:37
integer comp_cells_xy
Definition: geometry_2d.f90:69
real(wp), dimension(:,:), allocatable sourcee_vect_y
Definition: geometry_2d.f90:41
subroutine init_grid
Finite volume grid initialization.
Definition: geometry_2d.f90:91
subroutine limit(v, z, limiter, slope_lim)
Slope limiter.
real(wp), dimension(:), allocatable x_stag
Location of the boundaries (x) of the control volumes of the domain.
Definition: geometry_2d.f90:18
subroutine interp_2d_slope(x1, y1, f1, x2, y2, f_x, f_y)
Scalar interpolation (2D)
real(wp), dimension(:,:), allocatable dist_sourcen
Definition: geometry_2d.f90:38
real(wp) dx2
Half x Control volumes size.
Definition: geometry_2d.f90:62
integer, dimension(:,:), allocatable source_cell
Definition: geometry_2d.f90:29
subroutine deallocate_grid
subroutine init_source
Grid module.
Definition: geometry_2d.f90:7
real(wp), dimension(:), allocatable y_stag
Location of the boundaries (x) of the control volumes of the domain.
Definition: geometry_2d.f90:24
integer verbose_level
subroutine compute_cell_fract
real(wp), dimension(:,:), allocatable dx_rel
Definition: geometry_2d.f90:75
subroutine interp_2d_scalarb(x1, y1, f1, x2, y2, f2)
Scalar interpolation (2D)
real(wp) dx
Control volumes size.
Definition: geometry_2d.f90:56
subroutine interp_2d_scalar(x1, y1, f1, x2, y2, f2)
Scalar interpolation (2D)
real(wp) y_source
real(wp), dimension(:,:), allocatable upwind_dist
Definition: geometry_2d.f90:78
real(wp), dimension(:,:), allocatable sources_vect_y
Definition: geometry_2d.f90:47
integer, parameter wp
working precision
Definition: variables.f90:21
real(wp), dimension(:,:), allocatable sourcen_vect_y
Definition: geometry_2d.f90:50
real(wp), dimension(:,:), allocatable crosswind_dist
Definition: geometry_2d.f90:79
real(wp), dimension(:,:), allocatable grid_output
Solution in ascii grid format (ESRI)
Definition: geometry_2d.f90:27
logical, dimension(:,:), allocatable sourcen
Definition: geometry_2d.f90:33
integer k_source_s
Definition: geometry_2d.f90:72
integer comp_interfaces_x
Number of interfaces (comp_cells_x+1)
Definition: geometry_2d.f90:65
real(wp) y0
Bottom of the physical domain.
Definition: geometry_2d.f90:60
real(wp) xn
Right of the physical domain.
Definition: geometry_2d.f90:58
real(wp), dimension(:,:), allocatable dist_sourcew
Definition: geometry_2d.f90:36
real(wp) theta
Van Leer limiter parameter.
subroutine interp_1d_scalar(x1, f1, x2, f2)
Scalar interpolation.
real(wp) eps_sing
parameter for desingularization
real(wp) x_source
Global variables.
Definition: variables.f90:10
real(wp), dimension(:), allocatable y_comp
Location of the centers (y) of the control volume of the domain.
Definition: geometry_2d.f90:21
real(wp), dimension(:,:), allocatable sourcen_vect_x
Definition: geometry_2d.f90:49
integer k_source
Definition: geometry_2d.f90:71
logical, dimension(:,:), allocatable sources
Definition: geometry_2d.f90:32
real(wp) dy
Control volumes size.
Definition: geometry_2d.f90:59
real(wp), dimension(:,:), allocatable dy_rel
Definition: geometry_2d.f90:76