57 character(len=LENMEMPATH) :: memory_path
58 character(len=LINELENGTH) :: fname
59 character(len=16) :: solver_mode
62 integer(I4B),
pointer :: id
63 integer(I4B),
pointer :: iu
64 real(dp),
pointer :: ttform
65 real(dp),
pointer :: ttsoln
66 integer(I4B),
pointer :: isymmetric => null()
67 integer(I4B),
pointer :: neq => null()
68 integer(I4B),
pointer :: matrix_offset => null()
73 real(dp),
dimension(:),
pointer,
contiguous :: rhs => null()
74 real(dp),
dimension(:),
pointer,
contiguous :: x => null()
75 integer(I4B),
dimension(:),
pointer,
contiguous :: active => null()
76 real(dp),
dimension(:),
pointer,
contiguous :: xtemp => null()
80 real(dp),
pointer :: theta => null()
81 real(dp),
pointer :: akappa => null()
82 real(dp),
pointer :: gamma => null()
83 real(dp),
pointer :: amomentum => null()
84 real(dp),
pointer :: breduc => null()
85 real(dp),
pointer :: btol => null()
86 real(dp),
pointer :: res_lim => null()
87 real(dp),
pointer :: dvclose => null()
88 real(dp),
pointer :: bigchold => null()
89 real(dp),
pointer :: bigch => null()
90 real(dp),
pointer :: relaxold => null()
91 real(dp),
pointer :: res_prev => null()
92 real(dp),
pointer :: res_new => null()
93 integer(I4B),
pointer :: icnvg => null()
94 integer(I4B),
pointer :: itertot_timestep => null()
95 integer(I4B),
pointer :: iouttot_timestep => null()
96 integer(I4B),
pointer :: itertot_sim => null()
97 integer(I4B),
pointer :: mxiter => null()
98 integer(I4B),
pointer :: linsolver => null()
99 integer(I4B),
pointer :: nonmeth => null()
100 integer(I4B),
pointer :: numtrack => null()
101 integer(I4B),
pointer :: iprims => null()
102 integer(I4B),
pointer :: ibflag => null()
103 integer(I4B),
dimension(:, :),
pointer,
contiguous :: lrch => null()
104 real(dp),
dimension(:),
pointer,
contiguous :: hncg => null()
105 real(dp),
dimension(:),
pointer,
contiguous :: dxold => null()
106 real(dp),
dimension(:),
pointer,
contiguous :: deold => null()
107 real(dp),
dimension(:),
pointer,
contiguous :: wsave => null()
108 real(dp),
dimension(:),
pointer,
contiguous :: hchold => null()
111 character(len=31),
dimension(:),
pointer,
contiguous :: caccel => null()
112 integer(I4B),
pointer :: icsvouterout => null()
113 integer(I4B),
pointer :: icsvinnerout => null()
114 integer(I4B),
pointer :: nitermax => null()
115 integer(I4B),
pointer :: convnmod => null()
116 integer(I4B),
dimension(:),
pointer,
contiguous :: convmodstart => null()
123 integer(I4B),
pointer :: iallowptc => null()
124 integer(I4B),
pointer :: iptcopt => null()
125 integer(I4B),
pointer :: iptcout => null()
126 real(dp),
pointer :: l2norm0 => null()
127 real(dp),
pointer :: ptcdel => null()
128 real(dp),
pointer :: ptcdel0 => null()
129 real(dp),
pointer :: ptcexp => null()
132 real(dp),
pointer :: atsfrac => null()
145 class(*),
pointer :: synchronize_ctx => null()
207 integer(I4B) :: stage
208 class(*),
pointer :: ctx
227 character(len=*),
intent(in) :: filename
228 integer(I4B),
intent(in) :: id
230 integer(I4B) :: inunit
232 character(len=LENSOLUTIONNAME) :: solutionname
236 write (solutionname,
'(a, i0)')
'SLN_', id
238 num_sol%name = solutionname
240 allocate (num_sol%modellist)
241 allocate (num_sol%exchangelist)
243 call num_sol%allocate_scalars()
252 inquire (file=filename, number=inunit)
254 if (inunit < 0) inunit =
getunit()
256 write (
iout,
'(/a,a)')
' Creating solution: ', num_sol%name
260 call num_sol%parser%Initialize(num_sol%iu,
iout)
277 call mem_allocate(this%ttform,
'TTFORM', this%memory_path)
278 call mem_allocate(this%ttsoln,
'TTSOLN', this%memory_path)
279 call mem_allocate(this%isymmetric,
'ISYMMETRIC', this%memory_path)
281 call mem_allocate(this%matrix_offset,
'MATRIX_OFFSET', this%memory_path)
282 call mem_allocate(this%dvclose,
'DVCLOSE', this%memory_path)
283 call mem_allocate(this%bigchold,
'BIGCHOLD', this%memory_path)
284 call mem_allocate(this%bigch,
'BIGCH', this%memory_path)
285 call mem_allocate(this%relaxold,
'RELAXOLD', this%memory_path)
286 call mem_allocate(this%res_prev,
'RES_PREV', this%memory_path)
287 call mem_allocate(this%res_new,
'RES_NEW', this%memory_path)
288 call mem_allocate(this%icnvg,
'ICNVG', this%memory_path)
289 call mem_allocate(this%itertot_timestep,
'ITERTOT_TIMESTEP', this%memory_path)
290 call mem_allocate(this%iouttot_timestep,
'IOUTTOT_TIMESTEP', this%memory_path)
291 call mem_allocate(this%itertot_sim,
'INNERTOT_SIM', this%memory_path)
292 call mem_allocate(this%mxiter,
'MXITER', this%memory_path)
293 call mem_allocate(this%linsolver,
'LINSOLVER', this%memory_path)
294 call mem_allocate(this%nonmeth,
'NONMETH', this%memory_path)
295 call mem_allocate(this%iprims,
'IPRIMS', this%memory_path)
296 call mem_allocate(this%theta,
'THETA', this%memory_path)
297 call mem_allocate(this%akappa,
'AKAPPA', this%memory_path)
298 call mem_allocate(this%gamma,
'GAMMA', this%memory_path)
299 call mem_allocate(this%amomentum,
'AMOMENTUM', this%memory_path)
300 call mem_allocate(this%breduc,
'BREDUC', this%memory_path)
302 call mem_allocate(this%res_lim,
'RES_LIM', this%memory_path)
303 call mem_allocate(this%numtrack,
'NUMTRACK', this%memory_path)
304 call mem_allocate(this%ibflag,
'IBFLAG', this%memory_path)
305 call mem_allocate(this%icsvouterout,
'ICSVOUTEROUT', this%memory_path)
306 call mem_allocate(this%icsvinnerout,
'ICSVINNEROUT', this%memory_path)
307 call mem_allocate(this%nitermax,
'NITERMAX', this%memory_path)
308 call mem_allocate(this%convnmod,
'CONVNMOD', this%memory_path)
309 call mem_allocate(this%iallowptc,
'IALLOWPTC', this%memory_path)
310 call mem_allocate(this%iptcopt,
'IPTCOPT', this%memory_path)
311 call mem_allocate(this%iptcout,
'IPTCOUT', this%memory_path)
312 call mem_allocate(this%l2norm0,
'L2NORM0', this%memory_path)
313 call mem_allocate(this%ptcdel,
'PTCDEL', this%memory_path)
314 call mem_allocate(this%ptcdel0,
'PTCDEL0', this%memory_path)
315 call mem_allocate(this%ptcexp,
'PTCEXP', this%memory_path)
316 call mem_allocate(this%atsfrac,
'ATSFRAC', this%memory_path)
326 this%bigchold =
dzero
328 this%relaxold =
dzero
329 this%res_prev =
dzero
331 this%itertot_timestep = 0
332 this%iouttot_timestep = 0
341 this%amomentum =
dzero
347 this%icsvouterout = 0
348 this%icsvinnerout = 0
377 this%convnmod = this%modellist%Count()
380 call mem_allocate(this%active, this%neq,
'IACTIVE', this%memory_path)
381 call mem_allocate(this%xtemp, this%neq,
'XTEMP', this%memory_path)
382 call mem_allocate(this%dxold, this%neq,
'DXOLD', this%memory_path)
383 call mem_allocate(this%hncg, 0,
'HNCG', this%memory_path)
384 call mem_allocate(this%lrch, 3, 0,
'LRCH', this%memory_path)
385 call mem_allocate(this%wsave, 0,
'WSAVE', this%memory_path)
386 call mem_allocate(this%hchold, 0,
'HCHOLD', this%memory_path)
387 call mem_allocate(this%deold, 0,
'DEOLD', this%memory_path)
388 call mem_allocate(this%convmodstart, this%convnmod + 1,
'CONVMODSTART', &
393 this%xtemp(i) =
dzero
394 this%dxold(i) =
dzero
400 this%convmodstart(1) = ieq
401 do i = 1, this%modellist%Count()
404 this%convmodstart(i + 1) = ieq
426 integer(I4B),
allocatable,
dimension(:) :: rowmaxnnz
427 integer(I4B) :: ncol, irow_start, irow_end
428 integer(I4B) :: mod_offset
431 do i = 1, this%modellist%Count()
433 call mp%set_idsoln(this%id)
434 this%neq = this%neq + mp%neq
439 this%solver_mode =
'PETSC'
441 this%solver_mode =
'IMS'
445 allocate (this%linear_settings)
449 this%system_matrix => this%linear_solver%create_matrix()
450 this%vec_x => this%system_matrix%create_vec_mm(this%neq,
'X', &
452 this%x => this%vec_x%get_array()
453 this%vec_rhs => this%system_matrix%create_vec_mm(this%neq,
'RHS', &
455 this%rhs => this%vec_rhs%get_array()
457 call this%vec_rhs%get_ownership_range(irow_start, irow_end)
458 ncol = this%vec_rhs%get_size()
462 this%matrix_offset = irow_start - 1
463 do i = 1, this%modellist%Count()
470 call this%allocate_arrays()
473 allocate (this%cnvg_summary)
474 call this%cnvg_summary%init(this%modellist%Count(), this%convmodstart, &
478 do i = 1, this%modellist%Count()
480 call mp%set_xptr(this%x, this%matrix_offset,
'X', this%name)
481 call mp%set_rhsptr(this%rhs, this%matrix_offset,
'RHS', this%name)
482 call mp%set_iboundptr(this%active, this%matrix_offset,
'IBOUND', this%name)
486 allocate (rowmaxnnz(this%neq))
490 call this%sparse%init(this%neq, ncol, rowmaxnnz)
491 this%sparse%offset = this%matrix_offset
492 deallocate (rowmaxnnz)
495 call this%sln_connect()
514 character(len=linelength) :: warnmsg
515 character(len=linelength) :: keyword
516 character(len=linelength) :: fname
517 character(len=linelength) :: msg
519 integer(I4B) :: ifdparam, mxvl, npp
521 logical(LGP) :: isfound, endOfBlock
524 character(len=*),
parameter :: fmtcsvout = &
525 "(4x, 'CSV OUTPUT WILL BE SAVED TO FILE: ', a, &
526 &/4x, 'OPENED ON UNIT: ', I7)"
527 character(len=*),
parameter :: fmtptcout = &
528 "(4x, 'PTC OUTPUT WILL BE SAVED TO FILE: ', a, &
529 &/4x, 'OPENED ON UNIT: ', I7)"
530 character(len=*),
parameter :: fmterrasym = &
531 "(a,' **',a,'** PRODUCES AN ASYMMETRIC COEFFICIENT MATRIX, BUT THE &
532 &CONJUGATE GRADIENT METHOD WAS SELECTED. USE BICGSTAB INSTEAD. ')"
535 WRITE (
iout, 1) this%iu
536 00001
FORMAT(1x, /1x,
'IMS -- ITERATIVE MODEL SOLUTION PACKAGE, VERSION 6', &
537 ', 4/28/2017', /, 9x,
'INPUT READ FROM UNIT', i5)
546 call this%parser%GetBlock(
'OPTIONS', isfound, ierr, &
547 supportopenclose=.true., blockrequired=.false.)
551 write (
iout,
'(/1x,a)')
'PROCESSING IMS OPTIONS'
553 call this%parser%GetNextLine(endofblock)
555 call this%parser%GetStringCaps(keyword)
556 select case (keyword)
557 case (
'PRINT_OPTION')
558 call this%parser%GetStringCaps(keyword)
559 if (keyword .eq.
'NONE')
then
561 else if (keyword .eq.
'SUMMARY')
then
563 else if (keyword .eq.
'ALL')
then
566 write (errmsg,
'(3a)') &
567 'Unknown IMS print option (', trim(keyword),
').'
571 call this%parser%GetStringCaps(keyword)
572 if (keyword .eq.
'SIMPLE')
then
575 else if (keyword .eq.
'MODERATE')
then
578 else if (keyword .eq.
'COMPLEX')
then
582 write (errmsg,
'(3a)') &
583 'Unknown IMS COMPLEXITY option (', trim(keyword),
').'
586 case (
'CSV_OUTER_OUTPUT')
587 call this%parser%GetStringCaps(keyword)
588 if (keyword ==
'FILEOUT')
then
589 call this%parser%GetString(fname)
590 if (nr_procs > 1)
then
591 call append_processor_id(fname, proc_id)
594 call openfile(this%icsvouterout,
iout, fname,
'CSV_OUTER_OUTPUT', &
595 filstat_opt=
'REPLACE')
596 write (
iout, fmtcsvout) trim(fname), this%icsvouterout
598 write (errmsg,
'(a)')
'Optional CSV_OUTER_OUTPUT '// &
599 'keyword must be followed by FILEOUT'
602 case (
'CSV_INNER_OUTPUT')
603 call this%parser%GetStringCaps(keyword)
604 if (keyword ==
'FILEOUT')
then
605 call this%parser%GetString(fname)
606 if (nr_procs > 1)
then
607 call append_processor_id(fname, proc_id)
610 call openfile(this%icsvinnerout,
iout, fname,
'CSV_INNER_OUTPUT', &
611 filstat_opt=
'REPLACE')
612 write (
iout, fmtcsvout) trim(fname), this%icsvinnerout
614 write (errmsg,
'(a)')
'Optional CSV_INNER_OUTPUT '// &
615 'keyword must be followed by FILEOUT'
619 call this%parser%GetStringCaps(keyword)
620 select case (keyword)
631 this%iallowptc = ival
632 write (
iout,
'(1x,A)')
'PSEUDO-TRANSIENT CONTINUATION DISABLED FOR'// &
633 ' '//trim(adjustl(msg))//
' STRESS-PERIOD(S)'
634 case (
'ATS_OUTER_MAXIMUM_FRACTION')
635 rval = this%parser%GetDouble()
637 write (errmsg,
'(a,G0)')
'Value for ATS_OUTER_MAXIMUM_FRAC must be &
638 &between 0 and 0.5. Found ', rval
642 write (
iout,
'(1x,A,G0)')
'ADAPTIVE TIME STEP SETTING FOUND. FRACTION &
643 &OF OUTER MAXIMUM USED TO INCREASE OR DECREASE TIME STEP SIZE IS ',&
648 call this%parser%GetStringCaps(keyword)
649 if (keyword ==
'FILEOUT')
then
650 call this%parser%GetString(fname)
652 call openfile(this%icsvouterout,
iout, fname,
'CSV_OUTPUT', &
653 filstat_opt=
'REPLACE')
654 write (
iout, fmtcsvout) trim(fname), this%icsvouterout
657 write (warnmsg,
'(a)') &
658 'OUTER ITERATION INFORMATION WILL BE SAVED TO '//trim(fname)
662 warnmsg, this%parser%GetUnit())
664 write (errmsg,
'(a)')
'Optional CSV_OUTPUT '// &
665 'keyword must be followed by FILEOUT'
674 call this%parser%DevOpt()
676 write (
iout,
'(1x,A)')
'PSEUDO-TRANSIENT CONTINUATION ENABLED'
677 case (
'DEV_PTC_OUTPUT')
678 call this%parser%DevOpt()
680 call this%parser%GetStringCaps(keyword)
681 if (keyword ==
'FILEOUT')
then
682 call this%parser%GetString(fname)
683 if (nr_procs > 1)
then
684 call append_processor_id(fname, proc_id)
688 filstat_opt=
'REPLACE')
689 write (
iout, fmtptcout) trim(fname), this%iptcout
691 write (errmsg,
'(a)') &
692 'Optional PTC_OUTPUT keyword must be followed by FILEOUT'
695 case (
'DEV_PTC_OPTION')
696 call this%parser%DevOpt()
699 write (
iout,
'(1x,A)') &
700 'PSEUDO-TRANSIENT CONTINUATION USES BNORM AND L2NORM TO '// &
702 case (
'DEV_PTC_EXPONENT')
703 call this%parser%DevOpt()
704 rval = this%parser%GetDouble()
705 if (rval <
dzero)
then
706 write (errmsg,
'(a)')
'PTC_EXPONENT must be > 0.'
711 write (
iout,
'(1x,A,1x,g15.7)') &
712 'PSEUDO-TRANSIENT CONTINUATION EXPONENT', this%ptcexp
714 case (
'DEV_PTC_DEL0')
715 call this%parser%DevOpt()
716 rval = this%parser%GetDouble()
717 if (rval <
dzero)
then
718 write (errmsg,
'(a)')
'IMS sln_ar: PTC_DEL0 must be > 0.'
723 write (
iout,
'(1x,A,1x,g15.7)') &
724 'PSEUDO-TRANSIENT CONTINUATION INITIAL TIMESTEP', this%ptcdel0
727 write (errmsg,
'(a,2(1x,a))') &
728 'Unknown IMS option (', trim(keyword),
').'
732 write (
iout,
'(1x,a)')
'END OF IMS OPTIONS'
734 write (
iout,
'(1x,a)')
'NO IMS OPTION BLOCK DETECTED.'
737 00021
FORMAT(1x,
'SIMPLE OPTION:', /, &
738 1x,
'DEFAULT SOLVER INPUT VALUES FOR FAST SOLUTIONS')
739 00023
FORMAT(1x,
'MODERATE OPTION:', /, 1x,
'DEFAULT SOLVER', &
740 ' INPUT VALUES REFLECT MODERETELY NONLINEAR MODEL')
741 00025
FORMAT(1x,
'COMPLEX OPTION:', /, 1x,
'DEFAULT SOLVER', &
742 ' INPUT VALUES REFLECT STRONGLY NONLINEAR MODEL')
746 call this%sln_setouter(ifdparam)
749 call this%parser%GetBlock(
'NONLINEAR', isfound, ierr, &
750 supportopenclose=.true., blockrequired=.false.)
754 write (
iout,
'(/1x,a)')
'PROCESSING IMS NONLINEAR'
756 call this%parser%GetNextLine(endofblock)
758 call this%parser%GetStringCaps(keyword)
760 select case (keyword)
761 case (
'OUTER_DVCLOSE')
762 this%dvclose = this%parser%GetDouble()
763 case (
'OUTER_MAXIMUM')
764 this%mxiter = this%parser%GetInteger()
765 case (
'UNDER_RELAXATION')
766 call this%parser%GetStringCaps(keyword)
768 if (keyword ==
'NONE')
then
770 else if (keyword ==
'SIMPLE')
then
772 else if (keyword ==
'COOLEY')
then
774 else if (keyword ==
'DBD')
then
777 write (errmsg,
'(3a)') &
778 'Unknown UNDER_RELAXATION specified (', trim(keyword),
').'
782 case (
'LINEAR_SOLVER')
783 call this%parser%GetStringCaps(keyword)
785 if (keyword .eq.
'DEFAULT' .or. &
786 keyword .eq.
'LINEAR')
then
789 write (errmsg,
'(3a)') &
790 'Unknown LINEAR_SOLVER specified (', trim(keyword),
').'
793 this%linsolver = ival
794 case (
'UNDER_RELAXATION_THETA')
795 this%theta = this%parser%GetDouble()
796 case (
'UNDER_RELAXATION_KAPPA')
797 this%akappa = this%parser%GetDouble()
798 case (
'UNDER_RELAXATION_GAMMA')
799 this%gamma = this%parser%GetDouble()
800 case (
'UNDER_RELAXATION_MOMENTUM')
801 this%amomentum = this%parser%GetDouble()
802 case (
'BACKTRACKING_NUMBER')
803 this%numtrack = this%parser%GetInteger()
804 IF (this%numtrack > 0) this%ibflag = 1
805 case (
'BACKTRACKING_TOLERANCE')
806 this%btol = this%parser%GetDouble()
807 case (
'BACKTRACKING_REDUCTION_FACTOR')
808 this%breduc = this%parser%GetDouble()
809 case (
'BACKTRACKING_RESIDUAL_LIMIT')
810 this%res_lim = this%parser%GetDouble()
813 case (
'OUTER_HCLOSE')
814 this%dvclose = this%parser%GetDouble()
817 write (warnmsg,
'(a)') &
818 'SETTING OUTER_DVCLOSE TO OUTER_HCLOSE VALUE'
822 warnmsg, this%parser%GetUnit())
823 case (
'OUTER_RCLOSEBND')
826 write (warnmsg,
'(a)') &
827 'OUTER_DVCLOSE IS USED TO EVALUATE PACKAGE CONVERGENCE'
831 warnmsg, this%parser%GetUnit())
833 write (errmsg,
'(3a)') &
834 'Unknown IMS NONLINEAR keyword (', trim(keyword),
').'
838 write (
iout,
'(1x,a)')
'END OF IMS NONLINEAR DATA'
840 if (ifdparam .EQ. 0)
then
841 write (errmsg,
'(a)')
'NO IMS NONLINEAR block detected.'
846 if (this%theta <
dem3)
then
851 if (this%nonmeth < 1)
then
856 if (this%mxiter <= 0)
then
857 write (errmsg,
'(a)')
'Outer iteration number must be > 0.'
862 if (this%nonmeth > 0)
then
863 WRITE (
iout, *)
'**UNDER-RELAXATION WILL BE USED***'
865 elseif (this%nonmeth == 0)
then
866 WRITE (
iout, *)
'***UNDER-RELAXATION WILL NOT BE USED***'
869 WRITE (errmsg,
'(a)') &
870 'Incorrect value for variable NONMETH was specified.'
875 if (this%nonmeth == 1)
then
876 if (this%gamma == 0)
then
877 WRITE (errmsg,
'(a)') &
878 'GAMMA must be greater than zero if SIMPLE under-relaxation is used.'
883 if (this%solver_mode ==
'PETSC')
then
888 call this%linear_settings%init(this%memory_path)
889 call this%linear_settings%preset_config(ifdparam)
890 call this%linear_settings%read_from_file(this%parser,
iout)
892 if (this%linear_settings%ilinmeth ==
cg_method)
then
898 if (this%solver_mode ==
"IMS")
then
899 allocate (this%imslinear)
900 WRITE (
iout, *)
'***IMS LINEAR SOLVER WILL BE USED***'
901 call this%imslinear%imslinear_allocate(this%name,
iout, this%iprims, &
902 this%mxiter, this%neq, &
903 this%system_matrix, this%rhs, &
904 this%x, this%linear_settings)
907 else if (this%solver_mode ==
"PETSC")
then
908 call this%linear_solver%initialize(this%system_matrix, &
909 this%linear_settings, &
914 write (errmsg,
'(a)') &
915 'Incorrect value for linear solution method specified.'
920 if (this%isymmetric == 1)
then
921 write (
iout,
'(1x,a,/)')
'A symmetric matrix will be solved'
923 write (
iout,
'(1x,a,/)')
'An asymmetric matrix will be solved'
928 if (this%isymmetric == 1)
then
931 do i = 1, this%modellist%Count()
933 if (mp%get_iasym() /= 0)
then
934 write (errmsg, fmterrasym)
'MODEL', trim(adjustl(mp%name))
940 do i = 1, this%exchangelist%Count()
942 if (cp%get_iasym() /= 0)
then
943 write (errmsg, fmterrasym)
'EXCHANGE', trim(adjustl(cp%name))
953 WRITE (
iout, 9002) this%dvclose, this%mxiter, &
954 this%iprims, this%nonmeth, this%linsolver
957 9002
FORMAT(1x,
'OUTER ITERATION CONVERGENCE CRITERION (DVCLOSE) = ', e15.6, &
958 /1x,
'MAXIMUM NUMBER OF OUTER ITERATIONS (MXITER) = ', i0, &
959 /1x,
'SOLVER PRINTOUT INDEX (IPRIMS) = ', i0, &
960 /1x,
'NONLINEAR ITERATION METHOD (NONLINMETH) = ', i0, &
961 /1x,
'LINEAR SOLUTION METHOD (LINMETH) = ', i0)
963 if (this%nonmeth == 1)
then
964 write (
iout, 9003) this%gamma
965 else if (this%nonmeth == 2)
then
966 write (
iout, 9004) this%gamma
967 else if (this%nonmeth == 3)
then
968 write (
iout, 9005) this%theta, this%akappa, this%gamma, this%amomentum
972 if (this%numtrack /= 0)
write (
iout, 9006) this%numtrack, this%btol, &
973 this%breduc, this%res_lim
976 9003
FORMAT(1x,
'UNDER-RELAXATION FACTOR (GAMMA) = ', e15.6)
977 9004
FORMAT(1x,
'UNDER-RELAXATION PREVIOUS HISTORY FACTOR (GAMMA) = ', e15.6)
978 9005
FORMAT(1x,
'UNDER-RELAXATION WEIGHT REDUCTION FACTOR (THETA) = ', e15.6, &
979 /1x,
'UNDER-RELAXATION WEIGHT INCREASE INCREMENT (KAPPA) = ', e15.6, &
980 /1x,
'UNDER-RELAXATION PREVIOUS HISTORY FACTOR (GAMMA) = ', e15.6, &
981 /1x,
'UNDER-RELAXATION MOMENTUM TERM (AMOMENTUM) = ', e15.6)
984 9006
FORMAT(1x,
'MAXIMUM NUMBER OF BACKTRACKS (NUMTRACK) = ', i0, &
985 /1x,
'BACKTRACKING TOLERANCE FACTOR (BTOL) = ', e15.6, &
986 /1x,
'BACKTRACKING REDUCTION FACTOR (BREDUC) = ', e15.6, &
987 /1x,
'BACKTRACKING RESIDUAL LIMIT (RES_LIM) = ', e15.6)
991 call this%imslinear%imslinear_summary(this%mxiter)
993 call this%linear_solver%print_summary()
999 call this%parser%StoreErrorUnit()
1004 call mem_reallocate(this%lrch, 3, this%mxiter,
'LRCH', this%name)
1007 if (this%nonmeth == 3)
then
1012 this%wsave(i) =
dzero
1013 this%hchold(i) =
dzero
1014 this%deold(i) =
dzero
1021 if (this%iprims == 2 .or. this%icsvinnerout > 0)
then
1022 this%nitermax = this%linear_settings%iter1 * this%mxiter
1027 allocate (this%caccel(this%nitermax))
1031 call this%cnvg_summary%reinit(this%nitermax)
1036 call this%parser%StoreErrorUnit()
1040 call this%parser%Clear()
1056 integer(I4B) :: idir
1057 real(DP) :: delt_temp
1058 real(DP) :: fact_lower
1059 real(DP) :: fact_upper
1065 if (this%atsfrac > dzero)
then
1067 fact_lower = this%mxiter * this%atsfrac
1068 fact_upper = this%mxiter - fact_lower
1069 if (this%iouttot_timestep < int(fact_lower))
then
1072 else if (this%iouttot_timestep > int(fact_upper))
then
1097 if (
kper == 1 .and.
kstp == 1)
then
1098 call this%writeCSVHeader()
1102 call this%writePTCInfoToFile(
kper)
1106 this%itertot_timestep = 0
1107 this%iouttot_timestep = 0
1134 write (
iout,
'(//1x,a,1x,a,1x,a)') &
1135 'Solution', trim(adjustl(this%name)),
'summary'
1136 write (
iout,
"(1x,70('-'))")
1137 write (
iout,
'(1x,a,1x,g0,1x,a)') &
1138 'Total formulate time: ', this%ttform,
'seconds'
1139 write (
iout,
'(1x,a,1x,g0,1x,a,/)') &
1140 'Total solution time: ', this%ttsoln,
'seconds'
1157 call this%imslinear%imslinear_da()
1158 deallocate (this%imslinear)
1162 call this%modellist%Clear()
1163 call this%exchangelist%Clear()
1164 deallocate (this%modellist)
1165 deallocate (this%exchangelist)
1167 call this%system_matrix%destroy()
1168 deallocate (this%system_matrix)
1169 call this%vec_x%destroy()
1170 deallocate (this%vec_x)
1171 call this%vec_rhs%destroy()
1172 deallocate (this%vec_rhs)
1176 deallocate (this%caccel)
1179 if (
associated(this%innertab))
then
1180 call this%innertab%table_da()
1181 deallocate (this%innertab)
1182 nullify (this%innertab)
1186 if (
associated(this%outertab))
then
1187 call this%outertab%table_da()
1188 deallocate (this%outertab)
1189 nullify (this%outertab)
1204 call this%cnvg_summary%destroy()
1205 deallocate (this%cnvg_summary)
1208 call this%linear_solver%destroy()
1209 deallocate (this%linear_solver)
1212 call this%linear_settings%destroy()
1213 deallocate (this%linear_settings)
1265 subroutine sln_ca(this, isgcnvg, isuppress_output)
1268 integer(I4B),
intent(inout) :: isgcnvg
1269 integer(I4B),
intent(in) :: isuppress_output
1272 character(len=LINELENGTH) :: line
1273 character(len=LINELENGTH) :: fmt
1275 integer(I4B) :: kiter
1278 call this%prepareSolve()
1282 line =
'mode="validation" -- Skipping matrix assembly and solution.'
1284 do im = 1, this%modellist%Count()
1286 call mp%model_message(line, fmt=fmt)
1290 outerloop:
do kiter = 1, this%mxiter
1293 call this%solve(kiter)
1296 if (this%icnvg == 1)
then
1303 call this%finalizeSolve(kiter, isgcnvg, isuppress_output)
1319 if (this%icsvouterout > 0)
then
1320 write (this%icsvouterout,
'(*(G0,:,","))') &
1321 'total_inner_iterations',
'totim',
'kper',
'kstp',
'nouter', &
1322 'inner_iterations',
'solution_outer_dvmax', &
1323 'solution_outer_dvmax_model',
'solution_outer_dvmax_package', &
1324 'solution_outer_dvmax_node'
1328 if (this%icsvinnerout > 0)
then
1329 write (this%icsvinnerout,
'(*(G0,:,","))', advance=
'NO') &
1330 'total_inner_iterations',
'totim',
'kper',
'kstp',
'nouter', &
1331 'ninner',
'solution_inner_dvmax',
'solution_inner_dvmax_model', &
1332 'solution_inner_dvmax_node'
1333 write (this%icsvinnerout,
'(*(G0,:,","))', advance=
'NO') &
1334 '',
'solution_inner_rmax',
'solution_inner_rmax_model', &
1335 'solution_inner_rmax_node'
1338 write (this%icsvinnerout,
'(*(G0,:,","))', advance=
'NO') &
1339 '',
'solution_inner_alpha'
1340 if (this%imslinear%ilinmeth == 2)
then
1341 write (this%icsvinnerout,
'(*(G0,:,","))', advance=
'NO') &
1342 '',
'solution_inner_omega'
1347 do im = 1, this%modellist%Count()
1349 write (this%icsvinnerout,
'(*(G0,:,","))', advance=
'NO') &
1350 '', trim(adjustl(mp%name))//
'_inner_dvmax', &
1351 trim(adjustl(mp%name))//
'_inner_dvmax_node', &
1352 trim(adjustl(mp%name))//
'_inner_rmax', &
1353 trim(adjustl(mp%name))//
'_inner_rmax_node'
1356 write (this%icsvinnerout,
'(a)')
''
1368 integer(I4B),
intent(in) :: kper
1370 integer(I4B) :: n, im, iallowptc, iptc
1375 do im = 1, this%modellist%Count()
1379 if (this%iallowptc < 0)
then
1387 iallowptc = this%iallowptc
1390 if (iallowptc > 0)
then
1392 call mp%model_ptcchk(iptc)
1399 write (
iout,
'(//)')
1402 write (
iout,
'(1x,a,1x,i0,1x,3a)') &
1403 'PSEUDO-TRANSIENT CONTINUATION WILL BE APPLIED TO MODEL', im,
'("', &
1404 trim(adjustl(mp%name)),
'") DURING THIS TIME STEP'
1428 do ic = 1, this%exchangelist%Count()
1434 do im = 1, this%modellist%Count()
1459 integer(I4B),
intent(in) :: kiter
1463 character(len=LINELENGTH) :: title
1464 character(len=LINELENGTH) :: tag
1465 character(len=LENPAKLOC) :: cmod
1466 character(len=LENPAKLOC) :: cpak
1467 character(len=LENPAKLOC) :: cpakout
1468 character(len=LENPAKLOC) :: strh
1469 character(len=25) :: cval
1470 character(len=7) :: cmsg
1472 integer(I4B) :: im, m_idx, model_id
1473 integer(I4B) :: icsv0
1474 integer(I4B) :: kcsv0
1475 integer(I4B) :: ntabrows
1476 integer(I4B) :: ntabcols
1477 integer(I4B) :: i0, i1
1478 integer(I4B) :: itestmat, n
1479 integer(I4B) :: iter
1480 integer(I4B) :: inewtonur
1481 integer(I4B) :: locmax_nur
1482 integer(I4B) :: iend
1483 integer(I4B) :: icnvgmod
1484 integer(I4B) :: iptc
1485 integer(I4B) :: node_user
1486 integer(I4B) :: ipak
1487 integer(I4B) :: ipos0
1488 integer(I4B) :: ipos1
1489 real(DP) :: dxmax_nur
1490 real(DP) :: dxold_max
1495 real(DP) :: outer_hncg
1498 icsv0 = max(1, this%itertot_sim + 1)
1499 kcsv0 = max(1, this%itertot_timestep + 1)
1502 if (this%iprims > 0)
then
1503 if (.not.
associated(this%outertab))
then
1509 if (this%numtrack > 0)
then
1510 ntabcols = ntabcols + 4
1514 title = trim(this%memory_path)//
' OUTER ITERATION SUMMARY'
1515 call table_cr(this%outertab, this%name, title)
1516 call this%outertab%table_df(ntabrows, ntabcols,
iout, &
1518 tag =
'OUTER ITERATION STEP'
1519 call this%outertab%initialize_column(tag, 25, alignment=
tableft)
1520 tag =
'OUTER ITERATION'
1521 call this%outertab%initialize_column(tag, 10, alignment=
tabright)
1522 tag =
'INNER ITERATION'
1523 call this%outertab%initialize_column(tag, 10, alignment=
tabright)
1524 if (this%numtrack > 0)
then
1525 tag =
'BACKTRACK FLAG'
1526 call this%outertab%initialize_column(tag, 10, alignment=
tabright)
1527 tag =
'BACKTRACK ITERATIONS'
1528 call this%outertab%initialize_column(tag, 10, alignment=
tabright)
1529 tag =
'INCOMING RESIDUAL'
1530 call this%outertab%initialize_column(tag, 15, alignment=
tabright)
1531 tag =
'OUTGOING RESIDUAL'
1532 call this%outertab%initialize_column(tag, 15, alignment=
tabright)
1534 tag =
'MAXIMUM CHANGE'
1535 call this%outertab%initialize_column(tag, 15, alignment=
tabright)
1536 tag =
'STEP SUCCESS'
1537 call this%outertab%initialize_column(tag, 7, alignment=
tabright)
1538 tag =
'MAXIMUM CHANGE MODEL-(CELLID) OR MODEL-PACKAGE-(NUMBER)'
1539 call this%outertab%initialize_column(tag, 34, alignment=
tabright)
1544 if (this%numtrack > 0)
then
1545 call this%sln_backtracking(mp, cp, kiter)
1551 call this%sln_buildsystem(kiter, inewton=1)
1554 call this%sln_calc_ptc(iptc, ptcf)
1557 do im = 1, this%modellist%Count()
1559 call mp%model_nr(kiter, this%system_matrix, 1)
1565 call this%sln_ls(kiter,
kstp,
kper, iter, iptc, ptcf)
1571 this%itertot_timestep = this%itertot_timestep + iter
1572 this%iouttot_timestep = this%iouttot_timestep + 1
1573 this%itertot_sim = this%itertot_sim + iter
1579 if (itestmat /= 0)
then
1580 open (99, file=
'sol_MF6.TXT')
1581 WRITE (99, *)
'MATRIX SOLUTION FOLLOWS'
1582 WRITE (99,
'(10(I8,G15.4))') (n, this%x(n), n=1, this%NEQ)
1589 call this%sln_get_dxmax(this%hncg(kiter), this%lrch(1, kiter))
1591 if (this%sln_has_converged(this%hncg(kiter)))
then
1596 if (this%icnvg == 0)
then
1604 if (kiter == this%mxiter)
then
1609 if (this%iprims > 0)
then
1611 call this%sln_get_loc(this%lrch(1, kiter), strh)
1614 call this%outertab%add_term(cval)
1615 call this%outertab%add_term(kiter)
1616 call this%outertab%add_term(iter)
1617 if (this%numtrack > 0)
then
1618 call this%outertab%add_term(
' ')
1619 call this%outertab%add_term(
' ')
1620 call this%outertab%add_term(
' ')
1621 call this%outertab%add_term(
' ')
1623 call this%outertab%add_term(this%hncg(kiter))
1624 call this%outertab%add_term(cmsg)
1625 call this%outertab%add_term(trim(strh))
1629 do ic = 1, this%exchangelist%Count()
1631 call cp%exg_cc(this%icnvg)
1635 icnvgmod = this%icnvg
1639 do im = 1, this%modellist%Count()
1641 call mp%get_mcellid(0, cmod)
1642 call mp%model_cc(this%itertot_sim, kiter, iend, icnvgmod, &
1645 ipos0 = index(cpak,
'-', back=.true.)
1646 ipos1 = len_trim(cpak)
1647 write (cpakout,
'(a,a,"-(",i0,")",a)') &
1648 trim(cmod), cpak(1:ipos0 - 1), ipak, cpak(ipos0:ipos1)
1655 if (this%icnvg == 1)
then
1656 this%icnvg = this%sln_package_convergence(dpak, cpakout, iend)
1659 if (this%iprims > 0)
then
1661 if (this%icnvg /= 1)
then
1666 if (len_trim(cpakout) > 0)
then
1669 call this%outertab%add_term(cval)
1670 call this%outertab%add_term(kiter)
1671 call this%outertab%add_term(
' ')
1672 if (this%numtrack > 0)
then
1673 call this%outertab%add_term(
' ')
1674 call this%outertab%add_term(
' ')
1675 call this%outertab%add_term(
' ')
1676 call this%outertab%add_term(
' ')
1678 call this%outertab%add_term(dpak)
1679 call this%outertab%add_term(cmsg)
1680 call this%outertab%add_term(cpakout)
1686 if (this%icnvg /= 1)
then
1687 if (this%nonmeth > 0)
then
1688 call this%sln_underrelax(kiter, this%hncg(kiter), this%neq, &
1689 this%active, this%x, this%xtemp)
1691 call this%sln_calcdx(this%neq, this%active, &
1692 this%x, this%xtemp, this%dxold)
1699 do im = 1, this%modellist%Count()
1701 i0 = mp%moffset + 1 - this%matrix_offset
1702 i1 = i0 + mp%neq - 1
1703 call mp%model_nur(mp%neq, this%x(i0:i1), this%xtemp(i0:i1), &
1704 this%dxold(i0:i1), inewtonur, dxmax_nur, locmax_nur)
1708 inewtonur = this%sln_sync_newtonur_flag(inewtonur)
1711 if (inewtonur /= 0)
then
1715 call this%sln_maxval(this%neq, this%dxold, dxold_max)
1718 if (this%sln_nur_has_converged(dxold_max, this%hncg(kiter)))
then
1724 call this%sln_get_dxmax(this%hncg(kiter), this%lrch(1, kiter))
1728 if (this%iprims > 0)
then
1729 cval =
'Newton under-relaxation'
1731 call this%sln_get_loc(this%lrch(1, kiter), strh)
1734 call this%outertab%add_term(cval)
1735 call this%outertab%add_term(kiter)
1736 call this%outertab%add_term(iter)
1737 if (this%numtrack > 0)
then
1738 call this%outertab%add_term(
' ')
1739 call this%outertab%add_term(
' ')
1740 call this%outertab%add_term(
' ')
1741 call this%outertab%add_term(
' ')
1743 call this%outertab%add_term(this%hncg(kiter))
1744 call this%outertab%add_term(cmsg)
1745 call this%outertab%add_term(trim(strh))
1752 if (this%icsvouterout > 0)
then
1755 outer_hncg = this%hncg(kiter)
1758 if (abs(outer_hncg) > abs(dpak))
then
1761 call this%sln_get_nodeu(this%lrch(1, kiter), m_idx, node_user)
1763 else if (outer_hncg ==
dzero .and. dpak ==
dzero)
then
1773 ipos0 = index(cmod,
'_')
1774 read (cmod(1:ipos0 - 1), *) m_idx
1776 ipos0 = index(cpak,
'-', back=.true.)
1777 cpakout = cpak(1:ipos0 - 1)
1787 write (this%icsvouterout,
'(*(G0,:,","))') &
1789 outer_hncg, model_id, trim(cpakout), node_user
1793 if (this%icsvinnerout > 0)
then
1794 call this%csv_convergence_summary(this%icsvinnerout,
totim,
kper,
kstp, &
1795 kiter, iter, icsv0, kcsv0)
1798 end subroutine solve
1810 integer(I4B),
intent(in) :: kiter
1811 integer(I4B),
intent(inout) :: isgcnvg
1812 integer(I4B),
intent(in) :: isuppress_output
1814 integer(I4B) :: ic, im
1818 character(len=*),
parameter :: fmtnocnvg = &
1819 "(1X,'Solution ', i0, ' did not converge for stress period ', i0, &
1820 &' and time step ', i0)"
1821 character(len=*),
parameter :: fmtcnvg = &
1822 "(1X, I0, ' CALLS TO NUMERICAL SOLUTION ', 'IN TIME STEP ', I0, &
1823 &' STRESS PERIOD ',I0,/1X,I0,' TOTAL ITERATIONS')"
1826 if (this%iprims > 0)
then
1827 call this%outertab%finalize_table()
1833 if (this%icnvg /= 0)
then
1834 if (this%iprims > 0)
then
1835 write (
iout, fmtcnvg) kiter,
kstp,
kper, this%itertot_timestep
1844 if (this%iprims == 2)
then
1847 do im = 1, this%modellist%Count()
1849 call this%convergence_summary(mp%iout, im, this%itertot_timestep)
1853 call this%convergence_summary(
iout, this%convnmod + 1, &
1854 this%itertot_timestep)
1858 if (this%icnvg == 0) isgcnvg = 0
1861 do im = 1, this%modellist%Count()
1863 call mp%model_cq(this%icnvg, isuppress_output)
1867 do ic = 1, this%exchangelist%Count()
1869 call cp%exg_cq(isgcnvg, isuppress_output, this%id)
1873 do im = 1, this%modellist%Count()
1875 call mp%model_bd(this%icnvg, isuppress_output)
1879 do ic = 1, this%exchangelist%Count()
1881 call cp%exg_bd(isgcnvg, isuppress_output, this%id)
1889 integer(I4B),
intent(in) :: kiter
1890 integer(I4B),
intent(in) :: inewton
1892 integer(I4B) :: im, ic
1897 call this%sln_reset()
1900 do im = 1, this%modellist%Count()
1902 call mp%model_reset()
1910 do ic = 1, this%exchangelist%Count()
1912 call cp%exg_cf(kiter)
1916 do im = 1, this%modellist%Count()
1918 call mp%model_cf(kiter)
1926 do ic = 1, this%exchangelist%Count()
1928 call cp%exg_fc(kiter, this%system_matrix, this%rhs, inewton)
1932 do im = 1, this%modellist%Count()
1934 call mp%model_fc(kiter, this%system_matrix, inewton)
1949 integer(I4B),
intent(in) :: iu
1950 integer(I4B),
intent(in) :: im
1951 integer(I4B),
intent(in) :: itertot_timestep
1953 character(len=LINELENGTH) :: title
1954 character(len=LINELENGTH) :: tag
1955 character(len=LENPAKLOC) :: loc_dvmax_str
1956 character(len=LENPAKLOC) :: loc_rmax_str
1957 integer(I4B) :: ntabrows
1958 integer(I4B) :: ntabcols
1959 integer(I4B) :: iinner
1961 integer(I4B) :: iouter
1964 integer(I4B) :: locdv
1965 integer(I4B) :: locdr
1977 if (.not.
associated(this%innertab))
then
1981 ntabrows = itertot_timestep
1985 title = trim(this%memory_path)//
' INNER ITERATION SUMMARY'
1986 call table_cr(this%innertab, this%name, title)
1987 call this%innertab%table_df(ntabrows, ntabcols, iu)
1988 tag =
'TOTAL ITERATION'
1989 call this%innertab%initialize_column(tag, 10, alignment=
tabright)
1990 tag =
'OUTER ITERATION'
1991 call this%innertab%initialize_column(tag, 10, alignment=
tabright)
1992 tag =
'INNER ITERATION'
1993 call this%innertab%initialize_column(tag, 10, alignment=
tabright)
1994 tag =
'MAXIMUM CHANGE'
1995 call this%innertab%initialize_column(tag, 15, alignment=
tabright)
1996 tag =
'MAXIMUM CHANGE MODEL-(CELLID)'
1998 tag =
'MAXIMUM RESIDUAL'
1999 call this%innertab%initialize_column(tag, 15, alignment=
tabright)
2000 tag =
'MAXIMUM RESIDUAL MODEL-(CELLID)'
2005 call this%innertab%set_maxbound(itertot_timestep)
2006 call this%innertab%set_iout(iu)
2011 do k = 1, itertot_timestep
2012 iinner = this%cnvg_summary%itinner(k)
2013 if (iinner <= i0)
then
2016 if (im > this%convnmod)
then
2019 do j = 1, this%convnmod
2020 if (abs(this%cnvg_summary%convdvmax(j, k)) > abs(dv))
then
2021 locdv = this%cnvg_summary%convlocdv(j, k)
2022 dv = this%cnvg_summary%convdvmax(j, k)
2024 if (abs(this%cnvg_summary%convrmax(j, k)) > abs(res))
then
2025 locdr = this%cnvg_summary%convlocr(j, k)
2026 res = this%cnvg_summary%convrmax(j, k)
2030 locdv = this%cnvg_summary%convlocdv(im, k)
2031 locdr = this%cnvg_summary%convlocr(im, k)
2032 dv = this%cnvg_summary%convdvmax(im, k)
2033 res = this%cnvg_summary%convrmax(im, k)
2035 call this%sln_get_loc(locdv, loc_dvmax_str)
2036 call this%sln_get_loc(locdr, loc_rmax_str)
2039 call this%innertab%add_term(k)
2040 call this%innertab%add_term(iouter)
2041 call this%innertab%add_term(iinner)
2042 call this%innertab%add_term(dv)
2043 call this%innertab%add_term(adjustr(trim(loc_dvmax_str)))
2044 call this%innertab%add_term(res)
2045 call this%innertab%add_term(adjustr(trim(loc_rmax_str)))
2058 niter, istart, kstart)
2063 integer(I4B),
intent(in) :: iu
2064 real(DP),
intent(in) :: totim
2065 integer(I4B),
intent(in) :: kper
2066 integer(I4B),
intent(in) :: kstp
2067 integer(I4B),
intent(in) :: kouter
2068 integer(I4B),
intent(in) :: niter
2069 integer(I4B),
intent(in) :: istart
2070 integer(I4B),
intent(in) :: kstart
2072 integer(I4B) :: itot
2073 integer(I4B) :: m_idx, j, k
2074 integer(I4B) :: kpos
2075 integer(I4B) :: loc_dvmax
2076 integer(I4B) :: loc_rmax
2077 integer(I4B) :: model_id, node_user
2087 kpos = kstart + k - 1
2088 write (iu,
'(*(G0,:,","))', advance=
'NO') &
2089 itot, totim, kper, kstp, kouter, k
2094 do j = 1, this%convnmod
2095 if (abs(this%cnvg_summary%convdvmax(j, kpos)) > abs(dvmax))
then
2096 loc_dvmax = this%cnvg_summary%convlocdv(j, kpos)
2097 dvmax = this%cnvg_summary%convdvmax(j, kpos)
2099 if (abs(this%cnvg_summary%convrmax(j, kpos)) > abs(rmax))
then
2100 loc_rmax = this%cnvg_summary%convlocr(j, kpos)
2101 rmax = this%cnvg_summary%convrmax(j, kpos)
2106 if (dvmax ==
dzero) loc_dvmax = 0
2107 if (rmax ==
dzero) loc_rmax = 0
2110 if (loc_dvmax > 0)
then
2111 call this%sln_get_nodeu(loc_dvmax, m_idx, node_user)
2113 model_id = num_mod%id
2118 write (iu,
'(*(G0,:,","))', advance=
'NO')
'', dvmax, model_id, node_user
2121 if (loc_rmax > 0)
then
2122 call this%sln_get_nodeu(loc_rmax, m_idx, node_user)
2124 model_id = num_mod%id
2129 write (iu,
'(*(G0,:,","))', advance=
'NO')
'', rmax, model_id, node_user
2133 write (iu,
'(*(G0,:,","))', advance=
'NO') &
2134 '', trim(adjustl(this%caccel(kpos)))
2139 do j = 1, this%cnvg_summary%convnmod
2140 loc_dvmax = this%cnvg_summary%convlocdv(j, kpos)
2141 dvmax = this%cnvg_summary%convdvmax(j, kpos)
2142 loc_rmax = this%cnvg_summary%convlocr(j, kpos)
2143 rmax = this%cnvg_summary%convrmax(j, kpos)
2146 if (loc_dvmax > 0)
then
2147 call this%sln_get_nodeu(loc_dvmax, m_idx, node_user)
2151 write (iu,
'(*(G0,:,","))', advance=
'NO')
'', dvmax, node_user
2154 if (loc_rmax > 0)
then
2155 call this%sln_get_nodeu(loc_rmax, m_idx, node_user)
2159 write (iu,
'(*(G0,:,","))', advance=
'NO')
'', rmax, node_user
2164 write (iu,
'(a)')
''
2186 character(len=*),
intent(in) :: filename
2188 integer(I4B) :: inunit
2190 select type (spm => this%system_matrix)
2193 open (unit=inunit, file=filename, status=
'unknown')
2194 write (inunit, *)
'ia'
2195 write (inunit, *) spm%ia
2196 write (inunit, *)
'ja'
2197 write (inunit, *) spm%ja
2198 write (inunit, *)
'amat'
2199 write (inunit, *) spm%amat
2200 write (inunit, *)
'rhs'
2201 write (inunit, *) this%rhs
2202 write (inunit, *)
'x'
2203 write (inunit, *) this%x
2239 models => this%modellist
2256 select type (exchange)
2267 type(
listtype),
pointer :: exchanges
2269 exchanges => this%exchangelist
2294 do im = 1, this%modellist%Count()
2296 call mp%model_ac(this%sparse)
2303 do ic = 1, this%exchangelist%Count()
2305 call cp%exg_ac(this%sparse)
2310 call this%sparse%sort()
2311 call this%system_matrix%init(this%sparse, this%name)
2312 call this%sparse%destroy()
2317 do im = 1, this%modellist%Count()
2319 call mp%model_mc(this%system_matrix)
2323 do ic = 1, this%exchangelist%Count()
2325 call cp%exg_mc(this%system_matrix)
2340 call this%system_matrix%zero_entries()
2341 call this%vec_rhs%zero_entries()
2350 subroutine sln_ls(this, kiter, kstp, kper, in_iter, iptc, ptcf)
2353 integer(I4B),
intent(in) :: kiter
2354 integer(I4B),
intent(in) :: kstp
2355 integer(I4B),
intent(in) :: kper
2356 integer(I4B),
intent(inout) :: in_iter
2357 integer(I4B),
intent(inout) :: iptc
2358 real(DP),
intent(in) :: ptcf
2360 logical(LGP) :: lsame
2362 integer(I4B) :: irow_glo
2363 integer(I4B) :: itestmat
2364 integer(I4B) :: ipos
2365 integer(I4B) :: icol_s
2366 integer(I4B) :: icol_e
2367 integer(I4B) :: jcol
2368 integer(I4B) :: iptct
2369 integer(I4B) :: iallowptc
2375 character(len=50) :: fname
2376 character(len=*),
parameter :: fmtfname =
"('mf6mat_', i0, '_', i0, &
2377 &'_', i0, '_', i0, '.txt')"
2380 do ieq = 1, this%neq
2383 irow_glo = ieq + this%matrix_offset
2386 this%xtemp(ieq) = this%x(ieq)
2390 if (this%active(ieq) > 0)
then
2392 adiag = abs(this%system_matrix%get_diag_value(irow_glo))
2393 if (adiag <
dem15)
then
2394 call this%system_matrix%set_diag_value(irow_glo, diagval)
2395 this%rhs(ieq) = this%rhs(ieq) + diagval * this%x(ieq)
2399 call this%system_matrix%set_diag_value(irow_glo,
done)
2400 call this%system_matrix%zero_row_offdiag(irow_glo)
2401 this%rhs(ieq) = this%x(ieq)
2407 do ieq = 1, this%neq
2408 if (this%active(ieq) > 0)
then
2409 icol_s = this%system_matrix%get_first_col_pos(ieq)
2410 icol_e = this%system_matrix%get_last_col_pos(ieq)
2411 do ipos = icol_s, icol_e
2412 jcol = this%system_matrix%get_column(ipos)
2413 if (jcol == ieq) cycle
2414 if (this%active(jcol) < 0)
then
2415 this%rhs(ieq) = this%rhs(ieq) - &
2416 (this%system_matrix%get_value_pos(ipos) * &
2418 call this%system_matrix%set_value_pos(ipos,
dzero)
2430 if (this%iallowptc < 0)
then
2439 iallowptc = this%iallowptc
2443 iptct = iptc * iallowptc
2447 if (iptct /= 0)
then
2448 call this%sln_l2norm(l2norm)
2451 if (kiter == 1)
then
2452 if (kper > 1 .or. kstp > 1)
then
2453 if (l2norm <= this%l2norm0)
then
2458 lsame =
is_close(l2norm, this%l2norm0)
2464 iptct = iptc * iallowptc
2465 if (iptct /= 0)
then
2466 if (kiter == 1)
then
2467 if (this%iptcout > 0)
then
2468 write (this%iptcout,
'(A10,6(1x,A15))')
'OUTER ITER', &
2469 ' PTCDEL',
' L2NORM0',
' L2NORM', &
2470 ' RHSNORM',
' 1/PTCDEL',
' RHSNORM/L2NORM'
2472 if (this%ptcdel0 >
dzero)
then
2473 this%ptcdel = this%ptcdel0
2475 if (this%iptcopt == 0)
then
2478 this%ptcdel =
done / ptcf
2481 do ieq = 1, this%neq
2482 if (this%active(ieq) .gt. 0)
then
2483 bnorm = bnorm + this%rhs(ieq) * this%rhs(ieq)
2487 this%ptcdel = bnorm / l2norm
2491 if (l2norm >
dzero)
then
2492 this%ptcdel = this%ptcdel * (this%l2norm0 / l2norm)**this%ptcexp
2497 if (this%ptcdel >
dzero)
then
2498 ptcval =
done / this%ptcdel
2503 do ieq = 1, this%neq
2504 irow_glo = ieq + this%matrix_offset
2505 if (this%active(ieq) > 0)
then
2506 diagval = abs(this%system_matrix%get_diag_value(irow_glo))
2507 bnorm = bnorm + this%rhs(ieq) * this%rhs(ieq)
2508 call this%system_matrix%add_diag_value(irow_glo, -ptcval)
2509 this%rhs(ieq) = this%rhs(ieq) - ptcval * this%x(ieq)
2513 if (this%iptcout > 0)
then
2514 write (this%iptcout,
'(i10,5(1x,e15.7),1(1x,f15.6))') &
2515 kiter, this%ptcdel, this%l2norm0, l2norm, bnorm, &
2516 ptcval, bnorm / l2norm
2518 this%l2norm0 = l2norm
2525 if (itestmat == 1)
then
2526 write (fname, fmtfname) this%id, kper, kstp, kiter
2527 print *,
'Saving amat to: ', trim(adjustl(fname))
2530 open (itestmat, file=trim(adjustl(fname)))
2531 write (itestmat, *)
'NODE, RHS, AMAT FOLLOW'
2532 do ieq = 1, this%neq
2533 irow_glo = ieq + this%matrix_offset
2534 icol_s = this%system_matrix%get_first_col_pos(irow_glo)
2535 icol_e = this%system_matrix%get_last_col_pos(irow_glo)
2536 write (itestmat,
'(*(G0,:,","))') &
2539 (this%system_matrix%get_column(ipos), ipos=icol_s, icol_e), &
2540 (this%system_matrix%get_value_pos(ipos), ipos=icol_s, icol_e)
2551 call this%imslinear%imslinear_apply(this%icnvg, kstp, kiter, in_iter, &
2552 this%nitermax, this%convnmod, &
2553 this%convmodstart, this%caccel, &
2556 call this%linear_solver%solve(kiter, this%vec_rhs, &
2557 this%vec_x, this%cnvg_summary)
2558 in_iter = this%linear_solver%iteration_number
2559 this%icnvg = this%linear_solver%is_converged
2572 integer(I4B),
intent(in) :: ifdparam
2575 select case (ifdparam)
2583 this%amomentum =
dzero
2587 this%res_lim =
dzero
2595 this%akappa = 0.0001d0
2597 this%amomentum =
dzero
2601 this%res_lim =
dzero
2609 this%akappa = 0.0001d0
2611 this%amomentum =
dzero
2615 this%res_lim = 0.002d0
2631 integer(I4B),
intent(in) :: kiter
2633 character(len=7) :: cmsg
2635 integer(I4B) :: btflag
2636 integer(I4B) :: ibflag
2637 integer(I4B) :: ibtcnt
2645 call this%sln_buildsystem(kiter, inewton=0)
2649 if (kiter == 1)
then
2650 call this%sln_l2norm(this%res_prev)
2651 resin = this%res_prev
2654 call this%sln_l2norm(this%res_new)
2655 resin = this%res_new
2659 if (this%res_new > this%res_prev * this%btol)
then
2662 btloop:
do nb = 1, this%numtrack
2665 call this%sln_backtracking_xupdate(btflag)
2668 if (btflag == 0)
then
2676 call this%sln_buildsystem(kiter, inewton=0)
2680 call this%sln_l2norm(this%res_new)
2683 if (nb == this%numtrack)
then
2687 if (this%res_new < this%res_prev * this%btol)
then
2691 if (this%res_new < this%res_lim)
then
2697 this%res_prev = this%res_new
2701 if (this%iprims > 0)
then
2702 if (ibtcnt > 0)
then
2709 call this%outertab%add_term(
'Backtracking')
2710 call this%outertab%add_term(kiter)
2711 call this%outertab%add_term(
' ')
2712 if (this%numtrack > 0)
then
2713 call this%outertab%add_term(ibflag)
2714 call this%outertab%add_term(ibtcnt)
2715 call this%outertab%add_term(resin)
2716 call this%outertab%add_term(this%res_prev)
2718 call this%outertab%add_term(
' ')
2719 call this%outertab%add_term(cmsg)
2720 call this%outertab%add_term(
' ')
2733 integer(I4B),
intent(inout) :: bt_flag
2735 bt_flag = this%get_backtracking_flag()
2738 if (bt_flag > 0)
then
2739 call this%apply_backtracking()
2748 integer(I4B) :: bt_flag
2753 real(dp) :: dx_abs_max
2761 if (this%active(n) < 1) cycle
2762 dx = this%x(n) - this%xtemp(n)
2764 if (dx_abs > dx_abs_max) dx_abs_max = dx_abs
2768 if (this%breduc * dx_abs_max >= this%dvclose)
then
2783 if (this%active(n) < 1) cycle
2784 delx = this%breduc * (this%x(n) - this%xtemp(n))
2785 this%x(n) = this%xtemp(n) + delx
2808 vec_resid => this%system_matrix%create_vec(this%neq)
2809 call this%sln_calc_residual(vec_resid)
2812 l2norm = vec_resid%norm2()
2815 call vec_resid%destroy()
2816 deallocate (vec_resid)
2827 integer(I4B),
intent(in) :: nsize
2828 real(DP),
dimension(nsize),
intent(in) :: v
2829 real(DP),
intent(inout) :: vmax
2841 if (denom ==
dzero)
then
2846 dnorm = abs(d) / denom
2847 if (dnorm >
done)
then
2861 integer(I4B),
intent(in) :: neq
2862 integer(I4B),
dimension(neq),
intent(in) :: active
2863 real(DP),
dimension(neq),
intent(in) :: x
2864 real(DP),
dimension(neq),
intent(in) :: xtemp
2865 real(DP),
dimension(neq),
intent(inout) :: dx
2872 if (active(n) < 1)
then
2875 dx(n) = x(n) - xtemp(n)
2884 integer(I4B) :: iptc
2895 vec_resid => this%system_matrix%create_vec(this%neq)
2896 call this%sln_calc_residual(vec_resid)
2899 do im = 1, this%modellist%Count()
2901 call mp%model_ptc(vec_resid, iptc, ptcf)
2905 call vec_resid%destroy()
2906 deallocate (vec_resid)
2918 call this%system_matrix%multiply(this%vec_x, vec_resid)
2920 call vec_resid%axpy(-1.0_dp, this%vec_rhs)
2923 if (this%active(n) < 1)
then
2924 call vec_resid%set_value_local(n, 0.0_dp)
2938 integer(I4B),
intent(in) :: kiter
2939 real(DP),
intent(in) :: bigch
2940 integer(I4B),
intent(in) :: neq
2941 integer(I4B),
dimension(neq),
intent(in) :: active
2942 real(DP),
dimension(neq),
intent(inout) :: x
2943 real(DP),
dimension(neq),
intent(in) :: xtemp
2954 if (this%nonmeth == 1)
then
2958 if (active(n) < 1) cycle
2961 delx = x(n) - xtemp(n)
2962 this%dxold(n) = delx
2965 x(n) = xtemp(n) + this%gamma * delx
2969 else if (this%nonmeth == 2)
then
2975 if (kiter == 1)
then
2977 this%relaxold =
done
2978 this%bigchold = bigch
2982 es = this%bigch / (this%bigchold * this%relaxold)
2984 if (es < -
done)
then
2990 this%relaxold = relax
2993 this%bigchold = (
done - this%gamma) * this%bigch + this%gamma * &
2997 if (relax <
done)
then
3001 if (active(n) < 1) cycle
3004 delx = x(n) - xtemp(n)
3005 this%dxold(n) = delx
3006 x(n) = xtemp(n) + relax * delx
3011 else if (this%nonmeth == 3)
then
3015 if (active(n) < 1) cycle
3018 delx = x(n) - xtemp(n)
3021 if (kiter == 1)
then
3022 this%wsave(n) =
done
3023 this%hchold(n) =
dem20
3024 this%deold(n) =
dzero
3031 if (this%deold(n) * delx <
dzero)
then
3032 ww = this%theta * this%wsave(n)
3035 ww = this%wsave(n) + this%akappa
3041 if (kiter == 1)
then
3042 this%hchold(n) = delx
3044 this%hchold(n) = (
done - this%gamma) * delx + &
3045 this%gamma * this%hchold(n)
3049 this%deold(n) = delx
3050 this%dxold(n) = delx
3054 if (kiter > 4) amom = this%amomentum
3055 delx = delx * ww + amom * this%hchold(n)
3056 x(n) = xtemp(n) + delx
3071 real(DP),
intent(inout) :: hncg
3072 integer(I4B),
intent(inout) :: lrch
3086 if (this%active(n) < 1) cycle
3087 hdif = this%x(n) - this%xtemp(n)
3089 if (ahdif > abigch)
then
3104 logical(LGP) :: has_converged
3106 has_converged = .false.
3107 if (abs(max_dvc) <= this%dvclose)
then
3108 has_converged = .true.
3118 real(dp),
intent(in) :: dpak
3119 character(len=LENPAKLOC),
intent(in) :: cpakout
3120 integer(I4B),
intent(in) :: iend
3122 integer(I4B) :: ivalue
3124 if (abs(dpak) > this%dvclose)
then
3129 'PACKAGE (', trim(cpakout),
') CAUSED CONVERGENCE FAILURE'
3141 integer(I4B),
intent(in) :: inewtonur
3143 integer(I4B) :: ivalue
3152 result(has_converged)
3154 real(dp),
intent(in) :: dxold_max
3155 real(dp),
intent(in) :: hncg
3156 logical(LGP) :: has_converged
3158 has_converged = .false.
3159 if (abs(dxold_max) <= this%dvclose .and. &
3160 abs(hncg) <= this%dvclose)
then
3161 has_converged = .true.
3173 integer(I4B),
intent(in) :: nodesln
3174 character(len=*),
intent(inout) :: str
3178 integer(I4B) :: istart
3179 integer(I4B) :: iend
3180 integer(I4B) :: noder
3181 integer(I4B) :: nglo
3190 nglo = nodesln + this%matrix_offset
3193 do i = 1, this%modellist%Count()
3197 call mp%get_mrange(istart, iend)
3198 if (nglo >= istart .and. nglo <= iend)
then
3199 noder = nglo - istart + 1
3200 call mp%get_mcellid(noder, str)
3214 integer(I4B),
intent(in) :: nodesln
3215 integer(I4B),
intent(inout) :: im
3216 integer(I4B),
intent(inout) :: nodeu
3220 integer(I4B) :: istart
3221 integer(I4B) :: iend
3222 integer(I4B) :: noder, nglo
3228 nglo = nodesln + this%matrix_offset
3231 do i = 1, this%modellist%Count()
3235 call mp%get_mrange(istart, iend)
3236 if (nglo >= istart .and. nglo <= iend)
then
3237 noder = nglo - istart + 1
3238 call mp%get_mnodeu(noder, nodeu)
3252 class(*),
pointer,
intent(inout) :: obj
3260 if (.not.
associated(obj))
return
3276 type(
listtype),
intent(inout) :: list
3277 integer(I4B),
intent(in) :: idx
3281 class(*),
pointer :: obj
3283 obj => list%GetItem(idx)
subroutine, public ats_submit_delt(kstp, kper, dt, sloc, idir)
@ brief Allow and external caller to submit preferred time step
subroutine, public addbasesolutiontolist(list, solution)
This module contains block parser methods.
This module contains simulation constants.
integer(i4b), parameter linelength
maximum length of a standard line
@ tabright
right justified table column
@ tableft
left justified table column
@ mvalidate
validation mode - do not run time steps
@ mnormal
normal output mode
real(dp), parameter dem20
real constant 1e-20
real(dp), parameter dep3
real constant 1000
integer(i4b), parameter lensolutionname
maximum length of the solution name
real(dp), parameter dep6
real constant 1000000
real(dp), parameter donethird
real constant 1/3
real(dp), parameter dnodata
real no data constant
integer(i4b), parameter lenpakloc
maximum length of a package location
real(dp), parameter dep20
real constant 1e20
real(dp), parameter dem1
real constant 1e-1
real(dp), parameter dhalf
real constant 1/2
real(dp), parameter dem3
real constant 1e-3
real(dp), parameter dem4
real constant 1e-4
real(dp), parameter dem6
real constant 1e-6
real(dp), parameter dzero
real constant zero
real(dp), parameter dprec
real constant machine precision
real(dp), parameter dem15
real constant 1e-15
real(dp), parameter dem2
real constant 1e-2
real(dp), parameter dtwo
real constant 2
integer(i4b), parameter lenmempath
maximum length of the memory path
real(dp), parameter dthree
real constant 3
real(dp), parameter done
real constant 1
subroutine pstop(status, message)
Stop the program, optionally specifying an error status code.
subroutine allocate_scalars(this)
@ brief Allocate and initialize scalars
integer(i4b), parameter, public cg_method
This module defines variable data types.
class(linearsolverbasetype) function, pointer, public create_linear_solver(solver_mode, sln_name)
Factory method to create the linear solver object.
type(listtype), public basesolutionlist
pure logical function, public is_close(a, b, rtol, atol, symmetric)
Check if a real value is approximately equal to another.
character(len=lenmempath) function create_mem_path(component, subcomponent, context)
returns the path to the memory object
Store and issue logging messages to output units.
subroutine, public write_message(text, iunit, fmt, skipbefore, skipafter, advance)
Write a message to an output unit.
class(numericalexchangetype) function, pointer, public getnumericalexchangefromlist(list, idx)
Retrieve a specific numerical exchange from a list.
subroutine, public addnumericalexchangetolist(list, exchange)
Add numerical exchange to a list.
subroutine, public addnumericalmodeltolist(list, model)
class(numericalmodeltype) function, pointer, public getnumericalmodelfromlist(list, idx)
subroutine convergence_summary(this, iu, im, itertot_timestep)
@ brief Solution convergence summary
subroutine sln_get_nodeu(this, nodesln, im, nodeu)
@ brief Get user node number
integer(i4b) function sln_sync_newtonur_flag(this, inewtonur)
Synchronize Newton Under-relaxation flag.
subroutine save(this, filename)
@ brief Save solution data to a file
subroutine sln_backtracking_xupdate(this, bt_flag)
@ brief Backtracking update of the dependent variable
logical(lgp) function sln_nur_has_converged(this, dxold_max, hncg)
Custom convergence check for when Newton UR has been applied.
logical(lgp) function sln_has_converged(this, max_dvc)
integer(i4b), parameter petsc_solver
integer(i4b) function sln_package_convergence(this, dpak, cpakout, iend)
Check package convergence.
type(listtype) function, pointer get_exchanges(this)
Returns a pointer to the list of exchanges in this solution.
subroutine sln_l2norm(this, l2norm)
@ brief Calculate the solution L-2 norm for all active cells using
subroutine sln_connect(this)
@ brief Assign solution connections
subroutine sln_get_loc(this, nodesln, str)
@ brief Get cell location string
subroutine apply_backtracking(this)
Update x with backtracking.
subroutine writecsvheader(this)
@ brief CSV header
subroutine sln_buildsystem(this, kiter, inewton)
subroutine sln_maxval(this, nsize, v, vmax)
@ brief Get the maximum value from a vector
subroutine sln_calc_residual(this, vec_resid)
Calculate the current residual vector r = A*x - b,.
subroutine sln_backtracking(this, mp, cp, kiter)
@ brief Perform backtracking
subroutine sln_calc_ptc(this, iptc, ptcf)
Calculate pseudo-transient continuation factor.
subroutine sln_underrelax(this, kiter, bigch, neq, active, x, xtemp)
@ brief Under-relaxation
class(numericalsolutiontype) function, pointer, public castasnumericalsolutionclass(obj)
@ brief Cast a object as a Numerical Solution
type(listtype) function, pointer get_models(this)
Get a list of models.
subroutine finalizesolve(this, kiter, isgcnvg, isuppress_output)
@ brief finalize a solution
subroutine sln_setouter(this, ifdparam)
@ brief Set default Picard iteration variables
subroutine sln_ls(this, kiter, kstp, kper, in_iter, iptc, ptcf)
@ brief Solve the linear system of equations
subroutine sln_calcdx(this, neq, active, x, xtemp, dx)
@ brief Calculate dependent-variable change
integer(i4b), parameter ims_solver
subroutine csv_convergence_summary(this, iu, totim, kper, kstp, kouter, niter, istart, kstart)
@ brief Solution convergence CSV summary
subroutine sln_reset(this)
@ brief Reset the solution
class(numericalsolutiontype) function, pointer, public getnumericalsolutionfromlist(list, idx)
@ brief Get a numerical solution
subroutine allocate_arrays(this)
@ brief Allocate arrays
integer(i4b) function get_backtracking_flag(this)
Check if backtracking should be applied for this solution,.
subroutine preparesolve(this)
@ brief prepare to solve
subroutine writeptcinfotofile(this, kper)
@ brief PTC header
subroutine add_exchange(this, exchange)
Add exchange.
subroutine add_model(this, mp)
@ brief Add a model
subroutine, public create_numerical_solution(num_sol, filename, id)
@ brief Create a new solution
subroutine sln_get_dxmax(this, hncg, lrch)
@ brief Determine maximum dependent-variable change
This module contains simulation methods.
subroutine, public store_error(msg, terminate)
Store an error message.
integer(i4b) function, public count_errors()
Return number of errors.
subroutine, public deprecation_warning(cblock, cvar, cver, endmsg, iunit)
Store deprecation warning message.
integer(i4b), parameter, public stg_bfr_exg_ad
before exchange advance (per solution)
integer(i4b), parameter, public stg_bfr_exg_cf
before exchange calculate (per solution)
integer(i4b), parameter, public stg_bfr_exg_fc
before exchange formulate (per solution)
integer(i4b), parameter, public stg_bfr_exg_ac
before exchange add connections (per solution)
This module contains simulation variables.
character(len=maxcharlen) errmsg
error message string
character(len=linelength) simulation_mode
integer(i4b) iout
file unit number for simulation output
integer(i4b) isim_mode
simulation mode
subroutine, public table_cr(this, name, title)
real(dp), pointer, public totim
time relative to start of simulation
integer(i4b), pointer, public kstp
current time step number
integer(i4b), pointer, public kper
current stress period number
real(dp), pointer, public delt
length of the current time step
subroutine, public code_timer(it, t1, ts)
Get end time and calculate elapsed time.
This module contains version information.
integer(i4b), parameter idevelopmode
Highest level model type. All models extend this parent type.
This structure stores the generic convergence info for a solution.
Abstract type for linear solver.
A generic heterogeneous doubly-linked list.