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
135 logical (c_bool) :: using_tabular_precip_and_temperature
137 call model%set_default_method_pointers()
145 call model%set_output_directory( output_dirname )
189 call model%preflight_check_method_pointers()
199 call model%initialize_methods()
250 call model%update_rooting_depth_table()
253 call model%read_AWC_data()
257 call model%set_inactive_cells()
260 call model%initialize_arrays()
263 call model%initialize_row_column_indices()
269 call model%init_AWC()
276 call model%init_soil_storage_max()
298 call model%init_continuous_frozen_ground_index()
304 call model%initialize_growing_season()
312 character(len=*),
intent(in) :: lookup_table_dirname
323 character(len=*),
intent(in) :: data_dirname
325 integer (c_int) :: indx
327 if ( len_trim(data_dirname) > 0 )
then
333 case(
"PRECIPITATION",
"TMIN",
"TMAX")
354 character(len=*),
intent(in) :: weather_data_dirname
356 integer (c_int) :: indx
362 case(
"PRECIPITATION",
"TMIN",
"TMAX")
364 known_grids(indx)%sPathname = trim( weather_data_dirname )
378 type (DATA_CATALOG_ENTRY_T),
pointer :: pINITIAL_SNOW_COVER_STORAGE
381 real (c_float),
allocatable :: fInitial_Snow_Cover_Storage(:)
382 integer (c_int) :: iStat
384 allocate ( finitial_snow_cover_storage( count( model%active ) ), stat=istat )
387 pinitial_snow_cover_storage =>
dat%find(
"INITIAL_SNOW_COVER_STORAGE")
390 if ( .not.
associated( pinitial_snow_cover_storage ) ) &
392 pinitial_snow_cover_storage =>
dat%find(
"INITIAL_SNOW_COVER")
394 if ( .not.
associated( pinitial_snow_cover_storage ) )
then
395 call warn(smessage=
"An INITIAL_SNOW_COVER_STORAGE grid (or constant) was not found.", &
396 shints=
"Check your control file to see that a valid INITIAL_SNOW_COVER_STORAGE grid or" &
397 //
" constant is specified.", lfatal=
false )
399 model%snow_storage = 0.0_c_float
403 call pinitial_snow_cover_storage%getvalues()
406 finitial_snow_cover_storage = pack( pinitial_snow_cover_storage%pGrdBase%rData, model%active )
408 if ( minval( finitial_snow_cover_storage ) <
fzero &
409 .or. maxval( finitial_snow_cover_storage ) > 300.0_c_float ) &
410 call warn(smessage=
"One or more initial snow cover storage values outside of " &
411 //
"valid range (0 to 300)", lfatal=
true )
413 model%snow_storage = finitial_snow_cover_storage
423 type (DATA_CATALOG_ENTRY_T),
pointer :: pINITIAL_PERCENT_SOIL_MOISTURE
426 real (c_float),
allocatable :: fInitial_Percent_Soil_Moisture(:)
427 integer (c_int) :: iStat
429 allocate ( finitial_percent_soil_moisture( count( model%active ) ), stat=istat )
432 pinitial_percent_soil_moisture =>
dat%find(
"INITIAL_PERCENT_SOIL_MOISTURE")
435 if ( .not.
associated( pinitial_percent_soil_moisture ) ) &
436 pinitial_percent_soil_moisture =>
dat%find(
"INITIAL_SOIL_MOISTURE")
438 if ( .not.
associated( pinitial_percent_soil_moisture ) )
then
439 call warn(smessage=
"An INITIAL_PERCENT_SOIL_MOISTURE grid (or constant) was not found.", &
440 shints=
"Check your control file to see that a valid INITIAL_PERCENT_SOIL_MOISTURE grid or" &
441 //
" constant is specified.", lfatal=
true )
444 call pinitial_percent_soil_moisture%getvalues()
447 finitial_percent_soil_moisture = pack( pinitial_percent_soil_moisture%pGrdBase%rData, model%active )
449 if ( minval( finitial_percent_soil_moisture ) <
fzero &
450 .or. maxval( finitial_percent_soil_moisture ) > 100.0_c_float ) &
451 call warn(smessage=
"One or more initial percent soils moisture values outside of " &
452 //
"valid range (0% to 100%)", lfatal=
true )
454 model%soil_storage = finitial_percent_soil_moisture / 100.0_c_float * model%soil_storage_max
465 integer (c_int) :: iStat
466 integer (c_int) :: iIndex
467 type (DATA_CATALOG_ENTRY_T),
pointer :: pPERCENT_IMPERVIOUS
468 type (DATA_CATALOG_ENTRY_T),
pointer :: pPERCENT_PERVIOUS
469 type (DATA_CATALOG_ENTRY_T),
pointer :: pFRACTION_IMPERVIOUS
470 type (DATA_CATALOG_ENTRY_T),
pointer :: pFRACTION_PERVIOUS
471 type ( GENERAL_GRID_T ),
pointer :: pTempGrd
473 ppercent_impervious =>
dat%find(
"PERCENT_IMPERVIOUS_COVER")
474 ppercent_pervious =>
dat%find(
"PERCENT_PERVIOUS_COVER")
475 pfraction_impervious =>
dat%find(
"FRACTION_IMPERVIOUS_COVER")
476 pfraction_pervious =>
dat%find(
"FRACTION_PERVIOUS_COVER")
478 if (
associated(ppercent_impervious) )
then
480 call ppercent_impervious%getvalues()
482 if (
associated( ppercent_impervious%pGrdBase) )
then
483 model%pervious_fraction = pack( 1.0_c_float - ppercent_impervious%pGrdBase%rData/100.0_c_float, model%active )
485 call die(
"INTERNAL PROGRAMMING ERROR: attempted use of NULL pointer", __file__, __line__)
488 elseif (
associated( ppercent_pervious ) )
then
490 call ppercent_pervious%getvalues()
492 if (
associated( ppercent_pervious%pGrdBase) )
then
493 model%pervious_fraction = pack( (ppercent_pervious%pGrdBase%rData/100.0_c_float), model%active )
495 call die(
"INTERNAL PROGRAMMING ERROR: attempted use of NULL pointer", __file__, __line__)
498 elseif (
associated(pfraction_impervious) )
then
500 call pfraction_impervious%getvalues()
502 if (
associated( pfraction_impervious%pGrdBase) )
then
503 model%pervious_fraction = pack( 1.0_c_float - pfraction_impervious%pGrdBase%rData, model%active )
505 call die(
"INTERNAL PROGRAMMING ERROR: attempted use of NULL pointer", __file__, __line__)
508 elseif (
associated( pfraction_pervious ) )
then
510 call pfraction_pervious%getvalues()
512 if (
associated( pfraction_pervious%pGrdBase) )
then
513 model%pervious_fraction = pack( pfraction_pervious%pGrdBase%rData, model%active )
515 call die(
"INTERNAL PROGRAMMING ERROR: attempted use of NULL pointer", __file__, __line__)
520 model%pervious_fraction = 1.0_c_float
524 if ( minval( model%pervious_fraction ) <
fzero &
525 .or. maxval( model%pervious_fraction ) > 1.0_c_float ) &
526 call warn(smessage=
"One or more percent (im)pervious cover percent/fraction values are outside of " &
527 //
"valid range (0% to 100% or 0.0 to 1.0)", lfatal=
true )
529 if ( all( model%pervious_fraction < 0.01_c_float ) ) &
530 call warn(smessage=
"All (im)pervious cover percent/fraction values are suspiciously low " &
531 //
"(less than 1% or less than 0.01)", lfatal=
true, &
532 shints=
"Check to see whether (im)pervious cover is expressed as a fraction (0.0-1.0)" &
533 //
" or a percentage (0-100%)." )
535 ptempgrd =>
grid_create( inx=model%number_of_columns, iny=model%number_of_rows, &
536 rx0=model%X_ll, ry0=model%Y_ll, &
539 ptempgrd%rData = unpack( model%pervious_fraction, model%active, model%nodata_fill_value )
541 call grid_writearcgrid( sfilename=
"Fraction_pervious_surface__as_read_in_unitless.asc",
pgrd=ptempgrd )
552 integer (c_int) :: iStat
553 integer (c_int) :: iIndex
554 type (DATA_CATALOG_ENTRY_T),
pointer :: pPERCENT_CANOPY_COVER
555 type (DATA_CATALOG_ENTRY_T),
pointer :: pFRACTION_CANOPY_COVER
556 type ( GENERAL_GRID_T ),
pointer :: pTempGrd
558 ppercent_canopy_cover =>
dat%find(
"PERCENT_CANOPY_COVER")
559 pfraction_canopy_cover =>
dat%find(
"FRACTION_CANOPY_COVER")
561 if (
associated(ppercent_canopy_cover) )
then
563 call ppercent_canopy_cover%getvalues()
565 if (
associated( ppercent_canopy_cover%pGrdBase) )
then
566 model%canopy_cover_fraction = pack( ppercent_canopy_cover%pGrdBase%rData/100.0_c_float, model%active )
568 call die(
"INTERNAL PROGRAMMING ERROR: attempted use of NULL pointer", __file__, __line__)
571 elseif (
associated(pfraction_canopy_cover) )
then
573 call pfraction_canopy_cover%getvalues()
575 if (
associated( pfraction_canopy_cover%pGrdBase) )
then
576 model%canopy_cover_fraction = pack( pfraction_canopy_cover%pGrdBase%rData, model%active )
578 call die(
"INTERNAL PROGRAMMING ERROR: attempted use of NULL pointer", __file__, __line__)
583 model%canopy_cover_fraction = 1.0_c_float
585 call warn(
"Could not find a grid or constant value for the canopy cover fraction. Using a" &
586 //
" value of 1.0 for the entire model domain." )
590 if ( minval( model%canopy_cover_fraction ) <
fzero &
591 .or. maxval( model%canopy_cover_fraction ) > 1.0_c_float ) &
592 call warn(smessage=
"One or more percent canopy cover percent/fraction values values are outside of " &
593 //
"valid range (0% to 100% or 0.0 to 1.0)", lfatal=
true )
595 if ( all( model%canopy_cover_fraction < 0.01_c_float ) ) &
596 call warn(smessage=
"All canopy cover percent/fraction values are suspiciously low " &
597 //
"(less than 1% or less than 0.01)", lfatal=
true, &
598 shints=
"Check to see whether canopy cover is expressed as a fraction (0.0-1.0)" &
599 //
" or a percentage (0-100%)." )
601 ptempgrd =>
grid_create( inx=model%number_of_columns, iny=model%number_of_rows, &
602 rx0=model%X_ll, ry0=model%Y_ll, &
605 ptempgrd%rData = unpack( model%canopy_cover_fraction, model%active, model%nodata_fill_value )
618 integer (c_int) :: iStat
619 integer (c_int) :: iIndex
620 type (DATA_CATALOG_ENTRY_T),
pointer :: pHSG
622 phsg =>
dat%find(
"HYDROLOGIC_SOILS_GROUP")
624 if (
associated(phsg) )
then
626 if (
associated( phsg%pGrdBase) )
then
627 model%soil_group = pack( phsg%pGrdBase%iData, model%active )
629 call die(
"INTERNAL PROGRAMMING ERROR: attempted use of NULL pointer", __file__, __line__)
634 call die(
"Attempted use of NULL pointer. Failed to find HYDROLOGIC_SOILS_GROUP data element.", &
639 call logs%write(
"Hydrologic soils groups as read into SWB data structure", ilinesbefore=1, ilinesafter=1, iloglevel=
log_debug)
641 do iindex = 1, maxval(phsg%pGrdBase%iData)
643 call logs%write(
ascharacter(count(model%soil_group == iindex) )//
" cells belong to soils group " &
657 type (DATA_CATALOG_ENTRY_T),
pointer :: pHSG
659 phsg =>
dat%find(
"HYDROLOGIC_SOILS_GROUP")
661 if (
associated(phsg) )
then
663 call phsg%getvalues()
664 call grid_writearcgrid(
"Hydrologic_soil_groups__as_read_into_SWB.asc", phsg%pGrdBase )
668 call warn(smessage=
"HYDROLOGIC_SOILS_GROUP dataset is flawed or missing.", lfatal=
true, &
669 iloglevel =
log_all, shints=
"Check to see that a valid path and filename have" &
670 //
" been ~included in the control file for the HYDROLOGIC_SOILS_GROUP dataset.", &
684 type (DATA_CATALOG_ENTRY_T),
pointer :: pPOLYGON_ID
685 logical (c_bool) :: any_problems
686 type (FSTRING_LIST_T) :: slList
687 integer (c_int),
allocatable :: polygon_id(:)
688 real (c_float),
allocatable :: rooting_depth_inches(:)
689 real (c_float),
allocatable :: soil_moisture_storage(:)
690 integer (c_int) :: iNumberOfPolygonIDs
691 type (GENERAL_GRID_T),
pointer :: pTempGrd
692 integer (c_int) :: index
696 ptempgrd =>
grid_create( inx=model%number_of_columns, iny=model%number_of_rows, &
697 rx0=model%X_ll, ry0=model%Y_ll, &
704 ppolygon_id =>
dat%find(
"POLYGON_ID")
706 if ( .not.
associated( ppolygon_id ) )
exit
708 call ppolygon_id%getvalues()
709 call grid_writearcgrid(
"Polygon_ID__as_read_into_SWB.asc", ppolygon_id%pGrdBase )
711 model%polygon_id = pack( ppolygon_id%pGrdBase%iData, model%active )
821 character (len=*),
intent(in) :: sfilename
822 character (len=*),
intent(in),
optional :: sgridspecification
826 character (len=256) :: srecord, ssubstring
827 character (len=:),
allocatable :: stext
828 integer (c_int) :: istat
829 integer (c_int) :: iindex
830 integer (c_int) :: icount
836 call cf%open( sfilename = sfilename )
839 if (
present( sgridspecification ) )
then
840 call cf_dict%get_value(stext,
"GRID")
841 pdict =>
cf_dict%get_next_entry()
842 call assert(
associated( pdict ),
"INTERNAL PROGRAMMING ERROR -- Attempted use of null poitner", &
844 call cf%writeLine( trim( sgridspecification ) )
852 do while (
associated( pdict ) )
854 call cf_dict%get_value( stext )
855 call cf%writeLine( trim(pdict%key)//
" "//stext )
856 pdict =>
cf_dict%get_next_entry()
860 if (
present( slextradirectives ) )
then
862 icount = slextradirectives%count
866 call cf%writeLine( trim( slextradirectives%get( iindex ) ) )
880 character (len=*),
intent(in) :: sfilename
883 character (len=256) :: srecord, skey, svalue
884 integer (c_int) :: istat
886 integer (c_int) :: dumpfile_count
892 call cf%open( sfilename = sfilename, &
893 scommentchars =
"#%!+=|[{(-*$", &
894 sdelimiters =
"WHITESPACE", &
895 lhasheader = .
false._c_bool )
898 cf%remove_extra_delimiters =
true
903 srecord = cf%readLine()
905 if ( cf%isEOF() )
exit
910 call assert(istat == 0,
"Failed to allocate memory for dictionary object", &
914 call chomp(srecord, skey, cf%sDelimiters, cf%remove_extra_delimiters )
916 if ( len_trim( skey ) > 0 )
then
920 if ( skey .strequal.
"DUMP_VARIABLES" )
then
921 dumpfile_count = dumpfile_count + 1
922 skey = trim(skey)//
"_"//
ascharacter(dumpfile_count)
929 call chomp( srecord, svalue, cf%sDelimiters, cf%remove_extra_delimiters )
931 do while ( len_trim( svalue ) > 0 )
936 call chomp( srecord, svalue, cf%sDelimiters, cf%remove_extra_delimiters )
971 character (len=*),
intent(in) :: sKey
972 character (len=*),
intent(in) :: sPathname
973 logical (c_bool),
intent(in) :: lOptional
974 integer (c_int),
intent(in) :: iDataType
977 type (FSTRING_LIST_T) :: myDirectives
978 type (FSTRING_LIST_T) :: myOptions
979 integer (c_int) :: iIndex
980 character (len=512) :: sCmdText
981 character (len=512) :: sArgText
982 character (len=512) :: sArgText_1
983 character (len=512) :: sArgText_2
984 character (len=512) :: sArgText_3
985 character (len=512) :: sArgText_4
986 integer (c_int) :: iStat
987 type (DATA_CATALOG_ENTRY_T),
pointer :: pENTRY
988 logical (c_bool) :: lGridPresent
999 mydirectives =
cf_dict%grep_keys( skey )
1003 if ( mydirectives%count == 0 )
then
1005 call logs%write(
"Your control file is missing gridded data relating to "//
dquote(skey)//
".", &
1008 if (.not. loptional)
then
1009 call warn(
"Your control file is missing gridded data relating to "//
dquote(skey)//
".", &
1017 allocate(pentry, stat=istat)
1018 call assert( istat == 0,
"Failed to allocate memory for the "//
dquote(skey)//
" data structure", &
1019 __file__, __line__ )
1027 call myoptions%clear()
1030 do iindex = 1, mydirectives%count
1034 scmdtext = mydirectives%get(iindex)
1037 call cf_dict%get_values(scmdtext, myoptions )
1040 sargtext_1 = myoptions%get(1)
1041 sargtext_2 = myoptions%get(2)
1042 sargtext_3 = myoptions%get(3)
1043 sargtext_4 = myoptions%get(4)
1047 sargtext = myoptions%get(1, myoptions%count )
1050 call logs%write(
"> "//trim(scmdtext)//
" "//trim(sargtext), ilinesbefore=1 )
1055 if ( scmdtext .strapprox. skey )
then
1060 if (sargtext_1 .strapprox.
"CONSTANT" )
then
1063 call die(
"Non-numeric argument supplied as a CONSTANT in your control file.", &
1064 shints=
"Faulty control file argument was "//
squote(trim(scmdtext)//
" "//trim(sargtext)))
1066 select case ( idatatype )
1070 call pentry%initialize( &
1071 sdescription=trim(scmdtext), &
1072 rconstant=
asfloat(sargtext_2) )
1077 call pentry%initialize( &
1078 sdescription=trim(scmdtext), &
1079 iconstant=
asint(sargtext_2) )
1084 call die(
"INTERNAL PROGRAMMING ERROR: Unhandled data type selected.", &
1085 __file__, __line__ )
1089 elseif ( (sargtext_1 .strapprox.
"TABLE") &
1090 .or. (sargtext_1 .strapprox.
"TABLE_LOOKUP") )
then
1092 if (len_trim(sargtext_2) > 0) &
1095 select case ( idatatype )
1099 call pentry%initialize( &
1100 sdescription=trim(scmdtext), &
1101 sdatecolumnname =
"date", &
1102 svaluecolumnname = pentry%sVariableName_z, &
1108 call pentry%initialize( &
1109 sdescription=trim(scmdtext), &
1110 sdatecolumnname =
"date", &
1111 svaluecolumnname = pentry%sVariableName_z, &
1117 call die(
"INTERNAL PROGRAMMING ERROR: Unhandled data type selected.", &
1118 __file__, __line__ )
1121 elseif ( (sargtext_1 .strapprox.
"ARC_ASCII") &
1122 .or. (sargtext_1 .strapprox.
"SURFER") &
1123 .or. (sargtext_1 .strapprox.
"ARC_GRID") )
then
1125 call pentry%initialize( &
1126 sdescription=trim(scmdtext), &
1127 sfiletype=trim(sargtext_1), &
1129 idatatype=idatatype )
1132 elseif ( sargtext_1 .strapprox.
"NETCDF" )
then
1134 call pentry%initialize_netcdf( &
1135 sdescription=trim(scmdtext), &
1136 sfilename =
fix_pathname(trim(spathname)//sargtext_2), &
1137 idatatype=idatatype )
1148 call warn(
"Did not find a valid "//
dquote(skey)//
" option. Value supplied was: "//
dquote(sargtext_1), &
1149 lfatal =
true, shints=
"Valid options include "//
dquote(
"ARC_ASCII")//
", "//
dquote(
"ARC_GRID") &
1155 elseif ( scmdtext .containssimilar.
"_USE_MAJORITY_FILTER" )
then
1157 call pentry%set_majority_filter_flag(
true )
1159 elseif ( scmdtext .containssimilar.
"_MONTHNAMES_CAPITALIZED" )
then
1163 elseif ( scmdtext .containssimilar.
"_MONTHNAMES_LOWERCASE" )
then
1167 elseif ( scmdtext .containssimilar.
"_MONTHNAMES_UPPERCASE" )
then
1171 elseif ( scmdtext .containssimilar.
"_CONVERSION_FACTOR" )
then
1173 call pentry%set_scale(
asdouble(sargtext_1))
1175 elseif ( scmdtext .containssimilar.
"NETCDF_X_VAR_ADD_OFFSET" )
then
1177 call pentry%set_X_offset(
asdouble( sargtext_1 ) )
1179 elseif ( scmdtext .containssimilar.
"NETCDF_Y_VAR_ADD_OFFSET" )
then
1181 call pentry%set_Y_offset(
asdouble( sargtext_1 ) )
1183 elseif ( scmdtext .containssimilar.
"_SCALE_FACTOR" )
then
1185 call pentry%set_scale(
asdouble(sargtext_1))
1187 elseif ( scmdtext .containssimilar.
"_ADD_OFFSET" )
then
1189 call pentry%set_add_offset(
asdouble(sargtext_1))
1191 elseif ( scmdtext .containssimilar.
"_SUBTRACT_OFFSET" )
then
1193 call pentry%set_sub_offset(
asdouble(sargtext_1))
1195 elseif ( scmdtext .containssimilar.
"_UNITS_KELVIN" )
then
1199 call pentry%set_scale(
f_per_c)
1201 elseif ( scmdtext .containssimilar.
"_UNITS_CELSIUS" )
then
1204 call pentry%set_scale(
f_per_c)
1206 elseif ( scmdtext .containssimilar.
"_UNITS_MILLIMETERS" )
then
1208 call pentry%set_scale(1.0_c_double /
mm_per_in)
1210 elseif ( scmdtext .containssimilar.
"_COORDINATE_TOLERANCE" )
then
1212 call pentry%set_coordinate_tolerance(
asdouble(sargtext_1))
1214 elseif ( scmdtext .containssimilar.
"NETCDF_X_VAR" )
then
1216 pentry%sVariableName_x = trim(sargtext_1)
1218 elseif ( scmdtext .containssimilar.
"NETCDF_Y_VAR" )
then
1220 pentry%sVariableName_y = trim(sargtext_1)
1222 elseif ( (scmdtext .containssimilar.
"NETCDF_Z_VAR") &
1223 .or. (scmdtext .containssimilar.
"COLUMN_NAME") )
then
1225 pentry%sVariableName_z = trim(sargtext_1)
1227 elseif ( (scmdtext .containssimilar.
"NETCDF_TIME_VAR") &
1228 .or. (scmdtext .containssimilar.
"DATE_COLUMN_NAME") )
then
1230 pentry%sVariableName_time = trim(sargtext_1)
1232 elseif ( scmdtext .containssimilar.
"NETCDF_VARIABLE_ORDER" )
then
1234 call pentry%set_variable_order(
aslowercase(sargtext_1) )
1236 elseif ( scmdtext .containssimilar.
"NETCDF_FLIP_VERTICAL")
then
1238 call pentry%set_grid_flip_vertical()
1240 elseif ( scmdtext .containssimilar.
"NETCDF_FLIP_HORIZONTAL" )
then
1242 call pentry%set_grid_flip_horizontal()
1244 elseif ( scmdtext .containssimilar.
"NETCDF_NO_AUTOMATIC_GRID_FLIPPING" )
then
1246 call pentry%do_not_allow_netcdf_grid_data_flipping()
1248 elseif ( scmdtext .containssimilar.
"ALLOW_MISSING_FILES" )
then
1250 call pentry%allow_missing_files()
1252 elseif ( scmdtext .containssimilar.
"NETCDF_MAKE_LOCAL_ARCHIVE" )
then
1254 call pentry%set_make_local_archive(
true)
1256 elseif ( scmdtext .containssimilar.
"_PROJECTION_DEFINITION" )
then
1258 call pentry%set_source_PROJ4( trim(sargtext) )
1260 elseif ( scmdtext .containssimilar.
"_DATE_COLUMN" )
then
1262 pentry%sDateColumnName = trim( sargtext_1 )
1264 elseif ( scmdtext .containssimilar.
"_VALUE_COLUMN" )
then
1266 pentry%sValueColumnName = trim( sargtext_1 )
1268 elseif ( scmdtext .containssimilar.
"_MINIMUM_ALLOWED_VALUE" )
then
1270 pentry%rMinAllowedValue =
asfloat(sargtext_1)
1272 elseif ( scmdtext .containssimilar.
"_MAXIMUM_ALLOWED_VALUE" )
then
1274 pentry%rMaxAllowedValue =
asfloat(sargtext_1)
1276 elseif ( scmdtext .containssimilar.
"_MISSING_VALUES_CODE" )
then
1278 pentry%rMissingValuesCode =
asfloat(sargtext_1)
1280 elseif ( scmdtext .containssimilar.
"_MISSING_VALUES_OPERATOR" )
then
1282 pentry%sMissingValuesOperator = trim(sargtext_1)
1284 elseif ( scmdtext .containssimilar.
"_MISSING_VALUES_ACTION" )
then
1286 if (sargtext_1 .strapprox.
"ZERO")
then
1290 elseif (sargtext_1 .strapprox.
"MEAN" )
then
1296 call warn(
"Unknown missing value action supplied for " &
1301 elseif ( scmdtext .containssimilar.
"_METHOD" )
then
1306 elseif ( scmdtext .containssimilar.
"_LOOKUP_TABLE" )
then
1313 call warn(
"Unknown directive detected in code at line "//
ascharacter(__line__)//
", file "//__file__ &
1314 //
". ~Ignoring. Directive is: "//
dquote(scmdtext), iloglevel=
log_debug )
1322 if ( lgridpresent )
call dat%add( key=skey, data=pentry )
1328 call mydirectives%clear()
1329 call myoptions%clear()
1338 type (FSTRING_LIST_T) :: myOptions
1339 integer (c_int) :: iIndex
1340 character (len=:),
allocatable :: sArgText
1341 integer (c_int) :: iStat
1342 real (c_double) :: rX0, rX1, rY0, rY1, rGridCellSize
1343 integer (c_int) :: iNX, iNY
1344 real (c_float) :: fTempVal
1347 call cf_dict%get_values(
"GRID", myoptions )
1351 sargtext = myoptions%get(1, myoptions%count )
1354 call logs%write(
"> GRID "//sargtext, ilinesbefore=1 )
1356 inx =
asint( myoptions%get(1) )
1357 iny =
asint( myoptions%get(2) )
1361 if ( myoptions%count == 5 )
then
1363 rgridcellsize =
asdouble( myoptions%get(5) )
1365 call model%initialize_grid(inx, iny, rx0, ry0, rgridcellsize)
1367 rx1 = rx0 + rgridcellsize * real(inx, c_double)
1368 ry1 = ry0 + rgridcellsize * real(iny, c_double)
1370 elseif ( myoptions%count == 7 )
then
1374 rgridcellsize =
asdouble( myoptions%get(7) )
1376 ftempval = ( rx1 - rx0 ) / real(inx, c_double)
1378 call model%initialize_grid(inx, iny, rx0, ry0, rgridcellsize)
1382 call warn(
"Grid specification is flawed or missing.", lfatal=
true, iloglevel =
log_all, lecho =
true )
1386 call myoptions%clear()
1389 call cf_dict%get_values(
"BASE_PROJECTION_DEFINITION", myoptions )
1391 if ( myoptions%get(1) .strequal.
"<NA>" )
then
1392 call die(smessage=
"Your control file is missing a BASE_PROJECTION_DEFINITION entry.", &
1393 shints=
"This version of SWB requires that you add a BASE_PROJECTION_DEFINITION entry " &
1394 //
"to your control file." )
1399 sargtext = myoptions%get(1, myoptions%count )
1402 call logs%write(
"> BASE_PROJECTION_DEFINITION "//sargtext, ilinesbefore=1)
1412 bnds%fGridCellSize = rgridcellsize
1413 bnds%sPROJ4_string = trim(sargtext)
1415 model%PROJ4_string = trim(sargtext)
1424 type (FSTRING_LIST_T) :: myOptions
1425 integer (c_int) :: iIndex
1426 integer (c_int) :: jIndex
1427 character (len=:),
allocatable :: sArgText
1428 character (len=:),
allocatable :: sAction
1429 character (len=:),
allocatable :: sOutput
1430 integer (c_int) :: iStat
1431 logical (c_bool) :: enable_output
1433 enable_output =
true
1436 call cf_dict%get_values(
"OUTPUT", myoptions )
1450 sargtext = myoptions%get(1, myoptions%count )
1453 call logs%write(
"> OUTPUT"//sargtext, ilinesbefore=1 )
1456 do iindex=1,myoptions%count
1458 soutput = myoptions%get( iindex )
1460 if ( ( soutput .strapprox.
"ENABLE") .or. ( soutput .strapprox.
"ACTIVE") )
then
1462 enable_output =
true
1464 elseif ( ( soutput .strapprox.
"DISABLE") .or. ( soutput .strapprox.
"INACTIVE") )
then
1466 enable_output =
false
1470 if ( soutput .strapprox.
"ALL" )
then
1472 outspecs(:)%is_active = enable_output
1478 if (
outspecs( jindex )%variable_name .strapprox. soutput )
then
1479 outspecs( jindex )%is_active = enable_output
1480 if ( enable_output )
call logs%write(
"> Enabling output for "//
squote(soutput), ilinesbefore=1 )
1481 if ( .not. enable_output )
call logs%write(
"> Disabling output for "//
squote(soutput), ilinesbefore=1 )
1489 call myoptions%clear()
1498 type (FSTRING_LIST_T) :: myDirectives
1499 type (FSTRING_LIST_T) :: myOptions
1500 integer (c_int) :: iIndex
1501 character (len=:),
allocatable :: sCmdText
1502 character (len=:),
allocatable :: sOptionText
1503 character (len=:),
allocatable :: sArgText
1504 integer (c_int) :: iStat
1505 logical (c_bool) :: lHaveStartDate
1506 logical (c_bool) :: lHaveEndDate
1508 lhavestartdate =
false
1509 lhaveenddate =
false
1511 mydirectives =
cf_dict%grep_keys(
"DATE")
1524 do iindex = 1, mydirectives%count
1528 scmdtext = mydirectives%get(iindex)
1531 call cf_dict%get_values(scmdtext, myoptions )
1535 sargtext = myoptions%get(1, myoptions%count )
1538 call logs%write(
"> "//scmdtext//
" "//sargtext, ilinesbefore=1 )
1541 soptiontext = myoptions%get(1)
1543 select case ( scmdtext )
1545 case (
"START_DATE",
"STARTDATE",
"BEGIN_DATE" )
1547 lhavestartdate =
true
1548 call sim_dt%start%parseDate( soptiontext )
1549 call sim_dt%start%calcJulianDay()
1551 case (
"END_DATE",
"ENDDATE",
"STOP_DATE" )
1554 call sim_dt%end%parseDate( soptiontext )
1555 call sim_dt%end%calcJulianDay()
1559 call warn(
"Unknown directive present, line "//
ascharacter(__line__)//
", file "//__file__ &
1560 //
". Ignoring. Directive is: "//
dquote(scmdtext), iloglevel=
log_debug )
1566 if ( lhavestartdate .and. lhaveenddate )
then
1575 call logs%write(
"Model run start date set to: "//
sim_dt%start%prettydate(), itab=4, lecho=
true)
1576 call logs%write(
"Model run end date set to: "//
sim_dt%end%prettydate(), itab=4, lecho=
true)
1580 call warn(smessage=
"Your control file seems to be missing START_DATE and/or END_DATE", &
1581 shints=
"Add a START_DATE and/or END_DATE directive to your control file. Date " &
1582 //
"~should be specified as mm/dd/yyyy.", lfatal =
true, iloglevel =
log_all, &
1603 type (FSTRING_LIST_T) :: myDirectives
1604 type (FSTRING_LIST_T) :: myOptions
1605 type (FSTRING_LIST_T) :: slString
1606 integer (c_int) :: iIndex
1607 character (len=:),
allocatable :: sCmdText
1608 character (len=:),
allocatable :: sOptionText
1609 character (len=:),
allocatable :: sArgText
1610 character (len=:),
allocatable :: sText
1611 character (len=256) :: sBuf
1612 integer (c_int) :: iStat
1613 type (PARAMETERS_T) :: PARAMS_LU_TABLE
1614 integer (c_int) :: iCount
1615 type (DICT_ENTRY_T),
pointer :: pDict1
1616 type (DICT_ENTRY_T),
pointer :: pDict2
1620 mydirectives =
cf_dict%grep_keys(
"LOOKUP_TABLE")
1622 if ( mydirectives%count == 0 )
then
1624 call warn(
"Your control file seems to be missing the required lookup table(s).", &
1633 do iindex = 1, mydirectives%count
1636 scmdtext = mydirectives%get(iindex)
1639 call cf_dict%get_values(scmdtext, myoptions )
1643 sargtext = myoptions%get(1, myoptions%count )
1646 call logs%write(
"> "//scmdtext//
" "//sargtext, ilinesbefore=1 )
1655 if ( index(string=scmdtext, substring=
"LOOKUP_TABLE" ) > 0 )
then
1657 call params_lu_table%add_file(
fix_pathname( soptiontext ))
1662 call warn(
"Unknown directive present, line "//
ascharacter(__line__)//
", file "//__file__ &
1663 //
". Ignoring. Directive is: "//
dquote(scmdtext), iloglevel=
log_debug )
1669 if ( icount > 0 )
then
1671 call params_lu_table%munge_file(delimiters=
tab)
1672 call params_dict%print_all(sdescription=
"LOOKUP TABLE dictionary", &
1685 character (len=*),
intent(in) :: sKey
1686 logical (c_bool),
intent(in) :: lOptional
1689 type (FSTRING_LIST_T) :: myDirectives
1690 type (FSTRING_LIST_T) :: myOptions
1691 integer (c_int) :: iIndex
1692 integer (c_int) :: indx
1693 character (len=:),
allocatable :: sCmdText
1695 type (FSTRING_LIST_T) :: argv_list
1696 character (len=:),
allocatable :: sArgText
1697 integer (c_int) :: iStat
1698 integer (c_int) :: status
1699 logical (c_bool) :: lFatal
1700 integer (c_int) :: num_elements
1703 mydirectives =
cf_dict%grep_keys( trim(skey) )
1705 lfatal = .not. loptional
1707 if ( mydirectives%count == 0 )
then
1709 call warn(
"Your control file is missing any of the required directives relating to "//
dquote(skey)//
" method.", &
1710 lfatal = lfatal, iloglevel =
log_all, lecho =
true )
1718 do iindex = 1, mydirectives%count
1721 scmdtext = mydirectives%get(iindex)
1724 call cf_dict%get_values(scmdtext, myoptions )
1728 sargtext = myoptions%get(1, myoptions%count )
1731 call logs%write(
"> "//scmdtext//
" "//sargtext, ilinesbefore=1, iloglevel=
log_all, lecho=
false )
1736 num_elements = myoptions%count
1738 call argv_list%clear()
1740 do indx=1, myoptions%count
1741 call argv_list%append( myoptions%get( indx ) )
1747 if ( ( scmdtext .contains.
"METHOD" ) .or. ( scmdtext .contains.
"DUMP" ) )
then
1749 call model%set_method_pointers( trim(scmdtext), argv_list )
1764 type (FSTRING_LIST_T) :: myDirectives
1765 type (FSTRING_LIST_T) :: myOptions
1766 integer (c_int) :: iIndex
1767 integer (c_int) :: indx
1768 character (len=:),
allocatable :: sCmdText
1770 type (FSTRING_LIST_T) :: argv_list
1771 character (len=:),
allocatable :: sArgText
1772 integer (c_int) :: iStat
1773 integer (c_int) :: status
1774 logical (c_bool) :: lFatal
1775 integer (c_int) :: num_elements
1776 character (len=:),
allocatable :: Option_Name
1779 mydirectives =
cf_dict%grep_keys(
"OPTION" )
1785 do iindex = 1, mydirectives%count
1788 scmdtext = mydirectives%get(iindex)
1791 call cf_dict%get_values(scmdtext, myoptions )
1795 sargtext = myoptions%get(1, myoptions%count )
1798 call logs%write(
"> "//scmdtext//
" "//sargtext, ilinesbefore=1 )
1803 num_elements = myoptions%count
1805 call argv_list%clear()
1807 do indx=1, myoptions%count
1808 call argv_list%append( myoptions%get( indx ) )
1813 if ( ( scmdtext .contains.
"OPTION" ) )
then
1815 option_name = argv_list%get(1)
1817 select case ( option_name )
1819 case (
"NO_LATLON_IN_OUTPUT" )
1822 call logs%write(
"==> LATITUDE and LONGITUDE will *not* be included in output NetCDF files.", ilinesbefore=1 )
1839 integer (c_int) :: iIndex
1842 rx0=model%X_ll, ry0=model%Y_ll, &
1845 allocate ( model%X(model%number_of_columns ) )
1846 allocate ( model%Y(model%number_of_rows ) )
1857 stoproj4=
"+proj=lonlat +ellps=GRS80 +datum=WGS84 +no_defs" )
1859 model%latitude = pack(
pcoord_grd%rY, model%active )
1972 integer (c_int) :: iIndex
1973 integer (c_int) :: iStat
1974 character (len=256) :: sBuf
1975 type (FSTRING_LIST_T) :: slList
1976 integer( c_int),
allocatable :: iLanduseTableCodes(:)
1977 integer (c_int) :: iNumberOfLanduses
1978 real (c_float),
allocatable :: SURFACE_STORAGE_MAXIMUM(:)
1979 real (c_float) :: current_surface_storage_max
1983 call sllist%append(
"LU_Code" )
1984 call sllist%append(
"Landuse_Lookup_Code" )
1987 call params%get_parameters( slkeys=sllist, ivalues=ilandusetablecodes )
1988 inumberoflanduses = count( ilandusetablecodes >= 0 )
1991 call sllist%append(
"Surface_Storage_Max")
1992 call sllist%append(
"Surface_Storage_Maximum")
1994 model%surface_storage_max = 0.0_c_float
1996 call params%get_parameters( slkeys=sllist, fvalues=surface_storage_maximum, lfatal=
false )
1998 if ( all( surface_storage_maximum >
rtinyval ) )
then
2000 do iindex=1, ubound( surface_storage_maximum, 1)
2002 current_surface_storage_max = surface_storage_maximum( iindex )
2004 where( model%landuse_index == iindex )
2006 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
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
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.
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)