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
130 logical (c_bool),
intent(in) :: lactive(:,:)
133 integer (c_int) :: istat
136 integer (c_int) :: imaxrainzones
137 integer (c_int),
allocatable :: isimulationnumbers(:)
138 character (len=256) :: error_str
141 call cf_dict%get_values( skey=
"FRAGMENTS_SEQUENCE_SIMULATION_NUMBER", ivalues=isimulationnumbers )
145 prainfall_zone =>
dat%find(
"RAINFALL_ZONE")
146 if ( .not.
associated(prainfall_zone) ) &
147 call die(
"A RAINFALL_ZONE grid must be supplied in order to make use of this option.", &
151 call assert( istat == 0,
"Problem allocating memory", __file__, __line__ )
153 call prainfall_zone%getvalues()
156 rain_gage_id = pack( prainfall_zone%pGrdBase%iData, lactive )
159 call assert( istat == 0,
"Problem allocating memory", __file__, __line__ )
162 call assert( istat == 0,
"Problem allocating memory", __file__, __line__ )
166 call cf_dict%get_values( skey=
"FRAGMENTS_DAILY_FILE", slstring=slstring )
173 call slstring%clear()
176 call cf_dict%get_values( skey=
"FRAGMENTS_SEQUENCE_FILE", slstring=slstring )
178 if ( .not. ( slstring%get(1) .strequal.
"<NA>" ) )
then
182 call assert( istat == 0,
"Problem allocating memory", __file__, __line__ )
188 imaxrainzones = maxval(
fragments%iRainGageZone)
191 call assert( istat == 0,
"Problem allocating memory", __file__, __line__ )
195 call assert( istat == 0,
"Problem allocating memory, stat="//
ascharacter(istat) &
196 //
"; msg: "//trim(error_str), __file__, __line__ )
201 call assert( istat == 0,
"Problem allocating memory, stat="//
ascharacter(istat) &
202 //
"; msg: "//trim(error_str), __file__, __line__ )
211 "Simulation_Number, Month, Rain_Zone, Year, Random_Number, Fragment_Set,"
219 character (len=*),
intent(in) :: sfilename
222 character (len=512) :: srecord, ssubstring
223 integer (c_int) :: istat
224 integer (c_int) :: icount
225 integer (c_int) :: iindex
226 integer (c_int) :: last_zone
227 integer (c_int) :: last_fragment
228 integer (c_int) :: last_month
229 integer (c_int) :: inumlines
230 real (c_float) :: ftempvalue
234 call fragments_file%open( sfilename = sfilename, &
235 scommentchars =
"#%!", &
236 sdelimiters =
"WHITESPACE", &
237 lhasheader = .
false._c_bool )
239 inumlines = fragments_file%numLines()
241 allocate(
fragments( inumlines ), stat=istat )
242 call assert( istat == 0,
"Problem allocating memory for fragments table", __file__, __line__ )
252 srecord = fragments_file%readLine()
254 if ( fragments_file%isEOF() )
exit
259 call chomp(srecord, ssubstring, fragments_file%sDelimiters )
261 if ( len_trim(ssubstring) == 0 ) &
262 call die(
"Missing month number in the daily fragments file", &
263 __file__, __line__,
"Problem occured on line number " &
265 //
" of file "//
dquote(sfilename) )
270 if (
fragments(icount)%iMonth == (last_month + 1) )
then
275 if (
fragments(icount)%iMonth < last_month ) &
276 call die(
"Out-of-order month value in the daily fragments file", &
277 __file__, __line__,
"Problem occured on line number " &
279 //
" of file "//
dquote(sfilename) )
284 call chomp(srecord, ssubstring, fragments_file%sDelimiters )
286 if ( len_trim(ssubstring) == 0 ) &
287 call die(
"Missing rain gage zone number in the daily fragments file", &
288 __file__, __line__,
"Problem occured on line number " &
290 //
" of file "//
dquote(sfilename) )
294 if (
fragments(icount)%iRainGageZone < last_zone ) &
295 call die(
"Rain gage zone number out of order in the daily fragments file", &
296 __file__, __line__,
"Problem occured on line number " &
298 //
" of file "//
dquote(sfilename) )
301 if (
fragments(icount)%iRainGageZone == (last_zone + 1) ) &
304 last_zone =
fragments(icount)%iRainGageZone
307 call chomp(srecord, ssubstring, fragments_file%sDelimiters )
309 if ( len_trim(ssubstring) == 0 ) &
310 call die(
"Missing fragment set number in the daily fragments file", &
311 __file__, __line__,
"Problem occured on line number " &
313 //
" of file "//
dquote(sfilename) )
317 if (
fragments(icount)%iFragmentSet /= (last_fragment + 1) ) &
318 call die(
"Missing or out-of-order fragment value in the daily fragments file", &
319 __file__, __line__,
"Problem occured on line number " &
321 //
" of file "//
dquote(sfilename) )
323 last_fragment =
fragments(icount)%iFragmentSet
329 call chomp(srecord, ssubstring, fragments_file%sDelimiters )
331 if ( len_trim(ssubstring) == 0 ) &
332 call die(
"Missing fragment value in the daily fragments file", &
333 __file__, __line__,
"Problem occured on line number " &
335 //
" of file "//
dquote(sfilename) )
337 ftempvalue =
asfloat( ssubstring )
342 if ( ( ftempvalue < 0.0_c_float ) .or. ( ftempvalue > 1.0_c_float ) )
then
343 fragments(icount)%fFragmentValue(iindex) = 0.0_c_float
345 fragments(icount)%fFragmentValue(iindex) = ftempvalue
355 itab=31, ilinesafter=1, iloglevel=
log_all)
366 integer (c_int) :: iCount
367 integer (c_int) :: iIndex
368 integer (c_int) :: iRainGageZone
369 integer (c_int) :: iPreviousRainGageZone
370 integer (c_int) :: iFragmentChunk
371 integer (c_int) :: iMonth
372 integer (c_int) :: iPreviousMonth
373 character (len=10) :: sBuf0
374 character (len=10) :: sBuf1
375 character (len=12) :: sBuf2
376 character (len=10) :: sBuf3
377 character (len=52) :: sBuf4
384 ipreviousraingagezone = iraingagezone
398 iraingagezone =
fragments(iindex)%iRainGageZone
401 if ( iraingagezone /= ipreviousraingagezone )
then
406 fragments_sets( ipreviousraingagezone )%iNumberOfFragments(ipreviousmonth) = icount
419 ipreviousmonth = imonth
420 ipreviousraingagezone = iraingagezone
425 fragments_sets( iraingagezone )%iNumberOfFragments(imonth) = icount
427 call logs%write(
"### Summary of fragment sets in memory ###", &
428 iloglevel=
log_all, ilinesbefore=1, ilinesafter=1, lecho=
false )
429 call logs%write(
"gage number | month | start index | num records ")
430 call logs%write(
"----------- | ---------- | ------------ | ------------")
433 write (sbuf0, fmt=
"(i10)") iindex
434 write (sbuf1, fmt=
"(i10)") imonth
435 write (sbuf2, fmt=
"(i12)")
fragments_sets(iindex)%iStartRecord(imonth)
436 write (sbuf3, fmt=
"(i10)")
fragments_sets(iindex)%iNumberOfFragments(imonth)
437 write (sbuf4, fmt=
"(a10,' | ', a10,' | ', a12,' | ',a10)") adjustl(sbuf0), &
438 adjustl(sbuf1), adjustl(sbuf2), adjustl(sbuf3)
439 call logs%write( sbuf4 )
450 integer (c_int),
intent(in) :: iCount
453 real (c_float) :: sum_fragments
457 if (
fragments(icount)%fFragmentValue(29) > 0.0_c_float)
then
458 sum_fragments = sum(
fragments(icount)%fFragmentValue(1:28) )
464 fragments(icount)%fFragmentValue(29:31) = 0.0_c_float
476 character (len=*),
intent(in) :: sFilename
479 character (len=512) :: sRecord, sSubstring
480 integer (c_int) :: iStat
481 integer (c_int) :: iCount
482 integer (c_int) :: iIndex
483 integer (c_int) :: iNumLines
484 type (ASCII_FILE_T) :: SEQUENCE_FILE
485 character (len=10) :: sBuf0
486 character (len=10) :: sBuf1
487 character (len=12) :: sBuf2
488 character (len=10) :: sBuf3
489 character (len=10) :: sBuf4
490 character (len=256) :: sBuf5
491 character (len=256) :: error_str
492 type (FSTRING_LIST_T) :: slHeader
493 integer (c_int) :: max_rain_gage_number
494 integer (c_int) :: max_simulation_number
497 call sequence_file%open( sfilename = sfilename, &
498 scommentchars =
"#%!", &
499 sdelimiters =
"WHITESPACE", &
500 lhasheader = .
true._c_bool )
502 slheader = sequence_file%readHeader()
504 inumlines = sequence_file%numLines()
507 call assert( istat == 0,
"Problem allocating memory for fragments sequence table", &
515 srecord = sequence_file%readLine()
517 if ( sequence_file%isEOF() )
exit
522 call chomp(srecord, ssubstring, sequence_file%sDelimiters )
524 if ( len_trim(ssubstring) == 0 ) &
525 call die(
"Missing simulation number in the fragments sequence file", &
526 __file__, __line__,
"Problem occured on line number " &
528 //
" of file "//
dquote(sfilename) )
533 call chomp(srecord, ssubstring, sequence_file%sDelimiters )
535 if ( len_trim(ssubstring) == 0 ) &
536 call die(
"Missing month number in the fragments sequence file", &
537 __file__, __line__,
"Problem occured on line number " &
539 //
" of file "//
dquote(sfilename) )
544 call chomp(srecord, ssubstring, sequence_file%sDelimiters )
546 if ( len_trim(ssubstring) == 0 ) &
547 call die(
"Missing rainfall zone number in the fragments sequence file", &
548 __file__, __line__,
"Problem occured on line number " &
550 //
" of file "//
dquote(sfilename) )
556 call chomp(srecord, ssubstring, sequence_file%sDelimiters )
558 if ( len_trim(ssubstring) == 0 ) &
559 call die(
"Missing year number in the fragments sequence file", &
560 __file__, __line__,
"Problem occured on line number " &
562 //
" of file "//
dquote(sfilename) )
567 call chomp(srecord, ssubstring, sequence_file%sDelimiters )
569 if ( len_trim(ssubstring) == 0 ) &
570 call die(
"Missing simulation random number in the fragments sequence file", &
571 __file__, __line__,
"Problem occured on line number " &
573 //
" of file "//
dquote(sfilename) )
578 call chomp(srecord, ssubstring, sequence_file%sDelimiters )
580 if ( len_trim(ssubstring) == 0 ) &
581 call die(
"Missing selected fragment set number in the fragments sequence file", &
582 __file__, __line__,
"Problem occured on line number " &
584 //
" of file "//
dquote(sfilename) )
600 call assert( istat == 0,
"Problem deallocating memory, stat="//
ascharacter(istat) &
601 //
"; msg: "//trim(error_str), __file__, __line__ )
603 allocate(
current_fragments(max_rain_gage_number, max_simulation_number), stat=istat, &
605 call assert( istat == 0,
"Problem allocating memory, stat="//
ascharacter(istat) &
606 //
"; msg: "//trim(error_str), __file__, __line__ )
610 call assert( istat == 0,
"Problem deallocating memory, stat="//
ascharacter(istat) &
611 //
"; msg: "//trim(error_str), __file__, __line__ )
613 allocate(
random_values(max_rain_gage_number, max_simulation_number), stat=istat, &
615 call assert( istat == 0,
"Problem allocating memory, stat="//
ascharacter(istat) &
616 //
"; msg: "//trim(error_str), __file__, __line__ )
618 call logs%write(
"### Summary of fragment sequence sets in memory ###", &
620 call logs%write(
"sim number | rainfall zone | month | year | selected set ")
621 call logs%write(
"----------- | ---------- | ------------ | ------------|------------")
629 write (sbuf5, fmt=
"(a,' | ', a,' | ', a,' | ',a,' | ',a)") &
630 adjustl(sbuf0), adjustl(sbuf1), adjustl(sbuf2), adjustl(sbuf3), adjustl(sbuf4)
631 call logs%write( trim( sbuf5 ) )
651 logical (c_bool),
intent(in) :: lShuffle
654 integer (c_int) :: rain_zone
655 integer (c_int) :: iMaxRainZones
656 integer (c_int) :: iMonth
657 integer (c_int) :: iDay
658 integer (c_int) :: iYearOfSimulation
660 integer (c_int) :: iNumberOfFragments
661 integer (c_int) :: iStartRecord
662 integer (c_int) :: iEndRecord
663 integer (c_int) :: iTargetRecord
664 integer (c_int) :: iStat
665 integer (c_int) :: iUBOUND_FRAGMENTS
666 integer (c_int) :: iUBOUND_CURRENT_FRAGMENTS
667 character (len=512) :: sBuf
670 imaxrainzones = maxval(
fragments%iRainGageZone)
671 imonth =
sim_dt%curr%iMonth
673 iyearofsimulation=
sim_dt%iYearOfSimulation
676 iubound_fragments = ubound(
fragments, 1)
685 do rain_zone = 1, imaxrainzones
694 inumberoffragments =
fragments_sets(rain_zone)%iNumberOfFragments(imonth)
695 iendrecord = istartrecord + inumberoffragments - 1
696 itargetrecord = istartrecord &
698 * real( inumberoffragments ))
700 if ( ( rain_zone > iubound_current_fragments ) .or. ( itargetrecord > iubound_fragments ) &
701 .or. ( rain_zone < 1 ) .or. ( itargetrecord < 1) )
then
702 call logs%write(
"Error detected in method of fragments routine; dump of current" &
703 //
" variables follows:", ilinesbefore=1)
705 call logs%write(
"simulation_number : "//
ascharacter(rain_zone), itab=3 )
707 call logs%write(
"iNumberOfFragments: "//
ascharacter(inumberoffragments), itab=3 )
709 call logs%write(
"iTargetRecord : "//
ascharacter(itargetrecord), itab=3 )
710 call logs%write(
"ubound(CURRENT_FRAGMENTS, 1): "//
ascharacter(iubound_current_fragments), &
712 call logs%write(
"ubound(FRAGMENTS, 1): "//
ascharacter(iubound_fragments), itab=3 )
713 call logs%write(
"RANDOM_VALUES(rain_zone,SIMULATION_NUMBER): " &
715 call die(
"Miscalculation in target record: calculated record index is out of bounds", &
722 write(
lu_fragments_echo,fmt=
"(4(i5,','),f10.6,',',i5,',',30(f8.3,','),f8.3)") &
725 fragments( itargetrecord)%iRainGageZone, &
728 fragments( itargetrecord)%iFragmentSet, &
738 call logs%write(
"Error detected in method of fragments routine; dump of current variables" &
739 //
" follows:", ilinesbefore=1, iloglevel=
log_all )
768 integer (c_int) :: iIndex, iIndex2
769 logical (c_bool) :: lSequenceSelection
790 if ( .not. lsequenceselection ) cycle
809 call logs%write(
"Error detected in method of fragments routine - random values " &
810 //
"not found in sequence file for rainfall zone(s):", ilinesbefore=1)
813 call logs%write(
"simulation number, rainfall zone: " &
825 logical (c_bool),
intent(in) :: lactive(:,:)
828 integer (c_int) :: iindex
829 integer (c_int) :: imaxrainzones
830 integer (c_int) :: istat
831 logical (c_bool),
save :: lfirstcall =
true
838 if (
sim_dt%curr%iDay == 1 .or. lfirstcall )
then
844 call die(
"A RAINFALL_ADJUST_FACTOR grid must be supplied in order to make use" &
845 //
" of this option.", __file__, __line__)
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_long_long) 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.
type(fragments_sequence_t), pointer pfragments_sequence
Pointer to all or some of the FRAGMENTS_SEQUENCE array.
subroutine, public precipitation_method_of_fragments_initialize(lactive)
Initialize method of fragments.
type(data_catalog_entry_t), pointer prainfall_adjust_factor
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 to hold static (pre-calculated) fragment selection numbers.
Data structure to hold the current active rainfall fragments for a particular rain gage zone.
Data structure that holds a single line of data from the input rainfall fragments file.
Pointer to a rainfall fragments data structure.