MFIX  2016-1
iterate.f
Go to the documentation of this file.
1 ! -*- f90 -*-
2  MODULE iterate
3 
4  USE exit, ONLY: mfix_exit
5  USE run, ONLY: ier, tunit, time
6 
7 ! flag indicating convergence status with MUSTIT = 0,1,2 implying
8 ! complete convergence, non-covergence and divergence respectively
9  INTEGER :: mustit
10 
11 ! Number of iterations completed for current timestep
12  INTEGER :: nit
13 
14 ! User defined maximum number of iterations
15  INTEGER :: max_nit
16 
17  LOGICAL :: converged, diverged
18 
19 ! cpu time left
20  DOUBLE PRECISION :: tleft
21 ! Normalization factor for gas & solids pressure residual
22  DOUBLE PRECISION :: normg, norms
23 ! Set normalization factor for gas and solids pressure residual
24  LOGICAL :: setg, sets
25 ! gas & solids pressure residual
26  DOUBLE PRECISION :: resg, ress
27 ! Weight of solids in the reactor
28  DOUBLE PRECISION :: smass
29  DOUBLE PRECISION, DIMENSION(:), ALLOCATABLE :: errorpercent
30 ! Error Message
31  CHARACTER(LEN=32) :: lmsg
32 
33  CONTAINS
34 
35 !vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv!
36 ! !
37 ! Subroutine: ITERATE !
38 ! Author: M. Syamlal Date: 12-APR-96 !
39 ! !
40 ! Purpose: This module controls the iterations for solving equations !
41 ! !
42 !^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^!
43  SUBROUTINE iterate_init
44 
45  USE compar, only: mype, pe_io
46  USE cutcell, only: cartesian_grid
47  USE geometry, only: cyclic
48  USE leqsol, only: leq_adjust
49  USE output, only: full_log
50  USE param1, only: one, small_number, undefined, zero
52  USE time_cpu
53  USE toleranc, only: norm_g, norm_s
54 
55  IMPLICIT NONE
56 
57 ! initializations
58  dt_prev = dt
59  nit = 0
60  mustit = 0
61  converged = .false.
62  diverged = .false.
63  resg = zero
64  ress = zero
65 
66  IF(norm_g == undefined) THEN
67  normg = one
68  setg = .false.
69  ELSE
70  normg = norm_g
71  setg = .true.
72  ENDIF
73 
74  IF(norm_s == undefined) THEN
75  norms = one
76  sets = .false.
77  ELSE
78  norms = norm_s
79  sets = .true.
80  ENDIF
81 
82  leq_adjust = .false.
83 
84 ! Initialize residuals
85  CALL init_resid ()
86 
87 ! Initialize the routine for holding gas mass flux constant with cyclic bc
88  IF(cyclic) CALL goalseekmassflux(nit, mustit, .false.)
89 
90 ! CPU time left
91  IF (full_log) THEN
92  tleft = (tstop - time)*cpuos
93  CALL get_tunit (tleft, tunit)
94 
95  IF (steady_state) THEN
96  CALL get_smass (smass)
97  IF(mype.eq.pe_io) THEN
98  WRITE (*, '(/A,G12.5, A,F9.3,1X,A)') &
99  ' Starting solids mass = ', smass
100  ENDIF
101  ELSE
102  IF(mype.eq.pe_io) THEN
103  IF ((cn_on.AND.nstep>1.AND.run_type == 'NEW') .OR. &
104  (cn_on.AND.run_type /= 'NEW' .AND.&
105  nstep >= (nsteprst+1))) THEN
106  WRITE (*, '(/A,G12.5, A,G12.5, A,F9.3,1X,A)')&
107  ' Time = ', time, ' Dt = ', 2.d0*dt
108  ELSE
109  WRITE (*, '(/A,G12.5, A,G12.5, A,F9.3,1X,A)') &
110  ' Time = ', time, ' Dt = ', dt
111  ENDIF
112  ENDIF
113  ENDIF ! if/else(steady_state)
114  ENDIF ! if(full_log)
115 
116  CALL calc_resid_mb(0, errorpercent)
117 
118 ! Calculate the face values of densities and mass fluxes for the first
119 ! solve_vel_star call.
120  CALL conv_rop()
121  CALL calc_mflux ()
122  CALL set_bc1
123  CALL set_ep_factors
124 
125 ! JFD: modification for cartesian grid implementation
127 
128 ! Default/Generic Error message
129  lmsg = 'Run diverged/stalled'
130 
131  RETURN
132  END SUBROUTINE iterate_init
133 
134 
135 !vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv!
136 ! !
137 ! Subroutine: ITERATE !
138 ! Author: M. Syamlal Date: 12-APR-96 !
139 ! !
140 ! Purpose: This module controls the iterations for solving equations !
141 ! !
142 !^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^!
143  SUBROUTINE do_iteration
145  USE cont, only: solve_continuity
146  USE cutcell, only: cartesian_grid
147  USE discretelement, only: discrete_element, des_continuum_hybrid
148  USE fldvar, only: ep_g, ro_g, rop_g, rop_s, p_star
149  USE geometry, only: cyclic, cylindrical
150  USE leqsol, only: leq_adjust
151  USE mms, only: use_mms
153  USE physprop, only: mmax, ro_g0, smax
154  USE pscor, only: k_cp, mcp
155  USE qmom_kinetic_equation, only: qmomk
156  USE residual, only: resid_p, resid
158  USE scalars, only: nscalar
159 
160  IMPLICIT NONE
161 
162  INTEGER :: M
163 
164  phip_out_iter=nit ! To record the output of phip
165 ! mechanism to set the normalization factor for the correction
166 ! after the first iteration to the corresponding residual found
167 ! in the first iteration
168  IF (.NOT.setg) THEN
169  IF (resg > small_number) THEN
170  normg = resg
171  setg = .true.
172  ENDIF
173  ENDIF
174  IF (.NOT.sets) THEN
175  IF (ress > small_number) THEN
176  norms = ress
177  sets = .true.
178  ENDIF
179  ENDIF
180 
181 ! Call user-defined subroutine to set quantities that need to be updated
182 ! every iteration
183  IF (call_usr) CALL usr2
184 
185 ! Calculate coefficients, excluding density and reactions.
186  CALL calc_coeff(ier, 1)
187  IF (ier_manager()) return
188 
189 ! Diffusion coefficient and source terms for user-defined scalars
190  IF(nscalar /= 0) CALL scalar_prop()
191 
192 ! Diffusion coefficient and source terms for K & Epsilon Eq.
193  IF(k_epsilon) CALL k_epsilon_prop()
194 
195 ! Update the stress tensor trace and cross terms each subiteration
196 ! for MMS cases.
197  IF(use_mms) CALL calc_trd_and_tau()
198 
199 ! Solve starred velocity components
200  CALL solve_vel_star(ier)
201 
202 ! Correct the centerline velocity for cylindrical simulations.
204 
205 ! Calculate densities.
206  CALL physical_prop(ier, 0)
207  IF (ier_manager()) return
208 
209 ! Calculate chemical reactions.
210  CALL calc_rrate(ier)
211 
212 ! Solve solids volume fraction correction equation for close-packed
213 ! solids phases
214  IF(.NOT.(discrete_element .OR. qmomk) .OR. &
215  des_continuum_hybrid) THEN
216  IF (mmax > 0) THEN
217 ! MMS: Solve gas continuity only.
218  IF(use_mms) THEN
219  CALL solve_continuity(0,ier)
220 ! Regular, non-MMS cases.
221  ELSE
222  IF(mmax == 1 .AND. mcp /= undefined_i)THEN
223 ! if second phase (m=1) can overpack (e.g., bubbles) then solve its
224 ! continuity equation
225  CALL calc_k_cp (k_cp)
226  CALL solve_epp (norms, ress, ier)
227  CALL correct_1 ()
228  ELSE
229 
230 ! If one chooses to revert back to old mark_phase_4_cor wherein the
231 ! continuity of the gas phase can get marked to be solved then this
232 ! loop should start at 0.
233  DO m=1,smax ! mmax -> smax for GHD theory
234 ! Volume fraction correction technique for one of the solids phase
235 ! is not implemented. This will only slow down convergence.
236 ! IF (M .EQ. MCP) THEN
237 ! CALL CALC_K_CP (K_CP, IER)
238 ! CALL SOLVE_EPP (NORMS, RESS, IER)
239 ! CALL CORRECT_1 (IER)
240 ! ELSE
241  CALL solve_continuity(m,ier)
242 ! ENDIF
243  ENDDO
244  ENDIF ! end if/else (mmax==1 .and. mcp /= undefined)
245  ENDIF ! end if/else (MMS)
246 
247  IF(kt_type_enum == ghd_2007) CALL adjust_eps_ghd
248 
250  IF (ier_manager()) return
251 
252  ENDIF ! endif (mmax >0)
253 
254  ENDIF ! end if (.not.discrete_element)
255 
256 
257 ! Calculate P_star in cells where solids continuity equation is
258 ! solved
259  IF(.NOT.(discrete_element .OR. qmomk) .OR. &
260  des_continuum_hybrid) THEN
261  IF (mmax > 0 .AND. .NOT.friction) &
262  CALL calc_p_star (ep_g, p_star)
263  ENDIF
264 
265 ! Calculate the face values of densities.
266  CALL conv_rop()
267 
268  IF (ro_g0 /= zero) THEN
269 ! Solve fluid pressure correction equation
270 #ifndef FLAG_MMS
271  CALL solve_pp_g (normg, resg, ier)
272 #endif
273 ! Correct pressure, velocities, and density
274  CALL correct_0 ()
275  ENDIF
276 
277 ! Recalculate densities.
278  CALL physical_prop(ier, 0)
279  IF (ier_manager()) return
280 
281 ! Update wall velocities:
282 ! modified by sof to force wall functions so even when NSW or FSW are
283 ! declared, default wall BC will still be treated as NSW and no wall
284 ! functions will be used
285  IF(.NOT. k_epsilon) CALL set_wall_bc ()
286 
287 ! Calculate the face values of mass fluxes
288  CALL calc_mflux ()
289  CALL set_bc1
290  CALL set_ep_factors
291 
292 ! JFD: modification for cartesian grid implementation
294 
295 ! Solve energy equations
296  IF (energy_eq) THEN
297  CALL solve_energy_eq (ier)
298  IF (ier_manager()) return
299  ENDIF
300 
301 ! Solve granular energy equation
302  IF (granular_energy) THEN
303  IF(.NOT.discrete_element .OR. des_continuum_hybrid) THEN
305  IF (ier_manager()) return
306  ENDIF
307  ENDIF
308 
309 ! Solve species mass balance equations.
310  CALL solve_species_eq (ier)
311  IF (ier_manager()) return
312 
313 ! Solve other scalar transport equations
314  IF(nscalar /= 0) CALL solve_scalar_eq (ier)
315 
316 ! Solve K & Epsilon transport equations
317  IF(k_epsilon) CALL solve_k_epsilon_eq (ier)
318 
319 ! User-defined linear equation solver parameters may be adjusted after
320 ! the first iteration
321  IF (.NOT.cyclic) leq_adjust = .true.
322 
323 ! Check for convergence
324  CALL accum_resid ! Accumulating residuals from all the processors
325  resg = resid(resid_p,0)
326  ress = resid(resid_p,1)
327  CALL calc_resid_mb(1, errorpercent)
328  mustit = 0
330 
331  IF(cyclic .AND. (mustit==0 .OR. nit >= max_nit)) &
332  CALL goalseekmassflux(nit, mustit, .true.)
333 
334 ! Display residuals
335  CALL display_resid (nit)
336 
337  CALL end_iteration
338 
339  contains
340 
341  SUBROUTINE end_iteration
342  IMPLICIT NONE
343 
344  ! Determine course of simulation: converge, non-converge, diverge?
345  IF (mustit == 0) THEN
346  IF (steady_state .AND. nit==1) RETURN !Iterations converged
347  converged = .true.
348  ier = 0
349  ELSEIF (mustit==2 .AND. .NOT.steady_state) THEN
350  diverged = .true.
351  ier = 1
352  ENDIF
353 
354  END SUBROUTINE end_iteration
355 
356 !----------------------------------------------------------------------!
357 ! Function: IER_Manager !
358 ! !
359 ! Purpose: Identify and account for errors from called subroutines. !
360 ! Returns .TRUE. for lErr >= 100, otherwise .FALSE. !
361 ! !
362 ! Reserved Error Blocks: !
363 ! !
364 ! [ 100, 109]: PHYSICAL_PROP !
365 ! [ 110, 119]: CALC_VOL_FR !
366 ! [ 120, 129]: SOLVE_ENERGY_EQ !
367 ! [ 130, 139]: SOLVE_SPECIES_EQ !
368 ! [ 140, 149]: SOLVE_GRANULAR_ENERGY !
369 ! !
370 !----------------------------------------------------------------------!
371  LOGICAL FUNCTION ier_manager()
373 ! Default case: do nothing.
374  IF(ier < 100) THEN
375  ier_manager = .false.
376  return
377  ENDIF
378 
379 ! Errors with an index greater than 100 will force an exit from iterate
380 ! and in turn, reduce the step-size, and restart the time-step.
381  ier_manager = .true.
382  mustit = 2
383 
384 ! Errors reported from PHYSICAL_PROP
385 !```````````````````````````````````````````````````````````````````````
386  IF(ier < 110) THEN
387  IF(ier == 100) THEN
388  lmsg = 'Negative gas density detected'
389  ELSEIF(ier == 101) THEN
390  lmsg = 'Negative solids density detected'
391  ELSE
392  lmsg = 'UCE in PHYSICAL_PROP'
393  ENDIF
394 
395 
396 ! Errors reported from CALC_VOL_FR
397 !```````````````````````````````````````````````````````````````````````
398  ELSEIF(ier < 120) THEN
399  IF(ier == 110) THEN
400  lmsg = 'Negative void fraction detected'
401  ELSE
402  lmsg = 'UCE in CALC_VOL_FR'
403  ENDIF
404 
405 
406 ! Errors reported from SOLVE_ENERGY_EQ
407 !```````````````````````````````````````````````````````````````````````
408  ELSEIF(ier < 130) THEN
409  IF(ier == 120) THEN
410  lmsg = 'Energy Equation diverged'
411  ELSE
412  lmsg = 'UCE in SOLVE_ENERGY_EQ'
413  ENDIF
414 
415 
416 ! Errors reported from SOLVE_SPECIES_EQ
417 !```````````````````````````````````````````````````````````````````````
418  ELSEIF(ier < 140) THEN
419  IF(ier == 130) THEN
420  lmsg = 'Species Equation diverged'
421  ELSE
422  lmsg = 'UCE in SOLVE_SPECIES_EQ'
423  ENDIF
424 
425 
426 ! Errors reported from SOLVE_GRANULAR_ENERGY
427 !```````````````````````````````````````````````````````````````````````
428  ELSEIF(ier < 150) THEN
429  IF(ier == 140) THEN
430  lmsg = 'Granular Energy Eq diverged'
431  ELSE
432  lmsg = 'UCE in SOLVE_GRANULAR_ENERGY'
433  ENDIF
434 
435 ! Unclassified Errors
436 !```````````````````````````````````````````````````````````````````````
437  ELSE
438  lmsg = 'Run diverged/stalled with UCE'
439  ENDIF
440 
441 
442  IF(steady_state) ier_manager = .false.
443 
444  CALL end_iteration
445 
446  return
447  END FUNCTION ier_manager
448 
449  END SUBROUTINE do_iteration
450 
451 
452 !vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv!
453 ! !
454 ! Subroutine: ITERATE !
455 ! Author: M. Syamlal Date: 12-APR-96 !
456 ! !
457 ! Purpose: This module controls the iterations for solving equations !
458 ! !
459 !^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^!
460  SUBROUTINE post_iterate
462  USE compar, only: mype, pe_io
463  USE funits, only: dmp_log, unit_log, unit_out
464  USE machine, only: start_log, end_log
465  USE run, only: dt, time
466 
467  IMPLICIT NONE
468 
469  IF (converged) THEN
470  CALL log_converged
471  ELSEIF (diverged) THEN
472  CALL log_diverged
473  ELSE
474  CALL get_smass (smass)
475  IF (mype.eq.pe_io) WRITE(unit_out, 5100) time, dt, nit, smass
476  CALL start_log
477  IF(dmp_log) WRITE(unit_log, 5100) time, dt, nit, smass
478  CALL end_log
479  ENDIF
480 
481  IF(.NOT.(converged .OR. diverged)) THEN
482  ier = 1
483  ENDIF
484 
485 5100 FORMAT(1x,'t=',f11.4,' Dt=',g11.4,' NIT>',i3,' Sm= ',g12.5, &
486  'MbErr%=', g11.4)
487 
488  END SUBROUTINE post_iterate
489 
490 !vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv!
491 ! !
492 ! Subroutine: ITERATE !
493 ! Author: M. Syamlal Date: 12-APR-96 !
494 ! !
495 ! Purpose: This module controls the iterations for solving equations !
496 ! !
497 !^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^!
498  SUBROUTINE log_diverged
499  USE compar, only: mype, pe_io
501  USE funits, only: dmp_log, unit_log
502  USE machine, only: start_log, end_log
503  USE output, only: full_log
504  USE run, only: dt, time, tstop, get_tunit
505  USE time_cpu, only: cpuos
506 
507  IMPLICIT NONE
508 
509  CHARACTER(LEN=4) :: TUNIT
510 
511  IF (full_log) THEN
512  CALL start_log
513  CALL calc_resid_mb(1, errorpercent)
514 
515  IF(dmp_log) WRITE(unit_log,5200) time, dt, nit, &
516  errorpercent(0), trim(adjustl(lmsg))
517  CALL end_log
518 
519  IF (mype.EQ.pe_io) WRITE(*,5200) time, dt, nit, &
520  errorpercent(0), trim(adjustl(lmsg))
521  ENDIF
522 
523  ! JFD: modification for cartesian grid implementation
524  IF(write_dashboard) THEN
525  run_status = 'Diverged/stalled...'
527  IF(mod(n_dashboard,f_dashboard)==0) THEN
528  tleft = (tstop - time)*cpuos
529  CALL get_tunit (tleft, tunit)
530  CALL update_dashboard(nit,tleft,tunit)
531  ENDIF
532  ENDIF
533 5200 FORMAT(1x,'t=',f11.4,' Dt=',g11.4,' NIT=',&
534  i3,'MbErr%=', g11.4, ': ',a,' :-(')
535  END SUBROUTINE log_diverged
536 
537 !vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv!
538 ! !
539 ! Subroutine: ITERATE !
540 ! Author: M. Syamlal Date: 12-APR-96 !
541 ! !
542 ! Purpose: This module controls the iterations for solving equations !
543 ! !
544 !^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^!
545  SUBROUTINE log_converged
547  USE compar, only: mype, pe_io
549  USE error_manager, only: err_msg
550  USE funits, only: dmp_log, unit_log
551  USE geometry, only: cyclic_x, cyclic_y, cyclic_z
552  USE geometry, only: do_i, do_j, do_k
553  USE machine, only: start_log, end_log
554  USE output, only: full_log, nlog
555  USE physprop, only: mmax, smax
556  USE run, only: dt, energy_eq, time, tstop, nstep, get_tunit
557  USE time_cpu, only: cpu0, cpu_nlog, cpuos, time_nlog
558 
559  IMPLICIT NONE
560 
561  CHARACTER(LEN=4) :: TUNIT
562 ! Perform checks and dump to screen every NLOG time steps
563  IF (mod(nstep,nlog) == 0) CALL dump_to_screen
564 
565 ! JFD: modification for cartesian grid implementation
566  IF(write_dashboard) THEN
567  run_status = 'In Progress...'
569  IF(mod(n_dashboard,f_dashboard)==0) THEN
570  tleft = (tstop - time)*cpuos
571  CALL get_tunit (tleft, tunit)
572  CALL update_dashboard(nit,tleft,tunit)
573  ENDIF
574  ENDIF
575 
576  CONTAINS
577 
578  SUBROUTINE dump_to_screen
580  IMPLICIT NONE
581 
582  ! phase index
583  INTEGER :: M
584 ! current cpu time used
585  DOUBLE PRECISION :: CPU_NOW
586 ! Heat loss from the reactor
587  DOUBLE PRECISION :: HLOSS
588 ! average velocity
589  DOUBLE PRECISION :: Vavg
590 
591 !-----------------------------------------------
592 ! External functions
593 !-----------------------------------------------
594  DOUBLE PRECISION, EXTERNAL :: VAVG_U_G, VAVG_V_G, VAVG_W_G, &
595  VAVG_U_S, VAVG_V_S, VAVG_W_S
596 
597  CALL cpu_time (cpu_now)
598  cpuos = (cpu_now - cpu_nlog)/(time - time_nlog)
599  cpu_nlog = cpu_now
600  time_nlog = time
601  cpu_now = cpu_now - cpu0
602 
603  CALL calc_resid_mb(1, errorpercent)
604  CALL get_smass (smass)
605  IF (energy_eq) CALL get_hloss (hloss)
606 
607  CALL start_log
608  IF (energy_eq) THEN
609  WRITE(err_msg,5000)time, dt, nit, smass, hloss, cpu_now
610  CALL flush_err_msg(header=.false., footer=.false.)
611  ELSE
612  WRITE(err_msg,5001) time, dt, nit, smass, cpu_now
613  CALL flush_err_msg(header=.false., footer=.false.)
614  ENDIF
615 
616  5000 FORMAT(1x,'t=',f11.4,' Dt=',g11.4,' NIT=',i3,' Sm=',g12.5, &
617  ' Hl=',g12.5,t84,'CPU=',f8.0,' s')
618 
619  5001 FORMAT(1x,'t=',f11.4,' Dt=',g11.4,' NIT=',i3,' Sm=',g12.5, &
620  t84,'CPU=',f8.0,' s')
621 
622  IF(dmp_log)WRITE (unit_log, 5002) (errorpercent(m), m=0,mmax)
623  IF (full_log .and. mype.eq.pe_io) &
624  WRITE (*, 5002) (errorpercent(m), m=0,mmax)
625 
626  5002 FORMAT(3x,'MbError%(0,MMAX):', 5(1x,g11.4))
627 
628  IF (.NOT.full_log) THEN
629  tleft = (tstop - time)*cpuos
630  CALL get_tunit (tleft, tunit)
631  IF(dmp_log)WRITE (unit_log, '(46X,A,F9.3,1X,A)')
632  ENDIF
633 
634  IF (cyclic_x .OR. cyclic_y .OR. cyclic_z) THEN
635  IF (do_i) THEN
636  vavg = vavg_u_g()
637  IF(dmp_log)WRITE (unit_log, 5050) 'U_g = ', vavg
638  ENDIF
639  IF (do_j) THEN
640  vavg = vavg_v_g()
641  IF(dmp_log)WRITE (unit_log, 5050) 'V_g = ', vavg
642  ENDIF
643  IF (do_k) THEN
644  vavg = vavg_w_g()
645  IF(dmp_log)WRITE (unit_log, 5050) 'W_g = ', vavg
646  ENDIF
647  DO m = 1, smax
648  IF (do_i) Then
649  vavg = vavg_u_s(m)
650  IF(dmp_log)WRITE (unit_log, 5060) 'U_s(', m, ') = ', vavg
651  ENDIF
652  IF (do_j) Then
653  vavg = vavg_v_s(m)
654  IF(dmp_log)WRITE (unit_log, 5060) 'V_s(', m, ') = ', vavg
655  ENDIF
656  IF (do_k) Then
657  vavg = vavg_w_s(m)
658  IF(dmp_log)WRITE (unit_log, 5060) 'W_s(', m, ') = ', vavg
659  ENDIF
660  ENDDO
661  ENDIF ! end if cyclic_x, cyclic_y or cyclic_z
662 
663  CALL end_log
664 
665 5050 FORMAT(5x,'Average ',a,g12.5)
666 5060 FORMAT(5x,'Average ',a,i2,a,g12.5)
667 
668  END SUBROUTINE dump_to_screen
669 
670  END SUBROUTINE log_converged
671 
672 !vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv!
673 ! !
674 ! Subroutine: GoalSeekMassFlux !
675 ! Author: M. Syamlal Date: 12-APR-96 !
676 ! !
677 ! Purpose: In the following subroutine the mass flux across a periodic!
678 ! domain with pressure drop is held constant at a user-specified value.!
679 ! This module is activated only if the user specifies a value for the !
680 ! keyword flux_g in the mfix.dat file. !
681 !^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^!
682  SUBROUTINE goalseekmassflux(NIT, MUSTIT, doit)
684 !-----------------------------------------------
685 ! Modules
686 !-----------------------------------------------
687  USE bc
688  USE compar
689  USE constant
690  USE exit, only: mfix_exit
691  USE geometry
692  USE param1, only: one
693  USE run
694  USE time_cpu
695  USE utilities, ONLY: mfix_isnan
696  IMPLICIT NONE
697 !-----------------------------------------------
698 ! Dummy arguments
699 !-----------------------------------------------
700  INTEGER, INTENT(INOUT) :: NIT, MUSTIT
701  LOGICAL, INTENT(IN) :: doit
702 !-----------------------------------------------
703 ! Local Variables
704 !-----------------------------------------------
705  INTEGER, PARAMETER :: MAXOUTIT = 500
706  DOUBLE PRECISION, PARAMETER :: omega = 0.9
707  DOUBLE PRECISION, PARAMETER :: TOL = 1e-03
708  INTEGER, SAVE :: OUTIT
709  LOGICAL, SAVE :: firstPass = .true.
710 
711  DOUBLE PRECISION, SAVE :: mdot_n, mdot_nm1, delp_n, delp_nm1, err
712  DOUBLE PRECISION :: mdot_0, delp_xyz
713 
714 !-----------------------------------------------
715 ! Functions
716 !-----------------------------------------------
717  DOUBLE PRECISION, EXTERNAL :: VAVG_Flux_U_G, VAVG_Flux_V_G, &
718  VAVG_Flux_W_G
719 !-----------------------------------------------
720 
721  IF(cyclic_x_mf)THEN
722  delp_n = delp_x
723  ELSEIF(cyclic_y_mf)THEN
724  delp_n = delp_y
725  ELSEIF(cyclic_z_mf)THEN
726  delp_n = delp_z
727  ELSE
728  RETURN
729  ENDIF
730 
731  IF(.NOT.doit) THEN
732  outit = 0
733  RETURN
734  ENDIF
735 
736  outit = outit + 1
737  IF(outit > maxoutit) THEN
738  IF (mype.EQ.pe_io) write(*,5400) maxoutit
739  CALL mfix_exit(0)
740  ENDIF
741 
742  mdot_0 = flux_g
743 
744 
745  ! calculate the average gas mass flux and error
746  IF(cyclic_x_mf)THEN
747  mdot_n = vavg_flux_u_g()
748  ELSEIF(cyclic_y_mf)THEN
749  mdot_n = vavg_flux_v_g()
750  ELSEIF(cyclic_z_mf)THEN
751  mdot_n = vavg_flux_w_g()
752  ENDIF
753 
754  IF (mfix_isnan(mdot_n) .OR. mfix_isnan(delp_n)) THEN
755  IF (mype.eq.pe_io) write(*,*) mdot_n, delp_n, &
756  ' NaN being caught in GoalSeekMassFlux '
757  RETURN
758  ENDIF
759 
760  err = abs((mdot_n - mdot_0)/mdot_0)
761  IF( err < tol) THEN
762  mustit = 0
763  ELSE
764  mustit = 1
765  nit = 1
766  ENDIF
767 
768 ! correct delp
769  if(.not.firstpass)then
770 ! delp_xyz = delp_n - omega * (delp_n - delp_nm1) * (mdot_n - mdot_0) &
771 ! / (mdot_n - mdot_nm1)
772 ! Fail-Safe Newton's method (below) works better than the regular
773 ! Newton method (above)
774 
775  delp_xyz = delp_n - omega * (delp_n - delp_nm1) * &
776  ((mdot_n - mdot_0)/(mdot_nm1 - mdot_0)) / &
777  ((mdot_n - mdot_0)/(mdot_nm1 - mdot_0) - one)
778  else
779  firstpass=.false.
780  delp_xyz = delp_n*0.99
781  endif
782 
783  IF(mustit == 0) then
784  IF(mype.eq.pe_io) Write(*,5500) time, outit, delp_xyz, mdot_n
785  ENDIF
786 
787  mdot_nm1 = mdot_n
788  delp_nm1 = delp_n
789 
790  IF(cyclic_x_mf)THEN
791  delp_x = delp_xyz
792  ELSEIF(cyclic_y_mf)THEN
793  delp_y = delp_xyz
794  ELSEIF(cyclic_z_mf)THEN
795  delp_z = delp_xyz
796  ENDIF
797 
798 
799  RETURN
800 
801 5400 FORMAT(/1x,70('*')//' From: GoalSeekMassFlux',/&
802  ' Message: Number of outer iterations exceeded ', i4,/1x,70('*')/)
803 5500 Format(' Time=', g12.5, ' MassFluxIterations=', i4, ' DelP=', &
804  g12.5, ' Gas Flux=', g12.5)
805 
806  END SUBROUTINE goalseekmassflux
807 
808 !vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv!
809 ! !
810 ! Module name: ADJUST_DT() !
811 ! Author: M. Syamlal Date: FEB-10-97 !
812 ! !
813 ! Purpose: Automatically adjust time step. !
814 ! !
815 !^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^!
816  LOGICAL FUNCTION adjustdt()
818 ! Global Variables:
819 !---------------------------------------------------------------------//
820 ! User defined type of run: new or restart
821  use run, only: run_type
822 ! Integer flag: 0=Good, 100=initialize, otherwise bad.
823  use run, only: ier
824 ! User defined: min, max DT and adjustment factor
825  use run, only: dt_min, dt_max, dt_fac
826 ! Flag: Use stored DT value for advancing TIME
827  use run, only: use_dt_prev
828 ! Flag: 2nd order time implementation
829  use run, only: cn_on
830 ! Flag: Continue to run at DT_MIN
831  use run, only: persistent_mode
832 ! The current number of time steps (value at restart).
833  use run, only: nstep, nsteprst
834 ! Current DT (1/DT) and direction of last change (+/-)
835  use run, only: dt, odt, dt_dir, steady_state
836 
837 ! Global Parameters:
838 !---------------------------------------------------------------------//
839  use param1, only: zero, one, undefined
840 
841 ! Module procedures:
842 !---------------------------------------------------------------------//
843  use error_manager
844 
845  IMPLICIT NONE
846 
847 ! Dummy Arguments:
848 
849 ! Local Variables:
850 !---------------------------------------------------------------------//
851 ! Number of steps in between DT adjustments.
852  INTEGER, PARAMETER :: STEPS_MIN = 5
853 ! Number of time steps since last DT adjustment
854  INTEGER, SAVE :: STEPS_TOT=0
855 ! number of iterations since last DT adjustment
856  INTEGER, SAVE :: NIT_TOT=0
857 ! Iterations per second for last dt
858  DOUBLE PRECISION, SAVE :: NIToS=0.0
859 ! Current number of iterations per second
860  DOUBLE PRECISION :: NITOS_NEW
861 ! Flag to half/double the current time step
862  LOGICAL :: CN_ADJUST_DT
863 !......................................................................!
864 
865 ! Initialize the function result.
866  adjustdt = .false.
867  use_dt_prev = .false.
868 
869 ! Steady-state simulation.
870  IF (steady_state .OR. dt<zero) RETURN
871 
872 ! Local flag for adjusting the time step for CN implementation.
873  cn_adjust_dt = cn_on .AND. ((run_type=='NEW' .AND. nstep>1) .OR. &
874  (run_type/='NEW' .AND. nstep >= (nsteprst+1)))
875 
876 ! Iterate successfully converged.
877 !---------------------------------------------------------------------//
878  IF(ier == 0) THEN
879 
880 ! Set back the timestep to original size which was halved previously for
881 ! 2nd order accurate time implementation.
882  IF(cn_adjust_dt) dt = 2.0d0*dt
883 
884 ! Calculate a new DT every STEPS_MIN time steps.
885  IF(steps_tot >= steps_min) THEN
886  nitos_new = dble(nit_tot)/(steps_tot*dt)
887  IF (nitos_new > nitos) dt_dir = dt_dir*(-1)
888  steps_tot = 0
889  nitos = nitos_new
890  nit_tot = 0
891  IF (dt_dir > 0) THEN
892  IF(nit < max_nit) dt = min(dt_max,dt/dt_fac)
893  ELSE
894  dt = dt*dt_fac
895  IF(persistent_mode) dt = max(dt, dt_min)
896  ENDIF
897 
898 ! DT was modified. Use the stored DT should be used to update TIME.
899  use_dt_prev = .true.
900 
901 ! Write the convergence stats to the screen/log file.
902  WRITE(err_msg,"('DT=',g11.4,3x,'NIT/s=',A)") &
903  dt, trim(ival(nint(nitos)))
904  CALL flush_err_msg(header=.false., &
905  footer=.false., log=.false.)
906 
907  ELSE
908  steps_tot = steps_tot + 1
909  nit_tot = nit_tot + nit
910  ENDIF
911 ! No need to iterate again
912  adjustdt = .false.
913 ! Cut the timestep into half for 2nd order accurate time implementation.
914  IF(cn_adjust_dt) dt = 0.5d0*dt
915 
916 ! Iterate failed to converge.
917 !---------------------------------------------------------------------//
918  ELSE
919 
920 ! Clear the error flag.
921  ier = 0
922 
923 ! Reset the timestep to original size which was halved previously for
924 ! 2nd order accurate time implementation.
925  IF(cn_adjust_dt) dt = 2.0d0*dt
926 
927 ! Reset counters.
928  dt_dir = -1
929  steps_tot = 0
930  nitos = 0.
931  nit_tot = 0
932 
933 ! Reduce the step size.
934  dt = dt*dt_fac
935 
936 ! The step size has decreased to the minimum.
937  IF (dt_fac >= one) THEN
938 
939  IF(persistent_mode) THEN
940  adjustdt = .false.
941  ELSE
942  WRITE(err_msg,"(3X,A)") &
943  'DT_FAC >= 1. Recovery not possible!'
944  CALL flush_err_msg(abort=.true., &
945  header=.false., footer=.false.)
946  ENDIF
947 
948  ELSEIF (dt > dt_min) THEN
949 
950  WRITE(err_msg,"(3X,'Recovered: Dt=',G12.5,' :-)')") dt
951  CALL flush_err_msg(header=.false., footer=.false.)
952 
953  CALL reset_new
954 
955 ! Iterate again with new dt
956  adjustdt = .true.
957 
958 ! Cut the timestep for 2nd order accurate time implementation.
959  IF(cn_adjust_dt) dt = 0.5d0*dt
960 
961 ! Set the return flag stop iterating.
962  ELSE
963 
964 ! Prevent DT from dropping below DT_MIN.
965  IF(persistent_mode) dt = max(dt, dt_min)
966  adjustdt = .false.
967  ENDIF
968 
969  ENDIF
970 
971 ! Update ONE/DT variable.
972  odt = one/dt
973 
974  RETURN
975  END FUNCTION adjustdt
976 
977  END MODULE iterate
subroutine calc_k_cp(Kcp)
Definition: calc_k_cp.f:26
logical write_dashboard
Definition: dashboard_mod.f:3
subroutine calc_resid_mb(INIT, ErrorPercent)
Definition: calc_resid.f:550
character(len=32) lmsg
Definition: iterate.f:31
double precision norm_s
Definition: toleranc_mod.f:78
integer n_dashboard
Definition: dashboard_mod.f:4
double precision time_nlog
Definition: time_cpu_mod.f:6
logical dmp_log
Definition: funits_mod.f:6
subroutine calc_rrate(IER)
Definition: calc_coeff.f:142
logical steady_state
Definition: run_mod.f:57
subroutine solve_vel_star(IER)
double precision, dimension(:), allocatable ep_g
Definition: fldvar_mod.f:15
double precision dt_prev
Definition: run_mod.f:230
logical leq_adjust
Definition: leqsol_mod.f:8
subroutine update_dashboard(NIT, TLEFT, TUNIT)
integer f_dashboard
Definition: dashboard_mod.f:4
subroutine log_converged
Definition: iterate.f:546
double precision dt_fac
Definition: run_mod.f:226
subroutine k_epsilon_prop()
logical sets
Definition: iterate.f:24
double precision, parameter one
Definition: param1_mod.f:29
integer, parameter unit_out
Definition: funits_mod.f:18
integer, parameter resid_p
Definition: residual_mod.f:10
logical use_dt_prev
Definition: run_mod.f:234
subroutine solve_scalar_eq(IER)
integer dt_dir
Definition: run_mod.f:217
double precision delp_z
Definition: bc_mod.f:278
subroutine solve_epp(NORMS, RESS, IER)
Definition: solve_epp.f:13
double precision cpu_nlog
Definition: time_cpu_mod.f:6
subroutine solve_granular_energy(IER)
logical cyclic_z_mf
Definition: geometry_mod.f:165
subroutine set_wall_bc()
Definition: set_wall_bc.f:32
logical friction
Definition: run_mod.f:149
double precision delp_x
Definition: bc_mod.f:272
subroutine accum_resid
Definition: accum_resid.f:22
subroutine calc_mflux()
Definition: calc_mflux.f:11
double precision dt
Definition: run_mod.f:51
logical automatic_restart
Definition: run_mod.f:36
logical cyclic_z
Definition: geometry_mod.f:153
subroutine adjust_eps_ghd
double precision tleft
Definition: iterate.f:20
logical full_log
Definition: output_mod.f:31
double precision, parameter undefined
Definition: param1_mod.f:18
subroutine get_hloss(HLOSS)
Definition: get_hloss.f:25
double precision cpuos
Definition: time_cpu_mod.f:4
logical cn_on
Definition: run_mod.f:109
integer nlog
Definition: output_mod.f:29
double precision, dimension(:), allocatable errorpercent
Definition: iterate.f:29
integer nit
Definition: iterate.f:12
integer phip_out_iter
Definition: run_mod.f:172
logical chk_batchq_end
Definition: run_mod.f:190
integer pe_io
Definition: compar_mod.f:30
integer ier
Definition: run_mod.f:265
subroutine scalar_prop()
Definition: scalar_prop.f:21
double precision dt_max
Definition: run_mod.f:220
logical function adjustdt()
Definition: iterate.f:817
double precision normg
Definition: iterate.f:22
subroutine correct_0()
Definition: correct_0.f:18
subroutine mfix_exit(myID, normal_termination)
Definition: exit.f:5
integer mmax
Definition: physprop_mod.f:19
subroutine physical_prop(IER, LEVEL)
Definition: physical_prop.f:21
subroutine calc_coeff(IER, pLevel)
Definition: calc_coeff.f:99
double precision ro_g0
Definition: physprop_mod.f:59
double precision smass
Definition: iterate.f:28
double precision, parameter small_number
Definition: param1_mod.f:24
character(len=40) run_status
Definition: dashboard_mod.f:8
Definition: exit.f:2
subroutine usr2
Definition: usr2.f:30
logical cyclic_y
Definition: geometry_mod.f:151
double precision tstop
Definition: run_mod.f:48
subroutine solve_pp_g(NORMG, RESG, IER)
Definition: solve_pp_g.f:11
character(len=16) run_type
Definition: run_mod.f:33
subroutine dump_to_screen
Definition: iterate.f:579
subroutine calc_vol_fr(P_STAR, RO_G, ROP_G, EP_G, ROP_S, IER)
Definition: calc_vol_fr.f:19
logical persistent_mode
Definition: run_mod.f:124
subroutine do_iteration
Definition: iterate.f:144
subroutine end_iteration
Definition: iterate.f:342
subroutine get_smass(SMASS)
Definition: get_smass.f:25
double precision odt
Definition: run_mod.f:54
Definition: mms_mod.f:12
subroutine check_convergence(NIT, errorpercent, MUSTIT)
subroutine conv_rop()
Definition: conv_rop.f:12
subroutine solve_energy_eq(IER)
integer mustit
Definition: iterate.f:9
subroutine set_bc1
Definition: set_bc1.f:10
logical do_j
Definition: geometry_mod.f:26
character(len=4) tunit
Definition: run_mod.f:268
Definition: pscor_mod.f:1
logical cyclic_y_mf
Definition: geometry_mod.f:163
logical call_dqmom
Definition: run_mod.f:127
integer, parameter unit_log
Definition: funits_mod.f:21
Definition: run_mod.f:13
subroutine calc_trd_and_tau()
Definition: calc_coeff.f:204
double precision resg
Definition: iterate.f:26
logical cyclic_x
Definition: geometry_mod.f:149
double precision cpu0
Definition: time_cpu_mod.f:8
logical cyclic_x_mf
Definition: geometry_mod.f:161
integer mcp
Definition: pscor_mod.f:38
subroutine display_resid(NIT)
Definition: display_resid.f:10
logical cartesian_grid
Definition: cutcell_mod.f:13
subroutine post_iterate
Definition: iterate.f:461
logical diverged
Definition: iterate.f:17
integer nsteprst
Definition: run_mod.f:64
logical do_k
Definition: geometry_mod.f:30
logical k_epsilon
Definition: run_mod.f:97
integer mype
Definition: compar_mod.f:24
double precision, dimension(:), allocatable p_star
Definition: fldvar_mod.f:142
logical cylindrical
Definition: geometry_mod.f:168
logical function ier_manager()
Definition: iterate.f:372
integer nstep
Definition: run_mod.f:60
logical energy_eq
Definition: run_mod.f:100
subroutine set_ep_factors
Definition: calc_vol_fr.f:231
logical use_mms
Definition: mms_mod.f:15
integer, parameter undefined_i
Definition: param1_mod.f:19
character(len=line_length), dimension(line_count) err_msg
Definition: iterate.f:2
subroutine log_diverged
Definition: iterate.f:499
integer nscalar
Definition: scalars_mod.f:7
subroutine goalseekmassflux(NIT, MUSTIT, doit)
Definition: iterate.f:683
subroutine start_log
Definition: machine_mod.f:182
logical cyclic
Definition: geometry_mod.f:147
double precision delp_y
Definition: bc_mod.f:275
logical function mfix_isnan(x)
Definition: utilities_mod.f:14
double precision flux_g
Definition: bc_mod.f:283
integer max_nit
Definition: iterate.f:15
subroutine radial_vel_correction
double precision dt_min
Definition: run_mod.f:223
logical do_i
Definition: geometry_mod.f:22
subroutine calc_p_star(EP_G, P_STAR)
Definition: calc_p_star.f:27
subroutine solve_species_eq(IER)
double precision, dimension(:,:), allocatable rop_s
Definition: fldvar_mod.f:51
integer smax
Definition: physprop_mod.f:22
double precision, dimension(:), allocatable k_cp
Definition: pscor_mod.f:22
logical setg
Definition: iterate.f:24
logical converged
Definition: iterate.f:17
subroutine reset_new
Definition: reset_new.f:21
double precision, dimension(:,:), allocatable resid
Definition: residual_mod.f:37
subroutine solve_continuity(M, IER)
subroutine correct_1()
Definition: correct_1.f:31
subroutine cg_set_outflow
logical auto_restart
Definition: run_mod.f:205
double precision time
Definition: run_mod.f:45
logical granular_energy
Definition: run_mod.f:112
double precision, dimension(:), allocatable ro_g
Definition: fldvar_mod.f:32
subroutine iterate_init
Definition: iterate.f:44
double precision, dimension(:), allocatable rop_g
Definition: fldvar_mod.f:38
double precision ress
Definition: iterate.f:26
subroutine get_tunit(TLEFT, TUNIT)
Definition: run_mod.f:277
double precision norm_g
Definition: toleranc_mod.f:75
subroutine solve_k_epsilon_eq(IER)
double precision, dimension(:), allocatable x
Definition: geometry_mod.f:129
double precision, parameter zero
Definition: param1_mod.f:27
subroutine end_log
Definition: machine_mod.f:208
subroutine flush_err_msg(DEBUG, HEADER, FOOTER, ABORT, LOG, CALL_TREE)
Definition: bc_mod.f:23
double precision norms
Definition: iterate.f:22
logical call_usr
Definition: run_mod.f:121
subroutine init_resid()
Definition: init_resid.f:21