3 use iso_c_binding,
only : c_int, c_float, c_double, c_bool
36 character (len=38) :: sname
37 character (len=256) :: spathname
38 logical (c_bool) :: loptional
39 integer (c_int) :: idatatype
43 character (len=23) :: sname
44 logical (c_bool) :: loptional
126 lookup_table_dirname, weather_data_dirname )
130 character (len=*),
intent(in) :: output_prefix, output_dirname, data_dirname, &
131 lookup_table_dirname, weather_data_dirname
134 integer (c_int) :: iindex
136 call model%set_default_method_pointers()
144 call model%set_output_directory( output_dirname )
188 call model%preflight_check_method_pointers()
198 call model%initialize_methods()
249 call model%update_rooting_depth_table()
252 call model%read_AWC_data()
256 call model%set_inactive_cells()
259 call model%initialize_arrays()
262 call model%initialize_row_column_indices()
268 call model%init_AWC()
275 call model%init_soil_storage_max()
297 call model%init_continuous_frozen_ground_index()
303 call model%initialize_growing_season()
311 character(len=*),
intent(in) :: lookup_table_dirname
322 character(len=*),
intent(in) :: data_dirname
324 integer (c_int) :: indx
326 if ( len_trim(data_dirname) > 0 )
then
332 case(
"PRECIPITATION",
"TMIN",
"TMAX")
353 character(len=*),
intent(in) :: weather_data_dirname
355 integer (c_int) :: indx
361 case(
"PRECIPITATION",
"TMIN",
"TMAX")
363 known_grids(indx)%sPathname = trim( weather_data_dirname )
377 type (DATA_CATALOG_ENTRY_T),
pointer :: pINITIAL_SNOW_COVER_STORAGE
380 real (c_float),
allocatable :: fInitial_Snow_Cover_Storage(:)
381 integer (c_int) :: iStat
383 allocate ( finitial_snow_cover_storage( count( model%active ) ), stat=istat )
386 pinitial_snow_cover_storage =>
dat%find(
"INITIAL_SNOW_COVER_STORAGE")
389 if ( .not.
associated( pinitial_snow_cover_storage ) ) &
391 pinitial_snow_cover_storage =>
dat%find(
"INITIAL_SNOW_COVER")
393 if ( .not.
associated( pinitial_snow_cover_storage ) )
then
394 call warn(smessage=
"An INITIAL_SNOW_COVER_STORAGE grid (or constant) was not found.", &
395 shints=
"Check your control file to see that a valid INITIAL_SNOW_COVER_STORAGE grid or" &
396 //
" constant is specified.", lfatal=
false )
398 model%snow_storage = 0.0_c_float
402 call pinitial_snow_cover_storage%getvalues()
405 finitial_snow_cover_storage = pack( pinitial_snow_cover_storage%pGrdBase%rData, model%active )
407 if ( minval( finitial_snow_cover_storage ) <
fzero &
408 .or. maxval( finitial_snow_cover_storage ) > 300.0_c_float ) &
409 call warn(smessage=
"One or more initial snow cover storage values outside of " &
410 //
"valid range (0 to 300)", lfatal=
true )
412 model%snow_storage = finitial_snow_cover_storage
422 type (DATA_CATALOG_ENTRY_T),
pointer :: pINITIAL_PERCENT_SOIL_MOISTURE
425 real (c_float),
allocatable :: fInitial_Percent_Soil_Moisture(:)
426 integer (c_int) :: iStat
428 allocate ( finitial_percent_soil_moisture( count( model%active ) ), stat=istat )
431 pinitial_percent_soil_moisture =>
dat%find(
"INITIAL_PERCENT_SOIL_MOISTURE")
434 if ( .not.
associated( pinitial_percent_soil_moisture ) ) &
435 pinitial_percent_soil_moisture =>
dat%find(
"INITIAL_SOIL_MOISTURE")
437 if ( .not.
associated( pinitial_percent_soil_moisture ) )
then
438 call warn(smessage=
"An INITIAL_PERCENT_SOIL_MOISTURE grid (or constant) was not found.", &
439 shints=
"Check your control file to see that a valid INITIAL_PERCENT_SOIL_MOISTURE grid or" &
440 //
" constant is specified.", lfatal=
true )
443 call pinitial_percent_soil_moisture%getvalues()
446 finitial_percent_soil_moisture = pack( pinitial_percent_soil_moisture%pGrdBase%rData, model%active )
448 if ( minval( finitial_percent_soil_moisture ) <
fzero &
449 .or. maxval( finitial_percent_soil_moisture ) > 100.0_c_float ) &
450 call warn(smessage=
"One or more initial percent soils moisture values outside of " &
451 //
"valid range (0% to 100%)", lfatal=
true )
453 model%soil_storage = finitial_percent_soil_moisture / 100.0_c_float * model%soil_storage_max
464 type (DATA_CATALOG_ENTRY_T),
pointer :: pPERCENT_IMPERVIOUS
465 type (DATA_CATALOG_ENTRY_T),
pointer :: pPERCENT_PERVIOUS
466 type (DATA_CATALOG_ENTRY_T),
pointer :: pFRACTION_IMPERVIOUS
467 type (DATA_CATALOG_ENTRY_T),
pointer :: pFRACTION_PERVIOUS
468 type ( GENERAL_GRID_T ),
pointer :: pTempGrd
470 ppercent_impervious =>
dat%find(
"PERCENT_IMPERVIOUS_COVER")
471 ppercent_pervious =>
dat%find(
"PERCENT_PERVIOUS_COVER")
472 pfraction_impervious =>
dat%find(
"FRACTION_IMPERVIOUS_COVER")
473 pfraction_pervious =>
dat%find(
"FRACTION_PERVIOUS_COVER")
475 if (
associated(ppercent_impervious) )
then
477 call ppercent_impervious%getvalues()
479 if (
associated( ppercent_impervious%pGrdBase) )
then
480 model%pervious_fraction = pack( 1.0_c_float - ppercent_impervious%pGrdBase%rData/100.0_c_float, model%active )
482 call die(
"INTERNAL PROGRAMMING ERROR: attempted use of NULL pointer", __file__, __line__)
485 elseif (
associated( ppercent_pervious ) )
then
487 call ppercent_pervious%getvalues()
489 if (
associated( ppercent_pervious%pGrdBase) )
then
490 model%pervious_fraction = pack( (ppercent_pervious%pGrdBase%rData/100.0_c_float), model%active )
492 call die(
"INTERNAL PROGRAMMING ERROR: attempted use of NULL pointer", __file__, __line__)
495 elseif (
associated(pfraction_impervious) )
then
497 call pfraction_impervious%getvalues()
499 if (
associated( pfraction_impervious%pGrdBase) )
then
500 model%pervious_fraction = pack( 1.0_c_float - pfraction_impervious%pGrdBase%rData, model%active )
502 call die(
"INTERNAL PROGRAMMING ERROR: attempted use of NULL pointer", __file__, __line__)
505 elseif (
associated( pfraction_pervious ) )
then
507 call pfraction_pervious%getvalues()
509 if (
associated( pfraction_pervious%pGrdBase) )
then
510 model%pervious_fraction = pack( pfraction_pervious%pGrdBase%rData, model%active )
512 call die(
"INTERNAL PROGRAMMING ERROR: attempted use of NULL pointer", __file__, __line__)
517 model%pervious_fraction = 1.0_c_float
521 if ( minval( model%pervious_fraction ) <
fzero &
522 .or. maxval( model%pervious_fraction ) > 1.0_c_float ) &
523 call warn(smessage=
"One or more percent (im)pervious cover percent/fraction values are outside of " &
524 //
"valid range (0% to 100% or 0.0 to 1.0)", lfatal=
true )
526 if ( all( model%pervious_fraction < 0.01_c_float ) ) &
527 call warn(smessage=
"All (im)pervious cover percent/fraction values are suspiciously low " &
528 //
"(less than 1% or less than 0.01)", lfatal=
true, &
529 shints=
"Check to see whether (im)pervious cover is expressed as a fraction (0.0-1.0)" &
530 //
" or a percentage (0-100%)." )
532 ptempgrd =>
grid_create( inx=model%number_of_columns, iny=model%number_of_rows, &
533 rx0=model%X_ll, ry0=model%Y_ll, &
536 ptempgrd%rData = unpack( model%pervious_fraction, model%active, model%nodata_fill_value )
538 call grid_writearcgrid( sfilename=
"Fraction_pervious_surface__as_read_in_unitless.asc",
pgrd=ptempgrd )
549 type (DATA_CATALOG_ENTRY_T),
pointer :: pPERCENT_CANOPY_COVER
550 type (DATA_CATALOG_ENTRY_T),
pointer :: pFRACTION_CANOPY_COVER
551 type ( GENERAL_GRID_T ),
pointer :: pTempGrd
553 ppercent_canopy_cover =>
dat%find(
"PERCENT_CANOPY_COVER")
554 pfraction_canopy_cover =>
dat%find(
"FRACTION_CANOPY_COVER")
556 if (
associated(ppercent_canopy_cover) )
then
558 call ppercent_canopy_cover%getvalues()
560 if (
associated( ppercent_canopy_cover%pGrdBase) )
then
561 model%canopy_cover_fraction = pack( ppercent_canopy_cover%pGrdBase%rData/100.0_c_float, model%active )
563 call die(
"INTERNAL PROGRAMMING ERROR: attempted use of NULL pointer", __file__, __line__)
566 elseif (
associated(pfraction_canopy_cover) )
then
568 call pfraction_canopy_cover%getvalues()
570 if (
associated( pfraction_canopy_cover%pGrdBase) )
then
571 model%canopy_cover_fraction = pack( pfraction_canopy_cover%pGrdBase%rData, model%active )
573 call die(
"INTERNAL PROGRAMMING ERROR: attempted use of NULL pointer", __file__, __line__)
578 model%canopy_cover_fraction = 1.0_c_float
580 call warn(
"Could not find a grid or constant value for the canopy cover fraction. Using a" &
581 //
" value of 1.0 for the entire model domain." )
585 if ( minval( model%canopy_cover_fraction ) <
fzero &
586 .or. maxval( model%canopy_cover_fraction ) > 1.0_c_float ) &
587 call warn(smessage=
"One or more percent canopy cover percent/fraction values values are outside of " &
588 //
"valid range (0% to 100% or 0.0 to 1.0)", lfatal=
true )
590 if ( all( model%canopy_cover_fraction < 0.01_c_float ) ) &
591 call warn(smessage=
"All canopy cover percent/fraction values are suspiciously low " &
592 //
"(less than 1% or less than 0.01)", lfatal=
true, &
593 shints=
"Check to see whether canopy cover is expressed as a fraction (0.0-1.0)" &
594 //
" or a percentage (0-100%)." )
596 ptempgrd =>
grid_create( inx=model%number_of_columns, iny=model%number_of_rows, &
597 rx0=model%X_ll, ry0=model%Y_ll, &
600 ptempgrd%rData = unpack( model%canopy_cover_fraction, model%active, model%nodata_fill_value )
613 integer (c_int) :: iIndex
614 type (DATA_CATALOG_ENTRY_T),
pointer :: pHSG
616 phsg =>
dat%find(
"HYDROLOGIC_SOILS_GROUP")
618 if (
associated(phsg) )
then
620 if (
associated( phsg%pGrdBase) )
then
621 model%soil_group = pack( phsg%pGrdBase%iData, model%active )
623 call die(
"INTERNAL PROGRAMMING ERROR: attempted use of NULL pointer", __file__, __line__)
628 call die(
"Attempted use of NULL pointer. Failed to find HYDROLOGIC_SOILS_GROUP data element.", &
633 call logs%write(
"Hydrologic soils groups as read into SWB data structure", ilinesbefore=1, ilinesafter=1, iloglevel=
log_debug)
635 do iindex = 1, maxval(phsg%pGrdBase%iData)
637 call logs%write(
ascharacter(count(model%soil_group == iindex) )//
" cells belong to soils group " &
651 type (DATA_CATALOG_ENTRY_T),
pointer :: pHSG
653 phsg =>
dat%find(
"HYDROLOGIC_SOILS_GROUP")
655 if (
associated(phsg) )
then
657 call phsg%getvalues()
658 call grid_writearcgrid(
"Hydrologic_soil_groups__as_read_into_SWB.asc", phsg%pGrdBase )
662 call warn(smessage=
"HYDROLOGIC_SOILS_GROUP dataset is flawed or missing.", lfatal=
true, &
663 iloglevel =
log_all, shints=
"Check to see that a valid path and filename have" &
664 //
" been ~included in the control file for the HYDROLOGIC_SOILS_GROUP dataset.", &
678 type (DATA_CATALOG_ENTRY_T),
pointer :: pPOLYGON_ID
679 logical (c_bool) :: any_problems
680 type (GENERAL_GRID_T),
pointer :: pTempGrd
684 ptempgrd =>
grid_create( inx=model%number_of_columns, iny=model%number_of_rows, &
685 rx0=model%X_ll, ry0=model%Y_ll, &
692 ppolygon_id =>
dat%find(
"POLYGON_ID")
694 if ( .not.
associated( ppolygon_id ) )
exit
696 call ppolygon_id%getvalues()
697 call grid_writearcgrid(
"Polygon_ID__as_read_into_SWB.asc", ppolygon_id%pGrdBase )
699 model%polygon_id = pack( ppolygon_id%pGrdBase%iData, model%active )
809 character (len=*),
intent(in) :: sfilename
810 character (len=*),
intent(in),
optional :: sgridspecification
814 character (len=:),
allocatable :: stext
815 integer (c_int) :: iindex
816 integer (c_int) :: icount
823 call cf%open( sfilename = sfilename )
826 if (
present( sgridspecification ) )
then
827 call cf_dict%get_value(stext,
"GRID")
828 pdict =>
cf_dict%get_next_entry()
829 call assert(
associated( pdict ),
"INTERNAL PROGRAMMING ERROR -- Attempted use of null poitner", &
831 call cf%writeLine( trim( sgridspecification ) )
839 do while (
associated( pdict ) )
841 call cf_dict%get_value( stext )
842 call cf%writeLine( trim(pdict%key)//
" "//stext )
843 pdict =>
cf_dict%get_next_entry()
847 if (
present( slextradirectives ) )
then
849 icount = slextradirectives%count
853 call cf%writeLine( trim( slextradirectives%get( iindex ) ) )
867 character (len=*),
intent(in) :: sfilename
870 character (len=256) :: srecord, skey, svalue
871 integer (c_int) :: istat
873 integer (c_int) :: dumpfile_count
880 call cf%open( sfilename = sfilename, &
881 scommentchars =
"#%!+=|[{(-*$", &
882 sdelimiters =
"WHITESPACE", &
883 lhasheader = .
false._c_bool )
886 cf%remove_extra_delimiters =
true
891 srecord = cf%readLine()
893 if ( cf%isEOF() )
exit
898 call assert(istat == 0,
"Failed to allocate memory for dictionary object", &
902 call chomp(srecord, skey, cf%sDelimiters, cf%remove_extra_delimiters )
904 if ( len_trim( skey ) > 0 )
then
908 if ( skey .strequal.
"DUMP_VARIABLES" )
then
909 dumpfile_count = dumpfile_count + 1
910 skey = trim(skey)//
"_"//
ascharacter(dumpfile_count)
917 call chomp( srecord, svalue, cf%sDelimiters, cf%remove_extra_delimiters )
919 do while ( len_trim( svalue ) > 0 )
924 call chomp( srecord, svalue, cf%sDelimiters, cf%remove_extra_delimiters )
959 character (len=*),
intent(in) :: sKey
960 character (len=*),
intent(in) :: sPathname
961 logical (c_bool),
intent(in) :: lOptional
962 integer (c_int),
intent(in) :: iDataType
965 type (FSTRING_LIST_T) :: myDirectives
966 type (FSTRING_LIST_T) :: myOptions
967 integer (c_int) :: iIndex
968 character (len=512) :: sCmdText
969 character (len=512) :: sArgText
970 character (len=512) :: sArgText_1
971 character (len=512) :: sArgText_2
972 character (len=512) :: sArgText_3
973 character (len=512) :: sArgText_4
974 integer (c_int) :: iStat
975 type (DATA_CATALOG_ENTRY_T),
pointer :: pENTRY
976 logical (c_bool) :: lGridPresent
987 mydirectives =
cf_dict%grep_keys( skey )
991 if ( mydirectives%count == 0 )
then
993 call logs%write(
"Your control file is missing gridded data relating to "//
dquote(skey)//
".", &
996 if (.not. loptional)
then
997 call warn(
"Your control file is missing gridded data relating to "//
dquote(skey)//
".", &
1005 allocate(pentry, stat=istat)
1006 call assert( istat == 0,
"Failed to allocate memory for the "//
dquote(skey)//
" data structure", &
1007 __file__, __line__ )
1015 call myoptions%clear()
1018 do iindex = 1, mydirectives%count
1022 scmdtext = mydirectives%get(iindex)
1025 call cf_dict%get_values(scmdtext, myoptions )
1028 sargtext_1 = myoptions%get(1)
1029 sargtext_2 = myoptions%get(2)
1030 sargtext_3 = myoptions%get(3)
1031 sargtext_4 = myoptions%get(4)
1035 sargtext = myoptions%get(1, myoptions%count )
1038 call logs%write(
"> "//trim(scmdtext)//
" "//trim(sargtext), ilinesbefore=1 )
1043 if ( scmdtext .strapprox. skey )
then
1048 if (sargtext_1 .strapprox.
"CONSTANT" )
then
1051 call die(
"Non-numeric argument supplied as a CONSTANT in your control file.", &
1052 shints=
"Faulty control file argument was "//
squote(trim(scmdtext)//
" "//trim(sargtext)))
1054 select case ( idatatype )
1058 call pentry%initialize( &
1059 sdescription=trim(scmdtext), &
1060 rconstant=
asfloat(sargtext_2) )
1065 call pentry%initialize( &
1066 sdescription=trim(scmdtext), &
1067 iconstant=
asint(sargtext_2) )
1072 call die(
"INTERNAL PROGRAMMING ERROR: Unhandled data type selected.", &
1073 __file__, __line__ )
1077 elseif ( (sargtext_1 .strapprox.
"TABLE") &
1078 .or. (sargtext_1 .strapprox.
"TABLE_LOOKUP") )
then
1080 if (len_trim(sargtext_2) > 0) &
1083 select case ( idatatype )
1087 call pentry%initialize( &
1088 sdescription=trim(scmdtext), &
1089 sdatecolumnname =
"date", &
1090 svaluecolumnname = pentry%sVariableName_z, &
1096 call pentry%initialize( &
1097 sdescription=trim(scmdtext), &
1098 sdatecolumnname =
"date", &
1099 svaluecolumnname = pentry%sVariableName_z, &
1105 call die(
"INTERNAL PROGRAMMING ERROR: Unhandled data type selected.", &
1106 __file__, __line__ )
1109 elseif ( (sargtext_1 .strapprox.
"ARC_ASCII") &
1110 .or. (sargtext_1 .strapprox.
"SURFER") &
1111 .or. (sargtext_1 .strapprox.
"ARC_GRID") )
then
1113 call pentry%initialize( &
1114 sdescription=trim(scmdtext), &
1115 sfiletype=trim(sargtext_1), &
1117 idatatype=idatatype )
1120 elseif ( sargtext_1 .strapprox.
"NETCDF" )
then
1122 call pentry%initialize_netcdf( &
1123 sdescription=trim(scmdtext), &
1124 sfilename =
fix_pathname(trim(spathname)//sargtext_2), &
1125 idatatype=idatatype )
1136 call warn(
"Did not find a valid "//
dquote(skey)//
" option. Value supplied was: "//
dquote(sargtext_1), &
1137 lfatal =
true, shints=
"Valid options include "//
dquote(
"CONSTANT")//
", " &
1144 elseif ( scmdtext .containssimilar.
"_USE_MAJORITY_FILTER" )
then
1146 call pentry%set_majority_filter_flag(
true )
1148 elseif ( scmdtext .containssimilar.
"_MONTHNAMES_CAPITALIZED" )
then
1152 elseif ( scmdtext .containssimilar.
"_MONTHNAMES_LOWERCASE" )
then
1156 elseif ( scmdtext .containssimilar.
"_MONTHNAMES_UPPERCASE" )
then
1160 elseif ( scmdtext .containssimilar.
"_CONVERSION_FACTOR" )
then
1162 call pentry%set_scale(
asdouble(sargtext_1))
1164 elseif ( scmdtext .containssimilar.
"NETCDF_X_VAR_ADD_OFFSET" )
then
1166 call pentry%set_X_offset(
asdouble( sargtext_1 ) )
1168 elseif ( scmdtext .containssimilar.
"NETCDF_Y_VAR_ADD_OFFSET" )
then
1170 call pentry%set_Y_offset(
asdouble( sargtext_1 ) )
1172 elseif ( scmdtext .containssimilar.
"_SCALE_FACTOR" )
then
1174 call pentry%set_scale(
asdouble(sargtext_1))
1176 elseif ( scmdtext .containssimilar.
"_ADD_OFFSET" )
then
1178 call pentry%set_add_offset(
asdouble(sargtext_1))
1180 elseif ( scmdtext .containssimilar.
"_SUBTRACT_OFFSET" )
then
1182 call pentry%set_sub_offset(
asdouble(sargtext_1))
1184 elseif ( scmdtext .containssimilar.
"_UNITS_KELVIN" )
then
1188 call pentry%set_scale(
f_per_c)
1190 elseif ( scmdtext .containssimilar.
"_UNITS_CELSIUS" )
then
1193 call pentry%set_scale(
f_per_c)
1195 elseif ( scmdtext .containssimilar.
"_UNITS_MILLIMETERS" )
then
1197 call pentry%set_scale(1.0_c_double /
mm_per_in)
1199 elseif ( scmdtext .containssimilar.
"_COORDINATE_TOLERANCE" )
then
1201 call pentry%set_coordinate_tolerance(
asdouble(sargtext_1))
1203 elseif ( scmdtext .containssimilar.
"NETCDF_X_VAR" )
then
1205 pentry%sVariableName_x = trim(sargtext_1)
1207 elseif ( scmdtext .containssimilar.
"NETCDF_Y_VAR" )
then
1209 pentry%sVariableName_y = trim(sargtext_1)
1211 elseif ( (scmdtext .containssimilar.
"NETCDF_Z_VAR") &
1212 .or. (scmdtext .containssimilar.
"COLUMN_NAME") )
then
1214 pentry%sVariableName_z = trim(sargtext_1)
1216 elseif ( (scmdtext .containssimilar.
"NETCDF_TIME_VAR") &
1217 .or. (scmdtext .containssimilar.
"DATE_COLUMN_NAME") )
then
1219 pentry%sVariableName_time = trim(sargtext_1)
1221 elseif ( scmdtext .containssimilar.
"NETCDF_VARIABLE_ORDER" )
then
1223 call pentry%set_variable_order(
aslowercase(sargtext_1) )
1225 elseif ( scmdtext .containssimilar.
"NETCDF_FLIP_VERTICAL")
then
1227 call pentry%set_grid_flip_vertical()
1229 elseif ( scmdtext .containssimilar.
"NETCDF_FLIP_HORIZONTAL" )
then
1231 call pentry%set_grid_flip_horizontal()
1233 elseif ( scmdtext .containssimilar.
"NETCDF_NO_AUTOMATIC_GRID_FLIPPING" )
then
1235 call pentry%do_not_allow_netcdf_grid_data_flipping()
1237 elseif ( scmdtext .containssimilar.
"ALLOW_MISSING_FILES" )
then
1239 call pentry%allow_missing_files()
1241 elseif ( scmdtext .containssimilar.
"NETCDF_MAKE_LOCAL_ARCHIVE" )
then
1243 call pentry%set_make_local_archive(
true)
1245 elseif ( scmdtext .containssimilar.
"_PROJECTION_DEFINITION" )
then
1247 call pentry%set_source_PROJ4( trim(sargtext) )
1249 elseif ( scmdtext .containssimilar.
"_DATE_COLUMN" )
then
1251 pentry%sDateColumnName = trim( sargtext_1 )
1253 elseif ( scmdtext .containssimilar.
"_VALUE_COLUMN" )
then
1255 pentry%sValueColumnName = trim( sargtext_1 )
1257 elseif ( scmdtext .containssimilar.
"_MINIMUM_ALLOWED_VALUE" )
then
1259 pentry%rMinAllowedValue =
asfloat(sargtext_1)
1261 elseif ( scmdtext .containssimilar.
"_MAXIMUM_ALLOWED_VALUE" )
then
1263 pentry%rMaxAllowedValue =
asfloat(sargtext_1)
1265 elseif ( scmdtext .containssimilar.
"_MISSING_VALUES_CODE" )
then
1267 pentry%rMissingValuesCode =
asfloat(sargtext_1)
1269 elseif ( scmdtext .containssimilar.
"_MISSING_VALUES_OPERATOR" )
then
1271 pentry%sMissingValuesOperator = trim(sargtext_1)
1273 elseif ( scmdtext .containssimilar.
"_MISSING_VALUES_ACTION" )
then
1275 if (sargtext_1 .strapprox.
"ZERO")
then
1279 elseif (sargtext_1 .strapprox.
"MEAN" )
then
1285 call warn(
"Unknown missing value action supplied for " &
1290 elseif ( scmdtext .containssimilar.
"_METHOD" )
then
1295 elseif ( scmdtext .containssimilar.
"_LOOKUP_TABLE" )
then
1302 call warn(
"Unknown directive detected in code at line "//
ascharacter(__line__)//
", file "//__file__ &
1303 //
". ~Ignoring. Directive is: "//
dquote(scmdtext), iloglevel=
log_debug )
1311 if ( lgridpresent )
call dat%add( key=skey, data=pentry )
1317 call mydirectives%clear()
1318 call myoptions%clear()
1327 type (FSTRING_LIST_T) :: myOptions
1328 character (len=:),
allocatable :: sArgText
1329 real (c_double) :: rX0, rX1, rY0, rY1, rGridCellSize
1330 integer (c_int) :: iNX, iNY
1331 real (c_float) :: fTempVal
1335 rgridcellsize = 0.0_c_double
1338 call cf_dict%get_values(
"GRID", myoptions )
1342 sargtext = myoptions%get(1, myoptions%count )
1345 call logs%write(
"> GRID "//sargtext, ilinesbefore=1 )
1347 inx =
asint( myoptions%get(1) )
1348 iny =
asint( myoptions%get(2) )
1352 if ( myoptions%count == 5 )
then
1354 rgridcellsize =
asdouble( myoptions%get(5) )
1356 call model%initialize_grid(inx, iny, rx0, ry0, rgridcellsize)
1358 rx1 = rx0 + rgridcellsize * real(inx, c_double)
1359 ry1 = ry0 + rgridcellsize * real(iny, c_double)
1361 elseif ( myoptions%count == 7 )
then
1365 rgridcellsize =
asdouble( myoptions%get(7) )
1367 ftempval = real(( rx1 - rx0 ) / real(inx, c_double), c_float)
1369 call model%initialize_grid(inx, iny, rx0, ry0, rgridcellsize)
1373 call warn(
"Grid specification is flawed or missing.", lfatal=
true, iloglevel =
log_all, lecho =
true )
1377 call myoptions%clear()
1380 call cf_dict%get_values(
"BASE_PROJECTION_DEFINITION", myoptions )
1382 if ( myoptions%get(1) .strequal.
"<NA>" )
then
1383 call die(smessage=
"Your control file is missing a BASE_PROJECTION_DEFINITION entry.", &
1384 shints=
"This version of SWB requires that you add a BASE_PROJECTION_DEFINITION entry " &
1385 //
"to your control file." )
1390 sargtext = myoptions%get(1, myoptions%count )
1393 call logs%write(
"> BASE_PROJECTION_DEFINITION "//sargtext, ilinesbefore=1)
1403 bnds%fGridCellSize = rgridcellsize
1404 bnds%sPROJ4_string = trim(sargtext)
1406 model%PROJ4_string = trim(sargtext)
1415 type (FSTRING_LIST_T) :: myOptions
1416 integer (c_int) :: iIndex
1417 integer (c_int) :: jIndex
1418 character (len=:),
allocatable :: sArgText
1419 character (len=:),
allocatable :: sOutput
1420 logical (c_bool) :: enable_output
1422 enable_output =
true
1425 call cf_dict%get_values(
"OUTPUT", myoptions )
1439 sargtext = myoptions%get(1, myoptions%count )
1442 call logs%write(
"> OUTPUT"//sargtext, ilinesbefore=1 )
1445 do iindex=1,myoptions%count
1447 soutput = myoptions%get( iindex )
1449 if ( ( soutput .strapprox.
"ENABLE") .or. ( soutput .strapprox.
"ACTIVE") )
then
1451 enable_output =
true
1453 elseif ( ( soutput .strapprox.
"DISABLE") .or. ( soutput .strapprox.
"INACTIVE") )
then
1455 enable_output =
false
1459 if ( soutput .strapprox.
"ALL" )
then
1461 outspecs(:)%is_active = enable_output
1467 if (
outspecs( jindex )%variable_name .strapprox. soutput )
then
1468 outspecs( jindex )%is_active = enable_output
1469 if ( enable_output )
call logs%write(
"> Enabling output for "//
squote(soutput), ilinesbefore=1 )
1470 if ( .not. enable_output )
call logs%write(
"> Disabling output for "//
squote(soutput), ilinesbefore=1 )
1478 call myoptions%clear()
1487 type (FSTRING_LIST_T) :: myDirectives
1488 type (FSTRING_LIST_T) :: myOptions
1489 integer (c_int) :: iIndex
1490 character (len=:),
allocatable :: sCmdText
1491 character (len=:),
allocatable :: sOptionText
1492 character (len=:),
allocatable :: sArgText
1493 logical (c_bool) :: lHaveStartDate
1494 logical (c_bool) :: lHaveEndDate
1496 lhavestartdate =
false
1497 lhaveenddate =
false
1499 mydirectives =
cf_dict%grep_keys(
"DATE")
1512 do iindex = 1, mydirectives%count
1516 scmdtext = mydirectives%get(iindex)
1519 call cf_dict%get_values(scmdtext, myoptions )
1523 sargtext = myoptions%get(1, myoptions%count )
1526 call logs%write(
"> "//scmdtext//
" "//sargtext, ilinesbefore=1 )
1529 soptiontext = myoptions%get(1)
1531 select case ( scmdtext )
1533 case (
"START_DATE",
"STARTDATE",
"BEGIN_DATE" )
1535 lhavestartdate =
true
1536 call sim_dt%start%parseDate( soptiontext )
1537 call sim_dt%start%calcJulianDay()
1539 case (
"END_DATE",
"ENDDATE",
"STOP_DATE" )
1542 call sim_dt%end%parseDate( soptiontext )
1543 call sim_dt%end%calcJulianDay()
1547 call warn(
"Unknown directive present, line "//
ascharacter(__line__)//
", file "//__file__ &
1548 //
". Ignoring. Directive is: "//
dquote(scmdtext), iloglevel=
log_debug )
1554 if ( lhavestartdate .and. lhaveenddate )
then
1563 call logs%write(
"Model run start date set to: "//
sim_dt%start%prettydate(), itab=4, lecho=
true)
1564 call logs%write(
"Model run end date set to: "//
sim_dt%end%prettydate(), itab=4, lecho=
true)
1568 call warn(smessage=
"Your control file seems to be missing START_DATE and/or END_DATE", &
1569 shints=
"Add a START_DATE and/or END_DATE directive to your control file. Date " &
1570 //
"~should be specified as mm/dd/yyyy.", lfatal =
true, iloglevel =
log_all, &
1591 type (FSTRING_LIST_T) :: myDirectives
1592 type (FSTRING_LIST_T) :: myOptions
1593 integer (c_int) :: iIndex
1594 character (len=:),
allocatable :: sCmdText
1595 character (len=:),
allocatable :: sOptionText
1596 character (len=:),
allocatable :: sArgText
1597 type (PARAMETERS_T) :: PARAMS_LU_TABLE
1598 integer (c_int) :: iCount
1602 mydirectives =
cf_dict%grep_keys(
"LOOKUP_TABLE")
1604 if ( mydirectives%count == 0 )
then
1606 call warn(
"Your control file seems to be missing the required lookup table(s).", &
1615 do iindex = 1, mydirectives%count
1618 scmdtext = mydirectives%get(iindex)
1621 call cf_dict%get_values(scmdtext, myoptions )
1625 sargtext = myoptions%get(1, myoptions%count )
1628 call logs%write(
"> "//scmdtext//
" "//sargtext, ilinesbefore=1 )
1637 if ( index(string=scmdtext, substring=
"LOOKUP_TABLE" ) > 0 )
then
1639 call params_lu_table%add_file(
fix_pathname( soptiontext ))
1644 call warn(
"Unknown directive present, line "//
ascharacter(__line__)//
", file "//__file__ &
1645 //
". Ignoring. Directive is: "//
dquote(scmdtext), iloglevel=
log_debug )
1651 if ( icount > 0 )
then
1653 call params_lu_table%munge_file(delimiters=
tab)
1654 call params_dict%print_all(sdescription=
"LOOKUP TABLE dictionary", &
1667 character (len=*),
intent(in) :: sKey
1668 logical (c_bool),
intent(in) :: lOptional
1671 type (FSTRING_LIST_T) :: myDirectives
1672 type (FSTRING_LIST_T) :: myOptions
1673 integer (c_int) :: iIndex
1674 integer (c_int) :: indx
1675 character (len=:),
allocatable :: sCmdText
1677 type (FSTRING_LIST_T) :: argv_list
1678 character (len=:),
allocatable :: sArgText
1679 logical (c_bool) :: lFatal
1680 integer (c_int) :: num_elements
1683 mydirectives =
cf_dict%grep_keys( trim(skey) )
1685 lfatal = .not. loptional
1687 if ( mydirectives%count == 0 )
then
1689 call warn(
"Your control file is missing any of the required directives relating to "//
dquote(skey)//
" method.", &
1690 lfatal = lfatal, iloglevel =
log_all, lecho =
true )
1698 do iindex = 1, mydirectives%count
1701 scmdtext = mydirectives%get(iindex)
1704 call cf_dict%get_values(scmdtext, myoptions )
1708 sargtext = myoptions%get(1, myoptions%count )
1711 call logs%write(
"> "//scmdtext//
" "//sargtext, ilinesbefore=1, iloglevel=
log_all, lecho=
false )
1716 num_elements = myoptions%count
1718 call argv_list%clear()
1720 do indx=1, myoptions%count
1721 call argv_list%append( myoptions%get( indx ) )
1727 if ( ( scmdtext .contains.
"METHOD" ) .or. ( scmdtext .contains.
"DUMP" ) )
then
1729 call model%set_method_pointers( trim(scmdtext), argv_list )
1744 type (FSTRING_LIST_T) :: myDirectives
1745 type (FSTRING_LIST_T) :: myOptions
1746 integer (c_int) :: iIndex
1747 integer (c_int) :: indx
1748 character (len=:),
allocatable :: sCmdText
1750 type (FSTRING_LIST_T) :: argv_list
1751 character (len=:),
allocatable :: sArgText
1752 integer (c_int) :: num_elements
1753 character (len=:),
allocatable :: Option_Name
1756 mydirectives =
cf_dict%grep_keys(
"OPTION" )
1762 do iindex = 1, mydirectives%count
1765 scmdtext = mydirectives%get(iindex)
1768 call cf_dict%get_values(scmdtext, myoptions )
1772 sargtext = myoptions%get(1, myoptions%count )
1775 call logs%write(
"> "//scmdtext//
" "//sargtext, ilinesbefore=1 )
1780 num_elements = myoptions%count
1782 call argv_list%clear()
1784 do indx=1, myoptions%count
1785 call argv_list%append( myoptions%get( indx ) )
1790 if ( ( scmdtext .contains.
"OPTION" ) )
then
1792 option_name = argv_list%get(1)
1794 select case ( option_name )
1796 case (
"NO_LATLON_IN_OUTPUT" )
1799 call logs%write(
"==> LATITUDE and LONGITUDE will *not* be included in output NetCDF files.", ilinesbefore=1 )
1818 rx0=model%X_ll, ry0=model%Y_ll, &
1821 allocate ( model%X(model%number_of_columns ) )
1822 allocate ( model%Y(model%number_of_rows ) )
1833 stoproj4=
"+proj=lonlat +ellps=GRS80 +datum=WGS84 +no_defs" )
1835 model%latitude = real(pack(
pcoord_grd%rY, model%active ), c_float)
1948 integer (c_int) :: iIndex
1949 type (FSTRING_LIST_T) :: slList
1950 integer( c_int),
allocatable :: iLanduseTableCodes(:)
1951 integer (c_int) :: iNumberOfLanduses
1952 real (c_float),
allocatable :: SURFACE_STORAGE_MAXIMUM(:)
1953 real (c_float) :: current_surface_storage_max
1957 call sllist%append(
"LU_Code" )
1958 call sllist%append(
"Landuse_Lookup_Code" )
1961 call params%get_parameters( slkeys=sllist, ivalues=ilandusetablecodes )
1962 inumberoflanduses = count( ilandusetablecodes >= 0 )
1965 call sllist%append(
"Surface_Storage_Max")
1966 call sllist%append(
"Surface_Storage_Maximum")
1968 model%surface_storage_max = 0.0_c_float
1970 call params%get_parameters( slkeys=sllist, fvalues=surface_storage_maximum, lfatal=
false )
1972 if ( all( surface_storage_maximum >
rtinyval ) )
then
1974 do iindex=1, ubound( surface_storage_maximum, 1)
1976 current_surface_storage_max = surface_storage_maximum( iindex )
1978 where( model%landuse_index == iindex )
1980 model%surface_storage_max = current_surface_storage_max
This module contains physical constants and convenience functions aimed at performing unit conversion...
character(len=len_trim(input_pathname)) function fix_pathname(input_pathname)
logical(c_bool), parameter, public true
real(c_double), parameter, public f_per_c
type(bounds_t), public bnds
real(c_float), parameter, public rtinyval
real(c_double), parameter, public mm_per_in
character(len=:), allocatable, public lookup_table_directory_name
logical(c_bool), parameter, public false
real(c_double), parameter, public freezing_point_of_water_kelvin
real(c_double), parameter, public freezing_point_of_water_fahrenheit
integer(c_int), parameter datatype_float
impure elemental logical(c_bool) function, public is_numeric(value)
Determine if string contains numeric values.
character(len=:), allocatable, public data_directory_name
integer(c_int), parameter datatype_int
real(c_float), parameter fzero
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(general_grid_t), pointer, public pgrd
integer(c_int), parameter, public missing_values_replace_with_mean
integer(c_int), parameter, public file_template_uppercase_monthname
integer(c_int), parameter, public missing_values_zero_out
integer(c_int), parameter, public file_template_capitalized_monthname
integer(c_int), parameter, public file_template_lowercase_monthname
This module contains the DATETIME_T class and associated time and date-related routines,...
integer(c_int) function, public day_of_year(ijd)
type(dict_entry_t), pointer, public cf_entry
type(dict_t), public cf_dict
subroutine, public check_for_fatal_warnings()
subroutine, public warn(smessage, smodule, iline, shints, lfatal, iloglevel, lecho)
subroutine, public die(smessage, smodule, iline, shints, scalledby, icalledbyline)
character(len=1), parameter, public tab
Provides support for input and output of gridded ASCII data, as well as for creation and destruction ...
subroutine, public grid_populatexy(pgrd, rx, ry)
subroutine, public grid_destroy(pgrd)
subroutine, public grid_writearcgrid(sfilename, pgrd)
integer(c_int), parameter, public grid_datatype_real
subroutine, public grid_set_output_directory_name(sdirname)
subroutine, public grid_transform(pgrd, sfromproj4, stoproj4, rx, ry)
Call PROJ4 to transform coordinates.
type(logfile_t), public logs
subroutine, public initialize_landuse_codes()
Match landuse codes from table with those contained in the gridded landuse.
type(model_domain_t), public model
subroutine, public read_landuse_codes
real(c_float), dimension(:,:), allocatable, public rooting_depth_max
subroutine initialize_generic_method(skey, loptional)
type(methods_list_t), dimension(number_of_known_methods), parameter known_methods
type(general_grid_t), pointer pcoord_grd
subroutine initialize_grid_options()
subroutine initialize_ancillary_values()
subroutine, public write_control_file(sfilename, sgridspecification, slextradirectives)
subroutine, public read_control_file(sfilename)
subroutine initialize_latitude()
subroutine initialize_program_options()
subroutine, public initialize_all(output_prefix, output_dirname, data_dirname, lookup_table_dirname, weather_data_dirname)
subroutine initialize_lookup_tables()
Find any parameter tables specified in the control file; process and store contents.
subroutine initialize_snow_storage()
subroutine initialize_percent_pervious()
subroutine initialize_output_options()
integer(c_int), parameter number_of_known_methods
subroutine initialize_soil_storage()
type(gridded_datasets_t), dimension(number_of_known_grids) known_grids
subroutine set_data_directory(data_dirname)
subroutine initialize_start_and_end_dates()
subroutine set_weather_data_directory(weather_data_dirname)
subroutine read_hydrologic_soil_groups
subroutine initialize_surface_storage_max()
subroutine initialize_hydrologic_soil_groups
integer(c_int), parameter number_of_known_grids
subroutine initialize_percent_canopy_cover
subroutine initialize_soils_landuse_awc_flowdir_values()
Initialize soils, landuse, and available water content values.
subroutine initialize_generic_grid(skey, spathname, loptional, idatatype)
Generic routine to handle intake of gridded data.
subroutine set_lookup_table_directory(lookup_table_dirname)
subroutine read_polygon_id()
type(output_specs_t), dimension(ncdf_num_outputs) outspecs
subroutine initialize_output(cells)
subroutine set_output_prefix(output_prefix)
subroutine set_output_directory(output_dir_name)
subroutine set_output_latlon_option(output_includes_latlon_l)
type(parameters_t), public params
type(dict_t), public params_dict
Module precipitation__method_of_fragments provides support for creating synthetic daily precipitation...
type(date_range_t), public sim_dt
subroutine, public storm_drain_capture_initialize(is_cell_active, landuse_index)