File: RELATIVE:/../../../mfix.git/model/iterate.f
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32 SUBROUTINE ITERATE(IER, NIT)
33
34
35
36
37 USE compar
38 USE cont
39 USE cutcell
40 USE dashboard
41 USE discretelement
42 USE fldvar
43 USE funits
44 USE geometry
45 USE indices
46 USE leqsol
47 USE machine, only: start_log, end_log
48 USE mms, only: USE_MMS
49 USE mpi_utility
50 USE output
51 USE param
52 USE param1
53 USE pgcor
54 USE physprop
55 USE pscor
56 USE qmom_kinetic_equation
57 USE residual
58 USE run
59 USE scalars
60 USE time_cpu
61 USE toleranc
62 USE visc_g
63 USE vtk
64 USE interactive, only: CHECK_INTERACT_ITER
65
66 use error_manager
67
68 IMPLICIT NONE
69
70
71
72
73 INTEGER, INTENT(INOUT) :: IER
74
75 INTEGER, INTENT(OUT) :: NIT
76
77
78
79
80 DOUBLE PRECISION :: CPU_NOW
81
82 DOUBLE PRECISION :: TLEFT
83
84
85 INTEGER :: MUSTIT
86
87 DOUBLE PRECISION :: NORMg, NORMs
88
89 LOGICAL :: SETg, SETs
90
91 DOUBLE PRECISION :: RESg, RESs
92
93 DOUBLE PRECISION :: SMASS
94
95 DOUBLE PRECISION :: HLOSS
96
97 INTEGER :: M
98
99 DOUBLE PRECISION :: Vavg
100 DOUBLE PRECISION :: errorpercent(0:MMAX)
101 CHARACTER(LEN=4) :: TUNIT
102
103
104 CHARACTER(LEN=32) :: lMsg
105
106
107
108
109 DOUBLE PRECISION, EXTERNAL :: VAVG_U_G, VAVG_V_G, VAVG_W_G, &
110 VAVG_U_S, VAVG_V_S, VAVG_W_S
111
112
113
114
115
116
117
118 = DT
119 NIT = 0
120 MUSTIT = 0
121 RESG = ZERO
122 RESS = ZERO
123
124 IF (NORM_G == UNDEFINED) THEN
125 NORMG = ONE
126 SETG = .FALSE.
127 ELSE
128 NORMG = NORM_G
129 SETG = .TRUE.
130 ENDIF
131
132 IF (NORM_S == UNDEFINED) THEN
133 NORMS = ONE
134 SETS = .FALSE.
135 ELSE
136 NORMS = NORM_S
137 SETS = .TRUE.
138 ENDIF
139
140 LEQ_ADJUST = .FALSE.
141
142
143
144 CALL INIT_RESID ()
145
146
147
148 IF(CYCLIC) CALL GoalSeekMassFlux(NIT, MUSTIT, .false.)
149
150
151 IF (FULL_LOG) THEN
152 TLEFT = (TSTOP - TIME)*CPUOS
153 CALL GET_TUNIT (TLEFT, TUNIT)
154
155 IF (DT == UNDEFINED) THEN
156 CALL GET_SMASS (SMASS)
157 IF(myPE.eq.PE_IO) THEN
158 WRITE (*, '(/A,G12.5, A,F9.3,1X,A)') &
159 ' Starting solids mass = ', SMASS
160 ENDIF
161 ELSE
162 IF(myPE.eq.PE_IO) THEN
163 IF ((CN_ON.AND.NSTEP>1.AND.RUN_TYPE == 'NEW') .OR. &
164 (CN_ON.AND.RUN_TYPE /= 'NEW' .AND.&
165 NSTEP >= (NSTEPRST+1))) THEN
166 WRITE (*, '(/A,G12.5, A,G12.5, A,F9.3,1X,A)')&
167 ' Time = ', TIME, ' Dt = ', 2.D0*DT
168 ELSE
169 WRITE (*, '(/A,G12.5, A,G12.5, A,F9.3,1X,A)') &
170 ' Time = ', TIME, ' Dt = ', DT
171 ENDIF
172 ENDIF
173 ENDIF
174 ENDIF
175
176 CALL CALC_RESID_MB(0, errorpercent)
177
178
179
180 CALL CONV_ROP()
181 CALL CALC_MFLUX ()
182 CALL SET_BC1
183 CALL SET_EP_FACTORS
184
185
186 IF(CARTESIAN_GRID) CALL CG_SET_OUTFLOW
187
188
189 = 'Run diverged/stalled'
190
191
192
193 CONTINUE
194 MUSTIT = 0
195 NIT = NIT + 1
196 PHIP_OUT_ITER=NIT
197
198
199
200 IF (.NOT.SETG) THEN
201 IF (RESG > SMALL_NUMBER) THEN
202 NORMG = RESG
203 SETG = .TRUE.
204 ENDIF
205 ENDIF
206 IF (.NOT.SETS) THEN
207 IF (RESS > SMALL_NUMBER) THEN
208 NORMS = RESS
209 SETS = .TRUE.
210 ENDIF
211 ENDIF
212
213
214
215 IF (CALL_USR) CALL USR2
216
217
218 CALL CALC_COEFF(IER, 1)
219 IF (IER_MANAGER()) goto 1000
220
221
222 IF(NScalar /= 0) CALL SCALAR_PROP()
223
224
225 IF(K_Epsilon) CALL K_Epsilon_PROP()
226
227
228
229 IF(USE_MMS) CALL CALC_TRD_AND_TAU()
230
231
232 CALL SOLVE_VEL_STAR(IER)
233
234
235 IF(CYLINDRICAL) CALL RADIAL_VEL_CORRECTION
236
237
238 CALL PHYSICAL_PROP(IER, 0)
239 IF (IER_MANAGER()) goto 1000
240
241
242 CALL CALC_RRATE(IER)
243
244
245
246 IF(.NOT.(DISCRETE_ELEMENT .OR. QMOMK) .OR. &
247 DES_CONTINUUM_HYBRID) THEN
248 IF (MMAX > 0) THEN
249
250 IF(USE_MMS) THEN
251 CALL SOLVE_CONTINUITY(0,IER)
252
253 ELSE
254 IF(MMAX == 1 .AND. MCP /= UNDEFINED_I)THEN
255
256
257 CALL CALC_K_CP (K_CP)
258 CALL SOLVE_EPP (NORMS, RESS, IER)
259 CALL CORRECT_1 ()
260 ELSE
261
262
263
264
265 DO M=1,SMAX
266
267
268
269
270
271
272
273 CALL SOLVE_CONTINUITY(M,IER)
274
275 ENDDO
276 ENDIF
277 ENDIF
278
279 IF(KT_TYPE_ENUM == GHD_2007) CALL ADJUST_EPS_GHD
280
281 CALL CALC_VOL_FR (P_STAR, RO_G, ROP_G, EP_G, ROP_S, IER)
282 IF (IER_MANAGER()) goto 1000
283
284 ENDIF
285
286 ENDIF
287
288
289
290
291 IF(.NOT.(DISCRETE_ELEMENT .OR. QMOMK) .OR. &
292 DES_CONTINUUM_HYBRID) THEN
293 IF (MMAX > 0 .AND. .NOT.FRICTION) &
294 CALL CALC_P_STAR (EP_G, P_STAR)
295 ENDIF
296
297
298 CALL CONV_ROP()
299
300 IF (RO_G0 /= ZERO) THEN
301
302 CALL SOLVE_PP_G (NORMG, RESG, IER)
303
304 CALL CORRECT_0 ()
305 ENDIF
306
307
308 CALL PHYSICAL_PROP(IER, 0)
309 IF (IER_MANAGER()) goto 1000
310
311
312
313
314
315 IF(.NOT. K_EPSILON) CALL SET_WALL_BC ()
316
317
318 CALL CALC_MFLUX ()
319 CALL SET_BC1
320 CALL SET_EP_FACTORS
321
322
323 IF(CARTESIAN_GRID) CALL CG_SET_OUTFLOW
324
325
326 IF (ENERGY_EQ) THEN
327 CALL SOLVE_ENERGY_EQ (IER)
328 IF (IER_MANAGER()) goto 1000
329 ENDIF
330
331
332 IF (GRANULAR_ENERGY) THEN
333 IF(.NOT.DISCRETE_ELEMENT .OR. DES_CONTINUUM_HYBRID) THEN
334 CALL SOLVE_GRANULAR_ENERGY (IER)
335 IF (IER_MANAGER()) goto 1000
336 ENDIF
337 ENDIF
338
339
340 CALL SOLVE_SPECIES_EQ (IER)
341 IF (IER_MANAGER()) goto 1000
342
343
344 IF(NScalar /= 0) CALL SOLVE_Scalar_EQ (IER)
345
346
347 IF(K_Epsilon) CALL SOLVE_K_Epsilon_EQ (IER)
348
349
350
351
352 IF (.NOT.CYCLIC) LEQ_ADJUST = .TRUE.
353
354
355
356 CALL ACCUM_RESID
357 = RESID(RESID_P,0)
358 RESS = RESID(RESID_P,1)
359 CALL CALC_RESID_MB(1, errorpercent)
360 CALL CHECK_CONVERGENCE (NIT, errorpercent(0), MUSTIT)
361
362 IF(CYCLIC)THEN
363 IF(MUSTIT==0 .OR. NIT >= MAX_NIT) &
364 CALL GoalSeekMassFlux(NIT, MUSTIT, .true.)
365 IF(AUTOMATIC_RESTART) RETURN
366 ENDIF
367
368
369
370 CONTINUE
371
372
373
374 CALL DISPLAY_RESID (NIT)
375
376
377 IF (MUSTIT == 0) THEN
378
379 IF (DT==UNDEFINED .AND. NIT==1) GOTO 50
380
381
382 IF (MOD(NSTEP,NLOG) == 0) THEN
383 CALL CPU_TIME (CPU_NOW)
384 CPUOS = (CPU_NOW - CPU_NLOG)/(TIME - TIME_NLOG)
385 CPU_NLOG = CPU_NOW
386 TIME_NLOG = TIME
387 CPU_NOW = CPU_NOW - CPU0
388
389 CALL CALC_RESID_MB(1, errorpercent)
390 CALL GET_SMASS (SMASS)
391 IF (ENERGY_EQ) CALL GET_HLOSS (HLOSS)
392
393 CALL START_LOG
394 IF (ENERGY_EQ) THEN
395 WRITE(ERR_MSG,5000)TIME, DT, NIT, SMASS, HLOSS, CPU_NOW
396 CALL FLUSH_ERR_MSG(HEADER=.FALSE., FOOTER=.FALSE.)
397 ELSE
398 WRITE(ERR_MSG,5001) TIME, DT, NIT, SMASS, CPU_NOW
399 CALL FLUSH_ERR_MSG(HEADER=.FALSE., FOOTER=.FALSE.)
400 ENDIF
401
402 5000 FORMAT(1X,'t=',F11.4,' Dt=',G11.4,' NIT=',I3,' Sm=',G12.5, &
403 ' Hl=',G12.5,T84,'CPU=',F8.0,' s')
404
405 5001 FORMAT(1X,'t=',F11.4,' Dt=',G11.4,' NIT=',I3,' Sm=',G12.5, &
406 T84,'CPU=',F8.0,' s')
407
408 IF(DMP_LOG)WRITE (UNIT_LOG, 5002) (errorpercent(M), M=0,MMAX)
409 IF (FULL_LOG .and. myPE.eq.PE_IO) &
410 WRITE (*, 5002) (errorpercent(M), M=0,MMAX)
411
412 5002 FORMAT(3X,'MbError%(0,MMAX):', 5(1X,G11.4))
413
414
415
416 IF (.NOT.FULL_LOG) THEN
417 TLEFT = (TSTOP - TIME)*CPUOS
418 CALL GET_TUNIT (TLEFT, TUNIT)
419 IF(DMP_LOG)WRITE (UNIT_LOG, '(46X,A,F9.3,1X,A)')
420 ENDIF
421
422 IF (CYCLIC_X .OR. CYCLIC_Y .OR. CYCLIC_Z) THEN
423 IF (DO_I) THEN
424 Vavg = VAVG_U_G()
425 IF(DMP_LOG)WRITE (UNIT_LOG, 5050) 'U_g = ', Vavg
426 ENDIF
427 IF (DO_J) THEN
428 Vavg = VAVG_V_G()
429 IF(DMP_LOG)WRITE (UNIT_LOG, 5050) 'V_g = ', Vavg
430 ENDIF
431 IF (DO_K) THEN
432 Vavg = VAVG_W_G()
433 IF(DMP_LOG)WRITE (UNIT_LOG, 5050) 'W_g = ', Vavg
434 ENDIF
435 DO M = 1, SMAX
436 IF (DO_I) Then
437 Vavg = VAVG_U_S(M)
438 IF(DMP_LOG)WRITE (UNIT_LOG, 5060) 'U_s(', M, ') = ', Vavg
439 ENDIF
440 IF (DO_J) Then
441 Vavg = VAVG_V_S(M)
442 IF(DMP_LOG)WRITE (UNIT_LOG, 5060) 'V_s(', M, ') = ', Vavg
443 ENDIF
444 IF (DO_K) Then
445 Vavg = VAVG_W_S(M)
446 IF(DMP_LOG)WRITE (UNIT_LOG, 5060) 'W_s(', M, ') = ', Vavg
447 ENDIF
448 ENDDO
449 ENDIF
450
451 CALL END_LOG
452 ENDIF
453
454
455 IF(WRITE_DASHBOARD) THEN
456 RUN_STATUS = 'In Progress...'
457 N_DASHBOARD = N_DASHBOARD + 1
458 IF(MOD(N_DASHBOARD,F_DASHBOARD)==0) THEN
459 TLEFT = (TSTOP - TIME)*CPUOS
460 CALL GET_TUNIT (TLEFT, TUNIT)
461 CALL UPDATE_DASHBOARD(NIT,TLEFT,TUNIT)
462 ENDIF
463 ENDIF
464
465 IER = 0
466 RETURN
467
468
469
470
471 ELSEIF (MUSTIT==2 .AND. DT/=UNDEFINED) THEN
472
473 IF (FULL_LOG) THEN
474 CALL START_LOG
475 CALL CALC_RESID_MB(1, errorpercent)
476
477 IF(DMP_LOG) WRITE(UNIT_LOG,5200) TIME, DT, NIT, &
478 errorpercent(0), trim(adjustl(lMsg))
479 CALL END_LOG
480
481 IF (myPE.EQ.PE_IO) WRITE(*,5200) TIME, DT, NIT, &
482 errorpercent(0), trim(adjustl(lMsg))
483 ENDIF
484
485
486
487 IF(WRITE_DASHBOARD) THEN
488 RUN_STATUS = 'Diverged/stalled...'
489 N_DASHBOARD = N_DASHBOARD + 1
490 IF(MOD(N_DASHBOARD,F_DASHBOARD)==0) THEN
491 TLEFT = (TSTOP - TIME)*CPUOS
492 CALL GET_TUNIT (TLEFT, TUNIT)
493 CALL UPDATE_DASHBOARD(NIT,TLEFT,TUNIT)
494 ENDIF
495 ENDIF
496
497 IER = 1
498 RETURN
499 ENDIF
500
501
502
503
504
505 IF(INTERACTIVE_MODE .AND. INTERACTIVE_NITS/=UNDEFINED_I) THEN
506 CALL CHECK_INTERACT_ITER(MUSTIT)
507 IF(MUSTIT == 1) THEN
508 GOTO 50
509 ELSE
510 GOTO 1000
511 ENDIF
512 ELSEIF(NIT < MAX_NIT) THEN
513 MUSTIT = 0
514 GOTO 50
515 ENDIF
516
517
518 CALL GET_SMASS (SMASS)
519 IF (myPE.eq.PE_IO) WRITE(UNIT_OUT, 5100) TIME, DT, NIT, SMASS
520 CALL START_LOG
521 IF(DMP_LOG) WRITE(UNIT_LOG, 5100) TIME, DT, NIT, SMASS
522 CALL END_LOG
523
524
525
526 = 1
527 RETURN
528
529 5050 FORMAT(5X,'Average ',A,G12.5)
530 5060 FORMAT(5X,'Average ',A,I2,A,G12.5)
531 5100 FORMAT(1X,'t=',F11.4,' Dt=',G11.4,' NIT>',I3,' Sm= ',G12.5, 'MbErr%=', G11.4)
532 5200 FORMAT(1X,'t=',F11.4,' Dt=',G11.4,' NIT=',&
533 I3,'MbErr%=', G11.4, ': ',A,' :-(')
534
535 contains
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552 LOGICAL FUNCTION IER_MANAGER()
553
554
555 IF(IER < 100) THEN
556 IER_MANAGER = .FALSE.
557 return
558 ENDIF
559
560
561
562 = .TRUE.
563 MUSTIT = 2
564
565
566
567 IF(IER < 110) THEN
568 IF(IER == 100) THEN
569 lMsg = 'Negative gas density detected'
570 ELSEIF(IER == 101) THEN
571 lMsg = 'Negative solids density detected'
572 ELSE
573 lMsg = 'UCE in PHYSICAL_PROP'
574 ENDIF
575
576
577
578
579 ELSEIF(IER < 120) THEN
580 IF(IER == 110) THEN
581 lMsg = 'Negative void fraction detected'
582 ELSE
583 lMsg = 'UCE in CALC_VOL_FR'
584 ENDIF
585
586
587
588
589 ELSEIF(IER < 130) THEN
590 IF(IER == 120) THEN
591 lMsg = 'Energy Equation diverged'
592 ELSE
593 lMsg = 'UCE in SOLVE_ENERGY_EQ'
594 ENDIF
595
596
597
598
599 ELSEIF(IER < 140) THEN
600 IF(IER == 130) THEN
601 lMsg = 'Species Equation diverged'
602 ELSE
603 lMsg = 'UCE in SOLVE_SPECIES_EQ'
604 ENDIF
605
606
607
608
609 ELSEIF(IER < 150) THEN
610 IF(IER == 140) THEN
611 lMsg = 'Granular Energy Eq diverged'
612 ELSE
613 lMsg = 'UCE in SOLVE_GRANULAR_ENERGY'
614 ENDIF
615
616
617
618 ELSE
619 lMsg = 'Run diverged/stalled with UCE'
620 ENDIF
621
622
623 IF(DT == UNDEFINED) IER_MANAGER = .FALSE.
624
625 return
626 END FUNCTION IER_MANAGER
627
628
629
630 END SUBROUTINE ITERATE
631
632
633
634
635
636
637
638 SUBROUTINE GET_TUNIT(TLEFT, TUNIT)
639
640
641
642
643 IMPLICIT NONE
644
645
646
647 DOUBLE PRECISION, INTENT(INOUT) :: TLEFT
648 CHARACTER(LEN=4) :: TUNIT
649
650
651 IF (TLEFT < 3600.0d0) THEN
652 TUNIT = 's'
653 ELSE
654 TLEFT = TLEFT/3600.0d0
655 TUNIT = 'h'
656 IF (TLEFT >= 24.) THEN
657 TLEFT = TLEFT/24.0d0
658 TUNIT = 'days'
659 ENDIF
660 ENDIF
661
662 RETURN
663 END SUBROUTINE GET_TUNIT
664
665
666
667
668
669
670
671
672
673 subroutine GoalSeekMassFlux(NIT, MUSTIT, doit)
674
675
676
677
678 USE bc
679 USE geometry
680 USE constant
681 USE compar
682 USE run
683 USE time_cpu
684 USE utilities, ONLY: mfix_isnan
685 IMPLICIT NONE
686
687
688
689 INTEGER, INTENT(INOUT) :: NIT, MUSTIT
690 LOGICAL, INTENT(IN) :: doit
691
692
693
694 INTEGER, PARAMETER :: MAXOUTIT = 500
695 DOUBLE PRECISION, PARAMETER :: omega = 0.9
696 DOUBLE PRECISION, PARAMETER :: TOL = 1E-03
697 INTEGER, SAVE :: OUTIT
698 LOGICAL, SAVE :: firstPass = .true.
699
700 DOUBLE PRECISION, SAVE :: mdot_n, mdot_nm1, delp_n, delp_nm1, err
701 DOUBLE PRECISION :: mdot_0, delp_xyz
702
703
704
705
706 DOUBLE PRECISION, EXTERNAL :: VAVG_Flux_U_G, VAVG_Flux_V_G, &
707 VAVG_Flux_W_G
708
709
710 IF(CYCLIC_X_MF)THEN
711 delp_n = delp_x
712 ELSEIF(CYCLIC_Y_MF)THEN
713 delp_n = delp_y
714 ELSEIF(CYCLIC_Z_MF)THEN
715 delp_n = delp_z
716 ELSE
717 RETURN
718 ENDIF
719
720 IF(.NOT.doit) THEN
721 OUTIT = 0
722 RETURN
723 ENDIF
724
725 OUTIT = OUTIT + 1
726 IF(OUTIT > MAXOUTIT) THEN
727 IF (myPE.EQ.PE_IO) write(*,5400) MAXOUTIT
728 CALL mfix_exit(0)
729 ENDIF
730
731 mdot_0 = Flux_g
732
733
734
735 IF(CYCLIC_X_MF)THEN
736 mdot_n = VAVG_Flux_U_G()
737 ELSEIF(CYCLIC_Y_MF)THEN
738 mdot_n = VAVG_Flux_V_G()
739 ELSEIF(CYCLIC_Z_MF)THEN
740 mdot_n = VAVG_Flux_W_G()
741 ENDIF
742
743 IF (mfix_isnan(mdot_n) .OR. mfix_isnan(delp_n)) THEN
744 IF (myPE.eq.PE_IO) write(*,*) mdot_n, delp_n, &
745 ' NaN being caught in GoalSeekMassFlux '
746 AUTOMATIC_RESTART = .TRUE.
747 RETURN
748 ENDIF
749
750 err = abs((mdot_n - mdot_0)/mdot_0)
751 IF( err < TOL) THEN
752 MUSTIT = 0
753 ELSE
754 MUSTIT = 1
755 NIT = 1
756 ENDIF
757
758
759 if(.not.firstPass)then
760
761
762
763
764
765 = delp_n - omega * (delp_n - delp_nm1) * &
766 ((mdot_n - mdot_0)/(mdot_nm1 - mdot_0)) / &
767 ((mdot_n - mdot_0)/(mdot_nm1 - mdot_0) - ONE)
768 else
769 firstPass=.false.
770 delp_xyz = delp_n*0.99
771 endif
772
773 IF(MUSTIT == 0) then
774 IF(myPE.eq.PE_IO) Write(*,5500) TIME, OUTIT, delp_xyz, mdot_n
775 ENDIF
776
777 mdot_nm1 = mdot_n
778 delp_nm1 = delp_n
779
780 IF(CYCLIC_X_MF)THEN
781 delp_x = delp_xyz
782 ELSEIF(CYCLIC_Y_MF)THEN
783 delp_y = delp_xyz
784 ELSEIF(CYCLIC_Z_MF)THEN
785 delp_z = delp_xyz
786 ENDIF
787
788
789 RETURN
790
791 5400 FORMAT(/1X,70('*')//' From: GoalSeekMassFlux',/&
792 ' Message: Number of outer iterations exceeded ', I4,/1X,70('*')/)
793 5500 Format(' Time=', G12.5, ' MassFluxIterations=', I4, ' DelP=', &
794 G12.5, ' Gas Flux=', G12.5)
795
796 END SUBROUTINE GoalSeekMassFlux
797
798