IMEX_SfloW2D  0.9
Shallowwatergranularflowmodel
solver_2d.f90
Go to the documentation of this file.
1 !*******************************************************************************
3 !
6 !
10 !
11 !********************************************************************************
12 MODULE solver_2d
13 
14  ! external variables
15 
16  USE constitutive_2d, ONLY : implicit_flag
17 
20 
22  USE geometry_2d, ONLY : grav_surf
23 
24  USE parameters_2d, ONLY : n_eqns , n_vars , n_nh
25  USE parameters_2d, ONLY : n_rk
26  USE parameters_2d, ONLY : verbose_level
27 
28  USE parameters_2d, ONLY : bcw , bce , bcs , bcn
29 
30  IMPLICIT none
31 
33  REAL*8, ALLOCATABLE :: q(:,:,:)
35  REAL*8, ALLOCATABLE :: q0(:,:,:)
37  REAL*8, ALLOCATABLE :: q_fv(:,:,:)
39  REAL*8, ALLOCATABLE :: q_interfacel(:,:,:)
41  REAL*8, ALLOCATABLE :: q_interfacer(:,:,:)
43  REAL*8, ALLOCATABLE :: q_interfaceb(:,:,:)
45  REAL*8, ALLOCATABLE :: q_interfacet(:,:,:)
47  REAL*8, ALLOCATABLE :: a_interface_xneg(:,:,:)
49  REAL*8, ALLOCATABLE :: a_interface_xpos(:,:,:)
51  REAL*8, ALLOCATABLE :: a_interface_yneg(:,:,:)
53  REAL*8, ALLOCATABLE :: a_interface_ypos(:,:,:)
55  REAL*8, ALLOCATABLE :: h_interface_x(:,:,:)
57  REAL*8, ALLOCATABLE :: h_interface_y(:,:,:)
59  REAL*8, ALLOCATABLE :: qp(:,:,:)
60 
62  REAL*8, ALLOCATABLE :: source_xy(:,:)
63 
64  LOGICAL, ALLOCATABLE :: solve_mask(:,:) , solve_mask0(:,:)
65 
67  REAL*8 :: dt
68 
69  LOGICAL, ALLOCATABLE :: mask22(:,:) , mask21(:,:) , mask11(:,:) , mask12(:,:)
70 
71  INTEGER :: i_rk
72 
74  REAL*8, ALLOCATABLE :: a_tilde_ij(:,:)
76  REAL*8, ALLOCATABLE :: a_dirk_ij(:,:)
77 
79  REAL*8, ALLOCATABLE :: omega_tilde(:)
81  REAL*8, ALLOCATABLE :: omega(:)
82 
84  REAL*8, ALLOCATABLE :: a_tilde(:)
86  REAL*8, ALLOCATABLE :: a_dirk(:)
88  REAL*8 :: a_diag
89 
91  REAL*8, ALLOCATABLE :: q_rk(:,:,:,:)
93  REAL*8, ALLOCATABLE :: divflux(:,:,:,:)
95  REAL*8, ALLOCATABLE :: nh(:,:,:,:)
97  REAL*8, ALLOCATABLE :: si_nh(:,:,:,:)
98 
100  REAL*8, ALLOCATABLE :: expl_terms(:,:,:,:)
101 
103  REAL*8, ALLOCATABLE :: divfluxj(:,:)
105  REAL*8, ALLOCATABLE :: nhj(:,:)
107  REAL*8, ALLOCATABLE :: expl_terms_j(:,:)
109  REAL*8, ALLOCATABLE :: si_nhj(:,:)
110 
112  LOGICAL :: normalize_q
113 
115  LOGICAL :: normalize_f
116 
118  LOGICAL :: opt_search_nl
119 
121  REAL*8, ALLOCATABLE :: residual_term(:,:,:)
122 
123 
124  REAL*8 :: t_imex1,t_imex2
125 
126 CONTAINS
127 
128  !******************************************************************************
130  !
133  !
137  !
138  !******************************************************************************
139 
140  SUBROUTINE allocate_solver_variables
142  IMPLICIT NONE
143 
144  REAL*8 :: gamma , delta
145 
146  INTEGER :: i,j
147 
148  ALLOCATE( q( n_vars , comp_cells_x , comp_cells_y ) , q0( n_vars , &
149  comp_cells_x , comp_cells_y ) )
150 
151  ALLOCATE( q_fv( n_vars , comp_cells_x , comp_cells_y ) )
152 
153  ALLOCATE( q_interfacel( n_vars , comp_interfaces_x, comp_cells_y ) )
154  ALLOCATE( q_interfacer( n_vars , comp_interfaces_x, comp_cells_y ) )
155  ALLOCATE( a_interface_xneg( n_eqns , comp_interfaces_x, comp_cells_y ) )
156  ALLOCATE( a_interface_xpos( n_eqns , comp_interfaces_x, comp_cells_y ) )
157  ALLOCATE( h_interface_x( n_eqns , comp_interfaces_x, comp_cells_y ) )
158 
159 
160  ALLOCATE( q_interfaceb( n_vars , comp_cells_x, comp_interfaces_y ) )
161  ALLOCATE( q_interfacet( n_vars , comp_cells_x, comp_interfaces_y ) )
162  ALLOCATE( a_interface_yneg( n_eqns , comp_cells_x, comp_interfaces_y ) )
163  ALLOCATE( a_interface_ypos( n_eqns , comp_cells_x, comp_interfaces_y ) )
164 
165 
166  ALLOCATE( h_interface_y( n_eqns , comp_cells_x, comp_interfaces_y ) )
167 
168  ALLOCATE( solve_mask( comp_cells_x , comp_cells_y ) )
169  ALLOCATE( solve_mask0( comp_cells_x , comp_cells_y ) )
170 
171  ALLOCATE( qp( n_vars , comp_cells_x , comp_cells_y ) )
172 
173  ALLOCATE( source_xy( comp_cells_x , comp_cells_y ) )
174 
175 
176  ALLOCATE( a_tilde_ij(n_rk,n_rk) )
177  ALLOCATE( a_dirk_ij(n_rk,n_rk) )
178  ALLOCATE( omega_tilde(n_rk) )
179  ALLOCATE( omega(n_rk) )
180 
181 
182  ! Allocate the logical arrays defining the implicit parts of the system
183  ALLOCATE( mask22(n_eqns,n_eqns) )
184  ALLOCATE( mask21(n_eqns,n_eqns) )
185  ALLOCATE( mask11(n_eqns,n_eqns) )
186  ALLOCATE( mask12(n_eqns,n_eqns) )
187 
188  ! Initialize the logical arrays with all false (everything is implicit)
189  mask11(1:n_eqns,1:n_eqns) = .false.
190  mask12(1:n_eqns,1:n_eqns) = .false.
191  mask22(1:n_eqns,1:n_eqns) = .false.
192  mask21(1:n_eqns,1:n_eqns) = .false.
193 
194  ! Set to .TRUE. the elements not corresponding to equations and variables to
195  ! be solved implicitly
196  DO i = 1,n_eqns
197 
198  DO j = 1,n_eqns
199 
200  IF ( .NOT.implicit_flag(i) .AND. .NOT.implicit_flag(j) ) &
201  mask11(j,i) = .true.
202  IF ( implicit_flag(i) .AND. .NOT.implicit_flag(j) ) &
203  mask12(j,i) = .true.
204  IF ( implicit_flag(i) .AND. implicit_flag(j) ) &
205  mask22(j,i) = .true.
206  IF ( .NOT.implicit_flag(i) .AND. implicit_flag(j) ) &
207  mask21(j,i) = .true.
208 
209  END DO
210 
211  END DO
212 
213  ! Initialize the coefficients for the IMEX Runge-Kutta scheme
214  ! Please note that with respect to the schemes described in Pareschi & Russo
215  ! (2000) we do not have the coefficient vectors c_tilde and c, because the
216  ! explicit and implicit terms do not depend explicitly on time.
217 
218  ! Explicit part coefficients (a_tilde_ij=0 for j>=i)
219  a_tilde_ij = 0.d0
220 
221  ! Weight coefficients of the explicit part in the final assemblage
222  omega_tilde = 0.d0
223 
224  ! Implicit part coefficients (a_dirk_ij=0 for j>i)
225  a_dirk_ij = 0.d0
226 
227  ! Weight coefficients of the explicit part in the final assemblage
228  omega = 0.d0
229 
230  gamma = 1.d0 - 1.d0 / sqrt(2.d0)
231  delta = 1.d0 - 1.d0 / ( 2.d0 * gamma )
232 
233  IF ( n_rk .EQ. 1 ) THEN
234 
235  a_tilde_ij(1,1) = 1.d0
236 
237  omega_tilde(1) = 1.d0
238 
239  a_dirk_ij(1,1) = 0.d0
240 
241  omega(1) = 0.d0
242 
243  ELSEIF ( n_rk .EQ. 2 ) THEN
244 
245  a_tilde_ij(2,1) = 1.0d0
246 
247  omega_tilde(1) = 1.0d0
248  omega_tilde(2) = 0.0d0
249 
250  a_dirk_ij(2,2) = 1.0d0
251 
252  omega(1) = 0.d0
253  omega(2) = 1.d0
254 
255 
256  ELSEIF ( n_rk .EQ. 3 ) THEN
257 
258  ! Tableau for the IMEX-SSP(3,3,2) Stiffly Accurate Scheme
259  ! from Pareschi & Russo (2005), Table IV
260 
261  a_tilde_ij(2,1) = 0.5d0
262  a_tilde_ij(3,1) = 0.5d0
263  a_tilde_ij(3,2) = 0.5d0
264 
265  omega_tilde(1) = 1.0d0 / 3.0d0
266  omega_tilde(2) = 1.0d0 / 3.0d0
267  omega_tilde(3) = 1.0d0 / 3.0d0
268 
269  a_dirk_ij(1,1) = 0.25d0
270  a_dirk_ij(2,2) = 0.25d0
271  a_dirk_ij(3,1) = 1.0d0 / 3.0d0
272  a_dirk_ij(3,2) = 1.0d0 / 3.0d0
273  a_dirk_ij(3,3) = 1.0d0 / 3.0d0
274 
275  omega(1) = 1.0d0 / 3.0d0
276  omega(2) = 1.0d0 / 3.0d0
277  omega(3) = 1.0d0 / 3.0d0
278 
279 
280 
281  ELSEIF ( n_rk .EQ. 4 ) THEN
282 
283  ! LRR(3,2,2) from Table 3 in Pareschi & Russo (2000)
284 
285  a_tilde_ij(2,1) = 0.5d0
286  a_tilde_ij(3,1) = 1.d0 / 3.d0
287  a_tilde_ij(4,2) = 1.0d0
288 
289  omega_tilde(1) = 0.d0
290  omega_tilde(2) = 1.0d0
291  omega_tilde(3) = 0.0d0
292  omega_tilde(4) = 0.d0
293 
294  a_dirk_ij(2,2) = 0.5d0
295  a_dirk_ij(3,3) = 1.0d0 / 3.0d0
296  a_dirk_ij(4,3) = 0.75d0
297  a_dirk_ij(4,4) = 0.25d0
298 
299  omega(1) = 0.d0
300  omega(2) = 0.d0
301  omega(3) = 0.75d0
302  omega(4) = 0.25d0
303 
304  END IF
305 
306  ALLOCATE( a_tilde(n_rk) )
307  ALLOCATE( a_dirk(n_rk) )
308 
309  ALLOCATE( q_rk( n_vars , comp_cells_x , comp_cells_y , n_rk ) )
310  ALLOCATE( divflux( n_eqns , comp_cells_x , comp_cells_y , n_rk ) )
311  ALLOCATE( nh( n_eqns , comp_cells_x , comp_cells_y , n_rk ) )
312  ALLOCATE( si_nh( n_eqns , comp_cells_x , comp_cells_y , n_rk ) )
313 
314  ALLOCATE( expl_terms( n_eqns , comp_cells_x , comp_cells_y , n_rk ) )
315 
316  ALLOCATE( divfluxj(n_eqns,n_rk) )
317  ALLOCATE( nhj(n_eqns,n_rk) )
318  ALLOCATE( si_nhj(n_eqns,n_rk) )
319  ALLOCATE( expl_terms_j(n_eqns,n_rk) )
320 
321  ALLOCATE( residual_term( n_vars , comp_cells_x , comp_cells_y ) )
322 
323  END SUBROUTINE allocate_solver_variables
324 
325  !******************************************************************************
327  !
330  !
334  !
335  !******************************************************************************
336 
337  SUBROUTINE deallocate_solver_variables
339  DEALLOCATE( q , q0 )
340 
341  DEALLOCATE( q_fv )
342 
343  DEALLOCATE( q_interfacel )
344  DEALLOCATE( q_interfacer )
345  DEALLOCATE( q_interfaceb )
346  DEALLOCATE( q_interfacet )
347 
348  DEALLOCATE( a_interface_xneg )
349  DEALLOCATE( a_interface_xpos )
350  DEALLOCATE( a_interface_yneg )
351  DEALLOCATE( a_interface_ypos )
352 
353  DEALLOCATE( h_interface_x )
354  DEALLOCATE( h_interface_y )
355 
356  DEALLOCATE( solve_mask , solve_mask0 )
357 
358  Deallocate( qp )
359 
360  DEALLOCATE( source_xy )
361 
362  DEALLOCATE( a_tilde_ij )
363  DEALLOCATE( a_dirk_ij )
364  DEALLOCATE( omega_tilde )
365  DEALLOCATE( omega )
366 
367  DEALLOCATE( implicit_flag )
368 
369  DEALLOCATE( a_tilde )
370  DEALLOCATE( a_dirk )
371 
372  DEALLOCATE( q_rk )
373  DEALLOCATE( divflux )
374  DEALLOCATE( nh )
375  DEALLOCATE( si_nh )
376  DEALLOCATE( expl_terms )
377 
378  DEALLOCATE( divfluxj )
379  DEALLOCATE( nhj )
380  DEALLOCATE( si_nhj )
381  DEALLOCATE( expl_terms_j )
382 
383  DEALLOCATE( mask22 , mask21 , mask11 , mask12 )
384 
385  DEALLOCATE( residual_term )
386 
387  END SUBROUTINE deallocate_solver_variables
388 
389 
390  !******************************************************************************
392  !
396  !
400  !
401  !******************************************************************************
402 
403  SUBROUTINE check_solve
405  IMPLICIT NONE
406 
407  INTEGER :: i
408 
409  solve_mask0(1:comp_cells_x,1:comp_cells_y) = .false.
410 
412 
413  WHERE ( q(1,:,:) - b_cent(:,:) .GT. 0.d0 ) solve_mask = .true.
414 
415  DO i = 1,n_rk
416 
417  solve_mask(1+i:comp_cells_x,:) = solve_mask(1+i:comp_cells_x,:) .OR. &
418  solve_mask(1:comp_cells_x-i,:)
419 
420  solve_mask(1:comp_cells_x-i,:) = solve_mask(1:comp_cells_x-i,:) .OR. &
421  solve_mask(1+i:comp_cells_x,:)
422 
423  solve_mask(:,1+i:comp_cells_y) = solve_mask(:,1+i:comp_cells_y) .OR. &
424  solve_mask(:,1:comp_cells_y-i)
425 
426  solve_mask(:,1:comp_cells_y-i) = solve_mask(:,1:comp_cells_y-i) .OR. &
427  solve_mask(:,1+i:comp_cells_y)
428 
429  END DO
430 
431 
432  END SUBROUTINE check_solve
433 
434  !******************************************************************************
436  !
440  !
444  !
445  !******************************************************************************
446 
447  SUBROUTINE timestep
449  ! External variables
450  USE geometry_2d, ONLY : dx,dy
451  USE parameters_2d, ONLY : max_dt , cfl
452 
453  ! External procedures
455 
456  IMPLICIT none
457 
458  REAL*8 :: vel_max(n_vars)
459  REAL*8 :: vel_min(n_vars)
460  REAL*8 :: vel_j
461  REAL*8 :: dt_cfl
462  REAL*8 :: qj(n_vars)
463 
464  INTEGER :: j,k
465 
466  dt = max_dt
467 
468  IF ( cfl .NE. -1.d0 ) THEN
469 
470  DO j = 1,comp_cells_x
471 
472  DO k = 1,comp_cells_y
473 
474  qj = q( 1:n_vars , j , k )
475 
476  IF ( comp_cells_x .GT. 1 ) THEN
477 
478  ! x direction
479  CALL eval_local_speeds_x( qj , b_cent(j,k) , vel_min , vel_max )
480 
481  vel_j = max( maxval(abs(vel_min)) , maxval(abs(vel_max)) )
482 
483  dt_cfl = cfl * dx / vel_j
484 
485  dt = min( dt , dt_cfl )
486 
487  END IF
488 
489  IF ( comp_cells_y .GT. 1 ) THEN
490 
491  ! y direction
492  CALL eval_local_speeds_y( qj , b_cent(j,k) , vel_min , vel_max )
493 
494  vel_j = max( maxval(abs(vel_min)) , maxval(abs(vel_max)) )
495 
496  dt_cfl = cfl * dy / vel_j
497 
498  dt = min( dt , dt_cfl )
499 
500  END IF
501 
502  ENDDO
503 
504  END DO
505 
506  END IF
507 
508  END SUBROUTINE timestep
509 
510 
511  !*****************************************************************************
513  !
517  !
521  !
522  !*****************************************************************************
523 
524  SUBROUTINE timestep2
526  ! External variables
527  USE geometry_2d, ONLY : dx,dy
528  USE parameters_2d, ONLY : max_dt , cfl
529 
530  ! External procedures
532 
533  IMPLICIT none
534 
535  REAL*8 :: dt_cfl
536 
537  REAL*8 :: a_interface_x_max(n_eqns,comp_interfaces_x,comp_cells_y)
538  REAL*8 :: a_interface_y_max(n_eqns,comp_cells_x,comp_interfaces_y)
539  REAL*8 :: dt_interface_x, dt_interface_y
540 
541  INTEGER :: i,j,k
542 
543  dt = max_dt
544 
545  IF ( cfl .NE. -1.d0 ) THEN
546 
547  CALL reconstruction
548 
549  CALL eval_speeds
550 
551  DO i=1,n_vars
552 
553  a_interface_x_max(i,:,:) = &
554  max( a_interface_xpos(i,:,:) , -a_interface_xneg(i,:,:) )
555 
556  a_interface_y_max(i,:,:) = &
557  max( a_interface_ypos(i,:,:) , -a_interface_yneg(i,:,:) )
558 
559  END DO
560 
561  DO j = 1,comp_cells_x
562 
563  DO k = 1,comp_cells_y
564 
565  dt_interface_x = cfl * dx / max( maxval(a_interface_x_max(:,j,k)) &
566  , maxval(a_interface_x_max(:,j+1,k)) )
567 
568  dt_interface_y = cfl * dy / max( maxval(a_interface_y_max(:,j,k)) &
569  , maxval(a_interface_y_max(:,j,k+1)) )
570 
571  dt_cfl = min( dt_interface_x , dt_interface_y )
572 
573  dt = min(dt,dt_cfl)
574 
575  ENDDO
576 
577  END DO
578 
579  END IF
580 
581  END SUBROUTINE timestep2
582 
583  !******************************************************************************
585  !
590  !
594  !
595  !******************************************************************************
596 
597  SUBROUTINE imex_rk_solver
600 
602 
603  USE constitutive_2d, ONLY : qc_to_qp
604 
605  IMPLICIT NONE
606 
607  REAL*8 :: q_si(n_vars)
608  REAL*8 :: q_guess(n_vars)
609  INTEGER :: j,k
610 
611  REAL*8 :: h_new
612 
613  ! Initialization of the solution guess
614  q0( 1:n_vars , 1:comp_cells_x , 1:comp_cells_y ) = &
615  q( 1:n_vars , 1:comp_cells_x , 1:comp_cells_y )
616 
617  IF ( verbose_level .GE. 2 ) WRITE(*,*) 'solver, imex_RK_solver: beginning'
618 
619  ! Initialization of the variables for the Runge-Kutta scheme
620  q_rk(1:n_vars,1:comp_cells_x,1:comp_cells_y,1:n_rk) = 0.d0
621 
622  divflux(1:n_eqns,1:comp_cells_x,1:comp_cells_y,1:n_rk) = 0.d0
623 
624  nh(1:n_eqns,1:comp_cells_x,1:comp_cells_y,1:n_rk) = 0.d0
625 
626  si_nh(1:n_eqns,1:comp_cells_x,1:comp_cells_y,1:n_rk) = 0.d0
627 
628  expl_terms(1:n_eqns,1:comp_cells_x,1:comp_cells_y,1:n_rk) = 0.d0
629 
630  runge_kutta:DO i_rk = 1,n_rk
631 
632  IF ( verbose_level .GE. 2 ) WRITE(*,*) 'solver, imex_RK_solver: i_RK',i_rk
633 
634  ! define the explicits coefficients for the i-th step of the Runge-Kutta
635  a_tilde = 0.d0
636  a_dirk = 0.d0
637 
638  ! in the first step of the RK scheme all the coefficients remain to 0
639  a_tilde(1:i_rk-1) = a_tilde_ij(i_rk,1:i_rk-1)
640  a_dirk(1:i_rk-1) = a_dirk_ij(i_rk,1:i_rk-1)
641 
642  ! define the implicit coefficient for the i-th step of the Runge-Kutta
644 
645  CALL cpu_time(t_imex1)
646 
647  loop_over_ycells:DO k = 1,comp_cells_y
648 
649  loop_over_xcells:DO j = 1,comp_cells_x
650 
651  IF ( verbose_level .GE. 2 ) THEN
652 
653  WRITE(*,*) 'solver, imex_RK_solver: j',j,k
654 
655  END IF
656 
657  ! initialize the RK step
658  IF ( i_rk .EQ. 1 ) THEN
659 
660  ! solution from the previous time step
661  q_guess(1:n_vars) = q0( 1:n_vars , j , k)
662 
663  ELSE
664 
665  ! solution from the previous RK step
666  !q_guess(1:n_vars) = q_rk( 1:n_vars , j , k , MAX(1,i_RK-1) )
667 
668  END IF
669 
670  ! RK explicit hyperbolic terms for the volume (i,j)
671  divfluxj(1:n_eqns,1:n_rk) = divflux( 1:n_eqns , j , k , 1:n_rk )
672 
673  ! RK implicit terms for the volume (i,j)
674  nhj(1:n_eqns,1:n_rk) = nh( 1:n_eqns , j , k , 1:n_rk )
675 
676  ! RK semi-implicit terms for the volume (i,j)
677  si_nhj(1:n_eqns,1:n_rk) = si_nh( 1:n_eqns , j , k , 1:n_rk )
678 
679  ! RK additional explicit terms for the volume (i,j)
680  expl_terms_j(1:n_eqns,1:n_rk) = expl_terms( 1:n_eqns,j,k,1:n_rk )
681 
682  ! New solution at the i_RK step without the implicit and
683  ! semi-implicit term
684  q_fv( 1:n_vars , j , k ) = q0( 1:n_vars , j , k ) &
685  - dt * (matmul( divfluxj(1:n_eqns,1:i_rk) &
686  + expl_terms_j(1:n_eqns,1:i_rk) , a_tilde(1:i_rk) ) &
687  - matmul( nhj(1:n_eqns,1:i_rk) + si_nhj(1:n_eqns,1:i_rk) , &
688  a_dirk(1:i_rk) ) )
689 
690  IF ( verbose_level .GE. 2 ) THEN
691 
692  WRITE(*,*) 'q_guess',q_guess
693  CALL qc_to_qp( q_guess , b_cent(j,k) , qp(1:n_vars,j,k) )
694  WRITE(*,*) 'q_guess: qp',qp(1:n_vars,j,k)
695 
696  END IF
697 
698  adiag_pos:IF ( a_diag .NE. 0.d0 ) THEN
699 
700  pos_thick:IF ( q_fv(1,j,k) .GT. b_cent(j,k) ) THEN
701 
702  ! Eval the semi-implicit discontinuous terms
703  CALL eval_nh_semi_impl_terms( b_cent(j,k) , grav_surf(j,k) , &
704  r_qj = q_fv( 1:n_vars , j , k ) , &
705  r_nh_semi_impl_term = si_nh(1:n_eqns,j,k,i_rk) )
706 
707  si_nhj(1:n_eqns,i_rk) = si_nh( 1:n_eqns,j,k,i_rk )
708 
709  ! Assemble the initial guess for the implicit solver
710  q_si(1:n_vars) = q_fv(1:n_vars,j,k ) + dt * a_diag * &
711  si_nh(1:n_eqns,j,k,i_rk)
712 
713  IF ( q_fv(2,j,k)**2 + q_fv(3,j,k)**2 .EQ. 0.d0 ) THEN
714 
715  !Case 1: if the velocity was null, then it must stay null
716  q_si(2:3) = 0.d0
717 
718  ELSEIF ( ( q_si(2)*q_fv(2,j,k) .LT. 0.d0 ) .OR. &
719  ( q_si(3)*q_fv(3,j,k) .LT. 0.d0 ) ) THEN
720 
721  ! If the semi-impl. friction term changed the sign of the
722  ! velocity then set it to zero
723  q_si(2:3) = 0.d0
724 
725  ELSE
726 
727  ! Align the velocity vector with previous one
728  q_si(2:3) = dsqrt( q_si(2)**2 + q_si(3)**2 ) * &
729  q_fv(2:3,j,k) / dsqrt( q_fv(2,j,k)**2 &
730  + q_fv(3,j,k)**2 )
731 
732  END IF
733 
734  ! Update the semi-implicit term accordingly with the
735  ! corrections above
736  si_nh(1:n_eqns,j,k,i_rk) = ( q_si(1:n_vars) - &
737  q_fv(1:n_vars,j,k ) ) / ( dt*a_diag )
738 
739  si_nhj(1:n_eqns,i_rk) = si_nh( 1:n_eqns,j,k,i_rk )
740 
741  ! Initialize the guess for the NR solver
742  q_guess(1:n_vars) = q_si(1:n_vars)
743 
744  ! Solve the implicit system to find the solution at the
745  ! i_RK step of the IMEX RK procedure
746  CALL solve_rk_step( b_cent(j,k) , b_prime_x(j,k) , &
747  b_prime_y(j,k), grav_surf(j,k) , &
748  q_guess(1:n_vars) , q0(1:n_vars,j,k ) , a_tilde , &
749  a_dirk , a_diag )
750 
751  IF ( comp_cells_y .EQ. 1 ) THEN
752 
753  q_guess(3) = 0.d0
754 
755  END IF
756 
757  IF ( comp_cells_x .EQ. 1 ) THEN
758 
759  q_guess(2) = 0.d0
760 
761  END IF
762 
763  ! Eval and store the implicit term at the i_RK step
764  CALL eval_nonhyperbolic_terms( b_cent(j,k) , b_prime_x(j,k) ,&
765  b_prime_y(j,k) , grav_surf(j,k) , r_qj = q_guess , &
766  r_nh_term_impl = nh(1:n_eqns,j,k,i_rk) )
767 
768  IF ( q_si(2)**2 + q_si(3)**2 .EQ. 0.d0 ) THEN
769 
770  q_guess(2:3) = 0.d0
771 
772  ELSEIF ( ( q_guess(2)*q_si(2) .LE. 0.d0 ) .AND. &
773  ( q_guess(3)*q_si(3) .LE. 0.d0 ) ) THEN
774 
775  ! If the impl. friction term changed the sign of the
776  ! velocity then set it to zero
777  q_guess(2:3) = 0.d0
778 
779  ELSE
780 
781  ! Align the velocity vector with previous one
782  q_guess(2:3) = dsqrt( q_guess(2)**2 + q_guess(3)**2 ) * &
783  q_si(2:3) / dsqrt( q_si(2)**2 + q_si(3)**2 )
784 
785  END IF
786 
787  ELSE
788 
789  ! If h=0 nothing has to be changed
790  q_guess(1:n_vars) = q_fv( 1:n_vars , j , k )
791  q_si(1:n_vars) = q_fv( 1:n_vars , j , k )
792  si_nh(1:n_eqns,j,k,i_rk) = 0.d0
793  nh(1:n_eqns,j,k,i_rk) = 0.d0
794 
795  END IF pos_thick
796 
797  END IF adiag_pos
798 
799  ! Check the sign of the flow thickness
800  h_new = q_guess(1) - b_cent(j,k)
801 
802  IF ( j .EQ. 0 ) THEN
803 
804  WRITE(*,*) 'h',q_guess(1) - b_cent(j,k)
805  READ(*,*)
806 
807  END IF
808 
809  ! IF ( h_new .LT. 1.D-10 ) THEN
810  !
811  ! q_guess(1) = B_cent(j,k)
812  ! q_guess(2:n_vars) = 0.D0
813  !
814  ! END IF
815 
816  IF ( a_diag .NE. 0.d0 ) THEN
817 
818  ! Update the viscous term with the correction on the new velocity
819  nh(1:n_vars,j,k,i_rk) = ( q_guess(1:n_vars) - q_si(1:n_vars)) &
820  / ( dt*a_diag )
821 
822  END IF
823 
824  ! Store the solution at the end of the i_RK step
825  q_rk( 1:n_vars , j , k , i_rk ) = q_guess
826 
827  IF ( verbose_level .GE. 2 ) THEN
828 
829  WRITE(*,*) 'imex_RK_solver: qc',q_guess
830  CALL qc_to_qp( q_guess, b_cent(j,k) , qp(1:n_vars,j,k) )
831  WRITE(*,*) 'imex_RK_solver: qp',qp(1:n_vars,j,k)
832  READ(*,*)
833 
834  END IF
835 
836  END DO loop_over_xcells
837 
838  ENDDO loop_over_ycells
839 
840  CALL cpu_time(t_imex2)
841  ! WRITE(*,*) 'Time taken by implicit',t_imex2-t_imex1,'seconds'
842 
843 
844  ! Eval and store the explicit hyperbolic (fluxes) terms
845  CALL eval_hyperbolic_terms( q_rk(1:n_vars,1:comp_cells_x,1:comp_cells_y, &
846  i_rk) , divflux(1:n_eqns,1:comp_cells_x,1:comp_cells_y,i_rk) )
847 
848  CALL cpu_time(t_imex1)
849  ! WRITE(*,*) 'Time taken by explicit',t_imex1-t_imex2,'seconds'
850 
851  ! Eval and store the other explicit terms (e.g. gravity or viscous forces)
852  CALL eval_explicit_terms( q_rk(1:n_vars,1:comp_cells_x,1:comp_cells_y, &
853  i_rk) , expl_terms(1:n_eqns,1:comp_cells_x,1:comp_cells_y,i_rk) )
854 
855 
856  CALL cpu_time(t_imex1)
857  ! WRITE(*,*) 'Time taken by explicit',t_imex1-t_imex2,'seconds'
858 
859  IF ( verbose_level .GE. 1 ) THEN
860 
861  WRITE(*,*) 'div_flux(2),div_flux(3),expl_terms(2),expl_terms(3)'
862 
863  DO k = 1,comp_cells_y
864 
865  DO j = 1,comp_cells_x
866 
867  WRITE(*,*) divflux(2,j,k,i_rk) , divflux(3,j,k,i_rk) , &
868  expl_terms(2,j,k,i_rk) , expl_terms(3,j,k,i_rk)
869 
870  ENDDO
871 
872  END DO
873 
874  READ(*,*)
875 
876  END IF
877 
878  END DO runge_kutta
879 
880  DO k = 1,comp_cells_y
881 
882  DO j = 1,comp_cells_x
883 
884  residual_term(1:n_vars,j,k) = matmul( divflux(1:n_eqns,j,k,1:n_rk) &
885  + expl_terms(1:n_eqns,j,k,1:n_rk) , omega_tilde ) - &
886  matmul( nh(1:n_eqns,j,k,1:n_rk) + si_nh(1:n_eqns,j,k,1:n_rk) ,&
887  omega )
888 
889  ENDDO
890 
891  END DO
892 
893  DO k = 1,comp_cells_y
894 
895  DO j = 1,comp_cells_x
896 
897  IF ( verbose_level .GE. 1 ) THEN
898 
899  WRITE(*,*) 'cell jk =',j,k
900  WRITE(*,*) 'before imex_RK_solver: qc',q0(1:n_vars,j,k)
901  CALL qc_to_qp(q0(1:n_vars,j,k) , b_cent(j,k) , qp(1:n_vars,j,k))
902  WRITE(*,*) 'before imex_RK_solver: qp',qp(1:n_vars,j,k)
903 
904  END IF
905 
906  IF ( ( sum(abs( omega_tilde(:)-a_tilde_ij(n_rk,:))) .EQ. 0.d0 ) &
907  .AND. ( sum(abs(omega(:)-a_dirk_ij(n_rk,:))) .EQ. 0.d0 ) ) THEN
908 
909  ! The assembling coeffs are equal to the last step of the RK scheme
910  q(1:n_vars,j,k) = q_rk(1:n_vars,j,k,n_rk)
911 
912  ELSE
913 
914  ! The assembling coeffs are different
915  q(1:n_vars,j,k) = q0(1:n_vars,j,k) - dt*residual_term(1:n_vars,j,k)
916 
917  END IF
918 
919 
920  IF ( q(1,j,k) .LT. b_cent(j,k) ) THEN
921 
922  IF ( dabs( q(1,j,k)-b_cent(j,k) ) .LT. 1.d-10 ) THEN
923 
924  q(1,j,k) = b_cent(j,k)
925  q(2:n_vars,j,k) = 0.d0
926 
927  ELSE
928 
929  WRITE(*,*) 'j,k,n_RK',j,k,n_rk
930  WRITE(*,*) 'dt',dt
931 
932  WRITE(*,*) 'before imex_RK_solver: qc',q0(1:n_vars,j,k)
933  CALL qc_to_qp(q0(1:n_vars,j,k) , b_cent(j,k) , qp(1:n_vars,j,k))
934  WRITE(*,*) 'before imex_RK_solver: qp',qp(1:n_vars,j,k)
935  WRITE(*,*) 'h old',q0(1,j,k) - b_cent(j,k)
936 
937  READ(*,*)
938 
939  END IF
940 
941  END IF
942 
943  IF ( verbose_level .GE. 1 ) THEN
944 
945  CALL qc_to_qp(q(1:n_vars,j,k) , b_cent(j,k) , qp(1:n_vars,j,k))
946 
947  WRITE(*,*) 'after imex_RK_solver: qc',q(1:n_vars,j,k)
948  WRITE(*,*) 'after imex_RK_solver: qp',qp(1:n_vars,j,k)
949  WRITE(*,*) 'h new',q(1,j,k) - b_cent(j,k)
950  READ(*,*)
951 
952  END IF
953 
954 
955  ENDDO
956 
957  END DO
958 
959  END SUBROUTINE imex_rk_solver
960 
961  !******************************************************************************
963  !
970  !
978  !
982  !
983  !******************************************************************************
984 
985  SUBROUTINE solve_rk_step( Bj, Bprimej_x, Bprimej_y, grav3_surf, &
986  qj, qj_old, a_tilde , a_dirk , a_diag )
988  USE parameters_2d, ONLY : max_nl_iter , tol_rel , tol_abs
989 
990  USE constitutive_2d, ONLY : qc_to_qp
991 
992  IMPLICIT NONE
993 
994  REAL*8, INTENT(IN) :: Bj
995  REAL*8, INTENT(IN) :: Bprimej_x
996  REAL*8, INTENT(IN) :: Bprimej_y
997  REAL*8, INTENT(IN) :: grav3_surf
998  REAL*8, INTENT(INOUT) :: qj(n_vars)
999  REAL*8, INTENT(IN) :: qj_old(n_vars)
1000  REAL*8, INTENT(IN) :: a_tilde(n_rk)
1001  REAL*8, INTENT(IN) :: a_dirk(n_rk)
1002  REAL*8, INTENT(IN) :: a_diag
1003 
1004  REAL*8 :: qj_init(n_vars)
1005 
1006  REAL*8 :: qj_org(n_vars) , qj_rel(n_vars)
1007 
1008  REAL*8 :: left_matrix(n_eqns,n_vars)
1009  REAL*8 :: right_term(n_eqns)
1010 
1011  REAL*8 :: scal_f
1012 
1013  REAL*8 :: coeff_f(n_eqns)
1014 
1015  REAL*8 :: qj_rel_NR_old(n_vars)
1016  REAL*8 :: scal_f_old
1017  REAL*8 :: desc_dir(n_vars)
1018  REAL*8 :: grad_f(n_vars)
1019  REAL*8 :: mod_desc_dir
1020 
1021  INTEGER :: pivot(n_vars)
1022 
1023  REAL*8 :: left_matrix_small22(n_nh,n_nh)
1024  REAL*8 :: left_matrix_small21(n_eqns-n_nh,n_nh)
1025  REAL*8 :: left_matrix_small11(n_eqns-n_nh,n_vars-n_nh)
1026  REAL*8 :: left_matrix_small12(n_nh,n_vars-n_nh)
1027 
1028  REAL*8 :: desc_dir_small2(n_nh)
1029  INTEGER :: pivot_small2(n_nh)
1030 
1031  REAL*8 :: desc_dir_small1(n_vars-n_nh)
1032 
1033  INTEGER :: ok
1034 
1035  INTEGER :: i
1036  INTEGER :: nl_iter
1037 
1038  REAL*8, PARAMETER :: STPMX=100.d0
1039  REAL*8 :: stpmax
1040  LOGICAL :: check
1041 
1042  REAL*8, PARAMETER :: TOLF=1.d-10 , tolmin=1.d-6
1043  REAL*8 :: TOLX
1044 
1045  REAL*8 :: qpj(n_vars)
1046 
1047  REAL*8 :: desc_dir2(n_vars)
1048 
1049  REAL*8 :: desc_dir_temp(n_vars)
1050 
1051  normalize_q = .true.
1052  normalize_f = .false.
1053  opt_search_nl = .true.
1054 
1055  coeff_f(1:n_eqns) = 1.d0
1056 
1057  qj_init = qj
1058 
1059  ! normalize the functions of the nonlinear system
1060  IF ( normalize_f ) THEN
1061 
1062  qj = qj_old - dt * ( matmul(divfluxj+ expl_terms_j,a_tilde) &
1063  - matmul(nhj,a_dirk) )
1064 
1065  CALL eval_f( bj , bprimej_x , bprimej_y , grav3_surf , &
1066  qj , qj_old , a_tilde , a_dirk , a_diag , coeff_f , right_term , &
1067  scal_f )
1068 
1069  IF ( verbose_level .GE. 3 ) THEN
1070 
1071  WRITE(*,*) 'solve_rk_step: non-normalized right_term'
1072  WRITE(*,*) right_term
1073  WRITE(*,*) 'scal_f',scal_f
1074 
1075  END IF
1076 
1077  DO i=1,n_eqns
1078 
1079  IF ( abs(right_term(i)) .GE. 1.d0 ) coeff_f(i) = 1.d0 / right_term(i)
1080 
1081  END DO
1082 
1083  right_term = coeff_f * right_term
1084 
1085  scal_f = 0.5d0 * dot_product( right_term , right_term )
1086 
1087  IF ( verbose_level .GE. 3 ) THEN
1088  WRITE(*,*) 'solve_rk_step: after normalization',scal_f
1089  END IF
1090 
1091  END IF
1092 
1093  !---- normalize the conservative variables ------
1094 
1095  IF ( normalize_q ) THEN
1096 
1097  qj_org = qj
1098 
1099  qj_org = max( abs(qj_org) , 1.d-3 )
1100 
1101  ELSE
1102 
1103  qj_org(1:n_vars) = 1.d0
1104 
1105  END IF
1106 
1107  qj_rel = qj / qj_org
1108 
1109  ! -----------------------------------------------
1110 
1111  newton_raphson_loop:DO nl_iter=1,max_nl_iter
1112 
1113  tolx = epsilon(qj_rel)
1114 
1115  IF ( verbose_level .GE. 2 ) WRITE(*,*) 'solve_rk_step: nl_iter',nl_iter
1116 
1117  CALL eval_f( bj , bprimej_x , bprimej_y , grav3_surf , &
1118  qj , qj_old , a_tilde , a_dirk , a_diag , coeff_f , right_term , &
1119  scal_f )
1120 
1121  IF ( verbose_level .GE. 2 ) THEN
1122 
1123  WRITE(*,*) 'solve_rk_step: right_term',right_term
1124 
1125  END IF
1126 
1127  IF ( verbose_level .GE. 2 ) THEN
1128 
1129  WRITE(*,*) 'before_lnsrch: scal_f',scal_f
1130 
1131  END IF
1132 
1133  ! check the residual of the system
1134 
1135  IF ( maxval( abs( right_term(:) ) ) < tolf ) THEN
1136 
1137  IF ( verbose_level .GE. 3 ) WRITE(*,*) '1: check',check
1138  RETURN
1139 
1140  END IF
1141 
1142  IF ( ( normalize_f ) .AND. ( scal_f < 1.d-6 ) ) THEN
1143 
1144  IF ( verbose_level .GE. 3 ) WRITE(*,*) 'check scal_f',check
1145  RETURN
1146 
1147  END IF
1148 
1149  ! ---- evaluate the descent direction ------------------------------------
1150 
1151  IF ( count( implicit_flag ) .EQ. n_eqns ) THEN
1152 
1153  CALL eval_jacobian(bj,bprimej_x,bprimej_y,grav3_surf, &
1154  qj_rel,qj_org,coeff_f,left_matrix)
1155 
1156  desc_dir_temp = - right_term
1157 
1158  CALL dgesv(n_eqns,1, left_matrix , n_eqns, pivot, desc_dir_temp , &
1159  n_eqns, ok)
1160 
1161  desc_dir = desc_dir_temp
1162 
1163  ELSE
1164 
1165  CALL eval_jacobian(bj,bprimej_x,bprimej_y,grav3_surf, &
1166  qj_rel,qj_org,coeff_f,left_matrix)
1167 
1168  left_matrix_small11 = reshape(pack(left_matrix, mask11), &
1169  [n_eqns-n_nh,n_eqns-n_nh])
1170 
1171  left_matrix_small12 = reshape(pack(left_matrix, mask12), &
1172  [n_nh,n_eqns-n_nh])
1173 
1174  left_matrix_small22 = reshape(pack(left_matrix, mask22), &
1175  [n_nh,n_nh])
1176 
1177  left_matrix_small21 = reshape(pack(left_matrix, mask21), &
1178  [n_eqns-n_nh,n_nh])
1179 
1180 
1181  desc_dir_small1 = pack( right_term, .NOT.implicit_flag )
1182  desc_dir_small2 = pack( right_term , implicit_flag )
1183 
1184  DO i=1,n_vars-n_nh
1185 
1186  desc_dir_small1(i) = desc_dir_small1(i) / left_matrix_small11(i,i)
1187 
1188  END DO
1189 
1190  desc_dir_small2 = desc_dir_small2 - &
1191  matmul( desc_dir_small1 , left_matrix_small21 )
1192 
1193  CALL dgesv(n_nh,1, left_matrix_small22 , n_nh , pivot_small2 , &
1194  desc_dir_small2 , n_nh, ok)
1195 
1196  desc_dir = unpack( - desc_dir_small2 , implicit_flag , 0.0d0 ) &
1197  + unpack( - desc_dir_small1 , .NOT.implicit_flag , 0.0d0 )
1198 
1199  END IF
1200 
1201  mod_desc_dir = dsqrt( desc_dir(2)**2 + desc_dir(3)**2 )
1202 
1203  !IF ( qj(2)**2 + qj(3)**2 .GT. 0.D0 ) THEN
1204  !
1205  ! desc_dir(2) = mod_desc_dir * qj(2) / ( qj(2)**2 + qj(3)**2 )
1206  ! desc_dir(3) = mod_desc_dir * qj(3) / ( qj(2)**2 + qj(3)**2 )
1207  !
1208  !END IF
1209 
1210  IF ( verbose_level .GE. 3 ) WRITE(*,*) 'desc_dir',desc_dir
1211 
1212  qj_rel_nr_old = qj_rel
1213  scal_f_old = scal_f
1214 
1215  IF ( ( opt_search_nl ) .AND. ( nl_iter .GT. 1 ) ) THEN
1216  ! Search for the step lambda giving a suffic. decrease in the solution
1217 
1218  stpmax = stpmx * max( sqrt( dot_product(qj_rel,qj_rel) ) , &
1219  dble( SIZE(qj_rel) ) )
1220 
1221  grad_f = matmul( right_term , left_matrix )
1222 
1223  desc_dir2 = desc_dir
1224 
1225  CALL lnsrch( bj , bprimej_x , bprimej_y , grav3_surf , &
1226  qj_rel_nr_old , qj_org , qj_old , scal_f_old , grad_f , &
1227  desc_dir , coeff_f , qj_rel , scal_f , right_term , stpmax , &
1228  check )
1229 
1230  ELSE
1231 
1232  qj_rel = qj_rel_nr_old + desc_dir
1233 
1234  qj = qj_rel * qj_org
1235 
1236  CALL eval_f( bj , bprimej_x , bprimej_y , grav3_surf , &
1237  qj , qj_old , a_tilde , a_dirk , a_diag , coeff_f , &
1238  right_term , scal_f )
1239 
1240  END IF
1241 
1242  IF ( verbose_level .GE. 2 ) WRITE(*,*) 'after_lnsrch: scal_f',scal_f
1243 
1244  qj = qj_rel * qj_org
1245 
1246  IF ( verbose_level .GE. 3 ) THEN
1247 
1248  WRITE(*,*) 'qj',qj
1249  CALL qc_to_qp( qj , bj , qpj)
1250  WRITE(*,*) 'qp',qpj
1251 
1252  END IF
1253 
1254 
1255  IF ( maxval( abs( right_term(:) ) ) < tolf ) THEN
1256 
1257  IF ( verbose_level .GE. 3 ) WRITE(*,*) '1: check',check
1258  check= .false.
1259  RETURN
1260 
1261  END IF
1262 
1263  IF (check) THEN
1264 
1265  check = ( maxval( abs(grad_f(:)) * max( abs( qj_rel(:) ),1.d0 ) / &
1266  max( scal_f , 0.5d0 * SIZE(qj_rel) ) ) < tolmin )
1267 
1268  IF ( verbose_level .GE. 3 ) WRITE(*,*) '2: check',check
1269  ! RETURN
1270 
1271  END IF
1272 
1273  IF ( maxval( abs( qj_rel(:) - qj_rel_nr_old(:) ) / max( abs( qj_rel(:)) ,&
1274  1.d0 ) ) < tolx ) THEN
1275 
1276  IF ( verbose_level .GE. 3 ) WRITE(*,*) 'check',check
1277  RETURN
1278 
1279  END IF
1280 
1281  END DO newton_raphson_loop
1282 
1283  END SUBROUTINE solve_rk_step
1284 
1285  !******************************************************************************
1287  !
1308  !******************************************************************************
1309 
1310  SUBROUTINE lnsrch( Bj , Bprimej_x , Bprimej_y , grav3_surf , &
1311  qj_rel_nr_old , qj_org , qj_old , scal_f_old , grad_f , &
1312  desc_dir , coeff_f , qj_rel , scal_f , right_term , stpmax , check )
1314  IMPLICIT NONE
1315 
1316  REAL*8, INTENT(IN) :: Bj
1317 
1318  REAL*8, INTENT(IN) :: Bprimej_x
1319 
1320  REAL*8, INTENT(IN) :: Bprimej_y
1321 
1322  REAL*8, INTENT(IN) :: grav3_surf
1323 
1325  REAL*8, DIMENSION(:), INTENT(IN) :: qj_rel_NR_old
1326 
1328  REAL*8, DIMENSION(:), INTENT(IN) :: qj_org
1329 
1331  REAL*8, DIMENSION(:), INTENT(IN) :: qj_old
1332 
1334  REAL*8, DIMENSION(:), INTENT(IN) :: grad_f
1335 
1337  REAL*8, INTENT(IN) :: scal_f_old
1338 
1340  REAL*8, DIMENSION(:), INTENT(INOUT) :: desc_dir
1341 
1342  REAL*8, INTENT(IN) :: stpmax
1343 
1345  REAL*8, DIMENSION(:), INTENT(IN) :: coeff_f
1346 
1348  REAL*8, DIMENSION(:), INTENT(OUT) :: qj_rel
1349 
1351  REAL*8, INTENT(OUT) :: scal_f
1352 
1354  REAL*8, INTENT(OUT) :: right_term(n_eqns)
1355 
1357  LOGICAL, INTENT(OUT) :: check
1358 
1359  REAL*8, PARAMETER :: TOLX=epsilon(qj_rel)
1360 
1361  INTEGER, DIMENSION(1) :: ndum
1362  REAL*8 :: ALF , a,alam,alam2,alamin,b,disc
1363  REAL*8 :: scal_f2
1364  REAL*8 :: desc_dir_abs
1365  REAL*8 :: rhs1 , rhs2 , slope, tmplam
1366 
1367  REAL*8 :: scal_f_min , alam_min
1368 
1369  REAL*8 :: qj(n_vars)
1370 
1371  alf = 1.0d-4
1372 
1373  IF ( size(grad_f) == size(desc_dir) .AND. size(grad_f) == size(qj_rel) &
1374  .AND. size(qj_rel) == size(qj_rel_nr_old) ) THEN
1375 
1376  ndum = size(grad_f)
1377 
1378  ELSE
1379 
1380  WRITE(*,*) 'nrerror: an assert_eq failed with this tag:', 'lnsrch'
1381  stop 'program terminated by assert_eq4'
1382 
1383  END IF
1384 
1385  check = .false.
1386 
1387  desc_dir_abs = sqrt( dot_product(desc_dir,desc_dir) )
1388 
1389  IF ( desc_dir_abs > stpmax ) desc_dir(:) = desc_dir(:) * stpmax/desc_dir_abs
1390 
1391  slope = dot_product(grad_f,desc_dir)
1392 
1393  alamin = tolx / maxval( abs( desc_dir(:))/max( abs(qj_rel_nr_old(:)),1.d0 ) )
1394 
1395  IF ( alamin .EQ. 0.d0) THEN
1396 
1397  qj_rel(:) = qj_rel_nr_old(:)
1398 
1399  RETURN
1400 
1401  END IF
1402 
1403  alam = 1.0d0
1404 
1405  scal_f_min = scal_f_old
1406 
1407  optimal_step_search: DO
1408 
1409  IF ( verbose_level .GE. 4 ) THEN
1410 
1411  WRITE(*,*) 'alam',alam
1412 
1413  END IF
1414 
1415  qj_rel = qj_rel_nr_old + alam * desc_dir
1416 
1417  qj = qj_rel * qj_org
1418 
1419  CALL eval_f( bj , bprimej_x , bprimej_y , grav3_surf , qj , qj_old , &
1420  a_tilde , a_dirk , a_diag , coeff_f , right_term , scal_f )
1421 
1422  IF ( verbose_level .GE. 4 ) THEN
1423 
1424  WRITE(*,*) 'lnsrch: effe_old,effe',scal_f_old,scal_f
1425  READ(*,*)
1426 
1427  END IF
1428 
1429  IF ( scal_f .LT. scal_f_min ) THEN
1430 
1431  scal_f_min = scal_f
1432  alam_min = alam
1433 
1434  END IF
1435 
1436  IF ( scal_f .LE. 0.9 * scal_f_old ) THEN
1437  ! sufficient function decrease
1438 
1439  IF ( verbose_level .GE. 4 ) THEN
1440 
1441  WRITE(*,*) 'sufficient function decrease'
1442 
1443  END IF
1444 
1445  EXIT optimal_step_search
1446 
1447  ELSE IF ( alam < alamin ) THEN
1448  ! convergence on Delta_x
1449 
1450  IF ( verbose_level .GE. 4 ) THEN
1451 
1452  WRITE(*,*) ' convergence on Delta_x',alam,alamin
1453 
1454  END IF
1455 
1456  qj_rel(:) = qj_rel_nr_old(:)
1457  scal_f = scal_f_old
1458  check = .true.
1459 
1460  EXIT optimal_step_search
1461 
1462  ! ELSE IF ( scal_f .LE. scal_f_old + ALF * alam * slope ) THEN
1463  ELSE
1464 
1465  IF ( alam .EQ. 1.d0 ) THEN
1466 
1467  tmplam = - slope / ( 2.0d0 * ( scal_f - scal_f_old - slope ) )
1468 
1469  ELSE
1470 
1471  rhs1 = scal_f - scal_f_old - alam*slope
1472  rhs2 = scal_f2 - scal_f_old - alam2*slope
1473 
1474  a = ( rhs1/alam**2.d0 - rhs2/alam2**2.d0 ) / ( alam - alam2 )
1475  b = ( -alam2*rhs1/alam**2 + alam*rhs2/alam2**2 ) / ( alam - alam2 )
1476 
1477  IF ( a .EQ. 0.d0 ) THEN
1478 
1479  tmplam = - slope / ( 2.0d0 * b )
1480 
1481  ELSE
1482 
1483  disc = b*b - 3.0d0*a*slope
1484 
1485  IF ( disc .LT. 0.d0 ) THEN
1486 
1487  tmplam = 0.5d0 * alam
1488 
1489  ELSE IF ( b .LE. 0.d0 ) THEN
1490 
1491  tmplam = ( - b + sqrt(disc) ) / ( 3.d0 * a )
1492 
1493  ELSE
1494 
1495  tmplam = - slope / ( b + sqrt(disc) )
1496 
1497  ENDIF
1498 
1499  END IF
1500 
1501  IF ( tmplam .GT. 0.5d0*alam ) tmplam = 0.5d0 * alam
1502 
1503  END IF
1504 
1505  END IF
1506 
1507  alam2 = alam
1508  scal_f2 = scal_f
1509  alam = max( tmplam , 0.5d0*alam )
1510 
1511  END DO optimal_step_search
1512 
1513  END SUBROUTINE lnsrch
1514 
1515  !******************************************************************************
1517  !
1533  !******************************************************************************
1534 
1535  SUBROUTINE eval_f( Bj , Bprimej_x , Bprimej_y , grav3_surf , qj , qj_old , &
1536  a_tilde , a_dirk , a_diag , coeff_f , f_nl , scal_f )
1539 
1540  IMPLICIT NONE
1541 
1542  REAL*8, INTENT(IN) :: Bj
1543  REAL*8, INTENT(IN) :: Bprimej_x
1544  REAL*8, INTENT(IN) :: Bprimej_y
1545  REAL*8, INTENT(IN) :: grav3_surf
1546  REAL*8, INTENT(IN) :: qj(n_vars)
1547  REAL*8, INTENT(IN) :: qj_old(n_vars)
1548  REAL*8, INTENT(IN) :: a_tilde(n_rk)
1549  REAL*8, INTENT(IN) :: a_dirk(n_rk)
1550  REAL*8, INTENT(IN) :: a_diag
1551  REAL*8, INTENT(IN) :: coeff_f(n_eqns)
1552  REAL*8, INTENT(OUT) :: f_nl(n_eqns)
1553  REAL*8, INTENT(OUT) :: scal_f
1554 
1555  REAL*8 :: nh_term_impl(n_eqns)
1556  REAL*8 :: Rj(n_eqns)
1557 
1558  CALL eval_nonhyperbolic_terms( bj , bprimej_x , bprimej_y , grav3_surf , &
1559  r_qj = qj , r_nh_term_impl = nh_term_impl )
1560 
1561  rj = ( matmul( divfluxj(1:n_eqns,1:i_rk-1)+expl_terms_j(1:n_eqns,1:i_rk-1), &
1562  a_tilde(1:i_rk-1) ) - matmul( nhj(1:n_eqns,1:i_rk-1) &
1563  + si_nhj(1:n_eqns,1:i_rk-1) , a_dirk(1:i_rk-1) ) ) &
1564  - a_diag * ( nh_term_impl + si_nhj(1:n_eqns,i_rk) )
1565 
1566  f_nl = qj - qj_old + dt * rj
1567 
1568  f_nl = coeff_f * f_nl
1569 
1570  scal_f = 0.5d0 * dot_product( f_nl , f_nl )
1571 
1572  !WRITE(*,*) 'i_RK',i_RK
1573  !WRITE(*,*) 'eval_f: qj(2) = ',qj(2)
1574  !WRITE(*,*) 'nh_term_impl(2) = ',nh_term_impl(2)
1575  !WRITE(*,*) ' SI_NHj(1:n_eqns,i_RK) = ', SI_NHj(1:n_eqns,i_RK)
1576  !WRITE(*,*) 'eval_f: new term = ',qj(2) + dt * ( - a_diag * nh_term_impl(2) )
1577  !WRITE(*,*) 'f_nl(2)=',f_nl(2)
1578  !READ(*,*)
1579 
1580  END SUBROUTINE eval_f
1581 
1582  !******************************************************************************
1584  !
1587  !
1596  !
1600  !******************************************************************************
1601 
1602  SUBROUTINE eval_jacobian(Bj , Bprimej_x , Bprimej_y , grav3_surf , &
1603  qj_rel , qj_org , coeff_f, left_matrix)
1606 
1607  IMPLICIT NONE
1608 
1609  REAL*8, INTENT(IN) :: Bj
1610  REAL*8, INTENT(IN) :: Bprimej_x
1611  REAL*8, INTENT(IN) :: Bprimej_y
1612  REAL*8, INTENT(IN) :: grav3_surf
1613  REAL*8, INTENT(IN) :: qj_rel(n_vars)
1614  REAL*8, INTENT(IN) :: qj_org(n_vars)
1615  REAL*8, INTENT(IN) :: coeff_f(n_eqns)
1616  REAL*8, INTENT(OUT) :: left_matrix(n_eqns,n_vars)
1617 
1618  REAL*8 :: Jacob_relax(n_eqns,n_vars)
1619  COMPLEX*16 :: nh_terms_cmplx_impl(n_eqns)
1620  COMPLEX*16 :: qj_cmplx(n_vars) , qj_rel_cmplx(n_vars)
1621 
1622  REAL*8 :: h
1623 
1624  INTEGER :: i
1625 
1626  h = n_vars * epsilon(1.d0)
1627 
1628  ! initialize the matrix of the linearized system and the Jacobian
1629 
1630  left_matrix(1:n_eqns,1:n_vars) = 0.d0
1631  jacob_relax(1:n_eqns,1:n_vars) = 0.d0
1632 
1633  ! evaluate the jacobian of the non-hyperbolic terms
1634 
1635  DO i=1,n_vars
1636 
1637  left_matrix(i,i) = coeff_f(i) * qj_org(i)
1638 
1639  IF ( implicit_flag(i) ) THEN
1640 
1641  qj_rel_cmplx(1:n_vars) = qj_rel(1:n_vars)
1642  qj_rel_cmplx(i) = dcmplx(qj_rel(i), h)
1643 
1644  qj_cmplx = qj_rel_cmplx * qj_org
1645 
1646  CALL eval_nonhyperbolic_terms( bj , bprimej_x , bprimej_y , &
1647  grav3_surf, c_qj = qj_cmplx , &
1648  c_nh_term_impl = nh_terms_cmplx_impl )
1649 
1650  jacob_relax(1:n_eqns,i) = coeff_f(i) * &
1651  aimag(nh_terms_cmplx_impl) / h
1652 
1653  left_matrix(1:n_eqns,i) = left_matrix(1:n_eqns,i) - dt * a_diag &
1654  * jacob_relax(1:n_eqns,i)
1655 
1656  END IF
1657 
1658  END DO
1659 
1660  END SUBROUTINE eval_jacobian
1661 
1662  !******************************************************************************
1664  !
1667  !
1670  !
1674  !******************************************************************************
1675 
1676  SUBROUTINE eval_explicit_terms( q_expl , expl_terms )
1678  USE constitutive_2d, ONLY : eval_expl_terms
1679 
1680  IMPLICIT NONE
1681 
1682  REAL*8, INTENT(IN) :: q_expl(n_vars,comp_cells_x,comp_cells_y)
1683  REAL*8, INTENT(OUT) :: expl_terms(n_eqns,comp_cells_x,comp_cells_y)
1684 
1685  REAL*8 :: qc(n_vars)
1686  REAL*8 :: expl_forces_term(n_eqns)
1687 
1688  INTEGER :: j,k
1689 
1690  DO k = 1,comp_cells_y
1691 
1692  DO j = 1,comp_cells_x
1693 
1694  qc = q_expl(1:n_vars,j,k)
1695 
1696  CALL eval_expl_terms( b_cent(j,k), b_prime_x(j,k), &
1697  b_prime_y(j,k), source_xy(j,k) , qc, expl_forces_term )
1698 
1699  expl_terms(1:n_eqns,j,k) = expl_forces_term
1700 
1701  ENDDO
1702 
1703  END DO
1704 
1705  END SUBROUTINE eval_explicit_terms
1706 
1707  !******************************************************************************
1709  !
1714  !
1717  !
1721  !******************************************************************************
1722 
1723  SUBROUTINE eval_hyperbolic_terms( q_expl , divFlux )
1725  ! External variables
1726  USE geometry_2d, ONLY : dx,dy
1727  USE parameters_2d, ONLY : solver_scheme
1728 
1729  IMPLICIT NONE
1730 
1731  REAL*8, INTENT(IN) :: q_expl(n_vars,comp_cells_x,comp_cells_y)
1732  REAL*8, INTENT(OUT) :: divFlux(n_eqns,comp_cells_x,comp_cells_y)
1733 
1734  REAL*8 :: q_old(n_vars,comp_cells_x,comp_cells_y)
1735 
1736  REAL*8 :: h_new
1737 
1738  REAL*8 :: tcpu0,tcpu1,tcpu2,tcpu3,tcpu4
1739 
1740  INTEGER :: i, j, k
1741 
1742  q_old = q
1743 
1744  q = q_expl
1745 
1746  CALL cpu_time(tcpu0)
1747 
1748  ! Linear reconstruction of the physical variables at the interfaces
1749  CALL reconstruction
1750 
1751  CALL cpu_time(tcpu1)
1752  !WRITE(*,*) 'eval_hyperbolic_terms: Time taken by the code was',tcpu1-tcpu0,'seconds'
1753 
1754 
1755  ! Evaluation of the maximum local speeds at the interfaces
1756  CALL eval_speeds
1757 
1758  CALL cpu_time(tcpu2)
1759  !WRITE(*,*) 'eval_hyperbolic_terms: Time taken by the code was',tcpu2-tcpu1,'seconds'
1760 
1761  ! Evaluation of the numerical fluxes
1762  SELECT CASE ( solver_scheme )
1763 
1764  CASE ("LxF")
1765 
1766  CALL eval_flux_lxf
1767 
1768  CASE ("GFORCE")
1769 
1770  CALL eval_flux_gforce
1771 
1772  CASE ("KT")
1773 
1774  CALL eval_flux_kt
1775 
1776  END SELECT
1777 
1778  CALL cpu_time(tcpu3)
1779  !WRITE(*,*) 'eval_hyperbolic_terms: Time taken by the code was',tcpu3-tcpu2,'seconds'
1780 
1781 
1782 
1783  ! Advance in time the solution
1784  DO k = 1,comp_cells_y
1785 
1786  DO j = 1,comp_cells_x
1787 
1788  DO i=1,n_eqns
1789 
1790  divflux(i,j,k) = 0.d0
1791 
1792  IF ( comp_cells_x .GT. 1 ) THEN
1793 
1794  divflux(i,j,k) = divflux(i,j,k) + &
1795  ( h_interface_x(i,j+1,k) - h_interface_x(i,j,k) ) / dx
1796 
1797  END IF
1798 
1799  IF ( comp_cells_y .GT. 1 ) THEN
1800 
1801  divflux(i,j,k) = divflux(i,j,k) + &
1802  ( h_interface_y(i,j,k+1) - h_interface_y(i,j,k) ) / dy
1803 
1804  END IF
1805 
1806 
1807  END DO
1808 
1809  h_new = q_expl(1,j,k) - dt * divflux(1,j,k) - b_cent(j,k)
1810 
1811  ! IF ( h_new .NE. 0.D0 ) THEN
1812  IF ( j .EQ. 0 ) THEN
1813 
1814  WRITE(*,*) 'j,k,h,divF',j,k,h_new, divflux(1,j,k)
1815  WRITE(*,*) 'dt',dt
1816 
1817  WRITE(*,*) 'h_interface(j,k) ',q_interfacel(1,j,k)-b_stag_x(j,k) , &
1818  q_interfacer(1,j,k) - b_stag_x(j,k)
1819 
1820  WRITE(*,*) 'hu_interface(j,k)' , q_interfacel(2,j,k) , &
1821  q_interfacer(2,j,k)
1822 
1823  WRITE(*,*) 'h_interface(j+1,k) ' , q_interfacel(1,j+1,k) &
1824  - b_stag_y(j+1,k) , q_interfacer(1,j+1,k) - b_stag_y(j+1,k)
1825 
1826  WRITE(*,*) 'hu_interface(j+1,k)' , q_interfacel(2,j+1,k) , &
1827  q_interfacer(2,j+1,k)
1828 
1829  WRITE(*,*) 'h flux x',h_interface_x(1,j,k) , h_interface_x(1,j+1,k)
1830 
1831  WRITE(*,*) 'h flux y',h_interface_y(i,j,k) , h_interface_y(1,j,k+1)
1832 
1833  WRITE(*,*) 'hu flux x',h_interface_x(2,j,k) , h_interface_x(2,j+1,k)
1834 
1835  WRITE(*,*) 'hu flux y',h_interface_y(2,j,k) , h_interface_y(2,j,k+1)
1836 
1837  READ(*,*)
1838 
1839  END IF
1840 
1841  ENDDO
1842 
1843  END DO
1844 
1845  CALL cpu_time(tcpu4)
1846  !WRITE(*,*) 'eval_hyperbolic_terms: Time taken by the code was',tcpu4-tcpu4,'seconds'
1847 
1848  q = q_old
1849 
1850  END SUBROUTINE eval_hyperbolic_terms
1851 
1852 
1853  !******************************************************************************
1855  !
1861  !******************************************************************************
1862 
1863  SUBROUTINE eval_flux_kt
1865  ! External procedures
1866  USE constitutive_2d, ONLY : eval_fluxes
1867 
1868  IMPLICIT NONE
1869 
1870  REAL*8 :: fluxL(n_eqns)
1871  REAL*8 :: fluxR(n_eqns)
1872  REAL*8 :: fluxB(n_eqns)
1873  REAL*8 :: fluxT(n_eqns)
1874 
1875  REAL*8 :: flux_avg_x(n_eqns)
1876  REAL*8 :: flux_avg_y(n_eqns)
1877 
1878  INTEGER :: j,k
1879  INTEGER :: i
1880 
1881  IF ( comp_cells_x .GT. 1 ) THEN
1882 
1883  DO k = 1,comp_cells_y
1884 
1885  DO j = 1,comp_interfaces_x
1886 
1887  CALL eval_fluxes( b_stag_x(j,k) , &
1888  r_qj = q_interfacel(1:n_vars,j,k) , r_flux=fluxl , dir=1 )
1889 
1890  CALL eval_fluxes( b_stag_x(j,k) , &
1891  r_qj = q_interfacer(1:n_vars,j,k) , r_flux=fluxr , dir=1 )
1892 
1893  CALL average_kt( a_interface_xneg(:,j,k), a_interface_xpos(:,j,k) ,&
1894  fluxl , fluxr , flux_avg_x )
1895 
1896  eqns_loop:DO i=1,n_eqns
1897 
1898  IF ( a_interface_xneg(i,j,k) .EQ. a_interface_xpos(i,j,k) ) THEN
1899 
1900  h_interface_x(i,j,k) = 0.d0
1901 
1902  ELSE
1903 
1904  h_interface_x(i,j,k) = flux_avg_x(i) &
1905  + ( a_interface_xpos(i,j,k) * a_interface_xneg(i,j,k) ) &
1906  / ( a_interface_xpos(i,j,k) - a_interface_xneg(i,j,k) ) &
1907  * ( q_interfacer(i,j,k) - q_interfacel(i,j,k) )
1908 
1909  END IF
1910 
1911  ENDDO eqns_loop
1912 
1913  ! In the equation for mass and for trasnport (T,xs) if the
1914  ! velocities at the interfaces are null, then the flux is null
1915  IF ( ( q_interfacel(2,j,k) .EQ. 0.d0 ) .AND. &
1916  ( q_interfacer(2,j,k) .EQ. 0.d0 ) ) THEN
1917 
1918  h_interface_x(1,j,k) = 0.d0
1919  h_interface_x(4:n_vars,j,k) = 0.d0
1920 
1921  END IF
1922 
1923  IF ( j .LE. 0 ) THEN
1924 
1925  WRITE(*,*) 'eval_flux_KT'
1926  WRITE(*,*) 'j',j
1927  WRITE(*,*) a_interface_xpos(1,j,k), a_interface_xneg(1,j,k)
1928  WRITE(*,*) q_interfacer(1,j,k) , q_interfacel(1,j,k)
1929  READ(*,*)
1930 
1931  END IF
1932 
1933  END DO
1934 
1935  END DO
1936 
1937  END IF
1938 
1939  IF ( comp_cells_y .GT. 1 ) THEN
1940 
1941  DO k = 1,comp_interfaces_y
1942 
1943  DO j = 1,comp_cells_x
1944 
1945  CALL eval_fluxes( b_stag_y(j,k) , &
1946  r_qj = q_interfaceb(1:n_vars,j,k) , r_flux=fluxb , dir=2 )
1947 
1948  CALL eval_fluxes( b_stag_y(j,k) , &
1949  r_qj = q_interfacet(1:n_vars,j,k) , r_flux=fluxt , dir=2 )
1950 
1951  CALL average_kt( a_interface_yneg(:,j,k) , &
1952  a_interface_ypos(:,j,k) , fluxb , fluxt , flux_avg_y )
1953 
1954  DO i=1,n_eqns
1955 
1956  IF ( a_interface_yneg(i,j,k) .EQ. a_interface_ypos(i,j,k) ) THEN
1957 
1958  h_interface_y(i,j,k) = 0.d0
1959 
1960  ELSE
1961 
1962  h_interface_y(i,j,k) = flux_avg_y(i) &
1963  + ( a_interface_ypos(i,j,k) * a_interface_yneg(i,j,k) ) &
1964  / ( a_interface_ypos(i,j,k) - a_interface_yneg(i,j,k) ) &
1965  * ( q_interfacet(i,j,k) - q_interfaceb(i,j,k) )
1966 
1967  END IF
1968 
1969  END DO
1970 
1971  ! In the equation for mass and for trasnport (T,xs) if the
1972  ! velocities at the interfaces are null, then the flux is null
1973  IF ( ( q_interfaceb(3,j,k) .EQ. 0.d0 ) .AND. &
1974  ( q_interfacet(3,j,k) .EQ. 0.d0 ) ) THEN
1975 
1976  h_interface_y(1,j,k) = 0.d0
1977  h_interface_y(4:n_vars,j,k) = 0.d0
1978 
1979  END IF
1980 
1981 
1982  ENDDO
1983 
1984  END DO
1985 
1986  END IF
1987 
1988  END SUBROUTINE eval_flux_kt
1989 
1990  !******************************************************************************
1992  !
2003  !******************************************************************************
2004 
2005 
2006  SUBROUTINE average_kt( a1 , a2 , w1 , w2 , w_avg )
2008  IMPLICIT NONE
2009 
2010  REAL*8, INTENT(IN) :: a1(:) , a2(:)
2011  REAL*8, INTENT(IN) :: w1(:) , w2(:)
2012  REAL*8, INTENT(OUT) :: w_avg(:)
2013 
2014  INTEGER :: n
2015  INTEGER :: i
2016 
2017  n = SIZE( a1 )
2018 
2019  DO i=1,n
2020 
2021  IF ( a1(i) .EQ. a2(i) ) THEN
2022 
2023  w_avg(i) = 0.5d0 * ( w1(i) + w2(i) )
2024  w_avg(i) = 0.d0
2025 
2026  ELSE
2027 
2028  w_avg(i) = ( a2(i) * w1(i) - a1(i) * w2(i) ) / ( a2(i) - a1(i) )
2029 
2030  END IF
2031 
2032  END DO
2033 
2034  END SUBROUTINE average_kt
2035 
2036  !******************************************************************************
2041  !******************************************************************************
2042 
2043  SUBROUTINE eval_flux_gforce
2045  ! to be implemented
2046  WRITE(*,*) 'method not yet implemented in 2-d case'
2047 
2048  END SUBROUTINE eval_flux_gforce
2049 
2050  !******************************************************************************
2055  !******************************************************************************
2056 
2057  SUBROUTINE eval_flux_lxf
2059  ! to be implemented
2060  WRITE(*,*) 'method not yet implemented in 2-d case'
2061 
2062  END SUBROUTINE eval_flux_lxf
2063 
2064 
2065  !******************************************************************************
2067  !
2074  !******************************************************************************
2075 
2076  SUBROUTINE reconstruction
2078  ! External procedures
2079  USE constitutive_2d, ONLY : qc_to_qp , qp_to_qc
2080  USE constitutive_2d, ONLY : qrec_to_qc
2081  USE parameters_2d, ONLY : limiter
2082 
2083  ! External variables
2084  USE geometry_2d, ONLY : x_comp , x_stag , y_comp , y_stag , dx , dx2 , dy , &
2085  dy2
2086 
2088 
2089  IMPLICIT NONE
2090 
2091  REAL*8 :: qc(n_vars)
2092  REAL*8 :: qrec(n_vars,comp_cells_x,comp_cells_y)
2093  REAL*8 :: qrecW(n_vars)
2094  REAL*8 :: qrecE(n_vars)
2095  REAL*8 :: qrecS(n_vars)
2096  REAL*8 :: qrecN(n_vars)
2097  REAL*8 :: qrec_bdry(n_vars)
2098 
2099  REAL*8 :: qrec_stencil(3)
2100  REAL*8 :: x_stencil(3)
2101  REAL*8 :: y_stencil(3)
2102  REAL*8 :: qrec_prime_x
2103  REAL*8 :: qrec_prime_y
2104 
2105  INTEGER :: j,k
2106  INTEGER :: i
2107 
2108  ! Compute the variable to reconstruct (phys or cons)
2109  DO k = 1,comp_cells_y
2110 
2111  DO j = 1,comp_cells_x
2112 
2113  qc = q(1:n_vars,j,k)
2114 
2115  IF ( reconstr_variables .EQ. 'phys' ) THEN
2116 
2117  CALL qc_to_qp( qc , b_cent(j,k) , qrec(1:n_vars,j,k) )
2118 
2119  ELSEIF ( reconstr_variables .EQ. 'cons' ) THEN
2120 
2121  qrec(1:n_vars,j,k) = qc
2122 
2123  END IF
2124 
2125  END DO
2126 
2127  ENDDO
2128 
2129  ! Linear reconstruction
2130 
2131  y_loop:DO k = 1,comp_cells_y
2132 
2133  x_loop:DO j = 1,comp_cells_x
2134 
2135  vars_loop:DO i=1,n_vars
2136 
2137  ! x direction
2138  IF ( comp_cells_x .GT. 1 ) THEN
2139 
2140  ! west boundary
2141  IF (j.EQ.1) THEN
2142 
2143  IF ( bcw(i)%flag .EQ. 0 ) THEN
2144 
2145  x_stencil(1) = x_stag(1)
2146  x_stencil(2:3) = x_comp(1:2)
2147 
2148  qrec_stencil(1) = bcw(i)%value
2149  qrec_stencil(2:3) = qrec(i,1:2,k)
2150 
2151  CALL limit( qrec_stencil , x_stencil , limiter(i) , &
2152  qrec_prime_x )
2153 
2154  ELSEIF ( bcw(i)%flag .EQ. 1 ) THEN
2155 
2156  qrec_prime_x = bcw(i)%value
2157 
2158  ELSEIF ( bcw(i)%flag .EQ. 2 ) THEN
2159 
2160  qrec_prime_x = ( qrec(i,2,k) - qrec(i,1,k) ) / dx
2161 
2162  END IF
2163 
2164  !east boundary
2165  ELSEIF (j.EQ.comp_cells_x) THEN
2166 
2167  IF ( bce(i)%flag .EQ. 0 ) THEN
2168 
2169  qrec_stencil(3) = bce(i)%value
2170  qrec_stencil(1:2) = qrec(i,comp_cells_x-1:comp_cells_x,k)
2171 
2172  x_stencil(3) = x_stag(comp_interfaces_x)
2173  x_stencil(1:2) = x_comp(comp_cells_x-1:comp_cells_x)
2174 
2175  CALL limit( qrec_stencil , x_stencil , limiter(i) , &
2176  qrec_prime_x )
2177 
2178  ELSEIF ( bce(i)%flag .EQ. 1 ) THEN
2179 
2180  qrec_prime_x = bce(i)%value
2181 
2182  ELSEIF ( bce(i)%flag .EQ. 2 ) THEN
2183 
2184  qrec_prime_x = ( qrec(i,comp_cells_x,k) - &
2185  qrec(i,comp_cells_x-1,k) ) / dx
2186 
2187  END IF
2188 
2189  ! internal x cells
2190  ELSE
2191 
2192  x_stencil(1:3) = x_comp(j-1:j+1)
2193  qrec_stencil = qrec(i,j-1:j+1,k)
2194 
2195  CALL limit( qrec_stencil , x_stencil , limiter(i) , &
2196  qrec_prime_x )
2197 
2198  ENDIF
2199 
2200  qrecw(i) = qrec(i,j,k) - reconstr_coeff * dx2 * qrec_prime_x
2201  qrece(i) = qrec(i,j,k) + reconstr_coeff * dx2 * qrec_prime_x
2202 
2203  ! positivity preserving reconstruction for h (i=1, 1st variable)
2204  IF ( i .EQ. 1 ) THEN
2205 
2206  IF ( qrece(i) .LT. b_stag_x(j+1,k) ) THEN
2207 
2208  qrec_prime_x = ( b_stag_x(j+1,k) - qrec(i,j,k) ) / dx2
2209 
2210  qrece(i) = qrec(i,j,k) + dx2 * qrec_prime_x
2211 
2212  qrecw(i) = 2.d0 * qrec(i,j,k) - qrece(i)
2213 
2214  ENDIF
2215 
2216  IF ( qrecw(i) .LT. b_stag_x(j,k) ) THEN
2217 
2218  qrec_prime_x = ( qrec(i,j,k) - b_stag_x(j,k) ) / dx2
2219 
2220  qrecw(i) = qrec(i,j,k) - dx2 * qrec_prime_x
2221 
2222  qrece(i) = 2.d0 * qrec(i,j,k) - qrecw(i)
2223 
2224  ENDIF
2225 
2226  END IF
2227 
2228  END IF
2229 
2230  ! y-direction
2231  check_comp_cells_y:IF ( comp_cells_y .GT. 1 ) THEN
2232 
2233  ! South boundary
2234  check_y_boundary:IF (k.EQ.1) THEN
2235 
2236  IF ( bcs(i)%flag .EQ. 0 ) THEN
2237 
2238  qrec_stencil(1) = bcs(i)%value
2239  qrec_stencil(2:3) = qrec(i,j,1:2)
2240 
2241  y_stencil(1) = y_stag(1)
2242  y_stencil(2:3) = y_comp(1:2)
2243 
2244  CALL limit( qrec_stencil , y_stencil , limiter(i) , &
2245  qrec_prime_y )
2246 
2247  ELSEIF ( bcs(i)%flag .EQ. 1 ) THEN
2248 
2249  qrec_prime_y = bcs(i)%value
2250 
2251  ELSEIF ( bcs(i)%flag .EQ. 2 ) THEN
2252 
2253  qrec_prime_y = ( qrec(i,j,2) - qrec(i,j,1) ) / dy
2254 
2255  END IF
2256 
2257  ! North boundary
2258  ELSEIF ( k .EQ. comp_cells_y ) THEN
2259 
2260  IF ( bcn(i)%flag .EQ. 0 ) THEN
2261 
2262  qrec_stencil(3) = bcn(i)%value
2263  qrec_stencil(1:2) = qrec(i,j,comp_cells_y-1:comp_cells_y)
2264 
2265  y_stencil(3) = y_stag(comp_interfaces_y)
2266  y_stencil(1:2) = y_comp(comp_cells_y-1:comp_cells_y)
2267 
2268  CALL limit( qrec_stencil , y_stencil , limiter(i) , &
2269  qrec_prime_y )
2270 
2271  ELSEIF ( bcn(i)%flag .EQ. 1 ) THEN
2272 
2273  qrec_prime_y = bcn(i)%value
2274 
2275  ELSEIF ( bcn(i)%flag .EQ. 2 ) THEN
2276 
2277  qrec_prime_y = ( qrec(i,j,comp_cells_y) - &
2278  qrec(i,j,comp_cells_y-1) ) / dy
2279 
2280  END IF
2281 
2282  ! Internal y cells
2283  ELSE
2284 
2285  y_stencil(1:3) = y_comp(k-1:k+1)
2286  qrec_stencil = qrec(i,j,k-1:k+1)
2287 
2288  CALL limit( qrec_stencil , y_stencil , limiter(i) , &
2289  qrec_prime_y )
2290 
2291  ENDIF check_y_boundary
2292 
2293  qrecs(i) = qrec(i,j,k) - reconstr_coeff * dy2 * qrec_prime_y
2294  qrecn(i) = qrec(i,j,k) + reconstr_coeff * dy2 * qrec_prime_y
2295 
2296  ! positivity preserving reconstruction for h
2297  IF ( i .EQ. 1 ) THEN
2298 
2299  IF ( qrecn(i) .LT. b_stag_y(j,k+1) ) THEN
2300 
2301  qrec_prime_y = ( b_stag_y(j,k+1) - qrec(i,j,k) ) / dy2
2302 
2303  qrecn(i) = qrec(i,j,k) + dy2 * qrec_prime_y
2304 
2305  qrecs(i) = 2.d0 * qrec(i,j,k) - qrecn(i)
2306 
2307  ENDIF
2308 
2309  IF ( qrecs(i) .LT. b_stag_y(j,k) ) THEN
2310 
2311  qrec_prime_y = ( qrec(i,j,k) - b_stag_y(j,k) ) / dy2
2312 
2313  qrecs(i) = qrec(i,j,k) - dy2 * qrec_prime_y
2314 
2315  qrecn(i) = 2.d0 * qrec(i,j,k) - qrecs(i)
2316 
2317  ENDIF
2318 
2319  END IF
2320 
2321  ENDIF check_comp_cells_y
2322 
2323  ENDDO vars_loop
2324 
2325 
2326  IF ( reconstr_variables .EQ. 'phys' ) THEN
2327 
2328  ! Convert back from physical to conservative variables
2329  IF ( comp_cells_x .GT. 1 ) THEN
2330 
2331  CALL qp_to_qc( qrecw , b_stag_x(j,k) , q_interfacer(:,j,k) )
2332  CALL qp_to_qc( qrece , b_stag_x(j+1,k) , q_interfacel(:,j+1,k) )
2333 
2334  END IF
2335 
2336  IF ( comp_cells_y .GT. 1 ) THEN
2337 
2338  CALL qp_to_qc( qrecs , b_stag_y(j,k) , q_interfacet(:,j,k) )
2339  CALL qp_to_qc( qrecn , b_stag_y(j,k+1) , q_interfaceb(:,j,k+1) )
2340 
2341  END IF
2342 
2343  ELSE IF ( reconstr_variables .EQ. 'cons' ) THEN
2344 
2345  IF ( comp_cells_x .GT. 1 ) THEN
2346 
2347  CALL qrec_to_qc( qrecw, b_stag_x(j,k) , q_interfacer(:,j,k) )
2348  CALL qrec_to_qc( qrece, b_stag_x(j+1,k) , q_interfacel(:,j+1,k) )
2349 
2350  END IF
2351 
2352  IF ( comp_cells_y .GT. 1 ) THEN
2353 
2354  CALL qrec_to_qc( qrecs, b_stag_y(j,k) , q_interfacet(:,j,k) )
2355  CALL qrec_to_qc( qrecn, b_stag_y(j,k+1) , q_interfaceb(:,j,k+1) )
2356 
2357  END IF
2358 
2359  END IF
2360 
2361  IF ( j.EQ.0 ) THEN
2362 
2363  WRITE(*,*) 'qrecW',qrecw
2364  WRITE(*,*) 'qrecE',qrece
2365 
2366  END IF
2367 
2368  ! boundary conditions
2369 
2370  IF ( comp_cells_y .GT. 1 ) THEN
2371 
2372  ! South q_interfaceB(:,j,1)
2373  IF ( k .EQ. 1 ) THEN
2374 
2375  DO i=1,n_vars
2376 
2377  IF ( bcs(i)%flag .EQ. 0 ) THEN
2378 
2379  qrec_bdry(i) = bcs(i)%value
2380 
2381  ELSE
2382 
2383  qrec_bdry(i) = qrecs(i)
2384 
2385  END IF
2386 
2387  ENDDO
2388 
2389  IF ( reconstr_variables .EQ. 'phys' ) THEN
2390 
2391  CALL qp_to_qc( qrec_bdry, b_stag_y(j,1), q_interfaceb(:,j,1) )
2392 
2393  ELSEIF ( reconstr_variables .EQ. 'cons' ) THEN
2394 
2395  CALL qrec_to_qc( qrec_bdry , b_stag_y(j,1) , &
2396  q_interfaceb(:,j,1) )
2397 
2398  END IF
2399 
2400  ENDIF
2401 
2402  ! North qT(i,j,comp_interfaces_y)
2403  IF(k.EQ.comp_cells_y)THEN
2404 
2405  DO i=1,n_vars
2406 
2407  IF ( bcn(i)%flag .EQ. 0 ) THEN
2408 
2409  qrec_bdry(i) = bcn(i)%value
2410 
2411  ELSE
2412 
2413  qrec_bdry(i) = qrecn(i)
2414 
2415  END IF
2416 
2417  ENDDO
2418 
2419  IF ( reconstr_variables .EQ. 'phys' ) THEN
2420 
2421  CALL qp_to_qc( qrec_bdry , b_stag_y(j,comp_interfaces_y) , &
2422  q_interfacet(:,j,comp_interfaces_y) )
2423 
2424  ELSEIF ( reconstr_variables .EQ. 'cons' ) THEN
2425 
2426  CALL qrec_to_qc( qrec_bdry , b_stag_y(j,comp_interfaces_y) , &
2427  q_interfacet(:,j,comp_interfaces_y) )
2428 
2429  END IF
2430 
2431  ENDIF
2432 
2433  END IF
2434 
2435  IF ( comp_cells_x .GT. 1 ) THEN
2436 
2437  ! West q_interfaceL(:,1,k)
2438  IF ( j.EQ.1 ) THEN
2439 
2440  DO i=1,n_vars
2441 
2442  IF ( bcw(i)%flag .EQ. 0 ) THEN
2443 
2444  qrec_bdry(i) = bcw(i)%value
2445 
2446  ELSE
2447 
2448  qrec_bdry(i) = qrecw(i)
2449 
2450  END IF
2451 
2452  ENDDO
2453 
2454  IF ( reconstr_variables .EQ. 'phys' ) THEN
2455 
2456  CALL qp_to_qc( qrec_bdry, b_stag_x(1,k), q_interfacel(:,1,k) )
2457 
2458  ELSEIF ( reconstr_variables .EQ. 'cons' ) THEN
2459 
2460  CALL qrec_to_qc( qrec_bdry , b_stag_x(1,k) , &
2461  q_interfacel(:,1,k) )
2462 
2463  END IF
2464 
2465  q_interfacer(:,1,k) = q_interfacel(:,1,k)
2466 
2467  ENDIF
2468 
2469  ! East q_interfaceR(:,comp_interfaces_x,k)
2470  IF ( j.EQ.comp_cells_x ) THEN
2471 
2472  DO i=1,n_vars
2473 
2474  IF ( bce(i)%flag .EQ. 0 ) THEN
2475 
2476  qrec_bdry(i) = bce(i)%value
2477 
2478  ELSE
2479 
2480  qrec_bdry(i) = qrece(i)
2481 
2482  END IF
2483 
2484  ENDDO
2485 
2486  IF ( reconstr_variables .EQ. 'phys' ) THEN
2487 
2488  CALL qp_to_qc( qrec_bdry , b_stag_x(comp_interfaces_x,k) , &
2489  q_interfacer(:,comp_interfaces_x,k) )
2490 
2491  ELSEIF ( reconstr_variables .EQ. 'cons' ) THEN
2492 
2493  CALL qrec_to_qc( qrec_bdry , b_stag_x(comp_interfaces_x,k) , &
2494  q_interfacer(:,comp_interfaces_x,k) )
2495 
2496  END IF
2497 
2498  q_interfacel(:,comp_interfaces_x,k) = &
2499  q_interfacer(:,comp_interfaces_x,k)
2500 
2501  ENDIF
2502 
2503  END IF
2504 
2505  END DO x_loop
2506 
2507  END DO y_loop
2508 
2509  END SUBROUTINE reconstruction
2510 
2511 
2512  !******************************************************************************
2514  !
2520  !******************************************************************************
2521 
2522  SUBROUTINE eval_speeds
2524  ! External procedures
2527 
2528  IMPLICIT NONE
2529 
2530  REAL*8 :: abslambdaL_min(n_vars) , abslambdaL_max(n_vars)
2531  REAL*8 :: abslambdaR_min(n_vars) , abslambdaR_max(n_vars)
2532  REAL*8 :: abslambdaB_min(n_vars) , abslambdaB_max(n_vars)
2533  REAL*8 :: abslambdaT_min(n_vars) , abslambdaT_max(n_vars)
2534  REAL*8 :: min_r(n_vars) , max_r(n_vars)
2535 
2536  INTEGER :: j,k
2537 
2538  IF ( comp_cells_x .GT. 1 ) THEN
2539 
2540  DO j = 1,comp_interfaces_x
2541 
2542  DO k = 1, comp_cells_y
2543 
2544  CALL eval_local_speeds2_x( q_interfacel(:,j,k) , b_stag_x(j,k) , &
2545  abslambdal_min , abslambdal_max )
2546 
2547  CALL eval_local_speeds2_x( q_interfacer(:,j,k) , b_stag_x(j,k) , &
2548  abslambdar_min , abslambdar_max )
2549 
2550  min_r = min(abslambdal_min , abslambdar_min , 0.0d0)
2551  max_r = max(abslambdal_max , abslambdar_max , 0.0d0)
2552 
2553  a_interface_xneg(:,j,k) = min_r
2554  a_interface_xpos(:,j,k) = max_r
2555 
2556  ENDDO
2557 
2558  END DO
2559 
2560  END IF
2561 
2562  IF ( comp_cells_y .GT. 1 ) THEN
2563 
2564  DO j = 1,comp_cells_x
2565 
2566  DO k = 1,comp_interfaces_y
2567 
2568  CALL eval_local_speeds2_y( q_interfaceb(:,j,k) , b_stag_y(j,k) , &
2569  abslambdab_min , abslambdab_max )
2570 
2571  CALL eval_local_speeds2_y( q_interfacet(:,j,k) , b_stag_y(j,k) , &
2572  abslambdat_min , abslambdat_max )
2573 
2574  min_r = min(abslambdab_min , abslambdat_min , 0.0d0)
2575  max_r = max(abslambdab_max , abslambdat_max , 0.0d0)
2576 
2577  a_interface_yneg(:,j,k) = min_r
2578  a_interface_ypos(:,j,k) = max_r
2579 
2580  ENDDO
2581 
2582  END DO
2583 
2584  END IF
2585 
2586  END SUBROUTINE eval_speeds
2587 
2588 
2589  !******************************************************************************
2591  !
2606  !******************************************************************************
2607 
2608  SUBROUTINE limit( v , z , limiter , slope_lim )
2610  USE parameters_2d, ONLY : theta
2611 
2612  IMPLICIT none
2613 
2614  REAL*8, INTENT(IN) :: v(3)
2615  REAL*8, INTENT(IN) :: z(3)
2616  INTEGER, INTENT(IN) :: limiter
2617 
2618  REAL*8, INTENT(OUT) :: slope_lim
2619 
2620  REAL*8 :: a , b , c
2621 
2622  REAL*8 :: sigma1 , sigma2
2623 
2624  a = ( v(3) - v(2) ) / ( z(3) - z(2) )
2625  b = ( v(2) - v(1) ) / ( z(2) - z(1) )
2626  c = ( v(3) - v(1) ) / ( z(3) - z(1) )
2627 
2628  SELECT CASE (limiter)
2629 
2630  CASE ( 0 )
2631 
2632  slope_lim = 0.d0
2633 
2634  CASE ( 1 )
2635 
2636  ! minmod
2637 
2638  slope_lim = minmod(a,b)
2639 
2640  CASE ( 2 )
2641 
2642  ! superbee
2643 
2644  sigma1 = minmod( a , 2.d0*b )
2645  sigma2 = minmod( 2.d0*a , b )
2646  slope_lim = maxmod( sigma1 , sigma2 )
2647 
2648  CASE ( 3 )
2649 
2650  ! generalized minmod
2651 
2652  slope_lim = minmod( c , theta * minmod( a , b ) )
2653 
2654  CASE ( 4 )
2655 
2656  ! monotonized central-difference (MC, LeVeque p.112)
2657 
2658  slope_lim = minmod( c , 2.0 * minmod( a , b ) )
2659 
2660  END SELECT
2661 
2662  END SUBROUTINE limit
2663 
2664 
2665  REAL*8 FUNCTION minmod(a,b)
2667  IMPLICIT none
2668 
2669  REAL*8 :: a , b , sa , sb
2670 
2671  IF ( a*b .EQ. 0.d0 ) THEN
2672 
2673  minmod = 0.d0
2674 
2675  ELSE
2676 
2677  sa = a / abs(a)
2678  sb = b / abs(b)
2679 
2680  minmod = 0.5d0 * ( sa+sb ) * min( abs(a) , abs(b) )
2681 
2682  END IF
2683 
2684  END FUNCTION minmod
2685 
2686  REAL*8 function maxmod(a,b)
2688  IMPLICIT none
2689 
2690  REAL*8 :: a , b , sa , sb
2691 
2692  IF ( a*b .EQ. 0.d0 ) THEN
2693 
2694  maxmod = 0.d0
2695 
2696  ELSE
2697 
2698  sa = a / abs(a)
2699  sb = b / abs(b)
2700 
2701  maxmod = 0.5d0 * ( sa+sb ) * max( abs(a) , abs(b) )
2702 
2703  END IF
2704 
2705  END function maxmod
2706 
2707 END MODULE solver_2d
real *8, dimension(:,:), allocatable b_prime_x
Topography slope (x direction) at the centers of the control volumes.
Definition: geometry_2d.f90:38
subroutine eval_explicit_terms(q_expl, expl_terms)
Evaluate the explicit terms.
Definition: solver_2d.f90:1677
real *8 max_dt
Largest time step allowed.
subroutine eval_speeds
Characteristic speeds.
Definition: solver_2d.f90:2523
subroutine qc_to_qp(qc, B, qp)
Conservative to physical variables.
real *8, dimension(:), allocatable a_dirk
Explicit coeff. for the non-hyp. part for a single step of the R-K scheme.
Definition: solver_2d.f90:86
real *8 dy
Control volumes size.
Definition: geometry_2d.f90:59
real *8, dimension(:,:), allocatable nhj
Local Intermediate non-hyperbolic terms of the Runge-Kutta scheme.
Definition: solver_2d.f90:105
integer n_rk
Runge-Kutta order.
real *8, parameter tol_rel
real *8, dimension(:,:,:,:), allocatable q_rk
Intermediate solutions of the Runge-Kutta scheme.
Definition: solver_2d.f90:91
real *8, dimension(:), allocatable x_comp
Location of the centers (x) of the control volume of the domain.
Definition: geometry_2d.f90:14
subroutine lnsrch(Bj, Bprimej_x, Bprimej_y, grav3_surf, qj_rel_NR_old, qj_org, qj_old, scal_f_old, grad_f, desc_dir, coeff_f, qj_rel, scal_f, right_term, stpmax, check)
Search the descent stepsize.
Definition: solver_2d.f90:1313
real *8, dimension(:,:,:), allocatable q0
Conservative variables.
Definition: solver_2d.f90:35
real *8, dimension(:,:), allocatable b_cent
Topography at the centers of the control volumes.
Definition: geometry_2d.f90:35
integer comp_cells_x
Number of control volumes x in the comp. domain.
Definition: geometry_2d.f90:64
subroutine eval_flux_gforce
Numerical fluxes GFORCE.
Definition: solver_2d.f90:2044
real *8, dimension(:,:), allocatable grav_surf
gravity vector wrt surface coordinates for each cell
Definition: geometry_2d.f90:47
real *8, dimension(:,:,:,:), allocatable divflux
Intermediate hyperbolic terms of the Runge-Kutta scheme.
Definition: solver_2d.f90:93
real *8, dimension(:), allocatable y_comp
Location of the centers (y) of the control volume of the domain.
Definition: geometry_2d.f90:20
logical, dimension(:,:), allocatable mask11
Definition: solver_2d.f90:69
real *8, dimension(:,:), allocatable source_xy
Array defining fraction of cells affected by source term.
Definition: solver_2d.f90:62
subroutine solve_rk_step(Bj, Bprimej_x, Bprimej_y, grav3_surf, qj, qj_old, a_tilde, a_dirk, a_diag)
Runge-Kutta single step integration.
Definition: solver_2d.f90:987
subroutine qrec_to_qc(qrec, B, qc)
Reconstructed to conservative variables.
subroutine average_kt(a1, a2, w1, w2, w_avg)
averaged KT flux
Definition: solver_2d.f90:2007
Parameters.
subroutine eval_local_speeds_x(qj, Bj, vel_min, vel_max)
Local Characteristic speeds x direction.
real *8 dx
Control volumes size.
Definition: geometry_2d.f90:56
real *8, dimension(:,:,:,:), allocatable si_nh
Intermediate semi-implicit non-hyperbolic terms of the Runge-Kutta scheme.
Definition: solver_2d.f90:97
real *8 function maxmod(a, b)
Definition: solver_2d.f90:2687
integer comp_cells_y
Number of control volumes y in the comp. domain.
Definition: geometry_2d.f90:66
Numerical solver.
Definition: solver_2d.f90:12
real *8, dimension(:,:,:), allocatable a_interface_xneg
Local speeds at the left of the x-interface.
Definition: solver_2d.f90:47
subroutine deallocate_solver_variables
Memory deallocation.
Definition: solver_2d.f90:338
subroutine eval_local_speeds2_y(qj, Bj, vel_min, vel_max)
Local Characteristic speeds.
real *8, dimension(:,:,:,:), allocatable expl_terms
Intermediate explicit terms of the Runge-Kutta scheme.
Definition: solver_2d.f90:100
type(bc), dimension(:), allocatable bcw
bcW&flag defines the west boundary condition:
subroutine eval_jacobian(Bj, Bprimej_x, Bprimej_y, grav3_surf, qj_rel, qj_org, coeff_f, left_matrix)
Evaluate the jacobian.
Definition: solver_2d.f90:1604
real *8, dimension(:,:,:,:), allocatable nh
Intermediate non-hyperbolic terms of the Runge-Kutta scheme.
Definition: solver_2d.f90:95
logical, dimension(:,:), allocatable solve_mask0
Definition: solver_2d.f90:64
real *8, dimension(:), allocatable a_tilde
Explicit coeff. for the hyperbolic part for a single step of the R-K scheme.
Definition: solver_2d.f90:84
real *8 dt
Time step.
Definition: solver_2d.f90:67
integer n_vars
Number of conservative variables.
real *8, dimension(:,:,:), allocatable a_interface_yneg
Local speeds at the bottom of the y-interface.
Definition: solver_2d.f90:51
subroutine eval_flux_lxf
Numerical fluxes Lax-Friedrichs.
Definition: solver_2d.f90:2058
integer comp_interfaces_y
Number of interfaces (comp_cells_y+1)
Definition: geometry_2d.f90:67
real *8 cfl
Courant-Friedrichs-Lewy parameter.
subroutine eval_hyperbolic_terms(q_expl, divFlux)
Semidiscrete finite volume central scheme.
Definition: solver_2d.f90:1724
integer, parameter max_nl_iter
real *8, dimension(:,:,:), allocatable residual_term
Sum of all the terms of the equations except the transient term.
Definition: solver_2d.f90:121
Constitutive equations.
logical normalize_q
Flag for the normalization of the array q in the implicit solution scheme.
Definition: solver_2d.f90:112
logical, dimension(:,:), allocatable mask21
Definition: solver_2d.f90:69
real *8, dimension(:,:,:), allocatable h_interface_x
Semidiscrete numerical interface fluxes.
Definition: solver_2d.f90:55
real *8, dimension(:,:), allocatable a_dirk_ij
Butcher Tableau for the implicit part of the Runge-Kutta scheme.
Definition: solver_2d.f90:76
real *8, dimension(:,:,:), allocatable a_interface_ypos
Local speeds at the top of the y-interface.
Definition: solver_2d.f90:53
logical, dimension(:), allocatable implicit_flag
real *8, dimension(:,:,:), allocatable h_interface_y
Semidiscrete numerical interface fluxes.
Definition: solver_2d.f90:57
real *8 function minmod(a, b)
Definition: solver_2d.f90:2666
real *8, dimension(:,:,:), allocatable q_interfacel
Reconstructed value at the left of the x-interface.
Definition: solver_2d.f90:39
real *8, dimension(:), allocatable omega_tilde
Coefficients for the explicit part of the Runge-Kutta scheme.
Definition: solver_2d.f90:79
character(len=20) solver_scheme
Finite volume method: .
subroutine eval_fluxes(Bj, c_qj, r_qj, c_flux, r_flux, dir)
Hyperbolic Fluxes.
Grid module.
Definition: geometry_2d.f90:7
real *8, dimension(:), allocatable omega
Coefficients for the implicit part of the Runge-Kutta scheme.
Definition: solver_2d.f90:81
real *8, dimension(:,:), allocatable expl_terms_j
Local Intermediate explicit terms of the Runge-Kutta scheme.
Definition: solver_2d.f90:107
real *8, dimension(:,:), allocatable b_stag_x
Topography at the boundaries (x) of the control volumes.
Definition: geometry_2d.f90:26
real *8 theta
Van Leer limiter parameter.
subroutine timestep2
Time-step computation.
Definition: solver_2d.f90:525
subroutine check_solve
Masking of cells to solve.
Definition: solver_2d.f90:404
subroutine eval_expl_terms(Bj, Bprimej_x, Bprimej_y, source_xy, qj, expl_term)
Explicit Forces term.
real *8, dimension(:,:,:), allocatable a_interface_xpos
Local speeds at the right of the x-interface.
Definition: solver_2d.f90:49
logical, dimension(:,:), allocatable mask22
Definition: solver_2d.f90:69
subroutine eval_local_speeds_y(qj, Bj, vel_min, vel_max)
Local Characteristic speeds y direction.
integer verbose_level
real *8, dimension(:,:), allocatable b_prime_y
Topography slope (y direction) at the centers of the control volumes.
Definition: geometry_2d.f90:41
subroutine timestep
Time-step computation.
Definition: solver_2d.f90:448
real *8, dimension(:,:), allocatable si_nhj
Local Intermediate semi-impl non-hyperbolic terms of the Runge-Kutta scheme.
Definition: solver_2d.f90:109
real *8, dimension(:,:), allocatable b_stag_y
Topography at the boundaries (y) of the control volumes.
Definition: geometry_2d.f90:29
real *8, dimension(:,:,:), allocatable q_interfaceb
Reconstructed value at the bottom of the y-interface.
Definition: solver_2d.f90:43
real *8, dimension(:), allocatable x_stag
Location of the boundaries (x) of the control volumes of the domain.
Definition: geometry_2d.f90:17
real *8, dimension(:,:), allocatable a_tilde_ij
Butcher Tableau for the explicit part of the Runge-Kutta scheme.
Definition: solver_2d.f90:74
real *8 a_diag
Implicit coeff. for the non-hyp. part for a single step of the R-K scheme.
Definition: solver_2d.f90:88
character(len=20) reconstr_variables
logical opt_search_nl
Flag for the search of optimal step size in the implicit solution scheme.
Definition: solver_2d.f90:118
real *8, dimension(:,:,:), allocatable q_fv
Solution of the finite-volume semidiscrete cheme.
Definition: solver_2d.f90:37
logical normalize_f
Flag for the normalization of the array f in the implicit solution scheme.
Definition: solver_2d.f90:115
integer, dimension(10) limiter
Limiter for the slope in the linear reconstruction: .
subroutine eval_nonhyperbolic_terms(Bj, Bprimej_x, Bprimej_y, grav3_surf, c_qj, c_nh_term_impl, r_qj, r_nh_term_impl)
Non-Hyperbolic terms.
type(bc), dimension(:), allocatable bcn
bcN&flag defines the north boundary condition:
subroutine eval_local_speeds2_x(qj, Bj, vel_min, vel_max)
Local Characteristic speeds.
subroutine eval_f(Bj, Bprimej_x, Bprimej_y, grav3_surf, qj, qj_old, a_tilde, a_dirk, a_diag, coeff_f, f_nl, scal_f)
Evaluate the nonlinear system.
Definition: solver_2d.f90:1537
real *8 dx2
Half x Control volumes size.
Definition: geometry_2d.f90:62
integer n_eqns
Number of equations.
subroutine qp_to_qc(qp, B, qc)
Physical to conservative variables.
real *8, parameter tol_abs
subroutine reconstruction
Linear reconstruction.
Definition: solver_2d.f90:2077
real *8 t_imex1
Definition: solver_2d.f90:124
real *8 reconstr_coeff
Slope coefficient in the linear reconstruction.
subroutine imex_rk_solver
Runge-Kutta integration.
Definition: solver_2d.f90:598
type(bc), dimension(:), allocatable bcs
bcS&flag defines the south boundary condition:
logical, dimension(:,:), allocatable solve_mask
Definition: solver_2d.f90:64
integer comp_interfaces_x
Number of interfaces (comp_cells_x+1)
Definition: geometry_2d.f90:65
real *8, dimension(:), allocatable y_stag
Location of the boundaries (x) of the control volumes of the domain.
Definition: geometry_2d.f90:23
type(bc), dimension(:), allocatable bce
bcE&flag defines the east boundary condition:
subroutine limit(v, z, limiter, slope_lim)
Slope limiter.
Definition: solver_2d.f90:2609
real *8, dimension(:,:,:), allocatable q_interfacer
Reconstructed value at the right of the x-interface.
Definition: solver_2d.f90:41
real *8, dimension(:,:), allocatable divfluxj
Local Intermediate hyperbolic terms of the Runge-Kutta scheme.
Definition: solver_2d.f90:103
subroutine eval_flux_kt
Semidiscrete numerical fluxes.
Definition: solver_2d.f90:1864
integer i_rk
loop counter for the RK iteration
Definition: solver_2d.f90:71
subroutine allocate_solver_variables
Memory allocation.
Definition: solver_2d.f90:141
real *8 t_imex2
Definition: solver_2d.f90:124
real *8 dy2
Half y Control volumes size.
Definition: geometry_2d.f90:63
logical, dimension(:,:), allocatable mask12
Definition: solver_2d.f90:69
real *8, dimension(:,:,:), allocatable q_interfacet
Reconstructed value at the top of the y-interface.
Definition: solver_2d.f90:45
real *8, dimension(:,:,:), allocatable qp
Physical variables ( )
Definition: solver_2d.f90:59
integer n_nh
Number of non-hyperbolic terms.
real *8, dimension(:,:,:), allocatable q
Conservative variables.
Definition: solver_2d.f90:33
subroutine eval_nh_semi_impl_terms(Bj, grav3_surf, c_qj, c_nh_semi_impl_term, r_qj, r_nh_semi_impl_term)
Non-Hyperbolic semi-implicit terms.