68 integer (c_int) :: imonth
69 integer (c_int) :: iraingagezone
70 integer (c_int) :: ifragmentset
71 real (c_float) :: ffragmentvalue(31)
82 integer (c_int) :: iraingagezone
83 integer (c_int) :: inumberoffragments(12)
84 integer (c_int) :: istartrecord(12)
100 integer (c_int) :: sim_number
101 integer (c_int) :: sim_month
102 integer (c_int) :: sim_rainfall_zone
103 integer (c_int) :: sim_year
104 real (c_float) :: sim_random_number
105 integer (c_int) :: sim_selected_set
125 logical (c_bool),
intent(in) :: lactive(:,:)
128 integer (c_int) :: istat
131 integer (c_int) :: imaxrainzones
132 integer (c_int),
allocatable :: isimulationnumbers(:)
133 character (len=256) :: error_str
136 call cf_dict%get_values( skey=
"FRAGMENTS_SEQUENCE_SIMULATION_NUMBER", ivalues=isimulationnumbers )
140 prainfall_zone =>
dat%find(
"RAINFALL_ZONE")
141 if ( .not.
associated(prainfall_zone) ) &
142 call die(
"A RAINFALL_ZONE grid must be supplied in order to make use of this option.", &
146 call assert( istat == 0,
"Problem allocating memory", __file__, __line__ )
148 call prainfall_zone%getvalues()
151 rain_gage_id = pack( prainfall_zone%pGrdBase%iData, lactive )
154 call assert( istat == 0,
"Problem allocating memory", __file__, __line__ )
157 call assert( istat == 0,
"Problem allocating memory", __file__, __line__ )
161 call cf_dict%get_values( skey=
"FRAGMENTS_DAILY_FILE", slstring=slstring )
168 call slstring%clear()
171 call cf_dict%get_values( skey=
"FRAGMENTS_SEQUENCE_FILE", slstring=slstring )
173 if ( .not. ( slstring%get(1) .strequal.
"<NA>" ) )
then
177 call assert( istat == 0,
"Problem allocating memory", __file__, __line__ )
183 imaxrainzones = maxval(
fragments%iRainGageZone)
186 call assert( istat == 0,
"Problem allocating memory", __file__, __line__ )
190 call assert( istat == 0,
"Problem allocating memory, stat="//
ascharacter(istat) &
191 //
"; msg: "//trim(error_str), __file__, __line__ )
196 call assert( istat == 0,
"Problem allocating memory, stat="//
ascharacter(istat) &
197 //
"; msg: "//trim(error_str), __file__, __line__ )
206 "Simulation_Number, Month, Rain_Zone, Year, Random_Number, Fragment_Set,"
214 character (len=*),
intent(in) :: sfilename
217 character (len=512) :: srecord, ssubstring
218 integer (c_int) :: istat
219 integer (c_int) :: icount
220 integer (c_int) :: iindex
221 integer (c_int) :: last_zone
222 integer (c_int) :: last_fragment
223 integer (c_int) :: last_month
224 integer (c_int) :: inumlines
225 real (c_float) :: ftempvalue
228 allocate(fragments_file)
230 call fragments_file%open( sfilename = sfilename, &
231 scommentchars =
"#%!", &
232 sdelimiters =
"WHITESPACE", &
233 lhasheader = .
false._c_bool )
235 inumlines = fragments_file%numLines()
237 allocate(
fragments( inumlines ), stat=istat )
238 call assert( istat == 0,
"Problem allocating memory for fragments table", __file__, __line__ )
248 srecord = fragments_file%readLine()
250 if ( fragments_file%isEOF() )
exit
255 call chomp(srecord, ssubstring, fragments_file%sDelimiters )
257 if ( len_trim(ssubstring) == 0 ) &
258 call die(
"Missing month number in the daily fragments file", &
259 __file__, __line__,
"Problem occured on line number " &
261 //
" of file "//
dquote(sfilename) )
266 if (
fragments(icount)%iMonth == (last_month + 1) )
then
271 if (
fragments(icount)%iMonth < last_month ) &
272 call die(
"Out-of-order month value in the daily fragments file", &
273 __file__, __line__,
"Problem occured on line number " &
275 //
" of file "//
dquote(sfilename) )
280 call chomp(srecord, ssubstring, fragments_file%sDelimiters )
282 if ( len_trim(ssubstring) == 0 ) &
283 call die(
"Missing rain gage zone number in the daily fragments file", &
284 __file__, __line__,
"Problem occured on line number " &
286 //
" of file "//
dquote(sfilename) )
290 if (
fragments(icount)%iRainGageZone < last_zone ) &
291 call die(
"Rain gage zone number out of order in the daily fragments file", &
292 __file__, __line__,
"Problem occured on line number " &
294 //
" of file "//
dquote(sfilename) )
297 if (
fragments(icount)%iRainGageZone == (last_zone + 1) ) &
300 last_zone =
fragments(icount)%iRainGageZone
303 call chomp(srecord, ssubstring, fragments_file%sDelimiters )
305 if ( len_trim(ssubstring) == 0 ) &
306 call die(
"Missing fragment set number in the daily fragments file", &
307 __file__, __line__,
"Problem occured on line number " &
309 //
" of file "//
dquote(sfilename) )
313 if (
fragments(icount)%iFragmentSet /= (last_fragment + 1) ) &
314 call die(
"Missing or out-of-order fragment value in the daily fragments file", &
315 __file__, __line__,
"Problem occured on line number " &
317 //
" of file "//
dquote(sfilename) )
319 last_fragment =
fragments(icount)%iFragmentSet
325 call chomp(srecord, ssubstring, fragments_file%sDelimiters )
327 if ( len_trim(ssubstring) == 0 ) &
328 call die(
"Missing fragment value in the daily fragments file", &
329 __file__, __line__,
"Problem occured on line number " &
331 //
" of file "//
dquote(sfilename) )
333 ftempvalue =
asfloat( ssubstring )
338 if ( ( ftempvalue < 0.0_c_float ) .or. ( ftempvalue > 1.0_c_float ) )
then
339 fragments(icount)%fFragmentValue(iindex) = 0.0_c_float
341 fragments(icount)%fFragmentValue(iindex) = ftempvalue
351 itab=31, ilinesafter=1, iloglevel=
log_all)
362 integer (c_int) :: iCount
363 integer (c_int) :: iIndex
364 integer (c_int) :: iRainGageZone
365 integer (c_int) :: iPreviousRainGageZone
366 integer (c_int) :: iMonth
367 integer (c_int) :: iPreviousMonth
368 character (len=10) :: sBuf0
369 character (len=10) :: sBuf1
370 character (len=12) :: sBuf2
371 character (len=10) :: sBuf3
372 character (len=52) :: sBuf4
379 ipreviousraingagezone = iraingagezone
393 iraingagezone =
fragments(iindex)%iRainGageZone
396 if ( iraingagezone /= ipreviousraingagezone )
then
401 fragments_sets( ipreviousraingagezone )%iNumberOfFragments(ipreviousmonth) = icount
414 ipreviousmonth = imonth
415 ipreviousraingagezone = iraingagezone
420 fragments_sets( iraingagezone )%iNumberOfFragments(imonth) = icount
422 call logs%write(
"### Summary of fragment sets in memory ###", &
423 iloglevel=
log_all, ilinesbefore=1, ilinesafter=1, lecho=
false )
424 call logs%write(
"gage number | month | start index | num records ")
425 call logs%write(
"----------- | ---------- | ------------ | ------------")
428 write (sbuf0, fmt=
"(i10)") iindex
429 write (sbuf1, fmt=
"(i10)") imonth
430 write (sbuf2, fmt=
"(i12)")
fragments_sets(iindex)%iStartRecord(imonth)
431 write (sbuf3, fmt=
"(i10)")
fragments_sets(iindex)%iNumberOfFragments(imonth)
432 write (sbuf4, fmt=
"(a10,' | ', a10,' | ', a12,' | ',a10)") adjustl(sbuf0), &
433 adjustl(sbuf1), adjustl(sbuf2), adjustl(sbuf3)
434 call logs%write( sbuf4 )
445 integer (c_int),
intent(in) :: iCount
448 real (c_float) :: sum_fragments
452 if (
fragments(icount)%fFragmentValue(29) > 0.0_c_float)
then
453 sum_fragments = sum(
fragments(icount)%fFragmentValue(1:28) )
459 fragments(icount)%fFragmentValue(29:31) = 0.0_c_float
471 character (len=*),
intent(in) :: sFilename
474 character (len=512) :: sRecord, sSubstring
475 integer (c_int) :: iStat
476 integer (c_int) :: iCount
477 integer (c_int) :: iIndex
478 integer (c_int) :: iNumLines
479 type (ASCII_FILE_T),
allocatable :: SEQUENCE_FILE
480 character (len=10) :: sBuf0
481 character (len=10) :: sBuf1
482 character (len=12) :: sBuf2
483 character (len=10) :: sBuf3
484 character (len=10) :: sBuf4
485 character (len=256) :: sBuf5
486 character (len=256) :: error_str
487 type (FSTRING_LIST_T) :: slHeader
488 integer (c_int) :: max_rain_gage_number
489 integer (c_int) :: max_simulation_number
491 allocate(sequence_file)
493 call sequence_file%open( sfilename = sfilename, &
494 scommentchars =
"#%!", &
495 sdelimiters =
"WHITESPACE", &
496 lhasheader = .
true._c_bool )
498 slheader = sequence_file%readHeader()
500 inumlines = sequence_file%numLines()
503 call assert( istat == 0,
"Problem allocating memory for fragments sequence table", &
511 srecord = sequence_file%readLine()
513 if ( sequence_file%isEOF() )
exit
518 call chomp(srecord, ssubstring, sequence_file%sDelimiters )
520 if ( len_trim(ssubstring) == 0 ) &
521 call die(
"Missing simulation number in the fragments sequence file", &
522 __file__, __line__,
"Problem occured on line number " &
524 //
" of file "//
dquote(sfilename) )
529 call chomp(srecord, ssubstring, sequence_file%sDelimiters )
531 if ( len_trim(ssubstring) == 0 ) &
532 call die(
"Missing month number in the fragments sequence file", &
533 __file__, __line__,
"Problem occured on line number " &
535 //
" of file "//
dquote(sfilename) )
540 call chomp(srecord, ssubstring, sequence_file%sDelimiters )
542 if ( len_trim(ssubstring) == 0 ) &
543 call die(
"Missing rainfall zone number in the fragments sequence file", &
544 __file__, __line__,
"Problem occured on line number " &
546 //
" of file "//
dquote(sfilename) )
552 call chomp(srecord, ssubstring, sequence_file%sDelimiters )
554 if ( len_trim(ssubstring) == 0 ) &
555 call die(
"Missing year number in the fragments sequence file", &
556 __file__, __line__,
"Problem occured on line number " &
558 //
" of file "//
dquote(sfilename) )
563 call chomp(srecord, ssubstring, sequence_file%sDelimiters )
565 if ( len_trim(ssubstring) == 0 ) &
566 call die(
"Missing simulation random number in the fragments sequence file", &
567 __file__, __line__,
"Problem occured on line number " &
569 //
" of file "//
dquote(sfilename) )
574 call chomp(srecord, ssubstring, sequence_file%sDelimiters )
576 if ( len_trim(ssubstring) == 0 ) &
577 call die(
"Missing selected fragment set number in the fragments sequence file", &
578 __file__, __line__,
"Problem occured on line number " &
580 //
" of file "//
dquote(sfilename) )
596 call assert( istat == 0,
"Problem deallocating memory, stat="//
ascharacter(istat) &
597 //
"; msg: "//trim(error_str), __file__, __line__ )
599 allocate(
current_fragments(max_rain_gage_number, max_simulation_number), stat=istat, &
601 call assert( istat == 0,
"Problem allocating memory, stat="//
ascharacter(istat) &
602 //
"; msg: "//trim(error_str), __file__, __line__ )
606 call assert( istat == 0,
"Problem deallocating memory, stat="//
ascharacter(istat) &
607 //
"; msg: "//trim(error_str), __file__, __line__ )
609 allocate(
random_values(max_rain_gage_number, max_simulation_number), stat=istat, &
611 call assert( istat == 0,
"Problem allocating memory, stat="//
ascharacter(istat) &
612 //
"; msg: "//trim(error_str), __file__, __line__ )
614 call logs%write(
"### Summary of fragment sequence sets in memory ###", &
616 call logs%write(
"sim number | rainfall zone | month | year | selected set ")
617 call logs%write(
"----------- | ---------- | ------------ | ------------|------------")
625 write (sbuf5, fmt=
"(a,' | ', a,' | ', a,' | ',a,' | ',a)") &
626 adjustl(sbuf0), adjustl(sbuf1), adjustl(sbuf2), adjustl(sbuf3), adjustl(sbuf4)
627 call logs%write( trim( sbuf5 ) )
647 logical (c_bool),
intent(in) :: lShuffle
650 integer (c_int) :: rain_zone
651 integer (c_int) :: iMaxRainZones
652 integer (c_int) :: iMonth
653 integer (c_int) :: iDay
654 integer (c_int) :: iYearOfSimulation
656 integer (c_int) :: iNumberOfFragments
657 integer (c_int) :: iStartRecord
658 integer (c_int) :: iEndRecord
659 integer (c_int) :: iTargetRecord
660 integer (c_int) :: iUBOUND_FRAGMENTS
661 integer (c_int) :: iUBOUND_CURRENT_FRAGMENTS
664 imaxrainzones = maxval(
fragments%iRainGageZone)
665 imonth =
sim_dt%curr%iMonth
667 iyearofsimulation=
sim_dt%iYearOfSimulation
670 iubound_fragments = ubound(
fragments, 1)
679 do rain_zone = 1, imaxrainzones
688 inumberoffragments =
fragments_sets(rain_zone)%iNumberOfFragments(imonth)
689 iendrecord = istartrecord + inumberoffragments - 1
690 itargetrecord = istartrecord &
692 * real( inumberoffragments ))
694 if ( ( rain_zone > iubound_current_fragments ) .or. ( itargetrecord > iubound_fragments ) &
695 .or. ( rain_zone < 1 ) .or. ( itargetrecord < 1) )
then
696 call logs%write(
"Error detected in method of fragments routine; dump of current" &
697 //
" variables follows:", ilinesbefore=1)
699 call logs%write(
"simulation_number : "//
ascharacter(rain_zone), itab=3 )
701 call logs%write(
"iNumberOfFragments: "//
ascharacter(inumberoffragments), itab=3 )
703 call logs%write(
"iTargetRecord : "//
ascharacter(itargetrecord), itab=3 )
704 call logs%write(
"ubound(CURRENT_FRAGMENTS, 1): "//
ascharacter(iubound_current_fragments), &
706 call logs%write(
"ubound(FRAGMENTS, 1): "//
ascharacter(iubound_fragments), itab=3 )
707 call logs%write(
"RANDOM_VALUES(rain_zone,SIMULATION_NUMBER): " &
709 call die(
"Miscalculation in target record: calculated record index is out of bounds", &
716 write(
lu_fragments_echo,fmt=
"(4(i5,','),f10.6,',',i5,',',30(f8.3,','),f8.3)") &
719 fragments( itargetrecord)%iRainGageZone, &
722 fragments( itargetrecord)%iFragmentSet, &
732 call logs%write(
"Error detected in method of fragments routine; dump of current variables" &
733 //
" follows:", ilinesbefore=1, iloglevel=
log_all )
762 integer (c_int) :: iIndex, iIndex2
763 logical (c_bool) :: lSequenceSelection
784 if ( .not. lsequenceselection ) cycle
803 call logs%write(
"Error detected in method of fragments routine - random values " &
804 //
"not found in sequence file for rainfall zone(s):", ilinesbefore=1)
807 call logs%write(
"simulation number, rainfall zone: " &
819 use ieee_exceptions,
only : ieee_invalid, &
820 ieee_divide_by_zero, &
822 ieee_set_halting_mode, &
823 ieee_get_halting_mode
824 use ieee_arithmetic,
only : ieee_is_nan
826 logical (c_bool),
intent(in) :: lactive(:,:)
829 logical (c_bool),
save :: lfirstcall =
true
832 logical :: old_invalid, old_div0, old_overflow
836 call ieee_get_halting_mode(ieee_invalid, old_invalid)
837 call ieee_get_halting_mode(ieee_divide_by_zero, old_div0)
838 call ieee_get_halting_mode(ieee_overflow, old_overflow)
841 call ieee_set_halting_mode(ieee_invalid, .
false.)
842 call ieee_set_halting_mode(ieee_divide_by_zero, .
false.)
843 call ieee_set_halting_mode(ieee_overflow, .
false.)
847 if (
sim_dt%curr%iDay == 1 .or. lfirstcall )
then
850 prainfall_adjust_factor =>
dat%find(
"RAINFALL_ADJUST_FACTOR")
852 if ( .not.
associated(prainfall_adjust_factor) ) &
853 call die(
"A RAINFALL_ADJUST_FACTOR grid must be supplied in order to make use" &
854 //
" of this option.", __file__, __line__)
856 call prainfall_adjust_factor%getvalues(
sim_dt%curr )
862 smessage=
"NaN detected in rainfall adjustment factor grid.")
874 call ieee_set_halting_mode(ieee_invalid, old_invalid)
875 call ieee_set_halting_mode(ieee_divide_by_zero, old_div0)
876 call ieee_set_halting_mode(ieee_overflow, old_overflow)
This module contains physical constants and convenience functions aimed at performing unit conversion...
logical(c_bool), parameter, public true
logical(c_bool), parameter, public false
integer(c_int) random_start
Defines the DATA_CATALOG_T data type, which contains type-bound procedures to add,...
type(data_catalog_t), public dat
DAT is a global to hold data catalog entries.
type(dict_t), public cf_dict
subroutine, public die(smessage, smodule, iline, shints, scalledby, icalledbyline)
Provides support for input and output of gridded ASCII data, as well as for creation and destruction ...
real(c_float) function kiss64_uniform_rng()
subroutine kiss64_initialize(seed)
type(logfile_t), public logs
Module precipitation__method_of_fragments provides support for creating synthetic daily precipitation...
type(fragments_sequence_t), dimension(:), allocatable, public fragments_sequence
Array of fragment sequence sets.
real(c_float), dimension(:), allocatable, public rainfall_adjust_factor
Module variable that holds the rainfall adjustment factor.
subroutine, public precipitation_method_of_fragments_calculate(lactive)
subroutine update_fragments(lshuffle)
Update rainfall fragments on daily basis.
subroutine, public precipitation_method_of_fragments_initialize(lactive)
Initialize method of fragments.
subroutine read_fragments_sequence(sfilename)
logical(c_bool) random_fragment_sequences
Module variable detemining whether fragment sequences are chosen at random or selected from an extern...
type(ptr_fragments_t), dimension(:,:), allocatable current_fragments
Subset of rainfall fragments file pointing to the currently active fragments.
subroutine process_fragment_sets()
after fragments file has been read in, iterate over a set of rainfall fragments
integer(c_int), public simulation_number
Module variable indicating which "simulation number" is active Only has meaning if the rainfall fragm...
integer(c_int), dimension(:), allocatable, public rain_gage_id
Module variable that holds the rainfall gage (zone) number.
real(c_double), dimension(:,:), allocatable random_values
Module variable that holds a sequence of random numbers associated with the selection of the fragment...
type(fragments_set_t), dimension(:), allocatable, public fragments_sets
Array of fragments sets; fragments sets include indices to the start record associated with the fragm...
real(c_float), dimension(:), allocatable, public fragment_value
Module variable that holds the current day's rainfall fragment value.
logical(c_bool), dimension(:), allocatable sequence_selection
Module level variable used to create subsets of the FRAGMENT_SEQUENCES file.
type(fragments_t), dimension(:), allocatable, target, public fragments
Array of all fragments read in from the rainfall fragments file.
subroutine, public read_daily_fragments(sfilename)
integer(c_int) lu_fragments_echo
subroutine normalize_february_fragment_sequence(icount)
eliminate rainfall on the 29th day of February; bump up all other values to ensure sum = 1
subroutine update_random_values()
type(date_range_t), public sim_dt
Data structure that holds a single line of data from the input rainfall fragments file.
Pointer to a rainfall fragments data structure.
Data structure to hold the current active rainfall fragments for a particular rain gage zone.
Data structure to hold static (pre-calculated) fragment selection numbers.