65 &
"fvcom grid (unstructured) surface forcing" 68 &
"FVCOM grid (unstructured) surface forcing" 71 &
"wrf grid (structured) surface forcing" 74 &
"single-point time-dependent surface forcing" 81 TYPE(
ncfile),
POINTER :: tide_file
82 TYPE(
ncvar),
POINTER :: tide_elv_n, tide_elv_p
90 TYPE(
ncfile),
POINTER :: ncf
91 INTEGER rivers_in_file
93 TYPE(
time) :: river_period
94 INTEGER,
ALLOCATABLE :: riv_file2loc(:)
98 TYPE(
ncvar),
POINTER :: flux_n, flux_p
99 TYPE(
ncvar),
POINTER :: temp_n, temp_p
100 TYPE(
ncvar),
POINTER :: salt_n, salt_p
102 END TYPE a_river_file
103 TYPE(a_river_file),
ALLOCATABLE :: river_forcing(:)
109 TYPE(
ncfile),
POINTER :: gwater_file
111 INTEGER :: gwater_forcing_type
112 INTEGER,
PARAMETER :: gwater_is_xxx = 0
113 INTEGER,
PARAMETER :: gwater_is_fvcomgrid = 1
115 INTEGER :: gwater_units
116 INTEGER,
PARAMETER :: gwater_m3s_1=1
117 INTEGER,
PARAMETER :: gwater_ms_1=2
119 TYPE(
time) :: gwater_period
124 TYPE(
ncvar),
POINTER :: gwater_flux_n, gwater_flux_p
125 TYPE(
ncvar),
POINTER :: gwater_temp_n, gwater_temp_p
126 TYPE(
ncvar),
POINTER :: gwater_salt_n, gwater_salt_p
130 TYPE(
ncfile),
POINTER :: obc_s_file
132 INTEGER :: obc_s_type
133 INTEGER,
PARAMETER :: obc_s_sigma = 1
134 TYPE(
ncvar),
POINTER :: obc_s_n, obc_s_p
138 TYPE(
ncfile),
POINTER :: obc_t_file
140 INTEGER :: obc_t_type
141 INTEGER,
PARAMETER :: obc_t_sigma = 1
142 TYPE(
ncvar),
POINTER :: obc_t_n, obc_t_p
151 INTEGER :: heat_forcing_type
153 INTEGER,
PARAMETER :: heat_is_wrfgrid = 0
154 INTEGER,
PARAMETER :: heat_is_fvcomgrid = 1
156 TYPE(
time) :: heat_period
158 TYPE(
ncfile),
POINTER :: heat_file
164 TYPE(
ncvar),
POINTER :: heat_swv_n, heat_swv_p
168 TYPE(
ncvar),
POINTER :: heat_net_n, heat_net_p
171 INTEGER :: winds_forcing_type
173 INTEGER,
PARAMETER :: winds_are_wrfgrid = 0
174 INTEGER,
PARAMETER :: winds_are_fvcomgrid = 1
175 INTEGER,
PARAMETER :: winds_are_pt_source = 2
178 TYPE(
time) :: winds_period
180 TYPE(
ncfile),
POINTER :: winds_file
184 TYPE(
ncvar),
POINTER :: winds_strx_n, winds_strx_p
185 TYPE(
ncvar),
POINTER :: winds_stry_n, winds_stry_p
195 INTEGER :: waves_forcing_type
197 INTEGER,
PARAMETER :: waves_are_wrfgrid = 0
198 INTEGER,
PARAMETER :: waves_are_fvcomgrid = 1
200 TYPE(
time) :: waves_period
202 TYPE(
ncfile),
POINTER :: waves_file
206 TYPE(
ncvar),
POINTER :: waves_height_n, waves_height_p
207 TYPE(
ncvar),
POINTER :: waves_length_n, waves_length_p
208 TYPE(
ncvar),
POINTER :: waves_direction_n, waves_direction_p
209 TYPE(
ncvar),
POINTER :: waves_period_n, waves_period_p
210 TYPE(
ncvar),
POINTER :: waves_per_bot_n, waves_per_bot_p
211 TYPE(
ncvar),
POINTER :: waves_ub_bot_n, waves_ub_bot_p
214 INTEGER :: precip_forcing_type
216 INTEGER,
PARAMETER :: precip_is_wrfgrid = 0
217 INTEGER,
PARAMETER :: precip_is_fvcomgrid = 1
219 TYPE(
time) :: precip_period
221 TYPE(
ncfile),
POINTER :: precip_file
225 TYPE(
ncvar),
POINTER :: precip_pre_n, precip_pre_p
226 TYPE(
ncvar),
POINTER :: precip_evp_n, precip_evp_p
230 INTEGER :: airpressure_forcing_type
232 INTEGER,
PARAMETER :: airpressure_is_wrfgrid = 0
233 INTEGER,
PARAMETER :: airpressure_is_fvcomgrid = 1
235 TYPE(
time) :: airpressure_period
237 TYPE(
ncfile),
POINTER :: airpressure_p_file
241 TYPE(
ncvar),
POINTER :: air_pressure_n, air_pressure_p
246 INTEGER :: ice_forcing_type
248 INTEGER,
PARAMETER :: ice_is_wrfgrid = 0
249 INTEGER,
PARAMETER :: ice_is_fvcomgrid = 1
251 TYPE(
time) :: ice_period
253 TYPE(
ncfile),
POINTER :: ice_file
257 TYPE(
ncvar),
POINTER :: ice_swv_n, ice_swv_p
258 TYPE(
ncvar),
POINTER :: ice_sat_n, ice_sat_p
259 TYPE(
ncvar),
POINTER :: ice_spq_n, ice_spq_p
260 TYPE(
ncvar),
POINTER :: ice_cld_n, ice_cld_p
264 INTEGER :: icing_forcing_type
266 INTEGER,
PARAMETER :: icing_is_wrfgrid = 0
267 INTEGER,
PARAMETER :: icing_is_fvcomgrid = 1
269 TYPE(
time) :: icing_period
271 TYPE(
ncfile),
POINTER :: icing_file
275 TYPE(
ncvar),
POINTER :: icing_sat_n, icing_sat_p
276 TYPE(
ncvar),
POINTER :: icing_wspx_n, icing_wspx_p
277 TYPE(
ncvar),
POINTER :: icing_wspy_n, icing_wspy_p
306 WRITE(ipt,* )
'! SETTING UP PRESCRIBED BOUNDARY CONDITIONS ' 312 NULLIFY(tide_file, tide_elv_n, tide_elv_p)
316 NULLIFY(heat_file,heat_intp_n, heat_intp_c, heat_swv_p,&
319 NULLIFY(winds_file,winds_intp_n,winds_intp_c, winds_strx_n,&
320 & winds_strx_p, winds_stry_n, winds_stry_p)
322 NULLIFY(airpressure_p_file,airpressure_intp_n,airpressure_intp_c, air_pressure_n,&
325 NULLIFY(waves_file,waves_intp_n,waves_intp_c, &
326 & waves_height_n, waves_height_p, &
327 & waves_length_n, waves_length_p, &
328 & waves_direction_n, waves_direction_p, &
329 & waves_period_n, waves_period_p, &
330 & waves_per_bot_n, waves_per_bot_p, &
331 & waves_ub_bot_n, waves_ub_bot_p )
342 CALL surface_windstress
343 CALL surface_precipitation
344 CALL surface_airpressure
355 CALL ice_model_forcing
361 SUBROUTINE ground_water
364 TYPE(
ncatt),
POINTER :: att, att_date
365 TYPE(
ncdim),
POINTER :: dim
366 TYPE(
ncvar),
POINTER :: var
369 REAL(sp),
POINTER :: storage_arr(:,:), storage_vec(:)
370 CHARACTER(len=60) :: tempstrng, flowstrng, saltstrng
371 TYPE(
time) :: timetest
373 INTEGER :: lats, lons, i, ntimes
379 IF (.NOT. groundwater_on )
THEN 380 IF(
dbg_set(
dbg_log))
write(ipt,*)
"! GROUND WATER FORCING IS OFF!" 389 SELECT CASE(groundwater_kind)
392 write(flowstrng,
'(f8.4)') groundwater_flow
393 write(tempstrng,
'(f8.4)') groundwater_temp
394 write(saltstrng,
'(f8.4)') groundwater_salt
397 WRITE(ipt,*)
"! SETTING UP CONSTANT GROUNDWATER FORCING: " 398 WRITE(ipt,*)
" Flow Rate: "//trim(flowstrng)
399 WRITE(ipt,*)
" Temp: "//trim(tempstrng)
400 WRITE(ipt,*)
" Salt: "//trim(saltstrng)
406 IF(groundwater_temp_on)
THEN 412 IF(groundwater_salt_on)
THEN 421 CALL fatal_error(
"STATIC GROUNDWATER Not Set Up Yet")
425 CALL fatal_error(
"TIME DEPENDENT GROUNDWATER Not Set Up Yet")
431 & (
"COULD NOT FIND GROUNDWATER FILE OBJECT",&
432 &
"FILE NAME: "//trim(groundwater_file))
435 att =>
find_att(gwater_file,
"source",found)
436 IF(.not. found) att =>
find_att(gwater_file,
"Source",found)
438 & (
"IN SURFACE HEATING BOUNDARY CONDITION FILE OBJECT",&
439 &
"FILE NAME: "//trim(groundwater_file),&
440 &
"COULD NOT FIND GLOBAL ATTRIBURE: 'source'")
444 gwater_forcing_type = gwater_is_fvcomgrid
448 gwater_forcing_type = gwater_is_fvcomgrid
452 CALL fatal_error(
"CAN NOT RECOGNIZE GROUNDWATER FILE!",&
453 &
"UNKNOWN SOURCE STRING:",trim(att%CHR(1)))
461 IF(groundwater_temp_on)
THEN 467 IF(groundwater_salt_on)
THEN 478 & (
"IN GROUNDWATER FILE OBJECT",&
479 &
"FILE NAME: "//trim(groundwater_file),&
480 &
"COULD NOT FIND THE UNLIMITED DIMENSION")
493 &(
"TO USE PERIODIC FORCING THE FILE TIME MUST COUNT FROM ZERO",&
494 &
"THE DIFFERENCE BETWEEN THE CURRENT MODEL TIME AND THE START TIME,",&
495 &
"MODULO THE FORCING PERIOD, DETERMINES THE CURRENT FORCING")
499 WRITE(ipt,*)
"! USING PERIODIC GroundWater FORCING:" 507 & (
"COULD NOT FIND GROUNDWATER FILE OBJECT",&
508 &
"FILE NAME: "//trim(groundwater_file))
511 att =>
find_att(gwater_file,
"source",found)
512 IF(.not. found) att =>
find_att(gwater_file,
"Source",found)
514 & (
"IN SURFACE HEATING BOUNDARY CONDITION FILE OBJECT",&
515 &
"FILE NAME: "//trim(groundwater_file),&
516 &
"COULD NOT FIND GLOBAL ATTRIBURE: 'source'")
520 gwater_forcing_type = gwater_is_fvcomgrid
524 gwater_forcing_type = gwater_is_fvcomgrid
528 CALL fatal_error(
"CAN NOT RECOGNIZE GROUNDWATER FILE!",&
529 &
"UNKNOWN SOURCE STRING:",trim(att%CHR(1)))
538 IF(groundwater_temp_on)
THEN 544 IF(groundwater_salt_on)
THEN 555 & (
"IN GROUNDWATER FILE OBJECT",&
556 &
"FILE NAME: "//trim(groundwater_file),&
557 &
"COULD NOT FIND THE UNLIMITED DIMENSION")
564 & (
"IN THE GROUNDWATER FILE OBJECT",&
565 &
"FILE NAME: "//trim(groundwater_file),&
566 &
"THE MODEL RUN STARTS BEFORE THE FORCING TIME SERIES")
570 & (
"IN THE GROUNDWATER FILE OBJECT",&
571 &
"FILE NAME: "//trim(groundwater_file),&
572 &
"THE MODEL RUN ENDS AFTER THE FORCING TIME SERIES")
575 CALL fatal_error(
"GROUND_WATER: UNKNOWN GROUND WATER KIND?")
581 SELECT CASE(gwater_forcing_type)
583 CASE(gwater_is_fvcomgrid)
587 &
"! SETTING UP GROUND WATER FORCING FROM A 'fvcom grid' FILE" 590 dim =>
find_dim(gwater_file,
'node',found)
592 & (
"IN THE GROUND WATER FILE OBJECT",&
593 &
"FILE NAME: "//trim(groundwater_file),&
594 &
"COULD NOT FIND DIMENSION 'node'")
597 &(
"GROUNDWATER: the number of nodes in the file does not match the fvcom grid?")
600 dim =>
find_dim(gwater_file,
'nele',found)
602 & (
"IN THE GROUND WATER FILE OBJECT",&
603 &
"FILE NAME: "//trim(groundwater_file),&
604 &
"COULD NOT FIND DIMENSION 'nele'")
607 &(
"GROUNDWATER: the number of elements in the file does not match the fvcom grid?")
612 var =>
find_var(gwater_file,
"groundwater_flux",found)
614 & (
"IN THE GROUNDWATER FILE OBJECT",&
615 &
"FILE NAME: "//trim(groundwater_file),&
616 &
"COULD NOT FIND VARIABLE 'groundwater_flux'")
620 & (
"IN THE GROUNDWATER FILE OBJECT",&
621 &
"FILE NAME: "//trim(groundwater_file),&
622 &
"COULD NOT FIND THE UNITS FOR THE VARIABLE 'groundwater_flux'")
624 IF (att%CHR(1)(1:len_trim(
"m3 s-1")) ==
"m3 s-1")
THEN 625 gwater_units = gwater_m3s_1
626 ELSEIF (att%CHR(1)(1:len_trim(
"m s-1")) ==
"m s-1")
THEN 627 gwater_units = gwater_ms_1
630 & (
"IN THE GROUNDWATER FILE OBJECT",&
631 &
"FILE NAME: "//trim(groundwater_file),&
632 &
"UNKNOWN UNITS FOR THE VARIABLE 'groundwater_flux'")
637 ALLOCATE(storage_vec(0:mt), stat = status)
638 IF(status /= 0)
CALL fatal_error(
"ALLOCATION ERROR IN GROUNDWATER")
645 ALLOCATE(storage_vec(0:mt), stat = status)
646 IF(status /= 0)
CALL fatal_error(
"ALLOCATION ERROR IN GROUNDWATER")
651 IF(groundwater_temp_on)
THEN 652 var =>
find_var(gwater_file,
"groundwater_temp",found)
654 & (
"IN THE GROUNDWATER FILE OBJECT",&
655 &
"FILE NAME: "//trim(groundwater_file),&
656 &
"COULD NOT FIND VARIABLE 'groundwater_temp'")
660 ALLOCATE(storage_vec(0:mt), stat = status)
661 IF(status /= 0)
CALL fatal_error(
"ALLOCATION ERROR IN GROUNDWATER")
668 ALLOCATE(storage_vec(0:mt), stat = status)
669 IF(status /= 0)
CALL fatal_error(
"ALLOCATION ERROR IN GROUNDWATER")
675 IF(groundwater_salt_on)
THEN 676 var =>
find_var(gwater_file,
"groundwater_salt",found)
678 & (
"IN THE GROUNDWATER FILE OBJECT",&
679 &
"FILE NAME: "//trim(groundwater_file),&
680 &
"COULD NOT FIND VARIABLE 'groundwater_salt'")
684 ALLOCATE(storage_vec(0:mt), stat = status)
685 IF(status /= 0)
CALL fatal_error(
"ALLOCATION ERROR IN GROUNDWATER")
692 ALLOCATE(storage_vec(0:mt), stat = status)
693 IF(status /= 0)
CALL fatal_error(
"ALLOCATION ERROR IN GROUNDWATER")
702 CALL fatal_error(
"CAN NOT RECOGNIZE GROUND WATER FILE TYPE!")
714 gwater_flux_p%curr_stkcnt = 0 ; gwater_flux_n%curr_stkcnt = 0
715 gwater_temp_p%curr_stkcnt = 0 ; gwater_temp_n%curr_stkcnt = 0
716 gwater_salt_p%curr_stkcnt = 0 ; gwater_salt_n%curr_stkcnt = 0
723 END SUBROUTINE ground_water
726 SUBROUTINE tidal_elevation
731 INTEGER,
ALLOCATABLE :: myobclist(:)
733 REAL(sp),
POINTER :: storage_vec(:)
735 TYPE(
ncatt),
POINTER :: att
736 TYPE(
ncdim),
POINTER :: dim
737 TYPE(
ncvar),
POINTER :: var
742 TYPE(
time) :: timetest
743 real(sp) rbuf,float_time
747 Character(len=80):: dstring
748 Character(len=80) :: dformat, tzone
750 REAL(sp),
ALLOCATABLE :: myperiod(:)
757 IF (.NOT. obc_elevation_forcing_on )
THEN 758 IF(
dbg_set(
dbg_log))
write(ipt,*)
"! TIDAL ELEVATION FORCING IS OFF!" 772 & (
"COULD NOT FIND OPEN BOUNDARY CONDITION ELEVATION FILE OBJECT",&
773 &
"FILE NAME: "//trim(obc_elevation_file))
775 att =>
find_att(tide_file,
"type",found)
777 & (
"IN OPEN BOUNDARY CONDITION ELEVATION FILE OBJECT",&
778 &
"FILE NAME: "//trim(obc_elevation_file),&
779 &
"COULD NOT FIND GLOBAL ATTRIBURE: 'type'")
782 SELECT CASE(trim(att%CHR(1)))
785 CASE(
"FVCOM NON JULIAN ELEVATION FORCING FILE",&
786 &
"FVCOM SPECTRAL ELEVATION FORCING FILE")
788 att =>
find_att(tide_file,
"components",found)
794 CALL warning(
"ATTRIBUTE 'components' IS MISSING IN THE TIDAL FORCING FILE!")
801 dim =>
find_dim(tide_file,
'tidal_components',found)
803 & (
"IN OPEN BOUNDARY CONDITION SPECTRAL ELEVATION FILE OBJECT",&
804 &
"FILE NAME: "//trim(obc_elevation_file),&
805 &
"COULD NOT FIND DIMENSION 'tidal_components'")
811 IF (0 /= status)
CALL fatal_error(
"TIDAL_ELEVATION COULD NOT & 812 &ALLOCATE 'NTIDECOMPS'")
814 var =>
find_var(tide_file,
'tide_period',found)
816 & (
"IN OPEN BOUNDARY CONDITION SPECTRAL ELEVATION FILE OBJECT",&
817 &
"FILE NAME: "//trim(obc_elevation_file),&
818 &
"COULD NOT FIND THE VARIABLE 'tide_period'")
822 & (
"IN OPEN BOUNDARY CONDITION TIME SERIES ELEVATION FILE OBJECT",&
823 &
"FILE NAME: "//trim(obc_elevation_file),&
824 &
"COULD NOT FIND PERIOD VARIRIABLE'S ATTRIBUTE 'units'")
826 if(trim(att%CHR(1)) .NE.
'seconds')
CALL fatal_error &
827 & (
"IN OPEN BOUNDARY CONDITION TIME SERIES ELEVATION FILE OBJECT",&
828 &
"FILE NAME: "//trim(obc_elevation_file),&
829 &
"PERIOD VARIRIABLE ATTRIBUTE 'units' SHOULD BE 'seconds'")
835 var =>
find_var(tide_file,
'time_origin', found)
845 & (
"Could not read date in 'time_origin' attribute of spectral forcing file")
862 CALL fatal_error(
"SPECTRAL TIDAL FORCING TIME ORIGIN VA& 863 &RIABLE MUST BE A CHARACTER STRING Date or a float& 868 CALL warning(
"Setting Spectral Tidal Phase Time Orgin to 0.0 MJD")
877 dim =>
find_dim(tide_file,
'nobc',found)
879 & (
"IN OPEN BOUNDARY CONDITION SPECTRAL ELEVATION FILE OBJECT",&
880 &
"FILE NAME: "//trim(obc_elevation_file),&
881 &
"COULD NOT FIND DIMENSION 'nobc'")
884 & (
"IN OPEN BOUNDARY CONDITION SPECTRAL ELEVATION FILE OBJECT",&
885 &
"FILE NAME: "//trim(obc_elevation_file),&
886 &
"THE DIMENSION 'nobc' MUST MATCH THE NUMBER OF OBC NODES")
891 ALLOCATE(myobclist(
iobcn))
892 var =>
find_var(tide_file,
'obc_nodes',found)
894 & (
"IN OPEN BOUNDARY CONDITION SPECTRAL ELEVATION FILE OBJECT",&
895 &
"FILE NAME: "//trim(obc_elevation_file),&
896 &
"COULD NOT FIND VARIABLE 'obc_nodes'")
903 write(ipt,*)
"NLID(MYOBCLIST)= ",
nlid(myobclist(i)),
"; I=",i
904 write(ipt,*)
"I_OBC_N= ",
i_obc_n(i),
"; I=",i
906 & (
"IN OPEN BOUNDARY CONDITION SPECTRAL ELEVATION FILE OBJECT",&
907 &
"FILE NAME: "//trim(obc_elevation_file),&
908 &
"THE LIST OF BOUNDARY NODES DOES NOT MATCH")
914 var =>
find_var(tide_file,
'tide_Eref',found)
916 & (
"IN OPEN BOUNDARY CONDITION SPECTRAL ELEVATION FILE OBJECT",&
917 &
"FILE NAME: "//trim(obc_elevation_file),&
918 &
"COULD NOT FIND VARIABLE 'tide_Eref'")
922 & (
"IN OPEN BOUNDARY CONDITION TIME SERIES ELEVATION FILE OBJECT",&
923 &
"FILE NAME: "//trim(obc_elevation_file),&
924 &
"COULD NOT FIND ELEVATION REFERENCE VARIRIABLE'S ATTRIBUTE 'units'")
926 if(trim(att%CHR(1)) .NE.
'meters')
CALL fatal_error &
927 & (
"IN OPEN BOUNDARY CONDITION TIME SERIES ELEVATION FILE OBJECT",&
928 &
"FILE NAME: "//trim(obc_elevation_file),&
929 &
"ELEVATION REFERENCE VARIRIABLE ATTRIBUTE 'units' SHOULD BE 'meters'")
936 var =>
find_var(tide_file,
'tide_Eamp',found)
938 & (
"IN OPEN BOUNDARY CONDITION SPECTRAL ELEVATION FILE OBJECT",&
939 &
"FILE NAME: "//trim(obc_elevation_file),&
940 &
"COULD NOT FIND VARIABLE 'tide_Eamp'")
944 & (
"IN OPEN BOUNDARY CONDITION TIME SERIES ELEVATION FILE OBJECT",&
945 &
"FILE NAME: "//trim(obc_elevation_file),&
946 &
"COULD NOT FIND AMPLITUDE VARIRIABLE'S ATTRIBUTE 'units'")
948 if(trim(att%CHR(1)) .NE.
'meters')
CALL fatal_error &
949 & (
"IN OPEN BOUNDARY CONDITION TIME SERIES ELEVATION FILE OBJECT",&
950 &
"FILE NAME: "//trim(obc_elevation_file),&
951 &
"AMPLITUDE VARIRIABLE ATTRIBUTE 'units' SHOULD BE 'meters'")
959 var =>
find_var(tide_file,
'tide_Ephase',found)
961 & (
"IN OPEN BOUNDARY CONDITION SPECTRAL ELEVATION FILE OBJECT",&
962 &
"FILE NAME: "//trim(obc_elevation_file),&
963 &
"COULD NOT FIND VARIABLE 'tide_Ephase'")
967 & (
"IN OPEN BOUNDARY CONDITION TIME SERIES ELEVATION FILE OBJECT",&
968 &
"FILE NAME: "//trim(obc_elevation_file),&
969 &
"COULD NOT FIND PHASE VARIRIABLE'S ATTRIBUTE 'units'")
971 if(att%CHR(1)(1:7) .NE.
'degrees')
CALL fatal_error &
972 & (
"IN OPEN BOUNDARY CONDITION TIME SERIES ELEVATION FILE OBJECT",&
973 &
"FILE NAME: "//trim(obc_elevation_file),&
974 &
"PHASE VARIRIABLE ATTRIBUTE 'units' SHOULD BE 'degrees'")
987 WRITE(ipt,* )
'! SPECTRAL TIDE : SET' 988 WRITE(ipt,101)
'! MAX TIDE AMPLITUDE : ',rbuf
1000 CASE(
"ASCII FILE DUMMY ATTRIBUTE")
1014 WRITE(ipt,* )
'! SPECTRAL TIDE : SET' 1015 WRITE(ipt,101)
'! MAX TIDE AMPLITUDE : ',rbuf
1025 CASE(
"FVCOM JULIAN TIME SERIES ELEVATION FORCING FILE", &
1026 &
"FVCOM TIME SERIES ELEVATION FORCING FILE")
1030 att =>
find_att(tide_file,
"title",found)
1035 CALL warning(
"ATTRIBUTE 'title' IS MISSING IN THE TIDAL FORCING FILE!")
1042 dim =>
find_dim(tide_file,
'time',found)
1044 & (
"IN OPEN BOUNDARY CONDITION TIME SERIES ELEVATION FILE OBJECT",&
1045 &
"FILE NAME: "//trim(obc_elevation_file),&
1046 &
"COULD NOT FIND DIMENSION 'time'")
1050 dim =>
find_dim(tide_file,
'nobc',found)
1052 & (
"IN OPEN BOUNDARY CONDITION TIME SERIES ELEVATION FILE OBJECT",&
1053 &
"FILE NAME: "//trim(obc_elevation_file),&
1054 &
"COULD NOT FIND DIMENSION 'nobc'")
1058 & (
"IN OPEN BOUNDARY CONDITION TIME SERIES ELEVATION FILE OBJECT",&
1059 &
"FILE NAME: "//trim(obc_elevation_file),&
1060 &
"THE DIMENSION 'nobc' MUST MATCH THE NUMBER OF OBC NODES")
1065 ALLOCATE(myobclist(
iobcn))
1066 var =>
find_var(tide_file,
'obc_nodes',found)
1068 & (
"IN OPEN BOUNDARY CONDITION TIME SERIES ELEVATION FILE OBJECT",&
1069 &
"FILE NAME: "//trim(obc_elevation_file),&
1070 &
"COULD NOT FIND VARIABLE 'obc_nodes'")
1077 IF(
i_obc_n(i) /= myobclist(i))
THEN 1078 write(ipt,*)
"NLID(MYOBCLIST)= ", myobclist(i),
"; I=",i
1079 write(ipt,*)
"I_OBC_N= ",
i_obc_n(i),
"; I=",i
1081 & (
"IN OPEN BOUNDARY CONDITION TIME SERIES ELEVATION FILE OBJECT",&
1082 &
"FILE NAME: "//trim(obc_elevation_file),&
1083 &
"THE LIST OF BOUNDARY NODES DOES NOT MATCH")
1094 & (
"IN OPEN BOUNDARY CONDITION TIME SERIES ELEVATION FILE OBJECT",&
1095 &
"FILE NAME: "//trim(obc_elevation_file),&
1096 &
"THE MODEL RUN STARTS BEFORE THE ELVATION TIME SERIES")
1102 & (
"IN OPEN BOUNDARY CONDITION TIME SERIES ELEVATION FILE OBJECT",&
1103 &
"FILE NAME: "//trim(obc_elevation_file),&
1104 &
"THE MODEL RUN ENDS AFTER THE ELVATION TIME SERIES")
1106 var =>
find_var(tide_file,
'elevation',found)
1108 & (
"IN OPEN BOUNDARY CONDITION TIME SERIES ELEVATION FILE OBJECT",&
1109 &
"FILE NAME: "//trim(obc_elevation_file),&
1110 &
"COULD NOT FIND VARIABLE 'elevation'")
1114 & (
"IN OPEN BOUNDARY CONDITION TIME SERIES ELEVATION FILE OBJECT",&
1115 &
"FILE NAME: "//trim(obc_elevation_file),&
1116 &
"COULD NOT FIND ELEVATION VARIRIABLE'S ATTRIBUTE 'units'")
1118 if(trim(att%CHR(1)) .NE.
'meters')
CALL fatal_error &
1119 & (
"IN OPEN BOUNDARY CONDITION TIME SERIES ELEVATION FILE OBJECT",&
1120 &
"FILE NAME: "//trim(obc_elevation_file),&
1121 &
"ELEVATION VARIRIABLE ATTRIBUTE 'units' SHOULD BE 'meters'")
1125 ALLOCATE(storage_vec(
iobcn), stat = status)
1126 IF(status /= 0)
CALL fatal_error(
"ALLOCATION ERROR IN TIDAL_ELEVATION")
1129 NULLIFY(storage_vec)
1132 ALLOCATE(storage_vec(
iobcn), stat = status)
1133 IF(status /= 0)
CALL fatal_error(
"ALLOCATION ERROR IN TIDAL_ELEVATION")
1136 NULLIFY(storage_vec)
1142 WRITE(ipt,* )
'! TIME SERIES TIDE : SET' 1155 tide_elv_p%curr_stkcnt = 0; tide_elv_n%curr_stkcnt = 0
1165 & (
"IN OPEN BOUNDARY CONDITION ELEVATION FILE OBJECT",&
1166 &
"FILE NAME: "//trim(obc_elevation_file),&
1167 &
"THE GLOBAL ATTRIBURE 'type' RETURNED UNKNOWN TYPE:",&
1173 101
FORMAT(1x,a26,f10.4)
1174 END SUBROUTINE tidal_elevation
1184 SUBROUTINE river_discharge
1186 INTEGER :: i, j,k, fcnt,rcnt,status, nfiles,nrs,ios,ns
1187 TYPE(a_river_file) dummy
1189 TYPE(
ncfile),
POINTER :: ncf
1190 TYPE(
ncdim),
POINTER :: dim
1191 TYPE(
ncvar),
POINTER :: var
1192 TYPE(
ncvar),
POINTER :: dum_p
1194 REAL(sp),
POINTER :: storage_vec(:)
1195 LOGICAL :: found, mine
1196 CHARACTER(LEN=7) :: chr
1197 character(len=20),
allocatable :: dist_strings(:)
1199 REAL(sp) :: mydist(kbm1)
1203 NULLIFY(storage_vec)
1206 numqbc_gl = river_number
1208 IF (river_number == 0 )
THEN 1210 IF(
dbg_set(
dbg_log))
write(ipt,*)
"! THERE ARE NO RIVERS IN THIS MODEL" 1219 WRITE(ipt,*)
"Total Number Of Rivers = ",river_number
1220 WRITE(ipt,*)
"RIVER_TS_SETTING = "//trim(river_ts_setting)
1221 WRITE(ipt,*)
"RIVER_INFLOW_LOCATION = "//trim(river_inflow_location)
1222 WRITE(ipt,*)
"RIVER_KIND = "//trim(river_kind)
1224 WRITE(ipt,*)
"=============================" 1225 DO i =1,river_number
1226 write(ipt,*)
"River number:",i
1227 WRITE(ipt,*)
"River File ="//trim(rivers(i)%FILE)
1228 WRITE(ipt,*)
"River Name ="//trim(rivers(i)%NAME)
1229 WRITE(ipt,*)
"River Location =",rivers(i)%LOCATION
1231 WRITE(ipt,*)
"River Distribution =",rivers(i)%distribution(1:kbm1)
1233 WRITE(ipt,*)
"=============================" 1237 IF(trim(river_ts_setting) /=
'calculated' .AND. trim(river_ts_setting) /=
'specified')
THEN 1238 CALL fatal_error(
"RIVER_TS_SETTING NOT CORRECT IN NAMELIST",
"SHOULD BE 'calculated' or 'specified'")
1242 WRITE(chr,
'(I7)')river_number
1246 &//
"s WHERE TEMPERATURE AND SALINITY ARE "//trim(river_ts_setting)//
" IN THE MODEL." 1249 DO i =1,river_number
1259 DO i =1,river_number
1265 SELECT CASE(trim(river_inflow_location))
1268 IF(rivers(i)%LOCATION > mgl .or. rivers(i)%LOCATION < 1)
THEN 1269 write(chr,
'(I7)') rivers(i)%LOCATION
1270 CALL fatal_error (
"RIVER_DISCHARGE: FOR THE RIVER NAMED: "&
1271 &//trim(rivers(i)%NAME),
"THE RIVER GRID LOCATION IN& 1272 & THE NAME LIST IS NOT IN THE GLOBAL DOMAIN",&
1273 &
"YOU SPECIFIED NODE NUMBER: "//chr)
1277 IF (
nlid(rivers(i)%LOCATION) .GT. 0) numqbc = numqbc + 1
1281 IF(rivers(i)%LOCATION > ngl .or. rivers(i)%LOCATION < 1)
THEN 1282 write(chr,
'(I7)') rivers(i)%LOCATION
1283 CALL fatal_error (
"RIVER_DISCHARGE: FOR THE RIVER NAMED: "&
1284 &//trim(rivers(i)%NAME),
"THE RIVER GRID LOCATION IN& 1285 & THE NAME LIST IS NOT IN THE GLOBAL DOMAIN",&
1286 &
"YOU SPECIFIED CELL NUMBER: "//chr)
1290 IF (
elid(rivers(i)%LOCATION) .GT. 0) numqbc = numqbc + 1
1296 CALL fatal_error(
"RIVER_INFLOW_LOCATION: NOT CORRECT IN NAMELIST",&
1297 &
"SHOULD BE 'node' or 'edge'")
1304 & (
"RIVER_DISCHARGE: COULD NOT FIND RIVER FILE OBJECT NAMED: & 1305 &"//trim(rivers(i)%FILE))
1308 &(
"RIVER FILE DID NOT LOAD PROPERLY",&
1309 &
"File name:"//trim(ncf%FNAME),&
1310 &
"Please check the time format!")
1313 IF (ncf%FTIME%PREV_STKCNT /= 999)
THEN 1315 ncf%FTIME%PREV_STKCNT = 999
1322 ALLOCATE(river_forcing(nfiles))
1324 NULLIFY(river_forcing(i)%NCF)
1325 NULLIFY(river_forcing(i)%FLUX_N)
1326 NULLIFY(river_forcing(i)%FLUX_P)
1327 NULLIFY(river_forcing(i)%TEMP_N)
1328 NULLIFY(river_forcing(i)%TEMP_P)
1329 NULLIFY(river_forcing(i)%SALT_N)
1330 NULLIFY(river_forcing(i)%SALT_P)
1340 ALLOCATE(
qdis(numqbc));
qdis = 0.0_sp
1342 ALLOCATE(
tdis(numqbc));
tdis = 0.0_sp
1343 ALLOCATE(
sdis(numqbc));
sdis = 0.0_sp
1351 DO i =1,river_number
1360 SELECT CASE(trim(river_inflow_location))
1363 IF (
nlid(rivers(i)%LOCATION) .GT. 0)
THEN 1375 IF (
elid(rivers(i)%LOCATION) .GT. 0)
THEN 1391 IF(any(rivers(i)%DISTRIBUTION(1:kbm1)<0.0_sp))
CALL fatal_error&
1392 &(
"You are not permitted to set the river distrobution value less than zero!",&
1393 &
"This usually indicates a mistake in the name list - not enough layers specifed" )
1394 vqdist(rcnt,1:kbm1)=rivers(i)%DISTRIBUTION(1:kbm1)
1404 IF (ncf%FTIME%PREV_STKCNT == 999)
THEN 1406 river_forcing(fcnt)%NCF => ncf
1407 ncf%FTIME%PREV_STKCNT = 0
1409 dim =>
find_dim(ncf,
'rivers',found)
1411 & (
"COULD NOT FIND DIMENSION 'rivers'",&
1412 &
"In the file: "//trim(ncf%FNAME) )
1414 river_forcing(fcnt)%RIVERS_IN_FILE=dim%DIM
1416 ALLOCATE(river_forcing(fcnt)%RIV_FILE2LOC(dim%DIM))
1417 river_forcing(fcnt)%RIV_FILE2LOC = 0
1424 IF (
associated(ncf,river_forcing(j)%NCF))
THEN 1425 k=search_name(ncf,rivers(i)%NAME)
1428 IF (mine) river_forcing(j)%RIV_FILE2LOC(k)=rcnt
1437 (
"RIVER_DISCHARGE: WE LOST A RIVER FILE IN THE MIDDLE OF NOWHERE!")
1440 (
"RIVER_DISCHARGE: WE LOST A RIVER IN THE MIDDLE OF NOWHERE!")
1445 ncf => river_forcing(i)%NCF
1447 SELECT CASE (river_kind)
1449 CALL check_river_file(ncf, river_forcing(i)%river_period)
1451 CALL check_river_file(ncf)
1453 CALL fatal_error(
"Invalid RIVER_KIND in namelist runfile:",&
1454 &
" Options are: "//trim(prdc)//
" or "//trim(vrbl))
1457 dim =>
find_dim(ncf,
'rivers',found)
1462 var =>
find_var(ncf,
'river_flux',found)
1464 ALLOCATE(storage_vec(nrs), stat = status)
1465 IF(status /= 0)
CALL fatal_error(
"ALLOCATION ERROR IN RIVER_DISCHARGE")
1468 NULLIFY(storage_vec)
1470 ALLOCATE(storage_vec(nrs), stat = status)
1471 IF(status /= 0)
CALL fatal_error(
"ALLOCATION ERROR IN RIVER_DISCHARGE")
1474 NULLIFY(storage_vec)
1477 var =>
find_var(ncf,
'river_temp',found)
1479 ALLOCATE(storage_vec(nrs), stat = status)
1480 IF(status /= 0)
CALL fatal_error(
"ALLOCATION ERROR IN RIVER_DISCHARGE")
1483 NULLIFY(storage_vec)
1485 ALLOCATE(storage_vec(nrs), stat = status)
1486 IF(status /= 0)
CALL fatal_error(
"ALLOCATION ERROR IN RIVER_DISCHARGE")
1489 NULLIFY(storage_vec)
1492 var =>
find_var(ncf,
'river_salt',found)
1494 ALLOCATE(storage_vec(nrs), stat = status)
1495 IF(status /= 0)
CALL fatal_error(
"ALLOCATION ERROR IN RIVER_DISCHARGE")
1498 NULLIFY(storage_vec)
1500 ALLOCATE(storage_vec(nrs), stat = status)
1501 IF(status /= 0)
CALL fatal_error(
"ALLOCATION ERROR IN RIVER_DISCHARGE")
1504 NULLIFY(storage_vec)
1509 river_forcing(i)%FLUX_N%curr_stkcnt = 0; river_forcing(i)%FLUX_P%curr_stkcnt = 0
1510 river_forcing(i)%TEMP_N%curr_stkcnt = 0; river_forcing(i)%TEMP_P%curr_stkcnt = 0
1511 river_forcing(i)%SALT_N%curr_stkcnt = 0; river_forcing(i)%SALT_P%curr_stkcnt = 0
1522 CALL set_river_bndry_metrics
1527 WRITE(ipt,*)
"! RIVER FORCING ON" 1528 WRITE(ipt,*)
'! GLOBAL NUMBER OF RIVERS :',river_number
1529 WRITE(ipt,*)
'! NUMBER OF RIVER FILES :', nfiles
1533 WRITE(ipt,*)
"/////////=============================///////////" 1534 WRITE(ipt,*)
" PRINTING RIVER FORCING DETAILS" 1536 WRITE(ipt,*)
" LOCAL NUMBER OF RIVERS : ", numqbc
1538 WRITE(ipt,*)
"=============================" 1540 WRITE(ipt,*)
" FILE NAME: "//trim(river_forcing(i)%NCF%FNAME)
1542 WRITE(ipt,*)
" NUMBER IN FILE=",river_forcing(i)%RIVERS_IN_FILE
1543 WRITE(ipt,*)
" RIV_FILE2LOC = ",river_forcing(i)%RIV_FILE2LOC
1544 WRITE(ipt,*)
"=============================" 1547 WRITE(ipt,*)
"/////////=============================///////////" 1554 END SUBROUTINE river_discharge
1557 FUNCTION search_name(NCF,NAME)
RESULT(RES)
1562 TYPE(
ncfile),
POINTER :: ncf
1563 CHARACTER(LEN=*) :: name
1565 INTEGER :: i, rvrs_in_file,strlen,status
1566 TYPE(
ncdim),
POINTER :: dim
1567 TYPE(
ncvar),
POINTER :: var
1571 WRITE(ipt,*)
"SEARCH_NAME (RIVERS)" 1572 WRITE(ipt,*)
"=============================" 1573 write(ipt,*)
"LOOKING FOR: '"//trim(name)//
"'" 1574 WRITE(ipt,*)
"==========" 1580 dim =>
find_dim(ncf,
'rivers',found)
1581 rvrs_in_file = dim%DIM
1583 var =>
find_var(ncf,
'river_names',found)
1586 IF(.NOT.
ASSOCIATED(var%VEC_CHR))
THEN 1588 ALLOCATE(var%VEC_CHR(dim%DIM),stat=status)
1589 IF(status/=0)
CALL fatal_error(
"SEARCH_NAME: CAN NOT ALLOCATE TEMP!")
1595 DO i = 1,rvrs_in_file
1596 IF(var%VEC_CHR(i) .EQ. name)
THEN 1607 WRITE(ipt,*)
"=============================" 1608 write(ipt,*)
"LOOKING FOR: '"//trim(name)//
"'; In File:" 1609 WRITE(ipt,*)
"=============================" 1611 DO i = 1,rvrs_in_file
1612 WRITE(ipt,*)
"RIVER NAMES: "//trim(var%VEC_CHR(i))
1614 WRITE(ipt,*)
"=============================" 1615 WRITE(ipt,*)
"=============================" 1616 WRITE(ipt,*)
"=============================" 1620 CALL fatal_error(
"COULD NOT FIND CORRECT NAME IN RIVER FILE?")
1622 END FUNCTION search_name
1625 SUBROUTINE check_river_file(NCF,PERIOD)
1628 TYPE(
ncfile),
POINTER ::ncf
1631 TYPE(
ncatt),
POINTER :: att
1632 TYPE(
ncdim),
POINTER :: dim
1633 TYPE(
ncvar),
POINTER :: var
1635 TYPE(
time) :: fstart, fend
1636 INTEGER :: ntimes,ns
1640 & (
"THE RIVER FILE OBJECT PASSED TO 'check_river_file' IS NOT ASSOCIATED")
1645 & (
"THE RIVER FILE:"//trim(ncf%FNAME),
"IS MISSING THE 'time' DIMENSION")
1649 dim =>
find_dim(ncf,
'namelen',found)
1651 & (
"THE RIVER FILE:"//trim(ncf%FNAME),
"IS MISSING THE 'namelen' DIMENSION")
1653 dim =>
find_dim(ncf,
'rivers',found)
1655 & (
"THE RIVER FILE:"//trim(ncf%FNAME),
"IS MISSING THE 'rivers' DIMENSION")
1658 IF(.NOT.
ASSOCIATED(ncf%FTIME))
CALL fatal_error &
1659 & (
'THE RIVER FILE '//trim(ncf%FNAME),&
1660 'DOES NOT HAVE A RECONGIZED TIME VARIABLE')
1666 IF(zerotime /= fstart)
THEN 1667 CALL print_time(fstart,ipt,
"River Data Start")
1669 & (
"Date of the first river data point must be 0.0 for periodic forcoing mode:",&
1670 &
"The River File: "//trim(ncf%FNAME)//
'; has a bad start date.')
1674 IF(
period .LE. zerotime)
THEN 1678 & (
"Date of the last river data point must be greater than or equal to zero for periodic forcing mode:",&
1679 &
"The River File: "//trim(ncf%FNAME)//
'; has a bad end date.')
1686 IF(fstart > starttime)
THEN 1690 & (
"Date of the first river data point must be less than or equal to the model start date:",&
1691 &
"The River File: "//trim(ncf%FNAME)//
'; has a bad start date.')
1695 IF(fend < endtime)
THEN 1700 & (
"Date of the last river data point must be greater than or equal to the model end date:",&
1701 &
"The River File: "//trim(ncf%FNAME)//
'; has a bad end date.')
1705 var =>
find_var(ncf,
'river_names',found)
1707 & (
"THE RIVER FILE:"//trim(ncf%FNAME),
"IS MISSING THE 'river_names' VARIABLE")
1710 var =>
find_var(ncf,
'river_flux',found)
1712 & (
"THE RIVER FILE:"//trim(ncf%FNAME),
"IS MISSING THE 'river_flux' VARIABLE")
1716 & (
"THE RIVER FILE:"//trim(ncf%FNAME),
"THE VARIABLE: "&
1717 &//trim(var%VARNAME),
"IS MISSING THE ATTRIBUTE 'units'")
1719 IF(trim(att%CHR(1)) /=
"m^3s^-1")
CALL fatal_error &
1720 & (
"THE RIVER FILE:"//trim(ncf%FNAME),
"THE VARIABLE: "&
1721 &//trim(var%VARNAME),
"THE ATTRIBUTE 'units' IS INCORRECT: EXPE& 1724 var =>
find_var(ncf,
'river_temp',found)
1726 & (
"THE RIVER FILE:"//trim(ncf%FNAME),
"IS MISSING THE 'river_temp' VARIABLE")
1730 & (
"THE RIVER FILE:"//trim(ncf%FNAME),
"THE VARIABLE: "&
1731 &//trim(var%VARNAME),
"IS MISSING THE ATTRIBUTE 'units'")
1733 IF(trim(att%CHR(1)) /=
"Celsius")
CALL fatal_error &
1734 & (
"THE RIVER FILE:"//trim(ncf%FNAME),
"THE VARIABLE: "&
1735 &//trim(var%VARNAME),
"THE ATTRIBUTE 'units' IS INCORRECT: EXPE& 1738 var =>
find_var(ncf,
'river_salt',found)
1740 & (
"THE RIVER FILE:"//trim(ncf%FNAME),
"IS MISSING THE 'river_salt' VARIABLE")
1744 & (
"THE RIVER FILE:"//trim(ncf%FNAME),
"THE VARIABLE: "&
1745 &//trim(var%VARNAME),
"IS MISSING THE ATTRIBUTE 'units'")
1748 & (
"THE RIVER FILE:"//trim(ncf%FNAME),
"THE VARIABLE: "&
1749 &//trim(var%VARNAME),
"THE ATTRIBUTE 'units' IS INCORRECT: EXPE& 1752 END SUBROUTINE check_river_file
1756 SUBROUTINE set_river_bndry_metrics
1758 REAL(dp) dx12,dy12,dx32,dy32,atmp1,atmp2,dxytmp,htmp,areatmp
1759 REAL(dp) xnorm,ynorm,xp,yp,xn,yn,xi,yi,fac,xnext,ynext,modnr
1760 INTEGER i,j,i1,i2,i3,j1,j2,ii,itmp,jtmp,inode,jnode,knode,nnorm
1761 CHARACTER(len=7) :: strng
1765 IF(
dbg_set(
dbg_sbr))
write(ipt,*)
"START SET_RIVER_BNDRY_METRICS" 1767 SELECT CASE(trim(river_inflow_location))
1777 if (
isonb(j) /= 1)
THEN 1778 write(strng,
'(I6)')
ngid(j)
1780 & (
"You seem to be trying to put a river in the middle of the domain",&
1781 &
"The global node number you selected is: "//trim(adjustl(strng)),&
1782 &
"but this is not a solid boundary node?")
1792 atmp1=atan2(dy12,dx12)
1793 atmp2=atan2(dy32,dx32)
1796 IF(atmp1 < atmp2) atmp1=atmp1+2.0_sp*3.1415927_sp
1797 dxytmp=sqrt(dx12**2+dy12**2)+sqrt(dx32**2+dy32**2)
1799 angleq(i)=(atmp1-atmp2)/2.+atmp2
1808 IF(
isbce(ii) /= 1)
THEN 1810 write(strng,
'(I6)')
egid(ii)
1812 & (
"You seem to be trying to put a river in the middle of the domain",&
1813 &
"The global cell number you selected is: "//trim(adjustl(strng)),&
1814 &
"but this is not a solid boundary node?")
1818 IF(
nbe(ii,j) == 0)
THEN 1825 write(strng,
'(I6)')
egid(ii)
1827 & (
"You have selected an invalide cell for edge based river inflow.",&
1828 &
"The global cell number you selected is: "//trim(adjustl(strng)),&
1829 &
"This cell has the wrong number of solid boundaries!")
1831 j1=jtmp+1-int((jtmp+1)/4)*3
1832 j2=jtmp+2-int((jtmp+2)/4)*3
1837 htmp=0.5_sp*(
h(i1)+
h(i2))
1840 atmp1=atan2(dy12,dx12)
1841 qarea(i)=sqrt(dx12**2+dy12**2)*htmp
1842 angleq(i)=atmp1+3.1415927/2.0
1851 CALL fatal_error(
"RIVER_INFLOW_LOCATION: NOT CORRECT IN NAMELIST",&
1852 &
"SHOULD BE 'node' or 'edge' - It passed River_Discharge: how?")
1859 END SUBROUTINE set_river_bndry_metrics
1862 SUBROUTINE set_distribution(NAME,TYPE,LOC,MYDIST)
1864 CHARACTER(LEN=*),
INTENT(IN) :: name,type
1865 INTEGER,
INTENT(IN) :: loc
1866 REAL(sp),
INTENT(OUT) :: mydist(kbm1)
1868 REAL(sp) :: myz(kbm1)
1869 REAL(sp) :: myh,myel
1873 CHARACTER(LEN=12) :: idx
1876 INTEGER :: nline, nchar, intval(150), nval
1877 REAL(dp) :: realval(150)
1878 CHARACTER(LEN=40) :: varname
1879 CHARACTER(LEN=80) :: stringval(150)
1880 CHARACTER(LEN=7) :: vartype
1886 IF (trim(type)==
'node')
THEN 1887 mydist =
dz(
nlid(loc),1:kbm1)
1888 myz =
zz(
nlid(loc),1:kbm1)
1892 ELSEIF (trim(type)==
'edge')
THEN 1893 mydist =
dz1(
elid(loc),1:kbm1)
1898 CALL fatal_error(
"BAD RIVER LOCATION (edge OR node) ?")
1901 SELECT CASE(name(1:6))
1906 WRITE(ipt,*)
"UNIFORM RIVER DISTRIBUTION",mydist
1911 nchar = len_trim(name)
1912 CALL get_value(nline,nchar,name,varname,vartype,logval&
1913 &,stringval,realval,intval,nval)
1915 IF(vartype /=
"float")
THEN 1918 &(
"HEAVISIDE RIVER DISTRIBUTION MUST SET A FLOATING POINT VALUE",&
1919 &
"River on "//trim(type)//
" number:"//trim(idx))
1923 &(
"COULD NOT READ RIVER DISTRIBUTION STRING?",&
1924 &
"BAD STRING:"//trim(name))
1926 IF(index(varname,
'depth')/=0)
THEN 1929 myz = (myh+myel)*myz+myel
1931 IF(myz(kbm1) > realval(1) .OR. realval(1) > myz(1))
THEN 1933 WRITE(ipt,*)
"================================" 1934 WRITE(ipt,*)
"HEAVISIDE CASE- depth",realval(1)
1935 WRITE(ipt,*)
"RIVER DEPTH = ",myh
1936 WRITE(ipt,*)
"RIVER SURFACE = ",myel
1938 CALL fatal_error(
"RIVER DISTRIBUTION: Depth value out of bounds!",&
1939 &
"River on "//trim(type)//
" number:"//trim(idx))
1942 WRITE(ipt,*)
"DEPTH:",myz
1944 WHERE (myz<realval(1))
1949 mydist = mydist/total
1951 ELSEIF(index(varname,
'sigma')/=0)
THEN 1954 IF(-1.0_sp > realval(1) .OR. realval(1) >0.0_sp)
THEN 1955 WRITE(ipt,*)
"================================" 1956 WRITE(ipt,*)
"HEAVISIDE CASE- sigma",realval(1)
1959 &(
"RIVER DISTRIBUTION: Sigma value out of bounds!",&
1960 &
"River on "//trim(type)//
" number:"//trim(idx))
1963 WHERE (myz<realval(1))
1968 mydist = mydist/total
1972 CALL fatal_error(
"RIVER DISTRIBUTION: UNKNOWN HEAVISIDE SETTING?",&
1973 &
"BAD STRING:"//trim(name))
1976 WRITE(ipt,*)
"HEAVISIDE RIVER DISTRIBUTION",mydist
1982 nchar = len_trim(name)
1983 CALL get_value(nline,nchar,name,varname,vartype,logval&
1984 &,stringval,realval,intval,nval)
1986 IF(vartype /=
"float")
THEN 1989 &(
"LINEAR RIVER DISTRIBUTION MUST SET A FLOATING POINT VALUE",&
1990 &
"River on "//trim(type)//
" number:"//trim(idx))
1994 &(
"COULD NOT READ RIVER DISTRIBUTION STRING?",&
1995 &
"BAD STRING:"//trim(name))
1997 IF(index(varname,
'slope')/=0)
THEN 1999 IF(realval(1) <0.0_sp)
THEN 2000 WRITE(ipt,*)
"================================" 2001 WRITE(ipt,*)
"LINEAR CASE- slope",realval(1)
2004 &(
"RIVER DISTRIBUTION: linear slope less than zero!",&
2005 &
"River on "//trim(type)//
" number:"//trim(idx))
2008 myz = (myh+myel)*myz+myel
2010 myz = myz *mydist * realval(1)
2012 DO WHILE(sum(myz,myz>0.0_sp)<1.0_sp)
2013 myz=myz + mydist*0.01
2016 WHERE (myz > 0.0_sp)
2023 mydist = mydist/total
2027 CALL fatal_error(
"RIVER DISTRIBUTION: UNKOWN LINEAR SETTING?",&
2028 &
"BAD STRING:"//trim(name))
2033 WRITE(ipt,*)
"LINEAR RIVER DISTRIBUTION",mydist
2037 CALL fatal_error(
"UNKNOWN RIVER DISTRIBUTION FUNCTION:"//trim(name),&
2038 &
"SEE FVCOM MANUAL OR mod_force.F FOR OPTIONS!")
2043 END SUBROUTINE set_distribution
2047 SUBROUTINE obc_temperature
2050 TYPE(
ncatt),
POINTER :: att, att_date
2051 TYPE(
ncdim),
POINTER :: dim
2052 TYPE(
ncvar),
POINTER :: var
2056 INTEGER,
ALLOCATABLE :: myobclist(:)
2059 REAL(sp),
POINTER :: storage_arr(:,:), storage_vec(:)
2060 INTEGER :: ntimes, i
2061 TYPE(
time) :: timetest
2068 IF (.NOT. obc_temp_nudging)
THEN 2069 IF(
dbg_set(
dbg_log))
write(ipt,*)
"! OPEN BOUNDARY TEMPERATURE NUDGING IS OFF!" 2074 IF(
dbg_set(
dbg_log))
write(ipt,*)
"! OPEN BOUNDARY TEMPERATURE NUDGING IS ON!" 2081 & (
"COULD NOT FIND OPEN BOUNDARY CONDITION TEMPERATURE FILE OBJECT",&
2082 &
"FILE NAME: "//trim(obc_temp_file))
2084 att =>
find_att(obc_t_file,
"type",found)
2086 & (
"IN OPEN BOUNDARY CONDITION TEMPERATURE FILE OBJECT",&
2087 &
"FILE NAME: "//trim(obc_temp_file),&
2088 &
"COULD NOT FIND GLOBAL ATTRIBURE: 'type'")
2091 SELECT CASE(trim(att%CHR(1)))
2094 CASE(
"FVCOM TIME SERIES OBC TS FILE")
2097 obc_t_type = obc_t_sigma
2099 att =>
find_att(obc_t_file,
"title",found)
2104 CALL warning(
"ATTRIBUTE 'title' IS MISSING IN THE TEMPERATURE NUDGING FILE!")
2109 dim =>
find_dim(obc_t_file,
'time',found)
2111 & (
"IN OPEN BOUNDARY CONDITION TEMPERATURE NUDGING FILE OBJECT",&
2112 &
"FILE NAME: "//trim(obc_temp_file),&
2113 &
"COULD NOT FIND DIMENSION 'time'")
2117 dim =>
find_dim(obc_t_file,
'siglay',found)
2119 & (
"IN OPEN BOUNDARY CONDITION TEMPERATURE NUDGING FILE OBJECT",&
2120 &
"FILE NAME: "//trim(obc_temp_file),&
2121 &
"COULD NOT FIND DIMENSION 'siglay'")
2126 & (
"IN OPEN BOUNDARY CONDITION TEMPERATURE NUDGING FILE OBJECT",&
2127 &
"FILE NAME: "//trim(obc_temp_file),&
2128 &
"THE 'siglay' DIMENSION DOES NOT MATCH THE MODEL RUN!")
2130 dim =>
find_dim(obc_t_file,
'nobc',found)
2132 & (
"IN OPEN BOUNDARY CONDITION TEMPERATURE NUDGING FILE OBJECT",&
2133 &
"FILE NAME: "//trim(obc_temp_file),&
2134 &
"COULD NOT FIND DIMENSION 'nobc'")
2138 & (
"IN OPEN BOUNDARY CONDITION TEMPERATURE NUDGING FILE OBJECT",&
2139 &
"FILE NAME: "//trim(obc_temp_file),&
2140 &
"THE DIMENSION 'nobc' MUST MATCH THE NUMBER OF OBC NODES")
2145 ALLOCATE(myobclist(
iobcn))
2146 var =>
find_var(obc_t_file,
'obc_nodes',found)
2148 & (
"IN OPEN BOUNDARY CONDITION TEMPERATURE NUDGING FILE OBJECT",&
2149 &
"FILE NAME: "//trim(obc_temp_file),&
2150 &
"COULD NOT FIND VARIABLE 'obc_nodes'")
2157 IF(
i_obc_n(i) /= myobclist(i))
THEN 2158 write(ipt,*)
"NLID(MYOBCLIST)= ", myobclist(i),
"; I=",i
2159 write(ipt,*)
"I_OBC_N= ",
i_obc_n(i),
"; I=",i
2161 & (
"IN OPEN BOUNDARY CONDITION TEMPERATURE NUDGING FILE OBJECT",&
2162 &
"FILE NAME: "//trim(obc_temp_file),&
2163 &
"THE LIST OF BOUNDARY NODES DOES NOT MATCH")
2174 & (
"IN OPEN BOUNDARY CONDITION TEMPERATURE NUDGING FILE OBJECT",&
2175 &
"FILE NAME: "//trim(obc_temp_file),&
2176 &
"THE MODEL RUN STARTS BEFORE THE TEMPERATURE TIME SERIES")
2181 & (
"IN OPEN BOUNDARY CONDITION TEMPERATURE NUDGING FILE OBJECT",&
2182 &
"FILE NAME: "//trim(obc_temp_file),&
2183 &
"THE MODEL RUN ENDS AFTER THE TEMPERATURE TIME SERIES")
2185 var =>
find_var(obc_t_file,
'obc_temp',found)
2187 & (
"IN OPEN BOUNDARY CONDITION TEMPERATURE NUDGING FILE OBJECT",&
2188 &
"FILE NAME: "//trim(obc_temp_file),&
2189 &
"COULD NOT FIND VARIABLE 'obc_temp'")
2193 & (
"IN OPEN BOUNDARY CONDITION TEMPERATURE NUDGING FILE OBJECT",&
2194 &
"FILE NAME: "//trim(obc_temp_file),&
2195 &
"COULD NOT FIND TEMP VARIRIABLE'S ATTRIBUTE 'units'")
2197 if(trim(att%CHR(1)) .NE.
'Celsius' .and. trim(att%CHR(1)) .NE.
'Celcius')
CALL fatal_error &
2198 & (
"IN OPEN BOUNDARY CONDITION TEMPERATURE NUDGING FILE OBJECT",&
2199 &
"FILE NAME: "//trim(obc_temp_file),&
2200 &
"TEMP VARIRIABLE ATTRIBUTE 'units' SHOULD BE 'Celsius'")
2205 ALLOCATE(storage_arr(
iobcn,kbm1), stat = status)
2206 IF(status /= 0)
CALL fatal_error(
"ALLOCATION ERROR IN OBC_TEMPERATURE")
2209 NULLIFY(storage_arr)
2212 ALLOCATE(storage_arr(
iobcn,kbm1), stat = status)
2213 IF(status /= 0)
CALL fatal_error(
"ALLOCATION ERROR IN OBC_TEMPERATURE")
2216 NULLIFY(storage_arr)
2224 & (
"IN OPEN BOUNDARY CONDITION TEMPERATURE FILE OBJECT",&
2225 &
"FILE NAME: "//trim(obc_temp_file),&
2226 &
"THE GLOBAL ATTRIBURE 'type' RETURNED UNKNOWN TYPE:",&
2239 obc_t_n%curr_stkcnt = 0; obc_t_p%curr_stkcnt = 0
2242 END SUBROUTINE obc_temperature
2245 SUBROUTINE obc_salinity
2248 TYPE(
ncatt),
POINTER :: att, att_date
2249 TYPE(
ncdim),
POINTER :: dim
2250 TYPE(
ncvar),
POINTER :: var
2254 INTEGER,
ALLOCATABLE :: myobclist(:)
2257 REAL(sp),
POINTER :: storage_arr(:,:), storage_vec(:)
2258 INTEGER :: ntimes, i
2259 TYPE(
time) :: timetest
2266 IF (.NOT. obc_salt_nudging)
THEN 2267 IF(
dbg_set(
dbg_log))
write(ipt,*)
"! OPEN BOUNDARY SALINITY NUDGING IS OFF!" 2272 IF(
dbg_set(
dbg_log))
write(ipt,*)
"! OPEN BOUNDARY SALINITY NUDGING IS ON!" 2278 & (
"COULD NOT FIND OPEN BOUNDARY CONDITION SALINITY FILE OBJECT",&
2279 &
"FILE NAME: "//trim(obc_salt_file))
2281 att =>
find_att(obc_s_file,
"type",found)
2283 & (
"IN OPEN BOUNDARY CONDITION SALINITY FILE OBJECT",&
2284 &
"FILE NAME: "//trim(obc_salt_file),&
2285 &
"COULD NOT FIND GLOBAL ATTRIBURE: 'type'")
2288 SELECT CASE(trim(att%CHR(1)))
2291 CASE(
"FVCOM TIME SERIES OBC TS FILE")
2294 obc_s_type = obc_s_sigma
2296 att =>
find_att(obc_s_file,
"title",found)
2301 CALL warning(
"ATTRIBUTE 'title' IS MISSING IN THE SALINITY NUDGING FILE!")
2306 dim =>
find_dim(obc_s_file,
'time',found)
2308 & (
"IN OPEN BOUNDARY CONDITION SALINITY NUDGING FILE OBJECT",&
2309 &
"FILE NAME: "//trim(obc_salt_file),&
2310 &
"COULD NOT FIND DIMENSION 'time'")
2314 dim =>
find_dim(obc_s_file,
'siglay',found)
2316 & (
"IN OPEN BOUNDARY CONDITION SALINITY NUDGING FILE OBJECT",&
2317 &
"FILE NAME: "//trim(obc_salt_file),&
2318 &
"COULD NOT FIND DIMENSION 'siglay'")
2323 & (
"IN OPEN BOUNDARY CONDITION SALINITY NUDGING FILE OBJECT",&
2324 &
"FILE NAME: "//trim(obc_salt_file),&
2325 &
"THE 'siglay' DIMENSION DOES NOT MATCH THE MODEL RUN!")
2327 dim =>
find_dim(obc_s_file,
'nobc',found)
2329 & (
"IN OPEN BOUNDARY CONDITION SALINITY NUDGING FILE OBJECT",&
2330 &
"FILE NAME: "//trim(obc_salt_file),&
2331 &
"COULD NOT FIND DIMENSION 'nobc'")
2335 & (
"IN OPEN BOUNDARY CONDITION SALINITY NUDGING FILE OBJECT",&
2336 &
"FILE NAME: "//trim(obc_salt_file),&
2337 &
"THE DIMENSION 'nobc' MUST MATCH THE NUMBER OF OBC NODES")
2342 ALLOCATE(myobclist(
iobcn))
2343 var =>
find_var(obc_s_file,
'obc_nodes',found)
2345 & (
"IN OPEN BOUNDARY CONDITION SALINITY NUDGING FILE OBJECT",&
2346 &
"FILE NAME: "//trim(obc_salt_file),&
2347 &
"COULD NOT FIND VARIABLE 'obc_nodes'")
2354 IF(
i_obc_n(i) /= myobclist(i))
THEN 2355 write(ipt,*)
"NLID(MYOBCLIST)= ", myobclist(i),
"; I=",i
2356 write(ipt,*)
"I_OBC_N= ",
i_obc_n(i),
"; I=",i
2358 & (
"IN OPEN BOUNDARY CONDITION SALINITY NUDGING FILE OBJECT",&
2359 &
"FILE NAME: "//trim(obc_salt_file),&
2360 &
"THE LIST OF BOUNDARY NODES DOES NOT MATCH")
2371 & (
"IN OPEN BOUNDARY CONDITION SALINITY NUDGING FILE OBJECT",&
2372 &
"FILE NAME: "//trim(obc_salt_file),&
2373 &
"THE MODEL RUN STARTS BEFORE THE SALINITY TIME SERIES")
2379 & (
"IN OPEN BOUNDARY CONDITION SALINITY NUDGING FILE OBJECT",&
2380 &
"FILE NAME: "//trim(obc_salt_file),&
2381 &
"THE MODEL RUN ENDS AFTER THE SALINITY TIME SERIES")
2383 var =>
find_var(obc_s_file,
'obc_salinity',found)
2385 & (
"IN OPEN BOUNDARY CONDITION SALINITY NUDGING FILE OBJECT",&
2386 &
"FILE NAME: "//trim(obc_salt_file),&
2387 &
"COULD NOT FIND VARIABLE 'obc_salinity'")
2391 & (
"IN OPEN BOUNDARY CONDITION SALINITY NUDGING FILE OBJECT",&
2392 &
"FILE NAME: "//trim(obc_salt_file),&
2393 &
"COULD NOT FIND TEMP VARIRIABLE'S ATTRIBUTE 'units'")
2395 if(trim(att%CHR(1)) .NE.
'PSU')
CALL fatal_error &
2396 & (
"IN OPEN BOUNDARY CONDITION SALINITY NUDGING FILE OBJECT",&
2397 &
"FILE NAME: "//trim(obc_salt_file),&
2398 &
"TEMP VARIRIABLE ATTRIBUTE 'units' SHOULD BE 'PSU'")
2403 ALLOCATE(storage_arr(
iobcn,kbm1), stat = status)
2404 IF(status /= 0)
CALL fatal_error(
"ALLOCATION ERROR IN OBC_SALINITY")
2407 NULLIFY(storage_arr)
2410 ALLOCATE(storage_arr(
iobcn,kbm1), stat = status)
2411 IF(status /= 0)
CALL fatal_error(
"ALLOCATION ERROR IN OBC_SALINITY")
2414 NULLIFY(storage_arr)
2422 & (
"IN OPEN BOUNDARY CONDITION SALINITY FILE OBJECT",&
2423 &
"FILE NAME: "//trim(obc_salt_file),&
2424 &
"THE GLOBAL ATTRIBURE 'type' RETURNED UNKNOWN TYPE:",&
2433 obc_s_n%curr_stkcnt = 0; obc_s_p%curr_stkcnt = 0
2439 END SUBROUTINE obc_salinity
2580 SUBROUTINE set_file_interp_bilinear(NCF,INTP_N,INTP_C,MASK_VAR_NAME)
2582 TYPE(
ncfile),
POINTER :: ncf
2586 TYPE(
ncatt),
POINTER :: att
2587 TYPE(
ncdim),
POINTER :: dim
2588 TYPE(
ncvar),
POINTER :: var
2590 INTEGER :: lats, lons, i, ntimes,j, ierr
2591 REAL(sp),
POINTER :: xlon(:,:),xlat(:,:)
2592 REAL(sp),
POINTER :: heatx(:,:),heaty(:,:)
2593 REAL(sp),
POINTER :: tmp1(:),tmp2(:)
2596 CHARACTER(LEN=80),
OPTIONAL :: mask_var_name
2597 REAL(sp),
POINTER :: fmask(:,:)
2598 INTEGER,
POINTER :: mask(:,:)
2604 & (
"SET_FILE_INTERP: FILE OBJECT ARGUMENT IS NOT ASSOCIATED!")
2607 IF(
ASSOCIATED(ncf%INTERP_N))
THEN 2608 IF(
ASSOCIATED(ncf%INTERP_C))
THEN 2609 intp_n => ncf%INTERP_N
2610 intp_c => ncf%INTERP_C
2614 CALL fatal_error(
"ONLY ONE INTERP POINTER IS ASSOCAITED IN THIS FILE",&
2615 &
"SET_FILE_INTERP: IS NOT PREPARED TO HANDLE THIS.")
2618 IF(
ASSOCIATED(ncf%INTERP_C))
THEN 2620 CALL fatal_error(
"ONLY ONE INTERP POINTER IS ASSOCAITED IN THIS FILE",&
2621 &
"SET_FILE_INTERP: IS NOT PREPARED TO HANDLE THIS.")
2627 dim =>
find_dim(ncf,
'south_north',found)
2629 & (
"SET_FILE_INTERP:",&
2630 &
"FILE NAME: "//trim(ncf%FNAME),&
2631 &
"COULD NOT FIND DIMENSION 'south_north'")
2635 dim =>
find_dim(ncf,
'west_east',found)
2637 & (
"SET_FILE_INTERP:",&
2638 &
"FILE NAME: "//trim(ncf%FNAME),&
2639 &
"COULD NOT FIND DIMENSION 'west_east'")
2644 ALLOCATE(xlon(lons,lats))
2645 ALLOCATE(xlat(lons,lats))
2649 & (
"SET_FILE_INTERP:",&
2650 &
"FILE NAME: "//trim(ncf%FNAME),&
2651 &
"COULD NOT FIND VARIABLE 'XLAT'")
2659 & (
"SET_FILE_INTERP:",&
2660 &
"FILE NAME: "//trim(ncf%FNAME),&
2661 &
"COULD NOT FIND VARIABLE 'XLONG'")
2666 ALLOCATE(heatx(lons,lats))
2667 ALLOCATE(heaty(lons,lats))
2669 IF (.NOT. use_proj)
CALL fatal_error(
'PROJ IS NEEDED TO USE T& 2670 &HIS TYPE OF FORCING FILE IN CARTESIAN MODE:',&
2671 &
' RECOMPILE WITH projection 4')
2672 IF(msr)
CALL degrees2meters(xlon,xlat,projection_reference,heatx,heaty,lons,lats)
2674 DEALLOCATE(xlat,xlon)
2691 IF (
PRESENT(mask_var_name))
THEN 2692 var =>
find_var(ncf,mask_var_name,found)
2694 & (
"SET_FILE_INTERP:",&
2695 &
"FILE NAME: "//trim(ncf%FNAME),&
2696 &
"COULD NOT FIND VARIABLE 'XLONG'")
2699 select case(var%XTYPE)
2701 ALLOCATE(mask(lons,lats))
2706 ALLOCATE(mask(lons,lats))
2707 ALLOCATE(fmask(lons,lats))
2714 call fatal_error(
"SET_FILE_INTERP_BILINEAR: Unknown mask variable xtype?")
2774 DEALLOCATE(heatx, heaty)
2777 ncf%INTERP_N => intp_n
2778 ncf%INTERP_C => intp_c
2780 END SUBROUTINE set_file_interp_bilinear
2783 SUBROUTINE surface_heating
2786 TYPE(
ncatt),
POINTER :: att, att_date
2787 TYPE(
ncdim),
POINTER :: dim
2788 TYPE(
ncvar),
POINTER :: var
2791 REAL(sp),
POINTER :: storage_arr(:,:), storage_vec(:)
2792 CHARACTER(len=60) :: swrstrng, nhfstrng
2793 TYPE(
time) :: timetest
2795 INTEGER :: lats, lons, i, ntimes
2801 NULLIFY(att,dim,var,storage_arr,storage_vec)
2803 IF (.NOT. heating_on )
THEN 2804 IF(
dbg_set(
dbg_log))
write(ipt,*)
"! SURFACE HEAT FORCING IS OFF!" 2812 SELECT CASE(heating_kind)
2815 write(swrstrng,
'(f8.4)') heating_radiation
2816 write(nhfstrng,
'(f8.4)') heating_netflux
2819 WRITE(ipt,*)
"! SETTING UP CONSTANT HEAT FORCING: " 2820 WRITE(ipt,*)
" Radiation: "//trim(swrstrng)
2821 WRITE(ipt,*)
" Net Heat Flux: "//trim(nhfstrng)
2836 CALL fatal_error(
"TIME DEPENDANT HEATING Not Set Up Yet")
2842 & (
"COULD NOT FIND SURFACE HEATING BOUNDARY CONDINTION FILE OBJECT",&
2843 &
"FILE NAME: "//trim(heating_file))
2846 att =>
find_att(heat_file,
"source",found)
2847 IF(.not. found) att =>
find_att(heat_file,
"Source",found)
2849 & (
"IN SURFACE HEATING BOUNDARY CONDITION FILE OBJECT",&
2850 &
"FILE NAME: "//trim(heating_file),&
2851 &
"COULD NOT FIND GLOBAL ATTRIBURE: 'source'")
2855 heat_forcing_type = heat_is_wrfgrid
2859 heat_forcing_type = heat_is_fvcomgrid
2863 heat_forcing_type = heat_is_fvcomgrid
2867 heat_forcing_type = heat_is_wrfgrid
2871 CALL fatal_error(
"CAN NOT RECOGNIZE HEATING FILE!",&
2872 &
"UNKNOWN SOURCE STRING:",trim(att%CHR(1)))
2882 att_date =>
find_att(heat_file,
"START_DATE",found)
2894 & (
"IN SURFACE HEATING BOUNDARY CONDITION FILE OBJECT",&
2895 &
"FILE NAME: "//trim(heating_file),&
2896 &
"COULD NOT FIND THE UNLIMITED DIMENSION")
2911 &(
"TO USE PERIODIC FORCING THE FILE TIME MUST COUNT FROM ZERO",&
2912 &
"THE DIFFERENCE BETWEEN THE CURRENT MODEL TIME AND THE START TIME,",&
2913 &
"MODULO THE FORCING PERIOD, DETERMINES THE CURRENT FORCING")
2918 WRITE(ipt,*)
"! USING PERIODIC HEAT FORCING:" 2926 & (
"COULD NOT FIND SURFACE HEATING BOUNDARY CONDINTION FILE OBJECT",&
2927 &
"FILE NAME: "//trim(heating_file))
2930 att =>
find_att(heat_file,
"source",found)
2931 IF(.not. found) att =>
find_att(heat_file,
"Source",found)
2933 & (
"IN SURFACE HEATING BOUNDARY CONDITION FILE OBJECT",&
2934 &
"FILE NAME: "//trim(heating_file),&
2935 &
"COULD NOT FIND GLOBAL ATTRIBURE: 'source'")
2939 heat_forcing_type = heat_is_wrfgrid
2943 heat_forcing_type = heat_is_fvcomgrid
2947 heat_forcing_type = heat_is_fvcomgrid
2951 heat_forcing_type = heat_is_wrfgrid
2955 CALL fatal_error(
"CAN NOT RECOGNIZE HEATING FILE!",&
2956 &
"UNKNOWN SOURCE STRING:",trim(att%CHR(1)))
2966 att_date =>
find_att(heat_file,
"START_DATE",found)
2976 & (
"IN SURFACE HEATING BOUNDARY CONDITION FILE OBJECT",&
2977 &
"FILE NAME: "//trim(heating_file),&
2978 &
"COULD NOT FIND UNLIMITED DIMENSION")
2985 & (
"IN SURFACE HEATING BOUNDARY CONDITION FILE OBJECT",&
2986 &
"FILE NAME: "//trim(heating_file),&
2987 &
"THE MODEL RUN STARTS BEFORE THE FORCING TIME SERIES")
2991 & (
"IN SURFACE HEATING BOUNDARY CONDITION FILE OBJECT",&
2992 &
"FILE NAME: "//trim(heating_file),&
2993 &
"THE MODEL RUN ENDS AFTER THE FORCING TIME SERIES")
2996 CALL fatal_error(
"SURFACE_HEATING: UNKNOWN HEATING KIND?")
3002 SELECT CASE(heat_forcing_type)
3004 CASE(heat_is_wrfgrid)
3008 &
"! SETTING UP HEAT FORCING FROM A 'wrf grid' FILE" 3011 dim =>
find_dim(heat_file,
'south_north',found)
3013 & (
"IN SURFACE HEATING BOUNDARY CONDITION FILE OBJECT",&
3014 &
"FILE NAME: "//trim(heating_file),&
3015 &
"COULD NOT FIND DIMENSION 'south_north'")
3019 dim =>
find_dim(heat_file,
'west_east',found)
3021 & (
"IN SURFACE HEATING BOUNDARY CONDITION FILE OBJECT",&
3022 &
"FILE NAME: "//trim(heating_file),&
3023 &
"COULD NOT FIND DIMENSION 'west_east'")
3027 CALL set_file_interp_bilinear(heat_file,heat_intp_n,heat_intp_c)
3032 var =>
find_var(heat_file,
"short_wave",found)
3033 IF(.not. found) var =>
find_var(heat_file,
"Shortwave",found)
3035 & (
"IN SURFACE HEATING BOUNDARY CONDITION FILE OBJECT",&
3036 &
"FILE NAME: "//trim(heating_file),&
3037 &
"COULD NOT FIND VARIABLE 'short_wave'")
3040 ALLOCATE(storage_arr(lons,lats), stat = status)
3041 IF(status /= 0)
CALL fatal_error(
"ALLOCATION ERROR IN SURFACE HEATING")
3044 NULLIFY(storage_arr)
3047 ALLOCATE(storage_vec(0:mt), stat = status)
3048 IF(status /= 0)
CALL fatal_error(
"ALLOCATION ERROR IN SURFACE HEATING")
3050 NULLIFY(storage_vec)
3054 ALLOCATE(storage_arr(lons,lats), stat = status)
3055 IF(status /= 0)
CALL fatal_error(
"ALLOCATION ERROR IN SURFACE HEATING")
3058 NULLIFY(storage_arr)
3061 ALLOCATE(storage_vec(0:mt), stat = status)
3062 IF(status /= 0)
CALL fatal_error(
"ALLOCATION ERROR IN SURFACE HEATING")
3064 NULLIFY(storage_vec)
3067 var =>
find_var(heat_file,
"net_heat_flux",found)
3068 IF(.not. found) var =>
find_var(heat_file,
"Net_Heat",found)
3070 & (
"IN SURFACE HEATING BOUNDARY CONDITION FILE OBJECT",&
3071 &
"FILE NAME: "//trim(heating_file),&
3072 &
"COULD NOT FIND VARIABLE 'net_heat_flux'")
3075 ALLOCATE(storage_arr(lons,lats), stat = status)
3076 IF(status /= 0)
CALL fatal_error(
"ALLOCATION ERROR IN SURFACE HEATING")
3079 NULLIFY(storage_arr)
3082 ALLOCATE(storage_vec(0:mt), stat = status)
3083 IF(status /= 0)
CALL fatal_error(
"ALLOCATION ERROR IN SURFACE HEATING")
3085 NULLIFY(storage_vec)
3089 ALLOCATE(storage_arr(lons,lats), stat = status)
3090 IF(status /= 0)
CALL fatal_error(
"ALLOCATION ERROR IN SURFACE HEATING")
3093 NULLIFY(storage_arr)
3096 ALLOCATE(storage_vec(0:mt), stat = status)
3097 IF(status /= 0)
CALL fatal_error(
"ALLOCATION ERROR IN SURFACE HEATING")
3099 NULLIFY(storage_vec)
3102 CASE(heat_is_fvcomgrid)
3106 &
"! SETTING UP HEAT FORCING FROM A 'fvcom grid' FILE" 3109 dim =>
find_dim(heat_file,
'node',found)
3111 & (
"IN SURFACE HEATING BOUNDARY CONDITION FILE OBJECT",&
3112 &
"FILE NAME: "//trim(heating_file),&
3113 &
"COULD NOT FIND DIMENSION 'node'")
3116 &(
"Surface Heating: the number of nodes in the file does not match the fvcom grid?")
3119 dim =>
find_dim(heat_file,
'nele',found)
3121 & (
"IN SURFACE HEATING BOUNDARY CONDITION FILE OBJECT",&
3122 &
"FILE NAME: "//trim(heating_file),&
3123 &
"COULD NOT FIND DIMENSION 'nele'")
3126 &(
"Surface Heating: the number of elements in the file does not match the fvcom grid?")
3131 var =>
find_var(heat_file,
"short_wave",found)
3133 & (
"IN SURFACE HEATING BOUNDARY CONDITION FILE OBJECT",&
3134 &
"FILE NAME: "//trim(heating_file),&
3135 &
"COULD NOT FIND VARIABLE 'short_wave'")
3139 ALLOCATE(storage_vec(0:mt), stat = status)
3140 IF(status /= 0)
CALL fatal_error(
"ALLOCATION ERROR IN SURFACE HEATING")
3142 NULLIFY(storage_vec)
3147 ALLOCATE(storage_vec(0:mt), stat = status)
3148 IF(status /= 0)
CALL fatal_error(
"ALLOCATION ERROR IN SURFACE HEATING")
3150 NULLIFY(storage_vec)
3153 var =>
find_var(heat_file,
"net_heat_flux",found)
3155 & (
"IN SURFACE HEATING BOUNDARY CONDITION FILE OBJECT",&
3156 &
"FILE NAME: "//trim(heating_file),&
3157 &
"COULD NOT FIND VARIABLE 'net_heat_flux'")
3161 ALLOCATE(storage_vec(0:mt), stat = status)
3162 IF(status /= 0)
CALL fatal_error(
"ALLOCATION ERROR IN SURFACE HEATING")
3164 NULLIFY(storage_vec)
3169 ALLOCATE(storage_vec(0:mt), stat = status)
3170 IF(status /= 0)
CALL fatal_error(
"ALLOCATION ERROR IN SURFACE HEATING")
3172 NULLIFY(storage_vec)
3177 CALL fatal_error(
"CAN NOT RECOGNIZE HEATING FILE TYPE!")
3188 heat_net_n%curr_stkcnt=0
3189 heat_net_p%curr_stkcnt=0
3190 heat_swv_n%curr_stkcnt=0
3191 heat_swv_p%curr_stkcnt=0
3195 END SUBROUTINE surface_heating
3202 SUBROUTINE ice_model_forcing
3205 TYPE(
ncatt),
POINTER :: att, att_date
3206 TYPE(
ncdim),
POINTER :: dim
3207 TYPE(
ncvar),
POINTER :: var
3210 REAL(sp),
POINTER :: storage_arr(:,:), storage_vec(:)
3211 CHARACTER(len=60) :: satstrng, slpstrng,spqstrng,cldstrng, swvstrng
3212 TYPE(
time) :: timetest
3214 INTEGER :: lats, lons, i, ntimes
3220 NULLIFY(att,dim,var,storage_arr,storage_vec)
3222 IF (.NOT. ice_model)
THEN 3232 SELECT CASE(ice_forcing_kind)
3237 write(satstrng,
'(f8.4)') ice_air_temp
3238 write(spqstrng,
'(f8.4)') ice_spec_humidity
3239 write(cldstrng,
'(f8.4)') ice_cloud_cover
3240 write(swvstrng,
'(f8.4)') ice_shortwave
3250 WRITE(ipt,*)
"! SETTING UP CONSTANT ICE FORCING:" 3251 WRITE(ipt,*)
"! Sea Leval Air Temp="//trim(satstrng)
3252 WRITE(ipt,*)
"! Specific Humidity="//trim(spqstrng)
3253 WRITE(ipt,*)
"! Cloud Cover="//trim(cldstrng)
3254 WRITE(ipt,*)
"! Shortwave Radiation="//trim(swvstrng)
3261 CALL fatal_error(
"STATIC ICE FORCING Not Set Up Yet")
3266 CALL fatal_error(
"TIME DEPENDANT ICE FORCING Not Set Up Yet")
3273 & (
"COULD NOT FIND ICE MODEL BOUNDARY CONDINTION FILE OBJECT",&
3274 &
"FILE NAME: "//trim(ice_forcing_file))
3278 att =>
find_att(ice_file,
"source",found)
3279 IF(.not. found) att =>
find_att(ice_file,
"Source",found)
3281 & (
"IN ICE FORCING BOUNDARY CONDITION FILE OBJECT",&
3282 &
"FILE NAME: "//trim(ice_forcing_file),&
3283 &
"COULD NOT FIND GLOBAL ATTRIBURE: 'source'")
3287 ice_forcing_type = ice_is_wrfgrid
3291 ice_forcing_type = ice_is_fvcomgrid
3295 ice_forcing_type = ice_is_fvcomgrid
3299 ice_forcing_type = ice_is_wrfgrid
3303 CALL fatal_error(
"CAN NOT RECOGNIZE ICE FORCING FILE!",&
3304 &
"UNKNOWN SOURCE STRING:",trim(att%CHR(1)))
3314 att_date =>
find_att(ice_file,
"START_DATE",found)
3326 & (
"IN ICE FORCING BOUNDARY CONDITION FILE OBJECT",&
3327 &
"FILE NAME: "//trim(ice_forcing_file),&
3328 &
"COULD NOT FIND THE UNLIMITED DIMENSION")
3343 &(
"TO USE PERIODIC FORCING THE FILE TIME MUST COUNT FROM ZERO",&
3344 &
"THE DIFFERENCE BETWEEN THE CURRENT MODEL TIME AND THE START TIME,",&
3345 &
"MODULO THE FORCING PERIOD, DETERMINES THE CURRENT FORCING")
3350 WRITE(ipt,*)
"! USING PERIODIC ICE FORCING:" 3358 & (
"COULD NOT FIND ICE FORCING BOUNDARY CONDINTION FILE OBJECT",&
3359 &
"FILE NAME: "//trim(ice_forcing_file))
3362 att =>
find_att(ice_file,
"source",found)
3363 IF(.not. found) att =>
find_att(ice_file,
"Source",found)
3365 & (
"IN ICE FORCING BOUNDARY CONDITION FILE OBJECT",&
3366 &
"FILE NAME: "//trim(ice_forcing_file),&
3367 &
"COULD NOT FIND GLOBAL ATTRIBURE: 'source'")
3371 ice_forcing_type = ice_is_wrfgrid
3375 ice_forcing_type = ice_is_fvcomgrid
3379 ice_forcing_type = ice_is_fvcomgrid
3383 ice_forcing_type = ice_is_wrfgrid
3387 CALL fatal_error(
"CAN NOT RECOGNIZE ICE FORCING FILE!",&
3388 &
"UNKNOWN SOURCE STRING:",trim(att%CHR(1)))
3399 att_date =>
find_att(ice_file,
"START_DATE",found)
3410 & (
"IN ICE FORCING BOUNDARY CONDITION FILE OBJECT",&
3411 &
"FILE NAME: "//trim(ice_forcing_file),&
3412 &
"COULD NOT FIND UNLIMITED DIMENSION")
3419 & (
"IN ICE FORCING BOUNDARY CONDITION FILE OBJECT",&
3420 &
"FILE NAME: "//trim(ice_forcing_file),&
3421 &
"THE MODEL RUN STARTS BEFORE THE FORCING TIME SERIES")
3425 & (
"IN ICE FORCING BOUNDARY CONDITION FILE OBJECT",&
3426 &
"FILE NAME: "//trim(ice_forcing_file),&
3427 &
"THE MODEL RUN ENDS AFTER THE FORCING TIME SERIES")
3430 CALL fatal_error(
"ICE FORCING: UNKNOWN ICE_FORCING KIND?")
3436 SELECT CASE(ice_forcing_type)
3438 CASE(ice_is_wrfgrid)
3442 &
"! SETTING UP ICE FORCING FROM A 'wrf grid' FILE" 3446 dim =>
find_dim(ice_file,
'south_north',found)
3448 & (
"IN ICE FORCING BOUNDARY CONDITION FILE OBJECT",&
3449 &
"FILE NAME: "//trim(ice_forcing_file),&
3450 &
"COULD NOT FIND DIMENSION 'south_north'")
3454 dim =>
find_dim(ice_file,
'west_east',found)
3456 & (
"IN ICE FORCING BOUNDARY CONDITION FILE OBJECT",&
3457 &
"FILE NAME: "//trim(ice_forcing_file),&
3458 &
"COULD NOT FIND DIMENSION 'west_east'")
3462 CALL set_file_interp_bilinear(ice_file,ice_intp_n,ice_intp_c)
3466 var =>
find_var(heat_file,
"short_wave",found)
3470 ice_swv_n => heat_swv_n
3472 ice_swv_p => heat_swv_p
3478 var =>
find_var(ice_file,
"short_wave",found)
3479 IF(.not. found) var =>
find_var(ice_file,
"Shortwave",found)
3481 & (
"IN ICE FORCING BOUNDARY CONDITION FILE OBJECT",&
3482 &
"FILE NAME: "//trim(ice_forcing_file),&
3483 &
"COULD NOT FIND VARIABLE 'short_wave'")
3486 ALLOCATE(storage_arr(lons,lats), stat = status)
3487 IF(status /= 0)
CALL fatal_error(
"ALLOCATION ERROR IN ICE FORCING")
3490 NULLIFY(storage_arr)
3493 ALLOCATE(storage_vec(0:mt), stat = status)
3494 IF(status /= 0)
CALL fatal_error(
"ALLOCATION ERROR IN ICE FORCING")
3496 NULLIFY(storage_vec)
3500 ALLOCATE(storage_arr(lons,lats), stat = status)
3501 IF(status /= 0)
CALL fatal_error(
"ALLOCATION ERROR IN ICE FORCING")
3504 NULLIFY(storage_arr)
3507 ALLOCATE(storage_vec(0:mt), stat = status)
3508 IF(status /= 0)
CALL fatal_error(
"ALLOCATION ERROR IN ICE FORCING")
3510 NULLIFY(storage_vec)
3516 var =>
find_var(ice_file,
"SAT",found)
3517 var =>
find_var(ice_file,
"T2",found)
3519 & (
"IN ICE FORCING BOUNDARY CONDITION FILE OBJECT",&
3520 &
"FILE NAME: "//trim(ice_forcing_file),&
3521 &
"COULD NOT FIND VARIABLE 'T2' of 'SAT'")
3524 ALLOCATE(storage_arr(lons,lats), stat = status)
3525 IF(status /= 0)
CALL fatal_error(
"ALLOCATION ERROR IN ICE FORCING")
3528 NULLIFY(storage_arr)
3531 ALLOCATE(storage_vec(0:mt), stat = status)
3532 IF(status /= 0)
CALL fatal_error(
"ALLOCATION ERROR IN ICE FORCING")
3534 NULLIFY(storage_vec)
3538 ALLOCATE(storage_arr(lons,lats), stat = status)
3539 IF(status /= 0)
CALL fatal_error(
"ALLOCATION ERROR IN ICE FORCING")
3542 NULLIFY(storage_arr)
3545 ALLOCATE(storage_vec(0:mt), stat = status)
3546 IF(status /= 0)
CALL fatal_error(
"ALLOCATION ERROR IN ICE FORCING")
3548 NULLIFY(storage_vec)
3551 var =>
find_var(ice_file,
"SPQ",found)
3552 var =>
find_var(ice_file,
"Q2",found)
3554 & (
"IN ICE FORCING BOUNDARY CONDITION FILE OBJECT",&
3555 &
"FILE NAME: "//trim(ice_forcing_file),&
3556 &
"COULD NOT FIND VARIABLE 'Q2' of 'SPQ'")
3559 ALLOCATE(storage_arr(lons,lats), stat = status)
3560 IF(status /= 0)
CALL fatal_error(
"ALLOCATION ERROR IN ICE FORCING")
3563 NULLIFY(storage_arr)
3566 ALLOCATE(storage_vec(0:mt), stat = status)
3567 IF(status /= 0)
CALL fatal_error(
"ALLOCATION ERROR IN ICE FORCING")
3569 NULLIFY(storage_vec)
3573 ALLOCATE(storage_arr(lons,lats), stat = status)
3574 IF(status /= 0)
CALL fatal_error(
"ALLOCATION ERROR IN ICE FORCING")
3577 NULLIFY(storage_arr)
3580 ALLOCATE(storage_vec(0:mt), stat = status)
3581 IF(status /= 0)
CALL fatal_error(
"ALLOCATION ERROR IN ICE FORCING")
3583 NULLIFY(storage_vec)
3586 var =>
find_var(ice_file,
"cloud_cover",found)
3588 & (
"IN ICE FORCING BOUNDARY CONDITION FILE OBJECT",&
3589 &
"FILE NAME: "//trim(ice_forcing_file),&
3590 &
"COULD NOT FIND VARIABLE 'cloud_cover'")
3593 ALLOCATE(storage_arr(lons,lats), stat = status)
3594 IF(status /= 0)
CALL fatal_error(
"ALLOCATION ERROR IN ICE FORCING")
3597 NULLIFY(storage_arr)
3600 ALLOCATE(storage_vec(0:mt), stat = status)
3601 IF(status /= 0)
CALL fatal_error(
"ALLOCATION ERROR IN ICE FORCING")
3603 NULLIFY(storage_vec)
3607 ALLOCATE(storage_arr(lons,lats), stat = status)
3608 IF(status /= 0)
CALL fatal_error(
"ALLOCATION ERROR IN ICE FORCING")
3611 NULLIFY(storage_arr)
3614 ALLOCATE(storage_vec(0:mt), stat = status)
3615 IF(status /= 0)
CALL fatal_error(
"ALLOCATION ERROR IN ICE FORCING")
3617 NULLIFY(storage_vec)
3620 CASE(ice_is_fvcomgrid)
3624 &
"! SETTING UP HEAT FORCING FROM A 'fvcom grid' FILE" 3627 dim =>
find_dim(ice_file,
'node',found)
3629 & (
"IN ICE FORCING BOUNDARY CONDITION FILE OBJECT",&
3630 &
"FILE NAME: "//trim(ice_forcing_file),&
3631 &
"COULD NOT FIND DIMENSION 'node'")
3634 &(
"Ice Forcing: the number of nodes in the file does not match the fvcom grid?")
3637 dim =>
find_dim(ice_file,
'nele',found)
3639 & (
"IN ICE FORCING BOUNDARY CONDITION FILE OBJECT",&
3640 &
"FILE NAME: "//trim(ice_forcing_file),&
3641 &
"COULD NOT FIND DIMENSION 'nele'")
3644 &(
"Ice Forcing: the number of elements in the file does not match the fvcom grid?")
3650 var =>
find_var(heat_file,
"short_wave",found)
3654 ice_swv_n => heat_swv_n
3656 ice_swv_p => heat_swv_p
3662 var =>
find_var(ice_file,
"short_wave",found)
3663 IF(.not. found) var =>
find_var(ice_file,
"Shortwave",found)
3665 & (
"IN ICE FORCING BOUNDARY CONDITION FILE OBJECT",&
3666 &
"FILE NAME: "//trim(ice_forcing_file),&
3667 &
"COULD NOT FIND VARIABLE 'short_wave'")
3671 ALLOCATE(storage_vec(0:mt), stat = status)
3672 IF(status /= 0)
CALL fatal_error(
"ALLOCATION ERROR IN ICE FORCING")
3674 NULLIFY(storage_vec)
3679 ALLOCATE(storage_vec(0:mt), stat = status)
3680 IF(status /= 0)
CALL fatal_error(
"ALLOCATION ERROR IN ICE FORCING")
3682 NULLIFY(storage_vec)
3688 var =>
find_var(ice_file,
"SAT",found)
3689 IF(.not. found) var =>
find_var(ice_file,
"T2",found)
3691 & (
"IN ICE FORCING BOUNDARY CONDITION FILE OBJECT",&
3692 &
"FILE NAME: "//trim(ice_forcing_file),&
3693 &
"COULD NOT FIND VARIABLE 'T2' or 'SAT'")
3697 ALLOCATE(storage_vec(0:mt), stat = status)
3698 IF(status /= 0)
CALL fatal_error(
"ALLOCATION ERROR IN ICE FORCING")
3700 NULLIFY(storage_vec)
3705 ALLOCATE(storage_vec(0:mt), stat = status)
3706 IF(status /= 0)
CALL fatal_error(
"ALLOCATION ERROR IN ICE FORCING")
3708 NULLIFY(storage_vec)
3711 var =>
find_var(ice_file,
"SPQ",found)
3712 IF(.not. found) var =>
find_var(ice_file,
"Q2",found)
3714 & (
"IN ICE FORCING BOUNDARY CONDITION FILE OBJECT",&
3715 &
"FILE NAME: "//trim(ice_forcing_file),&
3716 &
"COULD NOT FIND VARIABLE 'Q2' or 'SPQ'")
3720 ALLOCATE(storage_vec(0:mt), stat = status)
3721 IF(status /= 0)
CALL fatal_error(
"ALLOCATION ERROR IN ICE FORCING")
3723 NULLIFY(storage_vec)
3728 ALLOCATE(storage_vec(0:mt), stat = status)
3729 IF(status /= 0)
CALL fatal_error(
"ALLOCATION ERROR IN ICE FORCING")
3731 NULLIFY(storage_vec)
3734 var =>
find_var(ice_file,
"cloud_cover",found)
3736 & (
"IN ICE FORCING BOUNDARY CONDITION FILE OBJECT",&
3737 &
"FILE NAME: "//trim(ice_forcing_file),&
3738 &
"COULD NOT FIND VARIABLE 'cloud_cover'")
3742 ALLOCATE(storage_vec(0:mt), stat = status)
3743 IF(status /= 0)
CALL fatal_error(
"ALLOCATION ERROR IN ICE FORCING")
3745 NULLIFY(storage_vec)
3750 ALLOCATE(storage_vec(0:mt), stat = status)
3751 IF(status /= 0)
CALL fatal_error(
"ALLOCATION ERROR IN ICE FORCING")
3753 NULLIFY(storage_vec)
3759 CALL fatal_error(
"CAN NOT RECOGNIZE ICE FORCING FILE TYPE!")
3771 ice_swv_n%curr_stkcnt = 0;ice_swv_p%curr_stkcnt = 0
3772 ice_sat_n%curr_stkcnt = 0;ice_sat_p%curr_stkcnt = 0
3773 ice_spq_n%curr_stkcnt = 0;ice_spq_p%curr_stkcnt = 0
3774 ice_cld_n%curr_stkcnt = 0;ice_cld_p%curr_stkcnt = 0
3778 END SUBROUTINE ice_model_forcing
3781 SUBROUTINE icing_forcing
3784 TYPE(
ncatt),
POINTER :: att, att_date
3785 TYPE(
ncdim),
POINTER :: dim
3786 TYPE(
ncvar),
POINTER :: var
3789 REAL(sp),
POINTER :: storage_arr(:,:), storage_vec(:)
3790 CHARACTER(len=30) :: satstrng, wspdstrng
3791 TYPE(
time) :: timetest
3793 INTEGER :: lats, lons, i, ntimes
3799 NULLIFY(att,dim,var,storage_arr,storage_vec)
3801 IF (.NOT. icing_model )
THEN 3810 SELECT CASE(icing_forcing_kind)
3813 write(satstrng,
'(f8.4)') icing_air_temp
3814 write(wspdstrng,
'(f8.4)') icing_wspd
3823 WRITE(ipt,*)
"! SETTING UP CONSTANT ICING: " 3824 WRITE(ipt,*)
"! Sea Level Air Temperature:"//trim(satstrng)
3825 WRITE(ipt,*)
"! Wind Speed:"//trim(wspdstrng)
3836 CALL fatal_error(
"TIME DEPENDANT HEATING Not Set Up Yet")
3843 & (
"COULD NOT FIND SURFACE ICING BOUNDARY CONDINTION FILE OBJECT",&
3844 &
"FILE NAME: "//trim(icing_forcing_file))
3847 att =>
find_att(icing_file,
"source",found)
3848 IF(.not. found) att =>
find_att(icing_file,
"Source",found)
3850 & (
"IN SURFACE ICING BOUNDARY CONDITION FILE OBJECT",&
3851 &
"FILE NAME: "//trim(icing_forcing_file),&
3852 &
"COULD NOT FIND GLOBAL ATTRIBURE: 'source'")
3856 icing_forcing_type = icing_is_wrfgrid
3860 icing_forcing_type = icing_is_fvcomgrid
3864 icing_forcing_type = icing_is_fvcomgrid
3868 icing_forcing_type = icing_is_wrfgrid
3872 CALL fatal_error(
"CAN NOT RECOGNIZE ICING FILE!",&
3873 &
"UNKNOWN SOURCE STRING:",trim(att%CHR(1)))
3883 att_date =>
find_att(icing_file,
"START_DATE",found)
3895 & (
"IN SURFACE ICING BOUNDARY CONDITION FILE OBJECT",&
3896 &
"FILE NAME: "//trim(icing_forcing_file),&
3897 &
"COULD NOT FIND THE UNLIMITED DIMENSION")
3912 &(
"TO USE PERIODIC FORCING THE FILE TIME MUST COUNT FROM ZERO",&
3913 &
"THE DIFFERENCE BETWEEN THE CURRENT MODEL TIME AND THE START TIME,",&
3914 &
"MODULO THE FORCING PERIOD, DETERMINES THE CURRENT FORCING")
3919 WRITE(ipt,*)
"! USING PERIODIC ICING FORCING:" 3927 & (
"COULD NOT FIND SURFACE ICING BOUNDARY CONDINTION FILE OBJECT",&
3928 &
"FILE NAME: "//trim(icing_forcing_file))
3931 att =>
find_att(icing_file,
"source",found)
3932 IF(.not. found) att =>
find_att(icing_file,
"Source",found)
3934 & (
"IN SURFACE ICING BOUNDARY CONDITION FILE OBJECT",&
3935 &
"FILE NAME: "//trim(icing_forcing_file),&
3936 &
"COULD NOT FIND GLOBAL ATTRIBURE: 'source'")
3942 icing_forcing_type = icing_is_wrfgrid
3946 icing_forcing_type = icing_is_fvcomgrid
3950 icing_forcing_type = icing_is_fvcomgrid
3954 icing_forcing_type = icing_is_wrfgrid
3958 CALL fatal_error(
"CAN NOT RECOGNIZE ICING FILE!",&
3959 &
"UNKNOWN SOURCE STRING:",trim(att%CHR(1)))
3969 att_date =>
find_att(icing_file,
"START_DATE",found)
3980 & (
"IN SURFACE ICING BOUNDARY CONDITION FILE OBJECT",&
3981 &
"FILE NAME: "//trim(icing_forcing_file),&
3982 &
"COULD NOT FIND UNLIMITED DIMENSION")
3989 & (
"IN SURFACE ICING BOUNDARY CONDITION FILE OBJECT",&
3990 &
"FILE NAME: "//trim(icing_forcing_file),&
3991 &
"THE MODEL RUN STARTS BEFORE THE FORCING TIME SERIES")
3995 & (
"IN SURFACE ICING BOUNDARY CONDITION FILE OBJECT",&
3996 &
"FILE NAME: "//trim(icing_forcing_file),&
3997 &
"THE MODEL RUN ENDS AFTER THE FORCING TIME SERIES")
4000 CALL fatal_error(
"SURFACE_ICING: UNKNOWN ICING KIND?")
4006 SELECT CASE(icing_forcing_type)
4008 CASE(icing_is_wrfgrid)
4012 &
"! SETTING UP ICING FORCING FROM A 'wrf grid' FILE" 4015 dim =>
find_dim(icing_file,
'south_north',found)
4017 & (
"IN SURFACE ICING BOUNDARY CONDITION FILE OBJECT",&
4018 &
"FILE NAME: "//trim(icing_forcing_file),&
4019 &
"COULD NOT FIND DIMENSION 'south_north'")
4023 dim =>
find_dim(icing_file,
'west_east',found)
4025 & (
"IN SURFACE HEATING BOUNDARY CONDITION FILE OBJECT",&
4026 &
"FILE NAME: "//trim(icing_forcing_file),&
4027 &
"COULD NOT FIND DIMENSION 'west_east'")
4031 CALL set_file_interp_bilinear(icing_file,icing_intp_n,icing_intp_c)
4036 IF(
ASSOCIATED(ice_file,icing_file))
THEN 4038 icing_sat_n => ice_sat_n
4039 icing_sat_p => ice_sat_p
4043 var =>
find_var(icing_file,
"T2",found)
4046 & (
"IN SURFACE HEATING BOUNDARY CONDITION FILE OBJECT",&
4047 &
"FILE NAME: "//trim(icing_forcing_file),&
4048 &
"COULD NOT FIND VARIABLE 'T2'")
4051 ALLOCATE(storage_arr(lons,lats), stat = status)
4052 IF(status /= 0)
CALL fatal_error(
"ALLOCATION ERROR IN ICING_FORCING")
4055 NULLIFY(storage_arr)
4058 ALLOCATE(storage_vec(0:mt), stat = status)
4059 IF(status /= 0)
CALL fatal_error(
"ALLOCATION ERROR IN ICING_FORCING")
4061 NULLIFY(storage_vec)
4065 ALLOCATE(storage_arr(lons,lats), stat = status)
4066 IF(status /= 0)
CALL fatal_error(
"ALLOCATION ERROR IN ICING_FORCING")
4069 NULLIFY(storage_arr)
4072 ALLOCATE(storage_vec(0:mt), stat = status)
4073 IF(status /= 0)
CALL fatal_error(
"ALLOCATION ERROR IN ICING_FORCING")
4075 NULLIFY(storage_vec)
4080 var =>
find_var(heat_file,
"U10",found)
4083 & (
"IN SURFACE ICING BOUNDARY CONDITION FILE OBJECT",&
4084 &
"FILE NAME: "//trim(icing_forcing_file),&
4085 &
"COULD NOT FIND VARIABLE 'U10'")
4088 ALLOCATE(storage_arr(lons,lats), stat = status)
4089 IF(status /= 0)
CALL fatal_error(
"ALLOCATION ERROR IN ICING_FORCING")
4092 NULLIFY(storage_arr)
4095 ALLOCATE(storage_vec(0:mt), stat = status)
4096 IF(status /= 0)
CALL fatal_error(
"ALLOCATION ERROR IN ICING_FORCING")
4098 NULLIFY(storage_vec)
4102 ALLOCATE(storage_arr(lons,lats), stat = status)
4103 IF(status /= 0)
CALL fatal_error(
"ALLOCATION ERROR IN ICING_FORCING")
4106 NULLIFY(storage_arr)
4109 ALLOCATE(storage_vec(0:mt), stat = status)
4110 IF(status /= 0)
CALL fatal_error(
"ALLOCATION ERROR IN ICING_FORCING")
4112 NULLIFY(storage_vec)
4115 var =>
find_var(heat_file,
"V10",found)
4118 & (
"IN SURFACE ICING BOUNDARY CONDITION FILE OBJECT",&
4119 &
"FILE NAME: "//trim(icing_forcing_file),&
4120 &
"COULD NOT FIND VARIABLE 'V10'")
4123 ALLOCATE(storage_arr(lons,lats), stat = status)
4124 IF(status /= 0)
CALL fatal_error(
"ALLOCATION ERROR IN ICING_FORCING")
4127 NULLIFY(storage_arr)
4130 ALLOCATE(storage_vec(0:mt), stat = status)
4131 IF(status /= 0)
CALL fatal_error(
"ALLOCATION ERROR IN ICING_FORCING")
4133 NULLIFY(storage_vec)
4137 ALLOCATE(storage_arr(lons,lats), stat = status)
4138 IF(status /= 0)
CALL fatal_error(
"ALLOCATION ERROR IN ICING_FORCING")
4141 NULLIFY(storage_arr)
4144 ALLOCATE(storage_vec(0:mt), stat = status)
4145 IF(status /= 0)
CALL fatal_error(
"ALLOCATION ERROR IN ICING_FORCING")
4147 NULLIFY(storage_vec)
4150 CASE(icing_is_fvcomgrid)
4154 &
"! SETTING UP ICING FORCING FROM A 'fvcom grid' FILE" 4157 dim =>
find_dim(icing_file,
'node',found)
4159 & (
"IN SURFACE ICING BOUNDARY CONDITION FILE OBJECT",&
4160 &
"FILE NAME: "//trim(icing_forcing_file),&
4161 &
"COULD NOT FIND DIMENSION 'node'")
4164 &(
"Surface ICing: the number of nodes in the file does not match the fvcom grid?")
4167 dim =>
find_dim(heat_file,
'nele',found)
4169 & (
"IN SURFACE ICING BOUNDARY CONDITION FILE OBJECT",&
4170 &
"FILE NAME: "//trim(icing_forcing_file),&
4171 &
"COULD NOT FIND DIMENSION 'nele'")
4174 &(
"Surface Icing: the number of elements in the file does not match the fvcom grid?")
4179 IF(
ASSOCIATED(ice_file,icing_file))
THEN 4182 icing_sat_n => ice_sat_n
4184 icing_sat_p => ice_sat_p
4187 var =>
find_var(icing_file,
"T2",found)
4189 & (
"IN SURFACE ICING BOUNDARY CONDITION FILE OBJECT",&
4190 &
"FILE NAME: "//trim(icing_forcing_file),&
4191 &
"COULD NOT FIND VARIABLE 'T2'")
4195 ALLOCATE(storage_vec(0:mt), stat = status)
4196 IF(status /= 0)
CALL fatal_error(
"ALLOCATION ERROR IN ICING_FORCING")
4198 NULLIFY(storage_vec)
4203 ALLOCATE(storage_vec(0:mt), stat = status)
4204 IF(status /= 0)
CALL fatal_error(
"ALLOCATION ERROR IN ICING_FORCING")
4206 NULLIFY(storage_vec)
4211 var =>
find_var(heat_file,
"U10",found)
4213 & (
"IN SURFACE ICING BOUNDARY CONDITION FILE OBJECT",&
4214 &
"FILE NAME: "//trim(icing_forcing_file),&
4215 &
"COULD NOT FIND VARIABLE 'U10'")
4219 ALLOCATE(storage_vec(0:mt), stat = status)
4220 IF(status /= 0)
CALL fatal_error(
"ALLOCATION ERROR IN ICING_FORCING")
4222 NULLIFY(storage_vec)
4227 ALLOCATE(storage_vec(0:mt), stat = status)
4228 IF(status /= 0)
CALL fatal_error(
"ALLOCATION ERROR IN ICING_FORCING")
4230 NULLIFY(storage_vec)
4235 CALL fatal_error(
"CAN NOT RECOGNIZE ICING FILE TYPE!")
4247 icing_sat_p%CURR_STKCNT = 0; icing_sat_n%CURR_STKCNT = 0
4248 icing_wspx_p%CURR_STKCNT = 0; icing_wspx_n%CURR_STKCNT = 0
4249 icing_wspy_p%CURR_STKCNT = 0; icing_wspy_n%CURR_STKCNT = 0
4255 END SUBROUTINE icing_forcing
4258 SUBROUTINE surface_windstress
4261 TYPE(
ncatt),
POINTER :: att, att_date
4262 TYPE(
ncdim),
POINTER :: dim
4263 TYPE(
ncvar),
POINTER :: var
4265 REAL(sp),
POINTER :: storage_arr(:,:), storage_vec(:)
4266 TYPE(
time) :: timetest
4267 INTEGER :: lats, lons, i, ntimes
4269 CHARACTER(len=60) :: xstr, ystr
4273 NULLIFY(att,dim,var,storage_arr,storage_vec)
4276 IF (.NOT. wind_on )
THEN 4277 IF(
dbg_set(
dbg_log))
write(ipt,*)
"! SURFACE WIND FORCING IS OFF!" 4283 IF (wind_type /= speed .and.wind_type /= stress)
CALL fatal_error&
4284 &(
"YOU MUST SELECT A WIND TYPE IN THE RUNFILE: '"&
4285 &//trim(speed)//
", or '"//trim(stress)//
"'")
4289 SELECT CASE(wind_kind)
4292 write(xstr,
'(f8.4)') wind_x
4293 write(ystr,
'(f8.4)') wind_y
4295 IF (wind_type == speed)
THEN 4298 WRITE(ipt,*)
"! SETTING UP CONSTANT WIND SPEED FORCING: " 4299 WRITE(ipt,*)
" Xspeed: "//trim(xstr)
4300 WRITE(ipt,*)
" Yspeed: "//trim(ystr)
4308 ELSEIF(wind_type == stress)
THEN 4311 WRITE(ipt,*)
"! SETTING UP CONSTANT WIND STRESS FORCING: " 4312 WRITE(ipt,*)
" Xstress: "//trim(xstr)
4313 WRITE(ipt,*)
" Ystress: "//trim(ystr)
4330 CALL fatal_error(
"TIME DEPENDANT WIND Not Set Up Yet")
4336 & (
"COULD NOT FIND SURFACE WIND BOUNDARY CONDINTION FILE OBJECT",&
4337 &
"FILE NAME: "//trim(wind_file))
4340 att =>
find_att(winds_file,
"source",found)
4341 IF(.not. found) att =>
find_att(winds_file,
"Source",found)
4343 & (
"IN SURFACE WIND BOUNDARY CONDITION FILE OBJECT",&
4344 &
"FILE NAME: "//trim(wind_file),&
4345 &
"COULD NOT FIND GLOBAL ATTRIBURE: 'source'")
4350 winds_forcing_type = winds_are_wrfgrid
4354 winds_forcing_type = winds_are_fvcomgrid
4358 winds_forcing_type = winds_are_fvcomgrid
4362 winds_forcing_type = winds_are_wrfgrid
4366 &
"UNKNOWN SOURCE STRING:",trim(att%CHR(1)))
4376 att_date =>
find_att(winds_file,
"START_DATE",found)
4389 & (
"IN SURFACE WIND BOUNDARY CONDITION FILE OBJECT",&
4390 &
"FILE NAME: "//trim(wind_file),&
4391 &
"COULD NOT FIND THE UNLMITIED DIMENSION")
4405 &(
"TO USE PERIODIC FORCING THE FILE TIME MUST COUNT FROM ZERO",&
4406 &
"THE DIFFERENCE BETWEEN THE CURRENT MODEL TIME AND THE START TIME,",&
4407 &
"MODULO THE FORCING PERIOD, DETERMINES THE CURRENT FORCING")
4412 WRITE(ipt,*)
"! USING PERIODIC WIND FORCING:" 4421 & (
"COULD NOT FIND SURFACE WIND BOUNDARY CONDINTION FILE OBJECT",&
4422 &
"FILE NAME: "//trim(wind_file))
4425 att =>
find_att(winds_file,
"source",found)
4426 IF(.not. found) att =>
find_att(winds_file,
"Source",found)
4428 & (
"IN SURFACE WIND BOUNDARY CONDITION FILE OBJECT",&
4429 &
"FILE NAME: "//trim(wind_file),&
4430 &
"COULD NOT FIND GLOBAL ATTRIBURE: 'source'")
4434 winds_forcing_type = winds_are_wrfgrid
4438 winds_forcing_type = winds_are_fvcomgrid
4442 winds_forcing_type = winds_are_fvcomgrid
4446 winds_forcing_type = winds_are_wrfgrid
4449 winds_forcing_type = winds_are_pt_source
4453 &
"UNKNOWN SOURCE STRING:",trim(att%CHR(1)))
4463 att_date =>
find_att(winds_file,
"START_DATE",found)
4473 & (
"IN SURFACE WIND BOUNDARY CONDITION FILE OBJECT",&
4474 &
"FILE NAME: "//trim(wind_file),&
4475 &
"COULD NOT FIND THE UNLIMITED DIMENSION")
4482 & (
"IN SURFACE WIND BOUNDARY CONDITION FILE OBJECT",&
4483 &
"FILE NAME: "//trim(wind_file),&
4484 &
"THE MODEL RUN STARTS BEFORE THE FORCING TIME SERIES")
4488 & (
"IN SURFACE WIND BOUNDARY CONDITION FILE OBJECT",&
4489 &
"FILE NAME: "//trim(wind_file),&
4490 &
"THE MODEL RUN ENDS AFTER THE FORCING TIME SERIES")
4493 CALL fatal_error(
"SURFACE_WINDSTRESS: UNKNOWN WIND KIND?")
4497 SELECT CASE(winds_forcing_type)
4499 CASE(winds_are_wrfgrid)
4504 &
"! SETTING UP WIND STRESS FORCING FROM A 'wrf grid' FILE" 4506 dim =>
find_dim(winds_file,
'south_north',found)
4508 & (
"IN SURFACE WIND BOUNDARY CONDITION FILE OBJECT",&
4509 &
"FILE NAME: "//trim(wind_file),&
4510 &
"COULD NOT FIND DIMENSION 'south_north'")
4514 dim =>
find_dim(winds_file,
'west_east',found)
4516 & (
"IN SURFACE WIND BOUNDARY CONDITION FILE OBJECT",&
4517 &
"FILE NAME: "//trim(wind_file),&
4518 &
"COULD NOT FIND DIMENSION 'west_east'")
4521 CALL set_file_interp_bilinear(winds_file,winds_intp_n,winds_intp_c)
4525 IF (wind_type == speed)
THEN 4528 var =>
find_var(winds_file,
"uwind_speed",found)
4529 IF(.not. found) var =>
find_var(winds_file,
"U10",found)
4531 & (
"IN SURFACE WIND BOUNDARY CONDITION FILE OBJECT",&
4532 &
"FILE NAME: "//trim(wind_file),&
4533 &
"COULD NOT FIND VARIABLE 'uwind_speed' or 'U10'")
4535 ELSEIF(wind_type == stress)
THEN 4537 var =>
find_var(winds_file,
"uwind_stress",found)
4538 IF(.not. found) var =>
find_var(winds_file,
"Stress_U",found)
4540 & (
"IN SURFACE WIND BOUNDARY CONDITION FILE OBJECT",&
4541 &
"FILE NAME: "//trim(wind_file),&
4542 &
"COULD NOT FIND VARIABLE 'uwind_stress' or 'Stress_U'")
4546 ALLOCATE(storage_arr(lons,lats), stat = status)
4547 IF(status /= 0)
CALL fatal_error(
"ALLOCATION ERROR IN SURFACE WINDSTRESS")
4550 NULLIFY(storage_arr)
4553 ALLOCATE(storage_vec(0:nt), stat = status)
4554 IF(status /= 0)
CALL fatal_error(
"ALLOCATION ERROR IN SURFACE WINDSTRESS")
4556 NULLIFY(storage_vec)
4560 ALLOCATE(storage_arr(lons,lats), stat = status)
4561 IF(status /= 0)
CALL fatal_error(
"ALLOCATION ERROR IN SURFACE WINDSTRESS")
4564 NULLIFY(storage_arr)
4567 ALLOCATE(storage_vec(0:nt), stat = status)
4568 IF(status /= 0)
CALL fatal_error(
"ALLOCATION ERROR IN SURFACE WINDSTRESS")
4570 NULLIFY(storage_vec)
4572 IF (wind_type == speed)
THEN 4575 var =>
find_var(winds_file,
"vwind_speed",found)
4576 IF(.not. found) var =>
find_var(winds_file,
"V10",found)
4578 & (
"IN SURFACE WIND BOUNDARY CONDITION FILE OBJECT",&
4579 &
"FILE NAME: "//trim(wind_file),&
4580 &
"COULD NOT FIND VARIABLE 'vwind_speed' or 'V10'")
4582 ELSEIF(wind_type == stress)
THEN 4584 var =>
find_var(winds_file,
"vwind_stress",found)
4585 IF(.not. found) var =>
find_var(winds_file,
"Stress_V",found)
4587 & (
"IN SURFACE WIND BOUNDARY CONDITION FILE OBJECT",&
4588 &
"FILE NAME: "//trim(wind_file),&
4589 &
"COULD NOT FIND VARIABLE 'vwind_stress' or 'Stress_V'")
4593 ALLOCATE(storage_arr(lons,lats), stat = status)
4594 IF(status /= 0)
CALL fatal_error(
"ALLOCATION ERROR IN SURFACE WINDSTRESS")
4597 NULLIFY(storage_arr)
4600 ALLOCATE(storage_vec(0:nt), stat = status)
4601 IF(status /= 0)
CALL fatal_error(
"ALLOCATION ERROR IN SURFACE WINDSTRESS")
4603 NULLIFY(storage_vec)
4607 ALLOCATE(storage_arr(lons,lats), stat = status)
4608 IF(status /= 0)
CALL fatal_error(
"ALLOCATION ERROR IN SURFACE WINDSTRESS")
4611 NULLIFY(storage_arr)
4614 ALLOCATE(storage_vec(0:nt), stat = status)
4615 IF(status /= 0)
CALL fatal_error(
"ALLOCATION ERROR IN SURFACE WINDSTRESS")
4617 NULLIFY(storage_vec)
4621 CASE(winds_are_fvcomgrid)
4624 &
"! SETTING UP WIND STRESS FORCING FROM A 'FVCOM GRID' FILE" 4626 dim =>
find_dim(winds_file,
'node',found)
4628 & (
"IN SURFACE WIND BOUNDARY CONDITION FILE OBJECT",&
4629 &
"FILE NAME: "//trim(wind_file),&
4630 &
"COULD NOT FIND DIMENSION 'node'")
4633 &(
"Surface Windstress: the number of nodes in the file does not match the fvcom grid?")
4635 dim =>
find_dim(winds_file,
'nele',found)
4637 & (
"IN SURFACE WIND BOUNDARY CONDITION FILE OBJECT",&
4638 &
"FILE NAME: "//trim(wind_file),&
4639 &
"COULD NOT FIND DIMENSION 'nele'")
4642 &(
"Surface Windstress: the number of elements in the file does not match the fvcom grid?")
4647 IF (wind_type == speed)
THEN 4650 var =>
find_var(winds_file,
"uwind_speed",found)
4651 IF(.not. found) var =>
find_var(winds_file,
"U10",found)
4653 & (
"IN SURFACE WIND BOUNDARY CONDITION FILE OBJECT",&
4654 &
"FILE NAME: "//trim(wind_file),&
4655 &
"COULD NOT FIND VARIABLE 'uwind_speed' or 'U10'")
4657 ELSEIF(wind_type == stress)
THEN 4660 var =>
find_var(winds_file,
"uwind_stress",found)
4662 & (
"IN SURFACE WIND BOUNDARY CONDITION FILE OBJECT",&
4663 &
"FILE NAME: "//trim(wind_file),&
4664 &
"COULD NOT FIND VARIABLE 'uwind_stress'")
4670 ALLOCATE(storage_vec(0:nt), stat = status)
4671 IF(status /= 0)
CALL fatal_error(
"ALLOCATION ERROR IN SURFACE WINDSTRESS")
4673 NULLIFY(storage_vec)
4678 ALLOCATE(storage_vec(0:nt), stat = status)
4679 IF(status /= 0)
CALL fatal_error(
"ALLOCATION ERROR IN SURFACE WINDSTRESS")
4681 NULLIFY(storage_vec)
4683 IF (wind_type == speed)
THEN 4686 var =>
find_var(winds_file,
"vwind_speed",found)
4687 IF(.not. found) var =>
find_var(winds_file,
"V10",found)
4689 & (
"IN SURFACE WIND BOUNDARY CONDITION FILE OBJECT",&
4690 &
"FILE NAME: "//trim(wind_file),&
4691 &
"COULD NOT FIND VARIABLE 'vwind_speed' or 'V10'")
4692 ELSEIF(wind_type == stress)
THEN 4695 var =>
find_var(winds_file,
"vwind_stress",found)
4697 & (
"IN SURFACE WIND BOUNDARY CONDITION FILE OBJECT",&
4698 &
"FILE NAME: "//trim(wind_file),&
4699 &
"COULD NOT FIND VARIABLE 'vwind_stress'")
4704 ALLOCATE(storage_vec(0:nt), stat = status)
4705 IF(status /= 0)
CALL fatal_error(
"ALLOCATION ERROR IN SURFACE WINDSTRESS")
4707 NULLIFY(storage_vec)
4712 ALLOCATE(storage_vec(0:nt), stat = status)
4713 IF(status /= 0)
CALL fatal_error(
"ALLOCATION ERROR IN SURFACE WINDSTRESS")
4715 NULLIFY(storage_vec)
4718 CASE(winds_are_pt_source)
4721 &
"! SETTING UP WIND STRESS FORCING FROM A 'FVCOM GRID' FILE" 4726 IF (wind_type == speed)
THEN 4729 var =>
find_var(winds_file,
"uwind_speed",found)
4730 IF(.not. found) var =>
find_var(winds_file,
"U10",found)
4732 & (
"IN SURFACE WIND BOUNDARY CONDITION FILE OBJECT",&
4733 &
"FILE NAME: "//trim(wind_file),&
4734 &
"COULD NOT FIND VARIABLE 'uwind_speed' or 'U10'")
4736 ELSEIF(wind_type == stress)
THEN 4739 var =>
find_var(winds_file,
"uwind_stress",found)
4741 & (
"IN SURFACE WIND BOUNDARY CONDITION FILE OBJECT",&
4742 &
"FILE NAME: "//trim(wind_file),&
4743 &
"COULD NOT FIND VARIABLE 'uwind_stress'")
4749 ALLOCATE(storage_vec(1), stat = status)
4750 IF(status /= 0)
CALL fatal_error(
"ALLOCATION ERROR IN SURFACE WINDSTRESS")
4752 NULLIFY(storage_vec)
4757 ALLOCATE(storage_vec(1), stat = status)
4758 IF(status /= 0)
CALL fatal_error(
"ALLOCATION ERROR IN SURFACE WINDSTRESS")
4760 NULLIFY(storage_vec)
4762 IF (wind_type == speed)
THEN 4765 var =>
find_var(winds_file,
"vwind_speed",found)
4766 IF(.not. found) var =>
find_var(winds_file,
"V10",found)
4768 & (
"IN SURFACE WIND BOUNDARY CONDITION FILE OBJECT",&
4769 &
"FILE NAME: "//trim(wind_file),&
4770 &
"COULD NOT FIND VARIABLE 'vwind_speed' or 'V10'")
4771 ELSEIF(wind_type == stress)
THEN 4774 var =>
find_var(winds_file,
"vwind_stress",found)
4776 & (
"IN SURFACE WIND BOUNDARY CONDITION FILE OBJECT",&
4777 &
"FILE NAME: "//trim(wind_file),&
4778 &
"COULD NOT FIND VARIABLE 'vwind_stress'")
4783 ALLOCATE(storage_vec(1), stat = status)
4784 IF(status /= 0)
CALL fatal_error(
"ALLOCATION ERROR IN SURFACE WINDSTRESS")
4786 NULLIFY(storage_vec)
4791 ALLOCATE(storage_vec(1), stat = status)
4792 IF(status /= 0)
CALL fatal_error(
"ALLOCATION ERROR IN SURFACE WINDSTRESS")
4794 NULLIFY(storage_vec)
4799 CALL fatal_error(
"CAN NOT RECOGNIZE WIND FILE TYPE!")
4810 winds_strx_n%curr_stkcnt = 0; winds_strx_p%curr_stkcnt = 0
4811 winds_stry_n%curr_stkcnt = 0; winds_stry_p%curr_stkcnt = 0
4815 END SUBROUTINE surface_windstress
4832 SUBROUTINE surface_wave
4835 TYPE(
ncatt),
POINTER :: att, att_date
4836 TYPE(
ncdim),
POINTER :: dim
4837 TYPE(
ncvar),
POINTER :: var
4839 REAL(sp),
POINTER :: storage_arr(:,:), storage_vec(:)
4840 TYPE(
time) :: timetest
4841 INTEGER :: lats, lons, i, ntimes
4843 CHARACTER(len=60) :: w_hs, w_len,w_dir,w_per,w_per_bot,w_ub_bot
4847 NULLIFY(att,dim,var,storage_arr,storage_vec)
4850 IF (.NOT. wave_on )
THEN 4851 IF(
dbg_set(
dbg_log))
write(ipt,*)
"! SURFACE WAVE FORCING IS OFF!" 4859 SELECT CASE(wave_kind)
4862 write(w_hs,
'(f8.4)') wave_height
4863 write(w_len,
'(f8.4)') wave_length
4864 write(w_dir,
'(f8.4)') wave_direction
4865 write(w_per,
'(f8.4)') wave_period
4866 write(w_per_bot,
'(f8.4)') wave_per_bot
4867 write(w_ub_bot,
'(f8.4)') wave_ub_bot
4871 WRITE(ipt,*)
"! SETTING UP CONSTANT SURFACE WAVE FORCING: " 4872 WRITE(ipt,*)
" wave height : "//trim(w_hs)
4873 WRITE(ipt,*)
" wave length : "//trim(w_len)
4874 WRITE(ipt,*)
" wave direction: "//trim(w_dir)
4875 WRITE(ipt,*)
" wave period : "//trim(w_per)
4876 WRITE(ipt,*)
" wave per_bot : "//trim(w_per_bot)
4877 WRITE(ipt,*)
" wave ub_bot : "//trim(w_ub_bot)
4897 CALL fatal_error(
"TIME DEPENDANT WAVE Not Set Up Yet")
4903 & (
"COULD NOT FIND SURFACE WAVE BOUNDARY CONDINTION FILE OBJECT",&
4904 &
"FILE NAME: "//trim(wave_file))
4907 att =>
find_att(waves_file,
"source",found)
4908 IF(.not. found) att =>
find_att(waves_file,
"Source",found)
4910 & (
"IN SURFACE WAVE BOUNDARY CONDITION FILE OBJECT",&
4911 &
"FILE NAME: "//trim(wave_file),&
4912 &
"COULD NOT FIND GLOBAL ATTRIBURE: 'source'")
4917 waves_forcing_type = waves_are_wrfgrid
4921 waves_forcing_type = waves_are_fvcomgrid
4925 waves_forcing_type = waves_are_fvcomgrid
4929 waves_forcing_type = waves_are_wrfgrid
4934 &
"UNKNOWN SOURCE STRING:",trim(att%CHR(1)))
4944 att_date =>
find_att(waves_file,
"START_DATE",found)
4957 & (
"IN SURFACE WAVE BOUNDARY CONDITION FILE OBJECT",&
4958 &
"FILE NAME: "//trim(wave_file),&
4959 &
"COULD NOT FIND THE UNLMITIED DIMENSION")
4973 &(
"TO USE PERIODIC FORCING THE FILE TIME MUST COUNT FROM ZERO",&
4974 &
"THE DIFFERENCE BETWEEN THE CURRENT MODEL TIME AND THE START TIME,",&
4975 &
"MODULO THE FORCING PERIOD, DETERMINES THE CURRENT FORCING")
4980 WRITE(ipt,*)
"! USING PERIODIC WAVE FORCING:" 4989 & (
"COULD NOT FIND SURFACE WAVE BOUNDARY CONDINTION FILE OBJECT",&
4990 &
"FILE NAME: "//trim(wave_file))
4993 att =>
find_att(waves_file,
"source",found)
4994 IF(.not. found) att =>
find_att(waves_file,
"Source",found)
4996 & (
"IN SURFACE WAVE BOUNDARY CONDITION FILE OBJECT",&
4997 &
"FILE NAME: "//trim(wave_file),&
4998 &
"COULD NOT FIND GLOBAL ATTRIBURE: 'source'")
5002 waves_forcing_type = waves_are_wrfgrid
5006 waves_forcing_type = waves_are_fvcomgrid
5010 waves_forcing_type = waves_are_fvcomgrid
5014 waves_forcing_type = waves_are_wrfgrid
5019 &
"UNKNOWN SOURCE STRING:",trim(att%CHR(1)))
5029 att_date =>
find_att(waves_file,
"START_DATE",found)
5039 & (
"IN SURFACE WAVE BOUNDARY CONDITION FILE OBJECT",&
5040 &
"FILE NAME: "//trim(wave_file),&
5041 &
"COULD NOT FIND THE UNLIMITED DIMENSION")
5048 & (
"IN SURFACE WAVE BOUNDARY CONDITION FILE OBJECT",&
5049 &
"FILE NAME: "//trim(wave_file),&
5050 &
"THE MODEL RUN STARTS BEFORE THE FORCING TIME SERIES")
5054 & (
"IN SURFACE WAVE BOUNDARY CONDITION FILE OBJECT",&
5055 &
"FILE NAME: "//trim(wave_file),&
5056 &
"THE MODEL RUN ENDS AFTER THE FORCING TIME SERIES")
5059 CALL fatal_error(
"SURFACE_WAVE: UNKNOWN WAVE KIND?")
5063 SELECT CASE(waves_forcing_type)
5065 CASE(waves_are_wrfgrid)
5068 CALL fatal_error(
"WAVE based on WRF grid Not Set Up Yet")
5071 CASE(waves_are_fvcomgrid)
5074 &
"! SETTING UP WAVE FORCING FROM A 'FVCOM GRID' FILE" 5076 dim =>
find_dim(waves_file,
'node',found)
5078 & (
"IN SURFACE WAVE BOUNDARY CONDITION FILE OBJECT",&
5079 &
"FILE NAME: "//trim(wave_file),&
5080 &
"COULD NOT FIND DIMENSION 'node'")
5083 &(
"Surface Wave: the number of nodes in the file does not match the fvcom grid?")
5091 var =>
find_var(waves_file,
"hs",found)
5093 & (
"IN SURFACE WAVE BOUNDARY CONDITION FILE OBJECT",&
5094 &
"FILE NAME: "//trim(wave_file),&
5095 &
"COULD NOT FIND VARIABLE 'hs' ")
5100 ALLOCATE(storage_vec(0:mt), stat = status)
5101 IF(status /= 0)
CALL fatal_error(
"ALLOCATION ERROR IN WAVE HEIGHT")
5103 NULLIFY(storage_vec)
5108 ALLOCATE(storage_vec(0:mt), stat = status)
5109 IF(status /= 0)
CALL fatal_error(
"ALLOCATION ERROR IN WAVE HEIGHT")
5111 NULLIFY(storage_vec)
5115 var =>
find_var(waves_file,
"wlen",found)
5117 & (
"IN SURFACE WAVE BOUNDARY CONDITION FILE OBJECT",&
5118 &
"FILE NAME: "//trim(wave_file),&
5119 &
"COULD NOT FIND VARIABLE 'wlen' ")
5124 ALLOCATE(storage_vec(0:mt), stat = status)
5125 IF(status /= 0)
CALL fatal_error(
"ALLOCATION ERROR IN WAVE LENGTH")
5127 NULLIFY(storage_vec)
5132 ALLOCATE(storage_vec(0:mt), stat = status)
5133 IF(status /= 0)
CALL fatal_error(
"ALLOCATION ERROR IN WAVE LENGTH")
5135 NULLIFY(storage_vec)
5138 var =>
find_var(waves_file,
"dirm",found)
5139 IF(.not. found) var =>
find_var(waves_file,
"wdir",found)
5141 & (
"IN SURFACE WAVE BOUNDARY CONDITION FILE OBJECT",&
5142 &
"FILE NAME: "//trim(wave_file),&
5143 &
"COULD NOT FIND VARIABLE 'dirm' or 'wdir' ")
5147 ALLOCATE(storage_vec(0:mt), stat = status)
5148 IF(status /= 0)
CALL fatal_error(
"ALLOCATION ERROR IN WAVE DIRECTION")
5150 NULLIFY(storage_vec)
5154 ALLOCATE(storage_vec(0:mt), stat = status)
5155 IF(status /= 0)
CALL fatal_error(
"ALLOCATION ERROR IN WAVE DIRECTION")
5157 NULLIFY(storage_vec)
5160 var =>
find_var(waves_file,
"tpeak",found)
5162 & (
"IN SURFACE WAVE BOUNDARY CONDITION FILE OBJECT",&
5163 &
"FILE NAME: "//trim(wave_file),&
5164 &
"COULD NOT FIND VARIABLE 'tpeak' ")
5169 ALLOCATE(storage_vec(0:mt), stat = status)
5170 IF(status /= 0)
CALL fatal_error(
"ALLOCATION ERROR IN WAVE PERIOD")
5172 NULLIFY(storage_vec)
5177 ALLOCATE(storage_vec(0:mt), stat = status)
5178 IF(status /= 0)
CALL fatal_error(
"ALLOCATION ERROR IN WAVE PERIOD")
5180 NULLIFY(storage_vec)
5184 var =>
find_var(waves_file,
"pwave_bot",found)
5185 IF(.not. found) var =>
find_var(waves_file,
"tmbot",found)
5187 & (
"IN SURFACE WAVE BOUNDARY CONDITION FILE OBJECT",&
5188 &
"FILE NAME: "//trim(wave_file),&
5189 &
"COULD NOT FIND VARIABLE 'pwave_bot' or 'tmbot' ")
5194 ALLOCATE(storage_vec(0:mt), stat = status)
5195 IF(status /= 0)
CALL fatal_error(
"ALLOCATION ERROR IN BOTTOM WAVE PERIOD")
5197 NULLIFY(storage_vec)
5202 ALLOCATE(storage_vec(0:mt), stat = status)
5203 IF(status /= 0)
CALL fatal_error(
"ALLOCATION ERROR IN BOTTOM WAVE PERIOD")
5205 NULLIFY(storage_vec)
5209 var =>
find_var(waves_file,
"ub_bot",found)
5210 IF(.not. found) var =>
find_var(waves_file,
"ubot",found)
5212 & (
"IN SURFACE WAVE BOUNDARY CONDITION FILE OBJECT",&
5213 &
"FILE NAME: "//trim(wave_file),&
5214 &
"COULD NOT FIND VARIABLE 'ub_bot' or 'ubot' ")
5219 ALLOCATE(storage_vec(0:mt), stat = status)
5220 IF(status /= 0)
CALL fatal_error(
"ALLOCATION ERROR IN BOTTOM WAVE ORBITAL VELOCITY")
5222 NULLIFY(storage_vec)
5227 ALLOCATE(storage_vec(0:mt), stat = status)
5228 IF(status /= 0)
CALL fatal_error(
"ALLOCATION ERROR IN BOTTOM WAVE ORBITAL VELOCITY")
5230 NULLIFY(storage_vec)
5237 CALL fatal_error(
"CAN NOT RECOGNIZE WAVE FILE TYPE!")
5243 END SUBROUTINE surface_wave
5250 SUBROUTINE surface_airpressure
5253 TYPE(
ncatt),
POINTER :: att, att_date
5254 TYPE(
ncdim),
POINTER :: dim
5255 TYPE(
ncvar),
POINTER :: var
5257 REAL(sp),
POINTER :: storage_arr(:,:), storage_vec(:)
5258 TYPE(
time) :: timetest
5259 INTEGER :: lats, lons, i, ntimes
5261 CHARACTER(len=60) :: airpressurestr
5265 NULLIFY(att,dim,var,storage_arr,storage_vec)
5268 IF (.NOT. airpressure_on )
THEN 5269 IF(
dbg_set(
dbg_log))
write(ipt,*)
"! SURFACE AIR PRESSURE FORCING IS OFF!" 5277 SELECT CASE(airpressure_kind)
5280 write(airpressurestr,
'(f8.4)') airpressure_value
5284 WRITE(ipt,*)
"! SETTING UP CONSTANT AIR PRESSURE FORCING: " 5285 WRITE(ipt,*)
" Air pressure: "//trim(airpressurestr)
5295 CALL fatal_error(
"STATIC AIR PRESSURE Not Set Up Yet")
5299 CALL fatal_error(
"TIME DEPENDANT AIR PRESSURE Not Set Up Yet")
5305 & (
"COULD NOT FIND SURFACE AIR PRESSURE FILE OBJECT",&
5306 &
"FILE NAME: "//trim(airpressure_file))
5309 att =>
find_att(airpressure_p_file,
"source",found)
5310 IF(.not. found) att =>
find_att(airpressure_p_file,
"Source",found)
5312 & (
"IN SURFACE AIR PRESSURE FILE OBJECT",&
5313 &
"FILE NAME: "//trim(airpressure_file),&
5314 &
"COULD NOT FIND GLOBAL ATTRIBURE: 'source'")
5319 airpressure_forcing_type = airpressure_is_wrfgrid
5323 airpressure_forcing_type = airpressure_is_fvcomgrid
5327 airpressure_forcing_type = airpressure_is_fvcomgrid
5331 airpressure_forcing_type = airpressure_is_wrfgrid
5335 CALL fatal_error(
"CAN NOT RECOGNIZE AIR PRESSURE FILE!",&
5336 &
"UNKNOWN SOURCE STRING:",trim(att%CHR(1)))
5346 att_date =>
find_att(airpressure_p_file,
"START_DATE",found)
5359 & (
"IN AIR PRESSURE FILE OBJECT",&
5360 &
"FILE NAME: "//trim(airpressure_file),&
5361 &
"COULD NOT FIND THE UNLMITIED DIMENSION")
5365 airpressure_period =
get_file_time(airpressure_p_file,ntimes)
5367 airpressure_period = airpressure_period -
get_file_time(airpressure_p_file,1)
5369 IF (airpressure_period /=
get_file_time(airpressure_p_file,ntimes))
THEN 5375 &(
"TO USE PERIODIC FORCING THE FILE TIME MUST COUNT FROM ZERO",&
5376 &
"THE DIFFERENCE BETWEEN THE CURRENT MODEL TIME AND THE START TIME,",&
5377 &
"MODULO THE FORCING PERIOD, DETERMINES THE CURRENT FORCING")
5382 WRITE(ipt,*)
"! USING PERIODIC AIR PRESSURE FORCING:" 5383 CALL print_time(airpressure_period,ipt,
"PERIOD")
5391 & (
"COULD NOT FIND SURFACE AIR PRESSURE FILE OBJECT",&
5392 &
"FILE NAME: "//trim(airpressure_file))
5395 att =>
find_att(airpressure_p_file,
"source",found)
5396 IF(.not. found) att =>
find_att(airpressure_p_file,
"Source",found)
5398 & (
"IN SURFACE AIR PRESSURE FILE OBJECT",&
5399 &
"FILE NAME: "//trim(airpressure_file),&
5400 &
"COULD NOT FIND GLOBAL ATTRIBURE: 'source'")
5404 airpressure_forcing_type = airpressure_is_wrfgrid
5408 airpressure_forcing_type = airpressure_is_fvcomgrid
5412 airpressure_forcing_type = airpressure_is_fvcomgrid
5416 airpressure_forcing_type = airpressure_is_wrfgrid
5420 CALL fatal_error(
"CAN NOT RECOGNIZE AIR PRESSURE FILE!",&
5421 &
"UNKNOWN SOURCE STRING:",trim(att%CHR(1)))
5431 att_date =>
find_att(airpressure_p_file,
"START_DATE",found)
5441 & (
"IN SURFACE AIR PRESSURE FILE OBJECT",&
5442 &
"FILE NAME: "//trim(airpressure_file),&
5443 &
"COULD NOT FIND THE UNLIMITED DIMENSION")
5450 & (
"IN SURFACE AIR PRESSURE FILE OBJECT",&
5451 &
"FILE NAME: "//trim(airpressure_file),&
5452 &
"THE MODEL RUN STARTS BEFORE THE FORCING TIME SERIES")
5456 & (
"IN SURFACE AIR PRESSURE FILE OBJECT",&
5457 &
"FILE NAME: "//trim(airpressure_file),&
5458 &
"THE MODEL RUN ENDS AFTER THE FORCING TIME SERIES")
5461 CALL fatal_error(
"SURFACE_AIRPRESSURE: UNKNOWN ARE PRESSURE KIND?")
5465 SELECT CASE(airpressure_forcing_type)
5467 CASE(airpressure_is_wrfgrid)
5472 &
"! SETTING UP AIR PRESSURE FORCING FROM A 'wrf grid' FILE" 5474 dim =>
find_dim(airpressure_p_file,
'south_north',found)
5476 & (
"IN SURFACE AIR PRESSURE FILE OBJECT",&
5477 &
"FILE NAME: "//trim(airpressure_file),&
5478 &
"COULD NOT FIND DIMENSION 'south_north'")
5482 dim =>
find_dim(airpressure_p_file,
'west_east',found)
5484 & (
"IN SURFACE AIR PRESSURE FILE OBJECT",&
5485 &
"FILE NAME: "//trim(airpressure_file),&
5486 &
"COULD NOT FIND DIMENSION 'west_east'")
5489 CALL set_file_interp_bilinear(airpressure_p_file,airpressure_intp_n,airpressure_intp_c)
5494 var =>
find_var(airpressure_p_file,
"air_pressure",found)
5495 IF(.not. found) var =>
find_var(airpressure_p_file,
"pressure_air",found)
5497 & (
"IN SURFACE AIR PRESSURE FILE OBJECT",&
5498 &
"FILE NAME: "//trim(airpressure_file),&
5499 &
"COULD NOT FIND VARIABLE 'air_pressure'")
5502 ALLOCATE(storage_arr(lons,lats), stat = status)
5503 IF(status /= 0)
CALL fatal_error(
"ALLOCATION ERROR IN SURFACE AIR PRESSURE")
5506 NULLIFY(storage_arr)
5509 ALLOCATE(storage_vec(0:mt), stat = status)
5510 IF(status /= 0)
CALL fatal_error(
"ALLOCATION ERROR IN SURFACE AIR PRESSURE")
5512 NULLIFY(storage_vec)
5516 ALLOCATE(storage_arr(lons,lats), stat = status)
5517 IF(status /= 0)
CALL fatal_error(
"ALLOCATION ERROR IN SURFACE AIR PRESSURE")
5520 NULLIFY(storage_arr)
5523 ALLOCATE(storage_vec(0:mt), stat = status)
5524 IF(status /= 0)
CALL fatal_error(
"ALLOCATION ERROR IN SURFACE AIR PRESSURE")
5526 NULLIFY(storage_vec)
5529 CASE(airpressure_is_fvcomgrid)
5532 &
"! SETTING UP AIR PRESSURE FORCING FROM A 'FVCOM GRID' FILE" 5534 dim =>
find_dim(airpressure_p_file,
'node',found)
5536 & (
"IN SURFACE AIR PRESSURE FILE OBJECT",&
5537 &
"FILE NAME: "//trim(airpressure_file),&
5538 &
"COULD NOT FIND DIMENSION 'node'")
5541 &(
"Surface Air Pressure: the number of nodes in the file does not match the fvcom grid?")
5543 dim =>
find_dim(airpressure_p_file,
'nele',found)
5545 & (
"IN SURFACE AIR PRESSURE FILE OBJECT",&
5546 &
"FILE NAME: "//trim(airpressure_file),&
5547 &
"COULD NOT FIND DIMENSION 'nele'")
5550 &(
"Surface Air Pressure: the number of elements in the file does not match the fvcom grid?")
5556 var =>
find_var(airpressure_p_file,
"air_pressure",found)
5557 IF(.not. found) var =>
find_var(airpressure_p_file,
"SLP",found)
5559 & (
"IN SURFACE AIR PRESSURE FILE OBJECT",&
5560 &
"FILE NAME: "//trim(airpressure_file),&
5561 &
"COULD NOT FIND VARIABLE 'air_pressure' or 'SLP'")
5565 ALLOCATE(storage_vec(0:mt), stat = status)
5566 IF(status /= 0)
CALL fatal_error(
"ALLOCATION ERROR IN AIR PRESSURE")
5568 NULLIFY(storage_vec)
5573 ALLOCATE(storage_vec(0:mt), stat = status)
5574 IF(status /= 0)
CALL fatal_error(
"ALLOCATION ERROR IN AIR PRESSURE")
5576 NULLIFY(storage_vec)
5581 CALL fatal_error(
"CAN NOT RECOGNIZE AIR PRESSURE FILE TYPE!")
5593 air_pressure_p%curr_stkcnt = 0 ; air_pressure_n%curr_stkcnt = 0
5599 END SUBROUTINE surface_airpressure
5604 SUBROUTINE surface_precipitation
5607 TYPE(
ncatt),
POINTER :: att, att_date
5608 TYPE(
ncdim),
POINTER :: dim
5609 TYPE(
ncvar),
POINTER :: var
5611 REAL(sp),
POINTER :: storage_arr(:,:), storage_vec(:)
5612 TYPE(
time) :: timetest
5613 INTEGER :: lats, lons, i, ntimes
5615 CHARACTER(len=60) :: evpstr, prcstr
5619 IF (.NOT. precipitation_on )
THEN 5620 IF(
dbg_set(
dbg_log))
write(ipt,*)
"! SURFACE PRECIPITATION FORCING IS OFF!" 5626 NULLIFY(att,dim,var,storage_arr,storage_vec)
5629 SELECT CASE(precipitation_kind)
5632 write(evpstr,
'(f8.4)') precipitation_evp
5633 write(prcstr,
'(f8.4)') precipitation_prc
5636 WRITE(ipt,*)
"! SETTING UP CONSTANT PRECIPITATION FORCING: " 5637 WRITE(ipt,*)
" EVAPORATION: "//trim(evpstr)
5638 WRITE(ipt,*)
" PRECIPITATION: "//trim(prcstr)
5653 CALL fatal_error(
"TIME DEPENDANT PRECIP Not Set Up Yet")
5660 & (
"COULD NOT FIND SURFACE WIND BOUNDARY CONDINTION FILE OBJECT",&
5661 &
"FILE NAME: "//trim(precipitation_file))
5664 att =>
find_att(precip_file,
"source",found)
5665 IF(.not. found) att =>
find_att(precip_file,
"Source",found)
5667 & (
"IN SURFACE WIND BOUNDARY CONDITION FILE OBJECT",&
5668 &
"FILE NAME: "//trim(precipitation_file),&
5669 &
"COULD NOT FIND GLOBAL ATTRIBURE: 'source'")
5674 precip_forcing_type = precip_is_wrfgrid
5678 precip_forcing_type = precip_is_fvcomgrid
5682 precip_forcing_type = precip_is_fvcomgrid
5686 precip_forcing_type = precip_is_wrfgrid
5690 CALL fatal_error(
"CAN NOT RECOGNIZE PRECIP FILE!",&
5691 &
"UNKNOWN SOURCE STRING:",trim(att%CHR(1)))
5701 att_date =>
find_att(precip_file,
"START_DATE",found)
5713 & (
"IN SURFACE PRECIPITATION BOUNDARY CONDITION FILE OBJECT",&
5714 &
"FILE NAME: "//trim(wind_file),&
5715 &
"COULD NOT FIND THE UNLIMITED DIMENSION")
5721 precip_period = precip_period -
get_file_time(precip_file,1)
5723 IF (precip_period /=
get_file_time(precip_file,ntimes))
THEN 5729 &(
"TO USE PERIODIC FORCING THE FILE TIME MUST COUNT FROM ZERO",&
5730 &
"THE DIFFERENCE BETWEEN THE CURRENT MODEL TIME AND THE START TIME,",&
5731 &
"MODULO THE FORCING PERIOD, DETERMINES THE CURRENT FORCING")
5736 WRITE(ipt,*)
"! USING PERIODIC PRECIP FORCING:" 5746 & (
"COULD NOT FIND SURFACE WIND BOUNDARY CONDINTION FILE OBJECT",&
5747 &
"FILE NAME: "//trim(precipitation_file))
5750 att =>
find_att(precip_file,
"source",found)
5751 IF(.not. found) att =>
find_att(precip_file,
"Source",found)
5753 & (
"IN SURFACE WIND BOUNDARY CONDITION FILE OBJECT",&
5754 &
"FILE NAME: "//trim(precipitation_file),&
5755 &
"COULD NOT FIND GLOBAL ATTRIBURE: 'source'")
5759 precip_forcing_type = precip_is_wrfgrid
5763 precip_forcing_type = precip_is_fvcomgrid
5767 precip_forcing_type = precip_is_fvcomgrid
5771 precip_forcing_type = precip_is_wrfgrid
5775 CALL fatal_error(
"CAN NOT RECOGNIZE PRECIP FILE!",&
5776 &
"UNKNOWN SOURCE STRING:",trim(att%CHR(1)))
5786 att_date =>
find_att(precip_file,
"START_DATE",found)
5795 & (
"IN SURFACE WIND BOUNDARY CONDITION FILE OBJECT",&
5796 &
"FILE NAME: "//trim(precipitation_file),&
5797 &
"COULD NOT FIND THE UNLIMITED DIMENSION")
5804 & (
"IN SURFACE WIND BOUNDARY CONDITION FILE OBJECT",&
5805 &
"FILE NAME: "//trim(precipitation_file),&
5806 &
"THE MODEL RUN STARTS BEFORE THE FORCING TIME SERIES")
5810 & (
"IN SURFACE WIND BOUNDARY CONDITION FILE OBJECT",&
5811 &
"FILE NAME: "//trim(precipitation_file),&
5812 &
"THE MODEL RUN ENDS AFTER THE FORCING TIME SERIES")
5817 CALL fatal_error(
"SURFACE_PRECIP: UNKNOWN WIND KIND?")
5823 SELECT CASE(precip_forcing_type)
5825 CASE(precip_is_wrfgrid)
5829 &
"! SETTING UP WIND STRESS FORCING FROM A 'wrf grid' FILE" 5834 dim =>
find_dim(precip_file,
'south_north',found)
5836 & (
"IN SURFACE WIND BOUNDARY CONDITION FILE OBJECT",&
5837 &
"FILE NAME: "//trim(precipitation_file),&
5838 &
"COULD NOT FIND DIMENSION 'south_north'")
5843 dim =>
find_dim(precip_file,
'west_east',found)
5845 & (
"IN SURFACE WIND BOUNDARY CONDITION FILE OBJECT",&
5846 &
"FILE NAME: "//trim(precipitation_file),&
5847 &
"COULD NOT FIND DIMENSION 'west_east'")
5852 CALL set_file_interp_bilinear(precip_file,precip_intp_n,precip_intp_c)
5857 var =>
find_var(precip_file,
"Precipitation",found)
5859 & (
"IN SURFACE WIND BOUNDARY CONDITION FILE OBJECT",&
5860 &
"FILE NAME: "//trim(precipitation_file),&
5861 &
"COULD NOT FIND VARIABLE 'PRECIPITATION'")
5864 ALLOCATE(storage_arr(lons,lats), stat = status)
5865 IF(status /= 0)
CALL fatal_error(
"ALLOCATION ERROR IN SURFACE PRECIPITATION")
5868 NULLIFY(storage_arr)
5871 ALLOCATE(storage_vec(0:mt), stat = status)
5872 IF(status /= 0)
CALL fatal_error(
"ALLOCATION ERROR IN SURFACE PRECIPITATION")
5874 NULLIFY(storage_vec)
5878 ALLOCATE(storage_arr(lons,lats), stat = status)
5879 IF(status /= 0)
CALL fatal_error(
"ALLOCATION ERROR IN SURFACE PRECIPITATION")
5882 NULLIFY(storage_arr)
5885 ALLOCATE(storage_vec(0:mt), stat = status)
5886 IF(status /= 0)
CALL fatal_error(
"ALLOCATION ERROR IN SURFACE PRECIPITATION")
5888 NULLIFY(storage_vec)
5891 var =>
find_var(precip_file,
"Evaporation",found)
5893 & (
"IN SURFACE WIND BOUNDARY CONDITION FILE OBJECT",&
5894 &
"FILE NAME: "//trim(precipitation_file),&
5895 &
"COULD NOT FIND VARIABLE 'Evaporation'")
5898 ALLOCATE(storage_arr(lons,lats), stat = status)
5899 IF(status /= 0)
CALL fatal_error(
"ALLOCATION ERROR IN SURFACE PRECIPITATION")
5902 NULLIFY(storage_arr)
5905 ALLOCATE(storage_vec(0:mt), stat = status)
5906 IF(status /= 0)
CALL fatal_error(
"ALLOCATION ERROR IN SURFACE PRECIPITATION")
5908 NULLIFY(storage_vec)
5912 ALLOCATE(storage_arr(lons,lats), stat = status)
5913 IF(status /= 0)
CALL fatal_error(
"ALLOCATION ERROR IN SURFACE PRECIPITATION")
5916 NULLIFY(storage_arr)
5919 ALLOCATE(storage_vec(0:mt), stat = status)
5920 IF(status /= 0)
CALL fatal_error(
"ALLOCATION ERROR IN SURFACE PRECIPITATION")
5922 NULLIFY(storage_vec)
5925 CASE(precip_is_fvcomgrid)
5930 &
"! SETTING UP PRECIPITATION FORCING FROM A 'FVCOM grid' FILE" 5935 dim =>
find_dim(precip_file,
'node',found)
5937 & (
"IN PRECIPITATION BOUNDARY CONDITION FILE OBJECT",&
5938 &
"FILE NAME: "//trim(precipitation_file),&
5939 &
"COULD NOT FIND DIMENSION 'node'")
5942 &(
"Surface PRECIP: the number of nodes in the file does not match the fvcom grid?")
5945 dim =>
find_dim(precip_file,
'nele',found)
5947 & (
"IN PRECIPITATION BOUNDARY CONDITION FILE OBJECT",&
5948 &
"FILE NAME: "//trim(precipitation_file),&
5949 &
"COULD NOT FIND DIMENSION 'nele'")
5952 &(
"Surface PRECIP: the number of elements in the file does not match the fvcom grid?")
5959 var =>
find_var(precip_file,
"precip",found)
5961 & (
"IN PRECIPITATION BOUNDARY CONDITION FILE OBJECT",&
5962 &
"FILE NAME: "//trim(precipitation_file),&
5963 &
"COULD NOT FIND VARIABLE 'precip'")
5967 ALLOCATE(storage_vec(0:mt), stat = status)
5968 IF(status /= 0)
CALL fatal_error(
"ALLOCATION ERROR IN SURFACE PRECIPITATION")
5970 NULLIFY(storage_vec)
5975 ALLOCATE(storage_vec(0:mt), stat = status)
5976 IF(status /= 0)
CALL fatal_error(
"ALLOCATION ERROR IN SURFACE PRECIPITATION")
5978 NULLIFY(storage_vec)
5981 var =>
find_var(precip_file,
"evap",found)
5983 & (
"IN PRECIPITATION BOUNDARY CONDITION FILE OBJECT",&
5984 &
"FILE NAME: "//trim(precipitation_file),&
5985 &
"COULD NOT FIND VARIABLE 'evap'")
5989 ALLOCATE(storage_vec(0:mt), stat = status)
5990 IF(status /= 0)
CALL fatal_error(
"ALLOCATION ERROR IN SURFACE PRECIPITATION")
5992 NULLIFY(storage_vec)
5997 ALLOCATE(storage_vec(0:mt), stat = status)
5998 IF(status /= 0)
CALL fatal_error(
"ALLOCATION ERROR IN SURFACE PRECIPITATION")
6000 NULLIFY(storage_vec)
6005 CALL fatal_error(
"CAN NOT RECOGNIZE PRECIPITATION FILE TYPE")
6018 precip_pre_p%curr_stkcnt = 0
6019 precip_pre_n%curr_stkcnt = 0
6021 precip_evp_n%curr_stkcnt = 0
6022 precip_evp_p%curr_stkcnt = 0
6029 END SUBROUTINE surface_precipitation
6033 TYPE(
time),
INTENT(IN) :: now
6034 REAL(sp),
ALLOCATABLE :: flux(:)
6035 REAL(sp),
ALLOCATABLE,
OPTIONAL :: temp(:)
6036 REAL(sp),
ALLOCATABLE,
OPTIONAL :: salt(:)
6037 REAL(sp),
ALLOCATABLE,
OPTIONAL :: wqm(:,:)
6038 REAL(sp),
ALLOCATABLE,
OPTIONAL :: sed(:,:)
6039 REAL(sp),
ALLOCATABLE,
OPTIONAL :: bio(:,:)
6041 REAL(sp),
POINTER :: vnp(:), vpp(:)
6043 REAL(sp),
ALLOCATABLE :: current(:)
6044 TYPE(
time) :: rivtime
6046 TYPE(
ncfile),
POINTER :: ncf
6047 TYPE(
ncvar),
POINTER :: var_n
6048 TYPE(
ncvar),
POINTER :: var_p
6050 INTEGER :: status, i, j, nrsf,ind,ns
6053 &(
"THE RIVER FLUX VARIABLE PASSED TO UPDATE IS NOT ALLOCATED")
6055 IF(
PRESENT(temp))
THEN 6057 &(
"THE RIVER TEMP VARIABLE PASSED TO UPDATE IS NOT ALLOCATED")
6060 IF(
PRESENT(salt))
THEN 6062 &(
"THE RIVER SALT VARIABLE PASSED TO UPDATE IS NOT ALLOCATED")
6066 DO i = 1,
SIZE(river_forcing)
6068 SELECT CASE (river_kind)
6078 rivtime =
mod(rivtime,river_forcing(i)%RIVER_PERIOD)
6087 ncf => river_forcing(i)%NCF
6090 nrsf = river_forcing(i)%RIVERS_IN_FILE
6093 var_n => river_forcing(i)%FLUX_N
6094 var_p => river_forcing(i)%FLUX_P
6096 IF (status /= 0)
THEN 6097 CALL fatal_error(
"COULD NOT UPATE RIVER_FILE TIME BRACKET: BOUNDS EXCEEDED?")
6100 ALLOCATE(current(nrsf))
6113 if (ftm%PREV_WGHT .gt. 0.5_sp) current = vpp
6117 ind = river_forcing(i)%RIV_FILE2LOC(j)
6118 IF(ind /= 0) flux(ind) = current(j)
6123 IF(
PRESENT(salt))
THEN 6126 var_n => river_forcing(i)%SALT_N
6127 var_p => river_forcing(i)%SALT_P
6129 IF (status /= 0)
THEN 6130 CALL fatal_error(
"COULD NOT UPATE RIVER_FILE TIME BRACKET: BOUNDS EXCEEDED?")
6133 ALLOCATE(current(nrsf))
6146 if (ftm%PREV_WGHT .gt. 0.5_sp) current = vpp
6151 ind = river_forcing(i)%RIV_FILE2LOC(j)
6152 IF(ind /= 0) salt(ind) = current(j)
6158 IF(
PRESENT(temp))
THEN 6161 var_n => river_forcing(i)%TEMP_N
6162 var_p => river_forcing(i)%TEMP_P
6164 IF (status /= 0)
THEN 6165 CALL fatal_error(
"COULD NOT UPATE RIVER_FILE TIME BRACKET: BOUNDS EXCEEDED?")
6168 ALLOCATE(current(nrsf))
6181 if (ftm%PREV_WGHT .gt. 0.5_sp) current = vpp
6185 ind = river_forcing(i)%RIV_FILE2LOC(j)
6186 IF(ind /= 0) temp(ind) = current(j)
6201 TYPE(
time),
INTENT(IN) :: now
6202 TYPE(
time) :: gwtime
6203 REAL(sp),
ALLOCATABLE :: gw_flux(:)
6204 REAL(sp),
ALLOCATABLE,
OPTIONAL :: gw_salt(:)
6205 REAL(sp),
ALLOCATABLE,
OPTIONAL :: gw_temp(:)
6208 REAL(sp),
POINTER :: vnp(:), vpp(:)
6211 &(
"THE GROUNDWATER FLUX VARIABLE PASSED TO UPDATE IS NOT ALLOCATED")
6215 SELECT CASE(groundwater_kind)
6221 gw_flux(1:mt) = groundwater_flow*
art1(1:mt)
6223 IF(groundwater_temp_on .and.
PRESENT(gw_temp))
THEN 6225 &(
"THE GROUNDWATER TEMPERATURE VARIABLE PASSED TO UPDATE IS NOT ALLOCATED")
6226 gw_temp(1:mt) = groundwater_temp
6229 IF(groundwater_salt_on .and.
PRESENT(gw_salt))
THEN 6231 &(
"THE GROUNDWATER SALINITY VARIABLE PASSED TO UPDATE IS NOT ALLOCATED")
6232 gw_salt(1:mt) = groundwater_salt
6243 CALL fatal_error(
"TIME DEPENDANT HEATING Not Set Up Yet")
6254 gwtime =
mod(gwtime,gwater_period)
6265 SELECT CASE(gwater_forcing_type)
6267 CASE(gwater_is_fvcomgrid)
6269 ftm => gwater_file%FTIME
6273 IF (status /= 0)
THEN 6274 CALL fatal_error(
"COULD NOT UPATE GROUNDWATER_FILE TIME BRACKET: BOUNDS EXCEEDED?")
6280 gw_flux = ftm%NEXT_WGHT * vnp + ftm%PREV_WGHT * vpp
6283 IF(gwater_units == gwater_ms_1 ) gw_flux = gw_flux *
art1 6287 IF(groundwater_temp_on .and.
PRESENT(gw_temp))
THEN 6290 &(
"THE GROUNDWATER TEMPERATURE VARIABLE PASSED TO UPDATE IS NOT ALLOCATED")
6293 IF (status /= 0)
THEN 6294 CALL fatal_error(
"COULD NOT UPATE GROUNDWATER_FILE TIME BRACKET: BOUNDS EXCEEDED?")
6300 gw_temp = ftm%NEXT_WGHT * vnp + ftm%PREV_WGHT * vpp
6304 IF(groundwater_salt_on .and.
PRESENT(gw_salt))
THEN 6307 &(
"THE GROUNDWATER SALINITY VARIABLE PASSED TO UPDATE IS NOT ALLOCATED")
6310 IF (status /= 0)
THEN 6311 CALL fatal_error(
"COULD NOT UPATE GROUNDWATER_FILE TIME BRACKET: BOUNDS EXCEEDED?")
6317 gw_salt = ftm%NEXT_WGHT * vnp + ftm%PREV_WGHT * vpp
6323 CALL fatal_error(
"UNKNOWN GROUNDWATER_FORCING_TYPE IN UPDATE GROUNDWATER")
6331 TYPE(
time),
INTENT(IN) :: now
6333 REAL(sp),
ALLOCATABLE :: heat_swv(:), heat_net(:)
6336 REAL(sp),
POINTER :: vnp(:), vpp(:)
6339 &(
"THE HEAT SHORTWAVE VARIABLE PASSED TO UPDATE IS NOT ALLOCATED")
6342 &(
"THE NET HEAT VARIABLE PASSED TO UPDATE IS NOT ALLOCATED")
6345 SELECT CASE(heating_kind)
6349 heat_swv(1:mt) = heating_radiation
6350 heat_net(1:mt) = heating_netflux
6360 CALL fatal_error(
"TIME DEPENDANT HEATING Not Set Up Yet")
6371 htime =
mod(htime,heat_period)
6383 SELECT CASE(heat_forcing_type)
6385 CASE(heat_is_wrfgrid)
6387 ftm => heat_file%FTIME
6391 IF (status /= 0)
THEN 6392 CALL fatal_error(
"COULD NOT UPATE HEAT_FILE TIME BRACKET: BOUNDS EXCEEDED?")
6398 heat_swv = ftm%NEXT_WGHT * vnp + ftm%PREV_WGHT * vpp
6402 IF (status /= 0)
THEN 6403 CALL fatal_error(
"COULD NOT UPATE HEAT_FILE TIME BRACKET: BOUNDS EXCEEDED?")
6408 heat_net = ftm%NEXT_WGHT * vnp + ftm%PREV_WGHT * vpp
6410 CASE(heat_is_fvcomgrid)
6412 ftm => heat_file%FTIME
6416 IF (status /= 0)
THEN 6417 CALL fatal_error(
"COULD NOT UPATE HEAT_FILE TIME BRACKET: BOUNDS EXCEEDED?")
6423 heat_swv = ftm%NEXT_WGHT * vnp + ftm%PREV_WGHT * vpp
6427 IF (status /= 0)
THEN 6428 CALL fatal_error(
"COULD NOT UPATE HEAT_FILE TIME BRACKET: BOUNDS EXCEEDED?")
6433 heat_net = ftm%NEXT_WGHT * vnp + ftm%PREV_WGHT * vpp
6437 CALL fatal_error(
"UNKNOWN HEAT_FORCING_TYPE IN UPDATE HEAT")
6450 TYPE(
time),
INTENT(IN) :: now
6452 REAL(sp),
ALLOCATABLE :: wstrx(:),wstry(:)
6453 REAL(sp),
POINTER :: vnp(:), vpp(:)
6459 &(
"THE WIND VARIABLE PASSED TO UPDATE IS NOT ALLOCATED")
6461 &(
"THE WIND VARIABLE PASSED TO UPDATE IS NOT ALLOCATED")
6465 SELECT CASE(wind_kind)
6469 wstrx(1:nt) = wind_x
6470 wstry(1:nt) = wind_y
6480 CALL fatal_error(
"TIME DEPENDANT WIND Not Set Up Yet")
6491 wtime =
mod(wtime,winds_period)
6502 SELECT CASE(winds_forcing_type)
6504 CASE(winds_are_wrfgrid)
6506 ftm => winds_file%FTIME
6509 CALL update_var_bracket(winds_file,winds_strx_p,winds_strx_n,wtime,status,winds_intp_c)
6510 IF (status /= 0)
THEN 6511 CALL fatal_error(
"COULD NOT UPATE WIND X BRACKET: BOUNDS EXCEEDED?")
6516 wstrx = ftm%NEXT_WGHT * vnp + ftm%PREV_WGHT * vpp
6519 CALL update_var_bracket(winds_file,winds_stry_p,winds_stry_n,wtime,status,winds_intp_c)
6520 IF (status /= 0)
THEN 6521 CALL fatal_error(
"COULD NOT UPATE WIND Y BRACKET: BOUNDS EXCEEDED?")
6526 wstry = ftm%NEXT_WGHT * vnp + ftm%PREV_WGHT * vpp
6528 CASE(winds_are_fvcomgrid)
6530 ftm => winds_file%FTIME
6534 IF (status /= 0)
THEN 6535 CALL fatal_error(
"COULD NOT UPATE WIND X BRACKET: BOUNDS EXCEEDED?")
6540 wstrx = ftm%NEXT_WGHT * vnp + ftm%PREV_WGHT * vpp
6544 IF (status /= 0)
THEN 6545 CALL fatal_error(
"COULD NOT UPATE WIND Y BRACKET: BOUNDS EXCEEDED?")
6550 wstry = ftm%NEXT_WGHT * vnp + ftm%PREV_WGHT * vpp
6553 CASE(winds_are_pt_source)
6555 ftm => winds_file%FTIME
6559 IF (status /= 0)
THEN 6560 CALL fatal_error(
"COULD NOT UPATE WIND X BRACKET: BOUNDS EXCEEDED?")
6565 wstrx(1:nt) = ftm%NEXT_WGHT * vnp(1) + ftm%PREV_WGHT * vpp(1)
6569 IF (status /= 0)
THEN 6570 CALL fatal_error(
"COULD NOT UPATE WIND Y BRACKET: BOUNDS EXCEEDED?")
6575 wstry(1:nt) = ftm%NEXT_WGHT * vnp(1) + ftm%PREV_WGHT * vpp(1)
6579 CALL fatal_error(
"UNKNOWN WINDS_FORCING_TYPE IN UPDATE WIND")
6594 TYPE(
time),
INTENT(IN) :: now
6597 REAL(sp),
POINTER :: vnp(:), vpp(:)
6602 &(
"THE PRECIPITATION VARIABLE PASSED TO UPDATE IS NOT ALLOCATED")
6604 &(
"THE EVAPORATION VARIABLE PASSED TO UPDATE IS NOT ALLOCATED")
6607 SELECT CASE(precipitation_kind)
6611 qprec(1:mt) = precipitation_prc
6612 qevap(1:mt) = precipitation_evp
6622 CALL fatal_error(
"TIME DEPENDANT PRECIP Not Set Up Yet")
6633 ptime =
mod(ptime,precip_period)
6646 SELECT CASE(precip_forcing_type)
6648 CASE(precip_is_wrfgrid)
6650 ftm => precip_file%FTIME
6653 CALL update_var_bracket(precip_file,precip_pre_p,precip_pre_n,ptime,status,precip_intp_n)
6654 IF (status /= 0)
THEN 6655 CALL fatal_error(
"COULD NOT UPATE PRECIP BRACKET: BOUNDS EXCEEDED?")
6660 qprec = ftm%NEXT_WGHT * vnp + ftm%PREV_WGHT * vpp
6663 CALL update_var_bracket(precip_file,precip_evp_p,precip_evp_n,ptime,status,precip_intp_n)
6664 IF (status /= 0)
THEN 6665 CALL fatal_error(
"COULD NOT UPATE EVAP BRACKET: BOUNDS EXCEEDED?")
6670 qevap = ftm%NEXT_WGHT * vnp + ftm%PREV_WGHT * vpp
6672 CASE(precip_is_fvcomgrid)
6675 ftm => precip_file%FTIME
6679 IF (status /= 0)
THEN 6680 CALL fatal_error(
"COULD NOT UPATE PRECIP BRACKET: BOUNDS EXCEEDED?")
6685 qprec = ftm%NEXT_WGHT * vnp + ftm%PREV_WGHT * vpp
6689 IF (status /= 0)
THEN 6690 CALL fatal_error(
"COULD NOT UPATE EVAP BRACKET: BOUNDS EXCEEDED?")
6695 qevap = ftm%NEXT_WGHT * vnp + ftm%PREV_WGHT * vpp
6698 CALL fatal_error(
"UNKNOWN WINDS_FORCING_TYPE IN UPDATE PRECIPITATION")
6707 SUBROUTINE update_wave(NOW,WHS,WDIR,WPER,WLENGTH,WPER_BOT,WUB_BOT)
6709 TYPE(
time),
INTENT(IN) :: now
6712 REAL(sp),
POINTER :: vnp(:), vpp(:)
6716 REAL :: x1,x2,y1,y2,x0,y0,angle
6719 real:: a2, k2,h2,
t2,ub2,w2
6722 &(
"THE WAVE HEIGHT VARIABLE PASSED TO UPDATE IS NOT ALLOCATED")
6724 &(
"THE WAVE DIRECTION VARIABLE PASSED TO UPDATE IS NOT ALLOCATED")
6726 &(
"THE WAVE PERIOD VARIABLE PASSED TO UPDATE IS NOT ALLOCATED")
6728 &(
"THE WAVE LENGTH VARIABLE PASSED TO UPDATE IS NOT ALLOCATED")
6730 &(
"THE BOTTOM WAVE PERIOD VARIABLE PASSED TO UPDATE IS NOT ALLOCATED")
6732 &(
"THE BOTTOM WAVE ORBITAL VELOCITY VARIABLE PASSED TO UPDATE IS NOT ALLOCATED")
6735 SELECT CASE(wave_kind)
6739 whs(1:mt) = wave_height
6740 wdir(1:mt) = wave_direction
6741 wper(1:mt) = wave_period
6754 CALL fatal_error(
"TIME DEPENDANT PRECIP Not Set Up Yet")
6765 ptime =
mod(ptime,precip_period)
6778 SELECT CASE(waves_forcing_type)
6780 CASE(waves_are_wrfgrid)
6783 CASE(waves_are_fvcomgrid)
6786 ftm => waves_file%FTIME
6790 IF (status /= 0)
THEN 6791 CALL fatal_error(
"COULD NOT UPATE WAVE HEIGHT BRACKET: BOUNDS EXCEEDED?")
6796 whs = ftm%NEXT_WGHT * vnp + ftm%PREV_WGHT * vpp
6800 IF (status /= 0)
THEN 6801 CALL fatal_error(
"COULD NOT UPATE WAVE DIRECTION BRACKET: BOUNDS EXCEEDED?")
6806 wdir = ftm%NEXT_WGHT * vnp + ftm%PREV_WGHT * vpp
6809 x1 = cos(vnp(i)*3.1415926/180.0)
6810 x2 = cos(vpp(i)*3.1415926/180.0)
6811 y1 = sin(vnp(i)*3.1415926/180.0)
6812 y2 = sin(vpp(i)*3.1415926/180.0)
6813 x0 = ftm%NEXT_WGHT * x1 + ftm%PREV_WGHT * x2
6814 y0 = ftm%NEXT_WGHT * y1 + ftm%PREV_WGHT * y2
6815 angle = atan2(y0,x0)
6816 IF(angle<0)angle = angle + 3.1415926*2.0
6817 wdir(i) = angle*180.0/3.1415926
6823 IF (status /= 0)
THEN 6824 CALL fatal_error(
"COULD NOT UPATE WAVE LENGTH BRACKET: BOUNDS EXCEEDED?")
6829 wlength = ftm%NEXT_WGHT * vnp + ftm%PREV_WGHT * vpp
6834 IF (status /= 0)
THEN 6835 CALL fatal_error(
"COULD NOT UPATE WAVE PERIOD BRACKET: BOUNDS EXCEEDED?")
6840 wper = ftm%NEXT_WGHT * vnp + ftm%PREV_WGHT * vpp
6845 IF (status /= 0)
THEN 6846 CALL fatal_error(
"COULD NOT UPATE BOTTOM WAVE PERIOD BRACKET: BOUNDS EXCEEDED?")
6851 wper_bot = ftm%NEXT_WGHT * vnp + ftm%PREV_WGHT * vpp
6856 IF (status /= 0)
THEN 6857 CALL fatal_error(
"COULD NOT UPATE BOTTOM ORBITAL VELOCITY BRACKET: BOUNDS EXCEEDED?")
6862 wub_bot = ftm%NEXT_WGHT * vnp + ftm%PREV_WGHT * vpp
6877 CALL fatal_error(
"UNKNOWN WAVES_FORCING_TYPE IN UPDATE WAVE")
6890 TYPE(
time),
INTENT(IN) :: now
6892 REAL(sp),
ALLOCATABLE :: pa_air(:)
6893 REAL(sp),
POINTER :: vnp(:), vpp(:)
6898 &(
"THE AIR PRESSURE VARIABLE PASSED TO UPDATE IS NOT ALLOCATED")
6901 SELECT CASE(airpressure_kind)
6905 pa_air(1:mt) = airpressure_value
6911 CALL fatal_error(
"STATIC AIR PRESSURE Not Set Up Yet")
6915 CALL fatal_error(
"TIME DEPENDANT AIR PRESSURE Not Set Up Yet")
6926 atime =
mod(atime,airpressure_period)
6939 SELECT CASE(airpressure_forcing_type)
6941 CASE(airpressure_is_wrfgrid)
6943 ftm => airpressure_p_file%FTIME
6946 CALL update_var_bracket(airpressure_p_file,air_pressure_p,air_pressure_n,atime,status,airpressure_intp_n)
6947 IF (status /= 0)
THEN 6948 CALL fatal_error(
"COULD NOT UPATE AIR PRESSURE BRACKET: BOUNDS EXCEEDED?")
6953 pa_air = ftm%NEXT_WGHT * vnp + ftm%PREV_WGHT * vpp
6956 CASE(airpressure_is_fvcomgrid)
6959 ftm => airpressure_p_file%FTIME
6962 CALL update_var_bracket(airpressure_p_file,air_pressure_p,air_pressure_n,atime,status)
6963 IF (status /= 0)
THEN 6964 CALL fatal_error(
"COULD NOT UPATE AIR PRESSURE BRACKET: BOUNDS EXCEEDED?")
6969 pa_air = ftm%NEXT_WGHT * vnp + ftm%PREV_WGHT * vpp
6972 CALL fatal_error(
"UNKNOWN AIRPRESSURE_FORCING_TYPE IN UPDATE AIR PRESSURE")
6980 TYPE(
time),
INTENT(IN) :: now
6981 REAL(sp),
ALLOCATABLE :: bnd_elv(:)
6982 REAL(sp),
POINTER :: vnp(:), vpp(:)
6987 &(
"THE BOUNDARY ELEVATION VARIABLE PASSED TO UPDATE IS NOT ALLOCATED")
6993 ftm => tide_file%FTIME
6997 IF (status /= 0)
THEN 6998 CALL fatal_error(
"COULD NOT UPATE TIDE ELVATION BRACKET: BOUNDS EXCEEDED?")
7003 bnd_elv = ftm%NEXT_WGHT * vnp + ftm%PREV_WGHT * vpp
7006 CALL fatal_error(
"UNKNOWN TIDAL FORCING FILE TYPE IN UPDATE_TIDE")
7014 TYPE(
time),
INTENT(IN) :: now
7015 REAL(sp),
ALLOCATABLE :: salt(:,:)
7016 REAL(sp),
POINTER :: vnp(:,:), vpp(:,:)
7021 &(
"THE BOUNDARY SALINITY VARIABLE PASSED TO UPDATE IS NOT ALLOCATED")
7023 SELECT CASE(obc_s_type)
7026 ftm => obc_s_file%FTIME
7030 IF (status /= 0)
THEN 7031 CALL fatal_error(
"COULD NOT UPATE OBC SALINITY BRACKET: BOUNDS EXCEEDED?")
7036 salt = ftm%NEXT_WGHT * vnp + ftm%PREV_WGHT * vpp
7039 CALL fatal_error(
"UNKNOWN OBC SALINITY FILE TYPE IN UPDATE_OBC_SALT")
7047 TYPE(
time),
INTENT(IN) :: now
7048 REAL(sp),
ALLOCATABLE :: temp(:,:)
7049 REAL(sp),
POINTER :: vnp(:,:), vpp(:,:)
7054 &(
"THE BOUNDARY TEMPERATURE VARIABLE PASSED TO UPDATE IS NOT ALLOCATED")
7056 SELECT CASE(obc_t_type)
7059 ftm => obc_t_file%FTIME
7063 IF (status /= 0)
THEN 7064 CALL fatal_error(
"COULD NOT UPATE OBC TEMPERATURE BRACKET: BOUNDS EXCEEDED?")
7069 temp = ftm%NEXT_WGHT * vnp + ftm%PREV_WGHT * vpp
7072 CALL fatal_error(
"UNKNOWN OBC TEMPERATURE FILE TYPE IN UPDATE_OBC_TEMP")
7083 TYPE(
time),
INTENT(IN) :: now
7085 REAL(sp),
ALLOCATABLE :: sat(:)
7086 REAL(sp),
ALLOCATABLE :: swv(:)
7087 REAL(sp),
ALLOCATABLE :: slp(:)
7088 REAL(sp),
ALLOCATABLE :: spq(:)
7089 REAL(sp),
ALLOCATABLE :: cld(:)
7090 REAL(sp),
POINTER :: vnp(:), vpp(:)
7095 &(
"THE Sea Surface Air Temperature VARIABLE PASSED TO UPDATE ICE IS NOT ALLOCATED")
7097 &(
"THE SHORTWAVE RADIATION VARIABLE PASSED TO UPDATE ICE IS NOT ALLOCATED")
7099 &(
"THE SPECIFIC HUMIDIY VARIABLE PASSED TO UPDATE ICE IS NOT ALLOCATED")
7101 &(
"THE CLOUD COVER VARIABLE PASSED TO UPDATE ICE IS NOT ALLOCATED")
7104 SELECT CASE(ice_forcing_kind)
7108 sat(1:mt) = ice_air_temp
7109 spq(1:mt) = ice_spec_humidity
7110 cld(1:mt) = ice_cloud_cover
7111 swv(1:mt) = ice_shortwave
7117 CALL fatal_error(
"STATIC ICE FORCING Not Set Up Yet")
7121 CALL fatal_error(
"TIME DEPENDANT ICE FORCING Not Set Up Yet")
7132 wtime =
mod(wtime,ice_period)
7140 SELECT CASE(ice_forcing_type)
7142 CASE(ice_is_wrfgrid)
7145 ftm => ice_file%FTIME
7149 IF (status /= 0)
THEN 7150 CALL fatal_error(
"COULD NOT UPATE ICE Surface Air Temp BRACKET: BOUNDS EXCEEDED?")
7155 sat = ftm%NEXT_WGHT * vnp + ftm%PREV_WGHT * vpp
7160 IF (status /= 0)
THEN 7161 CALL fatal_error(
"COULD NOT UPDATE ICE SHORTWAVE BRACKET: BOUNDS EXCEEDED?")
7166 swv = ftm%NEXT_WGHT * vnp + ftm%PREV_WGHT * vpp
7170 IF (status /= 0)
THEN 7171 CALL fatal_error(
"COULD NOT UPATE ICE SPECIFIC HUMIDITY BRACKET: BOUNDS EXCEEDED?")
7176 spq = ftm%NEXT_WGHT * vnp + ftm%PREV_WGHT * vpp
7181 IF (status /= 0)
THEN 7182 CALL fatal_error(
"COULD NOT UPATE ICE CLOUD COVER BRACKET: BOUNDS EXCEEDED?")
7187 cld = ftm%NEXT_WGHT * vnp + ftm%PREV_WGHT * vpp
7193 CASE(ice_is_fvcomgrid)
7196 ftm => ice_file%FTIME
7201 IF (status /= 0)
THEN 7202 CALL fatal_error(
"COULD NOT UPATE ICE Surface Air Temp BRACKET: BOUNDS EXCEEDED?")
7207 sat = ftm%NEXT_WGHT * vnp + ftm%PREV_WGHT * vpp
7212 IF (status /= 0)
THEN 7213 CALL fatal_error(
"COULD NOT UPDATE ICE SHORTWAVE BRACKET: BOUNDS EXCEEDED?")
7218 swv = ftm%NEXT_WGHT * vnp + ftm%PREV_WGHT * vpp
7223 IF (status /= 0)
THEN 7224 CALL fatal_error(
"COULD NOT UPATE ICE SPECIFIC HUMIDITY BRACKET: BOUNDS EXCEEDED?")
7229 spq = ftm%NEXT_WGHT * vnp + ftm%PREV_WGHT * vpp
7234 IF (status /= 0)
THEN 7235 CALL fatal_error(
"COULD NOT UPATE ICE CLOUD COVER BRACKET: BOUNDS EXCEEDED?")
7240 cld = ftm%NEXT_WGHT * vnp + ftm%PREV_WGHT * vpp
7244 CALL fatal_error(
"UNKNOWN ICING_FORCING_TYPE IN UPDATE ICING")
7253 TYPE(
time),
INTENT(IN) :: now
7255 REAL(sp),
ALLOCATABLE :: sat(:)
7256 REAL(sp),
ALLOCATABLE :: wspdx(:)
7257 REAL(sp),
ALLOCATABLE :: wspdy(:)
7258 REAL(sp),
POINTER :: vnp(:), vpp(:)
7261 REAL(sp),
PARAMETER :: k2c = 273.15_sp
7264 &(
"THE Sea Surface Air Temperature VARIABLE PASSED TO UPDATE IS NOT ALLOCATED")
7265 IF(.NOT.
ALLOCATED(wspdx) .or. .NOT.
ALLOCATED(wspdy))
CALL fatal_error &
7266 &(
"THE WIND SPEED VARIABLES PASSED TO UPDATE ARE NOT ALLOCATED")
7269 SELECT CASE(icing_forcing_kind)
7273 wspdx(1:mt) = icing_wspd
7278 sat(1:mt) = icing_air_temp
7288 CALL fatal_error(
"TIME DEPENDANT ICING Not Set Up Yet")
7299 wtime =
mod(wtime,icing_period)
7308 SELECT CASE(icing_forcing_type)
7310 CASE(icing_is_wrfgrid)
7313 ftm => icing_file%FTIME
7316 CALL update_var_bracket(icing_file,icing_wspx_p,icing_wspx_n,wtime,status,icing_intp_n)
7317 IF (status /= 0)
THEN 7318 CALL fatal_error(
"COULD NOT UPATE WIND SPEED X BRACKET: BOUNDS EXCEEDED?")
7324 wspdx = ftm%NEXT_WGHT * vnp + ftm%PREV_WGHT * vpp
7327 CALL update_var_bracket(icing_file,icing_wspy_p,icing_wspy_n,wtime,status,icing_intp_n)
7328 IF (status /= 0)
THEN 7329 CALL fatal_error(
"COULD NOT UPATE WIND SPEED Y BRACKET: BOUNDS EXCEEDED?")
7335 wspdy = ftm%NEXT_WGHT * vnp + ftm%PREV_WGHT * vpp
7342 CALL update_var_bracket(icing_file,icing_sat_p,icing_sat_n,wtime,status,icing_intp_n)
7343 IF (status /= 0)
THEN 7344 CALL fatal_error(
"COULD NOT UPATE Surface Air Temp BRACKET: BOUNDS EXCEEDED?")
7349 sat = ftm%NEXT_WGHT * vnp + ftm%PREV_WGHT * vpp - k2c
7352 CASE(icing_is_fvcomgrid)
7354 ftm => icing_file%FTIME
7358 IF (status /= 0)
THEN 7359 CALL fatal_error(
"COULD NOT UPATE WIND SPEED X BRACKET: BOUNDS EXCEEDED?")
7365 wspdx = ftm%NEXT_WGHT * vnp + ftm%PREV_WGHT * vpp
7369 IF (status /= 0)
THEN 7370 CALL fatal_error(
"COULD NOT UPATE WIND SPEED Y BRACKET: BOUNDS EXCEEDED?")
7376 wspdy = ftm%NEXT_WGHT * vnp + ftm%PREV_WGHT * vpp
7384 IF (status /= 0)
THEN 7385 CALL fatal_error(
"COULD NOT UPATE Surface Air Temp BRACKET: BOUNDS EXCEEDED?")
7390 sat = ftm%NEXT_WGHT * vnp + ftm%PREV_WGHT * vpp -k2c
7394 CALL fatal_error(
"UNKNOWN ICING_FORCING_TYPE IN UPDATE ICING")
7409 SUBROUTINE gday2(IDD,IMM,IYY,ICC,KD)
7428 integer idd, imm, iyy, icc, kd
7431 data ndp/0,31,59,90,120,151,181,212,243,273,304,334,365/
7432 data ndm/31,28,31,30,31,30,31,31,30,31,30,31/
7439 if(iyy.lt.0.or.iyy.gt.99)
then 7443 if(imm.le.0.or.imm.gt.12)
then 7451 if(imm.ne.2.and.idd.gt.ndm(imm))
then 7455 if(imm.eq.2.and.idd.gt.29)
then 7459 if(imm.eq.2.and.idd.gt.28.and.((iyy/4)*4-iyy.ne.0.or.(iyy.eq.0.and.(icc/4)*4-icc.ne.0)))
then 7463 5000
format(
' input error. icc = ',i7)
7464 5010
format(
' input error. iyy = ',i7)
7465 5020
format(
' input error. imm = ',i7)
7466 5030
format(
' input error. idd = ',i7)
7469 kd = icc*36524 + (icc+3)/4
7472 kd = kd + iyy*365 + (iyy+3)/4
7477 if(iyy.gt.0.and.(icc-(icc/4)*4).ne.0) kd=kd-1
7484 if(imm.gt.2.and.((iyy/4)*4-iyy).eq.0.and.((iyy.ne.0).or.(((icc/4)*4-icc).eq.0))) kd=kd+1
7492 END SUBROUTINE gday2
integer, dimension(:), allocatable, target ntsn
subroutine, public update_ice(NOW, SAT, SWV, SPQ, CLD)
real(sp), dimension(:), allocatable, target qprec
real(sp), dimension(:,:), allocatable, target t2
real(sp), dimension(:), allocatable, target h
subroutine, public update_airpressure(NOW, PA_AIR)
integer, dimension(:), pointer elid
character(len=char_max_attlen), dimension(:), allocatable, public precip_forcing_comments
character(len=80), parameter, public fvcom_cap_grid_source
real(sp), dimension(:), allocatable emean
integer, parameter dbg_scl
real(sp), dimension(:), allocatable, target el
real(sp), dimension(:,:), allocatable, target vqdist
real(sp), dimension(:), allocatable, target wper
real(sp), dimension(:), allocatable, target wub_bot
character(len=80), dimension(:), allocatable tide_type
logical function dbg_set(vrb)
subroutine get_value(LNUM, NUMCHAR, TEXT_LINE, VARNAME, VARTYPE, LOGVAL, STRINGVAL, REALVAL, INTVAL, NVAL)
real(sp), dimension(:), allocatable, target qdis2
character(len=80), parameter, public surf_forcing_pt_source
subroutine, public update_wave(NOW, WHS, WDIR, WPER, WLENGTH, WPER_BOT, WUB_BOT)
real(sp), dimension(:), allocatable, target art1
real(sp), dimension(:), allocatable, target qdis
real(sp), dimension(:), allocatable, target yc
integer, public tide_forcing_type
subroutine, public update_obc_temp(NOW, TEMP)
subroutine print_real_time(mjd, IPT, char, TZONE)
integer, parameter, public tide_forcing_timeseries
subroutine, public update_icing(NOW, SAT, WSPDX, WSPDY)
subroutine print_file(NCF)
real(sp), dimension(:,:), allocatable apt
real(sp), dimension(:), allocatable, target angleq
real(sp), dimension(:), allocatable, target wlength
subroutine, public update_obc_salt(NOW, SALT)
character(len=char_max_attlen), dimension(:), allocatable, public airpressure_forcing_comments
real(sp), dimension(:), allocatable, target sdis
integer, parameter, public tide_forcing_spectral
integer, dimension(:), pointer nlid
integer, dimension(:), allocatable, target riv_gl2loc
real(sp), dimension(:), allocatable, target el1
real(sp), dimension(:), allocatable beta_eqi
real(sp), dimension(:), allocatable period
real(sp), dimension(:,:), allocatable, target rdisq
real(sp), dimension(:), allocatable, target wdir
real(sp), dimension(:), allocatable, target vx
character(len=char_max_attlen), dimension(:), allocatable, public gwater_forcing_comments
character(len=char_max_attlen), dimension(:), allocatable, public heat_calculate_comments
real(sp), dimension(:), allocatable, target wper_bot
character(len=80), parameter, public wrf_grid_source
subroutine, public setup_forcing
real(sp), dimension(:), allocatable, target vy
subroutine, public update_groundwater(NOW, GW_FLUX, GW_TEMP, GW_SALT)
subroutine, public update_tide(NOW, BND_ELV)
type(time) function read_datetime(timestr, frmt, TZONE, status)
integer, dimension(:,:), allocatable, target nbe
integer, dimension(:), allocatable i_obc_n
integer, parameter dbg_sbrio
subroutine warning(ER1, ER2, ER3, ER4)
character(len=char_max_attlen), dimension(:), allocatable, public heat_forcing_comments
integer, dimension(:,:), allocatable, target nv
character(len=char_max_attlen), dimension(:), allocatable, public icing_forcing_comments
character(len=char_max_attlen), public obc_s_comments
integer, dimension(:,:), allocatable, target n_icellq
real(sp), dimension(:,:), allocatable, target zz1
real(sp), dimension(:), allocatable, target qarea
character(len=80), parameter, public fvcom_grid_source
character(len=char_max_attlen), dimension(:), allocatable, public tide_forcing_comments
real(sp), dimension(:), allocatable apt_eqi
real(sp), dimension(:), allocatable, target qevap
subroutine, public update_precipitation(NOW, Qprec, Qevap)
character(len=char_max_attlen), dimension(:), allocatable, public winds_forcing_comments
real(sp), dimension(:,:), allocatable, target dz
character(len=char_max_attlen), public obc_t_comments
integer, dimension(:), allocatable, target icellq
subroutine, public update_wind(NOW, wstrx, wstry)
subroutine setup_interp_bilinear_p(Xin, Yin, Xout, Yout, WEIGHTS, land_mask)
subroutine fatal_error(ER1, ER2, ER3, ER4)
real(sp), dimension(:), allocatable, target h1
real(sp), dimension(:), allocatable, target xc
real(sp), dimension(:,:), allocatable phai
real(sp), dimension(:,:), allocatable, target dz1
real(sp), dimension(:), allocatable, target whs
character(len=char_max_attlen), dimension(:), allocatable, public ice_forcing_comments
integer, dimension(:), allocatable, target isbce
character(len=char_max_attlen), dimension(:), allocatable, public river_forcing_comments
character(len=80), parameter, public wrf2fvcom_source
subroutine, public update_rivers(NOW, FLUX, TEMP, SALT, WQM, SED, BIO)
integer, dimension(:,:), allocatable, target nbsn
type(ncvar) function, pointer reference_var(VARIN)
subroutine, public update_heat(NOW, HEAT_SWV, HEAT_NET)
integer, parameter dbg_io
real(sp), dimension(:), allocatable, target tdis
real(sp), dimension(:), allocatable, target vlctyq
integer, dimension(:), pointer ngid
integer, parameter dbg_sbr
character(len=char_max_attlen), dimension(:), allocatable, public waves_forcing_comments
integer, dimension(:), allocatable, target inodeq
integer, dimension(:), allocatable, target isonb
real(sp), dimension(:,:), allocatable, target zz
integer, dimension(:), pointer egid
character(len=char_max_attlen), dimension(:), allocatable, public heat_solar_comments
subroutine print_time(mjd, IPT, char)
integer, parameter dbg_log