!/===========================================================================/ ! Copyright (c) 2007, The University of Massachusetts Dartmouth ! Produced at the School of Marine Science & Technology ! Marine Ecosystem Dynamics Modeling group ! All rights reserved. ! ! FVCOM has been developed by the joint UMASSD-WHOI research team. For ! details of authorship and attribution of credit please see the FVCOM ! technical manual or contact the MEDM group. ! ! ! This file is part of FVCOM. For details, see http://fvcom.smast.umassd.edu ! The full copyright notice is contained in the file COPYRIGHT located in the ! root directory of the FVCOM code. This original header must be maintained ! in all distributed versions. ! ! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" ! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, ! THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR ! PURPOSE ARE DISCLAIMED. ! !/---------------------------------------------------------------------------/ ! CVS VERSION INFORMATION ! $Id$ ! $Name$ ! $Revision$ !/===========================================================================/ MODULE MOD_FORCE USE ALL_VARS USE MOD_INTERP USE BCS USE MOD_TIME USE MOD_NCTOOLS USE MOD_NCLL USE MOD_UTILS USE MOD_SPHERICAL USE MOD_PAR USE MOD_INPUT # if defined (HEATING_CALCULATED) USE MOD_HEATFLUX # endif # if defined (HEATING_SOLAR) USE MOD_SOLAR # endif IMPLICIT NONE SAVE PRIVATE ! COMMON FILE TYPE SHARED BY SEVERAL TYPES OF FORCING ! CHARACTER(LEN=80),PUBLIC, PARAMETER :: WRF2FVCOM_SOURCE = & ! & "wrf2fvcom version 0.14 (2007-07-19) (Bulk method: COARE 2.6Z)" CHARACTER(LEN=80),PUBLIC, PARAMETER :: WRF2FVCOM_SOURCE = & & "wrf2fvcom version" CHARACTER(LEN=80),PUBLIC, PARAMETER :: fvcom_grid_SOURCE = & & "fvcom grid (unstructured) surface forcing" CHARACTER(LEN=80),PUBLIC, PARAMETER :: fvcom_cap_grid_SOURCE = & & "FVCOM grid (unstructured) surface forcing" CHARACTER(LEN=80),PUBLIC, PARAMETER :: wrf_grid_SOURCE = & & "wrf grid (structured) surface forcing" CHARACTER(LEN=80),PUBLIC, PARAMETER :: surf_forcing_pt_SOURCE = & & "single-point time-dependent surface forcing" ! TIDAL FORCING VARIABLES FOR UPDATE AND SETUP INTEGER, PUBLIC :: TIDE_FORCING_TYPE INTEGER, PARAMETER, PUBLIC :: TIDE_FORCING_SPECTRAL = 1 INTEGER, PARAMETER, PUBLIC :: TIDE_FORCING_TIMESERIES = 2 TYPE(NCFILE), POINTER :: TIDE_FILE TYPE(NCVAR), POINTER :: TIDE_ELV_N, TIDE_ELV_P CHARACTER(LEN=Char_max_attlen), PUBLIC,ALLOCATABLE :: TIDE_FORCING_COMMENTS(:) ! RIVER FORCING VARIABLES FOR UPDATE AND SETUP ! NOTE RIVERS ARE A PAIN - EACH PROCESSOR HAS TO FETCH ITS OWN DATA! CHARACTER(LEN=Char_max_attlen), PUBLIC,ALLOCATABLE :: RIVER_FORCING_COMMENTS(:) TYPE A_RIVER_FILE TYPE(NCFILE), POINTER :: NCF INTEGER RIVERS_IN_FILE TYPE(TIME) :: RIVER_PERIOD INTEGER, ALLOCATABLE :: RIV_FILE2LOC(:) ! USAGE : DO I = 1, RIVERS_IN_FILE ! J = RIV_FILE2LOC(I) ! IF (J/=0) QDIS(J) = FILE_DIS(I) TYPE(NCVAR), POINTER :: FLUX_N, FLUX_P TYPE(NCVAR), POINTER :: TEMP_N, TEMP_P TYPE(NCVAR), POINTER :: SALT_N, SALT_P # if defined (WATER_QUALITY) TYPE(NCVAR), POINTER :: WQM1_N, WQM1_P TYPE(NCVAR), POINTER :: WQM2_N, WQM2_P TYPE(NCVAR), POINTER :: WQM3_N, WQM3_P TYPE(NCVAR), POINTER :: WQM4_N, WQM4_P TYPE(NCVAR), POINTER :: WQM5_N, WQM5_P TYPE(NCVAR), POINTER :: WQM6_N, WQM6_P TYPE(NCVAR), POINTER :: WQM7_N, WQM7_P TYPE(NCVAR), POINTER :: WQM8_N, WQM8_P # endif # if defined (SEDIMENT) TYPE(NCVAR), POINTER :: SED1_N,SED1_P TYPE(NCVAR), POINTER :: SED2_N,SED2_P TYPE(NCVAR), POINTER :: SED3_N,SED3_P TYPE(NCVAR), POINTER :: SED4_N,SED4_P TYPE(NCVAR), POINTER :: SED5_N,SED5_P TYPE(NCVAR), POINTER :: SED6_N,SED6_P TYPE(NCVAR), POINTER :: SED7_N,SED7_P TYPE(NCVAR), POINTER :: SED8_N,SED8_P TYPE(NCVAR), POINTER :: SED9_N,SED9_P TYPE(NCVAR), POINTER :: SED10_N,SED10_P # endif # if defined (BioGen) TYPE(NCVAR), POINTER :: BIO1_N,BIO1_P TYPE(NCVAR), POINTER :: BIO2_N,BIO2_P TYPE(NCVAR), POINTER :: BIO3_N,BIO3_P TYPE(NCVAR), POINTER :: BIO4_N,BIO4_P TYPE(NCVAR), POINTER :: BIO5_N,BIO5_P TYPE(NCVAR), POINTER :: BIO6_N,BIO6_P TYPE(NCVAR), POINTER :: BIO7_N,BIO7_P TYPE(NCVAR), POINTER :: BIO8_N,BIO8_P TYPE(NCVAR), POINTER :: BIO9_N,BIO9_P TYPE(NCVAR), POINTER :: BIO10_N,BIO10_P TYPE(NCVAR), POINTER :: BIO11_N,BIO11_P TYPE(NCVAR), POINTER :: BIO12_N,BIO12_P TYPE(NCVAR), POINTER :: BIO13_N,BIO13_P TYPE(NCVAR), POINTER :: BIO14_N,BIO14_P TYPE(NCVAR), POINTER :: BIO15_N,BIO15_P TYPE(NCVAR), POINTER :: BIO16_N,BIO16_P TYPE(NCVAR), POINTER :: BIO17_N,BIO17_P TYPE(NCVAR), POINTER :: BIO18_N,BIO18_P TYPE(NCVAR), POINTER :: BIO19_N,BIO19_P TYPE(NCVAR), POINTER :: BIO20_N,BIO20_P # endif ! ADD MORE HERE! END TYPE A_RIVER_FILE TYPE(A_RIVER_FILE), ALLOCATABLE :: RIVER_FORCING(:) ! ================================================================= ! GROUND WATER FORCING VARIABLES FOR UPDATE AND SETUP TYPE(NCFILE), POINTER :: GWATER_FILE INTEGER :: GWATER_FORCING_TYPE INTEGER,PARAMETER :: GWATER_IS_XXX = 0 INTEGER,PARAMETER :: GWATER_IS_FVCOMGRID = 1 INTEGER :: GWATER_UNITS INTEGER, PARAMETER :: GWATER_M3S_1=1 INTEGER, PARAMETER :: GWATER_MS_1=2 TYPE(TIME) :: GWATER_PERIOD CHARACTER(LEN=Char_max_attlen), PUBLIC, ALLOCATABLE :: GWATER_FORCING_COMMENTS(:) TYPE(INTERP_WEIGHTS),POINTER :: GWATER_INTP_N TYPE(INTERP_WEIGHTS),POINTER :: GWATER_INTP_C TYPE(NCVAR), POINTER :: GWATER_FLUX_N, GWATER_FLUX_P ! Discharge TYPE(NCVAR), POINTER :: GWATER_TEMP_N, GWATER_TEMP_P ! Temperature TYPE(NCVAR), POINTER :: GWATER_SALT_N, GWATER_SALT_P ! Salinity ! ================================================================= ! OPEN BOUNDARY CONDITION SALINITY VARIABLES FOR UPDATE AND SETUP TYPE(NCFILE), POINTER :: OBC_S_FILE CHARACTER(LEN=Char_max_attlen), PUBLIC :: OBC_S_COMMENTS INTEGER :: OBC_S_TYPE INTEGER,PARAMETER :: OBC_S_SIGMA = 1 TYPE(NCVAR), POINTER :: OBC_S_N, OBC_S_P ! ================================================================= ! OPEN BOUNDARY CONDITION TEMPERATURE VARIABLES FOR UPDATE AND SETUP TYPE(NCFILE), POINTER :: OBC_T_FILE CHARACTER(LEN=Char_max_attlen), PUBLIC :: OBC_T_COMMENTS INTEGER :: OBC_T_TYPE INTEGER,PARAMETER :: OBC_T_SIGMA = 1 TYPE(NCVAR), POINTER :: OBC_T_N, OBC_T_P ! ================================================================= # if defined (WATER_QUALITY) ! OPEN BOUNDARY CONDITION WATER QUALITY VARIABLES FOR UPDATE AND SETUP TYPE(NCFILE), POINTER :: OBC_W_FILE CHARACTER(LEN=Char_max_attlen), PUBLIC :: OBC_W_COMMENTS INTEGER :: OBC_W_TYPE INTEGER,PARAMETER :: OBC_W_SIGMA = 1 TYPE(NCVAR), POINTER :: OBC_W_N1, OBC_W_P1 TYPE(NCVAR), POINTER :: OBC_W_N2, OBC_W_P2 TYPE(NCVAR), POINTER :: OBC_W_N3, OBC_W_P3 TYPE(NCVAR), POINTER :: OBC_W_N4, OBC_W_P4 TYPE(NCVAR), POINTER :: OBC_W_N5, OBC_W_P5 TYPE(NCVAR), POINTER :: OBC_W_N6, OBC_W_P6 TYPE(NCVAR), POINTER :: OBC_W_N7, OBC_W_P7 TYPE(NCVAR), POINTER :: OBC_W_N8, OBC_W_P8 # endif ! ================================================================= ! ================================================================= # if defined (BioGen) ! OPEN BOUNDARY CONDITION BIOLOGICAL VARIABLES FOR UPDATE AND SETUP TYPE(NCFILE), POINTER :: OBC_B_FILE CHARACTER(LEN=Char_max_attlen), PUBLIC :: OBC_B_COMMENTS INTEGER :: OBC_B_TYPE INTEGER,PARAMETER :: OBC_B_SIGMA = 1 TYPE(NCVAR), POINTER :: OBC_B_N1, OBC_B_P1 TYPE(NCVAR), POINTER :: OBC_B_N2, OBC_B_P2 TYPE(NCVAR), POINTER :: OBC_B_N3, OBC_B_P3 TYPE(NCVAR), POINTER :: OBC_B_N4, OBC_B_P4 TYPE(NCVAR), POINTER :: OBC_B_N5, OBC_B_P5 TYPE(NCVAR), POINTER :: OBC_B_N6, OBC_B_P6 TYPE(NCVAR), POINTER :: OBC_B_N7, OBC_B_P7 TYPE(NCVAR), POINTER :: OBC_B_N8, OBC_B_P8 TYPE(NCVAR), POINTER :: OBC_B_N9, OBC_B_P9 TYPE(NCVAR), POINTER :: OBC_B_N10, OBC_B_P10 TYPE(NCVAR), POINTER :: OBC_B_N11, OBC_B_P11 TYPE(NCVAR), POINTER :: OBC_B_N12, OBC_B_P12 TYPE(NCVAR), POINTER :: OBC_B_N13, OBC_B_P13 TYPE(NCVAR), POINTER :: OBC_B_N14, OBC_B_P14 TYPE(NCVAR), POINTER :: OBC_B_N15, OBC_B_P15 TYPE(NCVAR), POINTER :: OBC_B_N16, OBC_B_P16 TYPE(NCVAR), POINTER :: OBC_B_N17, OBC_B_P17 TYPE(NCVAR), POINTER :: OBC_B_N18, OBC_B_P18 TYPE(NCVAR), POINTER :: OBC_B_N19, OBC_B_P19 TYPE(NCVAR), POINTER :: OBC_B_N20, OBC_B_P20 # endif ! ================================================================= ! SURFACE HEAT FORCING FILE DATA INTEGER :: HEAT_FORCING_TYPE INTEGER,PARAMETER :: HEAT_IS_WRFGRID = 0 INTEGER,PARAMETER :: HEAT_IS_FVCOMGRID = 1 TYPE(TIME) :: HEAT_PERIOD TYPE(NCFILE), POINTER :: HEAT_FILE CHARACTER(LEN=Char_max_attlen), PUBLIC, ALLOCATABLE :: HEAT_FORCING_COMMENTS(:) CHARACTER(LEN=Char_max_attlen), PUBLIC, ALLOCATABLE :: HEAT_CALCULATE_COMMENTS(:) CHARACTER(LEN=Char_max_attlen), PUBLIC, ALLOCATABLE :: HEAT_SOLAR_COMMENTS(:) TYPE(INTERP_WEIGHTS),POINTER :: HEAT_INTP_N TYPE(INTERP_WEIGHTS),POINTER :: HEAT_INTP_C TYPE(NCVAR), POINTER :: HEAT_SWV_N, HEAT_SWV_P ! SHORT WAVE ! TYPE(NCVAR), POINTER :: HEAT_LWV_N, HEAT_LWV_P ! LONG WAVE ! TYPE(NCVAR), POINTER :: HEAT_LTNT_N, HEAT_LTNT_P ! LATENT ! TYPE(NCVAR), POINTER :: HEAT_SNS_N, HEAT_SNS_P ! SENSIBLE TYPE(NCVAR), POINTER :: HEAT_NET_N, HEAT_NET_P ! NET HEAT FLUX # if defined (HEATING_CALCULATED) TYPE(NCVAR), POINTER :: T_AIR_N, T_AIR_P TYPE(NCVAR), POINTER :: RH_AIR_N, RH_AIR_P TYPE(NCVAR), POINTER :: PA_AIR_N, PA_AIR_P TYPE(NCVAR), POINTER :: DLW_AIR_N, DLW_AIR_P TYPE(NCVAR), POINTER :: DSW_AIR_N, DSW_AIR_P # endif # if defined (HEATING_SOLAR) TYPE(NCVAR), POINTER :: T_AIR_N, T_AIR_P TYPE(NCVAR), POINTER :: TDEW_N, TDEW_P TYPE(NCVAR), POINTER :: CCOV_N, CCOV_P INTEGER :: JULDAY0 INTEGER,PARAMETER :: JULDAY_ADJUST = 678942 # endif ! ================================================================= ! SURFACE WIND STRESS FILE DATA INTEGER :: WINDS_FORCING_TYPE INTEGER, PARAMETER :: WINDS_ARE_WRFGRID = 0 INTEGER, PARAMETER :: WINDS_ARE_FVCOMGRID = 1 INTEGER, PARAMETER :: WINDS_ARE_PT_SOURCE = 2 TYPE(TIME) :: WINDS_PERIOD TYPE(NCFILE), POINTER :: WINDS_FILE CHARACTER(LEN=Char_max_attlen), PUBLIC, ALLOCATABLE :: WINDS_FORCING_COMMENTS(:) TYPE(INTERP_WEIGHTS),POINTER :: WINDS_INTP_N TYPE(INTERP_WEIGHTS),POINTER :: WINDS_INTP_C TYPE(NCVAR), POINTER :: WINDS_STRX_N, WINDS_STRX_P ! STRESS IN THE X DIRECTION TYPE(NCVAR), POINTER :: WINDS_STRY_N, WINDS_STRY_P ! STRESS IN THE Y DIRECTION # if defined (WAVE_CURRENT_INTERACTION) TYPE(INTERP_WEIGHTS),POINTER :: WINDW_INTP_N TYPE(INTERP_WEIGHTS),POINTER :: WINDW_INTP_C TYPE(NCVAR), POINTER :: WINDW_STRX_N, WINDW_STRX_P ! STRESS IN THE X DIRECTION (wave) TYPE(NCVAR), POINTER :: WINDW_STRY_N, WINDW_STRY_P ! STRESS IN THE Y DIRECTION (wave) # endif # if defined (WAVE_CURRENT_INTERACTION) && (WAVE_ONLY) ! ================================================================= ! SURFACE ICE FILE DATA FOR WAVE ONLY MODE INTEGER :: ICEINS_FORCING_TYPE INTEGER, PARAMETER :: ICEINS_ARE_WRFGRID = 0 INTEGER, PARAMETER :: ICEINS_ARE_FVCOMGRID = 1 INTEGER, PARAMETER :: ICEINS_ARE_PT_SOURCE = 2 TYPE(TIME) :: ICEINS_PERIOD TYPE(NCFILE), POINTER :: ICEINS_FILE CHARACTER(LEN=Char_max_attlen), PUBLIC, ALLOCATABLE :: ICEINS_FORCING_COMMENTS(:) TYPE(INTERP_WEIGHTS),POINTER :: ICEINS_INTP_N TYPE(INTERP_WEIGHTS),POINTER :: ICEINS_INTP_C TYPE(NCVAR), POINTER :: ICEINS_ICEC_N, ICEINS_ICEC_P # endif # if defined (OFFLINE_SEDIMENT) ! ================================================================= ! OFFLINE SEDIMENT FILE DATA INTEGER :: SEDIMENTS_FORCING_TYPE INTEGER, PARAMETER :: SEDIMENTS_ARE_WRFGRID = 0 INTEGER, PARAMETER :: SEDIMENTS_ARE_FVCOMGRID = 1 TYPE(TIME) :: SEDIMENTS_PERIOD TYPE(NCFILE), POINTER :: SEDIMENTS_FILE CHARACTER(LEN=Char_max_attlen), PUBLIC, ALLOCATABLE :: SEDIMENTS_FORCING_COMMENTS(:) TYPE(INTERP_WEIGHTS),POINTER :: SEDIMENTS_INTP_N TYPE(INTERP_WEIGHTS),POINTER :: SEDIMENTS_INTP_C TYPE(NCVAR), POINTER :: SEDIMENTS_U_N , SEDIMENTS_U_P ! U VELOCITY TYPE(NCVAR), POINTER :: SEDIMENTS_V_N , SEDIMENTS_V_P ! V VELOCITY TYPE(NCVAR), POINTER :: SEDIMENTS_W_N , SEDIMENTS_W_P ! W VELOCITY TYPE(NCVAR), POINTER :: SEDIMENTS_S1_N , SEDIMENTS_S1_P ! SALINITY TYPE(NCVAR), POINTER :: SEDIMENTS_T1_N , SEDIMENTS_T1_P ! TEMPERATURE TYPE(NCVAR), POINTER :: SEDIMENTS_EL_N , SEDIMENTS_EL_P ! EL TYPE(NCVAR), POINTER :: SEDIMENTS_KH_N , SEDIMENTS_KH_P ! KM # if defined (GOTM) TYPE(NCVAR), POINTER :: SEDIMENTS_TEPS_N , SEDIMENTS_TEPS_P ! TEPS # else TYPE(NCVAR), POINTER :: SEDIMENTS_Q2_N , SEDIMENTS_Q2_P ! q2 TYPE(NCVAR), POINTER :: SEDIMENTS_Q2L_N, SEDIMENTS_Q2L_P ! q2l # endif # if defined (WET_DRY) TYPE(NCVAR), POINTER :: SEDIMENTS_WN_N, SEDIMENTS_WN_P ! WET NODES TYPE(NCVAR), POINTER :: SEDIMENTS_WC_N, SEDIMENTS_WC_P ! WET CELLS # endif # endif # if defined (OFFLINE_BIOLOGY) ! ================================================================= ! OFFLINE BIOLOGY FILE DATA INTEGER :: BIOLOGY_FORCING_TYPE INTEGER, PARAMETER :: BIOLOGY_ARE_WRFGRID = 0 INTEGER, PARAMETER :: BIOLOGY_ARE_FVCOMGRID = 1 TYPE(TIME) :: BIOLOGY_PERIOD TYPE(NCFILE), POINTER :: BIOLOGY_FILE CHARACTER(LEN=Char_max_attlen), PUBLIC, ALLOCATABLE :: BIOLOGY_FORCING_COMMENTS(:) TYPE(INTERP_WEIGHTS),POINTER :: BIOLOGY_INTP_N TYPE(INTERP_WEIGHTS),POINTER :: BIOLOGY_INTP_C TYPE(NCVAR), POINTER :: BIOLOGY_U_N , BIOLOGY_U_P ! U VELOCITY TYPE(NCVAR), POINTER :: BIOLOGY_V_N , BIOLOGY_V_P ! V VELOCITY TYPE(NCVAR), POINTER :: BIOLOGY_W_N , BIOLOGY_W_P ! W VELOCITY TYPE(NCVAR), POINTER :: BIOLOGY_S1_N , BIOLOGY_S1_P ! SALINITY TYPE(NCVAR), POINTER :: BIOLOGY_T1_N , BIOLOGY_T1_P ! TEMPERATURE TYPE(NCVAR), POINTER :: BIOLOGY_EL_N , BIOLOGY_EL_P ! EL TYPE(NCVAR), POINTER :: BIOLOGY_KH_N , BIOLOGY_KH_P ! KM # if defined (GOTM) TYPE(NCVAR), POINTER :: BIOLOGY_TEPS_N , BIOLOGY_TEPS_P ! TEPS # else TYPE(NCVAR), POINTER :: BIOLOGY_Q2_N , BIOLOGY_Q2_P ! q2 TYPE(NCVAR), POINTER :: BIOLOGY_Q2L_N, BIOLOGY_Q2L_P ! q2l # endif # if defined (WET_DRY) TYPE(NCVAR), POINTER :: BIOLOGY_WN_N, BIOLOGY_WN_P ! WET NODES TYPE(NCVAR), POINTER :: BIOLOGY_WC_N, BIOLOGY_WC_P ! WET CELLS # endif # endif !Jadon ! ================================================================= ! SURFACE WAVE STRESS FILE DATA INTEGER :: WAVES_FORCING_TYPE INTEGER, PARAMETER :: WAVES_ARE_WRFGRID = 0 INTEGER, PARAMETER :: WAVES_ARE_FVCOMGRID = 1 TYPE(TIME) :: WAVES_PERIOD TYPE(NCFILE), POINTER :: WAVES_FILE CHARACTER(LEN=Char_max_attlen), PUBLIC, ALLOCATABLE :: WAVES_FORCING_COMMENTS(:) TYPE(INTERP_WEIGHTS),POINTER :: WAVES_INTP_N TYPE(INTERP_WEIGHTS),POINTER :: WAVES_INTP_C TYPE(NCVAR), POINTER :: WAVES_HEIGHT_N, WAVES_HEIGHT_P ! WAVE HEIGHT TYPE(NCVAR), POINTER :: WAVES_LENGTH_N, WAVES_LENGTH_P ! WAVE LENGTH TYPE(NCVAR), POINTER :: WAVES_DIRECTION_N, WAVES_DIRECTION_P ! WAVE DIRECTION TYPE(NCVAR), POINTER :: WAVES_PERIOD_N, WAVES_PERIOD_P ! WAVE PERIOD TYPE(NCVAR), POINTER :: WAVES_PER_BOT_N, WAVES_PER_BOT_P ! BOTTOM PERIOD TYPE(NCVAR), POINTER :: WAVES_UB_BOT_N, WAVES_UB_BOT_P ! BOTTOM VELOCITY ! ================================================================= ! SURFACE PRECIPTATION DATA INTEGER :: PRECIP_FORCING_TYPE INTEGER,PARAMETER :: PRECIP_IS_WRFGRID = 0 INTEGER,PARAMETER :: PRECIP_IS_FVCOMGRID = 1 TYPE(TIME) :: PRECIP_PERIOD TYPE(NCFILE), POINTER :: PRECIP_FILE CHARACTER(LEN=Char_max_attlen), PUBLIC, ALLOCATABLE:: PRECIP_FORCING_COMMENTS(:) TYPE(INTERP_WEIGHTS),POINTER :: PRECIP_INTP_N TYPE(INTERP_WEIGHTS),POINTER :: PRECIP_INTP_C TYPE(NCVAR), POINTER :: PRECIP_PRE_N, PRECIP_PRE_P ! PRECIPITATION TYPE(NCVAR), POINTER :: PRECIP_EVP_N, PRECIP_EVP_P ! EVAPORATION ! ================================================================= ! AIR PRESSURE FILE DATA INTEGER :: AIRPRESSURE_FORCING_TYPE INTEGER, PARAMETER :: AIRPRESSURE_IS_WRFGRID = 0 INTEGER, PARAMETER :: AIRPRESSURE_IS_FVCOMGRID = 1 TYPE(TIME) :: AIRPRESSURE_PERIOD TYPE(NCFILE), POINTER :: AIRPRESSURE_P_FILE CHARACTER(LEN=Char_max_attlen), PUBLIC, ALLOCATABLE :: AIRPRESSURE_FORCING_COMMENTS(:) TYPE(INTERP_WEIGHTS),POINTER :: AIRPRESSURE_INTP_N TYPE(INTERP_WEIGHTS),POINTER :: AIRPRESSURE_INTP_C TYPE(NCVAR), POINTER :: AIR_PRESSURE_N, AIR_PRESSURE_P ! ================================================================= ! ICE MODEL DATA INTEGER :: ICE_FORCING_TYPE INTEGER,PARAMETER :: ICE_IS_WRFGRID = 0 INTEGER,PARAMETER :: ICE_IS_FVCOMGRID = 1 TYPE(TIME) :: ICE_PERIOD TYPE(NCFILE), POINTER :: ICE_FILE CHARACTER(LEN=Char_max_attlen), PUBLIC, ALLOCATABLE:: ICE_FORCING_COMMENTS(:) TYPE(INTERP_WEIGHTS),POINTER :: ICE_INTP_N TYPE(INTERP_WEIGHTS),POINTER :: ICE_INTP_C TYPE(NCVAR), POINTER :: ICE_SWV_N, ICE_SWV_P ! SHORT WAVE TYPE(NCVAR), POINTER :: ICE_SAT_N, ICE_SAT_P ! SEA LEVEL AIR TEMPERATURE TYPE(NCVAR), POINTER :: ICE_SPQ_N, ICE_SPQ_P ! SPECFIC HUMIDITY TYPE(NCVAR), POINTER :: ICE_CLD_N, ICE_CLD_P ! CLOUD COVER ! ================================================================= ! ICING MODEL DATA INTEGER :: ICING_FORCING_TYPE INTEGER,PARAMETER :: ICING_IS_WRFGRID = 0 INTEGER,PARAMETER :: ICING_IS_FVCOMGRID = 1 TYPE(TIME) :: ICING_PERIOD TYPE(NCFILE), POINTER :: ICING_FILE CHARACTER(LEN=Char_max_attlen), PUBLIC, ALLOCATABLE:: ICING_FORCING_COMMENTS(:) TYPE(INTERP_WEIGHTS),POINTER :: ICING_INTP_N TYPE(INTERP_WEIGHTS),POINTER :: ICING_INTP_C TYPE(NCVAR), POINTER :: ICING_SAT_N, ICING_SAT_P ! SEA LEVEL AIR PRESSURE TYPE(NCVAR), POINTER :: ICING_WSPX_N, ICING_WSPX_P ! SEA LEVEL AIR TEMPERATURE TYPE(NCVAR), POINTER :: ICING_WSPY_N, ICING_WSPY_P ! SPECFIC HUMIDITY PUBLIC :: SETUP_FORCING PUBLIC :: UPDATE_GROUNDWATER # if !defined (HEATING_CALCULATED) && !defined (HEATING_SOLAR) PUBLIC :: UPDATE_HEAT # endif PUBLIC :: UPDATE_WIND PUBLIC :: UPDATE_WAVE # if defined (WAVE_CURRENT_INTERACTION) && (WAVE_ONLY) PUBLIC :: UPDATE_ICEIN # endif # if defined (HEATING_CALCULATED) PUBLIC :: UPDATE_HEAT_CALCULATED # endif # if defined (HEATING_SOLAR) PUBLIC :: UPDATE_HEAT_SOLAR # endif # if defined (OFFLINE_SEDIMENT) PUBLIC :: UPDATE_OFFLINE_FORCING # endif # if defined (OFFLINE_BIOLOGY) PUBLIC :: UPDATE_OFFLINE_BIOLOGY_FORCING # endif PUBLIC :: UPDATE_PRECIPITATION PUBLIC :: UPDATE_AIRPRESSURE PUBLIC :: UPDATE_TIDE PUBLIC :: UPDATE_RIVERS PUBLIC :: UPDATE_OBC_TEMP PUBLIC :: UPDATE_OBC_SALT # if defined (WATER_QUALITY) PUBLIC :: UPDATE_OBC_WQM # endif # if defined (BioGen) PUBLIC :: UPDATE_OBC_BIO # endif PUBLIC :: UPDATE_ICE PUBLIC :: UPDATE_ICING # if defined (WAVE_CURRENT_INTERACTION) PUBLIC :: SURFACE_WIND2WAVE PUBLIC :: UPDATE_WIND2WAVE # endif CONTAINS SUBROUTINE SETUP_FORCING IMPLICIT NONE IF(DBG_SET(DBG_SBR)) write(IPT,*) "START SETUP_FORCING" IF(DBG_SET(DBG_LOG)) THEN WRITE(IPT,* )'!' WRITE(IPT,* )'! SETTING UP PRESCRIBED BOUNDARY CONDITIONS ' WRITE(IPT,* )'!' END IF ! NULLIFY EVERYTHING NULLIFY(TIDE_FILE, TIDE_ELV_N, TIDE_ELV_P) NULLIFY(GWATER_FILE) # if !defined (HEATING_CALCULATED) && !defined (HEATING_SOLAR) NULLIFY(HEAT_FILE,HEAT_INTP_N, HEAT_INTP_C, HEAT_SWV_P,& & HEAT_SWV_N) # endif # if defined (HEATING_CALCULATED) NULLIFY(HEAT_FILE,HEAT_INTP_N, HEAT_INTP_C, T_AIR_P, T_AIR_N, & & RH_AIR_P, RH_AIR_N, PA_AIR_P, PA_AIR_N, DLW_AIR_P, & & DLW_AIR_N, DSW_AIR_P, DSW_AIR_N) # endif # if defined (HEATING_SOLAR) NULLIFY(HEAT_FILE,HEAT_INTP_N, HEAT_INTP_C, T_AIR_P, T_AIR_N, & & TDEW_P, TDEW_N, CCOV_P, CCOV_N) # endif NULLIFY(WINDS_FILE,WINDS_INTP_N,WINDS_INTP_C, WINDS_STRX_N,& & WINDS_STRX_P, WINDS_STRY_N, WINDS_STRY_P) NULLIFY(AIRPRESSURE_P_FILE,AIRPRESSURE_INTP_N,AIRPRESSURE_INTP_C, AIR_PRESSURE_N,& & AIR_PRESSURE_P) NULLIFY(WAVES_FILE,WAVES_INTP_N,WAVES_INTP_C, & & WAVES_HEIGHT_N, WAVES_HEIGHT_P, & & WAVES_LENGTH_N, WAVES_LENGTH_P, & & WAVES_DIRECTION_N, WAVES_DIRECTION_P, & & WAVES_PERIOD_N, WAVES_PERIOD_P, & & WAVES_PER_BOT_N, WAVES_PER_BOT_P, & & WAVES_UB_BOT_N, WAVES_UB_BOT_P ) # if defined (OFFLINE_SEDIMENT) NULLIFY(SEDIMENTS_FILE,SEDIMENTS_INTP_N,SEDIMENTS_INTP_C, & & SEDIMENTS_U_N, SEDIMENTS_U_P, & & SEDIMENTS_V_N, SEDIMENTS_V_P, & & SEDIMENTS_W_N, SEDIMENTS_W_P, & & SEDIMENTS_S1_N, SEDIMENTS_S1_P, & & SEDIMENTS_T1_N, SEDIMENTS_T1_P, & & SEDIMENTS_EL_N, SEDIMENTS_EL_P, & # if defined (WET_DRY) & SEDIMENTS_WN_N, SEDIMENTS_WN_P, & & SEDIMENTS_WC_N, SEDIMENTS_WC_P, & # endif # if defined (GOTM) & SEDIMENTS_TEPS_N, SEDIMENTS_TEPS_P, & # else & SEDIMENTS_Q2_N, SEDIMENTS_Q2_P, & & SEDIMENTS_Q2L_N, SEDIMENTS_Q2L_P, & # endif & SEDIMENTS_KH_N, SEDIMENTS_KH_P ) # endif # if defined (OFFLINE_BIOLOGY) NULLIFY(BIOLOGY_FILE,BIOLOGY_INTP_N,BIOLOGY_INTP_C, & & BIOLOGY_U_N, BIOLOGY_U_P, & & BIOLOGY_V_N, BIOLOGY_V_P, & & BIOLOGY_W_N, BIOLOGY_W_P, & & BIOLOGY_S1_N, BIOLOGY_S1_P, & & BIOLOGY_T1_N, BIOLOGY_T1_P, & & BIOLOGY_EL_N, BIOLOGY_EL_P, & # if defined (WET_DRY) & BIOLOGY_WN_N, BIOLOGY_WN_P, & & BIOLOGY_WC_N, BIOLOGY_WC_P, & # endif # if defined (GOTM) & BIOLOGY_TEPS_N, BIOLOGY_TEPS_P, & # else & BIOLOGY_Q2_N, BIOLOGY_Q2_P, & & BIOLOGY_Q2L_N, BIOLOGY_Q2L_P, & # endif & BIOLOGY_KH_N, BIOLOGY_KH_P ) # endif CALL TIDAL_ELEVATION CALL OBC_TEMPERATURE CALL OBC_SALINITY # if defined (WATER_QUALITY) CALL OBC_WQM # endif # if defined (BioGen) IF(BIOLOGICAL_MODEL)CALL OBC_BIO # endif CALL RIVER_DISCHARGE # if !defined (HEATING_CALCULATED) && !defined (HEATING_SOLAR) CALL SURFACE_HEATING # endif CALL SURFACE_WINDSTRESS CALL SURFACE_PRECIPITATION CALL SURFACE_AIRPRESSURE # if defined (WAVE_CURRENT_INTERACTION) && (WAVE_ONLY) CALL SURFACE_ICEIN # endif # if defined (HEATING_CALCULATED) CALL SURFACE_HEATING_CALCULATED # endif # if defined (HEATING_SOLAR) CALL SURFACE_HEATING_SOLAR # endif # if defined (OFFLINE_SEDIMENT) CALL OFFLINE_SEDIMENT_FORCING # endif # if defined (OFFLINE_BIOLOGY) CALL OFFLINE_BIOLOGY_FORCING # endif # if defined (WAVE_CURRENT_INTERACTION) && (WAVE_OFFLINE) CALL SURFACE_WAVE # endif CALL GROUND_WATER ! ORDER IS IMPORTANT! ICE AND ICING MAY USE THE SAME POINTERS TO ! REFERENCE FILE! THEY MUST BE SET UP LAST. CALL ICING_FORCING CALL ICE_MODEL_FORCING IF(DBG_SET(DBG_SBR)) write(IPT,*) "END SETUP_FORCING" END SUBROUTINE SETUP_FORCING !================================================================ !================================================================ SUBROUTINE GROUND_WATER IMPLICIT NONE ! SOME NC POINTERS TYPE(NCATT), POINTER :: ATT, ATT_DATE TYPE(NCDIM), POINTER :: DIM TYPE(NCVAR), POINTER :: VAR LOGICAL :: FOUND REAL(SP), POINTER :: STORAGE_ARR(:,:), storage_vec(:) CHARACTER(len=60) :: tempstrng, flowstrng, saltstrng TYPE(TIME) :: TIMETEST INTEGER :: LATS, LONS, I, Ntimes INTEGER :: STATUS IF(DBG_SET(DBG_SBR)) write(IPT,*) "START GROUND_WATER" IF (.NOT. GROUNDWATER_ON ) THEN IF(DBG_SET(DBG_LOG)) write(IPT,*) "! GROUND WATER FORCING IS OFF!" ALLOCATE(GWATER_FORCING_COMMENTS(1)) GWATER_FORCING_COMMENTS="GROUND WATER FORCING IS OFF!" RETURN END IF ! DETERMINE HOW TO LOAD THE DATA SELECT CASE(GROUNDWATER_KIND) CASE (CNSTNT) write(flowstrng,'(f8.4)') groundwater_flow write(tempstrng,'(f8.4)') groundwater_temp write(saltstrng,'(f8.4)') groundwater_salt IF(DBG_SET(DBG_LOG)) THEN WRITE(IPT,*)"! SETTING UP CONSTANT GROUNDWATER FORCING: " WRITE(IPT,*)" Flow Rate: "//trim(flowstrng) WRITE(IPT,*)" Temp: "//trim(tempstrng) WRITE(IPT,*)" Salt: "//trim(saltstrng) END IF ALLOCATE(GWATER_FORCING_COMMENTS(4)) GWATER_FORCING_COMMENTS(1) = "Using constant groundwater forcing from run file:" GWATER_FORCING_COMMENTS(2) = "Flow Rate:"//trim(flowstrng) IF(GROUNDWATER_TEMP_ON) THEN GWATER_FORCING_COMMENTS(3) = "Temperature (specified):"//trim(tempstrng) ELSE GWATER_FORCING_COMMENTS(3) = "Temperature is calculated" END IF IF(GROUNDWATER_SALT_ON) THEN GWATER_FORCING_COMMENTS(4) = "Salinity (specified):"//trim(saltstrng) ELSE GWATER_FORCING_COMMENTS(4) = "Salinity is calculated" END IF RETURN CASE(STTC) CALL FATAL_ERROR("STATIC GROUNDWATER Not Set Up Yet") CASE(TMDPNDNT) CALL FATAL_ERROR("TIME DEPENDENT GROUNDWATER Not Set Up Yet") CASE(PRDC) GWATER_FILE => FIND_FILE(FILEHEAD,trim(GROUNDWATER_FILE),FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("COULD NOT FIND GROUNDWATER FILE OBJECT",& & "FILE NAME: "//TRIM(GROUNDWATER_FILE)) ! DETERMINE GRID TYPE BASED ON SOURCE ATTRIBUTE ATT => FIND_ATT(GWATER_FILE,"source",FOUND) IF(.not. FOUND) ATT => FIND_ATT(GWATER_FILE,"Source",FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN SURFACE HEATING BOUNDARY CONDITION FILE OBJECT",& & "FILE NAME: "//TRIM(GROUNDWATER_FILE),& &"COULD NOT FIND GLOBAL ATTRIBURE: 'source'") IF (ATT%CHR(1)(1:len_trim(fvcom_grid_source)) ==& & TRIM(fvcom_grid_source)) THEN GWATER_FORCING_TYPE = GWATER_IS_FVCOMGRID ELSEIF (ATT%CHR(1)(1:len_trim(fvcom_cap_grid_source)) ==& & TRIM(fvcom_cap_grid_source)) THEN GWATER_FORCING_TYPE = GWATER_IS_FVCOMGRID ELSE CALL PRINT_FILE(GWATER_FILE) CALL FATAL_ERROR("CAN NOT RECOGNIZE GROUNDWATER FILE!",& & "UNKNOWN SOURCE STRING:",TRIM(ATT%CHR(1))) END IF ! GOT GRID TYPE ALLOCATE(GWATER_FORCING_COMMENTS(5)) GWATER_FORCING_COMMENTS(1) = "FVCOM periodic GroundWater forcing:" GWATER_FORCING_COMMENTS(2) = "FILE NAME:"//TRIM(GroundWater_FILE) GWATER_FORCING_COMMENTS(3) = "SOURCE:"//TRIM(ATT%CHR(1)) IF(GROUNDWATER_TEMP_ON) THEN GWATER_FORCING_COMMENTS(4) = "Temperature is specified" ELSE GWATER_FORCING_COMMENTS(4) = "Temperature is calculated" END IF IF(GROUNDWATER_SALT_ON) THEN GWATER_FORCING_COMMENTS(5) = "Salinity is specified" ELSE GWATER_FORCING_COMMENTS(5) = "Salinity is calculated" END IF ! GET THE FILES LENGTH OF TIME AND SAVE FOR PERIODIC FORCING ! LOOK FOR THE DIMENSIONS DIM => FIND_UNLIMITED(GWATER_FILE,FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN GROUNDWATER FILE OBJECT",& & "FILE NAME: "//TRIM(GROUNDWATER_FILE),& &"COULD NOT FIND THE UNLIMITED DIMENSION") NTIMES = DIM%DIM GWATER_PERIOD = get_file_time(GWATER_FILE,ntimes) IF (ZEROTIME /= get_file_time(GWATER_FILE,1)) THEN CALL PRINT_REAL_TIME(get_file_time(GWATER_FILE,1),IPT,"FIRST FILE TIME",TIMEZONE) CALL PRINT_REAL_TIME(get_file_time(GWATER_FILE,ntimes),IPT,"LAST FILE TIME",TIMEZONE) CALL FATAL_ERROR& &("TO USE PERIODIC FORCING THE FILE TIME MUST COUNT FROM ZERO",& & "THE DIFFERENCE BETWEEN THE CURRENT MODEL TIME AND THE START TIME,",& & "MODULO THE FORCING PERIOD, DETERMINES THE CURRENT FORCING") END IF IF(DBG_SET(DBG_LOG)) THEN WRITE(IPT,*) "! USING PERIODIC GroundWater FORCING:" CALL PRINT_TIME(GWATER_PERIOD,IPT,"PERIOD") END IF CASE(VRBL) GWATER_FILE => FIND_FILE(FILEHEAD,trim(GROUNDWATER_FILE),FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("COULD NOT FIND GROUNDWATER FILE OBJECT",& & "FILE NAME: "//TRIM(GROUNDWATER_FILE)) ! DETERMINE GRID TYPE BASED ON SOURCE ATTRIBUTE ATT => FIND_ATT(GWATER_FILE,"source",FOUND) IF(.not. FOUND) ATT => FIND_ATT(GWATER_FILE,"Source",FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN SURFACE HEATING BOUNDARY CONDITION FILE OBJECT",& & "FILE NAME: "//TRIM(GROUNDWATER_FILE),& &"COULD NOT FIND GLOBAL ATTRIBURE: 'source'") IF (ATT%CHR(1)(1:len_trim(fvcom_cap_grid_source)) ==& & TRIM(fvcom_cap_grid_source)) THEN GWATER_FORCING_TYPE = GWATER_IS_FVCOMGRID ELSEIF (ATT%CHR(1)(1:len_trim(fvcom_grid_source)) ==& & TRIM(fvcom_grid_source)) THEN GWATER_FORCING_TYPE = GWATER_IS_FVCOMGRID ELSE CALL PRINT_FILE(GWATER_FILE) CALL FATAL_ERROR("CAN NOT RECOGNIZE GROUNDWATER FILE!",& & "UNKNOWN SOURCE STRING:",TRIM(ATT%CHR(1))) END IF ! GOT GRID TYPE ALLOCATE(GWATER_FORCING_COMMENTS(5)) GWATER_FORCING_COMMENTS(1) = "FVCOM variable GroundWater forcing:" GWATER_FORCING_COMMENTS(2) = "FILE NAME:"//TRIM(GroundWater_FILE) GWATER_FORCING_COMMENTS(3) = "SOURCE:"//TRIM(ATT%CHR(1)) IF(GROUNDWATER_TEMP_ON) THEN GWATER_FORCING_COMMENTS(4) = "Temperature is specified" ELSE GWATER_FORCING_COMMENTS(4) = "Temperature is calculated" END IF IF(GROUNDWATER_SALT_ON) THEN GWATER_FORCING_COMMENTS(5) = "Salinity is specified" ELSE GWATER_FORCING_COMMENTS(5) = "Salinity is calculated" END IF ! GET THE FILES LENGTH OF TIME AND SAVE FOR PERIODIC FORCING ! LOOK FOR THE DIMENSIONS DIM => FIND_UNLIMITED(GWATER_FILE,FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN GROUNDWATER FILE OBJECT",& & "FILE NAME: "//TRIM(GROUNDWATER_FILE),& &"COULD NOT FIND THE UNLIMITED DIMENSION") NTIMES = DIM%DIM ! CHECK THE FILE TIME AND COMPARE WITH MODEL RUN TIME TIMETEST = get_file_time(GWATER_FILE,1) IF(TIMETEST > STARTTIME) CALL FATAL_ERROR & & ("IN THE GROUNDWATER FILE OBJECT",& & "FILE NAME: "//TRIM(GROUNDWATER_FILE),& &"THE MODEL RUN STARTS BEFORE THE FORCING TIME SERIES") TIMETEST = get_file_time(GWATER_FILE,ntimes) IF(TIMETEST < ENDTIME) CALL FATAL_ERROR & & ("IN THE GROUNDWATER FILE OBJECT",& & "FILE NAME: "//TRIM(GROUNDWATER_FILE),& &"THE MODEL RUN ENDS AFTER THE FORCING TIME SERIES") CASE DEFAULT CALL FATAL_ERROR("GROUND_WATER: UNKNOWN GROUND WATER KIND?") END SELECT !================================================================== SELECT CASE(GWATER_FORCING_TYPE) !================================================================== CASE(GWATER_IS_FVCOMGRID) !================================================================== IF(DBG_SET(DBG_LOG)) WRITE(IPT,*) & & "! SETTING UP GROUND WATER FORCING FROM A 'fvcom grid' FILE" ! LOOK FOR THE DIMENSIONS DIM => FIND_DIM(GWATER_FILE,'node',FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN THE GROUND WATER FILE OBJECT",& & "FILE NAME: "//TRIM(GROUNDWATER_FILE),& & "COULD NOT FIND DIMENSION 'node'") if (mgl /= dim%dim) CALL FATAL_ERROR& &("GROUNDWATER: the number of nodes in the file does not match the fvcom grid?") DIM => FIND_DIM(GWATER_FILE,'nele',FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN THE GROUND WATER FILE OBJECT",& & "FILE NAME: "//TRIM(GROUNDWATER_FILE),& & "COULD NOT FIND DIMENSION 'nele'") if (ngl /= dim%dim) CALL FATAL_ERROR& &("GROUNDWATER: the number of elements in the file does not match the fvcom grid?") ! SETUP THE ACTUAL VARIABLES USED TO LOAD DATA! ! GROUND WATER FLUX DATA VAR => FIND_VAR(GWATER_FILE,"groundwater_flux",FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN THE GROUNDWATER FILE OBJECT",& & "FILE NAME: "//TRIM(GROUNDWATER_FILE),& & "COULD NOT FIND VARIABLE 'groundwater_flux'") ATT => FIND_ATT(VAR,"units",FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN THE GROUNDWATER FILE OBJECT",& & "FILE NAME: "//TRIM(GROUNDWATER_FILE),& & "COULD NOT FIND THE UNITS FOR THE VARIABLE 'groundwater_flux'") IF (ATT%CHR(1)(1:len_trim("m3 s-1")) == "m3 s-1") THEN GWATER_UNITS = GWATER_M3S_1 ELSEIF (ATT%CHR(1)(1:len_trim("m s-1")) == "m s-1") THEN GWATER_UNITS = GWATER_MS_1 ELSE CALL FATAL_ERROR & & ("IN THE GROUNDWATER FILE OBJECT",& & "FILE NAME: "//TRIM(GROUNDWATER_FILE),& & "UNKNOWN UNITS FOR THE VARIABLE 'groundwater_flux'") END IF ! MAKE SPACE FOR THE DATA FROM THE FILE GWATER_FLUX_N => reference_var(var) ALLOCATE(STORAGE_VEC(0:MT), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN GROUNDWATER") CALL NC_CONNECT_PVAR(GWATER_FLUX_N,STORAGE_VEC) NULLIFY(STORAGE_VEC) ! MAKE SPACE FOR THE DATA FROM THE FILE GWATER_FLUX_P => reference_var(var) ALLOCATE(STORAGE_VEC(0:MT), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN GROUNDWATER") CALL NC_CONNECT_PVAR(GWATER_FLUX_P,STORAGE_VEC) NULLIFY(STORAGE_VEC) ! GROUNDWATER INFLOW TEMPERATURE IF(GROUNDWATER_TEMP_ON)THEN VAR => FIND_VAR(GWATER_FILE,"groundwater_temp",FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN THE GROUNDWATER FILE OBJECT",& & "FILE NAME: "//TRIM(GROUNDWATER_FILE),& & "COULD NOT FIND VARIABLE 'groundwater_temp'") ! MAKE SPACE FOR THE DATA FROM THE FILE GWATER_TEMP_N => reference_var(var) ALLOCATE(STORAGE_VEC(0:MT), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN GROUNDWATER") CALL NC_CONNECT_PVAR(GWATER_TEMP_N,STORAGE_VEC) NULLIFY(STORAGE_VEC) ! MAKE SPACE FOR THE DATA FROM THE FILE GWATER_TEMP_P => reference_var(var) ALLOCATE(STORAGE_VEC(0:MT), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN GROUNDWATER") CALL NC_CONNECT_PVAR(GWATER_TEMP_P,STORAGE_VEC) NULLIFY(STORAGE_VEC) END IF ! GROUNDWATER INFLOW SALINITY IF(GROUNDWATER_SALT_ON)THEN VAR => FIND_VAR(GWATER_FILE,"groundwater_salt",FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN THE GROUNDWATER FILE OBJECT",& & "FILE NAME: "//TRIM(GROUNDWATER_FILE),& & "COULD NOT FIND VARIABLE 'groundwater_salt'") ! MAKE SPACE FOR THE DATA FROM THE FILE GWATER_SALT_N => reference_var(var) ALLOCATE(STORAGE_VEC(0:MT), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN GROUNDWATER") CALL NC_CONNECT_PVAR(GWATER_SALT_N,STORAGE_VEC) NULLIFY(STORAGE_VEC) ! MAKE SPACE FOR THE DATA FROM THE FILE GWATER_SALT_P => reference_var(var) ALLOCATE(STORAGE_VEC(0:MT), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN GROUNDWATER") CALL NC_CONNECT_PVAR(GWATER_SALT_P,STORAGE_VEC) NULLIFY(STORAGE_VEC) END IF !================================================================== CASE DEFAULT !================================================================== CALL FATAL_ERROR("CAN NOT RECOGNIZE GROUND WATER FILE TYPE!") !================================================================== END SELECT !================================================================== ! ---------- new: 2016 , april, Karsten Lettmann after Hint by Qi and ayumi.fujisaki@noaa.gov------ ! Initialize some variables GWATER_FLUX_P%curr_stkcnt = 0 ; GWATER_FLUX_N%curr_stkcnt = 0 GWATER_TEMP_P%curr_stkcnt = 0 ; GWATER_TEMP_N%curr_stkcnt = 0 GWATER_SALT_P%curr_stkcnt = 0 ; GWATER_SALT_N%curr_stkcnt = 0 ! --------- end new ---------------------------------------------------------------- IF(DBG_SET(DBG_SBR)) write(IPT,*) "END GROUND_WATER" END SUBROUTINE GROUND_WATER !================================================================ !================================================================ SUBROUTINE TIDAL_ELEVATION IMPLICIT NONE ! VARIABLES TO CHECK OBC NODE LIST INTEGER MYNOBC INTEGER, ALLOCATABLE :: MYOBCLIST(:) REAL(SP), POINTER :: STORAGE_VEC(:) ! SOME NC POINTERS TYPE(NCATT), POINTER :: ATT TYPE(NCDIM), POINTER :: DIM TYPE(NCVAR), POINTER :: VAR ! SOME HANDY VARIABLES TO PLAY WITH LOGICAL FOUND, VALID INTEGER NTIMES TYPE(TIME) :: TIMETEST real(SP) rbuf,float_time integer status, I, J ! SOME TEST STUFF FOR BRACKET Character(len=80):: dstring Character(len=80) :: dformat, tzone REAL(SP), ALLOCATABLE :: MYPERIOD(:) IF(DBG_SET(DBG_SBR)) write(IPT,*) "START TIDAL_ELEVATION" # if defined (EQUI_TIDE) IF(USE_REAL_WORLD_TIME) CALL ASTRONOMY # endif ! ONLY ESCAPE EARLY IF EQUI_TIDE IS OFF. OTHERWISE WE STILL NEED ! THE TIDAL FORCING FILE # if !defined (EQUI_TIDE) IF (.NOT. OBC_ELEVATION_FORCING_ON ) THEN IF(DBG_SET(DBG_LOG)) write(IPT,*) & "! TIDAL ELEVATION FORCING IS EITHER IN NESTING OR OFF!" ALLOCATE(TIDE_FORCING_COMMENTS(1)) TIDE_FORCING_COMMENTS="TIDAL ELEVATION FORCING IS EITHER IN NESTING OR OFF!" RETURN END IF # endif ! BOTH ASCII AND NETCDF NON JULIAN DATA FILES HAVE A NCFILE ! POINTER. THE DUMMY POINTER WAS CREATED FOR THE ASCII FILE AS A ! WAY TO 'TRICK' THE CODE AND CONTAIN THE NUMBER OF CONTROL VARIABLES ! FIND THE TIDAL FORCING FILE OBJECT TIDE_FILE => FIND_FILE(FILEHEAD,trim(OBC_ELEVATION_FILE),FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("COULD NOT FIND OPEN BOUNDARY CONDITION ELEVATION FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_ELEVATION_FILE)) ATT => FIND_ATT(TIDE_FILE,"type",FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION ELEVATION FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_ELEVATION_FILE),& &"COULD NOT FIND GLOBAL ATTRIBURE: 'type'") SELECT CASE(TRIM(ATT%CHR(1))) !================================= ! NON JULIAN ELEVATION FORCING DATA CASE("FVCOM NON JULIAN ELEVATION FORCING FILE",& & "FVCOM SPECTRAL ELEVATION FORCING FILE") !================================== ATT => FIND_ATT(TIDE_FILE,"components",FOUND) IF(FOUND) THEN ALLOCATE(TIDE_FORCING_COMMENTS(size(ATT%CHR)+1)) TIDE_FORCING_COMMENTS(1)= "Spectral Tidal Forcing Components:" TIDE_FORCING_COMMENTS(2:)= ATT%CHR(:) ELSE CALL WARNING("ATTRIBUTE 'components' IS MISSING IN THE TIDAL FORCING FILE!") ALLOCATE(TIDE_FORCING_COMMENTS(1)) TIDE_FORCING_COMMENTS = "Spectral Tidal Forcing Components& &: UNKNOWN" END IF DIM => FIND_DIM(TIDE_FILE,'tidal_components',FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION SPECTRAL ELEVATION FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_ELEVATION_FILE),& &"COULD NOT FIND DIMENSION 'tidal_components'") NTIDECOMPS = DIM%DIM ! LOAD TIDAL PERIOD DATA ALLOCATE(PERIOD(NTIDECOMPS),stat=status) IF (0 /= status) CALL FATAL_ERROR("TIDAL_ELEVATION COULD NOT & &ALLOCATE 'NTIDECOMPS'") VAR => FIND_VAR(TIDE_FILE,'tide_period',FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION SPECTRAL ELEVATION FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_ELEVATION_FILE),& &"COULD NOT FIND THE VARIABLE 'tide_period'") ATT => FIND_ATT(VAR,'units',FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION TIME SERIES ELEVATION FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_ELEVATION_FILE),& &"COULD NOT FIND PERIOD VARIRIABLE'S ATTRIBUTE 'units'") if(trim(ATT%CHR(1)) .NE. 'seconds') CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION TIME SERIES ELEVATION FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_ELEVATION_FILE),& &"PERIOD VARIRIABLE ATTRIBUTE 'units' SHOULD BE 'seconds'") CALL NC_CONNECT_AVAR(VAR,PERIOD) CALL NC_READ_VAR(VAR) ! LOAD THE Time Origin data if present VAR => FIND_VAR(TIDE_FILE,'time_origin', FOUND) IF (FOUND) THEN IF( IS_VALID_DATETIME( VAR,tzone)) THEN CALL NC_CONNECT_AVAR(VAR,dstring) CALL NC_READ_VAR(VAR) SPECTIME = READ_DATETIME(dstring,DATE_FORMAT,tzone,status) IF(Status == 0) CALL FATAL_ERROR& & ("Could not read date in 'time_origin' attribute of spectral forcing file") ELSE IF(IS_VALID_FLOAT_DAYS( VAR,tzone)) THEN CALL NC_CONNECT_AVAR(VAR,float_time) CALL NC_READ_VAR(VAR) SPECTIME = days2time(float_time) ELSE IF(IS_VALID_FLOAT_SECONDS( VAR,tzone)) THEN CALL NC_CONNECT_AVAR(VAR,float_time) CALL NC_READ_VAR(VAR) SPECTIME = seconds2time(float_time) ELSE CALL FATAL_ERROR("SPECTRAL TIDAL FORCING TIME ORIGIN VA& &RIABLE MUST BE A CHARACTER STRING Date or a float& &ing point time???") END IF ELSE CALL WARNING("Setting Spectral Tidal Phase Time Orgin to 0.0 MJD") SPECTIME%MJD =0 SPECTIME%MUSOD =0 END IF # if defined (EQUI_TIDE) IF(USE_REAL_WORLD_TIME) THEN ALLOCATE(EQUI_ID(NTIDECOMPS)) ; EQUI_ID = 0 ALLOCATE(EQUI_VN(NTIDECOMPS)) ; EQUI_VN = 0.0D0 ALLOCATE(EQUI_U(0:MT,NTIDECOMPS)); EQUI_U = 0.0D0 ALLOCATE(EQUI_F(0:MT,NTIDECOMPS)); EQUI_F = 0.0D0 ALLOCATE(MYPERIOD(8)) MYPERIOD(1) = 43200.0_SP MYPERIOD(2) = 44712.0_SP MYPERIOD(3) = 45570.0_SP MYPERIOD(4) = 43082.0_SP MYPERIOD(5) = 86164.0_SP MYPERIOD(6) = 86637.0_SP MYPERIOD(7) = 92950.0_SP MYPERIOD(8) = 96726.0_SP DO I=1, NTIDECOMPS DO J=1,8 IF( ABS(PERIOD(I)-MYPERIOD(J))<5.0 ) THEN EQUI_ID(I) = J EXIT ENDIF ENDDO IF(EQUI_ID(I)==0) CALL FATAL_ERROR("COULD NOT FIND A PROPER TIDAL COMPONENT& &FROM THE TIDAL INPUT FILE FOR EQUILIBRIUM TIDE???") ENDDO DEALLOCATE(MYPERIOD) ENDIF ! LOAD EQUILIBRIUM TIDE AMPLITUDE ALLOCATE(APT_EQI(NTIDECOMPS)) VAR => FIND_VAR(TIDE_FILE,'equilibrium_tide_Eamp',FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION SPECTRAL ELEVATION FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_ELEVATION_FILE),& &"COULD NOT FIND VARIABLE 'equilibrium_tide_Eamp'") ATT => FIND_ATT(VAR,'units',FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION TIME SERIES ELEVATION FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_ELEVATION_FILE),& &"COULD NOT FIND EQUILIBRIUM AMPLITUDE VARIRIABLE'S ATTRIBUTE 'units'") if(trim(ATT%CHR(1)) .NE. 'meters') CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION TIME SERIES ELEVATION FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_ELEVATION_FILE),& &"EQUILIBRIUM AMPLITUDE VARIRIABLE ATTRIBUTE 'units' SHOULD BE 'meters'") CALL NC_CONNECT_AVAR(VAR,APT_EQI) CALL NC_READ_VAR(VAR) ! LOAD THE BETA LOVE NUMBER ALLOCATE(BETA_EQI(NTIDECOMPS)) VAR => FIND_VAR(TIDE_FILE,'equilibrium_beta_love',FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION SPECTRAL ELEVATION FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_ELEVATION_FILE),& &"COULD NOT FIND VARIABLE 'equilibrium_beta_love'") ATT => FIND_ATT(VAR,'formula',FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION TIME SERIES ELEVATION FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_ELEVATION_FILE),& &"COULD NOT FIND LOVE NUMBER VARIRIABLE'S ATTRIBUTE 'formula'") if(trim(ATT%CHR(1)) .NE. 'beta=1+klove-hlove') CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION TIME SERIES ELEVATION FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_ELEVATION_FILE),& &"BETA LOVE VARIRIABLE ATTRIBUTE 'formula' SHOULD BE 'beta=1+klove-hlove'") CALL NC_CONNECT_AVAR(VAR,BETA_EQI) CALL NC_READ_VAR(VAR) ! LOAD THE EQUILIBRIUM TIDE TYPE ALLOCATE(TIDE_TYPE(NTIDECOMPS)) VAR => FIND_VAR(TIDE_FILE,'equilibrium_tide_type',FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION SPECTRAL ELEVATION FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_ELEVATION_FILE),& &"COULD NOT FIND VARIABLE 'equilibrium_tide_type'") IF(VAR%XTYPE .NE. NF90_CHAR) CALL FATAL_ERROR& &("IN OPEN BOUNDARY CONDITION SPECTRAL ELEVATION FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_ELEVATION_FILE),& &"VARIABLE 'equilibrium_tide_type' MUST BE A CHARACTER ARRAY") CALL NC_CONNECT_AVAR(VAR,TIDE_TYPE) CALL NC_READ_VAR(VAR) IF(DBG_SET(DBG_LOG)) THEN write(IPT,*) "! TIDAL EQUILIBRIUM FORCING IS ON!" write(IPT,*) "! FOUND:",NTIDECOMPS,"; EQUILIBRIUM TIDAL COMPONENTS" END IF IF (.NOT. OBC_ELEVATION_FORCING_ON ) THEN IF(DBG_SET(DBG_LOG)) write(IPT,*) "! TIDAL OBC ELEVATION FORCING IS OFF!" RETURN END IF # endif if(IOBCN_GL>0) then ! LOOK FOR THE DIMENSIONS 'nobc' and 'tidal_compontents' DIM => FIND_DIM(TIDE_FILE,'nobc',FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION SPECTRAL ELEVATION FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_ELEVATION_FILE),& &"COULD NOT FIND DIMENSION 'nobc'") IF(IOBCN_GL /= DIM%DIM) CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION SPECTRAL ELEVATION FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_ELEVATION_FILE),& &"THE DIMENSION 'nobc' MUST MATCH THE NUMBER OF OBC NODES") ! LOAD GLOBAL OPEN BOUNDARY NODE NUMBER DATA AND COMPARE WITH ! OBC.DAT/RESTART FILE INPUT ALLOCATE(MYOBCLIST(IOBCN)) VAR => FIND_VAR(TIDE_FILE,'obc_nodes',FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION SPECTRAL ELEVATION FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_ELEVATION_FILE),& &"COULD NOT FIND VARIABLE 'obc_nodes'") CALL NC_CONNECT_AVAR(VAR,MYOBCLIST) CALL NC_READ_VAR(VAR) DO I = 1, IOBCN IF(I_OBC_N(I) /= NLID(MYOBCLIST(I))) THEN write(IPT,*) "NLID(MYOBCLIST)= ", NLID(MYOBCLIST(I)), "; I=",I write(IPT,*) "I_OBC_N= ", I_OBC_N(I), "; I=",I CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION SPECTRAL ELEVATION FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_ELEVATION_FILE),& &"THE LIST OF BOUNDARY NODES DOES NOT MATCH") END IF END DO ! LOAD THE ELEVATION REFERENCE LEVEL DATA ALLOCATE(EMEAN(IOBCN)) VAR => FIND_VAR(TIDE_FILE,'tide_Eref',FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION SPECTRAL ELEVATION FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_ELEVATION_FILE),& &"COULD NOT FIND VARIABLE 'tide_Eref'") ATT => FIND_ATT(VAR,'units',FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION TIME SERIES ELEVATION FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_ELEVATION_FILE),& &"COULD NOT FIND ELEVATION REFERENCE VARIRIABLE'S ATTRIBUTE 'units'") if(trim(ATT%CHR(1)) .NE. 'meters') CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION TIME SERIES ELEVATION FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_ELEVATION_FILE),& &"ELEVATION REFERENCE VARIRIABLE ATTRIBUTE 'units' SHOULD BE 'meters'") CALL NC_CONNECT_AVAR(VAR,EMEAN) CALL NC_READ_VAR(VAR) ! LOAD THE AMPLITUDE DATA ALLOCATE(APT(IOBCN,NTIDECOMPS)) VAR => FIND_VAR(TIDE_FILE,'tide_Eamp',FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION SPECTRAL ELEVATION FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_ELEVATION_FILE),& &"COULD NOT FIND VARIABLE 'tide_Eamp'") ATT => FIND_ATT(VAR,'units',FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION TIME SERIES ELEVATION FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_ELEVATION_FILE),& &"COULD NOT FIND AMPLITUDE VARIRIABLE'S ATTRIBUTE 'units'") if(trim(ATT%CHR(1)) .NE. 'meters') CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION TIME SERIES ELEVATION FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_ELEVATION_FILE),& &"AMPLITUDE VARIRIABLE ATTRIBUTE 'units' SHOULD BE 'meters'") CALL NC_CONNECT_AVAR(VAR,APT) CALL NC_READ_VAR(VAR) ! LOAD THE PHASE DATA ALLOCATE(PHAI(IOBCN,NTIDECOMPS)) VAR => FIND_VAR(TIDE_FILE,'tide_Ephase',FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION SPECTRAL ELEVATION FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_ELEVATION_FILE),& &"COULD NOT FIND VARIABLE 'tide_Ephase'") ATT => FIND_ATT(VAR,'units',FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION TIME SERIES ELEVATION FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_ELEVATION_FILE),& &"COULD NOT FIND PHASE VARIRIABLE'S ATTRIBUTE 'units'") if(ATT%CHR(1)(1:7) .NE. 'degrees') CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION TIME SERIES ELEVATION FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_ELEVATION_FILE),& &"PHASE VARIRIABLE ATTRIBUTE 'units' SHOULD BE 'degrees'") CALL NC_CONNECT_AVAR(VAR,PHAI) CALL NC_READ_VAR(VAR) PHAI = MOD(PHAI,360.0_SP) !--REPORT RESULTS--------------------------------------------------------------! RBUF = MAXVAL(APT) # if defined (MULTIPROCESSOR) IF(PAR)CALL MPI_REDUCE(MAXVAL(APT),RBUF,1,MPI_F,MPI_MAX,0,MPI_FVCOM_GROUP,status) # endif IF(DBG_SET(DBG_LOG)) THEN WRITE(IPT,*)'!' WRITE(IPT,* )'! SPECTRAL TIDE : SET' WRITE(IPT,101)'! MAX TIDE AMPLITUDE : ',RBUF CALL PRINT_REAL_TIME(SpecTime,IPT,"Tide Time Origin") END IF endif ! SET THE TIDE FORCING TYPE FOR USE IN UPDATE TIDE_FORCING_TYPE = TIDE_FORCING_SPECTRAL !========================= ! NON JULIAN FORCING DATA IN AN ASCII FILE CASE("ASCII FILE DUMMY ATTRIBUTE") !========================= CALL LOAD_JULIAN_OBC(NTIDECOMPS,TIDE_FORCING_COMMENTS& &,PERIOD,APT_EQI, BETA_EQI, TIDE_TYPE,APT,PHAI,EMEAN,SPECTIME) PHAI = MOD(PHAI,360.0_SP) !--REPORT RESULTS--------------------------------------------------------------! RBUF = MAXVAL(APT) # if defined (MULTIPROCESSOR) IF(PAR)CALL MPI_ALLREDUCE(MAXVAL(APT),RBUF,1,MPI_F,MPI_MAX,MPI_FVCOM_GROUP,status) # endif IF(DBG_SET(DBG_LOG)) THEN WRITE(IPT,*)'!' WRITE(IPT,* )'! SPECTRAL TIDE : SET' WRITE(IPT,101)'! MAX TIDE AMPLITUDE : ',RBUF CALL PRINT_REAL_TIME(SpecTime,IPT,"Tide Time Origin") END IF ! SET THE TIDE FORCING TYPE FOR USE IN UPDATE TIDE_FORCING_TYPE = TIDE_FORCING_SPECTRAL !========================= ! TIME SERIES FORCING DATA CASE("FVCOM JULIAN TIME SERIES ELEVATION FORCING FILE", & & "FVCOM TIME SERIES ELEVATION FORCING FILE") !========================= ALLOCATE(TIDE_FORCING_COMMENTS(1)) ATT => FIND_ATT(TIDE_FILE,"title",FOUND) IF(FOUND) THEN TIDE_FORCING_COMMENTS = "Tidal Forcing Time Series Title: "& &//TRIM(ATT%CHR(1)) ELSE CALL WARNING("ATTRIBUTE 'title' IS MISSING IN THE TIDAL FORCING FILE!") TIDE_FORCING_COMMENTS = "Tidal Forcing Time Series Title: UNKNOWN" END IF # if defined (EQUI_TIDE) DIM => FIND_DIM(TIDE_FILE,'tidal_components',FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION SPECTRAL ELEVATION FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_ELEVATION_FILE),& &"COULD NOT FIND DIMENSION 'tidal_components'") NTIDECOMPS = DIM%DIM ! LOAD TIDAL PERIOD DATA ALLOCATE(PERIOD(NTIDECOMPS),stat=status) IF (0 /= status) CALL FATAL_ERROR("TIDAL_ELEVATION COULD NOT & &ALLOCATE 'NTIDECOMPS'") VAR => FIND_VAR(TIDE_FILE,'tide_period',FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION SPECTRAL ELEVATION FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_ELEVATION_FILE),& &"COULD NOT FIND THE VARIABLE 'tide_period'") ATT => FIND_ATT(VAR,'units',FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION TIME SERIES ELEVATION FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_ELEVATION_FILE),& &"COULD NOT FIND PERIOD VARIRIABLE'S ATTRIBUTE 'units'") if(trim(ATT%CHR(1)) .NE. 'seconds') CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION TIME SERIES ELEVATION FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_ELEVATION_FILE),& &"PERIOD VARIRIABLE ATTRIBUTE 'units' SHOULD BE 'seconds'") CALL NC_CONNECT_AVAR(VAR,PERIOD) CALL NC_READ_VAR(VAR) IF(USE_REAL_WORLD_TIME) THEN ALLOCATE(EQUI_ID(NTIDECOMPS)) ; EQUI_ID = 0 ALLOCATE(EQUI_VN(NTIDECOMPS)) ; EQUI_VN = 0.0D0 ALLOCATE(EQUI_U(0:MT,NTIDECOMPS)); EQUI_U = 0.0D0 ALLOCATE(EQUI_F(0:MT,NTIDECOMPS)); EQUI_F = 0.0D0 ALLOCATE(MYPERIOD(8)) MYPERIOD(1) = 43200.0_SP MYPERIOD(2) = 44712.0_SP MYPERIOD(3) = 45570.0_SP MYPERIOD(4) = 43082.0_SP MYPERIOD(5) = 86164.0_SP MYPERIOD(6) = 86637.0_SP MYPERIOD(7) = 92950.0_SP MYPERIOD(8) = 96726.0_SP DO I=1, NTIDECOMPS DO J=1,8 IF( ABS(PERIOD(I)-MYPERIOD(J))<5.0 ) THEN EQUI_ID(I) = J EXIT ENDIF ENDDO IF(EQUI_ID(I)==0) CALL FATAL_ERROR("COULD NOT FIND A PROPER TIDAL COMPONENT& &FROM THE TIDAL INPUT FILE FOR EQUILIBRIUM TIDE???") ENDDO DEALLOCATE(MYPERIOD) ENDIF ! LOAD EQUILIBRIUM TIDE AMPLITUDE ALLOCATE(APT_EQI(NTIDECOMPS)) VAR => FIND_VAR(TIDE_FILE,'equilibrium_tide_Eamp',FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION SPECTRAL ELEVATION FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_ELEVATION_FILE),& &"COULD NOT FIND VARIABLE 'equilibrium_tide_Eamp'") ATT => FIND_ATT(VAR,'units',FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION TIME SERIES ELEVATION FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_ELEVATION_FILE),& &"COULD NOT FIND EQUILIBRIUM AMPLITUDE VARIRIABLE'S ATTRIBUTE 'units'") if(trim(ATT%CHR(1)) .NE. 'meters') CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION TIME SERIES ELEVATION FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_ELEVATION_FILE),& &"EQUILIBRIUM AMPLITUDE VARIRIABLE ATTRIBUTE 'units' SHOULD BE 'meters'") CALL NC_CONNECT_AVAR(VAR,APT_EQI) CALL NC_READ_VAR(VAR) ! LOAD THE BETA LOVE NUMBER ALLOCATE(BETA_EQI(NTIDECOMPS)) VAR => FIND_VAR(TIDE_FILE,'equilibrium_beta_love',FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION SPECTRAL ELEVATION FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_ELEVATION_FILE),& &"COULD NOT FIND VARIABLE 'equilibrium_beta_love'") ATT => FIND_ATT(VAR,'formula',FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION TIME SERIES ELEVATION FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_ELEVATION_FILE),& &"COULD NOT FIND LOVE NUMBER VARIRIABLE'S ATTRIBUTE 'formula'") if(trim(ATT%CHR(1)) .NE. 'beta=1+klove-hlove') CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION TIME SERIES ELEVATION FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_ELEVATION_FILE),& &"BETA LOVE VARIRIABLE ATTRIBUTE 'formula' SHOULD BE 'beta=1+klove-hlove'") CALL NC_CONNECT_AVAR(VAR,BETA_EQI) CALL NC_READ_VAR(VAR) ! LOAD THE EQUILIBRIUM TIDE TYPE ALLOCATE(TIDE_TYPE(NTIDECOMPS)) VAR => FIND_VAR(TIDE_FILE,'equilibrium_tide_type',FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION SPECTRAL ELEVATION FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_ELEVATION_FILE),& &"COULD NOT FIND VARIABLE 'equilibrium_tide_type'") IF(VAR%XTYPE .NE. NF90_CHAR) CALL FATAL_ERROR& &("IN OPEN BOUNDARY CONDITION SPECTRAL ELEVATION FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_ELEVATION_FILE),& &"VARIABLE 'equilibrium_tide_type' MUST BE A CHARACTER ARRAY") CALL NC_CONNECT_AVAR(VAR,TIDE_TYPE) CALL NC_READ_VAR(VAR) IF(DBG_SET(DBG_LOG)) THEN write(IPT,*) "! TIDAL EQUILIBRIUM FORCING IS ON!" write(IPT,*) "! FOUND:",NTIDECOMPS,"; EQUILIBRIUM TIDAL COMPONENTS" END IF IF (.NOT. OBC_ELEVATION_FORCING_ON ) THEN IF(DBG_SET(DBG_LOG)) write(IPT,*) "! TIDAL OBC ELEVATION FORCING IS OFF!" RETURN END IF # endif ! LOOK FOR THE DIMENSIONS 'nobc' and 'time' DIM => FIND_DIM(TIDE_FILE,'time',FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION TIME SERIES ELEVATION FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_ELEVATION_FILE),& &"COULD NOT FIND DIMENSION 'time'") NTIMES = DIM%DIM DIM => FIND_DIM(TIDE_FILE,'nobc',FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION TIME SERIES ELEVATION FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_ELEVATION_FILE),& &"COULD NOT FIND DIMENSION 'nobc'") if(IOBCN_GL>0) then IF(IOBCN_GL /= DIM%DIM) CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION TIME SERIES ELEVATION FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_ELEVATION_FILE),& &"THE DIMENSION 'nobc' MUST MATCH THE NUMBER OF OBC NODES") endif ! lOAD GLOBAL OPEN BOUNDARY NOD NUMBER DATA AND COMPARE WITH ! OBC.DAT/RESTART FILE INPUT ALLOCATE(MYOBCLIST(IOBCN)) VAR => FIND_VAR(TIDE_FILE,'obc_nodes',FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION TIME SERIES ELEVATION FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_ELEVATION_FILE),& &"COULD NOT FIND VARIABLE 'obc_nodes'") CALL NC_CONNECT_AVAR(VAR,MYOBCLIST) CALL NC_READ_VAR(VAR) DO I = 1, IOBCN IF(SERIAL) THEN IF(I_OBC_N(I) /= MYOBCLIST(I)) THEN write(IPT,*) "NLID(MYOBCLIST)= ", MYOBCLIST(I), "; I=",I write(IPT,*) "I_OBC_N= ", I_OBC_N(I), "; I=",I CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION TIME SERIES ELEVATION FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_ELEVATION_FILE),& &"THE LIST OF BOUNDARY NODES DOES NOT MATCH") END IF ELSE # if defined(MULTIPROCESSOR) IF(I_OBC_N(I) /= NLID(MYOBCLIST(I))) THEN write(IPT,*) "NLID(MYOBCLIST)= ", NLID(MYOBCLIST(I)), "; I=",I write(IPT,*) "I_OBC_N= ", I_OBC_N(I), "; I=",I CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION TIME SERIES ELEVATION FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_ELEVATION_FILE),& &"THE LIST OF BOUNDARY NODES DOES NOT MATCH") END IF # endif END IF END DO ! LOAD TIME AND CHECK TO MAKE SURE THE TIME RANGE IS VALID TIMETEST = GET_FILE_TIME(TIDE_FILE,1) IF(TIMETEST > STARTTIME) CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION TIME SERIES ELEVATION FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_ELEVATION_FILE),& &"THE MODEL RUN STARTS BEFORE THE ELVATION TIME SERIES") TIMETEST = GET_FILE_TIME(TIDE_FILE,NTIMES) IF(TIMETEST < ENDTIME) CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION TIME SERIES ELEVATION FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_ELEVATION_FILE),& &"THE MODEL RUN ENDS AFTER THE ELVATION TIME SERIES") VAR => FIND_VAR(TIDE_FILE,'elevation',FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION TIME SERIES ELEVATION FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_ELEVATION_FILE),& &"COULD NOT FIND VARIABLE 'elevation'") ATT => FIND_ATT(VAR,'units',FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION TIME SERIES ELEVATION FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_ELEVATION_FILE),& &"COULD NOT FIND ELEVATION VARIRIABLE'S ATTRIBUTE 'units'") if(TRIM(ATT%CHR(1)) .NE. 'meters') CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION TIME SERIES ELEVATION FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_ELEVATION_FILE),& &"ELEVATION VARIRIABLE ATTRIBUTE 'units' SHOULD BE 'meters'") ! MAKE SPACE FOR THE DATA FROM THE FILE ALLOCATE(STORAGE_VEC(IOBCN), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN TIDAL_ELEVATION") TIDE_ELV_N => reference_var(var) CALL NC_CONNECT_PVAR(TIDE_ELV_N,STORAGE_VEC) NULLIFY(STORAGE_VEC) ! MAKE SPACE FOR THE DATA FROM THE FILE ALLOCATE(STORAGE_VEC(IOBCN), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN TIDAL_ELEVATION") TIDE_ELV_P => reference_var(var) CALL NC_CONNECT_PVAR(TIDE_ELV_P,STORAGE_VEC) NULLIFY(STORAGE_VEC) tide_elv_p%curr_stkcnt = 0; tide_elv_n%curr_stkcnt = 0 ! Siqi Li, 2021-01-27 ! SINCE NO DATA HAS BEEN LOADED THERE IS NOT MUCH TO REPORT IF(DBG_SET(DBG_LOG)) THEN WRITE(IPT,*)'!' WRITE(IPT,* )'! TIME SERIES TIDE : SET' END IF ! SET THE TIDE FORCING TYPE FOR USE IN UPDATE TIDE_FORCING_TYPE = TIDE_FORCING_TIMESERIES ! NOT MUCH ELSE TO REPORT SINCE WE DON'T LOAD ANY DATA NOW !===================================== ! DEFAULT CASE IF GLOBAL ATTRIBUTES OF FILE ARE INCORRECT CASE DEFAULT !===================================== CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION ELEVATION FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_ELEVATION_FILE),& &"THE GLOBAL ATTRIBURE 'type' RETURNED UNKNOWN TYPE:",& & TRIM(ATT%CHR(1))) END SELECT ! Removed by Siqi Li, 2021-01-27 ! afm 20151112 & EJA 20160921 ! Need initialization. Otherwise, random values are asigned ! and cause a hanging problem of MPI job in UPDATE_VAR_BRACKET ! This problem reported with Intel15.0.3. ! tide_elv_p%curr_stkcnt = 0; tide_elv_n%curr_stkcnt = 0 IF(DBG_SET(DBG_SBR)) write(IPT,*) "END TIDAL_ELEVATION" 101 FORMAT(1X,A26,F10.4) END SUBROUTINE TIDAL_ELEVATION !================================================================ !================================================================ ! Rules about river names: River names must be unique ! examples: r1, r2, r3 ! : Mississippi, Connecticut, St.Lawrence ! BAD EXAMPLES: Miss, Mississippi, Missouri ! : R1, R2, R SUBROUTINE RIVER_DISCHARGE # if defined (BioGen) USE MOD_1D, ONLY : NTT,BIO_NAME # endif IMPLICIT NONE INTEGER :: I, J,K, fcnt,rcnt,status, nfiles,nrs,IOS,NS TYPE(A_RIVER_FILE) DUMMY TYPE(NCFILE),POINTER :: NCF TYPE(NCDIM), POINTER :: DIM TYPE(NCVAR), POINTER :: VAR TYPE(NCVAR), POINTER :: DUM_P REAL(SP), POINTER :: STORAGE_VEC(:) LOGICAL :: FOUND, MINE CHARACTER(LEN=7) :: chr character(len=20), allocatable :: dist_strings(:) REAL(SP) :: MYDIST(KBM1) IF(DBG_SET(DBG_SBR)) write(IPT,*) "START RIVER_DISCHARGE" NULLIFY(STORAGE_VEC) ! TRANSLATE TO THE OLD NAME FOR TOTAL NUMBER OF RIVERS NUMQBC_GL = river_number IF (river_number == 0 ) THEN NUMQBC = 0 IF(DBG_SET(DBG_LOG)) write(IPT,*) "! THERE ARE NO RIVERS IN THIS MODEL" ALLOCATE(RIVER_FORCING_COMMENTS(1)) RIVER_FORCING_COMMENTS(1) = "THERE ARE NO RIVERS IN T& &HIS MODEL" RETURN END IF IF (DBG_SET(DBG_SBRIO))THEN WRITE(IPT,*) "Total Number Of Rivers = ",river_number WRITE(IPT,*) "RIVER_TS_SETTING = "//TRIM(RIVER_TS_SETTING) WRITE(IPT,*) "RIVER_INFLOW_LOCATION = "//trim(RIVER_INFLOW_LOCATION) WRITE(IPT,*) "RIVER_KIND = "//trim(RIVER_KIND) WRITE(IPT,*)"=============================" DO I =1,river_number write(IPT,*) "River number:",I WRITE(IPT,*) "River File ="//TRIM(RIVERS(i)%FILE) WRITE(IPT,*) "River Name ="//trim(RIVERS(i)%NAME) WRITE(IPT,*) "River Location =",RIVERS(i)%LOCATION # if defined(RIVER_FLOAT) WRITE(IPT,*) "River Distribution =",RIVERS(i)%distribution(1:KBM1) # else WRITE(IPT,*) "River Distribution ="//TRIM(RIVERS(i)%distribution) # endif WRITE(IPT,*)"=============================" END DO END IF IF(TRIM(RIVER_TS_SETTING) /= 'calculated' .AND. TRIM(RIVER_TS_SETTING) /= 'specified') THEN CALL FATAL_ERROR("RIVER_TS_SETTING NOT CORRECT IN NAMELIST","SHOULD BE 'calculated' or 'specified'") END IF ALLOCATE(RIVER_FORCING_COMMENTS(river_number + 3)) WRITE(CHR,'(I7)')river_number RIVER_FORCING_COMMENTS(1) = "THERE ARE "//TRIM(adjustl(CHR))//" RIVERS IN THIS MODEL." RIVER_FORCING_COMMENTS(2) = "RIVER INFLOW IS ON THE "//TRIM(RIVER_INFLOW_LOCATION)& &//"s WHERE TEMPERATURE AND SALINITY ARE "//TRIM(RIVER_TS_SETTING)//" IN THE MODEL." RIVER_FORCING_COMMENTS(3) = "THE FOLLOWING RIVER NAMES ARE USED:" DO I =1,river_number RIVER_FORCING_COMMENTS(3+I) = TRIM(RIVERS(i)%NAME) END DO ! SELECT CASE(trim(RIVER_INFLOW_LOCATION)) ! CHECK TO MAKE SURE THE LOCATION IS VALID AND ADD NAMES TO ! COMMENT STRING nfiles = 0 NUMQBC = 0 DO I =1,river_number ! CHECK THE INFLOW LOCATION OF EACH RIVER ! AND ! COUNT THE NUMBER THAT BELONG TO EACH PROCESSOR SELECT CASE(trim(RIVER_INFLOW_LOCATION)) CASE('node') IF(RIVERS(i)%LOCATION > MGL .or. RIVERS(i)%LOCATION < 1)THEN write(chr,'(I7)') RIVERS(i)%LOCATION CALL FATAL_ERROR ("RIVER_DISCHARGE: FOR THE RIVER NAMED: "& &//trim(RIVERS(i)%NAME),"THE RIVER GRID LOCATION IN& & THE NAME LIST IS NOT IN THE GLOBAL DOMAIN",& & "YOU SPECIFIED NODE NUMBER: "//chr) END IF ! COUNT THE NUMBER OF RIVERS OWNED BY THIS PROC IF (NLID(RIVERS(I)%LOCATION) .GT. 0) NUMQBC = NUMQBC + 1 CASE('edge') IF(RIVERS(i)%LOCATION > NGL .or. RIVERS(i)%LOCATION < 1)THEN write(chr,'(I7)') RIVERS(i)%LOCATION CALL FATAL_ERROR ("RIVER_DISCHARGE: FOR THE RIVER NAMED: "& &//trim(RIVERS(i)%NAME),"THE RIVER GRID LOCATION IN& & THE NAME LIST IS NOT IN THE GLOBAL DOMAIN",& & "YOU SPECIFIED CELL NUMBER: "//chr) END IF ! COUNT THE NUMBER OF RIVERS OWNED BY THIS PROC IF (ELID(RIVERS(I)%LOCATION) .GT. 0) NUMQBC = NUMQBC + 1 CASE DEFAULT CALL FATAL_ERROR("RIVER_INFLOW_LOCATION: NOT CORRECT IN NAMELIST",& & "SHOULD BE 'node' or 'edge'") END SELECT ! COUNT THE NUMBER OF FILES NCF => FIND_FILE(FILEHEAD,TRIM(Rivers(I)%FILE),FOUND) IF (.NOT.FOUND) CALL FATAL_ERROR & & ("RIVER_DISCHARGE: COULD NOT FIND RIVER FILE OBJECT NAMED: & &"//TRIM(RIVERS(I)%FILE)) IF(.NOT. associated(NCF%FTIME)) CALL FATAL_ERROR& &("RIVER FILE DID NOT LOAD PROPERLY",& & "File name:"//trim(NCF%FNAME),& &"Please check the time format!") IF (NCF%FTIME%PREV_STKCNT /= 999) THEN nfiles = nfiles +1 NCF%FTIME%PREV_STKCNT = 999 END IF END DO ! ALLOCATE THE SPACE FOR THE RIVER FILES AND NULLIFY POINTERS ALLOCATE(RIVER_FORCING(NFILES)) DO I =1,NFILES NULLIFY(RIVER_FORCING(I)%NCF) NULLIFY(RIVER_FORCING(I)%FLUX_N) NULLIFY(RIVER_FORCING(I)%FLUX_P) NULLIFY(RIVER_FORCING(I)%TEMP_N) NULLIFY(RIVER_FORCING(I)%TEMP_P) NULLIFY(RIVER_FORCING(I)%SALT_N) NULLIFY(RIVER_FORCING(I)%SALT_P) # if defined (WATER_QUALITY) NULLIFY(RIVER_FORCING(I)%WQM1_N) NULLIFY(RIVER_FORCING(I)%WQM1_P) NULLIFY(RIVER_FORCING(I)%WQM2_N) NULLIFY(RIVER_FORCING(I)%WQM2_P) NULLIFY(RIVER_FORCING(I)%WQM3_N) NULLIFY(RIVER_FORCING(I)%WQM3_P) NULLIFY(RIVER_FORCING(I)%WQM4_N) NULLIFY(RIVER_FORCING(I)%WQM4_P) NULLIFY(RIVER_FORCING(I)%WQM5_N) NULLIFY(RIVER_FORCING(I)%WQM5_P) NULLIFY(RIVER_FORCING(I)%WQM6_N) NULLIFY(RIVER_FORCING(I)%WQM6_P) NULLIFY(RIVER_FORCING(I)%WQM7_N) NULLIFY(RIVER_FORCING(I)%WQM7_P) NULLIFY(RIVER_FORCING(I)%WQM8_N) NULLIFY(RIVER_FORCING(I)%WQM8_P) # endif # if defined (SEDIMENT) NULLIFY(RIVER_FORCING(I)%SED1_N) NULLIFY(RIVER_FORCING(I)%SED1_P) NULLIFY(RIVER_FORCING(I)%SED2_N) NULLIFY(RIVER_FORCING(I)%SED2_P) NULLIFY(RIVER_FORCING(I)%SED3_N) NULLIFY(RIVER_FORCING(I)%SED3_P) NULLIFY(RIVER_FORCING(I)%SED4_N) NULLIFY(RIVER_FORCING(I)%SED4_P) NULLIFY(RIVER_FORCING(I)%SED5_N) NULLIFY(RIVER_FORCING(I)%SED5_P) NULLIFY(RIVER_FORCING(I)%SED6_N) NULLIFY(RIVER_FORCING(I)%SED6_P) NULLIFY(RIVER_FORCING(I)%SED7_N) NULLIFY(RIVER_FORCING(I)%SED7_P) NULLIFY(RIVER_FORCING(I)%SED8_N) NULLIFY(RIVER_FORCING(I)%SED8_P) NULLIFY(RIVER_FORCING(I)%SED9_N) NULLIFY(RIVER_FORCING(I)%SED9_P) NULLIFY(RIVER_FORCING(I)%SED10_N) NULLIFY(RIVER_FORCING(I)%SED10_P) # endif # if defined (BioGen) NULLIFY(RIVER_FORCING(I)%BIO1_N) NULLIFY(RIVER_FORCING(I)%BIO1_P) NULLIFY(RIVER_FORCING(I)%BIO2_N) NULLIFY(RIVER_FORCING(I)%BIO2_P) NULLIFY(RIVER_FORCING(I)%BIO3_N) NULLIFY(RIVER_FORCING(I)%BIO3_P) NULLIFY(RIVER_FORCING(I)%BIO4_N) NULLIFY(RIVER_FORCING(I)%BIO4_P) NULLIFY(RIVER_FORCING(I)%BIO5_N) NULLIFY(RIVER_FORCING(I)%BIO5_P) NULLIFY(RIVER_FORCING(I)%BIO6_N) NULLIFY(RIVER_FORCING(I)%BIO6_P) NULLIFY(RIVER_FORCING(I)%BIO7_N) NULLIFY(RIVER_FORCING(I)%BIO7_P) NULLIFY(RIVER_FORCING(I)%BIO8_N) NULLIFY(RIVER_FORCING(I)%BIO8_P) NULLIFY(RIVER_FORCING(I)%BIO9_N) NULLIFY(RIVER_FORCING(I)%BIO9_P) NULLIFY(RIVER_FORCING(I)%BIO10_N) NULLIFY(RIVER_FORCING(I)%BIO10_P) NULLIFY(RIVER_FORCING(I)%BIO11_N) NULLIFY(RIVER_FORCING(I)%BIO11_P) NULLIFY(RIVER_FORCING(I)%BIO12_N) NULLIFY(RIVER_FORCING(I)%BIO12_P) NULLIFY(RIVER_FORCING(I)%BIO13_N) NULLIFY(RIVER_FORCING(I)%BIO13_P) NULLIFY(RIVER_FORCING(I)%BIO14_N) NULLIFY(RIVER_FORCING(I)%BIO14_P) NULLIFY(RIVER_FORCING(I)%BIO15_N) NULLIFY(RIVER_FORCING(I)%BIO15_P) NULLIFY(RIVER_FORCING(I)%BIO16_N) NULLIFY(RIVER_FORCING(I)%BIO16_P) NULLIFY(RIVER_FORCING(I)%BIO17_N) NULLIFY(RIVER_FORCING(I)%BIO17_P) NULLIFY(RIVER_FORCING(I)%BIO18_N) NULLIFY(RIVER_FORCING(I)%BIO18_P) NULLIFY(RIVER_FORCING(I)%BIO19_N) NULLIFY(RIVER_FORCING(I)%BIO19_P) NULLIFY(RIVER_FORCING(I)%BIO20_N) NULLIFY(RIVER_FORCING(I)%BIO20_P) # endif END DO ! ALLOCATE THE SPACE FOR THE RIVER DATA ALLOCATE(RIV_GL2LOC(NUMQBC)) ALLOCATE(INODEQ(NUMQBC)) ALLOCATE(ICELLQ(NUMQBC)) ! THE CELL INDEX ALLOCATE(N_ICELLQ(NUMQBC,2)) ! THE NODES BOUNDING THE EDGE ALLOCATE(VQDIST(NUMQBC,KBM1)); VQDIST = 0.0_SP ALLOCATE(QDIS(NUMQBC)); QDIS = 0.0_SP # if !defined (SEMI_IMPLICIT) ALLOCATE(QDIS2(NUMQBC)); QDIS2 = 0.0_SP # endif # if defined (SEDIMENT) ALLOCATE(SEDDIS(NUMQBC,N_SED)); SEDDIS = 0.0_SP # endif # if defined (BioGen) IF(BIOLOGICAL_MODEL)THEN ALLOCATE(BIODIS(NUMQBC,NTT)); BIODIS = 0.0_SP END IF # endif ALLOCATE(TDIS(NUMQBC)); TDIS = 0.0_SP ALLOCATE(SDIS(NUMQBC)); SDIS = 0.0_SP ALLOCATE(QAREA(NUMQBC)); QAREA = 0.0_SP ALLOCATE(ANGLEQ(NUMQBC)); ANGLEQ = 0.0_SP ALLOCATE(VLCTYQ(NUMQBC)); VLCTYQ = 0.0_SP ALLOCATE(RDISQ(NUMQBC,2)); RDISQ = 0.0_SP FCNT = 0 RCNT = 0 DO I =1,river_number ! SET MINE TO FALSE MINE = .false. ! Mine is set true if this river name belongs ! to this processor ! MAKE THE LOCAL AND GLOBAL INDEX SELECT CASE(trim(RIVER_INFLOW_LOCATION)) CASE('node') IF (NLID(RIVERS(I)%LOCATION) .GT. 0) THEN rcnt = rcnt + 1 INODEQ(rcnt) = NLID(RIVERS(I)%LOCATION) RIV_GL2LOC(rcnt) = RIVERS(I)%LOCATION MINE = .TRUE. END IF CASE('edge') IF (ELID(RIVERS(I)%LOCATION) .GT. 0) THEN rcnt = rcnt + 1 ICELLQ(rcnt) = ELID(RIVERS(I)%LOCATION) RIV_GL2LOC(rcnt) = RIVERS(I)%LOCATION MINE = .true. END IF END SELECT ! MAKE VQDIST IF(MINE) THEN !-------------------------------------------------------------------- # if defined(RIVER_FLOAT) !-------------------------------------------------------------------- IF(any(RIVERS(I)%DISTRIBUTION(1:KBM1)<0.0_SP)) CALL FATAL_ERROR& &("You are not permitted to set the river distrobution value less than zero!",& & "This usually indicates a mistake in the name list - not enough layers specifed" ) VQDIST(RCNT,1:kbm1)=RIVERS(I)%DISTRIBUTION(1:KBM1) !-------------------------------------------------------------------- # else !-------------------------------------------------------------------- CALL SET_DISTRIBUTION(RIVERS(I)%DISTRIBUTION,RIVER_INFLOW_LOCATION,RIVERS(I)%LOCATION,MYDIST) VQDIST(RCNT,1:kbm1)=MYDIST !-------------------------------------------------------------------- # endif !-------------------------------------------------------------------- END IF ! NOW PUT THE RIVERS IN THE RIVER_FORCING TYPE NCF => FIND_FILE(FILEHEAD,TRIM(Rivers(I)%FILE),FOUND) IF (NCF%FTIME%PREV_STKCNT == 999) THEN FCNT = FCNT + 1 RIVER_FORCING(FCNT)%NCF => NCF NCF%FTIME%PREV_STKCNT = 0 DIM => FIND_DIM(NCF,'rivers',FOUND) IF(.not.FOUND) CALL FATAL_ERROR & & ("COULD NOT FIND DIMENSION 'rivers'",& & "In the file: "//trim(NCF%FNAME) ) RIVER_FORCING(FCNT)%RIVERS_IN_FILE=DIM%DIM ALLOCATE(RIVER_FORCING(FCNT)%RIV_FILE2LOC(DIM%DIM)) RIVER_FORCING(FCNT)%RIV_FILE2LOC = 0 END IF ! FIGURE OUT WHICH RIVER IT IS WHICH FILE AND SET THE INDEX DO J = 1, NFILES ! IN THIS FILE FIND THE NAME IF (associated(NCF,RIVER_FORCING(J)%NCF)) THEN K=SEARCH_NAME(NCF,Rivers(I)%NAME) ! THIS IS MY RIVER SO SET THE INDEX IF (MINE) RIVER_FORCING(J)%RIV_FILE2LOC(K)=RCNT END IF END DO END DO IF (FCNT /= NFILES) CALL FATAL_ERROR& ("RIVER_DISCHARGE: WE LOST A RIVER FILE IN THE MIDDLE OF NOWHERE!") IF (RCNT /= NUMQBC) CALL FATAL_ERROR& ("RIVER_DISCHARGE: WE LOST A RIVER IN THE MIDDLE OF NOWHERE!") DO I = 1, NFILES NCF => RIVER_FORCING(I)%NCF SELECT CASE (RIVER_KIND) CASE(PRDC) CALL CHECK_RIVER_FILE(NCF, RIVER_FORCING(I)%river_period) CASE(VRBL) CALL CHECK_RIVER_FILE(NCF) CASE DEFAULT CALL FATAL_ERROR("Invalid RIVER_KIND in namelist runfile:",& & " Options are: "//TRIM(PRDC)//" or "//TRIM(VRBL)) END SELECT DIM => FIND_DIM(NCF,'rivers',FOUND) nrs = DIM%dim ! GET THE FLUX VARIABLE VAR => FIND_VAR(NCF,'river_flux',FOUND) ALLOCATE(STORAGE_VEC(nrs), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN RIVER_DISCHARGE") RIVER_FORCING(I)%FLUX_N => reference_var(var) CALL NC_CONNECT_PVAR(RIVER_FORCING(I)%FLUX_N,STORAGE_VEC) NULLIFY(STORAGE_VEC) ALLOCATE(STORAGE_VEC(nrs), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN RIVER_DISCHARGE") RIVER_FORCING(I)%FLUX_P => reference_var(var) CALL NC_CONNECT_PVAR(RIVER_FORCING(I)%FLUX_P,STORAGE_VEC) NULLIFY(STORAGE_VEC) ! GET THE TEMPERATURE VARIABLE VAR => FIND_VAR(NCF,'river_temp',FOUND) ALLOCATE(STORAGE_VEC(nrs), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN RIVER_DISCHARGE") RIVER_FORCING(I)%TEMP_N => reference_var(var) CALL NC_CONNECT_PVAR(RIVER_FORCING(I)%TEMP_N,STORAGE_VEC) NULLIFY(STORAGE_VEC) ALLOCATE(STORAGE_VEC(nrs), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN RIVER_DISCHARGE") RIVER_FORCING(I)%TEMP_P => reference_var(var) CALL NC_CONNECT_PVAR(RIVER_FORCING(I)%TEMP_P,STORAGE_VEC) NULLIFY(STORAGE_VEC) ! GET THE SALINITY VARIABLE VAR => FIND_VAR(NCF,'river_salt',FOUND) ALLOCATE(STORAGE_VEC(nrs), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN RIVER_DISCHARGE") RIVER_FORCING(I)%SALT_N => reference_var(var) CALL NC_CONNECT_PVAR(RIVER_FORCING(I)%SALT_N,STORAGE_VEC) NULLIFY(STORAGE_VEC) ALLOCATE(STORAGE_VEC(nrs), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN RIVER_DISCHARGE") RIVER_FORCING(I)%SALT_P => reference_var(var) CALL NC_CONNECT_PVAR(RIVER_FORCING(I)%SALT_P,STORAGE_VEC) NULLIFY(STORAGE_VEC) ! afm 20160516 & EJA 20160921 RIVER_FORCING(I)%FLUX_N%curr_stkcnt = 0; RIVER_FORCING(I)%FLUX_P%curr_stkcnt = 0 RIVER_FORCING(I)%TEMP_N%curr_stkcnt = 0; RIVER_FORCING(I)%TEMP_P%curr_stkcnt = 0 RIVER_FORCING(I)%SALT_N%curr_stkcnt = 0; RIVER_FORCING(I)%SALT_P%curr_stkcnt = 0 # if defined (WATER_QUALITY) ! GET THE WATER QUALITY VARIABLE VAR => FIND_VAR(NCF,'river_wqm1',FOUND) ALLOCATE(STORAGE_VEC(nrs), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN RIVER_DISCHARGE") RIVER_FORCING(I)%WQM1_N => reference_var(var) CALL NC_CONNECT_PVAR(RIVER_FORCING(I)%WQM1_N,STORAGE_VEC) NULLIFY(STORAGE_VEC) ALLOCATE(STORAGE_VEC(nrs), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN RIVER_DISCHARGE") RIVER_FORCING(I)%WQM1_P => reference_var(var) CALL NC_CONNECT_PVAR(RIVER_FORCING(I)%WQM1_P,STORAGE_VEC) NULLIFY(STORAGE_VEC) VAR => FIND_VAR(NCF,'river_wqm2',FOUND) ALLOCATE(STORAGE_VEC(nrs), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN RIVER_DISCHARGE") RIVER_FORCING(I)%WQM2_N => reference_var(var) CALL NC_CONNECT_PVAR(RIVER_FORCING(I)%WQM2_N,STORAGE_VEC) NULLIFY(STORAGE_VEC) ALLOCATE(STORAGE_VEC(nrs), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN RIVER_DISCHARGE") RIVER_FORCING(I)%WQM2_P => reference_var(var) CALL NC_CONNECT_PVAR(RIVER_FORCING(I)%WQM2_P,STORAGE_VEC) NULLIFY(STORAGE_VEC) VAR => FIND_VAR(NCF,'river_wqm3',FOUND) ALLOCATE(STORAGE_VEC(nrs), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN RIVER_DISCHARGE") RIVER_FORCING(I)%WQM3_N => reference_var(var) CALL NC_CONNECT_PVAR(RIVER_FORCING(I)%WQM3_N,STORAGE_VEC) NULLIFY(STORAGE_VEC) ALLOCATE(STORAGE_VEC(nrs), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN RIVER_DISCHARGE") RIVER_FORCING(I)%WQM3_P => reference_var(var) CALL NC_CONNECT_PVAR(RIVER_FORCING(I)%WQM3_P,STORAGE_VEC) NULLIFY(STORAGE_VEC) VAR => FIND_VAR(NCF,'river_wqm4',FOUND) ALLOCATE(STORAGE_VEC(nrs), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN RIVER_DISCHARGE") RIVER_FORCING(I)%WQM4_N => reference_var(var) CALL NC_CONNECT_PVAR(RIVER_FORCING(I)%WQM4_N,STORAGE_VEC) NULLIFY(STORAGE_VEC) ALLOCATE(STORAGE_VEC(nrs), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN RIVER_DISCHARGE") RIVER_FORCING(I)%WQM4_P => reference_var(var) CALL NC_CONNECT_PVAR(RIVER_FORCING(I)%WQM4_P,STORAGE_VEC) NULLIFY(STORAGE_VEC) VAR => FIND_VAR(NCF,'river_wqm5',FOUND) ALLOCATE(STORAGE_VEC(nrs), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN RIVER_DISCHARGE") RIVER_FORCING(I)%WQM5_N => reference_var(var) CALL NC_CONNECT_PVAR(RIVER_FORCING(I)%WQM5_N,STORAGE_VEC) NULLIFY(STORAGE_VEC) ALLOCATE(STORAGE_VEC(nrs), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN RIVER_DISCHARGE") RIVER_FORCING(I)%WQM5_P => reference_var(var) CALL NC_CONNECT_PVAR(RIVER_FORCING(I)%WQM5_P,STORAGE_VEC) NULLIFY(STORAGE_VEC) VAR => FIND_VAR(NCF,'river_wqm6',FOUND) ALLOCATE(STORAGE_VEC(nrs), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN RIVER_DISCHARGE") RIVER_FORCING(I)%WQM6_N => reference_var(var) CALL NC_CONNECT_PVAR(RIVER_FORCING(I)%WQM6_N,STORAGE_VEC) NULLIFY(STORAGE_VEC) ALLOCATE(STORAGE_VEC(nrs), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN RIVER_DISCHARGE") RIVER_FORCING(I)%WQM6_P => reference_var(var) CALL NC_CONNECT_PVAR(RIVER_FORCING(I)%WQM6_P,STORAGE_VEC) NULLIFY(STORAGE_VEC) VAR => FIND_VAR(NCF,'river_wqm7',FOUND) ALLOCATE(STORAGE_VEC(nrs), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN RIVER_DISCHARGE") RIVER_FORCING(I)%WQM7_N => reference_var(var) CALL NC_CONNECT_PVAR(RIVER_FORCING(I)%WQM7_N,STORAGE_VEC) NULLIFY(STORAGE_VEC) ALLOCATE(STORAGE_VEC(nrs), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN RIVER_DISCHARGE") RIVER_FORCING(I)%WQM7_P => reference_var(var) CALL NC_CONNECT_PVAR(RIVER_FORCING(I)%WQM7_P,STORAGE_VEC) NULLIFY(STORAGE_VEC) VAR => FIND_VAR(NCF,'river_wqm8',FOUND) ALLOCATE(STORAGE_VEC(nrs), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN RIVER_DISCHARGE") RIVER_FORCING(I)%WQM8_N => reference_var(var) CALL NC_CONNECT_PVAR(RIVER_FORCING(I)%WQM8_N,STORAGE_VEC) NULLIFY(STORAGE_VEC) ALLOCATE(STORAGE_VEC(nrs), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN RIVER_DISCHARGE") RIVER_FORCING(I)%WQM8_P => reference_var(var) CALL NC_CONNECT_PVAR(RIVER_FORCING(I)%WQM8_P,STORAGE_VEC) NULLIFY(STORAGE_VEC) ! afm 20160516 & EJA 20160921 river_forcing(i)%wqm1_n%curr_stkcnt = 0; river_forcing(i)%wqm1_p%curr_stkcnt = 0 river_forcing(i)%wqm2_n%curr_stkcnt = 0; river_forcing(i)%wqm2_p%curr_stkcnt = 0 river_forcing(i)%wqm3_n%curr_stkcnt = 0; river_forcing(i)%wqm3_p%curr_stkcnt = 0 river_forcing(i)%wqm4_n%curr_stkcnt = 0; river_forcing(i)%wqm4_p%curr_stkcnt = 0 river_forcing(i)%wqm5_n%curr_stkcnt = 0; river_forcing(i)%wqm5_p%curr_stkcnt = 0 river_forcing(i)%wqm6_n%curr_stkcnt = 0; river_forcing(i)%wqm6_p%curr_stkcnt = 0 river_forcing(i)%wqm7_n%curr_stkcnt = 0; river_forcing(i)%wqm7_p%curr_stkcnt = 0 river_forcing(i)%wqm8_n%curr_stkcnt = 0; river_forcing(i)%wqm8_p%curr_stkcnt = 0 # endif # if defined (SEDIMENT) IF(SEDIMENT_MODEL)THEN ! GET THE SEDIMENT CONCENTRATION FOR SED TYPE 1 IF(N_SED > 0)THEN VAR => FIND_VAR(NCF,TRIM(SED_NAMES(1)),FOUND) IF(.NOT.FOUND)CALL FATAL_ERROR & & ("IN RIVER FILE COULD NOT FIND SED DATA FOR SED TYPE", & & TRIM(SED_NAMES(1)) ) ALLOCATE(STORAGE_VEC(nrs), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN RIVER_DISCHARGE") RIVER_FORCING(I)%SED1_N => reference_var(var) CALL NC_CONNECT_PVAR(RIVER_FORCING(I)%SED1_N,STORAGE_VEC) NULLIFY(STORAGE_VEC) ALLOCATE(STORAGE_VEC(nrs), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN RIVER_DISCHARGE") RIVER_FORCING(I)%SED1_P => reference_var(var) CALL NC_CONNECT_PVAR(RIVER_FORCING(I)%SED1_P,STORAGE_VEC) NULLIFY(STORAGE_VEC) ENDIF ! GET THE SEDIMENT CONCENTRATION FOR SED TYPE 2 IF(N_SED > 1)THEN VAR => FIND_VAR(NCF,TRIM(SED_NAMES(2)),FOUND) IF(.NOT.FOUND)CALL FATAL_ERROR & & ("IN RIVER FILE COULD NOT FIND SED DATA FOR SED TYPE", & & TRIM(SED_NAMES(2)) ) ALLOCATE(STORAGE_VEC(nrs), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN RIVER_DISCHARGE") RIVER_FORCING(I)%SED2_N => reference_var(var) CALL NC_CONNECT_PVAR(RIVER_FORCING(I)%SED2_N,STORAGE_VEC) NULLIFY(STORAGE_VEC) ALLOCATE(STORAGE_VEC(nrs), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN RIVER_DISCHARGE") RIVER_FORCING(I)%SED2_P => reference_var(var) CALL NC_CONNECT_PVAR(RIVER_FORCING(I)%SED2_P,STORAGE_VEC) NULLIFY(STORAGE_VEC) ENDIF ! GET THE SEDIMENT CONCENTRATION FOR SED TYPE 3 IF(N_SED > 2)THEN VAR => FIND_VAR(NCF,TRIM(SED_NAMES(3)),FOUND) IF(.NOT.FOUND)CALL FATAL_ERROR & & ("IN RIVER FILE COULD NOT FIND SED DATA FOR SED TYPE", & & TRIM(SED_NAMES(3)) ) ALLOCATE(STORAGE_VEC(nrs), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN RIVER_DISCHARGE") RIVER_FORCING(I)%SED3_N => reference_var(var) CALL NC_CONNECT_PVAR(RIVER_FORCING(I)%SED3_N,STORAGE_VEC) NULLIFY(STORAGE_VEC) ALLOCATE(STORAGE_VEC(nrs), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN RIVER_DISCHARGE") RIVER_FORCING(I)%SED3_P => reference_var(var) CALL NC_CONNECT_PVAR(RIVER_FORCING(I)%SED3_P,STORAGE_VEC) NULLIFY(STORAGE_VEC) ENDIF ! GET THE SEDIMENT CONCENTRATION FOR SED TYPE 4 IF(N_SED > 3)THEN VAR => FIND_VAR(NCF,TRIM(SED_NAMES(4)),FOUND) IF(.NOT.FOUND)CALL FATAL_ERROR & & ("IN RIVER FILE COULD NOT FIND SED DATA FOR SED TYPE", & & TRIM(SED_NAMES(4)) ) ALLOCATE(STORAGE_VEC(nrs), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN RIVER_DISCHARGE") RIVER_FORCING(I)%SED4_N => reference_var(var) CALL NC_CONNECT_PVAR(RIVER_FORCING(I)%SED4_N,STORAGE_VEC) NULLIFY(STORAGE_VEC) ALLOCATE(STORAGE_VEC(nrs), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN RIVER_DISCHARGE") RIVER_FORCING(I)%SED4_P => reference_var(var) CALL NC_CONNECT_PVAR(RIVER_FORCING(I)%SED4_P,STORAGE_VEC) NULLIFY(STORAGE_VEC) ENDIF ! GET THE SEDIMENT CONCENTRATION FOR SED TYPE 5 IF(N_SED > 4)THEN VAR => FIND_VAR(NCF,TRIM(SED_NAMES(5)),FOUND) IF(.NOT.FOUND)CALL FATAL_ERROR & & ("IN RIVER FILE COULD NOT FIND SED DATA FOR SED TYPE", & & TRIM(SED_NAMES(5)) ) ALLOCATE(STORAGE_VEC(nrs), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN RIVER_DISCHARGE") RIVER_FORCING(I)%SED5_N => reference_var(var) CALL NC_CONNECT_PVAR(RIVER_FORCING(I)%SED5_N,STORAGE_VEC) NULLIFY(STORAGE_VEC) ALLOCATE(STORAGE_VEC(nrs), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN RIVER_DISCHARGE") RIVER_FORCING(I)%SED5_P => reference_var(var) CALL NC_CONNECT_PVAR(RIVER_FORCING(I)%SED5_P,STORAGE_VEC) NULLIFY(STORAGE_VEC) ENDIF ! GET THE SEDIMENT CONCENTRATION FOR SED TYPE 6 IF(N_SED > 5)THEN ! GET THE SEDIMENT CONCENTRATION FOR SED TYPE 6 VAR => FIND_VAR(NCF,TRIM(SED_NAMES(6)),FOUND) IF(.NOT.FOUND)CALL FATAL_ERROR & & ("IN RIVER FILE COULD NOT FIND SED DATA FOR SED TYPE", & & TRIM(SED_NAMES(6)) ) ALLOCATE(STORAGE_VEC(nrs), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN RIVER_DISCHARGE") RIVER_FORCING(I)%SED6_N => reference_var(var) CALL NC_CONNECT_PVAR(RIVER_FORCING(I)%SED6_N,STORAGE_VEC) NULLIFY(STORAGE_VEC) ALLOCATE(STORAGE_VEC(nrs), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN RIVER_DISCHARGE") RIVER_FORCING(I)%SED6_P => reference_var(var) CALL NC_CONNECT_PVAR(RIVER_FORCING(I)%SED6_P,STORAGE_VEC) NULLIFY(STORAGE_VEC) ENDIF ! GET THE SEDIMENT CONCENTRATION FOR SED TYPE 7 IF(N_SED > 6)THEN ! GET THE SEDIMENT CONCENTRATION FOR SED TYPE 7 VAR => FIND_VAR(NCF,TRIM(SED_NAMES(7)),FOUND) IF(.NOT.FOUND)CALL FATAL_ERROR & & ("IN RIVER FILE COULD NOT FIND SED DATA FOR SED TYPE", & & TRIM(SED_NAMES(7)) ) ALLOCATE(STORAGE_VEC(nrs), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN RIVER_DISCHARGE") RIVER_FORCING(I)%SED7_N => reference_var(var) CALL NC_CONNECT_PVAR(RIVER_FORCING(I)%SED7_N,STORAGE_VEC) NULLIFY(STORAGE_VEC) ALLOCATE(STORAGE_VEC(nrs), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN RIVER_DISCHARGE") RIVER_FORCING(I)%SED7_P => reference_var(var) CALL NC_CONNECT_PVAR(RIVER_FORCING(I)%SED7_P,STORAGE_VEC) NULLIFY(STORAGE_VEC) ENDIF ! GET THE SEDIMENT CONCENTRATION FOR SED TYPE 8 IF(N_SED > 7)THEN VAR => FIND_VAR(NCF,TRIM(SED_NAMES(8)),FOUND) IF(.NOT.FOUND)CALL FATAL_ERROR & & ("IN RIVER FILE COULD NOT FIND SED DATA FOR SED TYPE", & & TRIM(SED_NAMES(8)) ) ALLOCATE(STORAGE_VEC(nrs), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN RIVER_DISCHARGE") RIVER_FORCING(I)%SED8_N => reference_var(var) CALL NC_CONNECT_PVAR(RIVER_FORCING(I)%SED8_N,STORAGE_VEC) NULLIFY(STORAGE_VEC) ALLOCATE(STORAGE_VEC(nrs), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN RIVER_DISCHARGE") RIVER_FORCING(I)%SED8_P => reference_var(var) CALL NC_CONNECT_PVAR(RIVER_FORCING(I)%SED8_P,STORAGE_VEC) NULLIFY(STORAGE_VEC) ENDIF ! GET THE SEDIMENT CONCENTRATION FOR SED TYPE 9 IF(N_SED > 8)THEN VAR => FIND_VAR(NCF,TRIM(SED_NAMES(9)),FOUND) IF(.NOT.FOUND)CALL FATAL_ERROR & & ("IN RIVER FILE COULD NOT FIND SED DATA FOR SED TYPE", & & TRIM(SED_NAMES(9)) ) ALLOCATE(STORAGE_VEC(nrs), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN RIVER_DISCHARGE") RIVER_FORCING(I)%SED9_N => reference_var(var) CALL NC_CONNECT_PVAR(RIVER_FORCING(I)%SED9_N,STORAGE_VEC) NULLIFY(STORAGE_VEC) ALLOCATE(STORAGE_VEC(nrs), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN RIVER_DISCHARGE") RIVER_FORCING(I)%SED9_P => reference_var(var) CALL NC_CONNECT_PVAR(RIVER_FORCING(I)%SED9_P,STORAGE_VEC) NULLIFY(STORAGE_VEC) ENDIF ! GET THE SEDIMENT CONCENTRATION FOR SED TYPE 10 IF(N_SED > 9)THEN VAR => FIND_VAR(NCF,TRIM(SED_NAMES(10)),FOUND) IF(.NOT.FOUND)CALL FATAL_ERROR & & ("IN RIVER FILE COULD NOT FIND SED DATA FOR SED TYPE", & & TRIM(SED_NAMES(10)) ) ALLOCATE(STORAGE_VEC(nrs), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN RIVER_DISCHARGE") RIVER_FORCING(I)%SED10_N => reference_var(var) CALL NC_CONNECT_PVAR(RIVER_FORCING(I)%SED10_N,STORAGE_VEC) NULLIFY(STORAGE_VEC) ALLOCATE(STORAGE_VEC(nrs), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN RIVER_DISCHARGE") RIVER_FORCING(I)%SED10_P => reference_var(var) CALL NC_CONNECT_PVAR(RIVER_FORCING(I)%SED10_P,STORAGE_VEC) NULLIFY(STORAGE_VEC) ENDIF IF(N_SED > 10)THEN CALL FATAL_ERROR & & ("MOD_FORCE NOT SETUP FOR N_SED > 10 REVISE") ENDIF ! ---------- new: 2016 , april, Karsten Lettmann after Hint by Qi and ayumi.fujisaki@noaa.gov------ ! Initialize some variables ! afm 20160216 ! Need initialization. Otherwise, random values are asigned ! and cause a hanging problem of MPI job in UPDATE_VAR_BRACKET ! This problem reported with Intel15.0.3. if(n_sed>0)then river_forcing(i)%sed1_n%curr_stkcnt = 0; river_forcing(i)%sed1_p%curr_stkcnt = 0 end if if(n_sed>1)then river_forcing(i)%sed2_n%curr_stkcnt = 0; river_forcing(i)%sed2_p%curr_stkcnt = 0 end if if(n_sed>2)then river_forcing(i)%sed3_n%curr_stkcnt = 0; river_forcing(i)%sed3_p%curr_stkcnt = 0 end if if(n_sed>3)then river_forcing(i)%sed4_n%curr_stkcnt = 0; river_forcing(i)%sed4_p%curr_stkcnt = 0 end if if(n_sed>4)then river_forcing(i)%sed5_n%curr_stkcnt = 0; river_forcing(i)%sed5_p%curr_stkcnt = 0 end if if(n_sed>5)then river_forcing(i)%sed6_n%curr_stkcnt = 0; river_forcing(i)%sed6_p%curr_stkcnt = 0 end if if(n_sed>6)then river_forcing(i)%sed7_n%curr_stkcnt = 0; river_forcing(i)%sed7_p%curr_stkcnt = 0 end if if(n_sed>7)then river_forcing(i)%sed8_n%curr_stkcnt = 0; river_forcing(i)%sed8_p%curr_stkcnt = 0 end if if(n_sed>8)then river_forcing(i)%sed9_n%curr_stkcnt = 0; river_forcing(i)%sed9_p%curr_stkcnt = 0 end if if(n_sed>9)then river_forcing(i)%sed10_n%curr_stkcnt = 0; river_forcing(i)%sed10_p%curr_stkcnt = 0 end if ! -------------------------------------------------------------------------------- ENDIF !SEDIMENT_MODEL ACTIVE # endif # if defined (BioGen) IF(BIOLOGICAL_MODEL)THEN ! GET THE BIOLOGICAL CONCENTRATION FOR BIO TYPE 1 IF(NTT > 0)THEN VAR => FIND_VAR(NCF,TRIM(BIO_NAME(1,1)),FOUND) IF(.NOT.FOUND)CALL FATAL_ERROR & & ("IN RIVER FILE COULD NOT FIND BIO DATA FOR BIO TYPE", & & TRIM(BIO_NAME(1,1)) ) ALLOCATE(STORAGE_VEC(nrs), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN RIVER_DISCHARGE") RIVER_FORCING(I)%BIO1_N => reference_var(var) CALL NC_CONNECT_PVAR(RIVER_FORCING(I)%BIO1_N,STORAGE_VEC) NULLIFY(STORAGE_VEC) ALLOCATE(STORAGE_VEC(nrs), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN RIVER_DISCHARGE") RIVER_FORCING(I)%BIO1_P => reference_var(var) CALL NC_CONNECT_PVAR(RIVER_FORCING(I)%BIO1_P,STORAGE_VEC) NULLIFY(STORAGE_VEC) ENDIF ! GET THE BIOLOGICAL CONCENTRATION FOR BIO TYPE 2 IF(NTT > 1)THEN VAR => FIND_VAR(NCF,TRIM(BIO_NAME(2,1)),FOUND) IF(.NOT.FOUND)CALL FATAL_ERROR & & ("IN RIVER FILE COULD NOT FIND BIO DATA FOR BIO TYPE", & & TRIM(BIO_NAME(2,1)) ) ALLOCATE(STORAGE_VEC(nrs), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN RIVER_DISCHARGE") RIVER_FORCING(I)%BIO2_N => reference_var(var) CALL NC_CONNECT_PVAR(RIVER_FORCING(I)%BIO2_N,STORAGE_VEC) NULLIFY(STORAGE_VEC) ALLOCATE(STORAGE_VEC(nrs), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN RIVER_DISCHARGE") RIVER_FORCING(I)%BIO2_P => reference_var(var) CALL NC_CONNECT_PVAR(RIVER_FORCING(I)%BIO2_P,STORAGE_VEC) NULLIFY(STORAGE_VEC) ENDIF ! GET THE BIOLOGICAL CONCENTRATION FOR BIO TYPE 3 IF(NTT > 2)THEN VAR => FIND_VAR(NCF,TRIM(BIO_NAME(3,1)),FOUND) IF(.NOT.FOUND)CALL FATAL_ERROR & & ("IN RIVER FILE COULD NOT FIND BIO DATA FOR BIO TYPE", & & TRIM(BIO_NAME(3,1)) ) ALLOCATE(STORAGE_VEC(nrs), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN RIVER_DISCHARGE") RIVER_FORCING(I)%BIO3_N => reference_var(var) CALL NC_CONNECT_PVAR(RIVER_FORCING(I)%BIO3_N,STORAGE_VEC) NULLIFY(STORAGE_VEC) ALLOCATE(STORAGE_VEC(nrs), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN RIVER_DISCHARGE") RIVER_FORCING(I)%BIO3_P => reference_var(var) CALL NC_CONNECT_PVAR(RIVER_FORCING(I)%BIO3_P,STORAGE_VEC) NULLIFY(STORAGE_VEC) ENDIF ! GET THE BIOLOGICAL CONCENTRATION FOR BIO TYPE 4 IF(NTT > 3)THEN VAR => FIND_VAR(NCF,TRIM(BIO_NAME(4,1)),FOUND) IF(.NOT.FOUND)CALL FATAL_ERROR & & ("IN RIVER FILE COULD NOT FIND BIO DATA FOR BIO TYPE", & & TRIM(BIO_NAME(4,1)) ) ALLOCATE(STORAGE_VEC(nrs), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN RIVER_DISCHARGE") RIVER_FORCING(I)%BIO4_N => reference_var(var) CALL NC_CONNECT_PVAR(RIVER_FORCING(I)%BIO4_N,STORAGE_VEC) NULLIFY(STORAGE_VEC) ALLOCATE(STORAGE_VEC(nrs), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN RIVER_DISCHARGE") RIVER_FORCING(I)%BIO4_P => reference_var(var) CALL NC_CONNECT_PVAR(RIVER_FORCING(I)%BIO4_P,STORAGE_VEC) NULLIFY(STORAGE_VEC) ENDIF ! GET THE BIOLOGICAL CONCENTRATION FOR BIO TYPE 5 IF(NTT > 4)THEN VAR => FIND_VAR(NCF,TRIM(BIO_NAME(5,1)),FOUND) IF(.NOT.FOUND)CALL FATAL_ERROR & & ("IN RIVER FILE COULD NOT FIND BIO DATA FOR BIO TYPE", & & TRIM(BIO_NAME(5,1)) ) ALLOCATE(STORAGE_VEC(nrs), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN RIVER_DISCHARGE") RIVER_FORCING(I)%BIO5_N => reference_var(var) CALL NC_CONNECT_PVAR(RIVER_FORCING(I)%BIO5_N,STORAGE_VEC) NULLIFY(STORAGE_VEC) ALLOCATE(STORAGE_VEC(nrs), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN RIVER_DISCHARGE") RIVER_FORCING(I)%BIO5_P => reference_var(var) CALL NC_CONNECT_PVAR(RIVER_FORCING(I)%BIO5_P,STORAGE_VEC) NULLIFY(STORAGE_VEC) ENDIF ! GET THE BIOLOGICAL CONCENTRATION FOR BIO TYPE 6 IF(NTT > 5)THEN VAR => FIND_VAR(NCF,TRIM(BIO_NAME(6,1)),FOUND) IF(.NOT.FOUND)CALL FATAL_ERROR & & ("IN RIVER FILE COULD NOT FIND BIO DATA FOR BIO TYPE", & & TRIM(BIO_NAME(6,1)) ) ALLOCATE(STORAGE_VEC(nrs), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN RIVER_DISCHARGE") RIVER_FORCING(I)%BIO6_N => reference_var(var) CALL NC_CONNECT_PVAR(RIVER_FORCING(I)%BIO6_N,STORAGE_VEC) NULLIFY(STORAGE_VEC) ALLOCATE(STORAGE_VEC(nrs), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN RIVER_DISCHARGE") RIVER_FORCING(I)%BIO6_P => reference_var(var) CALL NC_CONNECT_PVAR(RIVER_FORCING(I)%BIO6_P,STORAGE_VEC) NULLIFY(STORAGE_VEC) ENDIF ! GET THE BIOLOGICAL CONCENTRATION FOR BIO TYPE 7 IF(NTT > 6)THEN VAR => FIND_VAR(NCF,TRIM(BIO_NAME(7,1)),FOUND) IF(.NOT.FOUND)CALL FATAL_ERROR & & ("IN RIVER FILE COULD NOT FIND BIO DATA FOR BIO TYPE", & & TRIM(BIO_NAME(7,1)) ) ALLOCATE(STORAGE_VEC(nrs), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN RIVER_DISCHARGE") RIVER_FORCING(I)%BIO7_N => reference_var(var) CALL NC_CONNECT_PVAR(RIVER_FORCING(I)%BIO7_N,STORAGE_VEC) NULLIFY(STORAGE_VEC) ALLOCATE(STORAGE_VEC(nrs), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN RIVER_DISCHARGE") RIVER_FORCING(I)%BIO7_P => reference_var(var) CALL NC_CONNECT_PVAR(RIVER_FORCING(I)%BIO7_P,STORAGE_VEC) NULLIFY(STORAGE_VEC) ENDIF ! GET THE BIOLOGICAL CONCENTRATION FOR BIO TYPE 8 IF(NTT > 7)THEN VAR => FIND_VAR(NCF,TRIM(BIO_NAME(8,1)),FOUND) IF(.NOT.FOUND)CALL FATAL_ERROR & & ("IN RIVER FILE COULD NOT FIND BIO DATA FOR BIO TYPE", & & TRIM(BIO_NAME(8,1)) ) ALLOCATE(STORAGE_VEC(nrs), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN RIVER_DISCHARGE") RIVER_FORCING(I)%BIO8_N => reference_var(var) CALL NC_CONNECT_PVAR(RIVER_FORCING(I)%BIO8_N,STORAGE_VEC) NULLIFY(STORAGE_VEC) ALLOCATE(STORAGE_VEC(nrs), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN RIVER_DISCHARGE") RIVER_FORCING(I)%BIO8_P => reference_var(var) CALL NC_CONNECT_PVAR(RIVER_FORCING(I)%BIO8_P,STORAGE_VEC) NULLIFY(STORAGE_VEC) ENDIF ! GET THE BIOLOGICAL CONCENTRATION FOR BIO TYPE 9 IF(NTT > 8)THEN VAR => FIND_VAR(NCF,TRIM(BIO_NAME(9,1)),FOUND) IF(.NOT.FOUND)CALL FATAL_ERROR & & ("IN RIVER FILE COULD NOT FIND BIO DATA FOR BIO TYPE", & & TRIM(BIO_NAME(9,1)) ) ALLOCATE(STORAGE_VEC(nrs), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN RIVER_DISCHARGE") RIVER_FORCING(I)%BIO9_N => reference_var(var) CALL NC_CONNECT_PVAR(RIVER_FORCING(I)%BIO9_N,STORAGE_VEC) NULLIFY(STORAGE_VEC) ALLOCATE(STORAGE_VEC(nrs), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN RIVER_DISCHARGE") RIVER_FORCING(I)%BIO9_P => reference_var(var) CALL NC_CONNECT_PVAR(RIVER_FORCING(I)%BIO9_P,STORAGE_VEC) NULLIFY(STORAGE_VEC) ENDIF ! GET THE BIOLOGICAL CONCENTRATION FOR BIO TYPE 10 IF(NTT > 9)THEN VAR => FIND_VAR(NCF,TRIM(BIO_NAME(10,1)),FOUND) IF(.NOT.FOUND)CALL FATAL_ERROR & & ("IN RIVER FILE COULD NOT FIND BIO DATA FOR BIO TYPE", & & TRIM(BIO_NAME(10,1)) ) ALLOCATE(STORAGE_VEC(nrs), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN RIVER_DISCHARGE") RIVER_FORCING(I)%BIO10_N => reference_var(var) CALL NC_CONNECT_PVAR(RIVER_FORCING(I)%BIO10_N,STORAGE_VEC) NULLIFY(STORAGE_VEC) ALLOCATE(STORAGE_VEC(nrs), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN RIVER_DISCHARGE") RIVER_FORCING(I)%BIO10_P => reference_var(var) CALL NC_CONNECT_PVAR(RIVER_FORCING(I)%BIO10_P,STORAGE_VEC) NULLIFY(STORAGE_VEC) ENDIF ! GET THE BIOLOGICAL CONCENTRATION FOR BIO TYPE 11 IF(NTT > 10)THEN VAR => FIND_VAR(NCF,TRIM(BIO_NAME(11,1)),FOUND) IF(.NOT.FOUND)CALL FATAL_ERROR & & ("IN RIVER FILE COULD NOT FIND BIO DATA FOR BIO TYPE", & & TRIM(BIO_NAME(11,1)) ) ALLOCATE(STORAGE_VEC(nrs), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN RIVER_DISCHARGE") RIVER_FORCING(I)%BIO11_N => reference_var(var) CALL NC_CONNECT_PVAR(RIVER_FORCING(I)%BIO11_N,STORAGE_VEC) NULLIFY(STORAGE_VEC) ALLOCATE(STORAGE_VEC(nrs), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN RIVER_DISCHARGE") RIVER_FORCING(I)%BIO11_P => reference_var(var) CALL NC_CONNECT_PVAR(RIVER_FORCING(I)%BIO11_P,STORAGE_VEC) NULLIFY(STORAGE_VEC) ENDIF ! GET THE BIOLOGICAL CONCENTRATION FOR BIO TYPE 12 IF(NTT > 11)THEN VAR => FIND_VAR(NCF,TRIM(BIO_NAME(12,1)),FOUND) IF(.NOT.FOUND)CALL FATAL_ERROR & & ("IN RIVER FILE COULD NOT FIND BIO DATA FOR BIO TYPE", & & TRIM(BIO_NAME(12,1)) ) ALLOCATE(STORAGE_VEC(nrs), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN RIVER_DISCHARGE") RIVER_FORCING(I)%BIO12_N => reference_var(var) CALL NC_CONNECT_PVAR(RIVER_FORCING(I)%BIO12_N,STORAGE_VEC) NULLIFY(STORAGE_VEC) ALLOCATE(STORAGE_VEC(nrs), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN RIVER_DISCHARGE") RIVER_FORCING(I)%BIO12_P => reference_var(var) CALL NC_CONNECT_PVAR(RIVER_FORCING(I)%BIO12_P,STORAGE_VEC) NULLIFY(STORAGE_VEC) ENDIF ! GET THE BIOLOGICAL CONCENTRATION FOR BIO TYPE 13 IF(NTT > 12)THEN VAR => FIND_VAR(NCF,TRIM(BIO_NAME(13,1)),FOUND) IF(.NOT.FOUND)CALL FATAL_ERROR & & ("IN RIVER FILE COULD NOT FIND BIO DATA FOR BIO TYPE", & & TRIM(BIO_NAME(13,1)) ) ALLOCATE(STORAGE_VEC(nrs), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN RIVER_DISCHARGE") RIVER_FORCING(I)%BIO13_N => reference_var(var) CALL NC_CONNECT_PVAR(RIVER_FORCING(I)%BIO13_N,STORAGE_VEC) NULLIFY(STORAGE_VEC) ALLOCATE(STORAGE_VEC(nrs), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN RIVER_DISCHARGE") RIVER_FORCING(I)%BIO13_P => reference_var(var) CALL NC_CONNECT_PVAR(RIVER_FORCING(I)%BIO13_P,STORAGE_VEC) NULLIFY(STORAGE_VEC) ENDIF ! GET THE BIOLOGICAL CONCENTRATION FOR BIO TYPE 14 IF(NTT > 13)THEN VAR => FIND_VAR(NCF,TRIM(BIO_NAME(14,1)),FOUND) IF(.NOT.FOUND)CALL FATAL_ERROR & & ("IN RIVER FILE COULD NOT FIND BIO DATA FOR BIO TYPE", & & TRIM(BIO_NAME(14,1)) ) ALLOCATE(STORAGE_VEC(nrs), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN RIVER_DISCHARGE") RIVER_FORCING(I)%BIO14_N => reference_var(var) CALL NC_CONNECT_PVAR(RIVER_FORCING(I)%BIO14_N,STORAGE_VEC) NULLIFY(STORAGE_VEC) ALLOCATE(STORAGE_VEC(nrs), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN RIVER_DISCHARGE") RIVER_FORCING(I)%BIO14_P => reference_var(var) CALL NC_CONNECT_PVAR(RIVER_FORCING(I)%BIO14_P,STORAGE_VEC) NULLIFY(STORAGE_VEC) ENDIF ! GET THE BIOLOGICAL CONCENTRATION FOR BIO TYPE 15 IF(NTT > 14)THEN VAR => FIND_VAR(NCF,TRIM(BIO_NAME(15,1)),FOUND) IF(.NOT.FOUND)CALL FATAL_ERROR & & ("IN RIVER FILE COULD NOT FIND BIO DATA FOR BIO TYPE", & & TRIM(BIO_NAME(15,1)) ) ALLOCATE(STORAGE_VEC(nrs), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN RIVER_DISCHARGE") RIVER_FORCING(I)%BIO15_N => reference_var(var) CALL NC_CONNECT_PVAR(RIVER_FORCING(I)%BIO15_N,STORAGE_VEC) NULLIFY(STORAGE_VEC) ALLOCATE(STORAGE_VEC(nrs), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN RIVER_DISCHARGE") RIVER_FORCING(I)%BIO15_P => reference_var(var) CALL NC_CONNECT_PVAR(RIVER_FORCING(I)%BIO15_P,STORAGE_VEC) NULLIFY(STORAGE_VEC) ENDIF ! GET THE BIOLOGICAL CONCENTRATION FOR BIO TYPE 16 IF(NTT > 15)THEN VAR => FIND_VAR(NCF,TRIM(BIO_NAME(16,1)),FOUND) IF(.NOT.FOUND)CALL FATAL_ERROR & & ("IN RIVER FILE COULD NOT FIND BIO DATA FOR BIO TYPE", & & TRIM(BIO_NAME(16,1)) ) ALLOCATE(STORAGE_VEC(nrs), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN RIVER_DISCHARGE") RIVER_FORCING(I)%BIO16_N => reference_var(var) CALL NC_CONNECT_PVAR(RIVER_FORCING(I)%BIO16_N,STORAGE_VEC) NULLIFY(STORAGE_VEC) ALLOCATE(STORAGE_VEC(nrs), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN RIVER_DISCHARGE") RIVER_FORCING(I)%BIO16_P => reference_var(var) CALL NC_CONNECT_PVAR(RIVER_FORCING(I)%BIO16_P,STORAGE_VEC) NULLIFY(STORAGE_VEC) ENDIF ! GET THE BIOLOGICAL CONCENTRATION FOR BIO TYPE 17 IF(NTT > 16)THEN VAR => FIND_VAR(NCF,TRIM(BIO_NAME(17,1)),FOUND) IF(.NOT.FOUND)CALL FATAL_ERROR & & ("IN RIVER FILE COULD NOT FIND BIO DATA FOR BIO TYPE", & & TRIM(BIO_NAME(17,1)) ) ALLOCATE(STORAGE_VEC(nrs), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN RIVER_DISCHARGE") RIVER_FORCING(I)%BIO17_N => reference_var(var) CALL NC_CONNECT_PVAR(RIVER_FORCING(I)%BIO17_N,STORAGE_VEC) NULLIFY(STORAGE_VEC) ALLOCATE(STORAGE_VEC(nrs), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN RIVER_DISCHARGE") RIVER_FORCING(I)%BIO17_P => reference_var(var) CALL NC_CONNECT_PVAR(RIVER_FORCING(I)%BIO17_P,STORAGE_VEC) NULLIFY(STORAGE_VEC) ENDIF ! GET THE BIOLOGICAL CONCENTRATION FOR BIO TYPE 18 IF(NTT > 17)THEN VAR => FIND_VAR(NCF,TRIM(BIO_NAME(18,1)),FOUND) IF(.NOT.FOUND)CALL FATAL_ERROR & & ("IN RIVER FILE COULD NOT FIND BIO DATA FOR BIO TYPE", & & TRIM(BIO_NAME(18,1)) ) ALLOCATE(STORAGE_VEC(nrs), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN RIVER_DISCHARGE") RIVER_FORCING(I)%BIO18_N => reference_var(var) CALL NC_CONNECT_PVAR(RIVER_FORCING(I)%BIO18_N,STORAGE_VEC) NULLIFY(STORAGE_VEC) ALLOCATE(STORAGE_VEC(nrs), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN RIVER_DISCHARGE") RIVER_FORCING(I)%BIO18_P => reference_var(var) CALL NC_CONNECT_PVAR(RIVER_FORCING(I)%BIO18_P,STORAGE_VEC) NULLIFY(STORAGE_VEC) ENDIF ! GET THE BIOLOGICAL CONCENTRATION FOR BIO TYPE 19 IF(NTT > 18)THEN VAR => FIND_VAR(NCF,TRIM(BIO_NAME(19,1)),FOUND) IF(.NOT.FOUND)CALL FATAL_ERROR & & ("IN RIVER FILE COULD NOT FIND BIO DATA FOR BIO TYPE", & & TRIM(BIO_NAME(19,1)) ) ALLOCATE(STORAGE_VEC(nrs), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN RIVER_DISCHARGE") RIVER_FORCING(I)%BIO19_N => reference_var(var) CALL NC_CONNECT_PVAR(RIVER_FORCING(I)%BIO19_N,STORAGE_VEC) NULLIFY(STORAGE_VEC) ALLOCATE(STORAGE_VEC(nrs), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN RIVER_DISCHARGE") RIVER_FORCING(I)%BIO19_P => reference_var(var) CALL NC_CONNECT_PVAR(RIVER_FORCING(I)%BIO19_P,STORAGE_VEC) NULLIFY(STORAGE_VEC) ENDIF ! GET THE BIOLOGICAL CONCENTRATION FOR BIO TYPE 20 IF(NTT > 19)THEN VAR => FIND_VAR(NCF,TRIM(BIO_NAME(20,1)),FOUND) IF(.NOT.FOUND)CALL FATAL_ERROR & & ("IN RIVER FILE COULD NOT FIND BIO DATA FOR BIO TYPE", & & TRIM(BIO_NAME(20,1)) ) ALLOCATE(STORAGE_VEC(nrs), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN RIVER_DISCHARGE") RIVER_FORCING(I)%BIO20_N => reference_var(var) CALL NC_CONNECT_PVAR(RIVER_FORCING(I)%BIO20_N,STORAGE_VEC) NULLIFY(STORAGE_VEC) ALLOCATE(STORAGE_VEC(nrs), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN RIVER_DISCHARGE") RIVER_FORCING(I)%BIO20_P => reference_var(var) CALL NC_CONNECT_PVAR(RIVER_FORCING(I)%BIO20_P,STORAGE_VEC) NULLIFY(STORAGE_VEC) ENDIF IF(NTT > 20)THEN CALL FATAL_ERROR & & ("MOD_FORCE NOT SETUP FOR NTT > 20 REVISE") ENDIF ! ---------- new: 2016 , april, Karsten Lettmann after Hint by Qi and ayumi.fujisaki@noaa.gov------ ! Initialize some variables ! afm 20160216 ! Need initialization. Otherwise, random values are asigned ! and cause a hanging problem of MPI job in UPDATE_VAR_BRACKET ! This problem reported with Intel15.0.3. IF(NTT > 0)THEN RIVER_FORCING(I)%BIO1_N%CURR_STKCNT = 0; RIVER_FORCING(I)%BIO1_P%CURR_STKCNT = 0; END IF IF(NTT > 1)THEN RIVER_FORCING(I)%BIO2_N%CURR_STKCNT = 0; RIVER_FORCING(I)%BIO2_P%CURR_STKCNT = 0; END IF IF(NTT > 2)THEN RIVER_FORCING(I)%BIO3_N%CURR_STKCNT = 0; RIVER_FORCING(I)%BIO3_P%CURR_STKCNT = 0; END IF IF(NTT > 3)THEN RIVER_FORCING(I)%BIO4_N%CURR_STKCNT = 0; RIVER_FORCING(I)%BIO4_P%CURR_STKCNT = 0; END IF IF(NTT > 4)THEN RIVER_FORCING(I)%BIO5_N%CURR_STKCNT = 0; RIVER_FORCING(I)%BIO5_P%CURR_STKCNT = 0; END IF IF(NTT > 5)THEN RIVER_FORCING(I)%BIO6_N%CURR_STKCNT = 0; RIVER_FORCING(I)%BIO6_P%CURR_STKCNT = 0; END IF IF(NTT > 6)THEN RIVER_FORCING(I)%BIO7_N%CURR_STKCNT = 0; RIVER_FORCING(I)%BIO7_P%CURR_STKCNT = 0; END IF IF(NTT > 7)THEN RIVER_FORCING(I)%BIO8_N%CURR_STKCNT = 0; RIVER_FORCING(I)%BIO8_P%CURR_STKCNT = 0; END IF IF(NTT > 8)THEN RIVER_FORCING(I)%BIO9_N%CURR_STKCNT = 0; RIVER_FORCING(I)%BIO9_P%CURR_STKCNT = 0; END IF IF(NTT > 9)THEN RIVER_FORCING(I)%BIO10_N%CURR_STKCNT = 0; RIVER_FORCING(I)%BIO10_P%CURR_STKCNT = 0; END IF IF(NTT > 10)THEN RIVER_FORCING(I)%BIO11_N%CURR_STKCNT = 0; RIVER_FORCING(I)%BIO11_P%CURR_STKCNT = 0; END IF IF(NTT > 11)THEN RIVER_FORCING(I)%BIO12_N%CURR_STKCNT = 0; RIVER_FORCING(I)%BIO12_P%CURR_STKCNT = 0; END IF IF(NTT > 12)THEN RIVER_FORCING(I)%BIO13_N%CURR_STKCNT = 0; RIVER_FORCING(I)%BIO13_P%CURR_STKCNT = 0; END IF IF(NTT > 13)THEN RIVER_FORCING(I)%BIO14_N%CURR_STKCNT = 0; RIVER_FORCING(I)%BIO14_P%CURR_STKCNT = 0; END IF IF(NTT > 14)THEN RIVER_FORCING(I)%BIO15_N%CURR_STKCNT = 0; RIVER_FORCING(I)%BIO15_P%CURR_STKCNT = 0; END IF IF(NTT > 15)THEN RIVER_FORCING(I)%BIO16_N%CURR_STKCNT = 0; RIVER_FORCING(I)%BIO16_P%CURR_STKCNT = 0; END IF IF(NTT > 16)THEN RIVER_FORCING(I)%BIO17_N%CURR_STKCNT = 0; RIVER_FORCING(I)%BIO17_P%CURR_STKCNT = 0; END IF IF(NTT > 17)THEN RIVER_FORCING(I)%BIO18_N%CURR_STKCNT = 0; RIVER_FORCING(I)%BIO18_P%CURR_STKCNT = 0; END IF IF(NTT > 18)THEN RIVER_FORCING(I)%BIO19_N%CURR_STKCNT = 0; RIVER_FORCING(I)%BIO19_P%CURR_STKCNT = 0; END IF IF(NTT > 19)THEN RIVER_FORCING(I)%BIO20_N%CURR_STKCNT = 0; RIVER_FORCING(I)%BIO20_P%CURR_STKCNT = 0; END IF ! -------------------------------------------------------------------------------- ENDIF !BIOLOGICAL_MODEL ACTIVE # endif END DO ! SET THE RIVER BNDRY METRICS - USED TO BE SET_BNDRY CALL SET_RIVER_BNDRY_METRICS IF(DBG_SET(DBG_LOG)) THEN WRITE(IPT,*)"!" WRITE(IPT,*)"! RIVER FORCING ON" WRITE(IPT,*)'! GLOBAL NUMBER OF RIVERS :',river_number WRITE(IPT,*)'! NUMBER OF RIVER FILES :', nfiles END IF IF(DBG_SET(DBG_SCL)) THEN WRITE(IPT,*)"/////////=============================///////////" WRITE(IPT,*)" PRINTING RIVER FORCING DETAILS" WRITE(IPT,*)" LOCAL NUMBER OF RIVERS : ", numqbc WRITE(IPT,*)"=============================" DO I = 1,nfiles WRITE(IPT,*)" FILE NAME: "//TRIM(RIVER_FORCING(I)%NCF%FNAME) ! WRITE(IPT,*)" RIVER NAME: "//TRIM(RIVER_FORCING(I)%NAME) WRITE(IPT,*)" NUMBER IN FILE=",RIVER_FORCING(I)%RIVERS_IN_FILE WRITE(IPT,*)" RIV_FILE2LOC = ",RIVER_FORCING(I)%RIV_FILE2LOC WRITE(IPT,*)"=============================" END DO WRITE(IPT,*)"/////////=============================///////////" END IF IF(DBG_SET(DBG_SBR)) write(IPT,*) "END RIVER_DISCHARGE" END SUBROUTINE RIVER_DISCHARGE !================================================================ !================================================================ FUNCTION SEARCH_NAME(NCF,NAME) RESULT(RES) ! OUTPUT is the TYPE we are trying to set ! Input is the River type we are searching from IMPLICIT NONE INTEGER :: RES TYPE(NCFILE), POINTER :: NCF CHARACTER(LEN=*) :: NAME INTEGER :: I, rvrs_in_file,strlen,status TYPE(NCDIM), POINTER :: DIM TYPE(NCVAR), POINTER :: VAR LOGICAL FOUND IF (DBG_SET(DBG_IO)) THEN WRITE(IPT,*)"SEARCH_NAME (RIVERS)" WRITE(IPT,*)"=============================" write(IPT,*)"LOOKING FOR: '"//TRIM(NAME)//"'" WRITE(IPT,*)"==========" CALL PRINT_FILE(NCF) END IF ! FIND THE RIVER NAME IN THE FILE DIM => FIND_DIM(NCF,'rivers',FOUND) rvrs_in_file = DIM%DIM VAR => FIND_VAR(NCF,'river_names',found) ! ATTEMPT TO ONLY READ NAMES LIST ONCE IF(.NOT. ASSOCIATED(VAR%VEC_CHR)) THEN ALLOCATE(VAR%VEC_CHR(DIM%DIM),STAT=STATUS) IF(STATUS/=0) CALL FATAL_ERROR("SEARCH_NAME: CAN NOT ALLOCATE TEMP!") CALL NC_READ_VAR(VAR) END IF DO I = 1,rvrs_in_file IF(VAR%VEC_CHR(I) .EQ. NAME)THEN RES = I RETURN END IF END DO ! SHOULD NOT BE HERE, SOMETHING IS WRONG IF (DBG_SET(DBG_LOG)) THEN WRITE(IPT,*)"=============================" write(IPT,*)"LOOKING FOR: '"//TRIM(NAME)//"'; In File:" WRITE(IPT,*)"=============================" CALL PRINT_FILE(NCF) DO I = 1,rvrs_in_file WRITE(IPT,*) "RIVER NAMES: "//TRIM(VAR%VEC_CHR(I)) END DO WRITE(IPT,*)"=============================" WRITE(IPT,*)"=============================" WRITE(IPT,*)"=============================" END IF CALL FATAL_ERROR("COULD NOT FIND CORRECT NAME IN RIVER FILE?") END FUNCTION SEARCH_NAME !================================================================ !================================================================ SUBROUTINE CHECK_RIVER_FILE(NCF,PERIOD) ! CALL FATAL_ERROR IF THERE IS ANYTHING WRONG WITH THE FILE # if defined (BioGen) USE MOD_1D, ONLY : NTT, BIO_NAME # endif IMPLICIT NONE TYPE(NCFILE), POINTER ::NCF TYPE(TIME),OPTIONAL :: PERIOD ! SOME NC POINTERS TYPE(NCATT), POINTER :: ATT TYPE(NCDIM), POINTER :: DIM TYPE(NCVAR), POINTER :: VAR TYPE(TIME) :: fSTART, fEND INTEGER :: NTIMES,NS LOGICAL FOUND IF(.NOT. ASSOCIATED(NCF)) CALL FATAL_ERROR & & ("THE RIVER FILE OBJECT PASSED TO 'check_river_file' IS NOT ASSOCIATED") ! CHECK DIMENSIONS DIM => FIND_DIM(NCF,'time',FOUND) IF(.NOT. FOUND) CALL FATAL_ERROR & & ("THE RIVER FILE:"//TRIM(NCF%FNAME),"IS MISSING THE 'time' DIMENSION") nTIMES = DIM%dim DIM => FIND_DIM(NCF,'namelen',FOUND) IF(.NOT. FOUND) CALL FATAL_ERROR & & ("THE RIVER FILE:"//TRIM(NCF%FNAME),"IS MISSING THE 'namelen' DIMENSION") DIM => FIND_DIM(NCF,'rivers',FOUND) IF(.NOT. FOUND) CALL FATAL_ERROR & & ("THE RIVER FILE:"//TRIM(NCF%FNAME),"IS MISSING THE 'rivers' DIMENSION") ! CHECK VARIABLES AND THEIR ATTS IF(.NOT. ASSOCIATED(NCF%FTIME)) CALL FATAL_ERROR & & ('THE RIVER FILE '//TRIM(NCF%FNAME),& 'DOES NOT HAVE A RECONGIZED TIME VARIABLE') IF(PRESENT(PERIOD)) THEN ! CHECK START AND END TIME FOR THE FILE: FSTART = GET_FILE_TIME(NCF,1) IF(ZEROTIME /= FSTART) THEN CALL PRINT_TIME(FSTART,IPT,"River Data Start") CALL FATAL_ERROR & & ("Date of the first river data point must be 0.0 for periodic forcoing mode:",& & "The River File: "//TRIM(NCF%FNAME)//'; has a bad start date.') END IF PERIOD = GET_FILE_TIME(NCF,NTIMES) IF(PERIOD .LE. zerotime) THEN CALL PRINT_REAL_TIME(PERIOD,IPT,"River Data End") CALL FATAL_ERROR & & ("Date of the last river data point must be greater than or equal to zero for periodic forcing mode:",& & "The River File: "//TRIM(NCF%FNAME)//'; has a bad end date.') END IF ELSE ! CHECK START AND END TIME FOR THE FILE: FSTART = GET_FILE_TIME(NCF,1) IF(FSTART > StartTIME) THEN CALL PRINT_REAL_TIME(StartTime,IPT,"Model Start") CALL PRINT_REAL_TIME(FSTART,IPT,"River Data Start") CALL FATAL_ERROR & & ("Date of the first river data point must be less than or equal to the model start date:",& & "The River File: "//TRIM(NCF%FNAME)//'; has a bad start date.') END IF FEND = GET_FILE_TIME(NCF,NTIMES) IF(FEND < EndTime) THEN CALL PRINT_REAL_TIME(EndTime,IPT,"Model End") CALL PRINT_REAL_TIME(FEND,IPT,"River Data End") CALL FATAL_ERROR & & ("Date of the last river data point must be greater than or equal to the model end date:",& & "The River File: "//TRIM(NCF%FNAME)//'; has a bad end date.') END IF END IF VAR => FIND_VAR(NCF,'river_names',FOUND) IF(.NOT. FOUND) CALL FATAL_ERROR & & ("THE RIVER FILE:"//TRIM(NCF%FNAME),"IS MISSING THE 'river_names' VARIABLE") ! HAS NO ATTRIBUTES VAR => FIND_VAR(NCF,'river_flux',FOUND) IF(.NOT. FOUND) CALL FATAL_ERROR & & ("THE RIVER FILE:"//TRIM(NCF%FNAME),"IS MISSING THE 'river_flux' VARIABLE") ATT => FIND_ATT(VAR,'units',FOUND) IF(.NOT. FOUND) CALL FATAL_ERROR & & ("THE RIVER FILE:"//TRIM(NCF%FNAME),"THE VARIABLE: "& &//TRIM(VAR%VARNAME), "IS MISSING THE ATTRIBUTE 'units'") IF(TRIM(ATT%CHR(1)) /= "m^3s^-1")CALL FATAL_ERROR & & ("THE RIVER FILE:"//TRIM(NCF%FNAME),"THE VARIABLE: "& &//TRIM(VAR%VARNAME), "THE ATTRIBUTE 'units' IS INCORRECT: EXPE& &CTING 'm^3s^-1'") VAR => FIND_VAR(NCF,'river_temp',FOUND) IF(.NOT. FOUND) CALL FATAL_ERROR & & ("THE RIVER FILE:"//TRIM(NCF%FNAME),"IS MISSING THE 'river_temp' VARIABLE") ATT => FIND_ATT(VAR,'units',FOUND) IF(.NOT. FOUND) CALL FATAL_ERROR & & ("THE RIVER FILE:"//TRIM(NCF%FNAME),"THE VARIABLE: "& &//TRIM(VAR%VARNAME), "IS MISSING THE ATTRIBUTE 'units'") IF(TRIM(ATT%CHR(1)) /= "Celsius")CALL FATAL_ERROR & & ("THE RIVER FILE:"//TRIM(NCF%FNAME),"THE VARIABLE: "& &//TRIM(VAR%VARNAME), "THE ATTRIBUTE 'units' IS INCORRECT: EXPE& &CTING 'Celsius'") VAR => FIND_VAR(NCF,'river_salt',FOUND) IF(.NOT. FOUND) CALL FATAL_ERROR & & ("THE RIVER FILE:"//TRIM(NCF%FNAME),"IS MISSING THE 'river_salt' VARIABLE") ATT => FIND_ATT(VAR,'units',FOUND) IF(.NOT. FOUND) CALL FATAL_ERROR & & ("THE RIVER FILE:"//TRIM(NCF%FNAME),"THE VARIABLE: "& &//TRIM(VAR%VARNAME), "IS MISSING THE ATTRIBUTE 'units'") IF(TRIM(ATT%CHR(1)) /= "PSU")CALL FATAL_ERROR & & ("THE RIVER FILE:"//TRIM(NCF%FNAME),"THE VARIABLE: "& &//TRIM(VAR%VARNAME), "THE ATTRIBUTE 'units' IS INCORRECT: EXPE& &CTING 'PSU'") # if defined (WATER_QUALITY) VAR => FIND_VAR(NCF,'river_wqm1',FOUND) IF(.NOT. FOUND) CALL FATAL_ERROR & & ("THE RIVER FILE:"//TRIM(NCF%FNAME),"IS MISSING THE 'river_wqm1' VARIABLE") ATT => FIND_ATT(VAR,'units',FOUND) IF(.NOT. FOUND) CALL FATAL_ERROR & & ("THE RIVER FILE:"//TRIM(NCF%FNAME),"THE VARIABLE: "& &//TRIM(VAR%VARNAME), "IS MISSING THE ATTRIBUTE 'units'") IF(TRIM(ATT%CHR(1)) /= "mg O2/l")CALL FATAL_ERROR & & ("THE RIVER FILE:"//TRIM(NCF%FNAME),"THE VARIABLE: "& &//TRIM(VAR%VARNAME), "THE ATTRIBUTE 'units' IS INCORRECT: EXPE& &CTING 'mg O2/l'") VAR => FIND_VAR(NCF,'river_wqm2',FOUND) IF(.NOT. FOUND) CALL FATAL_ERROR & & ("THE RIVER FILE:"//TRIM(NCF%FNAME),"IS MISSING THE 'river_wqm2' VARIABLE") ATT => FIND_ATT(VAR,'units',FOUND) IF(.NOT. FOUND) CALL FATAL_ERROR & & ("THE RIVER FILE:"//TRIM(NCF%FNAME),"THE VARIABLE: "& &//TRIM(VAR%VARNAME), "IS MISSING THE ATTRIBUTE 'units'") IF(TRIM(ATT%CHR(1)) /= "mg C/l")CALL FATAL_ERROR & & ("THE RIVER FILE:"//TRIM(NCF%FNAME),"THE VARIABLE: "& &//TRIM(VAR%VARNAME), "THE ATTRIBUTE 'units' IS INCORRECT: EXPE& &CTING 'mg C/l'") VAR => FIND_VAR(NCF,'river_wqm3',FOUND) IF(.NOT. FOUND) CALL FATAL_ERROR & & ("THE RIVER FILE:"//TRIM(NCF%FNAME),"IS MISSING THE 'river_wqm3' VARIABLE") ATT => FIND_ATT(VAR,'units',FOUND) IF(.NOT. FOUND) CALL FATAL_ERROR & & ("THE RIVER FILE:"//TRIM(NCF%FNAME),"THE VARIABLE: "& &//TRIM(VAR%VARNAME), "IS MISSING THE ATTRIBUTE 'units'") IF(TRIM(ATT%CHR(1)) /= "mg C/l")CALL FATAL_ERROR & & ("THE RIVER FILE:"//TRIM(NCF%FNAME),"THE VARIABLE: "& &//TRIM(VAR%VARNAME), "THE ATTRIBUTE 'units' IS INCORRECT: EXPE& &CTING 'mg C/l'") VAR => FIND_VAR(NCF,'river_wqm4',FOUND) IF(.NOT. FOUND) CALL FATAL_ERROR & & ("THE RIVER FILE:"//TRIM(NCF%FNAME),"IS MISSING THE 'river_wqm4' VARIABLE") ATT => FIND_ATT(VAR,'units',FOUND) IF(.NOT. FOUND) CALL FATAL_ERROR & & ("THE RIVER FILE:"//TRIM(NCF%FNAME),"THE VARIABLE: "& &//TRIM(VAR%VARNAME), "IS MISSING THE ATTRIBUTE 'units'") IF(TRIM(ATT%CHR(1)) /= "mg N/l")CALL FATAL_ERROR & & ("THE RIVER FILE:"//TRIM(NCF%FNAME),"THE VARIABLE: "& &//TRIM(VAR%VARNAME), "THE ATTRIBUTE 'units' IS INCORRECT: EXPE& &CTING 'mg N/l'") VAR => FIND_VAR(NCF,'river_wqm5',FOUND) IF(.NOT. FOUND) CALL FATAL_ERROR & & ("THE RIVER FILE:"//TRIM(NCF%FNAME),"IS MISSING THE 'river_wqm5' VARIABLE") ATT => FIND_ATT(VAR,'units',FOUND) IF(.NOT. FOUND) CALL FATAL_ERROR & & ("THE RIVER FILE:"//TRIM(NCF%FNAME),"THE VARIABLE: "& &//TRIM(VAR%VARNAME), "IS MISSING THE ATTRIBUTE 'units'") IF(TRIM(ATT%CHR(1)) /= "mg N/l")CALL FATAL_ERROR & & ("THE RIVER FILE:"//TRIM(NCF%FNAME),"THE VARIABLE: "& &//TRIM(VAR%VARNAME), "THE ATTRIBUTE 'units' IS INCORRECT: EXPE& &CTING 'mg N/l'") VAR => FIND_VAR(NCF,'river_wqm6',FOUND) IF(.NOT. FOUND) CALL FATAL_ERROR & & ("THE RIVER FILE:"//TRIM(NCF%FNAME),"IS MISSING THE 'river_wqm6' VARIABLE") ATT => FIND_ATT(VAR,'units',FOUND) IF(.NOT. FOUND) CALL FATAL_ERROR & & ("THE RIVER FILE:"//TRIM(NCF%FNAME),"THE VARIABLE: "& &//TRIM(VAR%VARNAME), "IS MISSING THE ATTRIBUTE 'units'") IF(TRIM(ATT%CHR(1)) /= "mg N/l")CALL FATAL_ERROR & & ("THE RIVER FILE:"//TRIM(NCF%FNAME),"THE VARIABLE: "& &//TRIM(VAR%VARNAME), "THE ATTRIBUTE 'units' IS INCORRECT: EXPE& &CTING 'mg N/l'") VAR => FIND_VAR(NCF,'river_wqm7',FOUND) IF(.NOT. FOUND) CALL FATAL_ERROR & & ("THE RIVER FILE:"//TRIM(NCF%FNAME),"IS MISSING THE 'river_wqm7' VARIABLE") ATT => FIND_ATT(VAR,'units',FOUND) IF(.NOT. FOUND) CALL FATAL_ERROR & & ("THE RIVER FILE:"//TRIM(NCF%FNAME),"THE VARIABLE: "& &//TRIM(VAR%VARNAME), "IS MISSING THE ATTRIBUTE 'units'") IF(TRIM(ATT%CHR(1)) /= "mg P/l")CALL FATAL_ERROR & & ("THE RIVER FILE:"//TRIM(NCF%FNAME),"THE VARIABLE: "& &//TRIM(VAR%VARNAME), "THE ATTRIBUTE 'units' IS INCORRECT: EXPE& &CTING 'mg P/l'") VAR => FIND_VAR(NCF,'river_wqm8',FOUND) IF(.NOT. FOUND) CALL FATAL_ERROR & & ("THE RIVER FILE:"//TRIM(NCF%FNAME),"IS MISSING THE 'river_wqm8' VARIABLE") ATT => FIND_ATT(VAR,'units',FOUND) IF(.NOT. FOUND) CALL FATAL_ERROR & & ("THE RIVER FILE:"//TRIM(NCF%FNAME),"THE VARIABLE: "& &//TRIM(VAR%VARNAME), "IS MISSING THE ATTRIBUTE 'units'") IF(TRIM(ATT%CHR(1)) /= "mg P/l")CALL FATAL_ERROR & & ("THE RIVER FILE:"//TRIM(NCF%FNAME),"THE VARIABLE: "& &//TRIM(VAR%VARNAME), "THE ATTRIBUTE 'units' IS INCORRECT: EXPE& &CTING 'mg P/l'") # endif # if defined (SEDIMENT) DO NS=1,N_SED VAR => FIND_VAR(NCF,TRIM(SED_NAMES(NS)),FOUND) IF(.NOT. FOUND) CALL FATAL_ERROR & & ("THE RIVER FILE:"//TRIM(NCF%FNAME),"IS MISSING THE: "//TRIM(SED_NAMES(NS))//" VARIABLE") ATT => FIND_ATT(VAR,'units',FOUND) IF(.NOT. FOUND) CALL FATAL_ERROR & & ("THE RIVER FILE:"//TRIM(NCF%FNAME),"THE VARIABLE: "& &//TRIM(VAR%VARNAME), "IS MISSING THE ATTRIBUTE 'units'") IF(TRIM(ATT%CHR(1)) /= "g/l" .and. TRIM(ATT%CHR(1)) /= "kgm^-3")CALL FATAL_ERROR & & ("THE RIVER FILE:"//TRIM(NCF%FNAME),"THE VARIABLE: "& &//TRIM(VAR%VARNAME), "THE ATTRIBUTE 'units' IS INCORRECT: EXPE& &CTING 'g/l' or 'kgm^-3' and is "//TRIM(ATT%CHR(1))) END DO # endif # if defined (BioGen) IF(BIOLOGICAL_MODEL)THEN DO NS=1,NTT VAR => FIND_VAR(NCF,TRIM(BIO_NAME(NS,1)),FOUND) IF(.NOT. FOUND) CALL FATAL_ERROR & & ("THE RIVER FILE:"//TRIM(NCF%FNAME),"IS MISSING THE: "//TRIM(BIO_NAME(NS,1))//" VARIABLE") ATT => FIND_ATT(VAR,'units',FOUND) IF(.NOT. FOUND) CALL FATAL_ERROR & & ("THE RIVER FILE:"//TRIM(NCF%FNAME),"THE VARIABLE: "& &//TRIM(VAR%VARNAME), "IS MISSING THE ATTRIBUTE 'units'") IF(TRIM(ATT%CHR(1)) /= BIO_NAME(NS,2))CALL FATAL_ERROR & & ("THE RIVER FILE:"//TRIM(NCF%FNAME),"THE VARIABLE: "& &//TRIM(VAR%VARNAME), "THE ATTRIBUTE 'units' IS INCORRECT: EXPE& &CTING "//BIO_NAME(NS,2)//" and is "//TRIM(ATT%CHR(1))) END DO END IF # endif END SUBROUTINE CHECK_RIVER_FILE !==============================================================================| ! SET METRICS FOR THE BOUNDARY CONDITIONS | !==============================================================================| SUBROUTINE SET_RIVER_BNDRY_METRICS IMPLICIT NONE REAL(DP) DX12,DY12,DX32,DY32,ATMP1,ATMP2,DXYTMP,HTMP,AREATMP REAL(DP) XNORM,YNORM,XP,YP,XN,YN,XI,YI,FAC,XNEXT,YNEXT,MODNR INTEGER I,J,I1,I2,I3,J1,J2,II,ITMP,JTMP,INODE,JNODE,KNODE,NNORM # if defined (SPHERICAL) REAL(DP) X1_DP,Y1_DP,X2_DP,Y2_DP,XDIS1,YDIS1,XDIS2,YDIS2,SIDE # endif CHARACTER(len=7) :: strng !------------------------------------------------------------------------------! IF(DBG_SET(DBG_SBR)) write(IPT,*) "START SET_RIVER_BNDRY_METRICS" SELECT CASE(trim(RIVER_INFLOW_LOCATION)) !===================================== ! CASE NODE: if the river inflow is on the nodes CASE('node') !===================================== ! WHY DON'T WE REQUIRE THAT RIVERS ARE ON THE BOUNDARY FOR NODE? DO I=1,NUMQBC J=INODEQ(I) if (ISONB(J) /= 1) THEN write(strng,'(I6)') ngid(j) CALL FATAL_ERROR & & ("You seem to be trying to put a river in the middle of the domain",& & "The global node number you selected is: "//trim(adjustl(strng)),& &"but this is not a solid boundary node?") END if I1=NBSN(J,2) I2=NBSN(J,1) I3=NBSN(J,NTSN(J)-1) DY12=VY(I1)-VY(I2) DY32=VY(I3)-VY(I2) # if defined (SPHERICAL) X1_DP = VX(I2) Y1_DP = VY(I2) X2_DP = VX(I1) Y2_DP = VY(I1) CALL ARCX(X1_DP,Y1_DP,X2_DP,Y2_DP,SIDE) DX12 = SIDE X2_DP = VX(I3) Y2_DP = VY(I3) CALL ARCX(X1_DP,Y1_DP,X2_DP,Y2_DP,SIDE) DX32 = SIDE DY12 = TPI*DY12 DY32 = TPI*DY32 # else DX12=VX(I1)-VX(I2) DX32=VX(I3)-VX(I2) # endif ATMP1=ATAN2(DY12,DX12) ATMP2=ATAN2(DY32,DX32) ! IF(ATMP1 < 0.0_SP) ATMP1=ATMP1+2.0_SP*3.1415927_SP ! IF(ATMP2 < 0.0_SP) ATMP2=ATMP2+2.0_SP*3.1415927_SP IF(ATMP1 < ATMP2) ATMP1=ATMP1+2.0_SP*3.1415927_SP DXYTMP=SQRT(DX12**2+DY12**2)+SQRT(DX32**2+DY32**2) QAREA(I)=0.5_SP*DXYTMP*H(INODEQ(I)) ANGLEQ(I)=(ATMP1-ATMP2)/2.+ATMP2 END DO !===================================== ! CASE EDGE: if the river inflow is on the cell edge CASE('edge') !===================================== DO I=1,NUMQBC II=ICELLQ(I) IF(ISBCE(II) /= 1) THEN write(strng,'(I6)') egid(II) CALL FATAL_ERROR & & ("You seem to be trying to put a river in the middle of the domain",& & "The global cell number you selected is: "//trim(adjustl(strng)),& &"but this is not a solid boundary node?") END IF ITMP=0 DO J=1,3 IF(NBE(II,J) == 0) THEN JTMP=J ITMP=ITMP+1 END IF END DO IF(ITMP /= 1) THEN write(strng,'(I6)') egid(II) CALL FATAL_ERROR & & ("You have selected an invalide cell for edge based river inflow.",& & "The global cell number you selected is: "//trim(adjustl(strng)),& & "This cell has the wrong number of solid boundaries!") END IF J1=JTMP+1-INT((JTMP+1)/4)*3 J2=JTMP+2-INT((JTMP+2)/4)*3 I1=NV(II,J1) I2=NV(II,J2) N_ICELLQ(I,1)=I1 N_ICELLQ(I,2)=I2 HTMP=0.5_SP*(H(I1)+H(I2)) DY12=VY(I1)-VY(I2) # if defined (SPHERICAL) X1_DP = VX(I2) Y1_DP = VY(I2) X2_DP = VX(I1) Y2_DP = VY(I1) CALL ARCX(X1_DP,Y1_DP,X2_DP,Y2_DP,SIDE) DX12 = SIDE DY12 = TPI*DY12 # else DX12=VX(I1)-VX(I2) # endif ATMP1=ATAN2(DY12,DX12) QAREA(I)=SQRT(DX12**2+DY12**2)*HTMP ANGLEQ(I)=ATMP1+3.1415927/2.0 AREATMP=ART1(I1)+ART1(I2) RDISQ(I,1)=ART1(I1)/AREATMP RDISQ(I,2)=ART1(I2)/AREATMP END DO !===================================== ! DEFAULT CASE: if the name list has a bad value CASE DEFAULT !===================================== CALL FATAL_ERROR("RIVER_INFLOW_LOCATION: NOT CORRECT IN NAMELIST",& & "SHOULD BE 'node' or 'edge' - It passed River_Discharge: how?") END SELECT IF(DBG_SET(DBG_SBR)) write(IPT,*) "END SET_RIVER_BNDRY_METRICS" RETURN END SUBROUTINE SET_RIVER_BNDRY_METRICS !================================================================ !================================================================ SUBROUTINE SET_DISTRIBUTION(NAME,TYPE,LOC,MYDIST) IMPLICIT NONE CHARACTER(LEN=*),INTENT(IN) :: NAME,TYPE INTEGER, INTENT(IN) :: LOC REAL(SP), INTENT(OUT) :: MYDIST(KBM1) REAL(SP) :: MYZ(KBM1) REAL(SP) :: MYH,MYEL REAL(SP) :: TOTAL CHARACTER(LEN=12) :: IDX ! FOR GET VAL================ INTEGER :: NLINE, NCHAR, INTVAL(150), NVAL REAL(DP) :: REALVAL(150) CHARACTER(LEN=40) :: VARNAME CHARACTER(LEN=80) :: STRINGVAL(150) CHARACTER(LEN=7) :: VARTYPE LOGICAL :: LOGVAL !============================ MYDIST = 0.0_SP IF (trim(TYPE)=='node') THEN MYDIST = DZ(NLID(LOC),1:kbm1) MYZ = ZZ(NLID(LOC),1:KBM1) MYH = H(NLID(LOC)) MYEL = EL(NLID(LOC)) ELSEIF (trim(TYPE)=='edge') THEN MYDIST = DZ1(ELID(LOC),1:kbm1) MYZ = ZZ1(ELID(LOC),1:KBM1) MYH = H1(ELID(LOC)) MYEL = EL1(ELID(LOC)) ELSE CALL FATAL_ERROR("BAD RIVER LOCATION (edge OR node) ?") END IF SELECT CASE(NAME(1:6)) ! UNIFORM FUNCTION CASE ('unifor') ! ALREADY SET VALUES WRITE(IPT,*) "UNIFORM RIVER DISTRIBUTION",MYDIST ! HEAVISIDE FUNCTION CASE('heavis') NLINE=-1 NCHAR = LEN_TRIM(NAME) CALL GET_VALUE(NLINE,NCHAR,NAME,VARNAME,VARTYPE,LOGVAL& &,STRINGVAL,REALVAL,INTVAL,NVAL) IF(VARTYPE /= "float") THEN WRITE(IDX,*) LOC CALL FATAL_ERROR& &("HEAVISIDE RIVER DISTRIBUTION MUST SET A FLOATING POINT VALUE",& &"River on "//TRIM(TYPE)//" number:"//TRIM(IDX)) END IF IF(NVAL>1) CALL FATAL_ERROR& &("COULD NOT READ RIVER DISTRIBUTION STRING?",& & "BAD STRING:"//TRIM(NAME)) IF(index(VARNAME,'depth')/=0)THEN MYZ = (MYH+MYEL)*MYZ+MYEL IF(MYZ(KBM1) > REALVAL(1) .OR. REALVAL(1) > MYZ(1)) THEN WRITE(IDX,*) LOC WRITE(IPT,*) "================================" WRITE(IPT,*) "HEAVISIDE CASE- depth",REALVAL(1) WRITE(IPT,*) "RIVER DEPTH = ",MYH WRITE(IPT,*) "RIVER SURFACE = ",MYEL CALL FATAL_ERROR("RIVER DISTRIBUTION: Depth value out of bounds!",& & "River on "//TRIM(TYPE)//" number:"//TRIM(IDX)) END IF WRITE(IPT,*) "DEPTH:",MYZ WHERE (MYZ<REALVAL(1)) MYDIST = 0.0_SP END WHERE TOTAL = SUM(MYDIST) MYDIST = MYDIST/TOTAL ELSEIF(index(VARNAME,'sigma')/=0)THEN IF(-1.0_SP > REALVAL(1) .OR. REALVAL(1) >0.0_SP) THEN WRITE(IPT,*) "================================" WRITE(IPT,*) "HEAVISIDE CASE- sigma",REALVAL(1) WRITE(IDX,*) LOC CALL FATAL_ERROR& &("RIVER DISTRIBUTION: Sigma value out of bounds!",& & "River on "//TRIM(TYPE)//" number:"//TRIM(IDX)) END IF WHERE (MYZ<REALVAL(1)) MYDIST = 0.0_SP END WHERE TOTAL = SUM(MYDIST) MYDIST = MYDIST/TOTAL ELSE CALL FATAL_ERROR("RIVER DISTRIBUTION: UNKNOWN HEAVISIDE SETTING?",& & "BAD STRING:"//TRIM(NAME)) END IF WRITE(IPT,*) "HEAVISIDE RIVER DISTRIBUTION",MYDIST CASE('linear') NLINE=-1 NCHAR = LEN_TRIM(NAME) CALL GET_VALUE(NLINE,NCHAR,NAME,VARNAME,VARTYPE,LOGVAL& &,STRINGVAL,REALVAL,INTVAL,NVAL) IF(VARTYPE /= "float") THEN WRITE(IDX,*) LOC CALL FATAL_ERROR& &("LINEAR RIVER DISTRIBUTION MUST SET A FLOATING POINT VALUE",& &"River on "//TRIM(TYPE)//" number:"//TRIM(IDX)) END IF IF(NVAL>1) CALL FATAL_ERROR& &("COULD NOT READ RIVER DISTRIBUTION STRING?",& & "BAD STRING:"//TRIM(NAME)) IF(index(VARNAME,'slope')/=0)THEN IF(REALVAL(1) <0.0_SP) THEN WRITE(IPT,*) "================================" WRITE(IPT,*) "LINEAR CASE- slope",REALVAL(1) WRITE(IDX,*) LOC CALL FATAL_ERROR& &("RIVER DISTRIBUTION: linear slope less than zero!",& & "River on "//TRIM(TYPE)//" number:"//TRIM(IDX)) END IF MYZ = (MYH+MYEL)*MYZ+MYEL MYZ = MYZ *MYDIST * REALVAL(1) DO WHILE(SUM(MYZ,MYZ>0.0_SP)<1.0_SP) MYZ=MYZ + MYDIST*0.01 END DO WHERE (MYZ > 0.0_SP) MYDIST = MYZ ELSEWHERE MYDIST = 0.0_SP END WHERE TOTAL = SUM(MYDIST) MYDIST = MYDIST/TOTAL ELSE CALL FATAL_ERROR("RIVER DISTRIBUTION: UNKOWN LINEAR SETTING?",& & "BAD STRING:"//TRIM(NAME)) END IF WRITE(IPT,*) "LINEAR RIVER DISTRIBUTION",MYDIST CASE DEFAULT CALL FATAL_ERROR("UNKNOWN RIVER DISTRIBUTION FUNCTION:"//TRIM(NAME),& &"SEE FVCOM MANUAL OR mod_force.F FOR OPTIONS!") END SELECT END SUBROUTINE SET_DISTRIBUTION !================================================================ !================================================================ SUBROUTINE OBC_TEMPERATURE IMPLICIT NONE ! SOME NC POINTERS TYPE(NCATT), POINTER :: ATT, ATT_DATE TYPE(NCDIM), POINTER :: DIM TYPE(NCVAR), POINTER :: VAR LOGICAL :: FOUND INTEGER MYNOBC INTEGER, ALLOCATABLE :: MYOBCLIST(:) INTEGER :: MYSIGLAY REAL(SP), POINTER :: STORAGE_ARR(:,:), storage_vec(:) INTEGER :: NTIMES, I TYPE(TIME) :: TIMETEST INTEGER :: STATUS IF(DBG_SET(DBG_SBR)) write(IPT,*) "START OBC_TEMPERATURE" IF (.NOT. OBC_TEMP_NUDGING) THEN IF(DBG_SET(DBG_LOG)) write(IPT,*) "! OPEN BOUNDARY TEMPERATURE NUDGING IS OFF!" OBC_T_COMMENTS="OPEN BOUNDARY TEMPERATURE NUDGING IS OFF!" RETURN END IF IF(DBG_SET(DBG_LOG)) write(IPT,*) "! OPEN BOUNDARY TEMPERATURE NUDGING IS ON!" OBC_T_COMMENTS="OPEN BOUNDARY TEMPERATURE NUDGING IS ON!" ! FIND THE TIDAL FORCING FILE OBJECT OBC_T_FILE => FIND_FILE(FILEHEAD,trim(OBC_TEMP_FILE),FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("COULD NOT FIND OPEN BOUNDARY CONDITION TEMPERATURE FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_TEMP_FILE)) !08/05/2024 ! ATT => FIND_ATT(OBC_T_FILE,"type",FOUND) ! IF(.not. FOUND) CALL FATAL_ERROR & ! & ("IN OPEN BOUNDARY CONDITION TEMPERATURE FILE OBJECT",& ! & "FILE NAME: "//TRIM(OBC_TEMP_FILE),& ! &"COULD NOT FIND GLOBAL ATTRIBURE: 'type'") ! SELECT CASE(TRIM(ATT%CHR(1))) ! !================================= ! ! TIME SERIES OBC TEMPERATURE NUDGING DATA ! CASE("FVCOM TIME SERIES OBC TS FILE") ! !================================== OBC_T_TYPE = OBC_T_SIGMA ATT => FIND_ATT(OBC_T_FILE,"title",FOUND) IF(FOUND) THEN OBC_T_COMMENTS = "Open Boundary Temperature Data: "& &//TRIM(ATT%CHR(1)) ELSE CALL WARNING("ATTRIBUTE 'title' IS MISSING IN THE TEMPERATURE NUDGING FILE!") OBC_T_COMMENTS = "Open Boundary Temperature Data: UNKOWN SOURCE" END IF ! LOOK FOR THE DIMENSIONS 'nobc' and 'time' DIM => FIND_DIM(OBC_T_FILE,'time',FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION TEMPERATURE NUDGING FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_TEMP_FILE),& &"COULD NOT FIND DIMENSION 'time'") NTIMES = DIM%DIM DIM => FIND_DIM(OBC_T_FILE,'siglay',FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION TEMPERATURE NUDGING FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_TEMP_FILE),& &"COULD NOT FIND DIMENSION 'siglay'") MYSIGLAY = DIM%DIM if(KBM1 /= MYSIGLAY) CALL FATAL_ERROR& & ("IN OPEN BOUNDARY CONDITION TEMPERATURE NUDGING FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_TEMP_FILE),& &"THE 'siglay' DIMENSION DOES NOT MATCH THE MODEL RUN!") DIM => FIND_DIM(OBC_T_FILE,'nobc',FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION TEMPERATURE NUDGING FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_TEMP_FILE),& &"COULD NOT FIND DIMENSION 'nobc'") if(IOBCN_GL>0) then IF(IOBCN_GL /= DIM%DIM) CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION TEMPERATURE NUDGING FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_TEMP_FILE),& &"THE DIMENSION 'nobc' MUST MATCH THE NUMBER OF OBC NODES") endif ! lOAD GLOBAL OPEN BOUNDARY NOD NUMBER DATA AND COMPARE WITH ! OBC.DAT/RESTART FILE INPUT ALLOCATE(MYOBCLIST(IOBCN)) VAR => FIND_VAR(OBC_T_FILE,'obc_nodes',FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION TEMPERATURE NUDGING FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_TEMP_FILE),& &"COULD NOT FIND VARIABLE 'obc_nodes'") CALL NC_CONNECT_AVAR(VAR,MYOBCLIST) CALL NC_READ_VAR(VAR) DO I = 1, IOBCN IF(SERIAL) THEN IF(I_OBC_N(I) /= MYOBCLIST(I)) THEN write(IPT,*) "NLID(MYOBCLIST)= ", MYOBCLIST(I), "; I=",I write(IPT,*) "I_OBC_N= ", I_OBC_N(I), "; I=",I CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION TEMPERATURE NUDGING FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_TEMP_FILE),& &"THE LIST OF BOUNDARY NODES DOES NOT MATCH") END IF ELSE # if defined(MULTIPROCESSOR) IF(I_OBC_N(I) /= NLID(MYOBCLIST(I))) THEN write(IPT,*) "NLID(MYOBCLIST)= ", NLID(MYOBCLIST(I)), "; I=",I write(IPT,*) "I_OBC_N= ", I_OBC_N(I), "; I=",I CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION TEMPERATURE NUDGING FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_TEMP_FILE),& &"THE LIST OF BOUNDARY NODES DOES NOT MATCH") END IF # endif END IF END DO ! LOAD TIME AND CHECK TO MAKE SURE THE TIME RANGE IS VALID TIMETEST = GET_FILE_TIME(OBC_T_FILE,1) IF(TIMETEST > STARTTIME) CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION TEMPERATURE NUDGING FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_TEMP_FILE),& &"THE MODEL RUN STARTS BEFORE THE TEMPERATURE TIME SERIES") TIMETEST = GET_FILE_TIME(OBC_T_FILE,NTIMES) IF(TIMETEST < ENDTIME) CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION TEMPERATURE NUDGING FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_TEMP_FILE),& &"THE MODEL RUN ENDS AFTER THE TEMPERATURE TIME SERIES") VAR => FIND_VAR(OBC_T_FILE,'obc_temp',FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION TEMPERATURE NUDGING FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_TEMP_FILE),& &"COULD NOT FIND VARIABLE 'obc_temp'") ATT => FIND_ATT(VAR,'units',FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION TEMPERATURE NUDGING FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_TEMP_FILE),& &"COULD NOT FIND TEMP VARIRIABLE'S ATTRIBUTE 'units'") if(TRIM(ATT%CHR(1)) .NE. 'Celsius' .and. TRIM(ATT%CHR(1)) .NE. 'Celcius') CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION TEMPERATURE NUDGING FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_TEMP_FILE),& &"TEMP VARIRIABLE ATTRIBUTE 'units' SHOULD BE 'Celsius'") ! MAKE SPACE FOR THE DATA FROM THE FILE ALLOCATE(STORAGE_ARR(IOBCN,KBM1), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN OBC_TEMPERATURE") OBC_T_N => reference_var(var) CALL NC_CONNECT_PVAR(OBC_T_N,STORAGE_ARR) NULLIFY(STORAGE_ARR) ! MAKE SPACE FOR THE DATA FROM THE FILE ALLOCATE(STORAGE_ARR(IOBCN,KBM1), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN OBC_TEMPERATURE") OBC_T_P => reference_var(var) CALL NC_CONNECT_PVAR(OBC_T_P,STORAGE_ARR) NULLIFY(STORAGE_ARR) ! !===================================== ! ! DEFAULT CASE IF GLOBAL ATTRIBUTES OF FILE ARE INCORRECT ! CASE DEFAULT ! !===================================== ! CALL FATAL_ERROR & ! & ("IN OPEN BOUNDARY CONDITION TEMPERATURE FILE OBJECT",& ! & "FILE NAME: "//TRIM(OBC_TEMP_FILE),& ! &"THE GLOBAL ATTRIBURE 'type' RETURNED UNKNOWN TYPE:",& ! & TRIM(ATT%CHR(1))) ! END SELECT ! afm 20151112 & EJA 20160921 ! Need initialization. Otherwise, random values are asigned ! and cause a hanging problem of MPI job in UPDATE_VAR_BRACKET ! This problem reported with Intel15.0.3. OBC_T_N%curr_stkcnt = 0; OBC_T_P%curr_stkcnt = 0 IF(DBG_SET(DBG_SBR)) write(IPT,*) "END OBC_TEMPERATURE" END SUBROUTINE OBC_TEMPERATURE !================================================================ !================================================================ SUBROUTINE OBC_SALINITY IMPLICIT NONE ! SOME NC POINTERS TYPE(NCATT), POINTER :: ATT, ATT_DATE TYPE(NCDIM), POINTER :: DIM TYPE(NCVAR), POINTER :: VAR LOGICAL :: FOUND INTEGER MYNOBC INTEGER, ALLOCATABLE :: MYOBCLIST(:) INTEGER :: MYSIGLAY REAL(SP), POINTER :: STORAGE_ARR(:,:), storage_vec(:) INTEGER :: NTIMES, I TYPE(TIME) :: TIMETEST INTEGER :: STATUS IF(DBG_SET(DBG_SBR)) write(IPT,*) "START OBC_SALINITY" IF (.NOT. OBC_SALT_NUDGING) THEN IF(DBG_SET(DBG_LOG)) write(IPT,*) "! OPEN BOUNDARY SALINITY NUDGING IS OFF!" OBC_S_COMMENTS="OPEN BOUNDARY SALINITY NUDGING IS OFF!" RETURN END IF IF(DBG_SET(DBG_LOG)) write(IPT,*) "! OPEN BOUNDARY SALINITY NUDGING IS ON!" OBC_S_COMMENTS="OPEN BOUNDARY SALINITY NUDGING IS ON!" ! FIND THE TIDAL FORCING FILE OBJECT OBC_S_FILE => FIND_FILE(FILEHEAD,trim(OBC_SALT_FILE),FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("COULD NOT FIND OPEN BOUNDARY CONDITION SALINITY FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_SALT_FILE)) !08/05/2024 ! ATT => FIND_ATT(OBC_S_FILE,"type",FOUND) ! IF(.not. FOUND) CALL FATAL_ERROR & ! & ("IN OPEN BOUNDARY CONDITION SALINITY FILE OBJECT",& ! & "FILE NAME: "//TRIM(OBC_SALT_FILE),& ! &"COULD NOT FIND GLOBAL ATTRIBURE: 'type'") ! SELECT CASE(TRIM(ATT%CHR(1))) ! !================================= ! ! TIME SERIES OBC SALINITY NUDGING DATA ! CASE("FVCOM TIME SERIES OBC TS FILE") ! !================================== OBC_S_TYPE = OBC_S_SIGMA ATT => FIND_ATT(OBC_S_FILE,"title",FOUND) IF(FOUND) THEN OBC_S_COMMENTS = "Open Boundary Salinity Data: "& &//TRIM(ATT%CHR(1)) ELSE CALL WARNING("ATTRIBUTE 'title' IS MISSING IN THE SALINITY NUDGING FILE!") OBC_S_COMMENTS = "Open Boundary Salinity Data: UNKOWN SOURCE" END IF ! LOOK FOR THE DIMENSIONS 'nobc' and 'time' DIM => FIND_DIM(OBC_S_FILE,'time',FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION SALINITY NUDGING FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_SALT_FILE),& &"COULD NOT FIND DIMENSION 'time'") NTIMES = DIM%DIM DIM => FIND_DIM(OBC_S_FILE,'siglay',FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION SALINITY NUDGING FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_SALT_FILE),& &"COULD NOT FIND DIMENSION 'siglay'") MYSIGLAY = DIM%DIM if(KBM1 /= MYSIGLAY) CALL FATAL_ERROR& & ("IN OPEN BOUNDARY CONDITION SALINITY NUDGING FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_SALT_FILE),& &"THE 'siglay' DIMENSION DOES NOT MATCH THE MODEL RUN!") DIM => FIND_DIM(OBC_S_FILE,'nobc',FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION SALINITY NUDGING FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_SALT_FILE),& &"COULD NOT FIND DIMENSION 'nobc'") if(IOBCN_GL>0) then IF(IOBCN_GL /= DIM%DIM) CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION SALINITY NUDGING FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_SALT_FILE),& &"THE DIMENSION 'nobc' MUST MATCH THE NUMBER OF OBC NODES") endif ! lOAD GLOBAL OPEN BOUNDARY NOD NUMBER DATA AND COMPARE WITH ! OBC.DAT/RESTART FILE INPUT ALLOCATE(MYOBCLIST(IOBCN)) VAR => FIND_VAR(OBC_S_FILE,'obc_nodes',FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION SALINITY NUDGING FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_SALT_FILE),& &"COULD NOT FIND VARIABLE 'obc_nodes'") CALL NC_CONNECT_AVAR(VAR,MYOBCLIST) CALL NC_READ_VAR(VAR) DO I = 1, IOBCN IF(SERIAL) THEN IF(I_OBC_N(I) /= MYOBCLIST(I)) THEN write(IPT,*) "NLID(MYOBCLIST)= ", MYOBCLIST(I), "; I=",I write(IPT,*) "I_OBC_N= ", I_OBC_N(I), "; I=",I CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION SALINITY NUDGING FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_SALT_FILE),& &"THE LIST OF BOUNDARY NODES DOES NOT MATCH") END IF ELSE # if defined(MULTIPROCESSOR) IF(I_OBC_N(I) /= NLID(MYOBCLIST(I))) THEN write(IPT,*) "NLID(MYOBCLIST)= ", NLID(MYOBCLIST(I)), "; I=",I write(IPT,*) "I_OBC_N= ", I_OBC_N(I), "; I=",I CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION SALINITY NUDGING FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_SALT_FILE),& &"THE LIST OF BOUNDARY NODES DOES NOT MATCH") END IF # endif END IF END DO ! LOAD TIME AND CHECK TO MAKE SURE THE TIME RANGE IS VALID TIMETEST = GET_FILE_TIME(OBC_S_FILE,1) IF(TIMETEST > STARTTIME) CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION SALINITY NUDGING FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_SALT_FILE),& &"THE MODEL RUN STARTS BEFORE THE SALINITY TIME SERIES") TIMETEST = GET_FILE_TIME(OBC_S_FILE,NTIMES) IF(TIMETEST < ENDTIME) CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION SALINITY NUDGING FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_SALT_FILE),& &"THE MODEL RUN ENDS AFTER THE SALINITY TIME SERIES") VAR => FIND_VAR(OBC_S_FILE,'obc_salinity',FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION SALINITY NUDGING FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_SALT_FILE),& &"COULD NOT FIND VARIABLE 'obc_salinity'") ATT => FIND_ATT(VAR,'units',FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION SALINITY NUDGING FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_SALT_FILE),& &"COULD NOT FIND TEMP VARIRIABLE'S ATTRIBUTE 'units'") if(TRIM(ATT%CHR(1)) .NE. 'PSU') CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION SALINITY NUDGING FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_SALT_FILE),& &"TEMP VARIRIABLE ATTRIBUTE 'units' SHOULD BE 'PSU'") ! MAKE SPACE FOR THE DATA FROM THE FILE ALLOCATE(STORAGE_ARR(IOBCN,KBM1), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN OBC_SALINITY") OBC_S_N => reference_var(var) CALL NC_CONNECT_PVAR(OBC_S_N,STORAGE_ARR) NULLIFY(STORAGE_ARR) ! MAKE SPACE FOR THE DATA FROM THE FILE ALLOCATE(STORAGE_ARR(IOBCN,KBM1), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN OBC_SALINITY") OBC_S_P => reference_var(var) CALL NC_CONNECT_PVAR(OBC_S_P,STORAGE_ARR) NULLIFY(STORAGE_ARR) ! !===================================== ! ! DEFAULT CASE IF GLOBAL ATTRIBUTES OF FILE ARE INCORRECT ! CASE DEFAULT ! !===================================== ! CALL FATAL_ERROR & ! & ("IN OPEN BOUNDARY CONDITION SALINITY FILE OBJECT",& ! & "FILE NAME: "//TRIM(OBC_SALT_FILE),& ! &"THE GLOBAL ATTRIBURE 'type' RETURNED UNKNOWN TYPE:",& ! & TRIM(ATT%CHR(1))) ! END SELECT ! afm 20150914 & EJA 20160921 ! Need initialization. Otherwise, random values are asigned ! and cause a hanging problem of MPI job in UPDATE_VAR_BRACKET ! This problem reported with Intel15.0.3. OBC_S_N%curr_stkcnt = 0; OBC_S_P%curr_stkcnt = 0 IF(DBG_SET(DBG_SBR)) write(IPT,*) "END OBC_SALINITY" END SUBROUTINE OBC_SALINITY !================================================================ !================================================================ # if defined (WATER_QUALITY) SUBROUTINE OBC_WQM ! USE MOD_WQM, ONLY : WQM_NAME IMPLICIT NONE ! SOME NC POINTERS TYPE(NCATT), POINTER :: ATT, ATT_DATE TYPE(NCDIM), POINTER :: DIM TYPE(NCVAR), POINTER :: VAR LOGICAL :: FOUND INTEGER MYNOBC INTEGER, ALLOCATABLE :: MYOBCLIST(:) INTEGER :: MYSIGLAY REAL(SP), POINTER :: STORAGE_ARR(:,:), storage_vec(:) INTEGER :: NTIMES, I TYPE(TIME) :: TIMETEST INTEGER :: STATUS IF(DBG_SET(DBG_SBR)) write(IPT,*) "START OBC_WQM" IF (.NOT. OBC_WQM_NUDGING) THEN IF(DBG_SET(DBG_LOG)) write(IPT,*) "! OPEN BOUNDARY WATER QUALITY NUDGING IS OFF!" OBC_W_COMMENTS="OPEN BOUNDARY WATER QUALITY NUDGING IS OFF!" RETURN END IF IF(DBG_SET(DBG_LOG)) write(IPT,*) "! OPEN BOUNDARY WATER QUALITY NUDGING IS ON!" OBC_W_COMMENTS="OPEN BOUNDARY WATER QUALITY NUDGING IS ON!" ! FIND THE FORCING FILE OBJECT OBC_W_FILE => FIND_FILE(FILEHEAD,trim(OBC_WQM_FILE),FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("COULD NOT FIND OPEN BOUNDARY CONDITION WATER QUALITY FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_WQM_FILE)) ATT => FIND_ATT(OBC_W_FILE,"type",FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION WATER QUALITY FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_WQM_FILE),& &"COULD NOT FIND GLOBAL ATTRIBURE: 'type'") SELECT CASE(TRIM(ATT%CHR(1))) !================================= ! TIME SERIES OBC WATER QUALITY NUDGING DATA CASE("FVCOM TIME SERIES OBC WQM FILE") !================================== OBC_W_TYPE = OBC_W_SIGMA ATT => FIND_ATT(OBC_W_FILE,"title",FOUND) IF(FOUND) THEN OBC_W_COMMENTS = "Open Boundary WATER QUALITY Data: "& &//TRIM(ATT%CHR(1)) ELSE CALL WARNING("ATTRIBUTE 'title' IS MISSING IN THE WATER QUALITY NUDGING FILE!") OBC_W_COMMENTS = "Open Boundary Water Quality Data: UNKOWN SOURCE" END IF ! LOOK FOR THE DIMENSIONS 'nobc' and 'time' DIM => FIND_DIM(OBC_W_FILE,'time',FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION WATER QUALITY NUDGING FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_WQM_FILE),& &"COULD NOT FIND DIMENSION 'time'") NTIMES = DIM%DIM DIM => FIND_DIM(OBC_W_FILE,'siglay',FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION WATER QUALITY NUDGING FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_WQM_FILE),& &"COULD NOT FIND DIMENSION 'siglay'") MYSIGLAY = DIM%DIM if(KBM1 /= MYSIGLAY) CALL FATAL_ERROR& & ("IN OPEN BOUNDARY CONDITION WATER QUALITY NUDGING FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_WQM_FILE),& &"THE 'siglay' DIMENSION DOES NOT MATCH THE MODEL RUN!") DIM => FIND_DIM(OBC_W_FILE,'nobc',FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION WATER QUALITY NUDGING FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_WQM_FILE),& &"COULD NOT FIND DIMENSION 'nobc'") if(IOBCN_GL>0) then IF(IOBCN_GL /= DIM%DIM) CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION WATER QUALITY NUDGING FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_WQM_FILE),& &"THE DIMENSION 'nobc' MUST MATCH THE NUMBER OF OBC NODES") endif ! LOAD GLOBAL OPEN BOUNDARY NODE NUMBER DATA AND COMPARE WITH ! OBC.DAT/RESTART FILE INPUT ALLOCATE(MYOBCLIST(IOBCN)) VAR => FIND_VAR(OBC_W_FILE,'obc_nodes',FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION WATER QUALITY NUDGING FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_WQM_FILE),& &"COULD NOT FIND VARIABLE 'obc_nodes'") CALL NC_CONNECT_AVAR(VAR,MYOBCLIST) CALL NC_READ_VAR(VAR) DO I = 1, IOBCN IF(SERIAL) THEN IF(I_OBC_N(I) /= MYOBCLIST(I)) THEN write(IPT,*) "NLID(MYOBCLIST)= ", MYOBCLIST(I), "; I=",I write(IPT,*) "I_OBC_N= ", I_OBC_N(I), "; I=",I CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION WATER QUALITY NUDGING FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_WQM_FILE),& &"THE LIST OF BOUNDARY NODES DOES NOT MATCH") END IF ELSE # if defined(MULTIPROCESSOR) IF(I_OBC_N(I) /= NLID(MYOBCLIST(I))) THEN write(IPT,*) "NLID(MYOBCLIST)= ", NLID(MYOBCLIST(I)), "; I=",I write(IPT,*) "I_OBC_N= ", I_OBC_N(I), "; I=",I CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION WATER QUALITY NUDGING FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_WQM_FILE),& &"THE LIST OF BOUNDARY NODES DOES NOT MATCH") END IF # endif END IF END DO ! LOAD TIME AND CHECK TO MAKE SURE THE TIME RANGE IS VALID TIMETEST = GET_FILE_TIME(OBC_W_FILE,1) IF(TIMETEST > STARTTIME) CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION WATER QUALITY NUDGING FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_WQM_FILE),& &"THE MODEL RUN STARTS BEFORE THE WATER QUALITY TIME SERIES") TIMETEST = GET_FILE_TIME(OBC_W_FILE,NTIMES) IF(TIMETEST < ENDTIME) CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION WATER QUALITY NUDGING FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_WQM_FILE),& &"THE MODEL RUN ENDS AFTER THE WATER QUALITY TIME SERIES") VAR => FIND_VAR(OBC_W_FILE,WQM_NAME(1,1),FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION WATER QUALITY NUDGING FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_WQM_FILE),& &"COULD NOT FIND VARIABLE "//TRIM(WQM_NAME(1,1))) ATT => FIND_ATT(VAR,'units',FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION WATER QUALITY NUDGING FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_WQM_FILE),& &"COULD NOT FIND VARIRIABLE DO'S ATTRIBUTE 'units'") if(TRIM(ATT%CHR(1)) .NE. WQM_NAME(1,2)) CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION WATER QUALITY NUDGING FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_WQM_FILE),& &"VARIRIABLE DO'S ATTRIBUTE 'units' SHOULD BE "//TRIM(WQM_NAME(1,2))) ! MAKE SPACE FOR THE DATA FROM THE FILE ALLOCATE(STORAGE_ARR(IOBCN,KBM1), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN OBC_WQM") OBC_W_N1 => reference_var(var) CALL NC_CONNECT_PVAR(OBC_W_N1,STORAGE_ARR) NULLIFY(STORAGE_ARR) ! MAKE SPACE FOR THE DATA FROM THE FILE ALLOCATE(STORAGE_ARR(IOBCN,KBM1), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN OBC_WQM") OBC_W_P1 => reference_var(var) CALL NC_CONNECT_PVAR(OBC_W_P1,STORAGE_ARR) NULLIFY(STORAGE_ARR) VAR => FIND_VAR(OBC_W_FILE,WQM_NAME(2,1),FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION WATER QUALITY NUDGING FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_WQM_FILE),& &"COULD NOT FIND VARIABLE "//TRIM(WQM_NAME(2,1))) ATT => FIND_ATT(VAR,'units',FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION WATER QUALITY NUDGING FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_WQM_FILE),& &"COULD NOT FIND VARIRIABLE CBOD'S ATTRIBUTE 'units'") if(TRIM(ATT%CHR(1)) .NE. WQM_NAME(2,2)) CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION WATER QUALITY NUDGING FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_WQM_FILE),& &"VARIRIABLE CBOD'S ATTRIBUTE 'units' SHOULD BE "//TRIM(WQM_NAME(2,2))) ! MAKE SPACE FOR THE DATA FROM THE FILE ALLOCATE(STORAGE_ARR(IOBCN,KBM1), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN OBC_WQM") OBC_W_N2 => reference_var(var) CALL NC_CONNECT_PVAR(OBC_W_N2,STORAGE_ARR) NULLIFY(STORAGE_ARR) ! MAKE SPACE FOR THE DATA FROM THE FILE ALLOCATE(STORAGE_ARR(IOBCN,KBM1), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN OBC_WQM") OBC_W_P2 => reference_var(var) CALL NC_CONNECT_PVAR(OBC_W_P2,STORAGE_ARR) NULLIFY(STORAGE_ARR) VAR => FIND_VAR(OBC_W_FILE,WQM_NAME(3,1),FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION WATER QUALITY NUDGING FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_WQM_FILE),& &"COULD NOT FIND VARIABLE "//TRIM(WQM_NAME(3,1))) ATT => FIND_ATT(VAR,'units',FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION WATER QUALITY NUDGING FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_WQM_FILE),& &"COULD NOT FIND VARIRIABLE PHYT'S ATTRIBUTE 'units'") if(TRIM(ATT%CHR(1)) .NE. WQM_NAME(3,2)) CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION WATER QUALITY NUDGING FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_WQM_FILE),& &"VARIRIABLE PHYT'S ATTRIBUTE 'units' SHOULD BE "//TRIM(WQM_NAME(3,2))) ! MAKE SPACE FOR THE DATA FROM THE FILE ALLOCATE(STORAGE_ARR(IOBCN,KBM1), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN OBC_WQM") OBC_W_N3 => reference_var(var) CALL NC_CONNECT_PVAR(OBC_W_N3,STORAGE_ARR) NULLIFY(STORAGE_ARR) ! MAKE SPACE FOR THE DATA FROM THE FILE ALLOCATE(STORAGE_ARR(IOBCN,KBM1), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN OBC_WQM") OBC_W_P3 => reference_var(var) CALL NC_CONNECT_PVAR(OBC_W_P3,STORAGE_ARR) NULLIFY(STORAGE_ARR) VAR => FIND_VAR(OBC_W_FILE,WQM_NAME(4,1),FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION WATER QUALITY NUDGING FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_WQM_FILE),& &"COULD NOT FIND VARIABLE "//TRIM(WQM_NAME(4,1))) ATT => FIND_ATT(VAR,'units',FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION WATER QUALITY NUDGING FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_WQM_FILE),& &"COULD NOT FIND VARIRIABLE NH3'S ATTRIBUTE 'units'") if(TRIM(ATT%CHR(1)) .NE. WQM_NAME(4,2)) CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION WATER QUALITY NUDGING FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_WQM_FILE),& &"VARIRIABLE NH3'S ATTRIBUTE 'units' SHOULD BE "//TRIM(WQM_NAME(4,2))) ! MAKE SPACE FOR THE DATA FROM THE FILE ALLOCATE(STORAGE_ARR(IOBCN,KBM1), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN OBC_WQM") OBC_W_N4 => reference_var(var) CALL NC_CONNECT_PVAR(OBC_W_N4,STORAGE_ARR) NULLIFY(STORAGE_ARR) ! MAKE SPACE FOR THE DATA FROM THE FILE ALLOCATE(STORAGE_ARR(IOBCN,KBM1), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN OBC_WQM") OBC_W_P4 => reference_var(var) CALL NC_CONNECT_PVAR(OBC_W_P4,STORAGE_ARR) NULLIFY(STORAGE_ARR) VAR => FIND_VAR(OBC_W_FILE,WQM_NAME(5,1),FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION WATER QUALITY NUDGING FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_WQM_FILE),& &"COULD NOT FIND VARIABLE "//TRIM(WQM_NAME(5,1))) ATT => FIND_ATT(VAR,'units',FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION WATER QUALITY NUDGING FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_WQM_FILE),& &"COULD NOT FIND VARIRIABLE NO3'S ATTRIBUTE 'units'") if(TRIM(ATT%CHR(1)) .NE. WQM_NAME(5,2)) CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION WATER QUALITY NUDGING FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_WQM_FILE),& &"VARIRIABLE NO3'S ATTRIBUTE 'units' SHOULD BE "//TRIM(WQM_NAME(5,2))) ! MAKE SPACE FOR THE DATA FROM THE FILE ALLOCATE(STORAGE_ARR(IOBCN,KBM1), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN OBC_WQM") OBC_W_N5 => reference_var(var) CALL NC_CONNECT_PVAR(OBC_W_N5,STORAGE_ARR) NULLIFY(STORAGE_ARR) ! MAKE SPACE FOR THE DATA FROM THE FILE ALLOCATE(STORAGE_ARR(IOBCN,KBM1), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN OBC_WQM") OBC_W_P5 => reference_var(var) CALL NC_CONNECT_PVAR(OBC_W_P5,STORAGE_ARR) NULLIFY(STORAGE_ARR) VAR => FIND_VAR(OBC_W_FILE,WQM_NAME(6,1),FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION WATER QUALITY NUDGING FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_WQM_FILE),& &"COULD NOT FIND VARIABLE "//TRIM(WQM_NAME(6,1))) ATT => FIND_ATT(VAR,'units',FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION WATER QUALITY NUDGING FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_WQM_FILE),& &"COULD NOT FIND VARIRIABLE ON'S ATTRIBUTE 'units'") if(TRIM(ATT%CHR(1)) .NE. WQM_NAME(6,2)) CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION WATER QUALITY NUDGING FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_WQM_FILE),& &"VARIRIABLE ON'S ATTRIBUTE 'units' SHOULD BE "//TRIM(WQM_NAME(6,2))) ! MAKE SPACE FOR THE DATA FROM THE FILE ALLOCATE(STORAGE_ARR(IOBCN,KBM1), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN OBC_WQM") OBC_W_N6 => reference_var(var) CALL NC_CONNECT_PVAR(OBC_W_N6,STORAGE_ARR) NULLIFY(STORAGE_ARR) ! MAKE SPACE FOR THE DATA FROM THE FILE ALLOCATE(STORAGE_ARR(IOBCN,KBM1), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN OBC_WQM") OBC_W_P6 => reference_var(var) CALL NC_CONNECT_PVAR(OBC_W_P6,STORAGE_ARR) NULLIFY(STORAGE_ARR) VAR => FIND_VAR(OBC_W_FILE,WQM_NAME(7,1),FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION WATER QUALITY NUDGING FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_WQM_FILE),& &"COULD NOT FIND VARIABLE "//TRIM(WQM_NAME(7,1))) ATT => FIND_ATT(VAR,'units',FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION WATER QUALITY NUDGING FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_WQM_FILE),& &"COULD NOT FIND VARIRIABLE OPO4'S ATTRIBUTE 'units'") if(TRIM(ATT%CHR(1)) .NE. WQM_NAME(7,2)) CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION WATER QUALITY NUDGING FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_WQM_FILE),& &"VARIRIABLE OPO4'S ATTRIBUTE 'units' SHOULD BE "//TRIM(WQM_NAME(7,2))) ! MAKE SPACE FOR THE DATA FROM THE FILE ALLOCATE(STORAGE_ARR(IOBCN,KBM1), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN OBC_WQM") OBC_W_N7 => reference_var(var) CALL NC_CONNECT_PVAR(OBC_W_N7,STORAGE_ARR) NULLIFY(STORAGE_ARR) ! MAKE SPACE FOR THE DATA FROM THE FILE ALLOCATE(STORAGE_ARR(IOBCN,KBM1), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN OBC_WQM") OBC_W_P7 => reference_var(var) CALL NC_CONNECT_PVAR(OBC_W_P7,STORAGE_ARR) NULLIFY(STORAGE_ARR) VAR => FIND_VAR(OBC_W_FILE,WQM_NAME(8,1),FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION WATER QUALITY NUDGING FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_WQM_FILE),& &"COULD NOT FIND VARIABLE "//TRIM(WQM_NAME(8,1))) ATT => FIND_ATT(VAR,'units',FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION WATER QUALITY NUDGING FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_WQM_FILE),& &"COULD NOT FIND VARIRIABLE OP'S ATTRIBUTE 'units'") if(TRIM(ATT%CHR(1)) .NE. WQM_NAME(8,2)) CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION WATER QUALITY NUDGING FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_WQM_FILE),& &"VARIRIABLE OP'S ATTRIBUTE 'units' SHOULD BE "//TRIM(WQM_NAME(8,2))) ! MAKE SPACE FOR THE DATA FROM THE FILE ALLOCATE(STORAGE_ARR(IOBCN,KBM1), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN OBC_WQM") OBC_W_N8 => reference_var(var) CALL NC_CONNECT_PVAR(OBC_W_N8,STORAGE_ARR) NULLIFY(STORAGE_ARR) ! MAKE SPACE FOR THE DATA FROM THE FILE ALLOCATE(STORAGE_ARR(IOBCN,KBM1), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN OBC_WQM") OBC_W_P8 => reference_var(var) CALL NC_CONNECT_PVAR(OBC_W_P8,STORAGE_ARR) NULLIFY(STORAGE_ARR) !===================================== ! DEFAULT CASE IF GLOBAL ATTRIBUTES OF FILE ARE INCORRECT CASE DEFAULT !===================================== CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION WATER QUALITY FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_WQM_FILE),& &"THE GLOBAL ATTRIBURE 'type' RETURNED UNKNOWN TYPE:",& & TRIM(ATT%CHR(1))) END SELECT ! ---------- new: 2016 , april, Karsten Lettmann after Hint by Qi and ayumi.fujisaki@noaa.gov------ ! Initialize some variables ! afm 20150914 ! Need initialization. Otherwise, random values are asigned ! and cause a hanging problem of MPI job in UPDATE_VAR_BRACKET ! This problem reported with Intel15.0.3. OBC_W_P1%curr_stkcnt = 0; OBC_W_N1%curr_stkcnt = 0 OBC_W_P2%curr_stkcnt = 0; OBC_W_N2%curr_stkcnt = 0 OBC_W_P3%curr_stkcnt = 0; OBC_W_N3%curr_stkcnt = 0 OBC_W_P4%curr_stkcnt = 0; OBC_W_N4%curr_stkcnt = 0 OBC_W_P5%curr_stkcnt = 0; OBC_W_N5%curr_stkcnt = 0 OBC_W_P6%curr_stkcnt = 0; OBC_W_N6%curr_stkcnt = 0 OBC_W_P7%curr_stkcnt = 0; OBC_W_N7%curr_stkcnt = 0 OBC_W_P8%curr_stkcnt = 0; OBC_W_N8%curr_stkcnt = 0 ! -------- end new ---------------------------------------------------------------- IF(DBG_SET(DBG_SBR)) write(IPT,*) "END OBC_WQM" END SUBROUTINE OBC_WQM # endif !================================================================ !================================================================ # if defined (BioGen) SUBROUTINE OBC_BIO USE MOD_1D, ONLY : NTT, BIO_NAME IMPLICIT NONE ! SOME NC POINTERS TYPE(NCATT), POINTER :: ATT, ATT_DATE TYPE(NCDIM), POINTER :: DIM TYPE(NCVAR), POINTER :: VAR LOGICAL :: FOUND INTEGER MYNOBC INTEGER, ALLOCATABLE :: MYOBCLIST(:) INTEGER :: MYSIGLAY REAL(SP), POINTER :: STORAGE_ARR(:,:), storage_vec(:) INTEGER :: NTIMES, I TYPE(TIME) :: TIMETEST INTEGER :: STATUS IF(DBG_SET(DBG_SBR)) write(IPT,*) "START OBC_BIO" IF (.NOT. OBC_BIO_NUDGING) THEN IF(DBG_SET(DBG_LOG)) write(IPT,*) "! OPEN BOUNDARY BIOLOGICAL NUDGING IS OFF!" OBC_B_COMMENTS="OPEN BOUNDARY BIOLOGICAL NUDGING IS OFF!" RETURN END IF IF(DBG_SET(DBG_LOG)) write(IPT,*) "! OPEN BOUNDARY BIOLOGICAL NUDGING IS ON!" OBC_B_COMMENTS="OPEN BOUNDARY BIOLOGICAL NUDGING IS ON!" ! FIND THE FORCING FILE OBJECT OBC_B_FILE => FIND_FILE(FILEHEAD,trim(OBC_BIO_FILE),FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("COULD NOT FIND OPEN BOUNDARY CONDITION BIOLOGICAL FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_BIO_FILE)) ATT => FIND_ATT(OBC_B_FILE,"type",FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION BIOLOGICAL FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_BIO_FILE),& &"COULD NOT FIND GLOBAL ATTRIBURE: 'type'") SELECT CASE(TRIM(ATT%CHR(1))) !================================= ! TIME SERIES OBC BIOLOGICAL NUDGING DATA CASE("FVCOM TIME SERIES OBC BIO FILE") !================================== OBC_B_TYPE = OBC_B_SIGMA ATT => FIND_ATT(OBC_B_FILE,"title",FOUND) IF(FOUND) THEN OBC_B_COMMENTS = "Open Boundary Biological Data: "& &//TRIM(ATT%CHR(1)) ELSE CALL WARNING("ATTRIBUTE 'title' IS MISSING IN THE BIOLOGICAL NUDGING FILE!") OBC_B_COMMENTS = "Open Boundary Biological Data: UNKOWN SOURCE" END IF ! LOOK FOR THE DIMENSIONS 'nobc' and 'time' DIM => FIND_DIM(OBC_B_FILE,'time',FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION BIOLOGICAL NUDGING FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_BIO_FILE),& &"COULD NOT FIND DIMENSION 'time'") NTIMES = DIM%DIM DIM => FIND_DIM(OBC_B_FILE,'siglay',FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION BIOLOGICAL NUDGING FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_BIO_FILE),& &"COULD NOT FIND DIMENSION 'siglay'") MYSIGLAY = DIM%DIM if(KBM1 /= MYSIGLAY) CALL FATAL_ERROR& & ("IN OPEN BOUNDARY CONDITION BIOLOGICAL NUDGING FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_BIO_FILE),& &"THE 'siglay' DIMENSION DOES NOT MATCH THE MODEL RUN!") DIM => FIND_DIM(OBC_B_FILE,'nobc',FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION BIOLOGICAL NUDGING FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_BIO_FILE),& &"COULD NOT FIND DIMENSION 'nobc'") if(IOBCN_GL>0) then IF(IOBCN_GL /= DIM%DIM) CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION BIOLOGICAL NUDGING FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_BIO_FILE),& &"THE DIMENSION 'nobc' MUST MATCH THE NUMBER OF OBC NODES") endif ! lOAD GLOBAL OPEN BOUNDARY NOD NUMBER DATA AND COMPARE WITH ! OBC.DAT/RESTART FILE INPUT ALLOCATE(MYOBCLIST(IOBCN)) VAR => FIND_VAR(OBC_B_FILE,'obc_nodes',FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION BIOLOGICAL NUDGING FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_BIO_FILE),& &"COULD NOT FIND VARIABLE 'obc_nodes'") CALL NC_CONNECT_AVAR(VAR,MYOBCLIST) CALL NC_READ_VAR(VAR) DO I = 1, IOBCN IF(SERIAL) THEN IF(I_OBC_N(I) /= MYOBCLIST(I)) THEN write(IPT,*) "NLID(MYOBCLIST)= ", MYOBCLIST(I), "; I=",I write(IPT,*) "I_OBC_N= ", I_OBC_N(I), "; I=",I CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION BIOLOGICAL NUDGING FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_BIO_FILE),& &"THE LIST OF BOUNDARY NODES DOES NOT MATCH") END IF ELSE # if defined(MULTIPROCESSOR) IF(I_OBC_N(I) /= NLID(MYOBCLIST(I))) THEN write(IPT,*) "NLID(MYOBCLIST)= ", NLID(MYOBCLIST(I)), "; I=",I write(IPT,*) "I_OBC_N= ", I_OBC_N(I), "; I=",I CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION BIOLOGICAL NUDGING FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_BIO_FILE),& &"THE LIST OF BOUNDARY NODES DOES NOT MATCH") END IF # endif END IF END DO ! LOAD TIME AND CHECK TO MAKE SURE THE TIME RANGE IS VALID TIMETEST = GET_FILE_TIME(OBC_B_FILE,1) IF(TIMETEST > STARTTIME) CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION BIOLOGICAL NUDGING FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_BIO_FILE),& &"THE MODEL RUN STARTS BEFORE THE BIOLOGICAL TIME SERIES") TIMETEST = GET_FILE_TIME(OBC_B_FILE,NTIMES) IF(TIMETEST < ENDTIME) CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION BIOLOGICAL NUDGING FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_BIO_FILE),& &"THE MODEL RUN ENDS AFTER THE BIOLOGICAL TIME SERIES") IF(NTT > 0)THEN VAR => FIND_VAR(OBC_B_FILE,BIO_NAME(1,1),FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION BIOLOGICAL NUDGING FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_BIO_FILE),& &"COULD NOT FIND VARIABLE "//TRIM(BIO_NAME(1,1))) ATT => FIND_ATT(VAR,'units',FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION BIOLOGICAL NUDGING FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_BIO_FILE),& &"COULD NOT FIND BIO1 VARIRIABLE'S ATTRIBUTE 'units'") if(TRIM(ATT%CHR(1)) .NE. BIO_NAME(1,2)) CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION BIOLOGICAL NUDGING FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_BIO_FILE),& &"BIO1 VARIRIABLE ATTRIBUTE 'units' SHOULD BE "//TRIM(BIO_NAME(1,2))) ! MAKE SPACE FOR THE DATA FROM THE FILE ALLOCATE(STORAGE_ARR(IOBCN,KBM1), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN OBC_BIO") OBC_B_N1 => reference_var(var) CALL NC_CONNECT_PVAR(OBC_B_N1,STORAGE_ARR) NULLIFY(STORAGE_ARR) ! MAKE SPACE FOR THE DATA FROM THE FILE ALLOCATE(STORAGE_ARR(IOBCN,KBM1), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN OBC_BIO") OBC_B_P1 => reference_var(var) CALL NC_CONNECT_PVAR(OBC_B_P1,STORAGE_ARR) NULLIFY(STORAGE_ARR) END IF IF(NTT > 1)THEN VAR => FIND_VAR(OBC_B_FILE,BIO_NAME(2,1),FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION BIOLOGICAL NUDGING FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_BIO_FILE),& &"COULD NOT FIND VARIABLE "//TRIM(BIO_NAME(2,1))) ATT => FIND_ATT(VAR,'units',FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION BIOLOGICAL NUDGING FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_BIO_FILE),& &"COULD NOT FIND BIO2 VARIRIABLE'S ATTRIBUTE 'units'") if(TRIM(ATT%CHR(1)) .NE. BIO_NAME(2,2)) CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION BIOLOGICAL NUDGING FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_BIO_FILE),& &"BIO2 VARIRIABLE ATTRIBUTE 'units' SHOULD BE "//TRIM(BIO_NAME(2,2))) ! MAKE SPACE FOR THE DATA FROM THE FILE ALLOCATE(STORAGE_ARR(IOBCN,KBM1), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN OBC_BIO") OBC_B_N2 => reference_var(var) CALL NC_CONNECT_PVAR(OBC_B_N2,STORAGE_ARR) NULLIFY(STORAGE_ARR) ! MAKE SPACE FOR THE DATA FROM THE FILE ALLOCATE(STORAGE_ARR(IOBCN,KBM1), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN OBC_BIO") OBC_B_P2 => reference_var(var) CALL NC_CONNECT_PVAR(OBC_B_P2,STORAGE_ARR) NULLIFY(STORAGE_ARR) END IF IF(NTT > 2)THEN VAR => FIND_VAR(OBC_B_FILE,BIO_NAME(3,1),FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION BIOLOGICAL NUDGING FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_BIO_FILE),& &"COULD NOT FIND VARIABLE "//TRIM(BIO_NAME(3,1))) ATT => FIND_ATT(VAR,'units',FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION BIOLOGICAL NUDGING FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_BIO_FILE),& &"COULD NOT FIND BIO3 VARIRIABLE'S ATTRIBUTE 'units'") if(TRIM(ATT%CHR(1)) .NE. BIO_NAME(3,2)) CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION BIOLOGICAL NUDGING FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_BIO_FILE),& &"BIO3 VARIRIABLE ATTRIBUTE 'units' SHOULD BE "//TRIM(BIO_NAME(3,2))) ! MAKE SPACE FOR THE DATA FROM THE FILE ALLOCATE(STORAGE_ARR(IOBCN,KBM1), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN OBC_BIO") OBC_B_N3 => reference_var(var) CALL NC_CONNECT_PVAR(OBC_B_N3,STORAGE_ARR) NULLIFY(STORAGE_ARR) ! MAKE SPACE FOR THE DATA FROM THE FILE ALLOCATE(STORAGE_ARR(IOBCN,KBM1), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN OBC_BIO") OBC_B_P3 => reference_var(var) CALL NC_CONNECT_PVAR(OBC_B_P3,STORAGE_ARR) NULLIFY(STORAGE_ARR) END IF IF(NTT > 3)THEN VAR => FIND_VAR(OBC_B_FILE,BIO_NAME(4,1),FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION BIOLOGICAL NUDGING FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_BIO_FILE),& &"COULD NOT FIND VARIABLE "//TRIM(BIO_NAME(4,1))) ATT => FIND_ATT(VAR,'units',FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION BIOLOGICAL NUDGING FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_BIO_FILE),& &"COULD NOT FIND BIO4 VARIRIABLE'S ATTRIBUTE 'units'") if(TRIM(ATT%CHR(1)) .NE. BIO_NAME(4,2)) CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION BIOLOGICAL NUDGING FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_BIO_FILE),& &"BIO4 VARIRIABLE ATTRIBUTE 'units' SHOULD BE "//TRIM(BIO_NAME(4,2))) ! MAKE SPACE FOR THE DATA FROM THE FILE ALLOCATE(STORAGE_ARR(IOBCN,KBM1), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN OBC_BIO") OBC_B_N4 => reference_var(var) CALL NC_CONNECT_PVAR(OBC_B_N4,STORAGE_ARR) NULLIFY(STORAGE_ARR) ! MAKE SPACE FOR THE DATA FROM THE FILE ALLOCATE(STORAGE_ARR(IOBCN,KBM1), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN OBC_BIO") OBC_B_P4 => reference_var(var) CALL NC_CONNECT_PVAR(OBC_B_P4,STORAGE_ARR) NULLIFY(STORAGE_ARR) END IF IF(NTT > 4)THEN VAR => FIND_VAR(OBC_B_FILE,BIO_NAME(5,1),FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION BIOLOGICAL NUDGING FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_BIO_FILE),& &"COULD NOT FIND VARIABLE "//TRIM(BIO_NAME(5,1))) ATT => FIND_ATT(VAR,'units',FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION BIOLOGICAL NUDGING FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_BIO_FILE),& &"COULD NOT FIND BIO5 VARIRIABLE'S ATTRIBUTE 'units'") if(TRIM(ATT%CHR(1)) .NE. BIO_NAME(5,2)) CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION BIOLOGICAL NUDGING FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_BIO_FILE),& &"BIO5 VARIRIABLE ATTRIBUTE 'units' SHOULD BE "//TRIM(BIO_NAME(5,2))) ! MAKE SPACE FOR THE DATA FROM THE FILE ALLOCATE(STORAGE_ARR(IOBCN,KBM1), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN OBC_BIO") OBC_B_N5 => reference_var(var) CALL NC_CONNECT_PVAR(OBC_B_N5,STORAGE_ARR) NULLIFY(STORAGE_ARR) ! MAKE SPACE FOR THE DATA FROM THE FILE ALLOCATE(STORAGE_ARR(IOBCN,KBM1), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN OBC_BIO") OBC_B_P5 => reference_var(var) CALL NC_CONNECT_PVAR(OBC_B_P5,STORAGE_ARR) NULLIFY(STORAGE_ARR) END IF IF(NTT > 5)THEN VAR => FIND_VAR(OBC_B_FILE,BIO_NAME(6,1),FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION BIOLOGICAL NUDGING FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_BIO_FILE),& &"COULD NOT FIND VARIABLE "//TRIM(BIO_NAME(6,1))) ATT => FIND_ATT(VAR,'units',FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION BIOLOGICAL NUDGING FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_BIO_FILE),& &"COULD NOT FIND BIO6 VARIRIABLE'S ATTRIBUTE 'units'") if(TRIM(ATT%CHR(1)) .NE. BIO_NAME(6,2)) CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION BIOLOGICAL NUDGING FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_BIO_FILE),& &"BIO6 VARIRIABLE ATTRIBUTE 'units' SHOULD BE "//TRIM(BIO_NAME(6,2))) ! MAKE SPACE FOR THE DATA FROM THE FILE ALLOCATE(STORAGE_ARR(IOBCN,KBM1), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN OBC_BIO") OBC_B_N6 => reference_var(var) CALL NC_CONNECT_PVAR(OBC_B_N6,STORAGE_ARR) NULLIFY(STORAGE_ARR) ! MAKE SPACE FOR THE DATA FROM THE FILE ALLOCATE(STORAGE_ARR(IOBCN,KBM1), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN OBC_BIO") OBC_B_P6 => reference_var(var) CALL NC_CONNECT_PVAR(OBC_B_P6,STORAGE_ARR) NULLIFY(STORAGE_ARR) END IF IF(NTT > 6)THEN VAR => FIND_VAR(OBC_B_FILE,BIO_NAME(7,1),FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION BIOLOGICAL NUDGING FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_BIO_FILE),& &"COULD NOT FIND VARIABLE "//TRIM(BIO_NAME(7,1))) ATT => FIND_ATT(VAR,'units',FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION BIOLOGICAL NUDGING FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_BIO_FILE),& &"COULD NOT FIND BIO7 VARIRIABLE'S ATTRIBUTE 'units'") if(TRIM(ATT%CHR(1)) .NE. BIO_NAME(7,2)) CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION BIOLOGICAL NUDGING FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_BIO_FILE),& &"BIO7 VARIRIABLE ATTRIBUTE 'units' SHOULD BE "//TRIM(BIO_NAME(7,2))) ! MAKE SPACE FOR THE DATA FROM THE FILE ALLOCATE(STORAGE_ARR(IOBCN,KBM1), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN OBC_BIO") OBC_B_N7 => reference_var(var) CALL NC_CONNECT_PVAR(OBC_B_N7,STORAGE_ARR) NULLIFY(STORAGE_ARR) ! MAKE SPACE FOR THE DATA FROM THE FILE ALLOCATE(STORAGE_ARR(IOBCN,KBM1), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN OBC_BIO") OBC_B_P7 => reference_var(var) CALL NC_CONNECT_PVAR(OBC_B_P7,STORAGE_ARR) NULLIFY(STORAGE_ARR) END IF IF(NTT > 7)THEN VAR => FIND_VAR(OBC_B_FILE,BIO_NAME(8,1),FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION BIOLOGICAL NUDGING FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_BIO_FILE),& &"COULD NOT FIND VARIABLE "//TRIM(BIO_NAME(8,1))) ATT => FIND_ATT(VAR,'units',FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION BIOLOGICAL NUDGING FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_BIO_FILE),& &"COULD NOT FIND BIO8 VARIRIABLE'S ATTRIBUTE 'units'") if(TRIM(ATT%CHR(1)) .NE. BIO_NAME(8,2)) CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION BIOLOGICAL NUDGING FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_BIO_FILE),& &"BIO8 VARIRIABLE ATTRIBUTE 'units' SHOULD BE "//TRIM(BIO_NAME(8,2))) ! MAKE SPACE FOR THE DATA FROM THE FILE ALLOCATE(STORAGE_ARR(IOBCN,KBM1), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN OBC_BIO") OBC_B_N8 => reference_var(var) CALL NC_CONNECT_PVAR(OBC_B_N8,STORAGE_ARR) NULLIFY(STORAGE_ARR) ! MAKE SPACE FOR THE DATA FROM THE FILE ALLOCATE(STORAGE_ARR(IOBCN,KBM1), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN OBC_BIO") OBC_B_P8 => reference_var(var) CALL NC_CONNECT_PVAR(OBC_B_P8,STORAGE_ARR) NULLIFY(STORAGE_ARR) END IF IF(NTT > 8)THEN VAR => FIND_VAR(OBC_B_FILE,BIO_NAME(9,1),FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION BIOLOGICAL NUDGING FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_BIO_FILE),& &"COULD NOT FIND VARIABLE "//TRIM(BIO_NAME(9,1))) ATT => FIND_ATT(VAR,'units',FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION BIOLOGICAL NUDGING FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_BIO_FILE),& &"COULD NOT FIND BIO9 VARIRIABLE'S ATTRIBUTE 'units'") if(TRIM(ATT%CHR(1)) .NE. BIO_NAME(9,2)) CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION BIOLOGICAL NUDGING FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_BIO_FILE),& &"BIO9 VARIRIABLE ATTRIBUTE 'units' SHOULD BE "//TRIM(BIO_NAME(9,2))) ! MAKE SPACE FOR THE DATA FROM THE FILE ALLOCATE(STORAGE_ARR(IOBCN,KBM1), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN OBC_BIO") OBC_B_N9 => reference_var(var) CALL NC_CONNECT_PVAR(OBC_B_N9,STORAGE_ARR) NULLIFY(STORAGE_ARR) ! MAKE SPACE FOR THE DATA FROM THE FILE ALLOCATE(STORAGE_ARR(IOBCN,KBM1), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN OBC_BIO") OBC_B_P9 => reference_var(var) CALL NC_CONNECT_PVAR(OBC_B_P9,STORAGE_ARR) NULLIFY(STORAGE_ARR) END IF IF(NTT > 9)THEN VAR => FIND_VAR(OBC_B_FILE,BIO_NAME(10,1),FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION BIOLOGICAL NUDGING FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_BIO_FILE),& &"COULD NOT FIND VARIABLE "//TRIM(BIO_NAME(10,1))) ATT => FIND_ATT(VAR,'units',FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION BIOLOGICAL NUDGING FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_BIO_FILE),& &"COULD NOT FIND BIO10 VARIRIABLE'S ATTRIBUTE 'units'") if(TRIM(ATT%CHR(1)) .NE. BIO_NAME(10,2)) CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION BIOLOGICAL NUDGING FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_BIO_FILE),& &"BIO10 VARIRIABLE ATTRIBUTE 'units' SHOULD BE "//TRIM(BIO_NAME(10,2))) ! MAKE SPACE FOR THE DATA FROM THE FILE ALLOCATE(STORAGE_ARR(IOBCN,KBM1), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN OBC_BIO") OBC_B_N10 => reference_var(var) CALL NC_CONNECT_PVAR(OBC_B_N10,STORAGE_ARR) NULLIFY(STORAGE_ARR) ! MAKE SPACE FOR THE DATA FROM THE FILE ALLOCATE(STORAGE_ARR(IOBCN,KBM1), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN OBC_BIO") OBC_B_P10 => reference_var(var) CALL NC_CONNECT_PVAR(OBC_B_P10,STORAGE_ARR) NULLIFY(STORAGE_ARR) END IF IF(NTT > 10)THEN VAR => FIND_VAR(OBC_B_FILE,BIO_NAME(11,1),FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION BIOLOGICAL NUDGING FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_BIO_FILE),& &"COULD NOT FIND VARIABLE "//TRIM(BIO_NAME(11,1))) ATT => FIND_ATT(VAR,'units',FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION BIOLOGICAL NUDGING FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_BIO_FILE),& &"COULD NOT FIND BIO11 VARIRIABLE'S ATTRIBUTE 'units'") if(TRIM(ATT%CHR(1)) .NE. BIO_NAME(11,2)) CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION BIOLOGICAL NUDGING FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_BIO_FILE),& &"BIO11 VARIRIABLE ATTRIBUTE 'units' SHOULD BE "//TRIM(BIO_NAME(11,2))) ! MAKE SPACE FOR THE DATA FROM THE FILE ALLOCATE(STORAGE_ARR(IOBCN,KBM1), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN OBC_BIO") OBC_B_N11 => reference_var(var) CALL NC_CONNECT_PVAR(OBC_B_N11,STORAGE_ARR) NULLIFY(STORAGE_ARR) ! MAKE SPACE FOR THE DATA FROM THE FILE ALLOCATE(STORAGE_ARR(IOBCN,KBM1), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN OBC_BIO") OBC_B_P11 => reference_var(var) CALL NC_CONNECT_PVAR(OBC_B_P11,STORAGE_ARR) NULLIFY(STORAGE_ARR) END IF IF(NTT > 11)THEN VAR => FIND_VAR(OBC_B_FILE,BIO_NAME(12,1),FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION BIOLOGICAL NUDGING FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_BIO_FILE),& &"COULD NOT FIND VARIABLE "//TRIM(BIO_NAME(12,1))) ATT => FIND_ATT(VAR,'units',FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION BIOLOGICAL NUDGING FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_BIO_FILE),& &"COULD NOT FIND BIO12 VARIRIABLE'S ATTRIBUTE 'units'") if(TRIM(ATT%CHR(1)) .NE. BIO_NAME(12,2)) CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION BIOLOGICAL NUDGING FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_BIO_FILE),& &"BIO12 VARIRIABLE ATTRIBUTE 'units' SHOULD BE "//TRIM(BIO_NAME(12,2))) ! MAKE SPACE FOR THE DATA FROM THE FILE ALLOCATE(STORAGE_ARR(IOBCN,KBM1), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN OBC_BIO") OBC_B_N12 => reference_var(var) CALL NC_CONNECT_PVAR(OBC_B_N12,STORAGE_ARR) NULLIFY(STORAGE_ARR) ! MAKE SPACE FOR THE DATA FROM THE FILE ALLOCATE(STORAGE_ARR(IOBCN,KBM1), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN OBC_BIO") OBC_B_P12 => reference_var(var) CALL NC_CONNECT_PVAR(OBC_B_P12,STORAGE_ARR) NULLIFY(STORAGE_ARR) END IF IF(NTT > 12)THEN VAR => FIND_VAR(OBC_B_FILE,BIO_NAME(13,1),FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION BIOLOGICAL NUDGING FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_BIO_FILE),& &"COULD NOT FIND VARIABLE "//TRIM(BIO_NAME(13,1))) ATT => FIND_ATT(VAR,'units',FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION BIOLOGICAL NUDGING FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_BIO_FILE),& &"COULD NOT FIND BIO13 VARIRIABLE'S ATTRIBUTE 'units'") if(TRIM(ATT%CHR(1)) .NE. BIO_NAME(13,2)) CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION BIOLOGICAL NUDGING FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_BIO_FILE),& &"BIO13 VARIRIABLE ATTRIBUTE 'units' SHOULD BE "//TRIM(BIO_NAME(13,2))) ! MAKE SPACE FOR THE DATA FROM THE FILE ALLOCATE(STORAGE_ARR(IOBCN,KBM1), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN OBC_BIO") OBC_B_N13 => reference_var(var) CALL NC_CONNECT_PVAR(OBC_B_N13,STORAGE_ARR) NULLIFY(STORAGE_ARR) ! MAKE SPACE FOR THE DATA FROM THE FILE ALLOCATE(STORAGE_ARR(IOBCN,KBM1), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN OBC_BIO") OBC_B_P13 => reference_var(var) CALL NC_CONNECT_PVAR(OBC_B_P13,STORAGE_ARR) NULLIFY(STORAGE_ARR) END IF IF(NTT > 13)THEN VAR => FIND_VAR(OBC_B_FILE,BIO_NAME(14,1),FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION BIOLOGICAL NUDGING FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_BIO_FILE),& &"COULD NOT FIND VARIABLE "//TRIM(BIO_NAME(14,1))) ATT => FIND_ATT(VAR,'units',FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION BIOLOGICAL NUDGING FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_BIO_FILE),& &"COULD NOT FIND BIO14 VARIRIABLE'S ATTRIBUTE 'units'") if(TRIM(ATT%CHR(1)) .NE. BIO_NAME(14,2)) CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION BIOLOGICAL NUDGING FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_BIO_FILE),& &"BIO14 VARIRIABLE ATTRIBUTE 'units' SHOULD BE "//TRIM(BIO_NAME(14,2))) ! MAKE SPACE FOR THE DATA FROM THE FILE ALLOCATE(STORAGE_ARR(IOBCN,KBM1), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN OBC_BIO") OBC_B_N14 => reference_var(var) CALL NC_CONNECT_PVAR(OBC_B_N14,STORAGE_ARR) NULLIFY(STORAGE_ARR) ! MAKE SPACE FOR THE DATA FROM THE FILE ALLOCATE(STORAGE_ARR(IOBCN,KBM1), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN OBC_BIO") OBC_B_P14 => reference_var(var) CALL NC_CONNECT_PVAR(OBC_B_P14,STORAGE_ARR) NULLIFY(STORAGE_ARR) END IF IF(NTT > 14)THEN VAR => FIND_VAR(OBC_B_FILE,BIO_NAME(15,1),FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION BIOLOGICAL NUDGING FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_BIO_FILE),& &"COULD NOT FIND VARIABLE "//TRIM(BIO_NAME(15,1))) ATT => FIND_ATT(VAR,'units',FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION BIOLOGICAL NUDGING FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_BIO_FILE),& &"COULD NOT FIND BIO15 VARIRIABLE'S ATTRIBUTE 'units'") if(TRIM(ATT%CHR(1)) .NE. BIO_NAME(15,2)) CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION BIOLOGICAL NUDGING FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_BIO_FILE),& &"BIO15 VARIRIABLE ATTRIBUTE 'units' SHOULD BE "//TRIM(BIO_NAME(15,2))) ! MAKE SPACE FOR THE DATA FROM THE FILE ALLOCATE(STORAGE_ARR(IOBCN,KBM1), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN OBC_BIO") OBC_B_N15 => reference_var(var) CALL NC_CONNECT_PVAR(OBC_B_N15,STORAGE_ARR) NULLIFY(STORAGE_ARR) ! MAKE SPACE FOR THE DATA FROM THE FILE ALLOCATE(STORAGE_ARR(IOBCN,KBM1), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN OBC_BIO") OBC_B_P15 => reference_var(var) CALL NC_CONNECT_PVAR(OBC_B_P15,STORAGE_ARR) NULLIFY(STORAGE_ARR) END IF IF(NTT > 15)THEN VAR => FIND_VAR(OBC_B_FILE,BIO_NAME(16,1),FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION BIOLOGICAL NUDGING FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_BIO_FILE),& &"COULD NOT FIND VARIABLE "//TRIM(BIO_NAME(16,1))) ATT => FIND_ATT(VAR,'units',FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION BIOLOGICAL NUDGING FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_BIO_FILE),& &"COULD NOT FIND BIO16 VARIRIABLE'S ATTRIBUTE 'units'") if(TRIM(ATT%CHR(1)) .NE. BIO_NAME(16,2)) CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION BIOLOGICAL NUDGING FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_BIO_FILE),& &"BIO16 VARIRIABLE ATTRIBUTE 'units' SHOULD BE "//TRIM(BIO_NAME(16,2))) ! MAKE SPACE FOR THE DATA FROM THE FILE ALLOCATE(STORAGE_ARR(IOBCN,KBM1), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN OBC_BIO") OBC_B_N16 => reference_var(var) CALL NC_CONNECT_PVAR(OBC_B_N16,STORAGE_ARR) NULLIFY(STORAGE_ARR) ! MAKE SPACE FOR THE DATA FROM THE FILE ALLOCATE(STORAGE_ARR(IOBCN,KBM1), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN OBC_BIO") OBC_B_P16 => reference_var(var) CALL NC_CONNECT_PVAR(OBC_B_P16,STORAGE_ARR) NULLIFY(STORAGE_ARR) END IF IF(NTT > 16)THEN VAR => FIND_VAR(OBC_B_FILE,BIO_NAME(17,1),FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION BIOLOGICAL NUDGING FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_BIO_FILE),& &"COULD NOT FIND VARIABLE "//TRIM(BIO_NAME(17,1))) ATT => FIND_ATT(VAR,'units',FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION BIOLOGICAL NUDGING FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_BIO_FILE),& &"COULD NOT FIND BIO17 VARIRIABLE'S ATTRIBUTE 'units'") if(TRIM(ATT%CHR(1)) .NE. BIO_NAME(17,2)) CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION BIOLOGICAL NUDGING FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_BIO_FILE),& &"BIO17 VARIRIABLE ATTRIBUTE 'units' SHOULD BE "//TRIM(BIO_NAME(17,2))) ! MAKE SPACE FOR THE DATA FROM THE FILE ALLOCATE(STORAGE_ARR(IOBCN,KBM1), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN OBC_BIO") OBC_B_N17 => reference_var(var) CALL NC_CONNECT_PVAR(OBC_B_N17,STORAGE_ARR) NULLIFY(STORAGE_ARR) ! MAKE SPACE FOR THE DATA FROM THE FILE ALLOCATE(STORAGE_ARR(IOBCN,KBM1), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN OBC_BIO") OBC_B_P17 => reference_var(var) CALL NC_CONNECT_PVAR(OBC_B_P17,STORAGE_ARR) NULLIFY(STORAGE_ARR) END IF IF(NTT > 17)THEN VAR => FIND_VAR(OBC_B_FILE,BIO_NAME(18,1),FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION BIOLOGICAL NUDGING FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_BIO_FILE),& &"COULD NOT FIND VARIABLE "//TRIM(BIO_NAME(18,1))) ATT => FIND_ATT(VAR,'units',FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION BIOLOGICAL NUDGING FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_BIO_FILE),& &"COULD NOT FIND BIO18 VARIRIABLE'S ATTRIBUTE 'units'") if(TRIM(ATT%CHR(1)) .NE. BIO_NAME(18,2)) CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION BIOLOGICAL NUDGING FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_BIO_FILE),& &"BIO18 VARIRIABLE ATTRIBUTE 'units' SHOULD BE "//TRIM(BIO_NAME(18,2))) ! MAKE SPACE FOR THE DATA FROM THE FILE ALLOCATE(STORAGE_ARR(IOBCN,KBM1), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN OBC_BIO") OBC_B_N18 => reference_var(var) CALL NC_CONNECT_PVAR(OBC_B_N18,STORAGE_ARR) NULLIFY(STORAGE_ARR) ! MAKE SPACE FOR THE DATA FROM THE FILE ALLOCATE(STORAGE_ARR(IOBCN,KBM1), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN OBC_BIO") OBC_B_P18 => reference_var(var) CALL NC_CONNECT_PVAR(OBC_B_P18,STORAGE_ARR) NULLIFY(STORAGE_ARR) END IF IF(NTT > 18)THEN VAR => FIND_VAR(OBC_B_FILE,BIO_NAME(19,1),FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION BIOLOGICAL NUDGING FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_BIO_FILE),& &"COULD NOT FIND VARIABLE "//TRIM(BIO_NAME(19,1))) ATT => FIND_ATT(VAR,'units',FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION BIOLOGICAL NUDGING FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_BIO_FILE),& &"COULD NOT FIND BIO19 VARIRIABLE'S ATTRIBUTE 'units'") if(TRIM(ATT%CHR(1)) .NE. BIO_NAME(19,2)) CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION BIOLOGICAL NUDGING FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_BIO_FILE),& &"BIO19 VARIRIABLE ATTRIBUTE 'units' SHOULD BE "//TRIM(BIO_NAME(19,2))) ! MAKE SPACE FOR THE DATA FROM THE FILE ALLOCATE(STORAGE_ARR(IOBCN,KBM1), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN OBC_BIO") OBC_B_N19 => reference_var(var) CALL NC_CONNECT_PVAR(OBC_B_N19,STORAGE_ARR) NULLIFY(STORAGE_ARR) ! MAKE SPACE FOR THE DATA FROM THE FILE ALLOCATE(STORAGE_ARR(IOBCN,KBM1), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN OBC_BIO") OBC_B_P19 => reference_var(var) CALL NC_CONNECT_PVAR(OBC_B_P19,STORAGE_ARR) NULLIFY(STORAGE_ARR) END IF IF(NTT > 19)THEN VAR => FIND_VAR(OBC_B_FILE,BIO_NAME(20,1),FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION BIOLOGICAL NUDGING FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_BIO_FILE),& &"COULD NOT FIND VARIABLE "//TRIM(BIO_NAME(20,1))) ATT => FIND_ATT(VAR,'units',FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION BIOLOGICAL NUDGING FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_BIO_FILE),& &"COULD NOT FIND BIO20 VARIRIABLE'S ATTRIBUTE 'units'") if(TRIM(ATT%CHR(1)) .NE. BIO_NAME(20,2)) CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION BIOLOGICAL NUDGING FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_BIO_FILE),& &"BIO20 VARIRIABLE ATTRIBUTE 'units' SHOULD BE "//TRIM(BIO_NAME(20,2))) ! MAKE SPACE FOR THE DATA FROM THE FILE ALLOCATE(STORAGE_ARR(IOBCN,KBM1), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN OBC_BIO") OBC_B_N20 => reference_var(var) CALL NC_CONNECT_PVAR(OBC_B_N20,STORAGE_ARR) NULLIFY(STORAGE_ARR) ! MAKE SPACE FOR THE DATA FROM THE FILE ALLOCATE(STORAGE_ARR(IOBCN,KBM1), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN OBC_BIO") OBC_B_P20 => reference_var(var) CALL NC_CONNECT_PVAR(OBC_B_P20,STORAGE_ARR) NULLIFY(STORAGE_ARR) END IF IF(NTT > 20)THEN CALL FATAL_ERROR & & ("MOD_FORCE NOT SETUP FOR NTT > 20 REVISE") ENDIF !===================================== ! DEFAULT CASE IF GLOBAL ATTRIBUTES OF FILE ARE INCORRECT CASE DEFAULT !===================================== CALL FATAL_ERROR & & ("IN OPEN BOUNDARY CONDITION BIOLOGICAL FILE OBJECT",& & "FILE NAME: "//TRIM(OBC_BIO_FILE),& &"THE GLOBAL ATTRIBURE 'type' RETURNED UNKNOWN TYPE:",& & TRIM(ATT%CHR(1))) END SELECT ! ---------- new: 2016 , april, Karsten Lettmann after Hint by Qi and ayumi.fujisaki@noaa.gov------ ! Initialize some variables ! afm 20150914 ! Need initialization. Otherwise, random values are asigned ! and cause a hanging problem of MPI job in UPDATE_VAR_BRACKET ! This problem reported with Intel15.0.3. OBC_B_P1%CURR_STKCNT = 0; OBC_B_N1%CURR_STKCNT = 0 OBC_B_P2%CURR_STKCNT = 0; OBC_B_N2%CURR_STKCNT = 0 OBC_B_P3%CURR_STKCNT = 0; OBC_B_N3%CURR_STKCNT = 0 OBC_B_P4%CURR_STKCNT = 0; OBC_B_N4%CURR_STKCNT = 0 OBC_B_P5%CURR_STKCNT = 0; OBC_B_N5%CURR_STKCNT = 0 OBC_B_P6%CURR_STKCNT = 0; OBC_B_N6%CURR_STKCNT = 0 OBC_B_P7%CURR_STKCNT = 0; OBC_B_N7%CURR_STKCNT = 0 OBC_B_P8%CURR_STKCNT = 0; OBC_B_N8%CURR_STKCNT = 0 OBC_B_P9%CURR_STKCNT = 0; OBC_B_N9%CURR_STKCNT = 0 OBC_B_P10%CURR_STKCNT = 0; OBC_B_N10%CURR_STKCNT = 0 OBC_B_P11%CURR_STKCNT = 0; OBC_B_N11%CURR_STKCNT = 0 OBC_B_P12%CURR_STKCNT = 0; OBC_B_N12%CURR_STKCNT = 0 OBC_B_P13%CURR_STKCNT = 0; OBC_B_N13%CURR_STKCNT = 0 OBC_B_P14%CURR_STKCNT = 0; OBC_B_N14%CURR_STKCNT = 0 OBC_B_P15%CURR_STKCNT = 0; OBC_B_N15%CURR_STKCNT = 0 OBC_B_P16%CURR_STKCNT = 0; OBC_B_N16%CURR_STKCNT = 0 OBC_B_P17%CURR_STKCNT = 0; OBC_B_N17%CURR_STKCNT = 0 OBC_B_P18%CURR_STKCNT = 0; OBC_B_N18%CURR_STKCNT = 0 OBC_B_P19%CURR_STKCNT = 0; OBC_B_N19%CURR_STKCNT = 0 OBC_B_P20%CURR_STKCNT = 0; OBC_B_N20%CURR_STKCNT = 0 ! -------- end new ---------------------------------------------------------------- IF(DBG_SET(DBG_SBR)) write(IPT,*) "END OBC_BIO" END SUBROUTINE OBC_BIO # endif !================================================================ !================================================================ ! CURRENTELY NOT IN USE! REPLACEED BY INTERP_BILINEAR WHICH IS A ! GENERAL INTERPOLATION SCHEME FOR CURVILINEAR COORDINATES !!$ SUBROUTINE SET_FILE_INTERP_QUAD(NCF,INTP_N,INTP_C) !!$ IMPLICIT NONE !!$ TYPE(NCFILE), POINTER :: NCF !!$ TYPE(INTERP_WEIGHTS),POINTER :: INTP_N !!$ TYPE(INTERP_WEIGHTS),POINTER :: INTP_C !!$ !!$ TYPE(NCATT), POINTER :: ATT !!$ TYPE(NCDIM), POINTER :: DIM !!$ TYPE(NCVAR), POINTER :: VAR !!$ !!$ INTEGER :: LATS, LONS, I, Ntimes !!$ REAL(SP), POINTER :: XLON(:,:),XLAT(:,:) !!$ REAL(SP), POINTER :: HEATX(:,:),HEATY(:,:) !!$ REAL(SP), POINTER :: TMP1(:),TMP2(:) !!$ !!$ real(sp) :: rzero !!$ !!$ LOGICAL :: FOUND !!$ !!$ IF(.NOT. ASSOCIATED(NCF))CALL FATAL_ERROR& !!$ & ("SET_FILE_INTERP: FILE OBJECT ARGUMENT IS NOT ASSOCIATED!") !!$ !!$ ! EITHER BOTH WEIGHTS MUST ALREADY BE SET OR NONE !!$ IF(ASSOCIATED(NCF%INTERP_N)) THEN !!$ IF(ASSOCIATED(NCF%INTERP_C)) THEN !!$ INTP_N => NCF%INTERP_N !!$ INTP_C => NCF%INTERP_C !!$ RETURN !!$ ELSE !!$ CALL PRINT_FILE(NCF) !!$ CALL FATAL_ERROR("ONLY ONE INTERP POINTER IS ASSOCAITED IN THIS FILE",& !!$ & "SET_FILE_INTERP: IS NOT PREPARED TO HANDLE THIS.") !!$ END IF !!$ ELSE !!$ IF(ASSOCIATED(NCF%INTERP_C))THEN !!$ CALL PRINT_FILE(NCF) !!$ CALL FATAL_ERROR("ONLY ONE INTERP POINTER IS ASSOCAITED IN THIS FILE",& !!$ & "SET_FILE_INTERP: IS NOT PREPARED TO HANDLE THIS.") !!$ END IF !!$ !!$ END IF !!$ !!$ !!$ ATT => FIND_ATT(NCF,'DX',FOUND) !!$ IF(.not. FOUND) CALL FATAL_ERROR & !!$ & ( "SET_FILE_INTERP:",& !!$ & "FILE NAME: "//TRIM(NCF%FNAME),& !!$ & "COULD NOT FIND ATTRIBUTE 'DX'") !!$ !!$ rzero = att%flt(1) !!$ !!$ DIM => FIND_DIM(NCF,'south_north',FOUND) !!$ IF(.not. FOUND) CALL FATAL_ERROR & !!$ & ("SET_FILE_INTERP:",& !!$ & "FILE NAME: "//TRIM(NCF%FNAME),& !!$ & "COULD NOT FIND DIMENSION 'south_north'") !!$ !!$ LATS = DIM%DIM !!$ !!$ DIM => FIND_DIM(NCF,'west_east',FOUND) !!$ IF(.not. FOUND) CALL FATAL_ERROR & !!$ & ("SET_FILE_INTERP:",& !!$ & "FILE NAME: "//TRIM(NCF%FNAME),& !!$ & "COULD NOT FIND DIMENSION 'west_east'") !!$ LONS = DIM%DIM !!$ !!$ !!$ ! GET THE INTERPOLATION COEFFICIENTS !!$ ALLOCATE(XLON(lons,lats)) !!$ ALLOCATE(XLAT(lons,lats)) !!$ !!$ VAR => FIND_VAR(NCF,"XLAT",FOUND) !!$ IF(.not. FOUND) CALL FATAL_ERROR & !!$ & ("SET_FILE_INTERP:",& !!$ & "FILE NAME: "//TRIM(NCF%FNAME),& !!$ & "COULD NOT FIND VARIABLE 'XLAT'") !!$ !!$ CALL NC_CONNECT_PVAR(VAR,XLAT) !!$ CALL NC_READ_VAR(VAR) !!$ !!$ !!$ VAR => FIND_VAR(NCF,"XLONG",FOUND) !!$ IF(.not. FOUND) CALL FATAL_ERROR & !!$ & ("SET_FILE_INTERP:",& !!$ & "FILE NAME: "//TRIM(NCF%FNAME),& !!$ & "COULD NOT FIND VARIABLE 'XLONG'") !!$ !!$ CALL NC_CONNECT_PVAR(VAR,XLON) !!$ CALL NC_READ_VAR(VAR) !!$ !!$# if !defined(SPHERICAL) !!$ ALLOCATE(HEATX(lons,lats)) !!$ ALLOCATE(HEATY(lons,lats)) !!$ !!$ IF (.NOT. USE_PROJ) CALL FATAL_ERROR('PROJ IS NEEDED TO USE T& !!$ &HIS TYPE OF FORCING FILE IN CARTESIAN MODE:',& !!$ & ' RECOMPILE WITH projection 4') !!$ !!$ CALL DEGREES2METERS(XLON,XLAT,PROJECTION_REFERENCE,HEATX,HEATY,lons,lats) !!$ !!$ DEALLOCATE(XLAT,XLON) !!$# else !!$ HEATX => XLON !!$ HEATY => XLAT !!$ !!$ NULLIFY(XLON) !!$ NULLIFY(XLAT) !!$# endif !!$ TMP1 => XM !!$ TMP2 => YM !!$ ALLOCATE(INTP_N) !!$ CALL SETUP_INTERP_QUAD_P(HEATX,HEATY,TMP1,TMP2,INTP_N,rzero) !!$ !!$ TMP1 => XMC !!$ TMP2 => YMC !!$ !!$ ALLOCATE(INTP_C) !!$ CALL SETUP_INTERP_QUAD_P(HEATX,HEATY,TMP1,TMP2,INTP_C,rzero) !!$ !!$ ! THIS SHOULD DEALLOCATE HEATX,HEATY FOR NON SPHERICAL !!$ ! THIS SHOULD DEALLOCATE HEATX,HEATY WHICH ARE POINTED AT !!$ ! XLONS AND XLATS IN THE SHPERICAL CASE !!$ DEALLOCATE(HEATX, HEATY) !!$ !!$ !!$ NCF%INTERP_N => INTP_N !!$ NCF%INTERP_C => INTP_C !!$ !!$ END SUBROUTINE SET_FILE_INTERP_QUAD !================================================================ SUBROUTINE SET_FILE_INTERP_BILINEAR(NCF,INTP_N,INTP_C,MASK_VAR_NAME) IMPLICIT NONE TYPE(NCFILE), POINTER :: NCF TYPE(INTERP_WEIGHTS),POINTER :: INTP_N TYPE(INTERP_WEIGHTS),POINTER :: INTP_C TYPE(NCATT), POINTER :: ATT TYPE(NCDIM), POINTER :: DIM TYPE(NCVAR), POINTER :: VAR INTEGER :: LATS, LONS, I, Ntimes,j, ierr REAL(SP), POINTER :: XLON(:,:),XLAT(:,:) REAL(SP), POINTER :: HEATX(:,:),HEATY(:,:) REAL(SP), POINTER :: TMP1(:),TMP2(:) CHARACTER(LEN=80), OPTIONAL :: MASK_VAR_NAME REAL(SP), POINTER :: FMASK(:,:) INTEGER, POINTER :: MASK(:,:) LOGICAL :: FOUND IF(.NOT. ASSOCIATED(NCF))CALL FATAL_ERROR& & ("SET_FILE_INTERP: FILE OBJECT ARGUMENT IS NOT ASSOCIATED!") ! EITHER BOTH WEIGHTS MUST ALREADY BE SET OR NONE IF(ASSOCIATED(NCF%INTERP_N)) THEN IF(ASSOCIATED(NCF%INTERP_C)) THEN INTP_N => NCF%INTERP_N INTP_C => NCF%INTERP_C RETURN ELSE CALL PRINT_FILE(NCF) CALL FATAL_ERROR("ONLY ONE INTERP POINTER IS ASSOCAITED IN THIS FILE",& & "SET_FILE_INTERP: IS NOT PREPARED TO HANDLE THIS.") END IF ELSE IF(ASSOCIATED(NCF%INTERP_C))THEN CALL PRINT_FILE(NCF) CALL FATAL_ERROR("ONLY ONE INTERP POINTER IS ASSOCAITED IN THIS FILE",& & "SET_FILE_INTERP: IS NOT PREPARED TO HANDLE THIS.") END IF END IF DIM => FIND_DIM(NCF,'south_north',FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("SET_FILE_INTERP:",& & "FILE NAME: "//TRIM(NCF%FNAME),& & "COULD NOT FIND DIMENSION 'south_north'") LATS = DIM%DIM DIM => FIND_DIM(NCF,'west_east',FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("SET_FILE_INTERP:",& & "FILE NAME: "//TRIM(NCF%FNAME),& & "COULD NOT FIND DIMENSION 'west_east'") LONS = DIM%DIM ! GET THE INTERPOLATION COEFFICIENTS ALLOCATE(XLON(lons,lats)) ALLOCATE(XLAT(lons,lats)) ! # if !defined (SPHERICAL) && !defined (PROJ) !---> Siqi Li, Lu Wang, PROJ@20230928 VAR => FIND_VAR(NCF,"yy",FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("SET_FILE_INTERP:",& & "FILE NAME: "//TRIM(NCF%FNAME),& & "COULD NOT FIND VARIABLE 'yy'") CALL NC_CONNECT_PVAR(VAR,XLAT) CALL NC_READ_VAR(VAR) VAR => FIND_VAR(NCF,"xx",FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("SET_FILE_INTERP:",& & "FILE NAME: "//TRIM(NCF%FNAME),& & "COULD NOT FIND VARIABLE 'xx'") CALL NC_CONNECT_PVAR(VAR,XLON) CALL NC_READ_VAR(VAR) !<--- # else VAR => FIND_VAR(NCF,"XLAT",FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("SET_FILE_INTERP:",& & "FILE NAME: "//TRIM(NCF%FNAME),& & "COULD NOT FIND VARIABLE 'XLAT'") CALL NC_CONNECT_PVAR(VAR,XLAT) CALL NC_READ_VAR(VAR) VAR => FIND_VAR(NCF,"XLONG",FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("SET_FILE_INTERP:",& & "FILE NAME: "//TRIM(NCF%FNAME),& & "COULD NOT FIND VARIABLE 'XLONG'") CALL NC_CONNECT_PVAR(VAR,XLON) CALL NC_READ_VAR(VAR) # endif # if !defined(SPHERICAL) && defined (PROJ) ALLOCATE(HEATX(lons,lats)) ALLOCATE(HEATY(lons,lats)) IF (.NOT. USE_PROJ) CALL FATAL_ERROR('PROJ IS NEEDED TO USE T& &HIS TYPE OF FORCING FILE IN CARTESIAN MODE:',& & ' RECOMPILE WITH projection 4') IF(MSR) CALL DEGREES2METERS(XLON,XLAT,PROJECTION_REFERENCE,HEATX,HEATY,lons,lats) # if defined(MULTIPROCESSOR) IF (PAR) THEN CALL MPI_BCAST(HEATX,lats*lons,MPI_F,0,MPI_FVCOM_GROUP,ierr) CALL MPI_BCAST(HEATY,lats*lons,MPI_F,0,MPI_FVCOM_GROUP,ierr) END IF # endif DEALLOCATE(XLAT,XLON) # else ! WHERE (XLON<0.) XLON = XLON + 360._sp ! Siqi Li, XLON@20230817 HEATX => XLON HEATY => XLAT NULLIFY(XLON) NULLIFY(XLAT) # endif !!$ THIS IS VERY SLOW - LOAD DATA FROM A FILE IF NEEDED !!$ ! MAKE A LAND MASK !!$ ALLOCATE(MASK(lons,lats)) !!$ DO I = 1,lons !!$ DO J = 1,lats !!$ MASK(i,j) = FIND_ELEMENT_CONTAINING(HEATX(i,j)-vxmin,HEATY(i,j)-vymin) !!$ END DO !!$ END DO !!$ WHERE (MASK >0) !!$ MASK = 0 !!$ elsewhere !!$ MASK = 1 !!$ END WHERE IF (PRESENT(MASK_VAR_NAME))THEN VAR => FIND_VAR(NCF,MASK_VAR_NAME,FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("SET_FILE_INTERP:",& & "FILE NAME: "//TRIM(NCF%FNAME),& & "COULD NOT FIND VARIABLE 'XLONG'") select case(VAR%XTYPE) case(NF90_INT) ALLOCATE(MASK(lons,lats)) CALL NC_CONNECT_PVAR(VAR,MASK) CALL NC_READ_VAR(VAR) case(NF90_FLOAT) ALLOCATE(MASK(lons,lats)) ALLOCATE(FMASK(lons,lats)) CALL NC_CONNECT_PVAR(VAR,FMASK) CALL NC_READ_VAR(VAR) MASK = anint(FMASK) deallocate(Fmask) case default call fatal_error("SET_FILE_INTERP_BILINEAR: Unknown mask variable xtype?") END select TMP1 => VX TMP2 => VY # if !defined(SPHERICAL) TMP1 = TMP1 + VXmin TMP2 = TMP2 + VYmin # endif ALLOCATE(INTP_N) CALL SETUP_INTERP_BILINEAR_P(HEATX,HEATY,TMP1,TMP2,INTP_N,MASK) # if !defined(SPHERICAL) TMP1 = TMP1 - VXmin TMP2 = TMP2 - VYmin # endif TMP1 => XC TMP2 => YC # if !defined(SPHERICAL) TMP1 = TMP1 + VXmin TMP2 = TMP2 + VYmin # endif ALLOCATE(INTP_C) CALL SETUP_INTERP_BILINEAR_P(HEATX,HEATY,TMP1,TMP2,INTP_C,MASK) # if !defined(SPHERICAL) TMP1 = TMP1 - VXmin TMP2 = TMP2 - VYmin # endif ELSE TMP1 => VX TMP2 => VY # if !defined(SPHERICAL) TMP1 = TMP1 + VXmin TMP2 = TMP2 + VYmin # endif ! NO MASK ALLOCATE(INTP_N) CALL SETUP_INTERP_BILINEAR_P(HEATX,HEATY,TMP1,TMP2,INTP_N) # if !defined(SPHERICAL) TMP1 = TMP1 - VXmin TMP2 = TMP2 - VYmin # endif TMP1 => XC TMP2 => YC # if !defined(SPHERICAL) TMP1 = TMP1 + VXmin TMP2 = TMP2 + VYmin # endif ALLOCATE(INTP_C) CALL SETUP_INTERP_BILINEAR_P(HEATX,HEATY,TMP1,TMP2,INTP_C) # if !defined(SPHERICAL) TMP1 = TMP1 - VXmin TMP2 = TMP2 - VYmin # endif END IF ! THIS SHOULD DEALLOCATE HEATX,HEATY FOR NON SPHERICAL ! THIS SHOULD DEALLOCATE HEATX,HEATY WHICH ARE POINTED AT ! XLONS AND XLATS IN THE SHPERICAL CASE DEALLOCATE(HEATX, HEATY) NCF%INTERP_N => INTP_N NCF%INTERP_C => INTP_C END SUBROUTINE SET_FILE_INTERP_BILINEAR !================================================================ !================================================================ # if !defined (HEATING_CALCULATED) && !defined (HEATING_SOLAR) SUBROUTINE SURFACE_HEATING IMPLICIT NONE ! SOME NC POINTERS TYPE(NCATT), POINTER :: ATT, ATT_DATE TYPE(NCDIM), POINTER :: DIM TYPE(NCVAR), POINTER :: VAR LOGICAL :: FOUND REAL(SP), POINTER :: STORAGE_ARR(:,:), storage_vec(:) CHARACTER(len=60) :: swrstrng, nhfstrng TYPE(TIME) :: TIMETEST INTEGER :: LATS, LONS, I, Ntimes INTEGER :: STATUS IF(DBG_SET(DBG_SBR)) write(IPT,*) "START SURFACE_HEATING" NULLIFY(ATT,DIM,VAR,STORAGE_ARR,STORAGE_VEC) IF (.NOT. HEATING_ON ) THEN IF(DBG_SET(DBG_LOG)) write(IPT,*) "! SURFACE HEAT FORCING IS OFF!" ALLOCATE(HEAT_FORCING_COMMENTS(1)) HEAT_FORCING_COMMENTS(1) = "SURFACE HEAT FORCING IS OFF" RETURN END IF ! DETERMINE HOW TO LOAD THE DATA SELECT CASE(HEATING_KIND) CASE (CNSTNT) write(swrstrng,'(f8.4)') HEATING_RADIATION write(nhfstrng,'(f8.4)') HEATING_NETFLUX IF(DBG_SET(DBG_LOG)) THEN WRITE(IPT,*)"! SETTING UP CONSTANT HEAT FORCING: " WRITE(IPT,*)" Radiation: "//trim(swrstrng) WRITE(IPT,*)" Net Heat Flux: "//trim(nhfstrng) END IF ALLOCATE(HEAT_FORCING_COMMENTS(3)) HEAT_FORCING_COMMENTS(1) = "Using constant heating from run file:" HEAT_FORCING_COMMENTS(2) = "Radiation:"//trim(swrstrng) HEAT_FORCING_COMMENTS(3) = "Net Heat Flux:"//trim(nhfstrng) RETURN CASE(STTC) CALL FATAL_ERROR("STATIC HEATING Not Set Up Yet") CASE(TMDPNDNT) CALL FATAL_ERROR("TIME DEPENDANT HEATING Not Set Up Yet") CASE(PRDC) HEAT_FILE => FIND_FILE(FILEHEAD,trim(HEATING_FILE),FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("COULD NOT FIND SURFACE HEATING BOUNDARY CONDINTION FILE OBJECT",& & "FILE NAME: "//TRIM(HEATING_FILE)) ! DETERMINE GRID TYPE BASED ON SOURCE ATTRIBUTE ATT => FIND_ATT(HEAT_FILE,"source",FOUND) IF(.not. FOUND) ATT => FIND_ATT(HEAT_FILE,"Source",FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN SURFACE HEATING BOUNDARY CONDITION FILE OBJECT",& & "FILE NAME: "//TRIM(HEATING_FILE),& &"COULD NOT FIND GLOBAL ATTRIBURE: 'source'") IF (ATT%CHR(1)(1:len_trim(wrf2fvcom_source)) ==& & TRIM(wrf2fvcom_source)) THEN HEAT_FORCING_TYPE = HEAT_IS_WRFGRID ELSE IF (ATT%CHR(1)(1:len_trim(fvcom_grid_source)) ==& & TRIM(fvcom_grid_source)) THEN HEAT_FORCING_TYPE = HEAT_IS_FVCOMGRID ELSE IF (ATT%CHR(1)(1:len_trim(fvcom_cap_grid_source)) ==& & TRIM(fvcom_cap_grid_source)) THEN HEAT_FORCING_TYPE = HEAT_IS_FVCOMGRID ELSE IF (ATT%CHR(1)(1:len_trim(wrf_grid_source)) ==& & TRIM(wrf_grid_source)) THEN HEAT_FORCING_TYPE = HEAT_IS_WRFGRID ELSE CALL PRINT_FILE(HEAT_FILE) CALL FATAL_ERROR("CAN NOT RECOGNIZE HEATING FILE!",& & "UNKNOWN SOURCE STRING:",TRIM(ATT%CHR(1))) END IF ! GOT GRID TYPE ALLOCATE(HEAT_FORCING_COMMENTS(4)) HEAT_FORCING_COMMENTS(1) = "FVCOM periodic surface heat forcing:" HEAT_FORCING_COMMENTS(2) = "FILE NAME:"//TRIM(HEATING_FILE) HEAT_FORCING_COMMENTS(3) = "SOURCE:"//TRIM(ATT%CHR(1)) ATT_DATE => FIND_ATT(HEAT_FILE,"START_DATE",FOUND) IF (FOUND) THEN HEAT_FORCING_COMMENTS(4) ="MET DATA START DATE:"//TRIM(ATT_DATE%CHR(1)) ELSE HEAT_FORCING_COMMENTS(4) = "Unknown start date meta data format" END IF ! GET THE FILES LENGTH OF TIME AND SAVE FOR PERIODIC FORCING ! LOOK FOR THE DIMENSIONS DIM => FIND_UNLIMITED(HEAT_FILE,FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN SURFACE HEATING BOUNDARY CONDITION FILE OBJECT",& & "FILE NAME: "//TRIM(HEATING_FILE),& &"COULD NOT FIND THE UNLIMITED DIMENSION") NTIMES = DIM%DIM HEAT_PERIOD = get_file_time(HEAT_FILE,ntimes) HEAT_PERIOD = HEAT_PERIOD - get_file_time(HEAT_FILE,1) IF (HEAT_PERIOD /= get_file_time(HEAT_FILE,ntimes)) THEN CALL PRINT_REAL_TIME(get_file_time(HEAT_FILE,1),IPT,"FIRST FILE TIME",TIMEZONE) CALL PRINT_REAL_TIME(get_file_time(HEAT_FILE,ntimes),IPT,"LAST FILE TIME",TIMEZONE) CALL FATAL_ERROR& &("TO USE PERIODIC FORCING THE FILE TIME MUST COUNT FROM ZERO",& & "THE DIFFERENCE BETWEEN THE CURRENT MODEL TIME AND THE START TIME,",& & "MODULO THE FORCING PERIOD, DETERMINES THE CURRENT FORCING") END IF IF(DBG_SET(DBG_LOG)) THEN WRITE(IPT,*) "! USING PERIODIC HEAT FORCING:" CALL PRINT_TIME(HEAT_PERIOD,IPT,"PERIOD") END IF CASE(VRBL) HEAT_FILE => FIND_FILE(FILEHEAD,trim(HEATING_FILE),FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("COULD NOT FIND SURFACE HEATING BOUNDARY CONDINTION FILE OBJECT",& & "FILE NAME: "//TRIM(HEATING_FILE)) ! DETERMINE GRID TYPE BASED ON SOURCE ATTRIBUTE ATT => FIND_ATT(HEAT_FILE,"source",FOUND) IF(.not. FOUND) ATT => FIND_ATT(HEAT_FILE,"Source",FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN SURFACE HEATING BOUNDARY CONDITION FILE OBJECT",& & "FILE NAME: "//TRIM(HEATING_FILE),& &"COULD NOT FIND GLOBAL ATTRIBURE: 'source'") IF (ATT%CHR(1)(1:len_trim(wrf2fvcom_source)) ==& & TRIM(wrf2fvcom_source)) THEN HEAT_FORCING_TYPE = HEAT_IS_WRFGRID ELSE IF (ATT%CHR(1)(1:len_trim(fvcom_grid_source)) ==& & TRIM(fvcom_grid_source)) THEN HEAT_FORCING_TYPE = HEAT_IS_FVCOMGRID ELSE IF (ATT%CHR(1)(1:len_trim(fvcom_cap_grid_source)) ==& & TRIM(fvcom_cap_grid_source)) THEN HEAT_FORCING_TYPE = HEAT_IS_FVCOMGRID ELSE IF (ATT%CHR(1)(1:len_trim(wrf_grid_source)) ==& & TRIM(wrf_grid_source)) THEN HEAT_FORCING_TYPE = HEAT_IS_WRFGRID ELSE CALL PRINT_FILE(HEAT_FILE) CALL FATAL_ERROR("CAN NOT RECOGNIZE HEATING FILE!",& & "UNKNOWN SOURCE STRING:",TRIM(ATT%CHR(1))) END IF ! GOT GRID TYPE ALLOCATE(HEAT_FORCING_COMMENTS(4)) HEAT_FORCING_COMMENTS(1) = "FVCOM variable surface heat forcing file:" HEAT_FORCING_COMMENTS(2) = "FILE NAME:"//TRIM(HEATING_FILE) HEAT_FORCING_COMMENTS(3) = "SOURCE:"//TRIM(ATT%CHR(1)) ATT_DATE => FIND_ATT(HEAT_FILE,"START_DATE",FOUND) IF (FOUND) THEN HEAT_FORCING_COMMENTS(4) ="MET DATA START DATE:"//TRIM(ATT_DATE%CHR(1)) ELSE HEAT_FORCING_COMMENTS(4) = "Unknown start date meta data format" END IF ! CHECK DIMENSIONS DIM => FIND_UNLIMITED(HEAT_FILE,FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN SURFACE HEATING BOUNDARY CONDITION FILE OBJECT",& & "FILE NAME: "//TRIM(HEATING_FILE),& &"COULD NOT FIND UNLIMITED DIMENSION") NTIMES = DIM%DIM ! CHECK THE FILE TIME AND COMPARE WITH MODEL RUN TIME TIMETEST = get_file_time(HEAT_FILE,1) IF(TIMETEST > STARTTIME) CALL FATAL_ERROR & & ("IN SURFACE HEATING BOUNDARY CONDITION FILE OBJECT",& & "FILE NAME: "//TRIM(HEATING_FILE),& &"THE MODEL RUN STARTS BEFORE THE FORCING TIME SERIES") TIMETEST = get_file_time(HEAT_FILE,ntimes) IF(TIMETEST < ENDTIME) CALL FATAL_ERROR & & ("IN SURFACE HEATING BOUNDARY CONDITION FILE OBJECT",& & "FILE NAME: "//TRIM(HEATING_FILE),& &"THE MODEL RUN ENDS AFTER THE FORCING TIME SERIES") CASE DEFAULT CALL FATAL_ERROR("SURFACE_HEATING: UNKNOWN HEATING KIND?") END SELECT !================================================================== SELECT CASE(HEAT_FORCING_TYPE) !================================================================== CASE(HEAT_IS_WRFGRID) !================================================================== IF(DBG_SET(DBG_LOG)) WRITE(IPT,*) & & "! SETTING UP HEAT FORCING FROM A 'wrf grid' FILE" ! LOOK FOR THE DIMENSIONS DIM => FIND_DIM(HEAT_FILE,'south_north',FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN SURFACE HEATING BOUNDARY CONDITION FILE OBJECT",& & "FILE NAME: "//TRIM(HEATING_FILE),& & "COULD NOT FIND DIMENSION 'south_north'") LATS = DIM%DIM DIM => FIND_DIM(HEAT_FILE,'west_east',FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN SURFACE HEATING BOUNDARY CONDITION FILE OBJECT",& & "FILE NAME: "//TRIM(HEATING_FILE),& & "COULD NOT FIND DIMENSION 'west_east'") LONS = DIM%DIM CALL SET_FILE_INTERP_BILINEAR(HEAT_FILE,HEAT_INTP_N,HEAT_INTP_C) ! SETUP THE ACTUAL VARIABLES USED TO LOAD DATA! ! SHORT WAVE RADIATION DATA VAR => FIND_VAR(HEAT_FILE,"short_wave",FOUND) IF(.not. FOUND) VAR => FIND_VAR(HEAT_FILE,"Shortwave",FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN SURFACE HEATING BOUNDARY CONDITION FILE OBJECT",& & "FILE NAME: "//TRIM(HEATING_FILE),& & "COULD NOT FIND VARIABLE 'short_wave'") ! MAKE SPACE FOR THE DATA FROM THE FILE ALLOCATE(STORAGE_ARR(lons,lats), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN SURFACE HEATING") HEAT_SWV_N => reference_var(var) CALL NC_CONNECT_PVAR(HEAT_SWV_N,STORAGE_ARR) NULLIFY(STORAGE_ARR) ! MAKE SPACE FOR THE INTERPOLATED DATA ALLOCATE(STORAGE_VEC(0:MT), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN SURFACE HEATING") CALL NC_CONNECT_PVAR(HEAT_SWV_N,STORAGE_VEC) NULLIFY(STORAGE_VEC) ! MAKE SPACE FOR THE DATA FROM THE FILE ALLOCATE(STORAGE_ARR(lons,lats), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN SURFACE HEATING") HEAT_SWV_P => reference_var(var) CALL NC_CONNECT_PVAR(HEAT_SWV_P,STORAGE_ARR) NULLIFY(STORAGE_ARR) ! MAKE SPACE FOR THE INTERPOLATED DATA ALLOCATE(STORAGE_VEC(0:MT), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN SURFACE HEATING") CALL NC_CONNECT_PVAR(HEAT_SWV_P,STORAGE_VEC) NULLIFY(STORAGE_VEC) ! NET HEAT FLUX DATA VAR => FIND_VAR(HEAT_FILE,"net_heat_flux",FOUND) IF(.not. FOUND) VAR => FIND_VAR(HEAT_FILE,"Net_Heat",FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN SURFACE HEATING BOUNDARY CONDITION FILE OBJECT",& & "FILE NAME: "//TRIM(HEATING_FILE),& & "COULD NOT FIND VARIABLE 'net_heat_flux'") ! MAKE SPACE FOR THE DATA FROM THE FILE ALLOCATE(STORAGE_ARR(lons,lats), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN SURFACE HEATING") HEAT_NET_N => reference_var(var) CALL NC_CONNECT_PVAR(HEAT_NET_N,STORAGE_ARR) NULLIFY(STORAGE_ARR) ! MAKE SPACE FOR THE INTERPOLATED DATA ALLOCATE(STORAGE_VEC(0:MT), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN SURFACE HEATING") CALL NC_CONNECT_PVAR(HEAT_NET_N,STORAGE_VEC) NULLIFY(STORAGE_VEC) ! MAKE SPACE FOR THE DATA FROM THE FILE ALLOCATE(STORAGE_ARR(lons,lats), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN SURFACE HEATING") HEAT_NET_P => reference_var(var) CALL NC_CONNECT_PVAR(HEAT_NET_P,STORAGE_ARR) NULLIFY(STORAGE_ARR) ! MAKE SPACE FOR THE INTERPOLATED DATA ALLOCATE(STORAGE_VEC(0:MT), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN SURFACE HEATING") CALL NC_CONNECT_PVAR(HEAT_NET_P,STORAGE_VEC) NULLIFY(STORAGE_VEC) !================================================================== CASE(HEAT_IS_FVCOMGRID) !================================================================== IF(DBG_SET(DBG_LOG)) WRITE(IPT,*) & & "! SETTING UP HEAT FORCING FROM A 'fvcom grid' FILE" ! LOOK FOR THE DIMENSIONS DIM => FIND_DIM(HEAT_FILE,'node',FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN SURFACE HEATING BOUNDARY CONDITION FILE OBJECT",& & "FILE NAME: "//TRIM(HEATING_FILE),& & "COULD NOT FIND DIMENSION 'node'") if (mgl /= dim%dim) CALL FATAL_ERROR& &("Surface Heating: the number of nodes in the file does not match the fvcom grid?") DIM => FIND_DIM(HEAT_FILE,'nele',FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN SURFACE HEATING BOUNDARY CONDITION FILE OBJECT",& & "FILE NAME: "//TRIM(HEATING_FILE),& & "COULD NOT FIND DIMENSION 'nele'") if (ngl /= dim%dim) CALL FATAL_ERROR& &("Surface Heating: the number of elements in the file does not match the fvcom grid?") ! SETUP THE ACTUAL VARIABLES USED TO LOAD DATA! ! SHORT WAVE RADIATION DATA VAR => FIND_VAR(HEAT_FILE,"short_wave",FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN SURFACE HEATING BOUNDARY CONDITION FILE OBJECT",& & "FILE NAME: "//TRIM(HEATING_FILE),& & "COULD NOT FIND VARIABLE 'short_wave'") ! MAKE SPACE FOR THE DATA FROM THE FILE HEAT_SWV_N => reference_var(var) ALLOCATE(STORAGE_VEC(0:MT), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN SURFACE HEATING") CALL NC_CONNECT_PVAR(HEAT_SWV_N,STORAGE_VEC) NULLIFY(STORAGE_VEC) ! MAKE SPACE FOR THE DATA FROM THE FILE HEAT_SWV_P => reference_var(var) ALLOCATE(STORAGE_VEC(0:MT), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN SURFACE HEATING") CALL NC_CONNECT_PVAR(HEAT_SWV_P,STORAGE_VEC) NULLIFY(STORAGE_VEC) ! NET HEAT FLUX DATA VAR => FIND_VAR(HEAT_FILE,"net_heat_flux",FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN SURFACE HEATING BOUNDARY CONDITION FILE OBJECT",& & "FILE NAME: "//TRIM(HEATING_FILE),& & "COULD NOT FIND VARIABLE 'net_heat_flux'") ! MAKE SPACE FOR THE DATA FROM THE FILE HEAT_NET_N => reference_var(var) ALLOCATE(STORAGE_VEC(0:MT), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN SURFACE HEATING") CALL NC_CONNECT_PVAR(HEAT_NET_N,STORAGE_VEC) NULLIFY(STORAGE_VEC) ! MAKE SPACE FOR THE DATA FROM THE FILE HEAT_NET_P => reference_var(var) ALLOCATE(STORAGE_VEC(0:MT), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN SURFACE HEATING") CALL NC_CONNECT_PVAR(HEAT_NET_P,STORAGE_VEC) NULLIFY(STORAGE_VEC) !================================================================== CASE DEFAULT !================================================================== CALL FATAL_ERROR("CAN NOT RECOGNIZE HEATING FILE TYPE!") !================================================================== END SELECT !================================================================== ! afm 20151112 & EJA 20160921 ! Need initialization. Otherwise, random values are asigned ! and cause a hanging problem of MPI job in UPDATE_VAR_BRACKET ! This problem reported with Intel15.0.3. heat_net_n%curr_stkcnt=0 heat_net_p%curr_stkcnt=0 heat_swv_n%curr_stkcnt=0 heat_swv_p%curr_stkcnt=0 IF(DBG_SET(DBG_SBR)) write(IPT,*) "END SURFACE_HEATING" END SUBROUTINE SURFACE_HEATING # endif !================================================================ !================================================================ # if defined (HEATING_CALCULATED) SUBROUTINE SURFACE_HEATING_CALCULATED USE MOD_HEATFLUX IMPLICIT NONE ! SOME NC POINTERS TYPE(NCATT), POINTER :: ATT, ATT_DATE TYPE(NCDIM), POINTER :: DIM TYPE(NCVAR), POINTER :: VAR LOGICAL :: FOUND REAL(SP), POINTER :: STORAGE_ARR(:,:), STORAGE_VEC(:) CHARACTER(LEN=60) :: t_airstrng, rh_airstrng, pa_airstrng, dlw_airstrng, dsw_airstrng TYPE(TIME) :: TIMETEST INTEGER :: LATS, LONS, I, Ntimes INTEGER :: STATUS REAL(SP) :: TEMP CHARACTER(LEN=80) :: ISTR ISTR = "./"//TRIM(INPUT_DIR)//"/"//trim(casename) IF(DBG_SET(DBG_SBR)) write(IPT,*) "START SURFACE_HEATING_CALCULATED" NULLIFY(ATT,DIM,VAR,STORAGE_ARR,STORAGE_VEC) IF (.NOT. HEATING_CALCULATE_ON ) THEN IF(DBG_SET(DBG_LOG)) write(IPT,*) "! SURFACE HEAT FORCING IS OFF!" ALLOCATE(HEAT_CALCULATE_COMMENTS(1)) HEAT_CALCULATE_COMMENTS(1) = "SURFACE HEAT FORCING IS OFF" RETURN END IF !------------------------------------------------------------------------------| !--------------READ IN LATITUDE------------------------------------------------! ALLOCATE(CORRG(0:MGL)) ; CORRG = 0.0_SP CALL FOPEN(CORIOLISUNIT, TRIM(ISTR)//'_cor.dat',"cfr") REWIND(CORIOLISUNIT) READ(CORIOLISUNIT,*) DO I=1,MGL READ(CORIOLISUNIT,*) TEMP,TEMP,CORRG(I) END DO CLOSE(CORIOLISUNIT) !--------------TRANSFORM TO LOCAL DOMAINS IF PARALLEL--------------------------! ALLOCATE(CORR(0:MT)) ; CORR = 0.0_SP IF(SERIAL) CORR = CORRG # if defined (MULTIPROCESSOR) IF(PAR)THEN DO I=1,M CORR(I) = CORRG(NGID(I)) END DO DO I=1,NHN CORR(I+M) = CORRG(HN_LST(I)) END DO END IF # endif DEALLOCATE(CORRG) IF(TRIM(COARE_VERSION) == 'COARE40VN')THEN ALLOCATE(RAIN(0:MT)) ; RAIN = 0.0_SP ALLOCATE(CP40(0:MT)) ; CP40 = 0.0_SP ALLOCATE(SIGH(0:MT)) ; SIGH = 0.0_SP ALLOCATE(ZI40(0:MT)) ; ZI40 = 0.0_SP END IF IF(HEATING_FRESHWATER)THEN ALLOCATE(USRCOARE(0:MT)) ; USRCOARE = 0.0_SP END IF !----------------------------REPORT--------------------------------------------! IF(MSR)WRITE(IPT,*)'!' IF(MSR)WRITE(IPT,*)'! SETTING UP PRESCRIBED BOUNDARY CONDITIONS ' IF(MSR)WRITE(IPT,*)'!' !==============================================================================| ! Input Meteorological Boundary Conditions for Calculating Heat Flux | !==============================================================================| ! bulk air temperature at height 2m: degree(C) "t_air" | ! relative humidity at height 2m: (%) "rh_air" | !---> Siqi li, 2021-01-27 ! surface pressure: pa "pa_air" | ! surface pressure: mb "pa_air" | (the unit was wrong for coare) !<--- Siqi Li, 2021-01-27 ! downward longwave radiation: w/m^2 "dlw_air" | ! downward shortwave radiation: w/m^2 "dsw_air" | !==============================================================================| ! DETERMINE HOW TO LOAD THE DATA SELECT CASE(HEATING_CALCULATE_KIND) CASE (CNSTNT) write(t_airstrng,'(f8.4)') AIR_TEMPERATURE write(rh_airstrng,'(f8.4)') RELATIVE_HUMIDITY write(pa_airstrng,'(f8.4)') SURFACE_PRESSURE write(dlw_airstrng,'(f8.4)') LONGWAVE_RADIATION write(dsw_airstrng,'(f8.4)') SHORTWAVE_RADIATION IF(DBG_SET(DBG_LOG)) THEN WRITE(IPT,*)"! SETTING UP CONSTANT HEAT FORCING: " WRITE(IPT,*)" Bulk Air Temperature: "//trim(t_airstrng) WRITE(IPT,*)" Relative Hunidity: "//trim(rh_airstrng) WRITE(IPT,*)" Surface Pressure: "//trim(pa_airstrng) WRITE(IPT,*)" Downward Longwave Radiation: "//trim(dlw_airstrng) WRITE(IPT,*)" Downward shortwave Radiation: "//trim(dsw_airstrng) END IF ALLOCATE(HEAT_CALCULATE_COMMENTS(6)) HEAT_CALCULATE_COMMENTS(1) = "Using constant heating from run file:" HEAT_CALCULATE_COMMENTS(2) = "Bulk Air Temperature:"//trim(t_airstrng) HEAT_CALCULATE_COMMENTS(3) = "Relative Humidity:"//trim(rh_airstrng) HEAT_CALCULATE_COMMENTS(4) = "Surface Pressure:"//trim(pa_airstrng) HEAT_CALCULATE_COMMENTS(5) = "Downward Longwave Radiation:"//trim(dlw_airstrng) HEAT_CALCULATE_COMMENTS(6) = "Downward Shortwave Radiation:"//trim(dsw_airstrng) RETURN CASE(STTC) CALL FATAL_ERROR("STATIC HEATING Not Set Up Yet") CASE(TMDPNDNT) CALL FATAL_ERROR("TIME DEPENDANT HEATING Not Set Up Yet") CASE(PRDC) HEAT_FILE => FIND_FILE(FILEHEAD,trim(HEATING_CALCULATE_FILE),FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("COULD NOT FIND SURFACE HEATING BOUNDARY CONDINTION FILE OBJECT",& & "FILE NAME: "//TRIM(HEATING_CALCULATE_FILE)) ! DETERMINE GRID TYPE BASED ON SOURCE ATTRIBUTE ATT => FIND_ATT(HEAT_FILE,"source",FOUND) IF(.not. FOUND) ATT => FIND_ATT(HEAT_FILE,"Source",FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN SURFACE HEATING BOUNDARY CONDITION FILE OBJECT",& & "FILE NAME: "//TRIM(HEATING_CALCULATE_FILE),& &"COULD NOT FIND GLOBAL ATTRIBURE: 'source'") IF (ATT%CHR(1)(1:len_trim(wrf2fvcom_source)) ==& & TRIM(wrf2fvcom_source)) THEN HEAT_FORCING_TYPE = HEAT_IS_WRFGRID ELSE IF (ATT%CHR(1)(1:len_trim(fvcom_grid_source)) ==& & TRIM(fvcom_grid_source)) THEN HEAT_FORCING_TYPE = HEAT_IS_FVCOMGRID ELSE IF (ATT%CHR(1)(1:len_trim(fvcom_cap_grid_source)) ==& & TRIM(fvcom_cap_grid_source)) THEN HEAT_FORCING_TYPE = HEAT_IS_FVCOMGRID ELSE IF (ATT%CHR(1)(1:len_trim(wrf_grid_source)) ==& & TRIM(wrf_grid_source)) THEN HEAT_FORCING_TYPE = HEAT_IS_WRFGRID ELSE CALL PRINT_FILE(HEAT_FILE) CALL FATAL_ERROR("CAN NOT RECOGNIZE HEATING FILE!",& & "UNKNOWN SOURCE STRING:",TRIM(ATT%CHR(1))) END IF ! GOT GRID TYPE ALLOCATE(HEAT_FORCING_COMMENTS(4)) HEAT_FORCING_COMMENTS(1) = "FVCOM periodic surface heat forcing:" HEAT_FORCING_COMMENTS(2) = "FILE NAME:"//TRIM(HEATING_CALCULATE_FILE) HEAT_FORCING_COMMENTS(3) = "SOURCE:"//TRIM(ATT%CHR(1)) ATT_DATE => FIND_ATT(HEAT_FILE,"START_DATE",FOUND) IF (FOUND) THEN HEAT_FORCING_COMMENTS(4) ="MET DATA START DATE:"//TRIM(ATT_DATE%CHR(1)) ELSE HEAT_FORCING_COMMENTS(4) = "Unknown start date meta data format" END IF ! GET THE FILES LENGTH OF TIME AND SAVE FOR PERIODIC FORCING ! LOOK FOR THE DIMENSIONS DIM => FIND_UNLIMITED(HEAT_FILE,FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN SURFACE HEATING BOUNDARY CONDITION FILE OBJECT",& & "FILE NAME: "//TRIM(HEATING_CALCULATE_FILE),& &"COULD NOT FIND THE UNLIMITED DIMENSION") NTIMES = DIM%DIM HEAT_PERIOD = get_file_time(HEAT_FILE,ntimes) HEAT_PERIOD = HEAT_PERIOD - get_file_time(HEAT_FILE,1) IF (HEAT_PERIOD /= get_file_time(HEAT_FILE,ntimes)) THEN CALL PRINT_REAL_TIME(get_file_time(HEAT_FILE,1),IPT,"FIRST FILE TIME",TIMEZONE) CALL PRINT_REAL_TIME(get_file_time(HEAT_FILE,ntimes),IPT,"LAST FILE TIME",TIMEZONE) CALL FATAL_ERROR& &("TO USE PERIODIC FORCING THE FILE TIME MUST COUNT FROM ZERO",& & "THE DIFFERENCE BETWEEN THE CURRENT MODEL TIME AND THE START TIME,",& & "MODULO THE FORCING PERIOD, DETERMINES THE CURRENT FORCING") END IF IF(DBG_SET(DBG_LOG)) THEN WRITE(IPT,*) "! USING PERIODIC HEAT FORCING:" CALL PRINT_TIME(HEAT_PERIOD,IPT,"PERIOD") END IF CASE(VRBL) HEAT_FILE => FIND_FILE(FILEHEAD,trim(HEATING_CALCULATE_FILE),FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("COULD NOT FIND SURFACE HEATING BOUNDARY CONDINTION FILE OBJECT",& & "FILE NAME: "//TRIM(HEATING_CALCULATE_FILE)) ! DETERMINE GRID TYPE BASED ON SOURCE ATTRIBUTE ATT => FIND_ATT(HEAT_FILE,"source",FOUND) IF(.not. FOUND) ATT => FIND_ATT(HEAT_FILE,"Source",FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN SURFACE HEATING BOUNDARY CONDITION FILE OBJECT",& & "FILE NAME: "//TRIM(HEATING_CALCULATE_FILE),& &"COULD NOT FIND GLOBAL ATTRIBURE: 'source'") IF (ATT%CHR(1)(1:len_trim(wrf2fvcom_source)) ==& & TRIM(wrf2fvcom_source)) THEN HEAT_FORCING_TYPE = HEAT_IS_WRFGRID ELSE IF (ATT%CHR(1)(1:len_trim(fvcom_grid_source)) ==& & TRIM(fvcom_grid_source)) THEN HEAT_FORCING_TYPE = HEAT_IS_FVCOMGRID ELSE IF (ATT%CHR(1)(1:len_trim(fvcom_cap_grid_source)) ==& & TRIM(fvcom_cap_grid_source)) THEN HEAT_FORCING_TYPE = HEAT_IS_FVCOMGRID ELSE IF (ATT%CHR(1)(1:len_trim(wrf_grid_source)) ==& & TRIM(wrf_grid_source)) THEN HEAT_FORCING_TYPE = HEAT_IS_WRFGRID ELSE CALL PRINT_FILE(HEAT_FILE) CALL FATAL_ERROR("CAN NOT RECOGNIZE HEATING FILE!",& & "UNKNOWN SOURCE STRING:",TRIM(ATT%CHR(1))) END IF ! GOT GRID TYPE ALLOCATE(HEAT_FORCING_COMMENTS(4)) HEAT_FORCING_COMMENTS(1) = "FVCOM variable surface heat forcing file:" HEAT_FORCING_COMMENTS(2) = "FILE NAME:"//TRIM(HEATING_CALCULATE_FILE) HEAT_FORCING_COMMENTS(3) = "SOURCE:"//TRIM(ATT%CHR(1)) ATT_DATE => FIND_ATT(HEAT_FILE,"START_DATE",FOUND) IF (FOUND) THEN HEAT_FORCING_COMMENTS(4) ="MET DATA START DATE:"//TRIM(ATT_DATE%CHR(1)) ELSE HEAT_FORCING_COMMENTS(4) = "Unknown start date meta data format" END IF ! CHECK DIMENSIONS DIM => FIND_UNLIMITED(HEAT_FILE,FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN SURFACE HEATING BOUNDARY CONDITION FILE OBJECT",& & "FILE NAME: "//TRIM(HEATING_CALCULATE_FILE),& &"COULD NOT FIND UNLIMITED DIMENSION") NTIMES = DIM%DIM ! CHECK THE FILE TIME AND COMPARE WITH MODEL RUN TIME TIMETEST = get_file_time(HEAT_FILE,1) IF(TIMETEST > STARTTIME) CALL FATAL_ERROR & & ("IN SURFACE HEATING BOUNDARY CONDITION FILE OBJECT",& & "FILE NAME: "//TRIM(HEATING_CALCULATE_FILE),& &"THE MODEL RUN STARTS BEFORE THE FORCING TIME SERIES") TIMETEST = get_file_time(HEAT_FILE,ntimes) IF(TIMETEST < ENDTIME) CALL FATAL_ERROR & & ("IN SURFACE HEATING BOUNDARY CONDITION FILE OBJECT",& & "FILE NAME: "//TRIM(HEATING_CALCULATE_FILE),& &"THE MODEL RUN ENDS AFTER THE FORCING TIME SERIES") CASE DEFAULT CALL FATAL_ERROR("SURFACE_HEATING: UNKNOWN HEATING KIND?") END SELECT !================================================================== SELECT CASE(HEAT_FORCING_TYPE) !================================================================== CASE(HEAT_IS_WRFGRID) !================================================================== IF(DBG_SET(DBG_LOG)) WRITE(IPT,*) & & "! SETTING UP HEAT FORCING FROM A 'wrf grid' FILE" ! LOOK FOR THE DIMENSIONS DIM => FIND_DIM(HEAT_FILE,'south_north',FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN SURFACE HEATING BOUNDARY CONDITION FILE OBJECT",& & "FILE NAME: "//TRIM(HEATING_CALCULATE_FILE),& & "COULD NOT FIND DIMENSION 'south_north'") LATS = DIM%DIM DIM => FIND_DIM(HEAT_FILE,'west_east',FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN SURFACE HEATING BOUNDARY CONDITION FILE OBJECT",& & "FILE NAME: "//TRIM(HEATING_CALCULATE_FILE),& & "COULD NOT FIND DIMENSION 'west_east'") LONS = DIM%DIM CALL SET_FILE_INTERP_BILINEAR(HEAT_FILE,HEAT_INTP_N,HEAT_INTP_C) ! SETUP THE ACTUAL VARIABLES USED TO LOAD DATA! ! ! BULK AIR TEMPERATURE DATA VAR => FIND_VAR(HEAT_FILE,"air_temperature",FOUND) IF(.not. FOUND) VAR => FIND_VAR(HEAT_FILE,"air_temperature",FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN SURFACE HEATING BOUNDARY CONDITION FILE OBJECT",& & "FILE NAME: "//TRIM(HEATING_CALCULATE_FILE),& & "COULD NOT FIND VARIABLE 'air_temperature'") ! MAKE SPACE FOR THE DATA FROM THE FILE ALLOCATE(STORAGE_ARR(lons,lats), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN SURFACE HEATING") T_AIR_N => reference_var(var) CALL NC_CONNECT_PVAR(T_AIR_N,STORAGE_ARR) NULLIFY(STORAGE_ARR) ! MAKE SPACE FOR THE INTERPOLATED DATA ALLOCATE(STORAGE_VEC(0:MT), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN SURFACE HEATING") CALL NC_CONNECT_PVAR(T_AIR_N,STORAGE_VEC) NULLIFY(STORAGE_VEC) ! MAKE SPACE FOR THE DATA FROM THE FILE ALLOCATE(STORAGE_ARR(lons,lats), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN SURFACE HEATING") T_AIR_P => reference_var(var) CALL NC_CONNECT_PVAR(T_AIR_P,STORAGE_ARR) NULLIFY(STORAGE_ARR) ! MAKE SPACE FOR THE INTERPOLATED DATA ALLOCATE(STORAGE_VEC(0:MT), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN SURFACE HEATING") CALL NC_CONNECT_PVAR(T_AIR_P,STORAGE_VEC) NULLIFY(STORAGE_VEC) ! ! RELATIVE HUMIDITY VAR => FIND_VAR(HEAT_FILE,"relative_humidity",FOUND) IF(.not. FOUND) VAR => FIND_VAR(HEAT_FILE,"relative_humidity",FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN SURFACE HEATING BOUNDARY CONDITION FILE OBJECT",& & "FILE NAME: "//TRIM(HEATING_CALCULATE_FILE),& & "COULD NOT FIND VARIABLE 'relative_humidity'") ! MAKE SPACE FOR THE DATA FROM THE FILE ALLOCATE(STORAGE_ARR(lons,lats), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN SURFACE HEATING") RH_AIR_N => reference_var(var) CALL NC_CONNECT_PVAR(RH_AIR_N,STORAGE_ARR) NULLIFY(STORAGE_ARR) ! MAKE SPACE FOR THE INTERPOLATED DATA ALLOCATE(STORAGE_VEC(0:MT), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN SURFACE HEATING") CALL NC_CONNECT_PVAR(RH_AIR_N,STORAGE_VEC) NULLIFY(STORAGE_VEC) ! MAKE SPACE FOR THE DATA FROM THE FILE ALLOCATE(STORAGE_ARR(lons,lats), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN SURFACE HEATING") RH_AIR_P => reference_var(var) CALL NC_CONNECT_PVAR(RH_AIR_P,STORAGE_ARR) NULLIFY(STORAGE_ARR) ! MAKE SPACE FOR THE INTERPOLATED DATA ALLOCATE(STORAGE_VEC(0:MT), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN SURFACE HEATING") CALL NC_CONNECT_PVAR(RH_AIR_P,STORAGE_VEC) NULLIFY(STORAGE_VEC) ! ! SURFACE PRESSURE VAR => FIND_VAR(HEAT_FILE,"air_pressure",FOUND) IF(.not. FOUND) VAR => FIND_VAR(HEAT_FILE,"SLP",FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN SURFACE HEATING BOUNDARY CONDITION FILE OBJECT",& & "FILE NAME: "//TRIM(HEATING_CALCULATE_FILE),& & "COULD NOT FIND VARIABLE 'air_pressure' OR 'SLP'") !---> Siqi Li, 2021-01-27 ! The unit of air pressure is really important. It can influence both ! water elevation and wind stress. In calculation, the unit of air ! pressure is 'Pa'. ATT => FIND_ATT(VAR,'units',FOUND) IF(.not. FOUND) ATT => FIND_ATT(VAR,'unit',FOUND) IF (FOUND) THEN call UPCASE(ATT%CHR(1)) SELECT CASE (TRIM(ATT%CHR(1))) CASE ('MB', 'HPA') Pair_unit_factor = 100.0_SP CASE ('PA','PASCAL') Pair_unit_factor = 1.0_SP CASE DEFAULT CALL FATAL_ERROR("UNKNOWN UNIT of AIR PRESSURE: " & & //TRIM(ATT%CHR(1))) END SELECT ELSE ! There is no unit attribute for the air_pressure variable ! We assume the unit is 'Pa'. Pair_unit_factor = 1.0_SP END IF !<--- Siqi Li, 2021-01-27 ! MAKE SPACE FOR THE DATA FROM THE FILE ALLOCATE(STORAGE_ARR(lons,lats), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN SURFACE HEATING") PA_AIR_N => reference_var(var) CALL NC_CONNECT_PVAR(PA_AIR_N,STORAGE_ARR) NULLIFY(STORAGE_ARR) ! MAKE SPACE FOR THE INTERPOLATED DATA ALLOCATE(STORAGE_VEC(0:MT), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN SURFACE HEATING") CALL NC_CONNECT_PVAR(PA_AIR_N,STORAGE_VEC) NULLIFY(STORAGE_VEC) ! MAKE SPACE FOR THE DATA FROM THE FILE ALLOCATE(STORAGE_ARR(lons,lats), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN SURFACE HEATING") PA_AIR_P => reference_var(var) CALL NC_CONNECT_PVAR(PA_AIR_P,STORAGE_ARR) NULLIFY(STORAGE_ARR) ! MAKE SPACE FOR THE INTERPOLATED DATA ALLOCATE(STORAGE_VEC(0:MT), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN SURFACE HEATING") CALL NC_CONNECT_PVAR(PA_AIR_P,STORAGE_VEC) NULLIFY(STORAGE_VEC) ! ! DOWNWARD LONGWAVE RADIATION VAR => FIND_VAR(HEAT_FILE,"long_wave",FOUND) IF(.not. FOUND) VAR => FIND_VAR(HEAT_FILE,"Longwave",FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN SURFACE HEATING BOUNDARY CONDITION FILE OBJECT",& & "FILE NAME: "//TRIM(HEATING_CALCULATE_FILE),& & "COULD NOT FIND VARIABLE 'long_wave'") ! MAKE SPACE FOR THE DATA FROM THE FILE ALLOCATE(STORAGE_ARR(lons,lats), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN SURFACE HEATING") DLW_AIR_N => reference_var(var) CALL NC_CONNECT_PVAR(DLW_AIR_N,STORAGE_ARR) NULLIFY(STORAGE_ARR) ! MAKE SPACE FOR THE INTERPOLATED DATA ALLOCATE(STORAGE_VEC(0:MT), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN SURFACE HEATING") CALL NC_CONNECT_PVAR(DLW_AIR_N,STORAGE_VEC) NULLIFY(STORAGE_VEC) ! MAKE SPACE FOR THE DATA FROM THE FILE ALLOCATE(STORAGE_ARR(lons,lats), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN SURFACE HEATING") DLW_AIR_P => reference_var(var) CALL NC_CONNECT_PVAR(DLW_AIR_P,STORAGE_ARR) NULLIFY(STORAGE_ARR) ! MAKE SPACE FOR THE INTERPOLATED DATA ALLOCATE(STORAGE_VEC(0:MT), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN SURFACE HEATING") CALL NC_CONNECT_PVAR(DLW_AIR_P,STORAGE_VEC) NULLIFY(STORAGE_VEC) ! ! DOWNWARD SHORTWAVE RADIATION VAR => FIND_VAR(HEAT_FILE,"short_wave",FOUND) IF(.not. FOUND) VAR => FIND_VAR(HEAT_FILE,"Shortwave",FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN SURFACE HEATING BOUNDARY CONDITION FILE OBJECT",& & "FILE NAME: "//TRIM(HEATING_CALCULATE_FILE),& & "COULD NOT FIND VARIABLE 'short_wave'") ! MAKE SPACE FOR THE DATA FROM THE FILE ALLOCATE(STORAGE_ARR(lons,lats), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN SURFACE HEATING") DSW_AIR_N => reference_var(var) CALL NC_CONNECT_PVAR(DSW_AIR_N,STORAGE_ARR) NULLIFY(STORAGE_ARR) ! MAKE SPACE FOR THE INTERPOLATED DATA ALLOCATE(STORAGE_VEC(0:MT), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN SURFACE HEATING") CALL NC_CONNECT_PVAR(DSW_AIR_N,STORAGE_VEC) NULLIFY(STORAGE_VEC) ! MAKE SPACE FOR THE DATA FROM THE FILE ALLOCATE(STORAGE_ARR(lons,lats), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN SURFACE HEATING") DSW_AIR_P => reference_var(var) CALL NC_CONNECT_PVAR(DSW_AIR_P,STORAGE_ARR) NULLIFY(STORAGE_ARR) ! MAKE SPACE FOR THE INTERPOLATED DATA ALLOCATE(STORAGE_VEC(0:MT), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN SURFACE HEATING") CALL NC_CONNECT_PVAR(DSW_AIR_P,STORAGE_VEC) NULLIFY(STORAGE_VEC) ! !================================================================== CASE(HEAT_IS_FVCOMGRID) !================================================================== IF(DBG_SET(DBG_LOG)) WRITE(IPT,*) & & "! SETTING UP HEAT FORCING FROM A 'fvcom grid' FILE" ! LOOK FOR THE DIMENSIONS DIM => FIND_DIM(HEAT_FILE,'node',FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN SURFACE HEATING BOUNDARY CONDITION FILE OBJECT",& & "FILE NAME: "//TRIM(HEATING_CALCULATE_FILE),& & "COULD NOT FIND DIMENSION 'node'") if (mgl /= dim%dim) CALL FATAL_ERROR& &("Surface Heating: the number of nodes in the file does not match the fvcom grid?") DIM => FIND_DIM(HEAT_FILE,'nele',FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN SURFACE HEATING BOUNDARY CONDITION FILE OBJECT",& & "FILE NAME: "//TRIM(HEATING_CALCULATE_FILE),& & "COULD NOT FIND DIMENSION 'nele'") if (ngl /= dim%dim) CALL FATAL_ERROR& &("Surface Heating: the number of elements in the file does not match the fvcom grid?") ! SETUP THE ACTUAL VARIABLES USED TO LOAD DATA! ! ! BULK AIR TEMPERATURE DATA VAR => FIND_VAR(HEAT_FILE,"air_temperature",FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN SURFACE HEATING BOUNDARY CONDITION FILE OBJECT",& & "FILE NAME: "//TRIM(HEATING_CALCULATE_FILE),& & "COULD NOT FIND VARIABLE 'air_temperature'") ! MAKE SPACE FOR THE DATA FROM THE FILE T_AIR_N => reference_var(var) ALLOCATE(STORAGE_VEC(0:MT), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN SURFACE HEATING") CALL NC_CONNECT_PVAR(T_AIR_N,STORAGE_VEC) NULLIFY(STORAGE_VEC) ! MAKE SPACE FOR THE DATA FROM THE FILE T_AIR_P => reference_var(var) ALLOCATE(STORAGE_VEC(0:MT), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN SURFACE HEATING") CALL NC_CONNECT_PVAR(T_AIR_P,STORAGE_VEC) NULLIFY(STORAGE_VEC) ! ! RELATIVE HUMIDITY DATA VAR => FIND_VAR(HEAT_FILE,"relative_humidity",FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN SURFACE HEATING BOUNDARY CONDITION FILE OBJECT",& & "FILE NAME: "//TRIM(HEATING_CALCULATE_FILE),& & "COULD NOT FIND VARIABLE 'relative_humidity'") ! MAKE SPACE FOR THE DATA FROM THE FILE RH_AIR_N => reference_var(var) ALLOCATE(STORAGE_VEC(0:MT), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN SURFACE HEATING") CALL NC_CONNECT_PVAR(RH_AIR_N,STORAGE_VEC) NULLIFY(STORAGE_VEC) ! MAKE SPACE FOR THE DATA FROM THE FILE RH_AIR_P => reference_var(var) ALLOCATE(STORAGE_VEC(0:MT), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN SURFACE HEATING") CALL NC_CONNECT_PVAR(RH_AIR_P,STORAGE_VEC) NULLIFY(STORAGE_VEC) ! ! SURFACE PRESSURE VAR => FIND_VAR(HEAT_FILE,"air_pressure",FOUND) IF(.not. FOUND) VAR => FIND_VAR(HEAT_FILE,"SLP",FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN SURFACE HEATING BOUNDARY CONDITION FILE OBJECT",& & "FILE NAME: "//TRIM(HEATING_CALCULATE_FILE),& & "COULD NOT FIND VARIABLE 'air_pressure' OR 'SLP'") ! Siqi Li, 2021-01-27 ! & "COULD NOT FIND VARIABLE 'air_pressure' OR "SLP") !---> Siqi Li, 2021-01-27 ! The unit of air pressure is really important. It can influence both ! water elevation and wind stress. In calculation, the unit of air ! pressure is 'Pa'. ATT => FIND_ATT(VAR,'units',FOUND) IF(.not. FOUND) ATT => FIND_ATT(VAR,'unit',FOUND) IF (FOUND) THEN call UPCASE(ATT%CHR(1)) SELECT CASE (TRIM(ATT%CHR(1))) CASE ('MB', 'HPA') Pair_unit_factor = 100.0_SP CASE ('PA','PASCAL') Pair_unit_factor = 1.0_SP CASE DEFAULT CALL FATAL_ERROR("UNKNOWN UNIT of AIR PRESSURE: " & & //TRIM(ATT%CHR(1))) END SELECT ELSE ! There is no unit attribute for the air_pressure variable ! We assume the unit is 'Pa'. Pair_unit_factor = 1.0_SP END IF !<--- Siqi Li, 2021-01-27 ! MAKE SPACE FOR THE DATA FROM THE FILE PA_AIR_N => reference_var(var) ALLOCATE(STORAGE_VEC(0:MT), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN SURFACE HEATING") CALL NC_CONNECT_PVAR(PA_AIR_N,STORAGE_VEC) NULLIFY(STORAGE_VEC) ! MAKE SPACE FOR THE DATA FROM THE FILE PA_AIR_P => reference_var(var) ALLOCATE(STORAGE_VEC(0:MT), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN SURFACE HEATING") CALL NC_CONNECT_PVAR(PA_AIR_P,STORAGE_VEC) NULLIFY(STORAGE_VEC) ! ! DOWNWARD LONGWAVE RADIATION VAR => FIND_VAR(HEAT_FILE,"long_wave",FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN SURFACE HEATING BOUNDARY CONDITION FILE OBJECT",& & "FILE NAME: "//TRIM(HEATING_CALCULATE_FILE),& & "COULD NOT FIND VARIABLE 'long_wave'") ! MAKE SPACE FOR THE DATA FROM THE FILE DLW_AIR_N => reference_var(var) ALLOCATE(STORAGE_VEC(0:MT), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN SURFACE HEATING") CALL NC_CONNECT_PVAR(DLW_AIR_N,STORAGE_VEC) NULLIFY(STORAGE_VEC) ! MAKE SPACE FOR THE DATA FROM THE FILE DLW_AIR_P => reference_var(var) ALLOCATE(STORAGE_VEC(0:MT), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN SURFACE HEATING") CALL NC_CONNECT_PVAR(DLW_AIR_P,STORAGE_VEC) NULLIFY(STORAGE_VEC) ! ! DOWNWARD SHORTWAVE RADIATION VAR => FIND_VAR(HEAT_FILE,"short_wave",FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN SURFACE HEATING BOUNDARY CONDITION FILE OBJECT",& & "FILE NAME: "//TRIM(HEATING_CALCULATE_FILE),& & "COULD NOT FIND VARIABLE 'short_wave'") ! MAKE SPACE FOR THE DATA FROM THE FILE DSW_AIR_N => reference_var(var) ALLOCATE(STORAGE_VEC(0:MT), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN SURFACE HEATING") CALL NC_CONNECT_PVAR(DSW_AIR_N,STORAGE_VEC) NULLIFY(STORAGE_VEC) ! MAKE SPACE FOR THE DATA FROM THE FILE DSW_AIR_P => reference_var(var) ALLOCATE(STORAGE_VEC(0:MT), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN SURFACE HEATING") CALL NC_CONNECT_PVAR(DSW_AIR_P,STORAGE_VEC) NULLIFY(STORAGE_VEC) ! !================================================================== CASE DEFAULT !================================================================== CALL FATAL_ERROR("CAN NOT RECOGNIZE HEATING FILE TYPE!") !================================================================== END SELECT !================================================================== ! afm 20151112 & EJA 20160921 ! Need initialization. Otherwise, random values are asigned ! and cause a hanging problem of MPI job in UPDATE_VAR_BRACKET ! This problem reported with Intel15.0.3. t_air_n%curr_stkcnt = 0;t_air_p%curr_stkcnt = 0 rh_air_n%curr_stkcnt = 0;rh_air_p%curr_stkcnt = 0 pa_air_n%curr_stkcnt = 0;pa_air_p%curr_stkcnt = 0 dlw_air_n%curr_stkcnt = 0;dlw_air_p%curr_stkcnt = 0 dsw_air_n%curr_stkcnt = 0;dsw_air_p%curr_stkcnt = 0 IF(DBG_SET(DBG_SBR)) write(IPT,*) "END SURFACE_HEATING_CALCULATED" END SUBROUTINE SURFACE_HEATING_CALCULATED # endif !======================================================================== !======================================================================== # if defined (HEATING_SOLAR) SUBROUTINE SURFACE_HEATING_SOLAR USE MOD_SOLAR IMPLICIT NONE ! SOME NC POINTERS TYPE(NCATT), POINTER :: ATT, ATT_DATE TYPE(NCDIM), POINTER :: DIM TYPE(NCVAR), POINTER :: VAR LOGICAL :: FOUND REAL(SP), POINTER :: STORAGE_ARR(:,:), STORAGE_VEC(:) CHARACTER(LEN=60) :: t_airstrng, dp_airstrng, cc_airstrng TYPE(TIME) :: TIMETEST INTEGER :: LATS, LONS, I, Ntimes INTEGER :: STATUS REAL(SP) :: TEMP INTEGER :: year_start,month_start,day_start INTEGER :: cc_start,yy_start CHARACTER(LEN=80) :: ISTR ISTR = "./"//TRIM(INPUT_DIR)//"/"//trim(casename) IF(DBG_SET(DBG_SBR)) write(IPT,*) "START SURFACE_HEATING_SOLAR" NULLIFY(ATT,DIM,VAR,STORAGE_ARR,STORAGE_VEC) IF (.NOT. HEATING_SOLAR_ON ) THEN IF(DBG_SET(DBG_LOG)) write(IPT,*) "! SURFACE HEAT FORCING (SOLAR) IS OFF!" ALLOCATE(HEAT_CALCULATE_COMMENTS(1)) HEAT_CALCULATE_COMMENTS(1) = "SURFACE HEAT FORCING (SOLAR) IS OFF" RETURN END IF !------------------------------------------------------------------------------| !--------------READ IN LATITUDE------------------------------------------------! ALLOCATE(CORRG(0:MGL)) ; CORRG = 0.0_SP CALL FOPEN(CORIOLISUNIT, TRIM(ISTR)//'_cor.dat',"cfr") REWIND(CORIOLISUNIT) READ(CORIOLISUNIT,*) DO I=1,MGL READ(CORIOLISUNIT,*) TEMP,TEMP,CORRG(I) END DO CLOSE(CORIOLISUNIT) !--------------TRANSFORM TO LOCAL DOMAINS IF PARALLEL--------------------------! ALLOCATE(CORR(0:MT)) ; CORR = 0.0_SP IF(SERIAL) CORR = CORRG # if defined (MULTIPROCESSOR) IF(PAR)THEN DO I=1,M CORR(I) = CORRG(NGID(I)) END DO DO I=1,NHN CORR(I+M) = CORRG(HN_LST(I)) END DO END IF # endif DEALLOCATE(CORRG) !----------------------------REPORT--------------------------------------------! IF(MSR)WRITE(IPT,*)'!' IF(MSR)WRITE(IPT,*)'! SETTING UP PRESCRIBED BOUNDARY CONDITIONS ' IF(MSR)WRITE(IPT,*)'!' !==============================================================================| ! Input Meteorological Boundary Conditions for Calculating Heat Flux | !==============================================================================| ! air temperature at height ZM: degree(C) "t_air" | ! dew point at height ZM: degree(C) "dp_air" | ! cloud cover: (0-1) "cc_air" | !==============================================================================| ! DETERMINE HOW TO LOAD THE DATA SELECT CASE(HEATING_SOLAR_KIND) CASE (CNSTNT) CALL FATAL_ERROR("CONSTANT HEATING Not Available") CASE(STTC) CALL FATAL_ERROR("STATIC HEATING Not Set Up Yet") CASE(TMDPNDNT) CALL FATAL_ERROR("TIME DEPENDANT HEATING Not Set Up Yet") CASE(PRDC) CALL FATAL_ERROR("PERIODIC HEATING Not Set Up Yet") CASE(VRBL) HEAT_FILE => FIND_FILE(FILEHEAD,trim(HEATING_SOLAR_FILE),FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("COULD NOT FIND SURFACE HEATING BOUNDARY CONDINTION FILE OBJECT",& & "FILE NAME: "//TRIM(HEATING_SOLAR_FILE)) ! DETERMINE GRID TYPE BASED ON SOURCE ATTRIBUTE ATT => FIND_ATT(HEAT_FILE,"source",FOUND) IF(.not. FOUND) ATT => FIND_ATT(HEAT_FILE,"Source",FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN SURFACE HEATING BOUNDARY CONDITION FILE OBJECT",& & "FILE NAME: "//TRIM(HEATING_SOLAR_FILE),& &"COULD NOT FIND GLOBAL ATTRIBURE: 'source'") IF (ATT%CHR(1)(1:len_trim(wrf2fvcom_source)) ==& & TRIM(wrf2fvcom_source)) THEN HEAT_FORCING_TYPE = HEAT_IS_WRFGRID ELSE IF (ATT%CHR(1)(1:len_trim(fvcom_grid_source)) ==& & TRIM(fvcom_grid_source)) THEN HEAT_FORCING_TYPE = HEAT_IS_FVCOMGRID ELSE IF (ATT%CHR(1)(1:len_trim(fvcom_cap_grid_source)) ==& & TRIM(fvcom_cap_grid_source)) THEN HEAT_FORCING_TYPE = HEAT_IS_FVCOMGRID ELSE IF (ATT%CHR(1)(1:len_trim(wrf_grid_source)) ==& & TRIM(wrf_grid_source)) THEN HEAT_FORCING_TYPE = HEAT_IS_WRFGRID ELSE CALL PRINT_FILE(HEAT_FILE) CALL FATAL_ERROR("CAN NOT RECOGNIZE HEATING FILE!",& & "UNKNOWN SOURCE STRING:",TRIM(ATT%CHR(1))) END IF ! GOT GRID TYPE ALLOCATE(HEAT_FORCING_COMMENTS(4)) HEAT_FORCING_COMMENTS(1) = "FVCOM variable surface heat forcing file:" HEAT_FORCING_COMMENTS(2) = "FILE NAME:"//TRIM(HEATING_SOLAR_FILE) HEAT_FORCING_COMMENTS(3) = "SOURCE:"//TRIM(ATT%CHR(1)) ATT_DATE => FIND_ATT(HEAT_FILE,"START_DATE",FOUND) IF (FOUND) THEN HEAT_FORCING_COMMENTS(4) ="MET DATA START DATE:"//TRIM(ATT_DATE%CHR(1)) ELSE HEAT_FORCING_COMMENTS(4) = "Unknown start date meta data format" END IF ! CHECK DIMENSIONS DIM => FIND_UNLIMITED(HEAT_FILE,FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN SURFACE HEATING BOUNDARY CONDITION FILE OBJECT",& & "FILE NAME: "//TRIM(HEATING_SOLAR_FILE),& &"COULD NOT FIND UNLIMITED DIMENSION") NTIMES = DIM%DIM ! CHECK THE FILE TIME AND COMPARE WITH MODEL RUN TIME TIMETEST = get_file_time(HEAT_FILE,1) IF(TIMETEST > STARTTIME) CALL FATAL_ERROR & & ("IN SURFACE HEATING BOUNDARY CONDITION FILE OBJECT",& & "FILE NAME: "//TRIM(HEATING_SOLAR_FILE),& &"THE MODEL RUN STARTS BEFORE THE FORCING TIME SERIES") TIMETEST = get_file_time(HEAT_FILE,ntimes) IF(TIMETEST < ENDTIME) CALL FATAL_ERROR & & ("IN SURFACE HEATING BOUNDARY CONDITION FILE OBJECT",& & "FILE NAME: "//TRIM(HEATING_SOLAR_FILE),& &"THE MODEL RUN ENDS AFTER THE FORCING TIME SERIES") CALL NOW_2_month_days(STARTTIME,year_start,month_start,day_start) cc_start = INT(year_start/100) yy_start = year_start - cc_start*100 CALL GDAY2(1,1,yy_start,cc_start,JULDAY0) CASE DEFAULT CALL FATAL_ERROR("SURFACE_HEATING: UNKNOWN HEATING KIND?") END SELECT !================================================================== SELECT CASE(HEAT_FORCING_TYPE) !================================================================== CASE(HEAT_IS_WRFGRID) !================================================================== IF(DBG_SET(DBG_LOG)) WRITE(IPT,*) & & "! SETTING UP HEAT FORCING FROM A 'wrf grid' FILE" ! LOOK FOR THE DIMENSIONS DIM => FIND_DIM(HEAT_FILE,'south_north',FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN SURFACE HEATING BOUNDARY CONDITION FILE OBJECT",& & "FILE NAME: "//TRIM(HEATING_SOLAR_FILE),& & "COULD NOT FIND DIMENSION 'south_north'") LATS = DIM%DIM DIM => FIND_DIM(HEAT_FILE,'west_east',FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN SURFACE HEATING BOUNDARY CONDITION FILE OBJECT",& & "FILE NAME: "//TRIM(HEATING_SOLAR_FILE),& & "COULD NOT FIND DIMENSION 'west_east'") LONS = DIM%DIM CALL SET_FILE_INTERP_BILINEAR(HEAT_FILE,HEAT_INTP_N,HEAT_INTP_C) ! SETUP THE ACTUAL VARIABLES USED TO LOAD DATA! ! ! AIR TEMPERATURE DATA VAR => FIND_VAR(HEAT_FILE,"air_temperature",FOUND) IF(.not. FOUND) VAR => FIND_VAR(HEAT_FILE,"air_temperature",FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN SURFACE HEATING BOUNDARY CONDITION FILE OBJECT",& & "FILE NAME: "//TRIM(HEATING_SOLAR_FILE),& & "COULD NOT FIND VARIABLE 'air_temperature'") ! MAKE SPACE FOR THE DATA FROM THE FILE ALLOCATE(STORAGE_ARR(lons,lats), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN SURFACE HEATING") T_AIR_N => reference_var(var) CALL NC_CONNECT_PVAR(T_AIR_N,STORAGE_ARR) NULLIFY(STORAGE_ARR) ! MAKE SPACE FOR THE INTERPOLATED DATA ALLOCATE(STORAGE_VEC(0:MT), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN SURFACE HEATING") CALL NC_CONNECT_PVAR(T_AIR_N,STORAGE_VEC) NULLIFY(STORAGE_VEC) ! MAKE SPACE FOR THE DATA FROM THE FILE ALLOCATE(STORAGE_ARR(lons,lats), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN SURFACE HEATING") T_AIR_P => reference_var(var) CALL NC_CONNECT_PVAR(T_AIR_P,STORAGE_ARR) NULLIFY(STORAGE_ARR) ! MAKE SPACE FOR THE INTERPOLATED DATA ALLOCATE(STORAGE_VEC(0:MT), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN SURFACE HEATING") CALL NC_CONNECT_PVAR(T_AIR_P,STORAGE_VEC) NULLIFY(STORAGE_VEC) ! ! DEW POINT VAR => FIND_VAR(HEAT_FILE,"dew_point",FOUND) IF(.not. FOUND) VAR => FIND_VAR(HEAT_FILE,"dew point",FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN SURFACE HEATING BOUNDARY CONDITION FILE OBJECT",& & "FILE NAME: "//TRIM(HEATING_SOLAR_FILE),& & "COULD NOT FIND VARIABLE 'dew_point'") ! MAKE SPACE FOR THE DATA FROM THE FILE ALLOCATE(STORAGE_ARR(lons,lats), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN SURFACE HEATING") TDEW_N => reference_var(var) CALL NC_CONNECT_PVAR(TDEW_N,STORAGE_ARR) NULLIFY(STORAGE_ARR) ! MAKE SPACE FOR THE INTERPOLATED DATA ALLOCATE(STORAGE_VEC(0:MT), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN SURFACE HEATING") CALL NC_CONNECT_PVAR(TDEW_N,STORAGE_VEC) NULLIFY(STORAGE_VEC) ! MAKE SPACE FOR THE DATA FROM THE FILE ALLOCATE(STORAGE_ARR(lons,lats), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN SURFACE HEATING") TDEW_P => reference_var(var) CALL NC_CONNECT_PVAR(TDEW_P,STORAGE_ARR) NULLIFY(STORAGE_ARR) ! MAKE SPACE FOR THE INTERPOLATED DATA ALLOCATE(STORAGE_VEC(0:MT), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN SURFACE HEATING") CALL NC_CONNECT_PVAR(TDEW_P,STORAGE_VEC) NULLIFY(STORAGE_VEC) ! ! CLOUD COVER VAR => FIND_VAR(HEAT_FILE,"cloud_cover",FOUND) IF(.not. FOUND) VAR => FIND_VAR(HEAT_FILE,"cloud cover",FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN SURFACE HEATING BOUNDARY CONDITION FILE OBJECT",& & "FILE NAME: "//TRIM(HEATING_SOLAR_FILE),& & "COULD NOT FIND VARIABLE 'cloud_cover'") ! MAKE SPACE FOR THE DATA FROM THE FILE ALLOCATE(STORAGE_ARR(lons,lats), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN SURFACE HEATING") CCOV_N => reference_var(var) CALL NC_CONNECT_PVAR(CCOV_N,STORAGE_ARR) NULLIFY(STORAGE_ARR) ! MAKE SPACE FOR THE INTERPOLATED DATA ALLOCATE(STORAGE_VEC(0:MT), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN SURFACE HEATING") CALL NC_CONNECT_PVAR(CCOV_N,STORAGE_VEC) NULLIFY(STORAGE_VEC) ! MAKE SPACE FOR THE DATA FROM THE FILE ALLOCATE(STORAGE_ARR(lons,lats), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN SURFACE HEATING") CCOV_P => reference_var(var) CALL NC_CONNECT_PVAR(CCOV_P,STORAGE_ARR) NULLIFY(STORAGE_ARR) ! MAKE SPACE FOR THE INTERPOLATED DATA ALLOCATE(STORAGE_VEC(0:MT), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN SURFACE HEATING") CALL NC_CONNECT_PVAR(CCOV_P,STORAGE_VEC) NULLIFY(STORAGE_VEC) !================================================================== CASE(HEAT_IS_FVCOMGRID) !================================================================== IF(DBG_SET(DBG_LOG)) WRITE(IPT,*) & & "! SETTING UP HEAT FORCING FROM A 'fvcom grid' FILE" ! LOOK FOR THE DIMENSIONS DIM => FIND_DIM(HEAT_FILE,'node',FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN SURFACE HEATING BOUNDARY CONDITION FILE OBJECT",& & "FILE NAME: "//TRIM(HEATING_SOLAR_FILE),& & "COULD NOT FIND DIMENSION 'node'") if (mgl /= dim%dim) CALL FATAL_ERROR& &("Surface Heating: the number of nodes in the file does not match the fvcom grid?") DIM => FIND_DIM(HEAT_FILE,'nele',FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN SURFACE HEATING BOUNDARY CONDITION FILE OBJECT",& & "FILE NAME: "//TRIM(HEATING_SOLAR_FILE),& & "COULD NOT FIND DIMENSION 'nele'") if (ngl /= dim%dim) CALL FATAL_ERROR& &("Surface Heating: the number of elements in the file does not match the fvcom grid?") ! SETUP THE ACTUAL VARIABLES USED TO LOAD DATA! ! ! AIR TEMPERATURE DATA VAR => FIND_VAR(HEAT_FILE,"air_temperature",FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN SURFACE HEATING BOUNDARY CONDITION FILE OBJECT",& & "FILE NAME: "//TRIM(HEATING_SOLAR_FILE),& & "COULD NOT FIND VARIABLE 'air_temperature'") ! MAKE SPACE FOR THE DATA FROM THE FILE T_AIR_N => reference_var(var) ALLOCATE(STORAGE_VEC(0:MT), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN SURFACE HEATING") CALL NC_CONNECT_PVAR(T_AIR_N,STORAGE_VEC) NULLIFY(STORAGE_VEC) ! MAKE SPACE FOR THE DATA FROM THE FILE T_AIR_P => reference_var(var) ALLOCATE(STORAGE_VEC(0:MT), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN SURFACE HEATING") CALL NC_CONNECT_PVAR(T_AIR_P,STORAGE_VEC) NULLIFY(STORAGE_VEC) ! ! DEW POINT VAR => FIND_VAR(HEAT_FILE,"dew_point",FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN SURFACE HEATING BOUNDARY CONDITION FILE OBJECT",& & "FILE NAME: "//TRIM(HEATING_SOLAR_FILE),& & "COULD NOT FIND VARIABLE 'dew_point'") ! MAKE SPACE FOR THE DATA FROM THE FILE TDEW_N => reference_var(var) ALLOCATE(STORAGE_VEC(0:MT), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN SURFACE HEATING") CALL NC_CONNECT_PVAR(TDEW_N,STORAGE_VEC) NULLIFY(STORAGE_VEC) ! MAKE SPACE FOR THE DATA FROM THE FILE TDEW_P => reference_var(var) ALLOCATE(STORAGE_VEC(0:MT), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN SURFACE HEATING") CALL NC_CONNECT_PVAR(TDEW_P,STORAGE_VEC) NULLIFY(STORAGE_VEC) ! ! CLOUD COVER VAR => FIND_VAR(HEAT_FILE,"cloud_cover",FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN SURFACE HEATING BOUNDARY CONDITION FILE OBJECT",& & "FILE NAME: "//TRIM(HEATING_SOLAR_FILE),& & "COULD NOT FIND VARIABLE 'cloud_cover'") ! MAKE SPACE FOR THE DATA FROM THE FILE CCOV_N => reference_var(var) ALLOCATE(STORAGE_VEC(0:MT), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN SURFACE HEATING") CALL NC_CONNECT_PVAR(CCOV_N,STORAGE_VEC) NULLIFY(STORAGE_VEC) ! MAKE SPACE FOR THE DATA FROM THE FILE CCOV_P => reference_var(var) ALLOCATE(STORAGE_VEC(0:MT), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN SURFACE HEATING") CALL NC_CONNECT_PVAR(CCOV_P,STORAGE_VEC) NULLIFY(STORAGE_VEC) ! !================================================================== CASE DEFAULT !================================================================== CALL FATAL_ERROR("CAN NOT RECOGNIZE HEATING FILE TYPE!") !================================================================== END SELECT !================================================================== ! afm 20151112 & EJA 20160921 ! Need initialization. Otherwise, random values are asigned ! and cause a hanging problem of MPI job in UPDATE_VAR_BRACKET ! This problem reported with Intel15.0.3. t_air_n%curr_stkcnt = 0;t_air_p%curr_stkcnt = 0 tdew_n%curr_stkcnt = 0;tdew_p%curr_stkcnt = 0 ccov_n%curr_stkcnt = 0;ccov_p%curr_stkcnt = 0 IF(DBG_SET(DBG_SBR)) write(IPT,*) "END SURFACE_HEATING_SOLAR" END SUBROUTINE SURFACE_HEATING_SOLAR # endif !================================================================ !================================================================ SUBROUTINE ICE_MODEL_FORCING IMPLICIT NONE ! SOME NC POINTERS TYPE(NCATT), POINTER :: ATT, ATT_DATE TYPE(NCDIM), POINTER :: DIM TYPE(NCVAR), POINTER :: VAR LOGICAL :: FOUND REAL(SP), POINTER :: STORAGE_ARR(:,:), storage_vec(:) CHARACTER(len=60) :: SATstrng, SLPstrng,SPQstrng,CLDstrng, SWVstrng TYPE(TIME) :: TIMETEST INTEGER :: LATS, LONS, I, Ntimes INTEGER :: STATUS IF(DBG_SET(DBG_SBR)) write(IPT,*) "START ICE MODEL FORCING" NULLIFY(ATT,DIM,VAR,STORAGE_ARR,STORAGE_VEC) IF (.NOT. ICE_MODEL) THEN IF(DBG_SET(DBG_LOG)) write(IPT,*) "! ICE MODEL IS OFF!" ALLOCATE(ICE_FORCING_COMMENTS(1)) ICE_FORCING_COMMENTS(1) = "ICE MODEL FORCING IS OFF" RETURN END IF ! DETERMINE HOW TO LOAD THE DATA SELECT CASE(ICE_FORCING_KIND) CASE (CNSTNT) ALLOCATE(ICE_FORCING_COMMENTS(6)) write(SATstrng,'(f8.4)') ICE_AIR_TEMP write(SPQstrng,'(f8.4)') ICE_SPEC_HUMIDITY write(CLDstrng,'(f8.4)') ICE_CLOUD_COVER write(SWVstrng,'(f8.4)') ICE_SHORTWAVE ICE_FORCING_COMMENTS(1) = "Using constant ice forcing:" ICE_FORCING_COMMENTS(2) = "Sea Leval Air Temp="//trim(SATstrng) ICE_FORCING_COMMENTS(4) = "Specific Humidity="//trim(SPQstrng) ICE_FORCING_COMMENTS(5) = "Cloud Cover="//trim(CLDstrng) ICE_FORCING_COMMENTS(6) = "Shortwave Radiation="//trim(SWVstrng) IF(DBG_SET(DBG_LOG)) THEN WRITE(IPT,*)"! SETTING UP CONSTANT ICE FORCING:" WRITE(IPT,*)"! Sea Leval Air Temp="//trim(SATstrng) WRITE(IPT,*)"! Specific Humidity="//trim(SPQstrng) WRITE(IPT,*)"! Cloud Cover="//trim(CLDstrng) WRITE(IPT,*)"! Shortwave Radiation="//trim(SWVstrng) END IF RETURN CASE(STTC) CALL FATAL_ERROR("STATIC ICE FORCING Not Set Up Yet") ! HEAT_FORCING_COMMENTS = "Using Static heating from file" CASE(TMDPNDNT) CALL FATAL_ERROR("TIME DEPENDANT ICE FORCING Not Set Up Yet") ! HEAT_FORCING_COMMENTS = "Using TIME DEPENDENT heating from file" CASE(PRDC) ICE_FILE => FIND_FILE(FILEHEAD,trim(ICE_FORCING_FILE),FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("COULD NOT FIND ICE MODEL BOUNDARY CONDINTION FILE OBJECT",& & "FILE NAME: "//TRIM(ICE_FORCING_FILE)) ! DETERMINE GRID TYPE BASED ON SOURCE ATTRIBUTE ATT => FIND_ATT(ICE_FILE,"source",FOUND) IF(.not. FOUND) ATT => FIND_ATT(ICE_FILE,"Source",FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN ICE FORCING BOUNDARY CONDITION FILE OBJECT",& & "FILE NAME: "//TRIM(ICE_FORCING_FILE),& &"COULD NOT FIND GLOBAL ATTRIBURE: 'source'") IF (ATT%CHR(1)(1:len_trim(wrf2fvcom_source)) ==& & TRIM(wrf2fvcom_source)) THEN ICE_FORCING_TYPE = ICE_IS_WRFGRID ELSE IF (ATT%CHR(1)(1:len_trim(fvcom_cap_grid_source)) ==& & TRIM(fvcom_cap_grid_source)) THEN ICE_FORCING_TYPE = ICE_IS_FVCOMGRID ELSE IF (ATT%CHR(1)(1:len_trim(fvcom_grid_source)) ==& & TRIM(fvcom_grid_source)) THEN ICE_FORCING_TYPE = ICE_IS_FVCOMGRID ELSE IF (ATT%CHR(1)(1:len_trim(wrf_grid_source)) ==& & TRIM(wrf_grid_source)) THEN ICE_FORCING_TYPE = ICE_IS_WRFGRID ELSE CALL PRINT_FILE(ICE_FILE) CALL FATAL_ERROR("CAN NOT RECOGNIZE ICE FORCING FILE!",& & "UNKNOWN SOURCE STRING:",TRIM(ATT%CHR(1))) END IF ! GOT GRID TYPE ALLOCATE(ICE_FORCING_COMMENTS(4)) ICE_FORCING_COMMENTS(1) = "FVCOM periodic surface ice model forcing:" ICE_FORCING_COMMENTS(2) = "FILE NAME:"//TRIM(ICE_FORCING_FILE) ICE_FORCING_COMMENTS(3) = "SOURCE:"//TRIM(ATT%CHR(1)) ATT_DATE => FIND_ATT(ICE_FILE,"START_DATE",FOUND) IF (FOUND) THEN ICE_FORCING_COMMENTS(4) ="MET DATA START DATE:"//TRIM(ATT_DATE%CHR(1)) ELSE ICE_FORCING_COMMENTS(4) = "Unknown start date meta data format" END IF ! GET THE FILES LENGTH OF TIME AND SAVE FOR PERIODIC FORCING ! LOOK FOR THE DIMENSIONS DIM => FIND_UNLIMITED(ICE_FILE,FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN ICE FORCING BOUNDARY CONDITION FILE OBJECT",& & "FILE NAME: "//TRIM(ICE_FORCING_FILE),& &"COULD NOT FIND THE UNLIMITED DIMENSION") NTIMES = DIM%DIM ICE_PERIOD = get_file_time(ICE_FILE,ntimes) ICE_PERIOD = ICE_PERIOD - get_file_time(ICE_FILE,1) IF (ICE_PERIOD /= get_file_time(ICE_FILE,ntimes)) THEN CALL PRINT_TIME(get_file_time(ICE_FILE,1),IPT,"FIRST FILE TIME") CALL PRINT_TIME(get_file_time(ICE_FILE,ntimes),IPT,"LAST FILE TIME") CALL FATAL_ERROR& &("TO USE PERIODIC FORCING THE FILE TIME MUST COUNT FROM ZERO",& & "THE DIFFERENCE BETWEEN THE CURRENT MODEL TIME AND THE START TIME,",& & "MODULO THE FORCING PERIOD, DETERMINES THE CURRENT FORCING") END IF IF(DBG_SET(DBG_LOG)) THEN WRITE(IPT,*) "! USING PERIODIC ICE FORCING:" CALL PRINT_TIME(ICE_PERIOD,IPT,"PERIOD") END IF CASE(VRBL) ICE_FILE => FIND_FILE(FILEHEAD,trim(ICE_FORCING_FILE),FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("COULD NOT FIND ICE FORCING BOUNDARY CONDINTION FILE OBJECT",& & "FILE NAME: "//TRIM(ICE_FORCING_FILE)) ! DETERMINE GRID TYPE BASED ON SOURCE ATTRIBUTE ATT => FIND_ATT(ICE_FILE,"source",FOUND) IF(.not. FOUND) ATT => FIND_ATT(ICE_FILE,"Source",FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN ICE FORCING BOUNDARY CONDITION FILE OBJECT",& & "FILE NAME: "//TRIM(ICE_FORCING_FILE),& &"COULD NOT FIND GLOBAL ATTRIBURE: 'source'") IF (ATT%CHR(1)(1:len_trim(wrf2fvcom_source)) ==& & TRIM(wrf2fvcom_source)) THEN ICE_FORCING_TYPE = ICE_IS_WRFGRID ELSE IF (ATT%CHR(1)(1:len_trim(fvcom_grid_source)) ==& & TRIM(fvcom_grid_source)) THEN ICE_FORCING_TYPE = ICE_IS_FVCOMGRID ELSE IF (ATT%CHR(1)(1:len_trim(fvcom_cap_grid_source)) ==& & TRIM(fvcom_cap_grid_source)) THEN ICE_FORCING_TYPE = ICE_IS_FVCOMGRID ELSE IF (ATT%CHR(1)(1:len_trim(wrf_grid_source)) ==& & TRIM(wrf_grid_source)) THEN ICE_FORCING_TYPE = ICE_IS_WRFGRID ELSE CALL PRINT_FILE(ICE_FILE) CALL FATAL_ERROR("CAN NOT RECOGNIZE ICE FORCING FILE!",& & "UNKNOWN SOURCE STRING:",TRIM(ATT%CHR(1))) END IF ! GOT GRID TYPE ALLOCATE(ICE_FORCING_COMMENTS(4)) ICE_FORCING_COMMENTS(1) = "FVCOM variable surface ice model forcing:" ICE_FORCING_COMMENTS(2) = "FILE NAME:"//TRIM(ICE_FORCING_FILE) ICE_FORCING_COMMENTS(3) = "SOURCE:"//TRIM(ATT%CHR(1)) ATT_DATE => FIND_ATT(ICE_FILE,"START_DATE",FOUND) IF (FOUND) THEN ICE_FORCING_COMMENTS(4) ="MET DATA START DATE:"//TRIM(ATT_DATE%CHR(1)) ELSE ICE_FORCING_COMMENTS(4) = "Unknown start date meta data format" END IF ! CHECK DIMENSIONS DIM => FIND_UNLIMITED(ICE_FILE,FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN ICE FORCING BOUNDARY CONDITION FILE OBJECT",& & "FILE NAME: "//TRIM(ICE_FORCING_FILE),& &"COULD NOT FIND UNLIMITED DIMENSION") NTIMES = DIM%DIM ! CHECK THE FILE TIME AND COMPARE WITH MODEL RUN TIME TIMETEST = get_file_time(ICE_FILE,1) IF(TIMETEST > STARTTIME) CALL FATAL_ERROR & & ("IN ICE FORCING BOUNDARY CONDITION FILE OBJECT",& & "FILE NAME: "//TRIM(ICE_FORCING_FILE),& &"THE MODEL RUN STARTS BEFORE THE FORCING TIME SERIES") TIMETEST = get_file_time(ICE_FILE,ntimes) IF(TIMETEST < ENDTIME) CALL FATAL_ERROR & & ("IN ICE FORCING BOUNDARY CONDITION FILE OBJECT",& & "FILE NAME: "//TRIM(ICE_FORCING_FILE),& &"THE MODEL RUN ENDS AFTER THE FORCING TIME SERIES") CASE DEFAULT CALL FATAL_ERROR("ICE FORCING: UNKNOWN ICE_FORCING KIND?") END SELECT !================================================================== SELECT CASE(ICE_FORCING_TYPE) !================================================================== CASE(ICE_IS_WRFGRID) !================================================================== IF(DBG_SET(DBG_LOG)) WRITE(IPT,*) & & "! SETTING UP ICE FORCING FROM A 'wrf grid' FILE" ! LOOK FOR THE DIMENSIONS DIM => FIND_DIM(ICE_FILE,'south_north',FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN ICE FORCING BOUNDARY CONDITION FILE OBJECT",& & "FILE NAME: "//TRIM(ICE_FORCING_FILE),& & "COULD NOT FIND DIMENSION 'south_north'") LATS = DIM%DIM DIM => FIND_DIM(ICE_FILE,'west_east',FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN ICE FORCING BOUNDARY CONDITION FILE OBJECT",& & "FILE NAME: "//TRIM(ICE_FORCING_FILE),& & "COULD NOT FIND DIMENSION 'west_east'") LONS = DIM%DIM CALL SET_FILE_INTERP_BILINEAR(ICE_FILE,ICE_INTP_N,ICE_INTP_C) ! SETUP THE ACTUAL VARIABLES USED TO LOAD DATA! !IF(ASSOCIATED(ICE_FILE,HEAT_FILE)) THEN VAR => FIND_VAR(HEAT_FILE,"short_wave",FOUND) IF( FOUND ) THEN ! USE THE SAME MEMORY USED FOR OCEAN MODEL HEAT FLUX ICE_SWV_N => HEAT_SWV_N ICE_SWV_P => HEAT_SWV_P ELSE ! LOAD YOUR OWN DATA FOR THE ICE MODEL ! SHORT WAVE RADIATION DATA VAR => FIND_VAR(ICE_FILE,"short_wave",FOUND) IF(.not. FOUND) VAR => FIND_VAR(ICE_FILE,"Shortwave",FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN ICE FORCING BOUNDARY CONDITION FILE OBJECT",& & "FILE NAME: "//TRIM(ICE_FORCING_FILE),& & "COULD NOT FIND VARIABLE 'short_wave'") ! MAKE SPACE FOR THE DATA FROM THE FILE ALLOCATE(STORAGE_ARR(lons,lats), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN ICE FORCING") ICE_SWV_N => reference_var(var) CALL NC_CONNECT_PVAR(ICE_SWV_N,STORAGE_ARR) NULLIFY(STORAGE_ARR) ! MAKE SPACE FOR THE INTERPOLATED DATA ALLOCATE(STORAGE_VEC(0:MT), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN ICE FORCING") CALL NC_CONNECT_PVAR(ICE_SWV_N,STORAGE_VEC) NULLIFY(STORAGE_VEC) ! MAKE SPACE FOR THE DATA FROM THE FILE ALLOCATE(STORAGE_ARR(lons,lats), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN ICE FORCING") ICE_SWV_P => reference_var(var) CALL NC_CONNECT_PVAR(ICE_SWV_P,STORAGE_ARR) NULLIFY(STORAGE_ARR) ! MAKE SPACE FOR THE INTERPOLATED DATA ALLOCATE(STORAGE_VEC(0:MT), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN ICE FORCING") CALL NC_CONNECT_PVAR(ICE_SWV_P,STORAGE_VEC) NULLIFY(STORAGE_VEC) END IF ! Surface Air Temperature DATA VAR => FIND_VAR(ICE_FILE,"SAT",FOUND) ! VAR => FIND_VAR(ICE_FILE,"T2",FOUND) ! afm 20150930 & EJA 20160921 IF(.not. FOUND) VAR => FIND_VAR(ICE_FILE,"air_temperature",FOUND) IF(.not. FOUND) VAR => FIND_VAR(ICE_FILE,"T2",FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN ICE FORCING BOUNDARY CONDITION FILE OBJECT",& & "FILE NAME: "//TRIM(ICE_FORCING_FILE),& & "COULD NOT FIND VARIABLE 'T2','air_temperature' or 'SAT'") ! MAKE SPACE FOR THE DATA FROM THE FILE ALLOCATE(STORAGE_ARR(lons,lats), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN ICE FORCING") ICE_SAT_N => reference_var(var) CALL NC_CONNECT_PVAR(ICE_SAT_N,STORAGE_ARR) NULLIFY(STORAGE_ARR) ! MAKE SPACE FOR THE INTERPOLATED DATA ALLOCATE(STORAGE_VEC(0:MT), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN ICE FORCING") CALL NC_CONNECT_PVAR(ICE_SAT_N,STORAGE_VEC) NULLIFY(STORAGE_VEC) ! MAKE SPACE FOR THE DATA FROM THE FILE ALLOCATE(STORAGE_ARR(lons,lats), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN ICE FORCING") ICE_SAT_P => reference_var(var) CALL NC_CONNECT_PVAR(ICE_SAT_P,STORAGE_ARR) NULLIFY(STORAGE_ARR) ! MAKE SPACE FOR THE INTERPOLATED DATA ALLOCATE(STORAGE_VEC(0:MT), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN ICE FORCING") CALL NC_CONNECT_PVAR(ICE_SAT_P,STORAGE_VEC) NULLIFY(STORAGE_VEC) ! Specific Humidity DATA VAR => FIND_VAR(ICE_FILE,"SPQ",FOUND) ! VAR => FIND_VAR(ICE_FILE,"Q2",FOUND) ! afm 20160513 & EJA 20160921 IF(.not. FOUND) VAR => FIND_VAR(ICE_FILE,"Q2",FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN ICE FORCING BOUNDARY CONDITION FILE OBJECT",& & "FILE NAME: "//TRIM(ICE_FORCING_FILE),& & "COULD NOT FIND VARIABLE 'Q2' or 'SPQ'") ! MAKE SPACE FOR THE DATA FROM THE FILE ALLOCATE(STORAGE_ARR(lons,lats), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN ICE FORCING") ICE_SPQ_N => reference_var(var) CALL NC_CONNECT_PVAR(ICE_SPQ_N,STORAGE_ARR) NULLIFY(STORAGE_ARR) ! MAKE SPACE FOR THE INTERPOLATED DATA ALLOCATE(STORAGE_VEC(0:MT), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN ICE FORCING") CALL NC_CONNECT_PVAR(ICE_SPQ_N,STORAGE_VEC) NULLIFY(STORAGE_VEC) ! MAKE SPACE FOR THE DATA FROM THE FILE ALLOCATE(STORAGE_ARR(lons,lats), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN ICE FORCING") ICE_SPQ_P => reference_var(var) CALL NC_CONNECT_PVAR(ICE_SPQ_P,STORAGE_ARR) NULLIFY(STORAGE_ARR) ! MAKE SPACE FOR THE INTERPOLATED DATA ALLOCATE(STORAGE_VEC(0:MT), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN ICE FORCING") CALL NC_CONNECT_PVAR(ICE_SPQ_P,STORAGE_VEC) NULLIFY(STORAGE_VEC) ! Cloud Cover DATA VAR => FIND_VAR(ICE_FILE,"cloud_cover",FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN ICE FORCING BOUNDARY CONDITION FILE OBJECT",& & "FILE NAME: "//TRIM(ICE_FORCING_FILE),& & "COULD NOT FIND VARIABLE 'cloud_cover'") ! MAKE SPACE FOR THE DATA FROM THE FILE ALLOCATE(STORAGE_ARR(lons,lats), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN ICE FORCING") ICE_CLD_N => reference_var(var) CALL NC_CONNECT_PVAR(ICE_CLD_N,STORAGE_ARR) NULLIFY(STORAGE_ARR) ! MAKE SPACE FOR THE INTERPOLATED DATA ALLOCATE(STORAGE_VEC(0:MT), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN ICE FORCING") CALL NC_CONNECT_PVAR(ICE_CLD_N,STORAGE_VEC) NULLIFY(STORAGE_VEC) ! MAKE SPACE FOR THE DATA FROM THE FILE ALLOCATE(STORAGE_ARR(lons,lats), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN ICE FORCING") ICE_CLD_P => reference_var(var) CALL NC_CONNECT_PVAR(ICE_CLD_P,STORAGE_ARR) NULLIFY(STORAGE_ARR) ! MAKE SPACE FOR THE INTERPOLATED DATA ALLOCATE(STORAGE_VEC(0:MT), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN ICE FORCING") CALL NC_CONNECT_PVAR(ICE_CLD_P,STORAGE_VEC) NULLIFY(STORAGE_VEC) !================================================================== CASE(ICE_IS_FVCOMGRID) !================================================================== IF(DBG_SET(DBG_LOG)) WRITE(IPT,*) & & "! SETTING UP HEAT FORCING FROM A 'fvcom grid' FILE" ! LOOK FOR THE DIMENSIONS DIM => FIND_DIM(ICE_FILE,'node',FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN ICE FORCING BOUNDARY CONDITION FILE OBJECT",& & "FILE NAME: "//TRIM(ICE_FORCING_FILE),& & "COULD NOT FIND DIMENSION 'node'") if (mgl /= dim%dim) CALL FATAL_ERROR& &("Ice Forcing: the number of nodes in the file does not match the fvcom grid?") DIM => FIND_DIM(ICE_FILE,'nele',FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN ICE FORCING BOUNDARY CONDITION FILE OBJECT",& & "FILE NAME: "//TRIM(ICE_FORCING_FILE),& & "COULD NOT FIND DIMENSION 'nele'") if (ngl /= dim%dim) CALL FATAL_ERROR& &("Ice Forcing: the number of elements in the file does not match the fvcom grid?") ! SETUP THE ACTUAL VARIABLES USED TO LOAD DATA! ! SHORT WAVE RADIATION DATA !IF(ASSOCIATED(ICE_FILE,HEAT_FILE)) THEN # if !defined (ICE_FRESHWATER) ! afm 20151112 & & EJA 20160921 ! commented out for Solar ---------- ! With SOLAR, use SOLAR-derived shortwave ! Without SOLAR, use shortwave from forcing data VAR => FIND_VAR(HEAT_FILE,"short_wave",FOUND) IF( FOUND ) THEN ! USE THE SAME MEMORY USED FOR OCEAN MODEL HEAT FLUX ICE_SWV_N => HEAT_SWV_N ICE_SWV_P => HEAT_SWV_P ELSE ! LOAD YOUR OWN DATA FOR THE ICE MODEL ! SHORT WAVE RADIATION DATA VAR => FIND_VAR(ICE_FILE,"short_wave",FOUND) IF(.not. FOUND) VAR => FIND_VAR(ICE_FILE,"Shortwave",FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN ICE FORCING BOUNDARY CONDITION FILE OBJECT",& & "FILE NAME: "//TRIM(ICE_FORCING_FILE),& & "COULD NOT FIND VARIABLE 'short_wave'") ! MAKE SPACE FOR THE DATA FROM THE FILE ICE_SWV_N => reference_var(var) ALLOCATE(STORAGE_VEC(0:MT), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN ICE FORCING") CALL NC_CONNECT_PVAR(ICE_SWV_N,STORAGE_VEC) NULLIFY(STORAGE_VEC) ! MAKE SPACE FOR THE DATA FROM THE FILE ICE_SWV_P => reference_var(var) ALLOCATE(STORAGE_VEC(0:MT), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN ICE FORCING") CALL NC_CONNECT_PVAR(ICE_SWV_P,STORAGE_VEC) NULLIFY(STORAGE_VEC) END IF # endif ! Surface Air Temperature DATA VAR => FIND_VAR(ICE_FILE,"SAT",FOUND) ! afm 20151112 & EJA 20160921 IF(.not. FOUND) VAR => FIND_VAR(ICE_FILE,"air_temperature",FOUND) IF(.not. FOUND) VAR => FIND_VAR(ICE_FILE,"T2",FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN ICE FORCING BOUNDARY CONDITION FILE OBJECT",& & "FILE NAME: "//TRIM(ICE_FORCING_FILE),& & "COULD NOT FIND VARIABLE 'T2','air_temperature' or 'SAT'") ! MAKE SPACE FOR THE DATA FROM THE FILE ICE_SAT_N => reference_var(var) ALLOCATE(STORAGE_VEC(0:MT), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN ICE FORCING") CALL NC_CONNECT_PVAR(ICE_SAT_N,STORAGE_VEC) NULLIFY(STORAGE_VEC) ! MAKE SPACE FOR THE DATA FROM THE FILE ICE_SAT_P => reference_var(var) ALLOCATE(STORAGE_VEC(0:MT), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN ICE FORCING") CALL NC_CONNECT_PVAR(ICE_SAT_P,STORAGE_VEC) NULLIFY(STORAGE_VEC) ! Specific Humidity DATA VAR => FIND_VAR(ICE_FILE,"SPQ",FOUND) IF(.not. FOUND) VAR => FIND_VAR(ICE_FILE,"Q2",FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN ICE FORCING BOUNDARY CONDITION FILE OBJECT",& & "FILE NAME: "//TRIM(ICE_FORCING_FILE),& & "COULD NOT FIND VARIABLE 'Q2' or 'SPQ'") ! MAKE SPACE FOR THE DATA FROM THE FILE ICE_SPQ_N => reference_var(var) ALLOCATE(STORAGE_VEC(0:MT), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN ICE FORCING") CALL NC_CONNECT_PVAR(ICE_SPQ_N,STORAGE_VEC) NULLIFY(STORAGE_VEC) ! MAKE SPACE FOR THE DATA FROM THE FILE ICE_SPQ_P => reference_var(var) ALLOCATE(STORAGE_VEC(0:MT), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN ICE FORCING") CALL NC_CONNECT_PVAR(ICE_SPQ_P,STORAGE_VEC) NULLIFY(STORAGE_VEC) ! Specific Humidity DATA VAR => FIND_VAR(ICE_FILE,"cloud_cover",FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN ICE FORCING BOUNDARY CONDITION FILE OBJECT",& & "FILE NAME: "//TRIM(ICE_FORCING_FILE),& & "COULD NOT FIND VARIABLE 'cloud_cover'") ! MAKE SPACE FOR THE DATA FROM THE FILE ICE_CLD_N => reference_var(var) ALLOCATE(STORAGE_VEC(0:MT), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN ICE FORCING") CALL NC_CONNECT_PVAR(ICE_CLD_N,STORAGE_VEC) NULLIFY(STORAGE_VEC) ! MAKE SPACE FOR THE DATA FROM THE FILE ICE_CLD_P => reference_var(var) ALLOCATE(STORAGE_VEC(0:MT), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN ICE FORCING") CALL NC_CONNECT_PVAR(ICE_CLD_P,STORAGE_VEC) NULLIFY(STORAGE_VEC) !================================================================== CASE DEFAULT !================================================================== CALL FATAL_ERROR("CAN NOT RECOGNIZE ICE FORCING FILE TYPE!") !================================================================== END SELECT !================================================================== ! afm 20151112 & EJA 20160921 ! Need initialization. Otherwise, random values are asigned ! and cause a hanging problem of MPI job in UPDATE_VAR_BRACKET ! This problem reported with Intel15.0.3. ! afm 20180717 # if !defined (ICE_FRESHWATER) ice_swv_n%curr_stkcnt = 0;ice_swv_p%curr_stkcnt = 0 # endif ice_sat_n%curr_stkcnt = 0;ice_sat_p%curr_stkcnt = 0 ice_spq_n%curr_stkcnt = 0;ice_spq_p%curr_stkcnt = 0 ice_cld_n%curr_stkcnt = 0;ice_cld_p%curr_stkcnt = 0 IF(DBG_SET(DBG_SBR)) write(IPT,*) "END ICE MODEL FORCING" END SUBROUTINE ICE_MODEL_FORCING !================================================================ !================================================================ SUBROUTINE ICING_FORCING IMPLICIT NONE ! SOME NC POINTERS TYPE(NCATT), POINTER :: ATT, ATT_DATE TYPE(NCDIM), POINTER :: DIM TYPE(NCVAR), POINTER :: VAR LOGICAL :: FOUND REAL(SP), POINTER :: STORAGE_ARR(:,:), storage_vec(:) CHARACTER(len=30) :: SATstrng, WSPDstrng TYPE(TIME) :: TIMETEST INTEGER :: LATS, LONS, I, Ntimes INTEGER :: STATUS IF(DBG_SET(DBG_SBR)) write(IPT,*) "START ICING_FORCING" NULLIFY(ATT,DIM,VAR,STORAGE_ARR,STORAGE_VEC) IF (.NOT. ICING_MODEL ) THEN IF(DBG_SET(DBG_LOG)) write(IPT,*) "! ICING MODEL IS OFF!" ALLOCATE(ICING_FORCING_COMMENTS(1)) ICING_FORCING_COMMENTS(1) = "ICING MODEL IS OFF" RETURN END IF ! DETERMINE HOW TO LOAD THE DATA SELECT CASE(ICING_FORCING_KIND) CASE (CNSTNT) write(SATstrng,'(f8.4)') ICING_AIR_TEMP write(WSPDstrng,'(f8.4)') ICING_WSPD ALLOCATE(ICING_FORCING_COMMENTS(3)) ICING_FORCING_COMMENTS(1) = "Using Constant heating:" ICING_FORCING_COMMENTS(2) = "Sea Level Air Temperature:"//trim(SATstrng) ICING_FORCING_COMMENTS(3) = "Wind Speed:"//trim(wspdstrng) IF(DBG_SET(DBG_LOG)) THEN WRITE(IPT,*) "! SETTING UP CONSTANT ICING: " WRITE(IPT,*) "! Sea Level Air Temperature:"//trim(SATstrng) WRITE(IPT,*) "! Wind Speed:"//trim(wspdstrng) END IF RETURN CASE(STTC) CALL FATAL_ERROR("STATIC HEATING Not Set Up Yet") ! HEAT_FORCING_COMMENTS = "Using Static heating from file" CASE(TMDPNDNT) CALL FATAL_ERROR("TIME DEPENDANT HEATING Not Set Up Yet") ! HEAT_FORCING_COMMENTS = "Using TIME DEPENDENT heating from file" CASE(PRDC) ICING_FILE => FIND_FILE(FILEHEAD,trim(ICING_FORCING_FILE),FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("COULD NOT FIND SURFACE ICING BOUNDARY CONDINTION FILE OBJECT",& & "FILE NAME: "//TRIM(ICING_FORCING_FILE)) ! DETERMINE GRID TYPE BASED ON SOURCE ATTRIBUTE ATT => FIND_ATT(ICING_FILE,"source",FOUND) IF(.not. FOUND) ATT => FIND_ATT(ICING_FILE,"Source",FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN SURFACE ICING BOUNDARY CONDITION FILE OBJECT",& & "FILE NAME: "//TRIM(ICING_FORCING_FILE),& &"COULD NOT FIND GLOBAL ATTRIBURE: 'source'") IF (ATT%CHR(1)(1:len_trim(wrf2fvcom_source)) ==& & TRIM(wrf2fvcom_source)) THEN ICING_FORCING_TYPE = ICING_IS_WRFGRID ELSE IF (ATT%CHR(1)(1:len_trim(fvcom_cap_grid_source)) ==& & TRIM(fvcom_cap_grid_source)) THEN ICING_FORCING_TYPE = ICING_IS_FVCOMGRID ELSE IF (ATT%CHR(1)(1:len_trim(fvcom_grid_source)) ==& & TRIM(fvcom_grid_source)) THEN ICING_FORCING_TYPE = ICING_IS_FVCOMGRID ELSE IF (ATT%CHR(1)(1:len_trim(wrf_grid_source)) ==& & TRIM(wrf_grid_source)) THEN ICING_FORCING_TYPE = ICING_IS_WRFGRID ELSE CALL PRINT_FILE(ICING_FILE) CALL FATAL_ERROR("CAN NOT RECOGNIZE ICING FILE!",& & "UNKNOWN SOURCE STRING:",TRIM(ATT%CHR(1))) END IF ! GOT GRID TYPE ALLOCATE(ICING_FORCING_COMMENTS(4)) ICING_FORCING_COMMENTS(1) = "FVCOM periodic surface icing forcing:" ICING_FORCING_COMMENTS(2) = "FILE NAME:"//TRIM(ICING_FORCING_FILE) ICING_FORCING_COMMENTS(3) = "SOURCE:"//TRIM(ATT%CHR(1)) ATT_DATE => FIND_ATT(ICING_FILE,"START_DATE",FOUND) IF (FOUND) THEN ICING_FORCING_COMMENTS(4) ="MET DATA START DATE:"//TRIM(ATT_DATE%CHR(1)) ELSE ICING_FORCING_COMMENTS(4) = "Unknown start date meta data format" END IF ! GET THE FILES LENGTH OF TIME AND SAVE FOR PERIODIC FORCING ! LOOK FOR THE DIMENSIONS DIM => FIND_UNLIMITED(ICING_FILE,FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN SURFACE ICING BOUNDARY CONDITION FILE OBJECT",& & "FILE NAME: "//TRIM(ICING_FORCING_FILE),& &"COULD NOT FIND THE UNLIMITED DIMENSION") NTIMES = DIM%DIM ICING_PERIOD = get_file_time(ICING_FILE,ntimes) ICING_PERIOD = ICING_PERIOD - get_file_time(ICING_FILE,1) IF (ICING_PERIOD /= get_file_time(ICING_FILE,ntimes)) THEN CALL PRINT_REAL_TIME(get_file_time(ICING_FILE,1),IPT,"FIRST FILE TIME",TIMEZONE) CALL PRINT_REAL_TIME(get_file_time(ICING_FILE,ntimes),IPT,"LAST FILE TIME",TIMEZONE) CALL FATAL_ERROR& &("TO USE PERIODIC FORCING THE FILE TIME MUST COUNT FROM ZERO",& & "THE DIFFERENCE BETWEEN THE CURRENT MODEL TIME AND THE START TIME,",& & "MODULO THE FORCING PERIOD, DETERMINES THE CURRENT FORCING") END IF IF(DBG_SET(DBG_LOG)) THEN WRITE(IPT,*) "! USING PERIODIC ICING FORCING:" CALL PRINT_TIME(ICING_PERIOD,IPT,"PERIOD") END IF CASE(VRBL) ICING_FILE => FIND_FILE(FILEHEAD,trim(ICING_FORCING_FILE),FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("COULD NOT FIND SURFACE ICING BOUNDARY CONDINTION FILE OBJECT",& & "FILE NAME: "//TRIM(ICING_FORCING_FILE)) ! DETERMINE GRID TYPE BASED ON SOURCE ATTRIBUTE ATT => FIND_ATT(ICING_FILE,"source",FOUND) IF(.not. FOUND) ATT => FIND_ATT(ICING_FILE,"Source",FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN SURFACE ICING BOUNDARY CONDITION FILE OBJECT",& & "FILE NAME: "//TRIM(ICING_FORCING_FILE),& &"COULD NOT FIND GLOBAL ATTRIBURE: 'source'") ICING_FORCING_COMMENTS ="VARIABLE ICING: "//TRIM(ATT%CHR(1)) IF (ATT%CHR(1)(1:len_trim(wrf2fvcom_source)) ==& & TRIM(wrf2fvcom_source)) THEN ICING_FORCING_TYPE = ICING_IS_WRFGRID ELSE IF (ATT%CHR(1)(1:len_trim(fvcom_grid_source)) ==& & TRIM(fvcom_grid_source)) THEN ICING_FORCING_TYPE = ICING_IS_FVCOMGRID ELSE IF (ATT%CHR(1)(1:len_trim(fvcom_cap_grid_source)) ==& & TRIM(fvcom_cap_grid_source)) THEN ICING_FORCING_TYPE = ICING_IS_FVCOMGRID ELSE IF (ATT%CHR(1)(1:len_trim(wrf_grid_source)) ==& & TRIM(wrf_grid_source)) THEN ICING_FORCING_TYPE = ICING_IS_WRFGRID ELSE CALL PRINT_FILE(ICING_FILE) CALL FATAL_ERROR("CAN NOT RECOGNIZE ICING FILE!",& & "UNKNOWN SOURCE STRING:",TRIM(ATT%CHR(1))) END IF ! GOT GRID TYPE ALLOCATE(ICING_FORCING_COMMENTS(4)) ICING_FORCING_COMMENTS(1) = "FVCOM variable surface icing forcing:" ICING_FORCING_COMMENTS(2) = "FILE NAME:"//TRIM(ICING_FORCING_FILE) ICING_FORCING_COMMENTS(3) = "SOURCE:"//TRIM(ATT%CHR(1)) ATT_DATE => FIND_ATT(ICING_FILE,"START_DATE",FOUND) IF (FOUND) THEN ICING_FORCING_COMMENTS(4) ="MET DATA START DATE:"//TRIM(ATT_DATE%CHR(1)) ELSE ICING_FORCING_COMMENTS(4) = "Unknown start date meta data format" END IF ! CHECK DIMENSIONS DIM => FIND_UNLIMITED(ICING_FILE,FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN SURFACE ICING BOUNDARY CONDITION FILE OBJECT",& & "FILE NAME: "//TRIM(ICING_FORCING_FILE),& &"COULD NOT FIND UNLIMITED DIMENSION") NTIMES = DIM%DIM ! CHECK THE FILE TIME AND COMPARE WITH MODEL RUN TIME TIMETEST = get_file_time(ICING_FILE,1) IF(TIMETEST > STARTTIME) CALL FATAL_ERROR & & ("IN SURFACE ICING BOUNDARY CONDITION FILE OBJECT",& & "FILE NAME: "//TRIM(ICING_FORCING_FILE),& &"THE MODEL RUN STARTS BEFORE THE FORCING TIME SERIES") TIMETEST = get_file_time(ICING_FILE,ntimes) IF(TIMETEST < ENDTIME) CALL FATAL_ERROR & & ("IN SURFACE ICING BOUNDARY CONDITION FILE OBJECT",& & "FILE NAME: "//TRIM(ICING_FORCING_FILE),& &"THE MODEL RUN ENDS AFTER THE FORCING TIME SERIES") CASE DEFAULT CALL FATAL_ERROR("SURFACE_ICING: UNKNOWN ICING KIND?") END SELECT !================================================================== SELECT CASE(ICING_FORCING_TYPE) !================================================================== CASE(ICING_IS_WRFGRID) !================================================================== IF(DBG_SET(DBG_LOG)) WRITE(IPT,*) & & "! SETTING UP ICING FORCING FROM A 'wrf grid' FILE" ! LOOK FOR THE DIMENSIONS DIM => FIND_DIM(ICING_FILE,'south_north',FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN SURFACE ICING BOUNDARY CONDITION FILE OBJECT",& & "FILE NAME: "//TRIM(ICING_FORCING_FILE),& & "COULD NOT FIND DIMENSION 'south_north'") LATS = DIM%DIM DIM => FIND_DIM(ICING_FILE,'west_east',FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN SURFACE HEATING BOUNDARY CONDITION FILE OBJECT",& & "FILE NAME: "//TRIM(ICING_FORCING_FILE),& & "COULD NOT FIND DIMENSION 'west_east'") LONS = DIM%DIM CALL SET_FILE_INTERP_BILINEAR(ICING_FILE,ICING_INTP_N,ICING_INTP_C) ! SETUP THE ACTUAL VARIABLES USED TO LOAD DATA! ! SEA LEVEL AIR TEMPERATURE IF(ASSOCIATED(ICE_FILE,ICING_FILE)) THEN ! USE THE ALREADY LOADED DATA FROM THE ICE MODEL ICING_SAT_N => ICE_SAT_N ICING_SAT_P => ICE_SAT_P ELSE VAR => FIND_VAR(ICING_FILE,"T2",FOUND) ! IF(.not. FOUND) VAR => FIND_VAR(ICING_FILE,"T2",FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN SURFACE HEATING BOUNDARY CONDITION FILE OBJECT",& & "FILE NAME: "//TRIM(ICING_FORCING_FILE),& & "COULD NOT FIND VARIABLE 'T2'") ! MAKE SPACE FOR THE DATA FROM THE FILE ALLOCATE(STORAGE_ARR(lons,lats), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN ICING_FORCING") ICING_SAT_N => reference_var(var) CALL NC_CONNECT_PVAR(ICING_SAT_N,STORAGE_ARR) NULLIFY(STORAGE_ARR) ! MAKE SPACE FOR THE INTERPOLATED DATA ALLOCATE(STORAGE_VEC(0:MT), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN ICING_FORCING") CALL NC_CONNECT_PVAR(ICING_SAT_N,STORAGE_VEC) NULLIFY(STORAGE_VEC) ! MAKE SPACE FOR THE DATA FROM THE FILE ALLOCATE(STORAGE_ARR(lons,lats), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN ICING_FORCING") ICING_SAT_P => reference_var(var) CALL NC_CONNECT_PVAR(ICING_SAT_P,STORAGE_ARR) NULLIFY(STORAGE_ARR) ! MAKE SPACE FOR THE INTERPOLATED DATA ALLOCATE(STORAGE_VEC(0:MT), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN ICING_FORCING") CALL NC_CONNECT_PVAR(ICING_SAT_P,STORAGE_VEC) NULLIFY(STORAGE_VEC) END IF ! NET WIND SPEED X VAR => FIND_VAR(HEAT_FILE,"U10",FOUND) ! IF(.not. FOUND) VAR => FIND_VAR(HEAT_FILE,"U10",FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN SURFACE ICING BOUNDARY CONDITION FILE OBJECT",& & "FILE NAME: "//TRIM(ICING_FORCING_FILE),& & "COULD NOT FIND VARIABLE 'U10'") ! MAKE SPACE FOR THE DATA FROM THE FILE ALLOCATE(STORAGE_ARR(lons,lats), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN ICING_FORCING") ICING_WSPX_N => reference_var(var) CALL NC_CONNECT_PVAR(ICING_WSPX_N,STORAGE_ARR) NULLIFY(STORAGE_ARR) ! MAKE SPACE FOR THE INTERPOLATED DATA ALLOCATE(STORAGE_VEC(0:MT), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN ICING_FORCING") CALL NC_CONNECT_PVAR(ICING_WSPX_N,STORAGE_VEC) NULLIFY(STORAGE_VEC) ! MAKE SPACE FOR THE DATA FROM THE FILE ALLOCATE(STORAGE_ARR(lons,lats), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN ICING_FORCING") ICING_WSPX_P => reference_var(var) CALL NC_CONNECT_PVAR(ICING_WSPX_P,STORAGE_ARR) NULLIFY(STORAGE_ARR) ! MAKE SPACE FOR THE INTERPOLATED DATA ALLOCATE(STORAGE_VEC(0:MT), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN ICING_FORCING") CALL NC_CONNECT_PVAR(ICING_WSPX_P,STORAGE_VEC) NULLIFY(STORAGE_VEC) ! NET WIND SPEED Y VAR => FIND_VAR(HEAT_FILE,"V10",FOUND) ! IF(.not. FOUND) VAR => FIND_VAR(HEAT_FILE,"U10",FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN SURFACE ICING BOUNDARY CONDITION FILE OBJECT",& & "FILE NAME: "//TRIM(ICING_FORCING_FILE),& & "COULD NOT FIND VARIABLE 'V10'") ! MAKE SPACE FOR THE DATA FROM THE FILE ALLOCATE(STORAGE_ARR(lons,lats), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN ICING_FORCING") ICING_WSPY_N => reference_var(var) CALL NC_CONNECT_PVAR(ICING_WSPY_N,STORAGE_ARR) NULLIFY(STORAGE_ARR) ! MAKE SPACE FOR THE INTERPOLATED DATA ALLOCATE(STORAGE_VEC(0:MT), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN ICING_FORCING") CALL NC_CONNECT_PVAR(ICING_WSPY_N,STORAGE_VEC) NULLIFY(STORAGE_VEC) ! MAKE SPACE FOR THE DATA FROM THE FILE ALLOCATE(STORAGE_ARR(lons,lats), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN ICING_FORCING") ICING_WSPY_P => reference_var(var) CALL NC_CONNECT_PVAR(ICING_WSPY_P,STORAGE_ARR) NULLIFY(STORAGE_ARR) ! MAKE SPACE FOR THE INTERPOLATED DATA ALLOCATE(STORAGE_VEC(0:MT), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN ICING_FORCING") CALL NC_CONNECT_PVAR(ICING_WSPY_P,STORAGE_VEC) NULLIFY(STORAGE_VEC) !================================================================== CASE(ICING_IS_FVCOMGRID) !================================================================== IF(DBG_SET(DBG_LOG)) WRITE(IPT,*) & & "! SETTING UP ICING FORCING FROM A 'fvcom grid' FILE" ! LOOK FOR THE DIMENSIONS DIM => FIND_DIM(ICING_FILE,'node',FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN SURFACE ICING BOUNDARY CONDITION FILE OBJECT",& & "FILE NAME: "//TRIM(ICING_FORCING_FILE),& & "COULD NOT FIND DIMENSION 'node'") if (mgl /= dim%dim) CALL FATAL_ERROR& &("Surface ICing: the number of nodes in the file does not match the fvcom grid?") DIM => FIND_DIM(HEAT_FILE,'nele',FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN SURFACE ICING BOUNDARY CONDITION FILE OBJECT",& & "FILE NAME: "//TRIM(ICING_FORCING_FILE),& & "COULD NOT FIND DIMENSION 'nele'") if (ngl /= dim%dim) CALL FATAL_ERROR& &("Surface Icing: the number of elements in the file does not match the fvcom grid?") ! SETUP THE ACTUAL VARIABLES USED TO LOAD DATA! ! Sea Surface Air Temperature IF(ASSOCIATED(ICE_FILE,ICING_FILE)) THEN ! USE THE SAME MEMORY USED FOR OCEAN MODEL HEAT FLUX ICING_SAT_N => ICE_SAT_N ICING_SAT_P => ICE_SAT_P ELSE VAR => FIND_VAR(ICING_FILE,"T2",FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN SURFACE ICING BOUNDARY CONDITION FILE OBJECT",& & "FILE NAME: "//TRIM(ICING_FORCING_FILE),& & "COULD NOT FIND VARIABLE 'T2'") ! MAKE SPACE FOR THE DATA FROM THE FILE ICING_SAT_N => reference_var(var) ALLOCATE(STORAGE_VEC(0:MT), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN ICING_FORCING") CALL NC_CONNECT_PVAR(ICING_SAT_N,STORAGE_VEC) NULLIFY(STORAGE_VEC) ! MAKE SPACE FOR THE DATA FROM THE FILE ICING_SAT_P => reference_var(var) ALLOCATE(STORAGE_VEC(0:MT), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN ICING_FORCING") CALL NC_CONNECT_PVAR(ICING_SAT_P,STORAGE_VEC) NULLIFY(STORAGE_VEC) END IF ! Wind Speed X VAR => FIND_VAR(HEAT_FILE,"U10",FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN SURFACE ICING BOUNDARY CONDITION FILE OBJECT",& & "FILE NAME: "//TRIM(ICING_FORCING_FILE),& & "COULD NOT FIND VARIABLE 'U10'") ! MAKE SPACE FOR THE DATA FROM THE FILE ICING_WSPX_N => reference_var(var) ALLOCATE(STORAGE_VEC(0:MT), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN ICING_FORCING") CALL NC_CONNECT_PVAR(ICING_WSPX_N,STORAGE_VEC) NULLIFY(STORAGE_VEC) ! MAKE SPACE FOR THE DATA FROM THE FILE ICING_WSPX_P => reference_var(var) ALLOCATE(STORAGE_VEC(0:MT), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN ICING_FORCING") CALL NC_CONNECT_PVAR(ICING_WSPX_P,STORAGE_VEC) NULLIFY(STORAGE_VEC) !================================================================== CASE DEFAULT !================================================================== CALL FATAL_ERROR("CAN NOT RECOGNIZE ICING FILE TYPE!") !================================================================== END SELECT !================================================================== ! ---------- new: 2016 , april, Karsten Lettmann after Hint by Qi and ayumi.fujisaki@noaa.gov------ ! Initialize some variables ! afm 20150914 ! Need initialization. Otherwise, random values are asigned ! and cause a hanging problem of MPI job in UPDATE_VAR_BRACKET ! This problem reported with Intel15.0.3. ICING_SAT_P%CURR_STKCNT = 0; ICING_SAT_N%CURR_STKCNT = 0 ICING_WSPX_P%CURR_STKCNT = 0; ICING_WSPX_N%CURR_STKCNT = 0 ICING_WSPY_P%CURR_STKCNT = 0; ICING_WSPY_N%CURR_STKCNT = 0 ! --------------------- end new ---------------------------------------------------- IF(DBG_SET(DBG_SBR)) write(IPT,*) "END ICING FORCING" END SUBROUTINE ICING_FORCING !================================================================ !================================================================ SUBROUTINE SURFACE_WINDSTRESS IMPLICIT NONE ! SOME NC POINTERS TYPE(NCATT), POINTER :: ATT, ATT_DATE TYPE(NCDIM), POINTER :: DIM TYPE(NCVAR), POINTER :: VAR LOGICAL :: FOUND REAL(SP), POINTER :: STORAGE_ARR(:,:), storage_vec(:) TYPE(TIME) :: TIMETEST INTEGER :: LATS, LONS, I, Ntimes INTEGER :: STATUS CHARACTER(len=60) :: xstr, ystr IF(DBG_SET(DBG_SBR)) write(IPT,*) "START SURFACE_WINDSTRESS" NULLIFY(ATT,DIM,VAR,STORAGE_ARR,STORAGE_VEC) IF (.NOT. WIND_ON ) THEN IF(DBG_SET(DBG_LOG)) write(IPT,*) "! SURFACE WIND FORCING IS OFF!" ALLOCATE(WINDS_FORCING_COMMENTS(1)) WINDS_FORCING_COMMENTS(1) = "SURFACE WIND FORCING IS OFF" RETURN END IF IF (WIND_TYPE /= SPEED .and.WIND_TYPE /= STRESS) CALL FATAL_ERROR& &("YOU MUST SELECT A WIND TYPE IN THE RUNFILE: '"& &//TRIM(SPEED)//", or '"//TRIM(STRESS)//"'") !---> Siqi Li, 2021-01-27 IF (WIND_ON) THEN SELECT CASE (TRIM(WIND_STRESS_METHOD)) CASE ('LP1981') IF(DBG_SET(DBG_LOG)) write(IPT,*) "! WIND_STRESS_METHOD : LP1981!" # if defined (HEATING_CALCULATED) CASE ('COARE') IF(DBG_SET(DBG_LOG)) write(IPT,*) "! WIND_STRESS_METHOD : COARE!" # else CASE ('COARE') CALL FATAL_ERROR("TO USE COARE FOR WIND_STRESS_METHOD, & & RECOMPILE FVCOM WITH HEATING_CALCULATED") # endif # if defined (WAVE_CURRENT_INTERACTION) CASE ('TY2001') IF(DBG_SET(DBG_LOG)) write(IPT,*) "! WIND_STRESS_METHOD : TY2001!" # else CASE ('TY2001') CALL FATAL_ERROR("TO USE TY2001 FOR WIND_STRESS_METHOD, & & RECOMPILE FVCOM WITH WAVE_ONLY or WAVE_CURRENT_INTERACTION") # endif # if defined(HEATING_CALCULATED) && defined(WAVE_CURRENT_INTERACTION) CASE ('OOST') IF(DBG_SET(DBG_LOG)) write(IPT,*) "! WIND_STRESS_METHOD : OOST!" CASE ('DGHQ') IF(DBG_SET(DBG_LOG)) write(IPT,*) "! WIND_STRESS_METHOD : DGHQ!" # else CASE ('OOST') CALL FATAL_ERROR("TO USE OOST FOR WIND_STRESS_METHOD, & & RECOMPILE FVCOM WITH HEATING_CALCULATED and & & WAVE_ONLY / WAVE_CURRENT_INTERACTION") CASE ('DGHQ') CALL FATAL_ERROR("TO USE DGHQ FOR WIND_STRESS_METHOD, & & RECOMPILE FVCOM WITH HEATING_CALCULATED and & & WAVE_ONLY / WAVE_CURRENT_INTERACTION") # endif CASE DEFAULT CALL FATAL_ERROR & & ("WRONG WIND_STRESS_METHOD OPTIONS.") END SELECT # if defined(HEATING_CALCULATED) && defined(WAVE_CURRENT_INTERACTION) IF (TRIM(WIND_STRESS_METHOD) == 'COARE' .AND. TRIM(COARE_VERSION) == 'COARE26Z')& & CALL FATAL_ERROR("COARE26Z DOES NOT INVOLVE WAVE. & & CHANGE ANOTHER WIND_STRESS_METHOD") # endif END IF !<--- Siqi Li, 2021-01-27 ! DETERMINE HOW TO LOAD THE DATA SELECT CASE(WIND_KIND) CASE (CNSTNT) write(xstr,'(f8.4)') WIND_X write(ystr,'(f8.4)') WIND_Y IF (WIND_TYPE == SPEED)THEN IF(DBG_SET(DBG_LOG)) THEN WRITE(IPT,*)"! SETTING UP CONSTANT WIND SPEED FORCING: " WRITE(IPT,*)" Xspeed: "//trim(xstr) WRITE(IPT,*)" Yspeed: "//trim(ystr) END IF ALLOCATE(WINDS_FORCING_COMMENTS(3)) WINDS_FORCING_COMMENTS(1) = "Using constant wind speed from run file:" WINDS_FORCING_COMMENTS(2) = "Xspeed:"//trim(xstr) WINDS_FORCING_COMMENTS(3) = "Yspeed:"//trim(ystr) RETURN ELSEIF(WIND_TYPE == STRESS)THEN IF(DBG_SET(DBG_LOG)) THEN WRITE(IPT,*)"! SETTING UP CONSTANT WIND STRESS FORCING: " WRITE(IPT,*)" Xstress: "//trim(xstr) WRITE(IPT,*)" Ystress: "//trim(ystr) END IF ALLOCATE(WINDS_FORCING_COMMENTS(3)) WINDS_FORCING_COMMENTS(1) = "Using constant wind stress from run file:" WINDS_FORCING_COMMENTS(2) = "Xstress:"//trim(xstr) WINDS_FORCING_COMMENTS(3) = "Ystress:"//trim(ystr) RETURN END IF CASE(STTC) CALL FATAL_ERROR("STATIC WIND Not Set Up Yet") CASE(TMDPNDNT) CALL FATAL_ERROR("TIME DEPENDANT WIND Not Set Up Yet") CASE(PRDC) WINDS_FILE => FIND_FILE(FILEHEAD,trim(WIND_FILE),FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("COULD NOT FIND SURFACE WIND BOUNDARY CONDINTION FILE OBJECT",& & "FILE NAME: "//TRIM(WIND_FILE)) ! DETERMINE GRID TYPE BASED ON SOURCE ATTRIBUTE ATT => FIND_ATT(WINDS_FILE,"source",FOUND) IF(.not. FOUND) ATT => FIND_ATT(WINDS_FILE,"Source",FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN SURFACE WIND BOUNDARY CONDITION FILE OBJECT",& & "FILE NAME: "//TRIM(WIND_FILE),& &"COULD NOT FIND GLOBAL ATTRIBURE: 'source'") IF (ATT%CHR(1)(1:len_trim(wrf2fvcom_source)) ==& & TRIM(wrf2fvcom_source)) THEN WINDS_FORCING_TYPE = WINDS_ARE_WRFGRID ELSE IF (ATT%CHR(1)(1:len_trim(fvcom_grid_source)) ==& & TRIM(fvcom_grid_source)) THEN WINDS_FORCING_TYPE = WINDS_ARE_FVCOMGRID ELSE IF (ATT%CHR(1)(1:len_trim(fvcom_cap_grid_source)) ==& & TRIM(fvcom_cap_grid_source)) THEN WINDS_FORCING_TYPE = WINDS_ARE_FVCOMGRID ELSE IF (ATT%CHR(1)(1:len_trim(wrf_grid_source)) ==& & TRIM(wrf_grid_source)) THEN WINDS_FORCING_TYPE = WINDS_ARE_WRFGRID ELSE CALL PRINT_FILE(WINDS_FILE) CALL FATAL_ERROR("CAN NOT RECOGNIZE WIND FILE!",& & "UNKNOWN SOURCE STRING:",TRIM(ATT%CHR(1))) END IF ! GOT GRID TYPE ALLOCATE(WINDS_FORCING_COMMENTS(4)) WINDS_FORCING_COMMENTS(1) = "FVCOM periodic surface Wind forcing:" WINDS_FORCING_COMMENTS(2) = "FILE NAME:"//TRIM(WIND_FILE) WINDS_FORCING_COMMENTS(3) = "SOURCE:"//TRIM(ATT%CHR(1)) ATT_DATE => FIND_ATT(WINDS_FILE,"START_DATE",FOUND) IF (FOUND) THEN WINDS_FORCING_COMMENTS(4) ="MET DATA START DATE:"//TRIM(ATT_DATE%CHR(1)) ELSE WINDS_FORCING_COMMENTS(4) = "Unknown start date meta data format" END IF ! GET THE FILES LENGTH OF TIME AND SAVE FOR PERIODIC FORCING ! LOOK FOR THE DIMENSIONS DIM => FIND_UNLIMITED(WINDS_FILE,FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN SURFACE WIND BOUNDARY CONDITION FILE OBJECT",& & "FILE NAME: "//TRIM(WIND_FILE),& &"COULD NOT FIND THE UNLMITIED DIMENSION") NTIMES = DIM%DIM WINDS_PERIOD = get_file_time(WINDS_FILE,ntimes) WINDS_PERIOD = WINDS_PERIOD - get_file_time(WINDS_FILE,1) IF (WINDS_PERIOD /= get_file_time(WINDS_FILE,ntimes)) THEN CALL PRINT_REAL_TIME(get_file_time(WINDS_FILE,1),IPT,"FIRST FILE TIME",TIMEZONE) CALL PRINT_REAL_TIME(get_file_time(WINDS_FILE,ntimes),IPT,"LAST FILE TIME",TIMEZONE) CALL FATAL_ERROR& &("TO USE PERIODIC FORCING THE FILE TIME MUST COUNT FROM ZERO",& & "THE DIFFERENCE BETWEEN THE CURRENT MODEL TIME AND THE START TIME,",& & "MODULO THE FORCING PERIOD, DETERMINES THE CURRENT FORCING") END IF IF(DBG_SET(DBG_LOG)) THEN WRITE(IPT,*) "! USING PERIODIC WIND FORCING:" CALL PRINT_TIME(WINDS_PERIOD,IPT,"PERIOD") END IF CASE(VRBL) WINDS_FILE => FIND_FILE(FILEHEAD,trim(WIND_FILE),FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("COULD NOT FIND SURFACE WIND BOUNDARY CONDINTION FILE OBJECT",& & "FILE NAME: "//TRIM(WIND_FILE)) ! DETERMINE GRID TYPE BASED ON SOURCE ATTRIBUTE ATT => FIND_ATT(WINDS_FILE,"source",FOUND) IF(.not. FOUND) ATT => FIND_ATT(WINDS_FILE,"Source",FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN SURFACE WIND BOUNDARY CONDITION FILE OBJECT",& & "FILE NAME: "//TRIM(WIND_FILE),& &"COULD NOT FIND GLOBAL ATTRIBURE: 'source'") IF (ATT%CHR(1)(1:len_trim(wrf2fvcom_source)) ==& & TRIM(wrf2fvcom_source)) THEN WINDS_FORCING_TYPE = WINDS_ARE_WRFGRID ELSE IF (ATT%CHR(1)(1:len_trim(fvcom_grid_source)) ==& & TRIM(fvcom_grid_source)) THEN WINDS_FORCING_TYPE = WINDS_ARE_FVCOMGRID ELSE IF (ATT%CHR(1)(1:len_trim(fvcom_cap_grid_source)) ==& & TRIM(fvcom_cap_grid_source)) THEN WINDS_FORCING_TYPE = WINDS_ARE_FVCOMGRID ELSE IF (ATT%CHR(1)(1:len_trim(wrf_grid_source)) ==& & TRIM(wrf_grid_source)) THEN WINDS_FORCING_TYPE = WINDS_ARE_WRFGRID ELSE IF (ATT%CHR(1)(1:len_trim(surf_forcing_pt_source)) ==& & TRIM(surf_forcing_pt_source)) THEN WINDS_FORCING_TYPE = WINDS_ARE_PT_SOURCE ELSE CALL PRINT_FILE(WINDS_FILE) CALL FATAL_ERROR("CAN NOT RECOGNIZE WIND FILE!",& & "UNKNOWN SOURCE STRING:",TRIM(ATT%CHR(1))) END IF ! GOT GRID TYPE ALLOCATE(WINDS_FORCING_COMMENTS(4)) WINDS_FORCING_COMMENTS(1) = "FVCOM variable surface Wind forcing:" WINDS_FORCING_COMMENTS(2) = "FILE NAME:"//TRIM(WIND_FILE) WINDS_FORCING_COMMENTS(3) = "SOURCE:"//TRIM(ATT%CHR(1)) ATT_DATE => FIND_ATT(WINDS_FILE,"START_DATE",FOUND) IF (FOUND) THEN WINDS_FORCING_COMMENTS(4) ="MET DATA START DATE:"//TRIM(ATT_DATE%CHR(1)) ELSE WINDS_FORCING_COMMENTS(4) = "Unknown start date meta data format" END IF ! LOOK FOR THE DIMENSIONS DIM => FIND_UNLIMITED(WINDS_FILE,FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN SURFACE WIND BOUNDARY CONDITION FILE OBJECT",& & "FILE NAME: "//TRIM(WIND_FILE),& &"COULD NOT FIND THE UNLIMITED DIMENSION") NTIMES = DIM%DIM ! CHECK THE FILE TIME AND COMPARE WITH MODEL RUN TIME TIMETEST = get_file_time(WINDS_FILE,1) IF(TIMETEST > STARTTIME) CALL FATAL_ERROR & & ("IN SURFACE WIND BOUNDARY CONDITION FILE OBJECT",& & "FILE NAME: "//TRIM(WIND_FILE),& &"THE MODEL RUN STARTS BEFORE THE FORCING TIME SERIES") TIMETEST = get_file_time(WINDS_FILE,ntimes) IF(TIMETEST < ENDTIME) CALL FATAL_ERROR & & ("IN SURFACE WIND BOUNDARY CONDITION FILE OBJECT",& & "FILE NAME: "//TRIM(WIND_FILE),& &"THE MODEL RUN ENDS AFTER THE FORCING TIME SERIES") CASE DEFAULT CALL FATAL_ERROR("SURFACE_WINDSTRESS: UNKNOWN WIND KIND?") END SELECT !============================================================== SELECT CASE(WINDS_FORCING_TYPE) !============================================================== CASE(WINDS_ARE_WRFGRID) !============================================================== IF(DBG_SET(DBG_LOG)) WRITE(IPT,*) & & "! SETTING UP WIND STRESS FORCING FROM A 'wrf grid' FILE" DIM => FIND_DIM(WINDS_FILE,'south_north',FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN SURFACE WIND BOUNDARY CONDITION FILE OBJECT",& & "FILE NAME: "//TRIM(WIND_FILE),& & "COULD NOT FIND DIMENSION 'south_north'") LATS = DIM%DIM DIM => FIND_DIM(WINDS_FILE,'west_east',FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN SURFACE WIND BOUNDARY CONDITION FILE OBJECT",& & "FILE NAME: "//TRIM(WIND_FILE),& & "COULD NOT FIND DIMENSION 'west_east'") LONS = DIM%DIM CALL SET_FILE_INTERP_bilinear(WINDS_FILE,WINDS_INTP_N,WINDS_INTP_C) ! SETUP THE ACTUAL VARIABLES USED TO LOAD DATA! IF (WIND_TYPE == SPEED)THEN ! WIND SPEED IN THE X or EAST-WEST DIRECTION VAR => FIND_VAR(WINDS_FILE,"uwind_speed",FOUND) IF(.not. FOUND) VAR => FIND_VAR(WINDS_FILE,"U10",FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN SURFACE WIND BOUNDARY CONDITION FILE OBJECT",& & "FILE NAME: "//TRIM(WIND_FILE),& & "COULD NOT FIND VARIABLE 'uwind_speed' or 'U10'") ELSEIF(WIND_TYPE == STRESS)THEN ! WIND STRESS IN THE X or EAST-WEST DIRECTION VAR => FIND_VAR(WINDS_FILE,"uwind_stress",FOUND) IF(.not. FOUND) VAR => FIND_VAR(WINDS_FILE,"Stress_U",FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN SURFACE WIND BOUNDARY CONDITION FILE OBJECT",& & "FILE NAME: "//TRIM(WIND_FILE),& & "COULD NOT FIND VARIABLE 'uwind_stress' or 'Stress_U'") END IF ! MAKE SPACE FOR THE DATA FROM THE FILE ALLOCATE(STORAGE_ARR(lons,lats), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN SURFACE WINDSTRESS") WINDS_STRX_N => reference_var(var) CALL NC_CONNECT_PVAR(WINDS_STRX_N,STORAGE_ARR) NULLIFY(STORAGE_ARR) ! MAKE SPACE FOR THE INTERPOLATED DATA ALLOCATE(STORAGE_VEC(0:NT), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN SURFACE WINDSTRESS") CALL NC_CONNECT_PVAR(WINDS_STRX_N,STORAGE_VEC) NULLIFY(STORAGE_VEC) ! MAKE SPACE FOR THE DATA FROM THE FILE ALLOCATE(STORAGE_ARR(lons,lats), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN SURFACE WINDSTRESS") WINDS_STRX_P => reference_var(var) CALL NC_CONNECT_PVAR(WINDS_STRX_P,STORAGE_ARR) NULLIFY(STORAGE_ARR) ! MAKE SPACE FOR THE INTERPOLATED DATA ALLOCATE(STORAGE_VEC(0:NT), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN SURFACE WINDSTRESS") CALL NC_CONNECT_PVAR(WINDS_STRX_P,STORAGE_VEC) NULLIFY(STORAGE_VEC) IF (WIND_TYPE == SPEED)THEN ! WIND SPEED IN THE Y or NORTH SOUTH DIRECTION VAR => FIND_VAR(WINDS_FILE,"vwind_speed",FOUND) IF(.not. FOUND) VAR => FIND_VAR(WINDS_FILE,"V10",FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN SURFACE WIND BOUNDARY CONDITION FILE OBJECT",& & "FILE NAME: "//TRIM(WIND_FILE),& & "COULD NOT FIND VARIABLE 'vwind_speed' or 'V10'") ELSEIF(WIND_TYPE == STRESS)THEN ! WIND STRESS IN THE Y or NORTH SOUTH DIRECTION VAR => FIND_VAR(WINDS_FILE,"vwind_stress",FOUND) IF(.not. FOUND) VAR => FIND_VAR(WINDS_FILE,"Stress_V",FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN SURFACE WIND BOUNDARY CONDITION FILE OBJECT",& & "FILE NAME: "//TRIM(WIND_FILE),& & "COULD NOT FIND VARIABLE 'vwind_stress' or 'Stress_V'") END IF ! MAKE SPACE FOR THE DATA FROM THE FILE ALLOCATE(STORAGE_ARR(lons,lats), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN SURFACE WINDSTRESS") WINDS_STRY_N => reference_var(var) CALL NC_CONNECT_PVAR(WINDS_STRY_N,STORAGE_ARR) NULLIFY(STORAGE_ARR) ! MAKE SPACE FOR THE INTERPOLATED DATA ALLOCATE(STORAGE_VEC(0:NT), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN SURFACE WINDSTRESS") CALL NC_CONNECT_PVAR(WINDS_STRY_N,STORAGE_VEC) NULLIFY(STORAGE_VEC) ! MAKE SPACE FOR THE DATA FROM THE FILE ALLOCATE(STORAGE_ARR(lons,lats), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN SURFACE WINDSTRESS") WINDS_STRY_P => reference_var(var) CALL NC_CONNECT_PVAR(WINDS_STRY_P,STORAGE_ARR) NULLIFY(STORAGE_ARR) ! MAKE SPACE FOR THE INTERPOLATED DATA ALLOCATE(STORAGE_VEC(0:NT), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN SURFACE WINDSTRESS") CALL NC_CONNECT_PVAR(WINDS_STRY_P,STORAGE_VEC) NULLIFY(STORAGE_VEC) !============================================================== CASE(WINDS_ARE_FVCOMGRID) !============================================================== IF(DBG_SET(DBG_LOG)) WRITE(IPT,*) & & "! SETTING UP WIND STRESS FORCING FROM A 'FVCOM GRID' FILE" DIM => FIND_DIM(WINDS_FILE,'node',FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN SURFACE WIND BOUNDARY CONDITION FILE OBJECT",& & "FILE NAME: "//TRIM(WIND_FILE),& & "COULD NOT FIND DIMENSION 'node'") if (mgl /= dim%dim) CALL FATAL_ERROR& &("Surface Windstress: the number of nodes in the file does not match the fvcom grid?") DIM => FIND_DIM(WINDS_FILE,'nele',FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN SURFACE WIND BOUNDARY CONDITION FILE OBJECT",& & "FILE NAME: "//TRIM(WIND_FILE),& & "COULD NOT FIND DIMENSION 'nele'") if (ngl /= dim%dim) CALL FATAL_ERROR& &("Surface Windstress: the number of elements in the file does not match the fvcom grid?") ! SETUP THE ACTUAL VARIABLES USED TO LOAD DATA! IF (WIND_TYPE == SPEED)THEN ! WIND SPEED IN THE X or EAST-WEST DIRECTION VAR => FIND_VAR(WINDS_FILE,"uwind_speed",FOUND) IF(.not. FOUND) VAR => FIND_VAR(WINDS_FILE,"U10",FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN SURFACE WIND BOUNDARY CONDITION FILE OBJECT",& & "FILE NAME: "//TRIM(WIND_FILE),& & "COULD NOT FIND VARIABLE 'uwind_speed' or 'U10'") ELSEIF(WIND_TYPE == STRESS)THEN ! WIND STRESS IN THE X or EAST-WEST DIRECTION VAR => FIND_VAR(WINDS_FILE,"uwind_stress",FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN SURFACE WIND BOUNDARY CONDITION FILE OBJECT",& & "FILE NAME: "//TRIM(WIND_FILE),& & "COULD NOT FIND VARIABLE 'uwind_stress'") END IF ! MAKE SPACE FOR THE DATA FROM THE FILE WINDS_STRX_N => reference_var(var) ALLOCATE(STORAGE_VEC(0:NT), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN SURFACE WINDSTRESS") CALL NC_CONNECT_PVAR(WINDS_STRX_N,STORAGE_VEC) NULLIFY(STORAGE_VEC) ! MAKE SPACE FOR THE DATA FROM THE FILE WINDS_STRX_P => reference_var(var) ALLOCATE(STORAGE_VEC(0:NT), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN SURFACE WINDSTRESS") CALL NC_CONNECT_PVAR(WINDS_STRX_P,STORAGE_VEC) NULLIFY(STORAGE_VEC) IF (WIND_TYPE == SPEED)THEN ! WIND SPEED IN THE Y or NORTH SOUTH DIRECTION VAR => FIND_VAR(WINDS_FILE,"vwind_speed",FOUND) IF(.not. FOUND) VAR => FIND_VAR(WINDS_FILE,"V10",FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN SURFACE WIND BOUNDARY CONDITION FILE OBJECT",& & "FILE NAME: "//TRIM(WIND_FILE),& & "COULD NOT FIND VARIABLE 'vwind_speed' or 'V10'") ELSEIF(WIND_TYPE == STRESS)THEN ! WIND STRESS IN THE Y or NORTH SOUTH DIRECTION VAR => FIND_VAR(WINDS_FILE,"vwind_stress",FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN SURFACE WIND BOUNDARY CONDITION FILE OBJECT",& & "FILE NAME: "//TRIM(WIND_FILE),& & "COULD NOT FIND VARIABLE 'vwind_stress'") END IF ! MAKE SPACE FOR THE DATA FROM THE FILE WINDS_STRY_N => reference_var(var) ALLOCATE(STORAGE_VEC(0:NT), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN SURFACE WINDSTRESS") CALL NC_CONNECT_PVAR(WINDS_STRY_N,STORAGE_VEC) NULLIFY(STORAGE_VEC) ! MAKE SPACE FOR THE DATA FROM THE FILE WINDS_STRY_P => reference_var(var) ALLOCATE(STORAGE_VEC(0:NT), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN SURFACE WINDSTRESS") CALL NC_CONNECT_PVAR(WINDS_STRY_P,STORAGE_VEC) NULLIFY(STORAGE_VEC) !============================================================== CASE(WINDS_ARE_PT_SOURCE) !============================================================== IF(DBG_SET(DBG_LOG)) WRITE(IPT,*) & & "! SETTING UP WIND STRESS FORCING FROM A 'FVCOM GRID' FILE" ! SETUP THE ACTUAL VARIABLES USED TO LOAD DATA! IF (WIND_TYPE == SPEED)THEN ! WIND SPEED IN THE X or EAST-WEST DIRECTION VAR => FIND_VAR(WINDS_FILE,"uwind_speed",FOUND) IF(.not. FOUND) VAR => FIND_VAR(WINDS_FILE,"U10",FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN SURFACE WIND BOUNDARY CONDITION FILE OBJECT",& & "FILE NAME: "//TRIM(WIND_FILE),& & "COULD NOT FIND VARIABLE 'uwind_speed' or 'U10'") ELSEIF(WIND_TYPE == STRESS)THEN ! WIND STRESS IN THE X or EAST-WEST DIRECTION VAR => FIND_VAR(WINDS_FILE,"uwind_stress",FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN SURFACE WIND BOUNDARY CONDITION FILE OBJECT",& & "FILE NAME: "//TRIM(WIND_FILE),& & "COULD NOT FIND VARIABLE 'uwind_stress'") END IF ! MAKE SPACE FOR THE DATA FROM THE FILE WINDS_STRX_N => reference_var(var) ALLOCATE(STORAGE_VEC(1), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN SURFACE WINDSTRESS") CALL NC_CONNECT_PVAR(WINDS_STRX_N,STORAGE_VEC) NULLIFY(STORAGE_VEC) ! MAKE SPACE FOR THE DATA FROM THE FILE WINDS_STRX_P => reference_var(var) ALLOCATE(STORAGE_VEC(1), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN SURFACE WINDSTRESS") CALL NC_CONNECT_PVAR(WINDS_STRX_P,STORAGE_VEC) NULLIFY(STORAGE_VEC) IF (WIND_TYPE == SPEED)THEN ! WIND SPEED IN THE Y or NORTH SOUTH DIRECTION VAR => FIND_VAR(WINDS_FILE,"vwind_speed",FOUND) IF(.not. FOUND) VAR => FIND_VAR(WINDS_FILE,"V10",FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN SURFACE WIND BOUNDARY CONDITION FILE OBJECT",& & "FILE NAME: "//TRIM(WIND_FILE),& & "COULD NOT FIND VARIABLE 'vwind_speed' or 'V10'") ELSEIF(WIND_TYPE == STRESS)THEN ! WIND STRESS IN THE Y or NORTH SOUTH DIRECTION VAR => FIND_VAR(WINDS_FILE,"vwind_stress",FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN SURFACE WIND BOUNDARY CONDITION FILE OBJECT",& & "FILE NAME: "//TRIM(WIND_FILE),& & "COULD NOT FIND VARIABLE 'vwind_stress'") END IF ! MAKE SPACE FOR THE DATA FROM THE FILE WINDS_STRY_N => reference_var(var) ALLOCATE(STORAGE_VEC(1), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN SURFACE WINDSTRESS") CALL NC_CONNECT_PVAR(WINDS_STRY_N,STORAGE_VEC) NULLIFY(STORAGE_VEC) ! MAKE SPACE FOR THE DATA FROM THE FILE WINDS_STRY_P => reference_var(var) ALLOCATE(STORAGE_VEC(1), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN SURFACE WINDSTRESS") CALL NC_CONNECT_PVAR(WINDS_STRY_P,STORAGE_VEC) NULLIFY(STORAGE_VEC) !============================================================== CASE DEFAULT !============================================================== CALL FATAL_ERROR("CAN NOT RECOGNIZE WIND FILE TYPE!") !============================================================== END SELECT !============================================================== ! afm 20151112 & EJA 20160921 ! Need initialization. Otherwise, random values are asigned ! and cause a hanging problem of MPI job in UPDATE_VAR_BRACKET ! This problem reported with Intel15.0.3. winds_strx_n%curr_stkcnt = 0; winds_strx_p%curr_stkcnt = 0 winds_stry_n%curr_stkcnt = 0; winds_stry_p%curr_stkcnt = 0 IF(DBG_SET(DBG_SBR)) write(IPT,*) "END SURFACE_WINDSTRESS" END SUBROUTINE SURFACE_WINDSTRESS !================================================================ # if defined (WAVE_CURRENT_INTERACTION) && (WAVE_ONLY) !================================================================ SUBROUTINE SURFACE_ICEIN IMPLICIT NONE ! SOME NC POINTERS TYPE(NCATT), POINTER :: ATT, ATT_DATE TYPE(NCDIM), POINTER :: DIM TYPE(NCVAR), POINTER :: VAR LOGICAL :: FOUND REAL(SP), POINTER :: STORAGE_ARR(:,:), storage_vec(:) TYPE(TIME) :: TIMETEST INTEGER :: LATS, LONS, I, Ntimes INTEGER :: STATUS CHARACTER(len=60) :: icec IF(DBG_SET(DBG_SBR)) write(IPT,*) "START SURFACE_ICEIN" NULLIFY(ATT,DIM,VAR,STORAGE_ARR,STORAGE_VEC) IF (.NOT. ICEIN_ON ) THEN IF(DBG_SET(DBG_LOG)) write(IPT,*) "! SURFACE ICEIN FORCING IS OFF!" ALLOCATE(ICEINS_FORCING_COMMENTS(1)) ICEINS_FORCING_COMMENTS(1) = "SURFACE ICEIN FORCING IS OFF" RETURN END IF !PRINT *, "ICEIN_KIND",ICEIN_KIND !zhangyang ! DETERMINE HOW TO LOAD THE DATA SELECT CASE(ICEIN_KIND) CASE (CNSTNT) write(icec,'(f8.4)') ICEC IF(DBG_SET(DBG_LOG)) THEN WRITE(IPT,*)"! SETTING UP CONSTANT ICEIN FORCING: " WRITE(IPT,*)" Icec: "//trim(icec) END IF ALLOCATE(ICEINS_FORCING_COMMENTS(2)) ICEINS_FORCING_COMMENTS(1) = "Using constant ICEIN from run file:" ICEINS_FORCING_COMMENTS(2) = "Icec:"//trim(icec) RETURN CASE(VRBL) ICEINS_FILE => FIND_FILE(FILEHEAD,trim(ICEIN_FILE),FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("COULD NOT FIND SURFACE ICEIN CONDINTION FILE OBJECT",& & "FILE NAME: "//TRIM(ICEIN_FILE)) ! DETERMINE GRID TYPE BASED ON SOURCE ATTRIBUTE ATT => FIND_ATT(ICEINS_FILE,"source",FOUND) IF(.not. FOUND) ATT => FIND_ATT(ICEINS_FILE,"Source",FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN SURFACE ICEIN CONDITION FILE OBJECT",& & "FILE NAME: "//TRIM(ICEIN_FILE),& &"COULD NOT FIND GLOBAL ATTRIBURE: 'source'") IF (ATT%CHR(1)(1:len_trim(wrf2fvcom_source)) ==& & TRIM(wrf2fvcom_source)) THEN ICEINS_FORCING_TYPE = ICEINS_ARE_WRFGRID ELSE IF (ATT%CHR(1)(1:len_trim(fvcom_grid_source)) ==& & TRIM(fvcom_grid_source)) THEN ICEINS_FORCING_TYPE = ICEINS_ARE_FVCOMGRID ELSE IF (ATT%CHR(1)(1:len_trim(fvcom_cap_grid_source)) ==& & TRIM(fvcom_cap_grid_source)) THEN ICEINS_FORCING_TYPE = ICEINS_ARE_FVCOMGRID ELSE IF (ATT%CHR(1)(1:len_trim(wrf_grid_source)) ==& & TRIM(wrf_grid_source)) THEN ICEINS_FORCING_TYPE = ICEINS_ARE_WRFGRID ELSE IF (ATT%CHR(1)(1:len_trim(surf_forcing_pt_source)) ==& & TRIM(surf_forcing_pt_source)) THEN ICEINS_FORCING_TYPE = ICEINS_ARE_PT_SOURCE ELSE CALL PRINT_FILE(ICEINS_FILE) CALL FATAL_ERROR("CAN NOT RECOGNIZE ICEIN FILE!",& & "UNKNOWN SOURCE STRING:",TRIM(ATT%CHR(1))) END IF ! GOT GRID TYPE ALLOCATE(ICEINS_FORCING_COMMENTS(4)) ICEINS_FORCING_COMMENTS(1) = "FVCOM variable surface Icein forcing:" ICEINS_FORCING_COMMENTS(2) = "FILE NAME:"//TRIM(ICEIN_FILE) ICEINS_FORCING_COMMENTS(3) = "SOURCE:"//TRIM(ATT%CHR(1)) ATT_DATE => FIND_ATT(ICEINS_FILE,"START_DATE",FOUND) IF (FOUND) THEN ICEINS_FORCING_COMMENTS(4) ="MET DATA START DATE:"//TRIM(ATT_DATE%CHR(1)) ELSE ICEINS_FORCING_COMMENTS(4) = "Unknown start date meta data format" END IF ! LOOK FOR THE DIMENSIONS DIM => FIND_UNLIMITED(ICEINS_FILE,FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN SURFACE ICEIN BOUNDARY CONDITION FILE OBJECT",& & "FILE NAME: "//TRIM(ICEIN_FILE),& &"COULD NOT FIND THE UNLIMITED DIMENSION") NTIMES = DIM%DIM ! CHECK THE FILE TIME AND COMPARE WITH MODEL RUN TIME TIMETEST = get_file_time(ICEINS_FILE,1) IF(TIMETEST > STARTTIME) CALL FATAL_ERROR & & ("IN SURFACE ICEIN BOUNDARY CONDITION FILE OBJECT",& & "FILE NAME: "//TRIM(ICEIN_FILE),& &"THE MODEL RUN STARTS BEFORE THE FORCING TIME SERIES") TIMETEST = get_file_time(ICEINS_FILE,ntimes) IF(TIMETEST < ENDTIME) CALL FATAL_ERROR & & ("IN SURFACE ICEIN BOUNDARY CONDITION FILE OBJECT",& & "FILE NAME: "//TRIM(ICEIN_FILE),& &"THE MODEL RUN ENDS AFTER THE FORCING TIME SERIES") CASE DEFAULT CALL FATAL_ERROR("SURFACE_ICEIN: UNKNOWN ICEIN KIND?") END SELECT !PRINT *, "ICEINS_FORCING_TYPE_in",ICEINS_FORCING_TYPE !============================================================== SELECT CASE(ICEINS_FORCING_TYPE) !============================================================== CASE(ICEINS_ARE_WRFGRID) !============================================================== CALL FATAL_ERROR("ICEIN based on WRF grid Not Set Up Yet") !============================================================== CASE(ICEINS_ARE_FVCOMGRID) !============================================================== IF(DBG_SET(DBG_LOG)) WRITE(IPT,*) & & "! SETTING UP ICEIN FORCING FROM A 'FVCOM GRID' FILE" DIM => FIND_DIM(ICEINS_FILE,'node',FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN SURFACE ICEIN CONDITION FILE OBJECT",& & "FILE NAME: "//TRIM(ICEIN_FILE),& & "COULD NOT FIND DIMENSION 'node'") if (mgl /= dim%dim) CALL FATAL_ERROR& &("Surface ICEIN: the number of nodes in the file does not match the fvcom grid?") ! ICE CONCENTRATION AT EVERY NODES VAR => FIND_VAR(ICEINS_FILE,"icec",FOUND) IF(.not. FOUND) VAR => FIND_VAR(ICEINS_FILE,"aice",FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN SURFACE ICEIN BOUNDARY CONDITION FILE OBJECT",& & "FILE NAME: "//TRIM(ICEIN_FILE),& & "COULD NOT FIND VARIABLE 'icec'") ! MAKE SPACE FOR THE DATA FROM THE FILE ICEINS_ICEC_N => reference_var(var) ALLOCATE(STORAGE_VEC(0:MT), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN SURFACE ICE CONCENTRATION") CALL NC_CONNECT_PVAR(ICEINS_ICEC_N,STORAGE_VEC) NULLIFY(STORAGE_VEC) ! MAKE SPACE FOR THE DATA FROM THE FILE ICEINS_ICEC_P => reference_var(var) ALLOCATE(STORAGE_VEC(0:MT), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN SURFACE ICE CONCENTRATION") CALL NC_CONNECT_PVAR(ICEINS_ICEC_P,STORAGE_VEC) NULLIFY(STORAGE_VEC) CASE DEFAULT !============================================================== CALL FATAL_ERROR("CAN NOT RECOGNIZE ICEIN FILE TYPE!") !============================================================== END SELECT !============================================================== IF(DBG_SET(DBG_SBR)) write(IPT,*) "END SURFACE_ICEIN" END SUBROUTINE SURFACE_ICEIN !================================================================ # endif # if defined (OFFLINE_SEDIMENT) !================================================================ !================================================================ SUBROUTINE OFFLINE_SEDIMENT_FORCING IMPLICIT NONE ! SOME NC POINTERS TYPE(NCATT), POINTER :: ATT, ATT_DATE TYPE(NCDIM), POINTER :: DIM TYPE(NCVAR), POINTER :: VAR LOGICAL :: FOUND REAL(SP), POINTER :: STORAGE_ARR(:,:), storage_vec(:) INTEGER , POINTER :: STORAGE_INT(:) TYPE(TIME) :: TIMETEST INTEGER :: LATS, LONS, I, Ntimes INTEGER :: STATUS CHARACTER(len=60) :: xstr, ystr IF(DBG_SET(DBG_SBR)) write(IPT,*) "START OFFLINE_SEDIMET_FORCING" NULLIFY(ATT,DIM,VAR,STORAGE_ARR,STORAGE_VEC,STORAGE_INT) ! DETERMINE THE VARIABLE FORCING TO LOAD THE DATA SEDIMENTS_FILE => FIND_FILE(FILEHEAD,trim(OFFLINE_SEDIMENT_FILE),FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("COULD NOT FIND OFFLINE SEDIMENT HYDRODRAULIC FORCING FILE OBJECT",& & "FILE NAME: "//TRIM(OFFLINE_SEDIMENT_FILE)) ! DETERMINE GRID TYPE BASED ON SOURCE ATTRIBUTE ATT => FIND_ATT(SEDIMENTS_FILE,"source",FOUND) IF(.not. FOUND) ATT => FIND_ATT(SEDIMENTS_FILE,"Source",FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN OFFLINE SEDIMENT FILE OBJECT",& & "FILE NAME: "//TRIM(OFFLINE_SEDIMENT_FILE),& &"COULD NOT FIND GLOBAL ATTRIBURE: 'source'") IF (ATT%CHR(1)(1:len_trim(wrf2fvcom_source)) ==& & TRIM(wrf2fvcom_source)) THEN SEDIMENTS_FORCING_TYPE = SEDIMENTS_ARE_WRFGRID ELSE IF (ATT%CHR(1)(1:len_trim(fvcom_grid_source)) ==& & TRIM(fvcom_grid_source)) THEN SEDIMENTS_FORCING_TYPE = SEDIMENTS_ARE_FVCOMGRID ELSE IF (ATT%CHR(1)(1:len_trim(fvcom_cap_grid_source)) ==& & TRIM(fvcom_cap_grid_source)) THEN SEDIMENTS_FORCING_TYPE = SEDIMENTS_ARE_FVCOMGRID ELSE IF (ATT%CHR(1)(1:len_trim(wrf_grid_source)) ==& & TRIM(wrf_grid_source)) THEN SEDIMENTS_FORCING_TYPE = SEDIMENTS_ARE_WRFGRID ELSE IF (ATT%CHR(1)(1:5)=='fvcom'.or.ATT%CHR(1)(1:5)=='FVCOM')THEN SEDIMENTS_FORCING_TYPE = SEDIMENTS_ARE_FVCOMGRID ELSE CALL PRINT_FILE(SEDIMENTS_FILE) CALL FATAL_ERROR("CAN NOT RECOGNIZE OFFLINE SEDIMENT FILE!",& & "UNKNOWN SOURCE STRING:",TRIM(ATT%CHR(1))) END IF ! GOT GRID TYPE ALLOCATE(SEDIMENTS_FORCING_COMMENTS(4)) SEDIMENTS_FORCING_COMMENTS(1) = "FVCOM variable offline sedimen& &t hydraulic forcing:" SEDIMENTS_FORCING_COMMENTS(2) = "FILE NAME:"//TRIM(OFFLINE_SEDIMENT_FILE) SEDIMENTS_FORCING_COMMENTS(3) = "SOURCE:"//TRIM(ATT%CHR(1)) ATT_DATE => FIND_ATT(SEDIMENTS_FILE,"START_DATE",FOUND) IF (FOUND) THEN SEDIMENTS_FORCING_COMMENTS(4) ="MET DATA START DATE:"//TRIM(ATT_DATE%CHR(1)) ELSE SEDIMENTS_FORCING_COMMENTS(4) = "Unknown start date meta data format" END IF ! LOOK FOR THE DIMENSIONS DIM => FIND_UNLIMITED(SEDIMENTS_FILE,FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN OFFLINE SEDIMENT HYDRAULIC FORCING FILE OBJECT",& & "FILE NAME: "//TRIM(OFFLINE_SEDIMENT_FILE),& &"COULD NOT FIND THE UNLIMITED DIMENSION") NTIMES = DIM%DIM ! CHECK THE FILE TIME AND COMPARE WITH MODEL RUN TIME TIMETEST = get_file_time(SEDIMENTS_FILE,1) IF(TIMETEST > STARTTIME) CALL FATAL_ERROR & & ("IN OFFLINE SEDIMENT HYDRAULIC FORCING FILE OBJECT",& & "FILE NAME: "//TRIM(OFFLINE_SEDIMENT_FILE),& &"THE MODEL RUN STARTS BEFORE THE FORCING TIME SERIES") TIMETEST = get_file_time(SEDIMENTS_FILE,ntimes) IF(TIMETEST < ENDTIME) CALL FATAL_ERROR & & ("IN OFFLINE SEDIMENT HYDRAULIC FORCING FILE OBJECT",& & "FILE NAME: "//TRIM(OFFLINE_SEDIMENT_FILE),& &"THE MODEL RUN ENDS AFTER THE FORCING TIME SERIES") !----------------------------------------------------------------! !--SET THE DATA TYPE OF FVCOM FORMAT ! !----------------------------------------------------------------! IF(DBG_SET(DBG_LOG)) WRITE(IPT,*) & & "! SETTING UP OFFLINE SEDIMENT HYDRAULIC FORCING FROM A 'FVCOM GRID' FILE" DIM => FIND_DIM(SEDIMENTS_FILE,'node',FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN OFFLINE SEDIMENT HYDRAULIC FORCING FILE OBJECT",& & "FILE NAME: "//TRIM(OFFLINE_SEDIMENT_FILE),& & "COULD NOT FIND DIMENSION 'node'") if (mgl /= dim%dim) CALL FATAL_ERROR& &("Offline sediment forcing: the number of nodes in the file does not match the fvcom grid?") DIM => FIND_DIM(SEDIMENTS_FILE,'nele',FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN OFFLINE SEDIMENT HYDRAULIC FORCING FILE OBJECT",& & "FILE NAME: "//TRIM(OFFLINE_SEDIMENT_FILE),& & "COULD NOT FIND DIMENSION 'nele'") if (ngl /= dim%dim) CALL FATAL_ERROR& &("Offline sediment forcing: the number of elements in the file does not match the fvcom grid?") ! SETUP THE ACTUAL VARIABLES USED TO LOAD DATA! ! X-DIRECTION U VELOCITY VAR => FIND_VAR(SEDIMENTS_FILE,"u",FOUND) IF(.not. FOUND) VAR => FIND_VAR(SEDIMENTS_FILE,"U",FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN OFFLINE SEDIMENT HYDRAULIC FORCING FILE OBJECT",& & "FILE NAME: "//TRIM(OFFLINE_SEDIMENT_FILE),& & "COULD NOT FIND VARIABLE 'u' or 'U'") ! MAKE SPACE FOR THE DATA FROM THE FILE SEDIMENTS_U_N => reference_var(var) ALLOCATE(STORAGE_ARR(0:NT,KB), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN OFFLINE FORCING") CALL NC_CONNECT_PVAR(SEDIMENTS_U_N,STORAGE_ARR) NULLIFY(STORAGE_ARR) ! MAKE SPACE FOR THE DATA FROM THE FILE SEDIMENTS_U_P => reference_var(var) ALLOCATE(STORAGE_ARR(0:NT,KB), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN OFFLINE FORCING") CALL NC_CONNECT_PVAR(SEDIMENTS_U_P,STORAGE_ARR) NULLIFY(STORAGE_ARR) ! Y-DIRECTION V VELOCITY VAR => FIND_VAR(SEDIMENTS_FILE,"v",FOUND) IF(.not. FOUND) VAR => FIND_VAR(SEDIMENTS_FILE,"V",FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN OFFLINE SEDIMENT HYDRAULIC FORCING FILE OBJECT",& & "FILE NAME: "//TRIM(OFFLINE_SEDIMENT_FILE),& & "COULD NOT FIND VARIABLE 'v' or 'V'") ! MAKE SPACE FOR THE DATA FROM THE FILE SEDIMENTS_V_N => reference_var(var) ALLOCATE(STORAGE_ARR(0:NT,KB), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN OFFLINE FORCING") CALL NC_CONNECT_PVAR(SEDIMENTS_V_N,STORAGE_ARR) NULLIFY(STORAGE_ARR) ! MAKE SPACE FOR THE DATA FROM THE FILE SEDIMENTS_V_P => reference_var(var) ALLOCATE(STORAGE_ARR(0:NT,KB), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN OFFLINE FORCING") CALL NC_CONNECT_PVAR(SEDIMENTS_V_P,STORAGE_ARR) NULLIFY(STORAGE_ARR) ! Z-DIRECTION W VELOCITY VAR => FIND_VAR(SEDIMENTS_FILE,"omega",FOUND) IF(.not. FOUND) VAR => FIND_VAR(SEDIMENTS_FILE,"ww",FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN OFFLINE SEDIMENT HYDRAULIC FORCING FILE OBJECT",& & "FILE NAME: "//TRIM(OFFLINE_SEDIMENT_FILE),& & "COULD NOT FIND VARIABLE 'omega' or 'ww'") ! MAKE SPACE FOR THE DATA FROM THE FILE SEDIMENTS_W_N => reference_var(var) ALLOCATE(STORAGE_ARR(0:MT,KB), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN OFFLINE FORCING") CALL NC_CONNECT_PVAR(SEDIMENTS_W_N,STORAGE_ARR) NULLIFY(STORAGE_ARR) ! MAKE SPACE FOR THE DATA FROM THE FILE SEDIMENTS_W_P => reference_var(var) ALLOCATE(STORAGE_ARR(0:MT,KB), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN OFFLINE FORCING") CALL NC_CONNECT_PVAR(SEDIMENTS_W_P,STORAGE_ARR) NULLIFY(STORAGE_ARR) ! SALINITY VAR => FIND_VAR(SEDIMENTS_FILE,"salinity",FOUND) IF(.not. FOUND) VAR => FIND_VAR(SEDIMENTS_FILE,"s1",FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN OFFLINE SEDIMENT HYDRAULIC FORCING FILE OBJECT",& & "FILE NAME: "//TRIM(OFFLINE_SEDIMENT_FILE),& & "COULD NOT FIND VARIABLE 'salinity' or 's1'") ! MAKE SPACE FOR THE DATA FROM THE FILE SEDIMENTS_S1_N => reference_var(var) ALLOCATE(STORAGE_ARR(0:MT,KB), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN OFFLINE FORCING") CALL NC_CONNECT_PVAR(SEDIMENTS_S1_N,STORAGE_ARR) NULLIFY(STORAGE_ARR) ! MAKE SPACE FOR THE DATA FROM THE FILE SEDIMENTS_S1_P => reference_var(var) ALLOCATE(STORAGE_ARR(0:MT,KB), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN OFFLINE FORCING") CALL NC_CONNECT_PVAR(SEDIMENTS_S1_P,STORAGE_ARR) NULLIFY(STORAGE_ARR) ! TEMPERATURE VAR => FIND_VAR(SEDIMENTS_FILE,"temp",FOUND) IF(.not. FOUND) VAR => FIND_VAR(SEDIMENTS_FILE,"t1",FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN OFFLINE SEDIMENT HYDRAULIC FORCING FILE OBJECT",& & "FILE NAME: "//TRIM(OFFLINE_SEDIMENT_FILE),& & "COULD NOT FIND VARIABLE 'temp' or 't1'") ! MAKE SPACE FOR THE DATA FROM THE FILE SEDIMENTS_T1_N => reference_var(var) ALLOCATE(STORAGE_ARR(0:MT,KB), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN OFFLINE FORCING") CALL NC_CONNECT_PVAR(SEDIMENTS_T1_N,STORAGE_ARR) NULLIFY(STORAGE_ARR) ! MAKE SPACE FOR THE DATA FROM THE FILE SEDIMENTS_T1_P => reference_var(var) ALLOCATE(STORAGE_ARR(0:MT,KB), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN OFFLINE FORCING") CALL NC_CONNECT_PVAR(SEDIMENTS_T1_P,STORAGE_ARR) NULLIFY(STORAGE_ARR) ! EL OF OFFLINE FORCING VAR => FIND_VAR(SEDIMENTS_FILE,"zeta",FOUND) IF(.not. FOUND) VAR => FIND_VAR(SEDIMENTS_FILE,"el",FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN OFFLINE SEDIMENT HYDRAULIC FORCING FILE OBJECT",& & "FILE NAME: "//TRIM(OFFLINE_SEDIMENT_FILE),& & "COULD NOT FIND VARIABLE 'zeta' or 'el'") ! MAKE SPACE FOR THE DATA FROM THE FILE SEDIMENTS_EL_N => reference_var(var) ALLOCATE(STORAGE_VEC(0:MT), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN OFFLINE FORCING") CALL NC_CONNECT_PVAR(SEDIMENTS_EL_N,STORAGE_VEC) NULLIFY(STORAGE_VEC) ! MAKE SPACE FOR THE DATA FROM THE FILE SEDIMENTS_EL_P => reference_var(var) ALLOCATE(STORAGE_VEC(0:MT), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN OFFLINE FORCING") CALL NC_CONNECT_PVAR(SEDIMENTS_EL_P,STORAGE_VEC) NULLIFY(STORAGE_VEC) ! KH OF OFFLINE FORCING VAR => FIND_VAR(SEDIMENTS_FILE,"kh",FOUND) IF(.not. FOUND) VAR => FIND_VAR(SEDIMENTS_FILE,"KH",FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN OFFLINE SEDIMENT HYDRAULIC FORCING FILE OBJECT",& & "FILE NAME: "//TRIM(OFFLINE_SEDIMENT_FILE),& & "COULD NOT FIND VARIABLE 'KH' or 'kh'") ! MAKE SPACE FOR THE DATA FROM THE FILE SEDIMENTS_KH_N => reference_var(var) ALLOCATE(STORAGE_ARR(0:MT,KB), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN OFFLINE FORCING") CALL NC_CONNECT_PVAR(SEDIMENTS_KH_N,STORAGE_ARR) NULLIFY(STORAGE_ARR) ! MAKE SPACE FOR THE DATA FROM THE FILE SEDIMENTS_KH_P => reference_var(var) ALLOCATE(STORAGE_ARR(0:MT,KB), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN OFFLINE FORCING") CALL NC_CONNECT_PVAR(SEDIMENTS_KH_P,STORAGE_ARR) NULLIFY(STORAGE_ARR) # if defined (GOTM) ! TEPS OF OFFLINE FORCING VAR => FIND_VAR(SEDIMENTS_FILE,"teps",FOUND) IF(.not. FOUND) VAR => FIND_VAR(SEDIMENTS_FILE,"TEPS",FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN OFFLINE SEDIMENT HYDRAULIC FORCING FILE OBJECT",& & "FILE NAME: "//TRIM(OFFLINE_SEDIMENT_FILE),& & "COULD NOT FIND VARIABLE 'teps' or 'TEPS'") ! MAKE SPACE FOR THE DATA FROM THE FILE SEDIMENTS_TEPS_N => reference_var(var) ALLOCATE(STORAGE_ARR(0:MT,KB), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN OFFLINE FORCING") CALL NC_CONNECT_PVAR(SEDIMENTS_TEPS_N,STORAGE_ARR) NULLIFY(STORAGE_ARR) ! MAKE SPACE FOR THE DATA FROM THE FILE SEDIMENTS_TEPS_P => reference_var(var) ALLOCATE(STORAGE_ARR(0:MT,KB), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN OFFLINE FORCING") CALL NC_CONNECT_PVAR(SEDIMENTS_TEPS_P,STORAGE_ARR) NULLIFY(STORAGE_ARR) # else ! Q2 OF OFFLINE FORCING VAR => FIND_VAR(SEDIMENTS_FILE,"q2",FOUND) IF(.not. FOUND) VAR => FIND_VAR(SEDIMENTS_FILE,"Q2",FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN OFFLINE SEDIMENT HYDRAULIC FORCING FILE OBJECT",& & "FILE NAME: "//TRIM(OFFLINE_SEDIMENT_FILE),& & "COULD NOT FIND VARIABLE 'q2' or 'Q2'") ! MAKE SPACE FOR THE DATA FROM THE FILE SEDIMENTS_Q2_N => reference_var(var) ALLOCATE(STORAGE_ARR(0:MT,KB), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN OFFLINE FORCING") CALL NC_CONNECT_PVAR(SEDIMENTS_Q2_N,STORAGE_ARR) NULLIFY(STORAGE_ARR) ! MAKE SPACE FOR THE DATA FROM THE FILE SEDIMENTS_Q2_P => reference_var(var) ALLOCATE(STORAGE_ARR(0:MT,KB), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN OFFLINE FORCING") CALL NC_CONNECT_PVAR(SEDIMENTS_Q2_P,STORAGE_ARR) NULLIFY(STORAGE_ARR) ! Q2L OF OFFLINE FORCING VAR => FIND_VAR(SEDIMENTS_FILE,"q2l",FOUND) IF(.not. FOUND) VAR => FIND_VAR(SEDIMENTS_FILE,"Q2L",FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN OFFLINE SEDIMENT HYDRAULIC FORCING FILE OBJECT",& & "FILE NAME: "//TRIM(OFFLINE_SEDIMENT_FILE),& & "COULD NOT FIND VARIABLE 'q2l' or 'Q2L'") ! MAKE SPACE FOR THE DATA FROM THE FILE SEDIMENTS_Q2L_N => reference_var(var) ALLOCATE(STORAGE_ARR(0:MT,KB), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN OFFLINE FORCING") CALL NC_CONNECT_PVAR(SEDIMENTS_Q2L_N,STORAGE_ARR) NULLIFY(STORAGE_ARR) ! MAKE SPACE FOR THE DATA FROM THE FILE SEDIMENTS_Q2L_P => reference_var(var) ALLOCATE(STORAGE_ARR(0:MT,KB), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN OFFLINE FORCING") CALL NC_CONNECT_PVAR(SEDIMENTS_Q2L_P,STORAGE_ARR) NULLIFY(STORAGE_ARR) # endif # if defined (WET_DRY) ! KH OF OFFLINE FORCING VAR => FIND_VAR(SEDIMENTS_FILE,"wet_nodes",FOUND) IF(.not. FOUND) VAR => FIND_VAR(SEDIMENTS_FILE,"wet_nodes",FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN OFFLINE SEDIMENT HYDRAULIC FORCING FILE OBJECT",& & "FILE NAME: "//TRIM(OFFLINE_SEDIMENT_FILE),& & "COULD NOT FIND VARIABLE 'wet_nodes' or 'wet_nodes'") ! MAKE SPACE FOR THE DATA FROM THE FILE SEDIMENTS_WN_N => reference_var(var) ALLOCATE(STORAGE_INT(0:MT), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN OFFLINE FORCING") CALL NC_CONNECT_PVAR(SEDIMENTS_WN_N,STORAGE_INT) NULLIFY(STORAGE_INT) ! MAKE SPACE FOR THE DATA FROM THE FILE SEDIMENTS_WN_P => reference_var(var) ALLOCATE(STORAGE_INT(0:MT), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN OFFLINE FORCING") CALL NC_CONNECT_PVAR(SEDIMENTS_WN_P,STORAGE_INT) NULLIFY(STORAGE_INT) ! KH OF OFFLINE FORCING VAR => FIND_VAR(SEDIMENTS_FILE,"wet_cells",FOUND) IF(.not. FOUND) VAR => FIND_VAR(SEDIMENTS_FILE,"wet_cells",FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN OFFLINE SEDIMENT HYDRAULIC FORCING FILE OBJECT",& & "FILE NAME: "//TRIM(OFFLINE_SEDIMENT_FILE),& & "COULD NOT FIND VARIABLE 'wet_cells' or 'wet_cells'") ! MAKE SPACE FOR THE DATA FROM THE FILE SEDIMENTS_WC_N => reference_var(var) ALLOCATE(STORAGE_INT(0:NT), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN OFFLINE FORCING") CALL NC_CONNECT_PVAR(SEDIMENTS_WC_N,STORAGE_INT) NULLIFY(STORAGE_INT) ! MAKE SPACE FOR THE DATA FROM THE FILE SEDIMENTS_WC_P => reference_var(var) ALLOCATE(STORAGE_INT(0:NT), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN OFFLINE FORCING") CALL NC_CONNECT_PVAR(SEDIMENTS_WC_P,STORAGE_INT) NULLIFY(STORAGE_INT) # endif ! ---------- new: 2016 , april, Karsten Lettmann after Hint by Qi and ayumi.fujisaki@noaa.gov------ ! Initialize some variables ! afm 20150914 ! Need initialization. Otherwise, random values are asigned ! and cause a hanging problem of MPI job in UPDATE_VAR_BRACKET ! This problem reported with Intel15.0.3. SEDIMENTS_U_P%CURR_STKCNT = 0; SEDIMENTS_U_N%CURR_STKCNT = 0 SEDIMENTS_V_P%CURR_STKCNT = 0; SEDIMENTS_V_N%CURR_STKCNT = 0 SEDIMENTS_W_P%CURR_STKCNT = 0; SEDIMENTS_W_N%CURR_STKCNT = 0 SEDIMENTS_S1_P%CURR_STKCNT = 0; SEDIMENTS_S1_N%CURR_STKCNT = 0 SEDIMENTS_EL_P%CURR_STKCNT = 0; SEDIMENTS_EL_N%CURR_STKCNT = 0 SEDIMENTS_KH_P%CURR_STKCNT = 0; SEDIMENTS_KH_N%CURR_STKCNT = 0 # if defined (WET_DRY) SEDIMENTS_WN_P%CURR_STKCNT = 0; SEDIMENTS_WN_N%CURR_STKCNT = 0 SEDIMENTS_WC_P%CURR_STKCNT = 0; SEDIMENTS_WC_N%CURR_STKCNT = 0 # endif ! -------------- end new ---------------------------------------------------------- IF(DBG_SET(DBG_SBR)) write(IPT,*) "END OFFLINE_SEDIMENT_FORCING" END SUBROUTINE OFFLINE_SEDIMENT_FORCING !================================================================ # endif # if defined (OFFLINE_BIOLOGY) !================================================================ !================================================================ SUBROUTINE OFFLINE_BIOLOGY_FORCING IMPLICIT NONE ! SOME NC POINTERS TYPE(NCATT), POINTER :: ATT, ATT_DATE TYPE(NCDIM), POINTER :: DIM TYPE(NCVAR), POINTER :: VAR LOGICAL :: FOUND REAL(SP), POINTER :: STORAGE_ARR(:,:), storage_vec(:) INTEGER , POINTER :: STORAGE_INT(:) TYPE(TIME) :: TIMETEST INTEGER :: LATS, LONS, I, Ntimes INTEGER :: STATUS CHARACTER(len=60) :: xstr, ystr IF(DBG_SET(DBG_SBR)) write(IPT,*) "START OFFLINE_BIOLOGY_FORCING" NULLIFY(ATT,DIM,VAR,STORAGE_ARR,STORAGE_VEC,STORAGE_INT) ! DETERMINE THE VARIABLE FORCING TO LOAD THE DATA BIOLOGY_FILE => FIND_FILE(FILEHEAD,trim(OFFLINE_BIOLOGY_FILE),FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("COULD NOT FIND OFFLINE BIOLOGY HYDRODRAULIC FORCING FILE OBJECT",& & "FILE NAME: "//TRIM(OFFLINE_BIOLOGY_FILE)) ! DETERMINE GRID TYPE BASED ON SOURCE ATTRIBUTE ATT => FIND_ATT(BIOLOGY_FILE,"source",FOUND) IF(.not. FOUND) ATT => FIND_ATT(BIOLOGY_FILE,"Source",FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN OFFLINE BIOLOGY FILE OBJECT",& & "FILE NAME: "//TRIM(OFFLINE_BIOLOGY_FILE),& &"COULD NOT FIND GLOBAL ATTRIBURE: 'source'") IF (ATT%CHR(1)(1:len_trim(wrf2fvcom_source)) ==& & TRIM(wrf2fvcom_source)) THEN BIOLOGY_FORCING_TYPE = BIOLOGY_ARE_WRFGRID ELSE IF (ATT%CHR(1)(1:len_trim(fvcom_grid_source)) ==& & TRIM(fvcom_grid_source)) THEN BIOLOGY_FORCING_TYPE = BIOLOGY_ARE_FVCOMGRID ELSE IF (ATT%CHR(1)(1:len_trim(fvcom_cap_grid_source)) ==& & TRIM(fvcom_cap_grid_source)) THEN BIOLOGY_FORCING_TYPE = BIOLOGY_ARE_FVCOMGRID ELSE IF (ATT%CHR(1)(1:len_trim(wrf_grid_source)) ==& & TRIM(wrf_grid_source)) THEN BIOLOGY_FORCING_TYPE = BIOLOGY_ARE_WRFGRID ELSE IF (ATT%CHR(1)(1:5)=='fvcom'.or.ATT%CHR(1)(1:5)=='FVCOM')THEN BIOLOGY_FORCING_TYPE = BIOLOGY_ARE_FVCOMGRID ELSE CALL PRINT_FILE(BIOLOGY_FILE) CALL FATAL_ERROR("CAN NOT RECOGNIZE OFFLINE BIOLOGY FILE!",& & "UNKNOWN SOURCE STRING:",TRIM(ATT%CHR(1))) END IF ! GOT GRID TYPE ALLOCATE(BIOLOGY_FORCING_COMMENTS(4)) BIOLOGY_FORCING_COMMENTS(1) = "FVCOM variable offline sedimen& &t hydraulic forcing:" BIOLOGY_FORCING_COMMENTS(2) = "FILE NAME:"//TRIM(OFFLINE_BIOLOGY_FILE) BIOLOGY_FORCING_COMMENTS(3) = "SOURCE:"//TRIM(ATT%CHR(1)) ATT_DATE => FIND_ATT(BIOLOGY_FILE,"START_DATE",FOUND) IF (FOUND) THEN BIOLOGY_FORCING_COMMENTS(4) ="MET DATA START DATE:"//TRIM(ATT_DATE%CHR(1)) ELSE BIOLOGY_FORCING_COMMENTS(4) = "Unknown start date meta data format" END IF ! LOOK FOR THE DIMENSIONS DIM => FIND_UNLIMITED(BIOLOGY_FILE,FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN OFFLINE BIOLOGY HYDRAULIC FORCING FILE OBJECT",& & "FILE NAME: "//TRIM(OFFLINE_BIOLOGY_FILE),& &"COULD NOT FIND THE UNLIMITED DIMENSION") NTIMES = DIM%DIM ! CHECK THE FILE TIME AND COMPARE WITH MODEL RUN TIME TIMETEST = get_file_time(BIOLOGY_FILE,1) IF(TIMETEST > STARTTIME) CALL FATAL_ERROR & & ("IN OFFLINE BIOLOGY HYDRAULIC FORCING FILE OBJECT",& & "FILE NAME: "//TRIM(OFFLINE_BIOLOGY_FILE),& &"THE MODEL RUN STARTS BEFORE THE FORCING TIME SERIES") TIMETEST = get_file_time(BIOLOGY_FILE,ntimes) IF(TIMETEST < ENDTIME) CALL FATAL_ERROR & & ("IN OFFLINE BIOLOGY HYDRAULIC FORCING FILE OBJECT",& & "FILE NAME: "//TRIM(OFFLINE_BIOLOGY_FILE),& &"THE MODEL RUN ENDS AFTER THE FORCING TIME SERIES") !----------------------------------------------------------------! !--SET THE DATA TYPE OF FVCOM FORMAT ! !----------------------------------------------------------------! IF(DBG_SET(DBG_LOG)) WRITE(IPT,*) & & "! SETTING UP OFFLINE BIOLOGY HYDRAULIC FORCING FROM A 'FVCOM GRID' FILE" DIM => FIND_DIM(BIOLOGY_FILE,'node',FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN OFFLINE BIOLOGY HYDRAULIC FORCING FILE OBJECT",& & "FILE NAME: "//TRIM(OFFLINE_BIOLOGY_FILE),& & "COULD NOT FIND DIMENSION 'node'") if (mgl /= dim%dim) CALL FATAL_ERROR& &("Offline biology forcing: the number of nodes in the file does not match the fvcom grid?") DIM => FIND_DIM(BIOLOGY_FILE,'nele',FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN OFFLINE BIOLOGY HYDRAULIC FORCING FILE OBJECT",& & "FILE NAME: "//TRIM(OFFLINE_BIOLOGY_FILE),& & "COULD NOT FIND DIMENSION 'nele'") if (ngl /= dim%dim) CALL FATAL_ERROR& &("Offline biology forcing: the number of elements in the file does not match the fvcom grid?") ! SETUP THE ACTUAL VARIABLES USED TO LOAD DATA! ! X-DIRECTION U VELOCITY VAR => FIND_VAR(BIOLOGY_FILE,"u",FOUND) IF(.not. FOUND) VAR => FIND_VAR(BIOLOGY_FILE,"U",FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN OFFLINE BIOLOGY HYDRAULIC FORCING FILE OBJECT",& & "FILE NAME: "//TRIM(OFFLINE_BIOLOGY_FILE),& & "COULD NOT FIND VARIABLE 'u' or 'U'") ! MAKE SPACE FOR THE DATA FROM THE FILE BIOLOGY_U_N => reference_var(var) ALLOCATE(STORAGE_ARR(0:NT,KB), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN OFFLINE FORCING") CALL NC_CONNECT_PVAR(BIOLOGY_U_N,STORAGE_ARR) NULLIFY(STORAGE_ARR) ! MAKE SPACE FOR THE DATA FROM THE FILE BIOLOGY_U_P => reference_var(var) ALLOCATE(STORAGE_ARR(0:NT,KB), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN OFFLINE FORCING") CALL NC_CONNECT_PVAR(BIOLOGY_U_P,STORAGE_ARR) NULLIFY(STORAGE_ARR) ! Y-DIRECTION V VELOCITY VAR => FIND_VAR(BIOLOGY_FILE,"v",FOUND) IF(.not. FOUND) VAR => FIND_VAR(BIOLOGY_FILE,"V",FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN OFFLINE BIOLOGY HYDRAULIC FORCING FILE OBJECT",& & "FILE NAME: "//TRIM(OFFLINE_BIOLOGY_FILE),& & "COULD NOT FIND VARIABLE 'v' or 'V'") ! MAKE SPACE FOR THE DATA FROM THE FILE BIOLOGY_V_N => reference_var(var) ALLOCATE(STORAGE_ARR(0:NT,KB), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN OFFLINE FORCING") CALL NC_CONNECT_PVAR(BIOLOGY_V_N,STORAGE_ARR) NULLIFY(STORAGE_ARR) ! MAKE SPACE FOR THE DATA FROM THE FILE BIOLOGY_V_P => reference_var(var) ALLOCATE(STORAGE_ARR(0:NT,KB), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN OFFLINE FORCING") CALL NC_CONNECT_PVAR(BIOLOGY_V_P,STORAGE_ARR) NULLIFY(STORAGE_ARR) ! Z-DIRECTION W VELOCITY VAR => FIND_VAR(BIOLOGY_FILE,"omega",FOUND) IF(.not. FOUND) VAR => FIND_VAR(BIOLOGY_FILE,"ww",FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN OFFLINE BIOLOGY HYDRAULIC FORCING FILE OBJECT",& & "FILE NAME: "//TRIM(OFFLINE_BIOLOGY_FILE),& & "COULD NOT FIND VARIABLE 'omega' or 'ww'") ! MAKE SPACE FOR THE DATA FROM THE FILE BIOLOGY_W_N => reference_var(var) ALLOCATE(STORAGE_ARR(0:MT,KB), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN OFFLINE FORCING") CALL NC_CONNECT_PVAR(BIOLOGY_W_N,STORAGE_ARR) NULLIFY(STORAGE_ARR) ! MAKE SPACE FOR THE DATA FROM THE FILE BIOLOGY_W_P => reference_var(var) ALLOCATE(STORAGE_ARR(0:MT,KB), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN OFFLINE FORCING") CALL NC_CONNECT_PVAR(BIOLOGY_W_P,STORAGE_ARR) NULLIFY(STORAGE_ARR) ! SALINITY VAR => FIND_VAR(BIOLOGY_FILE,"salinity",FOUND) IF(.not. FOUND) VAR => FIND_VAR(BIOLOGY_FILE,"s1",FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN OFFLINE BIOLOGY HYDRAULIC FORCING FILE OBJECT",& & "FILE NAME: "//TRIM(OFFLINE_BIOLOGY_FILE),& & "COULD NOT FIND VARIABLE 'salinity' or 's1'") ! MAKE SPACE FOR THE DATA FROM THE FILE BIOLOGY_S1_N => reference_var(var) ALLOCATE(STORAGE_ARR(0:MT,KB), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN OFFLINE FORCING") CALL NC_CONNECT_PVAR(BIOLOGY_S1_N,STORAGE_ARR) NULLIFY(STORAGE_ARR) ! MAKE SPACE FOR THE DATA FROM THE FILE BIOLOGY_S1_P => reference_var(var) ALLOCATE(STORAGE_ARR(0:MT,KB), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN OFFLINE FORCING") CALL NC_CONNECT_PVAR(BIOLOGY_S1_P,STORAGE_ARR) NULLIFY(STORAGE_ARR) ! TEMPERATURE VAR => FIND_VAR(BIOLOGY_FILE,"temp",FOUND) IF(.not. FOUND) VAR => FIND_VAR(BIOLOGY_FILE,"t1",FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN OFFLINE BIOLOGY HYDRAULIC FORCING FILE OBJECT",& & "FILE NAME: "//TRIM(OFFLINE_BIOLOGY_FILE),& & "COULD NOT FIND VARIABLE 'temp' or 't1'") ! MAKE SPACE FOR THE DATA FROM THE FILE BIOLOGY_T1_N => reference_var(var) ALLOCATE(STORAGE_ARR(0:MT,KB), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN OFFLINE FORCING") CALL NC_CONNECT_PVAR(BIOLOGY_T1_N,STORAGE_ARR) NULLIFY(STORAGE_ARR) ! MAKE SPACE FOR THE DATA FROM THE FILE BIOLOGY_T1_P => reference_var(var) ALLOCATE(STORAGE_ARR(0:MT,KB), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN OFFLINE FORCING") CALL NC_CONNECT_PVAR(BIOLOGY_T1_P,STORAGE_ARR) NULLIFY(STORAGE_ARR) ! EL OF OFFLINE FORCING VAR => FIND_VAR(BIOLOGY_FILE,"zeta",FOUND) IF(.not. FOUND) VAR => FIND_VAR(BIOLOGY_FILE,"el",FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN OFFLINE BIOLOGY HYDRAULIC FORCING FILE OBJECT",& & "FILE NAME: "//TRIM(OFFLINE_BIOLOGY_FILE),& & "COULD NOT FIND VARIABLE 'zeta' or 'el'") ! MAKE SPACE FOR THE DATA FROM THE FILE BIOLOGY_EL_N => reference_var(var) ALLOCATE(STORAGE_VEC(0:MT), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN OFFLINE FORCING") CALL NC_CONNECT_PVAR(BIOLOGY_EL_N,STORAGE_VEC) NULLIFY(STORAGE_VEC) ! MAKE SPACE FOR THE DATA FROM THE FILE BIOLOGY_EL_P => reference_var(var) ALLOCATE(STORAGE_VEC(0:MT), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN OFFLINE FORCING") CALL NC_CONNECT_PVAR(BIOLOGY_EL_P,STORAGE_VEC) NULLIFY(STORAGE_VEC) ! KH OF OFFLINE FORCING VAR => FIND_VAR(BIOLOGY_FILE,"kh",FOUND) IF(.not. FOUND) VAR => FIND_VAR(BIOLOGY_FILE,"KH",FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN OFFLINE BIOLOGY HYDRAULIC FORCING FILE OBJECT",& & "FILE NAME: "//TRIM(OFFLINE_BIOLOGY_FILE),& & "COULD NOT FIND VARIABLE 'KH' or 'kh'") ! MAKE SPACE FOR THE DATA FROM THE FILE BIOLOGY_KH_N => reference_var(var) ALLOCATE(STORAGE_ARR(0:MT,KB), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN OFFLINE FORCING") CALL NC_CONNECT_PVAR(BIOLOGY_KH_N,STORAGE_ARR) NULLIFY(STORAGE_ARR) ! MAKE SPACE FOR THE DATA FROM THE FILE BIOLOGY_KH_P => reference_var(var) ALLOCATE(STORAGE_ARR(0:MT,KB), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN OFFLINE FORCING") CALL NC_CONNECT_PVAR(BIOLOGY_KH_P,STORAGE_ARR) NULLIFY(STORAGE_ARR) # if defined (GOTM) ! TEPS OF OFFLINE FORCING VAR => FIND_VAR(BIOLOGY_FILE,"teps",FOUND) IF(.not. FOUND) VAR => FIND_VAR(BIOLOGY_FILE,"TEPS",FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN OFFLINE BIOLOGY HYDRAULIC FORCING FILE OBJECT",& & "FILE NAME: "//TRIM(OFFLINE_BIOLOGY_FILE),& & "COULD NOT FIND VARIABLE 'teps' or 'TEPS'") ! MAKE SPACE FOR THE DATA FROM THE FILE BIOLOGY_TEPS_N => reference_var(var) ALLOCATE(STORAGE_ARR(0:MT,KB), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN OFFLINE FORCING") CALL NC_CONNECT_PVAR(BIOLOGY_TEPS_N,STORAGE_ARR) NULLIFY(STORAGE_ARR) ! MAKE SPACE FOR THE DATA FROM THE FILE BIOLOGY_TEPS_P => reference_var(var) ALLOCATE(STORAGE_ARR(0:MT,KB), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN OFFLINE FORCING") CALL NC_CONNECT_PVAR(BIOLOGY_TEPS_P,STORAGE_ARR) NULLIFY(STORAGE_ARR) # else ! Q2 OF OFFLINE FORCING VAR => FIND_VAR(BIOLOGY_FILE,"q2",FOUND) IF(.not. FOUND) VAR => FIND_VAR(BIOLOGY_FILE,"Q2",FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN OFFLINE BIOLOGY HYDRAULIC FORCING FILE OBJECT",& & "FILE NAME: "//TRIM(OFFLINE_BIOLOGY_FILE),& & "COULD NOT FIND VARIABLE 'q2' or 'Q2'") ! MAKE SPACE FOR THE DATA FROM THE FILE BIOLOGY_Q2_N => reference_var(var) ALLOCATE(STORAGE_ARR(0:MT,KB), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN OFFLINE FORCING") CALL NC_CONNECT_PVAR(BIOLOGY_Q2_N,STORAGE_ARR) NULLIFY(STORAGE_ARR) ! MAKE SPACE FOR THE DATA FROM THE FILE BIOLOGY_Q2_P => reference_var(var) ALLOCATE(STORAGE_ARR(0:MT,KB), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN OFFLINE FORCING") CALL NC_CONNECT_PVAR(BIOLOGY_Q2_P,STORAGE_ARR) NULLIFY(STORAGE_ARR) ! Q2L OF OFFLINE FORCING VAR => FIND_VAR(BIOLOGY_FILE,"q2l",FOUND) IF(.not. FOUND) VAR => FIND_VAR(BIOLOGY_FILE,"Q2L",FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN OFFLINE BIOLOGY HYDRAULIC FORCING FILE OBJECT",& & "FILE NAME: "//TRIM(OFFLINE_BIOLOGY_FILE),& & "COULD NOT FIND VARIABLE 'q2l' or 'Q2L'") ! MAKE SPACE FOR THE DATA FROM THE FILE BIOLOGY_Q2L_N => reference_var(var) ALLOCATE(STORAGE_ARR(0:MT,KB), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN OFFLINE FORCING") CALL NC_CONNECT_PVAR(BIOLOGY_Q2L_N,STORAGE_ARR) NULLIFY(STORAGE_ARR) ! MAKE SPACE FOR THE DATA FROM THE FILE BIOLOGY_Q2L_P => reference_var(var) ALLOCATE(STORAGE_ARR(0:MT,KB), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN OFFLINE FORCING") CALL NC_CONNECT_PVAR(BIOLOGY_Q2L_P,STORAGE_ARR) NULLIFY(STORAGE_ARR) # endif # if defined (WET_DRY) ! KH OF OFFLINE FORCING VAR => FIND_VAR(BIOLOGY_FILE,"wet_nodes",FOUND) IF(.not. FOUND) VAR => FIND_VAR(BIOLOGY_FILE,"wet_nodes",FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN OFFLINE BIOLOGY HYDRAULIC FORCING FILE OBJECT",& & "FILE NAME: "//TRIM(OFFLINE_BIOLOGY_FILE),& & "COULD NOT FIND VARIABLE 'wet_nodes' or 'wet_nodes'") ! MAKE SPACE FOR THE DATA FROM THE FILE BIOLOGY_WN_N => reference_var(var) ALLOCATE(STORAGE_INT(0:MT), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN OFFLINE FORCING") CALL NC_CONNECT_PVAR(BIOLOGY_WN_N,STORAGE_INT) NULLIFY(STORAGE_INT) ! MAKE SPACE FOR THE DATA FROM THE FILE BIOLOGY_WN_P => reference_var(var) ALLOCATE(STORAGE_INT(0:MT), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN OFFLINE FORCING") CALL NC_CONNECT_PVAR(BIOLOGY_WN_P,STORAGE_INT) NULLIFY(STORAGE_INT) ! KH OF OFFLINE FORCING VAR => FIND_VAR(BIOLOGY_FILE,"wet_cells",FOUND) IF(.not. FOUND) VAR => FIND_VAR(BIOLOGY_FILE,"wet_cells",FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN OFFLINE BIOLOGY HYDRAULIC FORCING FILE OBJECT",& & "FILE NAME: "//TRIM(OFFLINE_BIOLOGY_FILE),& & "COULD NOT FIND VARIABLE 'wet_cells' or 'wet_cells'") ! MAKE SPACE FOR THE DATA FROM THE FILE BIOLOGY_WC_N => reference_var(var) ALLOCATE(STORAGE_INT(0:NT), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN OFFLINE FORCING") CALL NC_CONNECT_PVAR(BIOLOGY_WC_N,STORAGE_INT) NULLIFY(STORAGE_INT) ! MAKE SPACE FOR THE DATA FROM THE FILE BIOLOGY_WC_P => reference_var(var) ALLOCATE(STORAGE_INT(0:NT), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN OFFLINE FORCING") CALL NC_CONNECT_PVAR(BIOLOGY_WC_P,STORAGE_INT) NULLIFY(STORAGE_INT) # endif IF(DBG_SET(DBG_SBR)) write(IPT,*) "END OFFLINE_BIOLOGY_FORCING" END SUBROUTINE OFFLINE_BIOLOGY_FORCING !================================================================ # endif !================================================================ SUBROUTINE SURFACE_WAVE IMPLICIT NONE ! SOME NC POINTERS TYPE(NCATT), POINTER :: ATT, ATT_DATE TYPE(NCDIM), POINTER :: DIM TYPE(NCVAR), POINTER :: VAR LOGICAL :: FOUND REAL(SP), POINTER :: STORAGE_ARR(:,:), storage_vec(:) TYPE(TIME) :: TIMETEST INTEGER :: LATS, LONS, I, Ntimes INTEGER :: STATUS CHARACTER(len=60) :: w_hs, w_len,w_dir,w_per,w_per_bot,w_ub_bot IF(DBG_SET(DBG_SBR)) write(IPT,*) "START SURFACE_WAVE" NULLIFY(ATT,DIM,VAR,STORAGE_ARR,STORAGE_VEC) IF (.NOT. WAVE_ON ) THEN IF(DBG_SET(DBG_LOG)) write(IPT,*) "! SURFACE WAVE FORCING IS OFF!" ALLOCATE(WAVES_FORCING_COMMENTS(1)) WAVES_FORCING_COMMENTS(1) = "SURFACE WAVE FORCING IS OFF" RETURN END IF ! DETERMINE HOW TO LOAD THE DATA SELECT CASE(WAVE_KIND) CASE (CNSTNT) write(w_hs, '(f8.4)') WAVE_HEIGHT write(w_len, '(f8.4)') WAVE_LENGTH write(w_dir, '(f8.4)') WAVE_DIRECTION write(w_per, '(f8.4)') WAVE_PERIOD write(w_per_bot,'(f8.4)') WAVE_PER_BOT write(w_ub_bot, '(f8.4)') WAVE_UB_BOT IF(DBG_SET(DBG_LOG)) THEN WRITE(IPT,*)"! SETTING UP CONSTANT SURFACE WAVE FORCING: " WRITE(IPT,*)" wave height : "//trim(w_hs) WRITE(IPT,*)" wave length : "//trim(w_len) WRITE(IPT,*)" wave direction: "//trim(w_dir) WRITE(IPT,*)" wave period : "//trim(w_per) WRITE(IPT,*)" wave per_bot : "//trim(w_per_bot) WRITE(IPT,*)" wave ub_bot : "//trim(w_ub_bot) END IF ALLOCATE(WAVES_FORCING_COMMENTS(7)) WAVES_FORCING_COMMENTS(1) = "Using constant surface wave from run file:" WAVES_FORCING_COMMENTS(2) = " wave height : "//trim(w_hs) WAVES_FORCING_COMMENTS(3) = " wave length : "//trim(w_len) WAVES_FORCING_COMMENTS(4) = " wave direction: "//trim(w_dir) WAVES_FORCING_COMMENTS(5) = " wave period : "//trim(w_per) WAVES_FORCING_COMMENTS(6) = " wave per_bot : "//trim(w_per_bot) WAVES_FORCING_COMMENTS(7) = " wave ub_bot : "//trim(w_ub_bot) RETURN CASE(STTC) CALL FATAL_ERROR("STATIC WAVE Not Set Up Yet") CASE(TMDPNDNT) CALL FATAL_ERROR("TIME DEPENDANT WAVE Not Set Up Yet") CASE(PRDC) WAVES_FILE => FIND_FILE(FILEHEAD,trim(WAVE_FILE),FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("COULD NOT FIND SURFACE WAVE BOUNDARY CONDINTION FILE OBJECT",& & "FILE NAME: "//TRIM(WAVE_FILE)) ! DETERMINE GRID TYPE BASED ON SOURCE ATTRIBUTE ATT => FIND_ATT(WAVES_FILE,"source",FOUND) IF(.not. FOUND) ATT => FIND_ATT(WAVES_FILE,"Source",FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN SURFACE WAVE BOUNDARY CONDITION FILE OBJECT",& & "FILE NAME: "//TRIM(WAVE_FILE),& &"COULD NOT FIND GLOBAL ATTRIBURE: 'source'") IF (ATT%CHR(1)(1:len_trim(wrf2fvcom_source)) ==& & TRIM(wrf2fvcom_source)) THEN WAVES_FORCING_TYPE = WAVES_ARE_WRFGRID ELSE IF (ATT%CHR(1)(1:len_trim(fvcom_grid_source)) ==& & TRIM(fvcom_grid_source)) THEN WAVES_FORCING_TYPE = WAVES_ARE_FVCOMGRID ELSE IF (ATT%CHR(1)(1:len_trim(fvcom_cap_grid_source)) ==& & TRIM(fvcom_cap_grid_source)) THEN WAVES_FORCING_TYPE = WAVES_ARE_FVCOMGRID ELSE IF (ATT%CHR(1)(1:len_trim(wrf_grid_source)) ==& & TRIM(wrf_grid_source)) THEN WAVES_FORCING_TYPE = WAVES_ARE_WRFGRID ELSE CALL PRINT_FILE(WAVES_FILE) CALL FATAL_ERROR("CAN NOT RECOGNIZE WAVE FILE!",& & "UNKNOWN SOURCE STRING:",TRIM(ATT%CHR(1))) END IF ! GOT GRID TYPE ALLOCATE(WAVES_FORCING_COMMENTS(4)) WAVES_FORCING_COMMENTS(1) = "FVCOM periodic surface wave forcing:" WAVES_FORCING_COMMENTS(2) = "FILE NAME:"//TRIM(WAVE_FILE) WAVES_FORCING_COMMENTS(3) = "SOURCE:"//TRIM(ATT%CHR(1)) ATT_DATE => FIND_ATT(WAVES_FILE,"START_DATE",FOUND) IF (FOUND) THEN WAVES_FORCING_COMMENTS(4) ="MET DATA START DATE:"//TRIM(ATT_DATE%CHR(1)) ELSE WAVES_FORCING_COMMENTS(4) = "Unknown start date meta data format" END IF ! GET THE FILES LENGTH OF TIME AND SAVE FOR PERIODIC FORCING ! LOOK FOR THE DIMENSIONS DIM => FIND_UNLIMITED(WAVES_FILE,FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN SURFACE WAVE BOUNDARY CONDITION FILE OBJECT",& & "FILE NAME: "//TRIM(WAVE_FILE),& &"COULD NOT FIND THE UNLMITIED DIMENSION") NTIMES = DIM%DIM WAVES_PERIOD = get_file_time(WAVES_FILE,ntimes) WAVES_PERIOD = WAVES_PERIOD - get_file_time(WAVES_FILE,1) IF (WAVES_PERIOD /= get_file_time(WAVES_FILE,ntimes)) THEN CALL PRINT_REAL_TIME(get_file_time(WAVES_FILE,1),IPT,"FIRST FILE TIME",TIMEZONE) CALL PRINT_REAL_TIME(get_file_time(WAVES_FILE,ntimes),IPT,"LAST FILE TIME",TIMEZONE) CALL FATAL_ERROR& &("TO USE PERIODIC FORCING THE FILE TIME MUST COUNT FROM ZERO",& & "THE DIFFERENCE BETWEEN THE CURRENT MODEL TIME AND THE START TIME,",& & "MODULO THE FORCING PERIOD, DETERMINES THE CURRENT FORCING") END IF IF(DBG_SET(DBG_LOG)) THEN WRITE(IPT,*) "! USING PERIODIC WAVE FORCING:" CALL PRINT_TIME(WAVES_PERIOD,IPT,"PERIOD") END IF CASE(VRBL) WAVES_FILE => FIND_FILE(FILEHEAD,trim(WAVE_FILE),FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("COULD NOT FIND SURFACE WAVE BOUNDARY CONDINTION FILE OBJECT",& & "FILE NAME: "//TRIM(WAVE_FILE)) ! DETERMINE GRID TYPE BASED ON SOURCE ATTRIBUTE ATT => FIND_ATT(WAVES_FILE,"source",FOUND) IF(.not. FOUND) ATT => FIND_ATT(WAVES_FILE,"Source",FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN SURFACE WAVE BOUNDARY CONDITION FILE OBJECT",& & "FILE NAME: "//TRIM(WAVE_FILE),& &"COULD NOT FIND GLOBAL ATTRIBURE: 'source'") IF (ATT%CHR(1)(1:len_trim(wrf2fvcom_source)) ==& & TRIM(wrf2fvcom_source)) THEN WAVES_FORCING_TYPE = WAVES_ARE_WRFGRID ELSE IF (ATT%CHR(1)(1:len_trim(fvcom_grid_source)) ==& & TRIM(fvcom_grid_source).or.(ATT%CHR(1)(1:5)=='fvcom')) THEN WAVES_FORCING_TYPE = WAVES_ARE_FVCOMGRID ELSE IF (ATT%CHR(1)(1:len_trim(fvcom_cap_grid_source)) ==& & TRIM(fvcom_cap_grid_source).or.(ATT%CHR(1)(1:5)=='FVCOM')) THEN WAVES_FORCING_TYPE = WAVES_ARE_FVCOMGRID ELSE IF (ATT%CHR(1)(1:len_trim(wrf_grid_source)) ==& & TRIM(wrf_grid_source)) THEN WAVES_FORCING_TYPE = WAVES_ARE_WRFGRID ELSE CALL PRINT_FILE(WAVES_FILE) CALL FATAL_ERROR("CAN NOT RECOGNIZE WAVE FILE!",& & "UNKNOWN SOURCE STRING:",TRIM(ATT%CHR(1))) END IF ! GOT GRID TYPE ALLOCATE(WAVES_FORCING_COMMENTS(4)) WAVES_FORCING_COMMENTS(1) = "FVCOM variable surface wave forcing:" WAVES_FORCING_COMMENTS(2) = "FILE NAME:"//TRIM(WAVE_FILE) WAVES_FORCING_COMMENTS(3) = "SOURCE:"//TRIM(ATT%CHR(1)) ATT_DATE => FIND_ATT(WAVES_FILE,"START_DATE",FOUND) IF (FOUND) THEN WAVES_FORCING_COMMENTS(4) ="MET DATA START DATE:"//TRIM(ATT_DATE%CHR(1)) ELSE WAVES_FORCING_COMMENTS(4) = "Unknown start date meta data format" END IF ! LOOK FOR THE DIMENSIONS DIM => FIND_UNLIMITED(WAVES_FILE,FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN SURFACE WAVE BOUNDARY CONDITION FILE OBJECT",& & "FILE NAME: "//TRIM(WAVE_FILE),& &"COULD NOT FIND THE UNLIMITED DIMENSION") NTIMES = DIM%DIM ! CHECK THE FILE TIME AND COMPARE WITH MODEL RUN TIME TIMETEST = get_file_time(WAVES_FILE,1) IF(TIMETEST > STARTTIME) CALL FATAL_ERROR & & ("IN SURFACE WAVE BOUNDARY CONDITION FILE OBJECT",& & "FILE NAME: "//TRIM(WAVE_FILE),& &"THE MODEL RUN STARTS BEFORE THE FORCING TIME SERIES") TIMETEST = get_file_time(WAVES_FILE,ntimes) IF(TIMETEST < ENDTIME) CALL FATAL_ERROR & & ("IN SURFACE WAVE BOUNDARY CONDITION FILE OBJECT",& & "FILE NAME: "//TRIM(WAVE_FILE),& &"THE MODEL RUN ENDS AFTER THE FORCING TIME SERIES") CASE DEFAULT CALL FATAL_ERROR("SURFACE_WAVE: UNKNOWN WAVE KIND?") END SELECT !============================================================== SELECT CASE(WAVES_FORCING_TYPE) !============================================================== CASE(WAVES_ARE_WRFGRID) !============================================================== CALL FATAL_ERROR("WAVE based on WRF grid Not Set Up Yet") !============================================================== CASE(WAVES_ARE_FVCOMGRID) !============================================================== IF(DBG_SET(DBG_LOG)) WRITE(IPT,*) & & "! SETTING UP WAVE FORCING FROM A 'FVCOM GRID' FILE" DIM => FIND_DIM(WAVES_FILE,'node',FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN SURFACE WAVE BOUNDARY CONDITION FILE OBJECT",& & "FILE NAME: "//TRIM(WAVE_FILE),& & "COULD NOT FIND DIMENSION 'node'") if (mgl /= dim%dim) CALL FATAL_ERROR& &("Surface Wave: the number of nodes in the file does not match the fvcom grid?") ! SETUP THE ACTUAL VARIABLES USED TO LOAD DATA! ! WAVE HEIGHT VAR => FIND_VAR(WAVES_FILE,"hs",FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN SURFACE WAVE BOUNDARY CONDITION FILE OBJECT",& & "FILE NAME: "//TRIM(WAVE_FILE),& & "COULD NOT FIND VARIABLE 'hs' ") ! MAKE SPACE FOR THE DATA FROM THE FILE WAVES_HEIGHT_N => reference_var(var) ALLOCATE(STORAGE_VEC(0:MT), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN WAVE HEIGHT") CALL NC_CONNECT_PVAR(WAVES_HEIGHT_N,STORAGE_VEC) NULLIFY(STORAGE_VEC) ! MAKE SPACE FOR THE DATA FROM THE FILE WAVES_HEIGHT_P => reference_var(var) ALLOCATE(STORAGE_VEC(0:MT), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN WAVE HEIGHT") CALL NC_CONNECT_PVAR(WAVES_HEIGHT_P,STORAGE_VEC) NULLIFY(STORAGE_VEC) ! WAVE LENGTH VAR => FIND_VAR(WAVES_FILE,"wlen",FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN SURFACE WAVE BOUNDARY CONDITION FILE OBJECT",& & "FILE NAME: "//TRIM(WAVE_FILE),& & "COULD NOT FIND VARIABLE 'wlen' ") ! MAKE SPACE FOR THE DATA FROM THE FILE WAVES_LENGTH_N => reference_var(var) ALLOCATE(STORAGE_VEC(0:MT), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN WAVE LENGTH") CALL NC_CONNECT_PVAR(WAVES_LENGTH_N,STORAGE_VEC) NULLIFY(STORAGE_VEC) ! MAKE SPACE FOR THE DATA FROM THE FILE WAVES_LENGTH_P => reference_var(var) ALLOCATE(STORAGE_VEC(0:MT), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN WAVE LENGTH") CALL NC_CONNECT_PVAR(WAVES_LENGTH_P,STORAGE_VEC) NULLIFY(STORAGE_VEC) ! WAVE DIRECTION VAR => FIND_VAR(WAVES_FILE,"dirm",FOUND) IF(.not. FOUND) VAR => FIND_VAR(WAVES_FILE,"wdir",FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN SURFACE WAVE BOUNDARY CONDITION FILE OBJECT",& & "FILE NAME: "//TRIM(WAVE_FILE),& & "COULD NOT FIND VARIABLE 'dirm' or 'wdir' ") ! MAKE SPACE FOR THE DATA FROM THE FILE WAVES_DIRECTION_N => reference_var(var) ALLOCATE(STORAGE_VEC(0:MT), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN WAVE DIRECTION") CALL NC_CONNECT_PVAR(WAVES_DIRECTION_N,STORAGE_VEC) NULLIFY(STORAGE_VEC) ! MAKE SPACE FOR THE DATA FROM THE FILE WAVES_DIRECTION_P => reference_var(var) ALLOCATE(STORAGE_VEC(0:MT), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN WAVE DIRECTION") CALL NC_CONNECT_PVAR(WAVES_DIRECTION_P,STORAGE_VEC) NULLIFY(STORAGE_VEC) ! WAVE PERIOD VAR => FIND_VAR(WAVES_FILE,"tpeak",FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN SURFACE WAVE BOUNDARY CONDITION FILE OBJECT",& & "FILE NAME: "//TRIM(WAVE_FILE),& & "COULD NOT FIND VARIABLE 'tpeak' ") ! MAKE SPACE FOR THE DATA FROM THE FILE WAVES_PERIOD_N => reference_var(var) ALLOCATE(STORAGE_VEC(0:MT), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN WAVE PERIOD") CALL NC_CONNECT_PVAR(WAVES_PERIOD_N,STORAGE_VEC) NULLIFY(STORAGE_VEC) ! MAKE SPACE FOR THE DATA FROM THE FILE WAVES_PERIOD_P => reference_var(var) ALLOCATE(STORAGE_VEC(0:MT), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN WAVE PERIOD") CALL NC_CONNECT_PVAR(WAVES_PERIOD_P,STORAGE_VEC) NULLIFY(STORAGE_VEC) ! BOTTOM WAVE PERIOD VAR => FIND_VAR(WAVES_FILE,"pwave_bot",FOUND) IF(.not. FOUND) VAR => FIND_VAR(WAVES_FILE,"tmbot",FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN SURFACE WAVE BOUNDARY CONDITION FILE OBJECT",& & "FILE NAME: "//TRIM(WAVE_FILE),& & "COULD NOT FIND VARIABLE 'pwave_bot' or 'tmbot' ") ! MAKE SPACE FOR THE DATA FROM THE FILE WAVES_PER_BOT_N => reference_var(var) ALLOCATE(STORAGE_VEC(0:MT), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN BOTTOM WAVE PERIOD") CALL NC_CONNECT_PVAR(WAVES_PER_BOT_N,STORAGE_VEC) NULLIFY(STORAGE_VEC) ! MAKE SPACE FOR THE DATA FROM THE FILE WAVES_PER_BOT_P => reference_var(var) ALLOCATE(STORAGE_VEC(0:MT), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN BOTTOM WAVE PERIOD") CALL NC_CONNECT_PVAR(WAVES_PER_BOT_P,STORAGE_VEC) NULLIFY(STORAGE_VEC) ! BOTTOM ORBITAL VELOCITY VAR => FIND_VAR(WAVES_FILE,"ub_bot",FOUND) IF(.not. FOUND) VAR => FIND_VAR(WAVES_FILE,"ubot",FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN SURFACE WAVE BOUNDARY CONDITION FILE OBJECT",& & "FILE NAME: "//TRIM(WAVE_FILE),& & "COULD NOT FIND VARIABLE 'ub_bot' or 'ubot' ") ! MAKE SPACE FOR THE DATA FROM THE FILE WAVES_UB_BOT_N => reference_var(var) ALLOCATE(STORAGE_VEC(0:MT), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN BOTTOM WAVE ORBITAL VELOCITY") CALL NC_CONNECT_PVAR(WAVES_UB_BOT_N,STORAGE_VEC) NULLIFY(STORAGE_VEC) ! MAKE SPACE FOR THE DATA FROM THE FILE WAVES_UB_BOT_P => reference_var(var) ALLOCATE(STORAGE_VEC(0:MT), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN BOTTOM WAVE ORBITAL VELOCITY") CALL NC_CONNECT_PVAR(WAVES_UB_BOT_P,STORAGE_VEC) NULLIFY(STORAGE_VEC) !============================================================== CASE DEFAULT !============================================================== CALL FATAL_ERROR("CAN NOT RECOGNIZE WAVE FILE TYPE!") !============================================================== END SELECT !============================================================== IF(DBG_SET(DBG_SBR)) write(IPT,*) "END SURFACE_WAVE" END SUBROUTINE SURFACE_WAVE !================================================================ !================================================================ SUBROUTINE SURFACE_AIRPRESSURE IMPLICIT NONE ! SOME NC POINTERS TYPE(NCATT), POINTER :: ATT, ATT_DATE TYPE(NCDIM), POINTER :: DIM TYPE(NCVAR), POINTER :: VAR LOGICAL :: FOUND REAL(SP), POINTER :: STORAGE_ARR(:,:), storage_vec(:) TYPE(TIME) :: TIMETEST INTEGER :: LATS, LONS, I, Ntimes INTEGER :: STATUS CHARACTER(len=60) :: airpressurestr IF(DBG_SET(DBG_SBR)) write(IPT,*) "START SURFACE_AIRPRESSURE" NULLIFY(ATT,DIM,VAR,STORAGE_ARR,STORAGE_VEC) IF (.NOT. AIRPRESSURE_ON ) THEN IF(DBG_SET(DBG_LOG)) write(IPT,*) "! SURFACE AIR PRESSURE FORCING IS OFF!" ALLOCATE(AIRPRESSURE_FORCING_COMMENTS(1)) AIRPRESSURE_FORCING_COMMENTS(1) = "SURFACE AIR PRESSURE FORCING IS OFF" RETURN END IF ! DETERMINE HOW TO LOAD THE DATA SELECT CASE(AIRPRESSURE_KIND) CASE (CNSTNT) write(airpressurestr,'(f8.4)') AIRPRESSURE_VALUE IF(DBG_SET(DBG_LOG)) THEN WRITE(IPT,*)"! SETTING UP CONSTANT AIR PRESSURE FORCING: " WRITE(IPT,*)" Air pressure: "//trim(airpressurestr) END IF ALLOCATE(AIRPRESSURE_FORCING_COMMENTS(3)) AIRPRESSURE_FORCING_COMMENTS(1) = "Using constant air pressure from run file:" AIRPRESSURE_FORCING_COMMENTS(2) = "Air pressure:"//trim(airpressurestr) RETURN CASE(STTC) CALL FATAL_ERROR("STATIC AIR PRESSURE Not Set Up Yet") CASE(TMDPNDNT) CALL FATAL_ERROR("TIME DEPENDANT AIR PRESSURE Not Set Up Yet") CASE(PRDC) AIRPRESSURE_P_FILE => FIND_FILE(FILEHEAD,trim(AIRPRESSURE_FILE),FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("COULD NOT FIND SURFACE AIR PRESSURE FILE OBJECT",& & "FILE NAME: "//TRIM(AIRPRESSURE_FILE)) ! DETERMINE GRID TYPE BASED ON SOURCE ATTRIBUTE ATT => FIND_ATT(AIRPRESSURE_P_FILE,"source",FOUND) IF(.not. FOUND) ATT => FIND_ATT(AIRPRESSURE_P_FILE,"Source",FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN SURFACE AIR PRESSURE FILE OBJECT",& & "FILE NAME: "//TRIM(AIRPRESSURE_FILE),& &"COULD NOT FIND GLOBAL ATTRIBURE: 'source'") IF (ATT%CHR(1)(1:len_trim(wrf2fvcom_source)) ==& & TRIM(wrf2fvcom_source)) THEN AIRPRESSURE_FORCING_TYPE = AIRPRESSURE_IS_WRFGRID ELSE IF (ATT%CHR(1)(1:len_trim(fvcom_grid_source)) ==& & TRIM(fvcom_grid_source)) THEN AIRPRESSURE_FORCING_TYPE = AIRPRESSURE_IS_FVCOMGRID ELSE IF (ATT%CHR(1)(1:len_trim(fvcom_cap_grid_source)) ==& & TRIM(fvcom_cap_grid_source)) THEN AIRPRESSURE_FORCING_TYPE = AIRPRESSURE_IS_FVCOMGRID ELSE IF (ATT%CHR(1)(1:len_trim(wrf_grid_source)) ==& & TRIM(wrf_grid_source)) THEN AIRPRESSURE_FORCING_TYPE = AIRPRESSURE_IS_WRFGRID ELSE CALL PRINT_FILE(AIRPRESSURE_P_FILE) CALL FATAL_ERROR("CAN NOT RECOGNIZE AIR PRESSURE FILE!",& & "UNKNOWN SOURCE STRING:",TRIM(ATT%CHR(1))) END IF ! GOT GRID TYPE ALLOCATE(AIRPRESSURE_FORCING_COMMENTS(4)) AIRPRESSURE_FORCING_COMMENTS(1) = "FVCOM periodic surface Air Pressure forcing:" AIRPRESSURE_FORCING_COMMENTS(2) = "FILE NAME:"//TRIM(AIRPRESSURE_FILE) AIRPRESSURE_FORCING_COMMENTS(3) = "SOURCE:"//TRIM(ATT%CHR(1)) ATT_DATE => FIND_ATT(AIRPRESSURE_P_FILE,"START_DATE",FOUND) IF (FOUND) THEN AIRPRESSURE_FORCING_COMMENTS(4) ="MET DATA START DATE:"//TRIM(ATT_DATE%CHR(1)) ELSE AIRPRESSURE_FORCING_COMMENTS(4) = "Unknown start date meta data format" END IF ! GET THE FILES LENGTH OF TIME AND SAVE FOR PERIODIC FORCING ! LOOK FOR THE DIMENSIONS DIM => FIND_UNLIMITED(AIRPRESSURE_P_FILE,FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN AIR PRESSURE FILE OBJECT",& & "FILE NAME: "//TRIM(AIRPRESSURE_FILE),& &"COULD NOT FIND THE UNLMITIED DIMENSION") NTIMES = DIM%DIM AIRPRESSURE_PERIOD = get_file_time(AIRPRESSURE_P_FILE,ntimes) AIRPRESSURE_PERIOD = AIRPRESSURE_PERIOD - get_file_time(AIRPRESSURE_P_FILE,1) IF (AIRPRESSURE_PERIOD /= get_file_time(AIRPRESSURE_P_FILE,ntimes)) THEN CALL PRINT_REAL_TIME(get_file_time(AIRPRESSURE_P_FILE,1),IPT,"FIRST FILE TIME",TIMEZONE) CALL PRINT_REAL_TIME(get_file_time(AIRPRESSURE_P_FILE,ntimes),IPT,"LAST FILE TIME",TIMEZONE) CALL FATAL_ERROR& &("TO USE PERIODIC FORCING THE FILE TIME MUST COUNT FROM ZERO",& & "THE DIFFERENCE BETWEEN THE CURRENT MODEL TIME AND THE START TIME,",& & "MODULO THE FORCING PERIOD, DETERMINES THE CURRENT FORCING") END IF IF(DBG_SET(DBG_LOG)) THEN WRITE(IPT,*) "! USING PERIODIC AIR PRESSURE FORCING:" CALL PRINT_TIME(AIRPRESSURE_PERIOD,IPT,"PERIOD") END IF CASE(VRBL) AIRPRESSURE_P_FILE => FIND_FILE(FILEHEAD,trim(AIRPRESSURE_FILE),FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("COULD NOT FIND SURFACE AIR PRESSURE FILE OBJECT",& & "FILE NAME: "//TRIM(AIRPRESSURE_FILE)) ! DETERMINE GRID TYPE BASED ON SOURCE ATTRIBUTE ATT => FIND_ATT(AIRPRESSURE_P_FILE,"source",FOUND) IF(.not. FOUND) ATT => FIND_ATT(AIRPRESSURE_P_FILE,"Source",FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN SURFACE AIR PRESSURE FILE OBJECT",& & "FILE NAME: "//TRIM(AIRPRESSURE_FILE),& &"COULD NOT FIND GLOBAL ATTRIBURE: 'source'") IF (ATT%CHR(1)(1:len_trim(wrf2fvcom_source)) ==& & TRIM(wrf2fvcom_source)) THEN AIRPRESSURE_FORCING_TYPE = AIRPRESSURE_IS_WRFGRID ELSE IF (ATT%CHR(1)(1:len_trim(fvcom_grid_source)) ==& & TRIM(fvcom_grid_source)) THEN AIRPRESSURE_FORCING_TYPE = AIRPRESSURE_IS_FVCOMGRID ELSE IF (ATT%CHR(1)(1:len_trim(fvcom_cap_grid_source)) ==& & TRIM(fvcom_cap_grid_source)) THEN AIRPRESSURE_FORCING_TYPE = AIRPRESSURE_IS_FVCOMGRID ELSE IF (ATT%CHR(1)(1:len_trim(wrf_grid_source)) ==& & TRIM(wrf_grid_source)) THEN AIRPRESSURE_FORCING_TYPE = AIRPRESSURE_IS_WRFGRID ELSE CALL PRINT_FILE(AIRPRESSURE_P_FILE) CALL FATAL_ERROR("CAN NOT RECOGNIZE AIR PRESSURE FILE!",& & "UNKNOWN SOURCE STRING:",TRIM(ATT%CHR(1))) END IF ! GOT GRID TYPE ALLOCATE(AIRPRESSURE_FORCING_COMMENTS(4)) AIRPRESSURE_FORCING_COMMENTS(1) = "FVCOM variable surface Air Pressure:" AIRPRESSURE_FORCING_COMMENTS(2) = "FILE NAME:"//TRIM(AIRPRESSURE_FILE) AIRPRESSURE_FORCING_COMMENTS(3) = "SOURCE:"//TRIM(ATT%CHR(1)) ATT_DATE => FIND_ATT(AIRPRESSURE_P_FILE,"START_DATE",FOUND) IF (FOUND) THEN AIRPRESSURE_FORCING_COMMENTS(4) ="MET DATA START DATE:"//TRIM(ATT_DATE%CHR(1)) ELSE AIRPRESSURE_FORCING_COMMENTS(4) = "Unknown start date meta data format" END IF ! LOOK FOR THE DIMENSIONS DIM => FIND_UNLIMITED(AIRPRESSURE_P_FILE,FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN SURFACE AIR PRESSURE FILE OBJECT",& & "FILE NAME: "//TRIM(AIRPRESSURE_FILE),& &"COULD NOT FIND THE UNLIMITED DIMENSION") NTIMES = DIM%DIM ! CHECK THE FILE TIME AND COMPARE WITH MODEL RUN TIME TIMETEST = get_file_time(AIRPRESSURE_P_FILE,1) IF(TIMETEST > STARTTIME) CALL FATAL_ERROR & & ("IN SURFACE AIR PRESSURE FILE OBJECT",& & "FILE NAME: "//TRIM(AIRPRESSURE_FILE),& &"THE MODEL RUN STARTS BEFORE THE FORCING TIME SERIES") TIMETEST = get_file_time(AIRPRESSURE_P_FILE,ntimes) IF(TIMETEST < ENDTIME) CALL FATAL_ERROR & & ("IN SURFACE AIR PRESSURE FILE OBJECT",& & "FILE NAME: "//TRIM(AIRPRESSURE_FILE),& &"THE MODEL RUN ENDS AFTER THE FORCING TIME SERIES") CASE DEFAULT CALL FATAL_ERROR("SURFACE_AIRPRESSURE: UNKNOWN ARE PRESSURE KIND?") END SELECT !============================================================== SELECT CASE(AIRPRESSURE_FORCING_TYPE) !============================================================== CASE(AIRPRESSURE_IS_WRFGRID) !============================================================== IF(DBG_SET(DBG_LOG)) WRITE(IPT,*) & & "! SETTING UP AIR PRESSURE FORCING FROM A 'wrf grid' FILE" DIM => FIND_DIM(AIRPRESSURE_P_FILE,'south_north',FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN SURFACE AIR PRESSURE FILE OBJECT",& & "FILE NAME: "//TRIM(AIRPRESSURE_FILE),& & "COULD NOT FIND DIMENSION 'south_north'") LATS = DIM%DIM DIM => FIND_DIM(AIRPRESSURE_P_FILE,'west_east',FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN SURFACE AIR PRESSURE FILE OBJECT",& & "FILE NAME: "//TRIM(AIRPRESSURE_FILE),& & "COULD NOT FIND DIMENSION 'west_east'") LONS = DIM%DIM CALL SET_FILE_INTERP_bilinear(AIRPRESSURE_P_FILE,AIRPRESSURE_INTP_N,AIRPRESSURE_INTP_C) ! SETUP THE ACTUAL VARIABLES USED TO LOAD DATA! ! AIR PRESSURE VAR => FIND_VAR(AIRPRESSURE_P_FILE,"air_pressure",FOUND) IF(.not. FOUND) VAR => FIND_VAR(AIRPRESSURE_P_FILE,"pressure_air",FOUND) IF(.not. FOUND) VAR => FIND_VAR(AIRPRESSURE_P_FILE,"SLP",FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN SURFACE AIR PRESSURE FILE OBJECT",& & "FILE NAME: "//TRIM(AIRPRESSURE_FILE),& & "COULD NOT FIND VARIABLE 'air_pressure' OR 'SLP'") !---> Siqi Li, 2021-01-27 ! The unit of air pressure is really important. It can influence both ! water elevation and wind stress. In calculation, the unit of air ! pressure is 'Pa'. ATT => FIND_ATT(VAR,'units',FOUND) IF(.not. FOUND) ATT => FIND_ATT(VAR,'unit',FOUND) IF (FOUND) THEN call UPCASE(ATT%CHR(1)) SELECT CASE (TRIM(ATT%CHR(1))) CASE ('MB', 'HPA') Pair_unit_factor = 100.0_SP CASE ('PA','PASCAL') Pair_unit_factor = 1.0_SP CASE DEFAULT CALL FATAL_ERROR("UNKNOWN UNIT of AIR PRESSURE: " & & //TRIM(ATT%CHR(1))) END SELECT ELSE ! There is no unit attribute for the air_pressure variable ! We assume the unit is 'Pa'. Pair_unit_factor = 1.0_SP END IF !<--- Siqi Li, 2021-01-27 ! MAKE SPACE FOR THE DATA FROM THE FILE ALLOCATE(STORAGE_ARR(lons,lats), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN SURFACE AIR PRESSURE") AIR_PRESSURE_N => reference_var(var) CALL NC_CONNECT_PVAR(AIR_PRESSURE_N,STORAGE_ARR) NULLIFY(STORAGE_ARR) ! MAKE SPACE FOR THE INTERPOLATED DATA ALLOCATE(STORAGE_VEC(0:MT), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN SURFACE AIR PRESSURE") CALL NC_CONNECT_PVAR(AIR_PRESSURE_N,STORAGE_VEC) NULLIFY(STORAGE_VEC) ! MAKE SPACE FOR THE DATA FROM THE FILE ALLOCATE(STORAGE_ARR(lons,lats), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN SURFACE AIR PRESSURE") AIR_PRESSURE_P => reference_var(var) CALL NC_CONNECT_PVAR(AIR_PRESSURE_P,STORAGE_ARR) NULLIFY(STORAGE_ARR) ! MAKE SPACE FOR THE INTERPOLATED DATA ALLOCATE(STORAGE_VEC(0:MT), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN SURFACE AIR PRESSURE") CALL NC_CONNECT_PVAR(AIR_PRESSURE_P,STORAGE_VEC) NULLIFY(STORAGE_VEC) !============================================================== CASE(AIRPRESSURE_IS_FVCOMGRID) !============================================================== IF(DBG_SET(DBG_LOG)) WRITE(IPT,*) & & "! SETTING UP AIR PRESSURE FORCING FROM A 'FVCOM GRID' FILE" DIM => FIND_DIM(AIRPRESSURE_P_FILE,'node',FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN SURFACE AIR PRESSURE FILE OBJECT",& & "FILE NAME: "//TRIM(AIRPRESSURE_FILE),& & "COULD NOT FIND DIMENSION 'node'") if (mgl /= dim%dim) CALL FATAL_ERROR& &("Surface Air Pressure: the number of nodes in the file does not match the fvcom grid?") DIM => FIND_DIM(AIRPRESSURE_P_FILE,'nele',FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN SURFACE AIR PRESSURE FILE OBJECT",& & "FILE NAME: "//TRIM(AIRPRESSURE_FILE),& & "COULD NOT FIND DIMENSION 'nele'") if (ngl /= dim%dim) CALL FATAL_ERROR& &("Surface Air Pressure: the number of elements in the file does not match the fvcom grid?") ! SETUP THE ACTUAL VARIABLES USED TO LOAD DATA! ! AIR PRESSURE VAR => FIND_VAR(AIRPRESSURE_P_FILE,"air_pressure",FOUND) IF(.not. FOUND) VAR => FIND_VAR(AIRPRESSURE_P_FILE,"SLP",FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN SURFACE AIR PRESSURE FILE OBJECT",& & "FILE NAME: "//TRIM(AIRPRESSURE_FILE),& & "COULD NOT FIND VARIABLE 'air_pressure' or 'SLP'") !---> Siqi Li, 2021-01-27 ! The unit of air pressure is really important. It can influence both ! water elevation and wind stress. In calculation, the unit of air ! pressure is 'Pa'. ATT => FIND_ATT(VAR,'units',FOUND) IF(.not. FOUND) ATT => FIND_ATT(VAR,'unit',FOUND) IF (FOUND) THEN call UPCASE(ATT%CHR(1)) SELECT CASE (TRIM(ATT%CHR(1))) CASE ('MB', 'HPA') Pair_unit_factor = 100.0_SP CASE ('PA','PASCAL') Pair_unit_factor = 1.0_SP CASE DEFAULT CALL FATAL_ERROR("UNKNOWN UNIT of AIR PRESSURE: " & & //TRIM(ATT%CHR(1))) END SELECT ELSE ! There is no unit attribute for the air_pressure variable ! We assume the unit is 'Pa'. Pair_unit_factor = 1.0_SP END IF !<--- Siqi Li, 2021-01-27 ! MAKE SPACE FOR THE DATA FROM THE FILE AIR_PRESSURE_N => reference_var(var) ALLOCATE(STORAGE_VEC(0:MT), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN AIR PRESSURE") CALL NC_CONNECT_PVAR(AIR_PRESSURE_N,STORAGE_VEC) NULLIFY(STORAGE_VEC) ! MAKE SPACE FOR THE DATA FROM THE FILE AIR_PRESSURE_P => reference_var(var) ALLOCATE(STORAGE_VEC(0:MT), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN AIR PRESSURE") CALL NC_CONNECT_PVAR(AIR_PRESSURE_P,STORAGE_VEC) NULLIFY(STORAGE_VEC) !============================================================== CASE DEFAULT !============================================================== CALL FATAL_ERROR("CAN NOT RECOGNIZE AIR PRESSURE FILE TYPE!") !============================================================== END SELECT !============================================================== ! ---------- new: 2016 , april, Karsten Lettmann after Hint by Qi and ayumi.fujisaki@noaa.gov------ ! Initialize some variables ! afm 20150914 ! Need initialization. Otherwise, random values are asigned ! and cause a hanging problem of MPI job in UPDATE_VAR_BRACKET ! This problem reported with Intel15.0.3. ! PRECIPITATION AIR_PRESSURE_P%curr_stkcnt = 0 ; AIR_PRESSURE_N%curr_stkcnt = 0 ! --------- end new ---------------------------------------------------------------- IF(DBG_SET(DBG_SBR)) write(IPT,*) "END SURFACE_AIRPRESSURE" END SUBROUTINE SURFACE_AIRPRESSURE !================================================================ !================================================================ SUBROUTINE SURFACE_PRECIPITATION IMPLICIT NONE ! SOME NC POINTERS TYPE(NCATT), POINTER :: ATT, ATT_DATE TYPE(NCDIM), POINTER :: DIM TYPE(NCVAR), POINTER :: VAR LOGICAL :: FOUND REAL(SP), POINTER :: STORAGE_ARR(:,:), storage_vec(:) TYPE(TIME) :: TIMETEST INTEGER :: LATS, LONS, I, Ntimes INTEGER :: STATUS CHARACTER(len=60) :: evpstr, prcstr IF(DBG_SET(DBG_SBR)) write(IPT,*) "START SURFACE_PRECIPITATION" IF (.NOT. PRECIPITATION_ON ) THEN IF(DBG_SET(DBG_LOG)) write(IPT,*) "! SURFACE PRECIPITATION FORCING IS OFF!" ALLOCATE(PRECIP_FORCING_COMMENTS(1)) PRECIP_FORCING_COMMENTS(1) = "SURFACE PRECIPITATION FORCING IS OFF" RETURN END IF NULLIFY(ATT,DIM,VAR,STORAGE_ARR,STORAGE_VEC) ! DETERMINE HOW TO LOAD THE DATA SELECT CASE(PRECIPITATION_KIND) CASE (CNSTNT) write(evpstr,'(f8.4)') PRECIPITATION_EVP write(prcstr,'(f8.4)') PRECIPITATION_PRC IF(DBG_SET(DBG_LOG)) THEN WRITE(IPT,*)"! SETTING UP CONSTANT PRECIPITATION FORCING: " WRITE(IPT,*)" EVAPORATION: "//trim(evpstr) WRITE(IPT,*)" PRECIPITATION: "//trim(prcstr) END IF ALLOCATE(PRECIP_FORCING_COMMENTS(3)) PRECIP_FORCING_COMMENTS(1) = "Using constant precipitation from run file:" PRECIP_FORCING_COMMENTS(2) = "Precipitation:"//trim(prcstr) PRECIP_FORCING_COMMENTS(3) = "Evaporation:"//trim(evpstr) RETURN CASE(STTC) CALL FATAL_ERROR("STATIC PRECIP Not Set Up Yet") CASE(TMDPNDNT) CALL FATAL_ERROR("TIME DEPENDANT PRECIP Not Set Up Yet") CASE(PRDC) PRECIP_FILE => FIND_FILE(FILEHEAD,trim(PRECIPITATION_FILE),FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("COULD NOT FIND SURFACE WIND BOUNDARY CONDINTION FILE OBJECT",& & "FILE NAME: "//TRIM(PRECIPITATION_FILE)) ! DETERMINE GRID TYPE BASED ON SOURCE ATTRIBUTE ATT => FIND_ATT(PRECIP_FILE,"source",FOUND) IF(.not. FOUND) ATT => FIND_ATT(PRECIP_FILE,"Source",FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN SURFACE WIND BOUNDARY CONDITION FILE OBJECT",& & "FILE NAME: "//TRIM(PRECIPITATION_FILE),& &"COULD NOT FIND GLOBAL ATTRIBURE: 'source'") IF (ATT%CHR(1)(1:len_trim(wrf2fvcom_source)) ==& & TRIM(wrf2fvcom_source)) THEN PRECIP_FORCING_TYPE = PRECIP_IS_WRFGRID ELSE IF (ATT%CHR(1)(1:len_trim(fvcom_grid_source)) ==& & TRIM(fvcom_grid_source)) THEN PRECIP_FORCING_TYPE = PRECIP_IS_FVCOMGRID ELSE IF (ATT%CHR(1)(1:len_trim(fvcom_cap_grid_source)) ==& & TRIM(fvcom_cap_grid_source)) THEN PRECIP_FORCING_TYPE = PRECIP_IS_FVCOMGRID ELSE IF (ATT%CHR(1)(1:len_trim(wrf_grid_source)) ==& & TRIM(wrf_grid_source)) THEN PRECIP_FORCING_TYPE = PRECIP_IS_WRFGRID ELSE CALL PRINT_FILE(PRECIP_FILE) CALL FATAL_ERROR("CAN NOT RECOGNIZE PRECIP FILE!",& & "UNKNOWN SOURCE STRING:",TRIM(ATT%CHR(1))) END IF ! GOT GRID TYPE ALLOCATE(PRECIP_FORCING_COMMENTS(4)) PRECIP_FORCING_COMMENTS(1) = "FVCOM periodic surface precip forcing:" PRECIP_FORCING_COMMENTS(2) = "FILE NAME:"//TRIM(PRECIPITATION_FILE) PRECIP_FORCING_COMMENTS(3) = "SOURCE:"//TRIM(ATT%CHR(1)) ATT_DATE => FIND_ATT(PRECIP_FILE,"START_DATE",FOUND) IF (FOUND) THEN PRECIP_FORCING_COMMENTS(4) ="MET DATA START DATE:"//TRIM(ATT_DATE%CHR(1)) ELSE PRECIP_FORCING_COMMENTS(4) = "Unknown start date meta data format" END IF ! GET THE FILES LENGTH OF TIME AND SAVE FOR PERIODIC FORCING ! LOOK FOR THE DIMENSIONS DIM => FIND_UNLIMITED(PRECIP_FILE,FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN SURFACE PRECIPITATION BOUNDARY CONDITION FILE OBJECT",& & "FILE NAME: "//TRIM(WIND_FILE),& &"COULD NOT FIND THE UNLIMITED DIMENSION") NTIMES = DIM%DIM PRECIP_PERIOD = get_file_time(PRECIP_FILE,ntimes) PRECIP_PERIOD = PRECIP_PERIOD - get_file_time(PRECIP_FILE,1) IF (PRECIP_PERIOD /= get_file_time(PRECIP_FILE,ntimes)) THEN CALL PRINT_REAL_TIME(get_file_time(PRECIP_FILE,1),IPT,"FIRST FILE TIME",TIMEZONE) CALL PRINT_REAL_TIME(get_file_time(PRECIP_FILE,ntimes),IPT,"LAST FILE TIME",TIMEZONE) CALL FATAL_ERROR& &("TO USE PERIODIC FORCING THE FILE TIME MUST COUNT FROM ZERO",& & "THE DIFFERENCE BETWEEN THE CURRENT MODEL TIME AND THE START TIME,",& & "MODULO THE FORCING PERIOD, DETERMINES THE CURRENT FORCING") END IF IF(DBG_SET(DBG_LOG)) THEN WRITE(IPT,*) "! USING PERIODIC PRECIP FORCING:" CALL PRINT_TIME(PRECIP_PERIOD,IPT,"PERIOD") END IF CASE(VRBL) PRECIP_FILE => FIND_FILE(FILEHEAD,trim(PRECIPITATION_FILE),FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("COULD NOT FIND SURFACE WIND BOUNDARY CONDINTION FILE OBJECT",& & "FILE NAME: "//TRIM(PRECIPITATION_FILE)) ! DETERMINE GRID TYPE BASED ON SOURCE ATTRIBUTE ATT => FIND_ATT(PRECIP_FILE,"source",FOUND) IF(.not. FOUND) ATT => FIND_ATT(PRECIP_FILE,"Source",FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN SURFACE WIND BOUNDARY CONDITION FILE OBJECT",& & "FILE NAME: "//TRIM(PRECIPITATION_FILE),& &"COULD NOT FIND GLOBAL ATTRIBURE: 'source'") IF (ATT%CHR(1)(1:len_trim(wrf2fvcom_source)) ==& & TRIM(wrf2fvcom_source)) THEN PRECIP_FORCING_TYPE = PRECIP_IS_WRFGRID ELSE IF (ATT%CHR(1)(1:len_trim(fvcom_grid_source)) ==& & TRIM(fvcom_grid_source)) THEN PRECIP_FORCING_TYPE = PRECIP_IS_FVCOMGRID ELSE IF (ATT%CHR(1)(1:len_trim(fvcom_cap_grid_source)) ==& & TRIM(fvcom_cap_grid_source)) THEN PRECIP_FORCING_TYPE = PRECIP_IS_FVCOMGRID ELSE IF (ATT%CHR(1)(1:len_trim(wrf_grid_source)) ==& & TRIM(wrf_grid_source)) THEN PRECIP_FORCING_TYPE = PRECIP_IS_WRFGRID ELSE CALL PRINT_FILE(PRECIP_FILE) CALL FATAL_ERROR("CAN NOT RECOGNIZE PRECIP FILE!",& & "UNKNOWN SOURCE STRING:",TRIM(ATT%CHR(1))) END IF ! GOT GRID TYPE ALLOCATE(PRECIP_FORCING_COMMENTS(4)) PRECIP_FORCING_COMMENTS(1) = "FVCOM periodic surface precip forcing:" PRECIP_FORCING_COMMENTS(2) = "FILE NAME:"//TRIM(PRECIPITATION_FILE) PRECIP_FORCING_COMMENTS(3) = "SOURCE:"//TRIM(ATT%CHR(1)) ATT_DATE => FIND_ATT(PRECIP_FILE,"START_DATE",FOUND) IF (FOUND) THEN PRECIP_FORCING_COMMENTS(4) ="MET DATA START DATE:"//TRIM(ATT_DATE%CHR(1)) ELSE PRECIP_FORCING_COMMENTS(4) = "Unknown start date meta data format" END IF DIM => FIND_UNLIMITED(PRECIP_FILE,FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN SURFACE WIND BOUNDARY CONDITION FILE OBJECT",& & "FILE NAME: "//TRIM(PRECIPITATION_FILE),& &"COULD NOT FIND THE UNLIMITED DIMENSION") NTIMES = DIM%DIM ! CHECK THE FILE TIME AND COMPARE WITH MODEL RUN TIME TIMETEST = get_file_time(PRECIP_FILE,1) IF(TIMETEST > STARTTIME) CALL FATAL_ERROR & & ("IN SURFACE WIND BOUNDARY CONDITION FILE OBJECT",& & "FILE NAME: "//TRIM(PRECIPITATION_FILE),& &"THE MODEL RUN STARTS BEFORE THE FORCING TIME SERIES") TIMETEST = get_file_time(PRECIP_FILE,ntimes) IF(TIMETEST < ENDTIME) CALL FATAL_ERROR & & ("IN SURFACE WIND BOUNDARY CONDITION FILE OBJECT",& & "FILE NAME: "//TRIM(PRECIPITATION_FILE),& &"THE MODEL RUN ENDS AFTER THE FORCING TIME SERIES") CASE DEFAULT CALL FATAL_ERROR("SURFACE_PRECIP: UNKNOWN WIND KIND?") END SELECT ! DEAL WITH DATA SET UP !===================================================================== SELECT CASE(PRECIP_FORCING_TYPE) !===================================================================== CASE(PRECIP_IS_WRFGRID) !===================================================================== IF(DBG_SET(DBG_LOG)) WRITE(IPT,*) & & "! SETTING UP WIND STRESS FORCING FROM A 'wrf grid' FILE" ! LOOK FOR THE DIMENSIONS DIM => FIND_DIM(PRECIP_FILE,'south_north',FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN SURFACE WIND BOUNDARY CONDITION FILE OBJECT",& & "FILE NAME: "//TRIM(PRECIPITATION_FILE),& & "COULD NOT FIND DIMENSION 'south_north'") LATS = DIM%DIM DIM => FIND_DIM(PRECIP_FILE,'west_east',FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN SURFACE WIND BOUNDARY CONDITION FILE OBJECT",& & "FILE NAME: "//TRIM(PRECIPITATION_FILE),& & "COULD NOT FIND DIMENSION 'west_east'") LONS = DIM%DIM CALL SET_FILE_INTERP_bilinear(PRECIP_FILE,PRECIP_INTP_N,PRECIP_INTP_C) ! SETUP THE ACTUAL VARIABLES USED TO LOAD DATA! ! WIND STRESS IN THE X or EAST-WEST DIRECTION VAR => FIND_VAR(PRECIP_FILE,"Precipitation",FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN SURFACE WIND BOUNDARY CONDITION FILE OBJECT",& & "FILE NAME: "//TRIM(PRECIPITATION_FILE),& & "COULD NOT FIND VARIABLE 'PRECIPITATION'") ! MAKE SPACE FOR THE DATA FROM THE FILE ALLOCATE(STORAGE_ARR(lons,lats), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN SURFACE PRECIPITATION") PRECIP_PRE_N => reference_var(var) CALL NC_CONNECT_PVAR(PRECIP_PRE_N,STORAGE_ARR) NULLIFY(STORAGE_ARR) ! MAKE SPACE FOR THE INTERPOLATED DATA ALLOCATE(STORAGE_VEC(0:MT), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN SURFACE PRECIPITATION") CALL NC_CONNECT_PVAR(PRECIP_PRE_N,STORAGE_VEC) NULLIFY(STORAGE_VEC) ! MAKE SPACE FOR THE DATA FROM THE FILE ALLOCATE(STORAGE_ARR(lons,lats), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN SURFACE PRECIPITATION") PRECIP_PRE_P => reference_var(var) CALL NC_CONNECT_PVAR(PRECIP_PRE_P,STORAGE_ARR) NULLIFY(STORAGE_ARR) ! MAKE SPACE FOR THE INTERPOLATED DATA ALLOCATE(STORAGE_VEC(0:MT), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN SURFACE PRECIPITATION") CALL NC_CONNECT_PVAR(PRECIP_PRE_P,STORAGE_VEC) NULLIFY(STORAGE_VEC) ! WIND STRESS IN THE X or EAST-WEST DIRECTION VAR => FIND_VAR(PRECIP_FILE,"Evaporation",FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN SURFACE WIND BOUNDARY CONDITION FILE OBJECT",& & "FILE NAME: "//TRIM(PRECIPITATION_FILE),& & "COULD NOT FIND VARIABLE 'Evaporation'") ! MAKE SPACE FOR THE DATA FROM THE FILE ALLOCATE(STORAGE_ARR(lons,lats), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN SURFACE PRECIPITATION") PRECIP_EVP_N => reference_var(var) CALL NC_CONNECT_PVAR(PRECIP_EVP_N,STORAGE_ARR) NULLIFY(STORAGE_ARR) ! MAKE SPACE FOR THE INTERPOLATED DATA ALLOCATE(STORAGE_VEC(0:MT), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN SURFACE PRECIPITATION") CALL NC_CONNECT_PVAR(PRECIP_EVP_N,STORAGE_VEC) NULLIFY(STORAGE_VEC) ! MAKE SPACE FOR THE DATA FROM THE FILE ALLOCATE(STORAGE_ARR(lons,lats), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN SURFACE PRECIPITATION") PRECIP_EVP_P => reference_var(var) CALL NC_CONNECT_PVAR(PRECIP_EVP_P,STORAGE_ARR) NULLIFY(STORAGE_ARR) ! MAKE SPACE FOR THE INTERPOLATED DATA ALLOCATE(STORAGE_VEC(0:MT), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN SURFACE PRECIPITATION") CALL NC_CONNECT_PVAR(PRECIP_EVP_P,STORAGE_VEC) NULLIFY(STORAGE_VEC) !===================================================================== CASE(PRECIP_IS_FVCOMGRID) !===================================================================== IF(DBG_SET(DBG_LOG)) WRITE(IPT,*) & & "! SETTING UP PRECIPITATION FORCING FROM A 'FVCOM grid' FILE" ! LOOK FOR THE DIMENSIONS DIM => FIND_DIM(PRECIP_FILE,'node',FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN PRECIPITATION BOUNDARY CONDITION FILE OBJECT",& & "FILE NAME: "//TRIM(PRECIPITATION_FILE),& & "COULD NOT FIND DIMENSION 'node'") if (mgl /= dim%dim) CALL FATAL_ERROR& &("Surface PRECIP: the number of nodes in the file does not match the fvcom grid?") DIM => FIND_DIM(PRECIP_FILE,'nele',FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN PRECIPITATION BOUNDARY CONDITION FILE OBJECT",& & "FILE NAME: "//TRIM(PRECIPITATION_FILE),& & "COULD NOT FIND DIMENSION 'nele'") if (ngl /= dim%dim) CALL FATAL_ERROR& &("Surface PRECIP: the number of elements in the file does not match the fvcom grid?") ! SETUP THE ACTUAL VARIABLES USED TO LOAD DATA! ! WIND STRESS IN THE X or EAST-WEST DIRECTION VAR => FIND_VAR(PRECIP_FILE,"precip",FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN PRECIPITATION BOUNDARY CONDITION FILE OBJECT",& & "FILE NAME: "//TRIM(PRECIPITATION_FILE),& & "COULD NOT FIND VARIABLE 'precip'") ! MAKE SPACE FOR THE DATA FROM THE FILE PRECIP_PRE_N => reference_var(var) ALLOCATE(STORAGE_VEC(0:MT), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN SURFACE PRECIPITATION") CALL NC_CONNECT_PVAR(PRECIP_PRE_N,STORAGE_VEC) NULLIFY(STORAGE_VEC) ! MAKE SPACE FOR THE DATA FROM THE FILE PRECIP_PRE_P => reference_var(var) ALLOCATE(STORAGE_VEC(0:MT), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN SURFACE PRECIPITATION") CALL NC_CONNECT_PVAR(PRECIP_PRE_P,STORAGE_VEC) NULLIFY(STORAGE_VEC) ! EVAP VAR => FIND_VAR(PRECIP_FILE,"evap",FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN PRECIPITATION BOUNDARY CONDITION FILE OBJECT",& & "FILE NAME: "//TRIM(PRECIPITATION_FILE),& & "COULD NOT FIND VARIABLE 'evap'") ! MAKE SPACE FOR THE DATA FROM THE FILE PRECIP_EVP_N => reference_var(var) ALLOCATE(STORAGE_VEC(0:MT), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN SURFACE PRECIPITATION") CALL NC_CONNECT_PVAR(PRECIP_EVP_N,STORAGE_VEC) NULLIFY(STORAGE_VEC) ! MAKE SPACE FOR THE DATA FROM THE FILE PRECIP_EVP_P => reference_var(var) ALLOCATE(STORAGE_VEC(0:MT), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN SURFACE PRECIPITATION") CALL NC_CONNECT_PVAR(PRECIP_EVP_P,STORAGE_VEC) NULLIFY(STORAGE_VEC) !===================================================================== CASE DEFAULT !===================================================================== CALL FATAL_ERROR("CAN NOT RECOGNIZE PRECIPITATION FILE TYPE") !===================================================================== END SELECT !===================================================================== ! ---------- new: 2016 , april, Karsten Lettmann after Hint by Qi and ayumi.fujisaki@noaa.gov------ ! Initialize some variables ! afm 20150914 ! Need initialization. Otherwise, random values are asigned ! and cause a hanging problem of MPI job in UPDATE_VAR_BRACKET ! This problem reported with Intel15.0.3. ! PRECIPITATION PRECIP_PRE_P%curr_stkcnt = 0 PRECIP_PRE_N%curr_stkcnt = 0 ! EVAPORATION PRECIP_EVP_N%curr_stkcnt = 0 PRECIP_EVP_P%curr_stkcnt = 0 ! --------- end new ---------------------------------------------------------------- IF(DBG_SET(DBG_SBR)) write(IPT,*) "END SURFACE_PRECIPITATION" END SUBROUTINE SURFACE_PRECIPITATION !==============================================================================| SUBROUTINE UPDATE_RIVERS(NOW,FLUX,TEMP,SALT,WQM,SED,BIO) # if defined (BioGen) USE MOD_1D, ONLY : NTT # endif IMPLICIT NONE TYPE(TIME), INTENT(IN) :: NOW REAL(SP), ALLOCATABLE :: FLUX(:) REAL(SP), ALLOCATABLE, OPTIONAL :: TEMP(:) REAL(SP), ALLOCATABLE, OPTIONAL :: SALT(:) REAL(SP), ALLOCATABLE, OPTIONAL :: WQM(:,:) REAL(SP), ALLOCATABLE, OPTIONAL :: SED(:,:) REAL(SP), ALLOCATABLE, OPTIONAL :: BIO(:,:) REAL(SP), POINTER :: VNP(:), VPP(:) REAL(SP), ALLOCATABLE :: CURRENT(:) TYPE(TIME) :: RIVTIME TYPE(NCFILE), POINTER :: NCF TYPE(NCVAR), POINTER :: VAR_N TYPE(NCVAR), POINTER :: VAR_P TYPE(NCFTIME), POINTER :: FTM INTEGER :: STATUS, I, J, NRSF,IND,NS IF(.NOT. ALLOCATED(FLUX)) CALL FATAL_ERROR & &("THE RIVER FLUX VARIABLE PASSED TO UPDATE IS NOT ALLOCATED") IF(PRESENT(TEMP)) THEN IF(.NOT. ALLOCATED(TEMP)) CALL FATAL_ERROR & &("THE RIVER TEMP VARIABLE PASSED TO UPDATE IS NOT ALLOCATED") END IF IF(PRESENT(SALT)) THEN IF(.NOT. ALLOCATED(SALT)) CALL FATAL_ERROR & &("THE RIVER SALT VARIABLE PASSED TO UPDATE IS NOT ALLOCATED") END IF # if defined (WATER_QUALITY) IF(PRESENT(WQM)) THEN IF(.NOT. ALLOCATED(WQM)) CALL FATAL_ERROR & &("THE RIVER WATER QUALITY VARIABLE PASSED TO UPDATE IS NOT ALLOCATED") END IF # endif # if defined (SEDIMENT) IF(PRESENT(SED)) THEN IF(.NOT. ALLOCATED(SED)) CALL FATAL_ERROR & &("THE RIVER SEDIMENT VARIABLE PASSED TO UPDATE IS NOT ALLOCATED") END IF # endif # if defined (BioGen) IF(BIOLOGICAL_MODEL)THEN IF(PRESENT(BIO)) THEN IF(.NOT. ALLOCATED(BIO)) CALL FATAL_ERROR & &("THE RIVER BIOLOGICAL VARIABLE PASSED TO UPDATE IS NOT ALLOCATED") END IF END IF # endif DO I = 1, SIZE(RIVER_FORCING) ! (NUMBER OF FILES) SELECT CASE (RIVER_KIND) CASE(PRDC) ! TO SET ZERO TIME PHASE USING RUNFILE START TIME ! RIVTIME= NOW - RUNFILE_StartTime ! TO USE ZERO AS THE PHASE OF THE FORCING RIVTIME= NOW RIVTIME = MOD(RIVTIME,RIVER_FORCING(I)%RIVER_PERIOD) CASE(VRBL) RIVTIME = NOW END SELECT NCF => RIVER_FORCING(I)%NCF FTM => NCF%FTIME NRSF = RIVER_FORCING(I)%RIVERS_IN_FILE ! RIVER FLUX VAR_N => RIVER_FORCING(I)%FLUX_N VAR_P => RIVER_FORCING(I)%FLUX_P CALL UPDATE_VAR_BRACKET(NCF,VAR_P,VAR_N,RIVTIME,STATUS) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPATE RIVER_FILE TIME BRACKET: BOUNDS EXCEEDED?") end if ALLOCATE(CURRENT(NRSF)) CALL NC_POINT_VAR(VAR_N,VNP) CALL NC_POINT_VAR(VAR_P,VPP) !==================================================== ! Linear interpolation between time points !CURRENT = FTM%NEXT_WGHT * VNP + FTM%PREV_WGHT * VPP ! ! OR ! ! Nearest time sets the value CURRENT = VNP if (FTM%PREV_WGHT .gt. 0.5_sp) CURRENT = VPP !==================================================== DO J =1,NRSF IND = RIVER_FORCING(I)%RIV_FILE2LOC(J) IF(IND /= 0) FLUX(IND) = CURRENT(J) END DO DEALLOCATE(CURRENT) IF(PRESENT(SALT)) THEN ! RIVER SALT VAR_N => RIVER_FORCING(I)%SALT_N VAR_P => RIVER_FORCING(I)%SALT_P CALL UPDATE_VAR_BRACKET(NCF,VAR_P,VAR_N,RIVTIME,STATUS) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPATE RIVER_FILE TIME BRACKET: BOUNDS EXCEEDED?") end if ALLOCATE(CURRENT(NRSF)) CALL NC_POINT_VAR(VAR_N,VNP) CALL NC_POINT_VAR(VAR_P,VPP) !==================================================== ! Linear interpolation between time points !CURRENT = FTM%NEXT_WGHT * VNP + FTM%PREV_WGHT * VPP ! ! OR ! ! Nearest time sets the value CURRENT = VNP if (FTM%PREV_WGHT .gt. 0.5_sp) current = VPP !==================================================== DO J =1,NRSF IND = RIVER_FORCING(I)%RIV_FILE2LOC(J) IF(IND /= 0) SALT(IND) = CURRENT(J) END DO DEALLOCATE(CURRENT) END IF IF(PRESENT(TEMP)) THEN ! RIVER TEMP VAR_N => RIVER_FORCING(I)%TEMP_N VAR_P => RIVER_FORCING(I)%TEMP_P CALL UPDATE_VAR_BRACKET(NCF,VAR_P,VAR_N,RIVTIME,STATUS) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPATE RIVER_FILE TIME BRACKET: BOUNDS EXCEEDED?") end if ALLOCATE(CURRENT(NRSF)) CALL NC_POINT_VAR(VAR_N,VNP) CALL NC_POINT_VAR(VAR_P,VPP) !==================================================== ! Linear interpolation between time points !CURRENT = FTM%NEXT_WGHT * VNP + FTM%PREV_WGHT * VPP ! ! OR ! ! Nearest time sets the value CURRENT = VNP if (FTM%PREV_WGHT .gt. 0.5_sp) current = VPP !==================================================== DO J =1,NRSF IND = RIVER_FORCING(I)%RIV_FILE2LOC(J) IF(IND /= 0) TEMP(IND) = CURRENT(J) END DO DEALLOCATE(CURRENT) END IF # if defined (WATER_QUALITY) IF(PRESENT(WQM)) THEN ! RIVER WATER QUALITY VAR_N => RIVER_FORCING(I)%WQM1_N VAR_P => RIVER_FORCING(I)%WQM1_P CALL UPDATE_VAR_BRACKET(NCF,VAR_P,VAR_N,RIVTIME,STATUS) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPATE RIVER_FILE TIME BRACKET: BOUNDS EXCEEDED?") end if ALLOCATE(CURRENT(NRSF)) CALL NC_POINT_VAR(VAR_N,VNP) CALL NC_POINT_VAR(VAR_P,VPP) !==================================================== ! Linear interpolation between time points !CURRENT = FTM%NEXT_WGHT * VNP + FTM%PREV_WGHT * VPP ! ! OR ! ! Nearest time sets the value CURRENT = VNP if (FTM%PREV_WGHT .gt. 0.5_sp) current = VPP !==================================================== DO J =1,NRSF IND = RIVER_FORCING(I)%RIV_FILE2LOC(J) IF(IND /= 0) WQM(IND,1) = CURRENT(J) END DO DEALLOCATE(CURRENT) VAR_N => RIVER_FORCING(I)%WQM2_N VAR_P => RIVER_FORCING(I)%WQM2_P CALL UPDATE_VAR_BRACKET(NCF,VAR_P,VAR_N,RIVTIME,STATUS) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPATE RIVER_FILE TIME BRACKET: BOUNDS EXCEEDED?") end if ALLOCATE(CURRENT(NRSF)) CALL NC_POINT_VAR(VAR_N,VNP) CALL NC_POINT_VAR(VAR_P,VPP) !==================================================== ! Linear interpolation between time points !CURRENT = FTM%NEXT_WGHT * VNP + FTM%PREV_WGHT * VPP ! ! OR ! ! Nearest time sets the value CURRENT = VNP if (FTM%PREV_WGHT .gt. 0.5_sp) current = VPP !==================================================== DO J =1,NRSF IND = RIVER_FORCING(I)%RIV_FILE2LOC(J) IF(IND /= 0) WQM(IND,2) = CURRENT(J) END DO DEALLOCATE(CURRENT) VAR_N => RIVER_FORCING(I)%WQM3_N VAR_P => RIVER_FORCING(I)%WQM3_P CALL UPDATE_VAR_BRACKET(NCF,VAR_P,VAR_N,RIVTIME,STATUS) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPATE RIVER_FILE TIME BRACKET: BOUNDS EXCEEDED?") end if ALLOCATE(CURRENT(NRSF)) CALL NC_POINT_VAR(VAR_N,VNP) CALL NC_POINT_VAR(VAR_P,VPP) !==================================================== ! Linear interpolation between time points !CURRENT = FTM%NEXT_WGHT * VNP + FTM%PREV_WGHT * VPP ! ! OR ! ! Nearest time sets the value CURRENT = VNP if (FTM%PREV_WGHT .gt. 0.5_sp) current = VPP !==================================================== DO J =1,NRSF IND = RIVER_FORCING(I)%RIV_FILE2LOC(J) IF(IND /= 0) WQM(IND,3) = CURRENT(J) END DO DEALLOCATE(CURRENT) VAR_N => RIVER_FORCING(I)%WQM4_N VAR_P => RIVER_FORCING(I)%WQM4_P CALL UPDATE_VAR_BRACKET(NCF,VAR_P,VAR_N,RIVTIME,STATUS) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPATE RIVER_FILE TIME BRACKET: BOUNDS EXCEEDED?") end if ALLOCATE(CURRENT(NRSF)) CALL NC_POINT_VAR(VAR_N,VNP) CALL NC_POINT_VAR(VAR_P,VPP) !==================================================== ! Linear interpolation between time points !CURRENT = FTM%NEXT_WGHT * VNP + FTM%PREV_WGHT * VPP ! ! OR ! ! Nearest time sets the value CURRENT = VNP if (FTM%PREV_WGHT .gt. 0.5_sp) current = VPP !==================================================== DO J =1,NRSF IND = RIVER_FORCING(I)%RIV_FILE2LOC(J) IF(IND /= 0) WQM(IND,4) = CURRENT(J) END DO DEALLOCATE(CURRENT) VAR_N => RIVER_FORCING(I)%WQM5_N VAR_P => RIVER_FORCING(I)%WQM5_P CALL UPDATE_VAR_BRACKET(NCF,VAR_P,VAR_N,RIVTIME,STATUS) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPATE RIVER_FILE TIME BRACKET: BOUNDS EXCEEDED?") end if ALLOCATE(CURRENT(NRSF)) CALL NC_POINT_VAR(VAR_N,VNP) CALL NC_POINT_VAR(VAR_P,VPP) !==================================================== ! Linear interpolation between time points !CURRENT = FTM%NEXT_WGHT * VNP + FTM%PREV_WGHT * VPP ! ! OR ! ! Nearest time sets the value CURRENT = VNP if (FTM%PREV_WGHT .gt. 0.5_sp) current = VPP !==================================================== DO J =1,NRSF IND = RIVER_FORCING(I)%RIV_FILE2LOC(J) IF(IND /= 0) WQM(IND,5) = CURRENT(J) END DO DEALLOCATE(CURRENT) VAR_N => RIVER_FORCING(I)%WQM6_N VAR_P => RIVER_FORCING(I)%WQM6_P CALL UPDATE_VAR_BRACKET(NCF,VAR_P,VAR_N,RIVTIME,STATUS) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPATE RIVER_FILE TIME BRACKET: BOUNDS EXCEEDED?") end if ALLOCATE(CURRENT(NRSF)) CALL NC_POINT_VAR(VAR_N,VNP) CALL NC_POINT_VAR(VAR_P,VPP) !==================================================== ! Linear interpolation between time points !CURRENT = FTM%NEXT_WGHT * VNP + FTM%PREV_WGHT * VPP ! ! OR ! ! Nearest time sets the value CURRENT = VNP if (FTM%PREV_WGHT .gt. 0.5_sp) current = VPP !==================================================== DO J =1,NRSF IND = RIVER_FORCING(I)%RIV_FILE2LOC(J) IF(IND /= 0) WQM(IND,6) = CURRENT(J) END DO DEALLOCATE(CURRENT) VAR_N => RIVER_FORCING(I)%WQM7_N VAR_P => RIVER_FORCING(I)%WQM7_P CALL UPDATE_VAR_BRACKET(NCF,VAR_P,VAR_N,RIVTIME,STATUS) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPATE RIVER_FILE TIME BRACKET: BOUNDS EXCEEDED?") end if ALLOCATE(CURRENT(NRSF)) CALL NC_POINT_VAR(VAR_N,VNP) CALL NC_POINT_VAR(VAR_P,VPP) !==================================================== ! Linear interpolation between time points !CURRENT = FTM%NEXT_WGHT * VNP + FTM%PREV_WGHT * VPP ! ! OR ! ! Nearest time sets the value CURRENT = VNP if (FTM%PREV_WGHT .gt. 0.5_sp) current = VPP !==================================================== DO J =1,NRSF IND = RIVER_FORCING(I)%RIV_FILE2LOC(J) IF(IND /= 0) WQM(IND,7) = CURRENT(J) END DO DEALLOCATE(CURRENT) VAR_N => RIVER_FORCING(I)%WQM8_N VAR_P => RIVER_FORCING(I)%WQM8_P CALL UPDATE_VAR_BRACKET(NCF,VAR_P,VAR_N,RIVTIME,STATUS) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPATE RIVER_FILE TIME BRACKET: BOUNDS EXCEEDED?") end if ALLOCATE(CURRENT(NRSF)) CALL NC_POINT_VAR(VAR_N,VNP) CALL NC_POINT_VAR(VAR_P,VPP) !==================================================== ! Linear interpolation between time points !CURRENT = FTM%NEXT_WGHT * VNP + FTM%PREV_WGHT * VPP ! ! OR ! ! Nearest time sets the value CURRENT = VNP if (FTM%PREV_WGHT .gt. 0.5_sp) current = VPP !==================================================== DO J =1,NRSF IND = RIVER_FORCING(I)%RIV_FILE2LOC(J) IF(IND /= 0) WQM(IND,8) = CURRENT(J) END DO DEALLOCATE(CURRENT) END IF # endif # if defined (SEDIMENT) IF(PRESENT(SED)) THEN ! RIVER SEDIMENT LOAD FOR SED1 IF(N_SED > 0)THEN VAR_N => RIVER_FORCING(I)%SED1_N VAR_P => RIVER_FORCING(I)%SED1_P CALL UPDATE_VAR_BRACKET(NCF,VAR_P,VAR_N,RIVTIME,STATUS) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPATE RIVER_FILE TIME BRACKET: BOUNDS EXCEEDED?") end if ALLOCATE(CURRENT(NRSF)) CALL NC_POINT_VAR(VAR_N,VNP) CALL NC_POINT_VAR(VAR_P,VPP) CURRENT = VNP if (FTM%PREV_WGHT .gt. 0.5_sp) current = VPP DO J =1,NRSF IND = RIVER_FORCING(I)%RIV_FILE2LOC(J) IF(IND /= 0) SED(IND,1) = CURRENT(J) END DO DEALLOCATE(CURRENT) ENDIF ! RIVER SEDIMENT LOAD FOR SED2 IF(N_SED > 1)THEN VAR_N => RIVER_FORCING(I)%SED2_N VAR_P => RIVER_FORCING(I)%SED2_P CALL UPDATE_VAR_BRACKET(NCF,VAR_P,VAR_N,RIVTIME,STATUS) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPATE RIVER_FILE TIME BRACKET: BOUNDS EXCEEDED?") end if ALLOCATE(CURRENT(NRSF)) CALL NC_POINT_VAR(VAR_N,VNP) CALL NC_POINT_VAR(VAR_P,VPP) CURRENT = VNP if (FTM%PREV_WGHT .gt. 0.5_sp) current = VPP DO J =1,NRSF IND = RIVER_FORCING(I)%RIV_FILE2LOC(J) IF(IND /= 0) SED(IND,2) = CURRENT(J) END DO DEALLOCATE(CURRENT) ENDIF ! RIVER SEDIMENT LOAD FOR SED3 IF(N_SED > 2)THEN VAR_N => RIVER_FORCING(I)%SED3_N VAR_P => RIVER_FORCING(I)%SED3_P CALL UPDATE_VAR_BRACKET(NCF,VAR_P,VAR_N,RIVTIME,STATUS) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPATE RIVER_FILE TIME BRACKET: BOUNDS EXCEEDED?") end if ALLOCATE(CURRENT(NRSF)) CALL NC_POINT_VAR(VAR_N,VNP) CALL NC_POINT_VAR(VAR_P,VPP) CURRENT = VNP if (FTM%PREV_WGHT .gt. 0.5_sp) current = VPP DO J =1,NRSF IND = RIVER_FORCING(I)%RIV_FILE2LOC(J) IF(IND /= 0) SED(IND,3) = CURRENT(J) END DO DEALLOCATE(CURRENT) ENDIF ! RIVER SEDIMENT LOAD FOR SED4 IF(N_SED > 3)THEN VAR_N => RIVER_FORCING(I)%SED4_N VAR_P => RIVER_FORCING(I)%SED4_P CALL UPDATE_VAR_BRACKET(NCF,VAR_P,VAR_N,RIVTIME,STATUS) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPATE RIVER_FILE TIME BRACKET: BOUNDS EXCEEDED?") end if ALLOCATE(CURRENT(NRSF)) CALL NC_POINT_VAR(VAR_N,VNP) CALL NC_POINT_VAR(VAR_P,VPP) CURRENT = VNP if (FTM%PREV_WGHT .gt. 0.5_sp) current = VPP DO J =1,NRSF IND = RIVER_FORCING(I)%RIV_FILE2LOC(J) IF(IND /= 0) SED(IND,4) = CURRENT(J) END DO DEALLOCATE(CURRENT) ENDIF ! RIVER SEDIMENT LOAD FOR SED5 IF(N_SED > 4)THEN VAR_N => RIVER_FORCING(I)%SED5_N VAR_P => RIVER_FORCING(I)%SED5_P CALL UPDATE_VAR_BRACKET(NCF,VAR_P,VAR_N,RIVTIME,STATUS) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPATE RIVER_FILE TIME BRACKET: BOUNDS EXCEEDED?") end if ALLOCATE(CURRENT(NRSF)) CALL NC_POINT_VAR(VAR_N,VNP) CALL NC_POINT_VAR(VAR_P,VPP) CURRENT = VNP if (FTM%PREV_WGHT .gt. 0.5_sp) current = VPP DO J =1,NRSF IND = RIVER_FORCING(I)%RIV_FILE2LOC(J) IF(IND /= 0) SED(IND,5) = CURRENT(J) END DO DEALLOCATE(CURRENT) ENDIF ! RIVER SEDIMENT LOAD FOR SED6 IF(N_SED > 5)THEN VAR_N => RIVER_FORCING(I)%SED6_N VAR_P => RIVER_FORCING(I)%SED6_P CALL UPDATE_VAR_BRACKET(NCF,VAR_P,VAR_N,RIVTIME,STATUS) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPATE RIVER_FILE TIME BRACKET: BOUNDS EXCEEDED?") end if ALLOCATE(CURRENT(NRSF)) CALL NC_POINT_VAR(VAR_N,VNP) CALL NC_POINT_VAR(VAR_P,VPP) CURRENT = VNP if (FTM%PREV_WGHT .gt. 0.5_sp) current = VPP DO J =1,NRSF IND = RIVER_FORCING(I)%RIV_FILE2LOC(J) IF(IND /= 0) SED(IND,6) = CURRENT(J) END DO DEALLOCATE(CURRENT) ENDIF ! RIVER SEDIMENT LOAD FOR SED7 IF(N_SED > 6)THEN VAR_N => RIVER_FORCING(I)%SED7_N VAR_P => RIVER_FORCING(I)%SED7_P CALL UPDATE_VAR_BRACKET(NCF,VAR_P,VAR_N,RIVTIME,STATUS) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPATE RIVER_FILE TIME BRACKET: BOUNDS EXCEEDED?") end if ALLOCATE(CURRENT(NRSF)) CALL NC_POINT_VAR(VAR_N,VNP) CALL NC_POINT_VAR(VAR_P,VPP) CURRENT = VNP if (FTM%PREV_WGHT .gt. 0.5_sp) current = VPP DO J =1,NRSF IND = RIVER_FORCING(I)%RIV_FILE2LOC(J) IF(IND /= 0) SED(IND,7) = CURRENT(J) END DO DEALLOCATE(CURRENT) ENDIF ! RIVER SEDIMENT LOAD FOR SED8 IF(N_SED > 7)THEN VAR_N => RIVER_FORCING(I)%SED8_N VAR_P => RIVER_FORCING(I)%SED8_P CALL UPDATE_VAR_BRACKET(NCF,VAR_P,VAR_N,RIVTIME,STATUS) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPATE RIVER_FILE TIME BRACKET: BOUNDS EXCEEDED?") end if ALLOCATE(CURRENT(NRSF)) CALL NC_POINT_VAR(VAR_N,VNP) CALL NC_POINT_VAR(VAR_P,VPP) CURRENT = VNP if (FTM%PREV_WGHT .gt. 0.5_sp) current = VPP DO J =1,NRSF IND = RIVER_FORCING(I)%RIV_FILE2LOC(J) IF(IND /= 0) SED(IND,8) = CURRENT(J) END DO DEALLOCATE(CURRENT) ENDIF ! RIVER SEDIMENT LOAD FOR SED9 IF(N_SED > 8)THEN VAR_N => RIVER_FORCING(I)%SED9_N VAR_P => RIVER_FORCING(I)%SED9_P CALL UPDATE_VAR_BRACKET(NCF,VAR_P,VAR_N,RIVTIME,STATUS) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPATE RIVER_FILE TIME BRACKET: BOUNDS EXCEEDED?") end if ALLOCATE(CURRENT(NRSF)) CALL NC_POINT_VAR(VAR_N,VNP) CALL NC_POINT_VAR(VAR_P,VPP) CURRENT = VNP if (FTM%PREV_WGHT .gt. 0.5_sp) current = VPP DO J =1,NRSF IND = RIVER_FORCING(I)%RIV_FILE2LOC(J) IF(IND /= 0) SED(IND,9) = CURRENT(J) END DO DEALLOCATE(CURRENT) ENDIF ! RIVER SEDIMENT LOAD FOR SED10 IF(N_SED > 9)THEN VAR_N => RIVER_FORCING(I)%SED10_N VAR_P => RIVER_FORCING(I)%SED10_P CALL UPDATE_VAR_BRACKET(NCF,VAR_P,VAR_N,RIVTIME,STATUS) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPATE RIVER_FILE TIME BRACKET: BOUNDS EXCEEDED?") end if ALLOCATE(CURRENT(NRSF)) CALL NC_POINT_VAR(VAR_N,VNP) CALL NC_POINT_VAR(VAR_P,VPP) CURRENT = VNP if (FTM%PREV_WGHT .gt. 0.5_sp) current = VPP DO J =1,NRSF IND = RIVER_FORCING(I)%RIV_FILE2LOC(J) IF(IND /= 0) SED(IND,10) = CURRENT(J) END DO DEALLOCATE(CURRENT) ENDIF END IF # endif # if defined (BioGen) IF(BIOLOGICAL_MODEL)THEN IF(PRESENT(BIO)) THEN ! RIVER BIOLOGICAL LOAD FOR BIO1 IF(NTT > 0)THEN VAR_N => RIVER_FORCING(I)%BIO1_N VAR_P => RIVER_FORCING(I)%BIO1_P CALL UPDATE_VAR_BRACKET(NCF,VAR_P,VAR_N,RIVTIME,STATUS) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPATE RIVER_FILE TIME BRACKET: BOUNDS EXCEEDED?") end if ALLOCATE(CURRENT(NRSF)) CALL NC_POINT_VAR(VAR_N,VNP) CALL NC_POINT_VAR(VAR_P,VPP) CURRENT = VNP if (FTM%PREV_WGHT .gt. 0.5_sp) current = VPP DO J =1,NRSF IND = RIVER_FORCING(I)%RIV_FILE2LOC(J) IF(IND /= 0) BIO(IND,1) = CURRENT(J) END DO DEALLOCATE(CURRENT) ENDIF ! RIVER BIOLOGICAL LOAD FOR BIO2 IF(NTT > 1)THEN VAR_N => RIVER_FORCING(I)%BIO2_N VAR_P => RIVER_FORCING(I)%BIO2_P CALL UPDATE_VAR_BRACKET(NCF,VAR_P,VAR_N,RIVTIME,STATUS) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPATE RIVER_FILE TIME BRACKET: BOUNDS EXCEEDED?") end if ALLOCATE(CURRENT(NRSF)) CALL NC_POINT_VAR(VAR_N,VNP) CALL NC_POINT_VAR(VAR_P,VPP) CURRENT = VNP if (FTM%PREV_WGHT .gt. 0.5_sp) current = VPP DO J =1,NRSF IND = RIVER_FORCING(I)%RIV_FILE2LOC(J) IF(IND /= 0) BIO(IND,2) = CURRENT(J) END DO DEALLOCATE(CURRENT) ENDIF ! RIVER BIOLOGICAL LOAD FOR BIO3 IF(NTT > 2)THEN VAR_N => RIVER_FORCING(I)%BIO3_N VAR_P => RIVER_FORCING(I)%BIO3_P CALL UPDATE_VAR_BRACKET(NCF,VAR_P,VAR_N,RIVTIME,STATUS) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPATE RIVER_FILE TIME BRACKET: BOUNDS EXCEEDED?") end if ALLOCATE(CURRENT(NRSF)) CALL NC_POINT_VAR(VAR_N,VNP) CALL NC_POINT_VAR(VAR_P,VPP) CURRENT = VNP if (FTM%PREV_WGHT .gt. 0.5_sp) current = VPP DO J =1,NRSF IND = RIVER_FORCING(I)%RIV_FILE2LOC(J) IF(IND /= 0) BIO(IND,3) = CURRENT(J) END DO DEALLOCATE(CURRENT) ENDIF ! RIVER BIOLOGICAL LOAD FOR BIO4 IF(NTT > 3)THEN VAR_N => RIVER_FORCING(I)%BIO4_N VAR_P => RIVER_FORCING(I)%BIO4_P CALL UPDATE_VAR_BRACKET(NCF,VAR_P,VAR_N,RIVTIME,STATUS) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPATE RIVER_FILE TIME BRACKET: BOUNDS EXCEEDED?") end if ALLOCATE(CURRENT(NRSF)) CALL NC_POINT_VAR(VAR_N,VNP) CALL NC_POINT_VAR(VAR_P,VPP) CURRENT = VNP if (FTM%PREV_WGHT .gt. 0.5_sp) current = VPP DO J =1,NRSF IND = RIVER_FORCING(I)%RIV_FILE2LOC(J) IF(IND /= 0) BIO(IND,4) = CURRENT(J) END DO DEALLOCATE(CURRENT) ENDIF ! RIVER BIOLOGICAL LOAD FOR BIO5 IF(NTT > 4)THEN VAR_N => RIVER_FORCING(I)%BIO5_N VAR_P => RIVER_FORCING(I)%BIO5_P CALL UPDATE_VAR_BRACKET(NCF,VAR_P,VAR_N,RIVTIME,STATUS) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPATE RIVER_FILE TIME BRACKET: BOUNDS EXCEEDED?") end if ALLOCATE(CURRENT(NRSF)) CALL NC_POINT_VAR(VAR_N,VNP) CALL NC_POINT_VAR(VAR_P,VPP) CURRENT = VNP if (FTM%PREV_WGHT .gt. 0.5_sp) current = VPP DO J =1,NRSF IND = RIVER_FORCING(I)%RIV_FILE2LOC(J) IF(IND /= 0) BIO(IND,5) = CURRENT(J) END DO DEALLOCATE(CURRENT) ENDIF ! RIVER BIOLOGICAL LOAD FOR BIO6 IF(NTT > 5)THEN VAR_N => RIVER_FORCING(I)%BIO6_N VAR_P => RIVER_FORCING(I)%BIO6_P CALL UPDATE_VAR_BRACKET(NCF,VAR_P,VAR_N,RIVTIME,STATUS) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPATE RIVER_FILE TIME BRACKET: BOUNDS EXCEEDED?") end if ALLOCATE(CURRENT(NRSF)) CALL NC_POINT_VAR(VAR_N,VNP) CALL NC_POINT_VAR(VAR_P,VPP) CURRENT = VNP if (FTM%PREV_WGHT .gt. 0.5_sp) current = VPP DO J =1,NRSF IND = RIVER_FORCING(I)%RIV_FILE2LOC(J) IF(IND /= 0) BIO(IND,6) = CURRENT(J) END DO DEALLOCATE(CURRENT) ENDIF ! RIVER BIOLOGICAL LOAD FOR BIO7 IF(NTT > 6)THEN VAR_N => RIVER_FORCING(I)%BIO7_N VAR_P => RIVER_FORCING(I)%BIO7_P CALL UPDATE_VAR_BRACKET(NCF,VAR_P,VAR_N,RIVTIME,STATUS) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPATE RIVER_FILE TIME BRACKET: BOUNDS EXCEEDED?") end if ALLOCATE(CURRENT(NRSF)) CALL NC_POINT_VAR(VAR_N,VNP) CALL NC_POINT_VAR(VAR_P,VPP) CURRENT = VNP if (FTM%PREV_WGHT .gt. 0.5_sp) current = VPP DO J =1,NRSF IND = RIVER_FORCING(I)%RIV_FILE2LOC(J) IF(IND /= 0) BIO(IND,7) = CURRENT(J) END DO DEALLOCATE(CURRENT) ENDIF ! RIVER BIOLOGICAL LOAD FOR BIO8 IF(NTT > 7)THEN VAR_N => RIVER_FORCING(I)%BIO8_N VAR_P => RIVER_FORCING(I)%BIO8_P CALL UPDATE_VAR_BRACKET(NCF,VAR_P,VAR_N,RIVTIME,STATUS) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPATE RIVER_FILE TIME BRACKET: BOUNDS EXCEEDED?") end if ALLOCATE(CURRENT(NRSF)) CALL NC_POINT_VAR(VAR_N,VNP) CALL NC_POINT_VAR(VAR_P,VPP) CURRENT = VNP if (FTM%PREV_WGHT .gt. 0.5_sp) current = VPP DO J =1,NRSF IND = RIVER_FORCING(I)%RIV_FILE2LOC(J) IF(IND /= 0) BIO(IND,8) = CURRENT(J) END DO DEALLOCATE(CURRENT) ENDIF ! RIVER BIOLOGICAL LOAD FOR BIO9 IF(NTT > 8)THEN VAR_N => RIVER_FORCING(I)%BIO9_N VAR_P => RIVER_FORCING(I)%BIO9_P CALL UPDATE_VAR_BRACKET(NCF,VAR_P,VAR_N,RIVTIME,STATUS) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPATE RIVER_FILE TIME BRACKET: BOUNDS EXCEEDED?") end if ALLOCATE(CURRENT(NRSF)) CALL NC_POINT_VAR(VAR_N,VNP) CALL NC_POINT_VAR(VAR_P,VPP) CURRENT = VNP if (FTM%PREV_WGHT .gt. 0.5_sp) current = VPP DO J =1,NRSF IND = RIVER_FORCING(I)%RIV_FILE2LOC(J) IF(IND /= 0) BIO(IND,9) = CURRENT(J) END DO DEALLOCATE(CURRENT) ENDIF ! RIVER BIOLOGICAL LOAD FOR BIO10 IF(NTT > 9)THEN VAR_N => RIVER_FORCING(I)%BIO10_N VAR_P => RIVER_FORCING(I)%BIO10_P CALL UPDATE_VAR_BRACKET(NCF,VAR_P,VAR_N,RIVTIME,STATUS) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPATE RIVER_FILE TIME BRACKET: BOUNDS EXCEEDED?") end if ALLOCATE(CURRENT(NRSF)) CALL NC_POINT_VAR(VAR_N,VNP) CALL NC_POINT_VAR(VAR_P,VPP) CURRENT = VNP if (FTM%PREV_WGHT .gt. 0.5_sp) current = VPP DO J =1,NRSF IND = RIVER_FORCING(I)%RIV_FILE2LOC(J) IF(IND /= 0) BIO(IND,10) = CURRENT(J) END DO DEALLOCATE(CURRENT) ENDIF ! RIVER BIOLOGICAL LOAD FOR BIO11 IF(NTT > 10)THEN VAR_N => RIVER_FORCING(I)%BIO11_N VAR_P => RIVER_FORCING(I)%BIO11_P CALL UPDATE_VAR_BRACKET(NCF,VAR_P,VAR_N,RIVTIME,STATUS) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPATE RIVER_FILE TIME BRACKET: BOUNDS EXCEEDED?") end if ALLOCATE(CURRENT(NRSF)) CALL NC_POINT_VAR(VAR_N,VNP) CALL NC_POINT_VAR(VAR_P,VPP) CURRENT = VNP if (FTM%PREV_WGHT .gt. 0.5_sp) current = VPP DO J =1,NRSF IND = RIVER_FORCING(I)%RIV_FILE2LOC(J) IF(IND /= 0) BIO(IND,11) = CURRENT(J) END DO DEALLOCATE(CURRENT) ENDIF ! RIVER BIOLOGICAL LOAD FOR BIO12 IF(NTT > 11)THEN VAR_N => RIVER_FORCING(I)%BIO12_N VAR_P => RIVER_FORCING(I)%BIO12_P CALL UPDATE_VAR_BRACKET(NCF,VAR_P,VAR_N,RIVTIME,STATUS) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPATE RIVER_FILE TIME BRACKET: BOUNDS EXCEEDED?") end if ALLOCATE(CURRENT(NRSF)) CALL NC_POINT_VAR(VAR_N,VNP) CALL NC_POINT_VAR(VAR_P,VPP) CURRENT = VNP if (FTM%PREV_WGHT .gt. 0.5_sp) current = VPP DO J =1,NRSF IND = RIVER_FORCING(I)%RIV_FILE2LOC(J) IF(IND /= 0) BIO(IND,12) = CURRENT(J) END DO DEALLOCATE(CURRENT) ENDIF ! RIVER BIOLOGICAL LOAD FOR BIO13 IF(NTT > 12)THEN VAR_N => RIVER_FORCING(I)%BIO13_N VAR_P => RIVER_FORCING(I)%BIO13_P CALL UPDATE_VAR_BRACKET(NCF,VAR_P,VAR_N,RIVTIME,STATUS) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPATE RIVER_FILE TIME BRACKET: BOUNDS EXCEEDED?") end if ALLOCATE(CURRENT(NRSF)) CALL NC_POINT_VAR(VAR_N,VNP) CALL NC_POINT_VAR(VAR_P,VPP) CURRENT = VNP if (FTM%PREV_WGHT .gt. 0.5_sp) current = VPP DO J =1,NRSF IND = RIVER_FORCING(I)%RIV_FILE2LOC(J) IF(IND /= 0) BIO(IND,13) = CURRENT(J) END DO DEALLOCATE(CURRENT) ENDIF ! RIVER BIOLOGICAL LOAD FOR BIO14 IF(NTT > 13)THEN VAR_N => RIVER_FORCING(I)%BIO14_N VAR_P => RIVER_FORCING(I)%BIO14_P CALL UPDATE_VAR_BRACKET(NCF,VAR_P,VAR_N,RIVTIME,STATUS) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPATE RIVER_FILE TIME BRACKET: BOUNDS EXCEEDED?") end if ALLOCATE(CURRENT(NRSF)) CALL NC_POINT_VAR(VAR_N,VNP) CALL NC_POINT_VAR(VAR_P,VPP) CURRENT = VNP if (FTM%PREV_WGHT .gt. 0.5_sp) current = VPP DO J =1,NRSF IND = RIVER_FORCING(I)%RIV_FILE2LOC(J) IF(IND /= 0) BIO(IND,14) = CURRENT(J) END DO DEALLOCATE(CURRENT) ENDIF ! RIVER BIOLOGICAL LOAD FOR BIO15 IF(NTT > 14)THEN VAR_N => RIVER_FORCING(I)%BIO15_N VAR_P => RIVER_FORCING(I)%BIO15_P CALL UPDATE_VAR_BRACKET(NCF,VAR_P,VAR_N,RIVTIME,STATUS) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPATE RIVER_FILE TIME BRACKET: BOUNDS EXCEEDED?") end if ALLOCATE(CURRENT(NRSF)) CALL NC_POINT_VAR(VAR_N,VNP) CALL NC_POINT_VAR(VAR_P,VPP) CURRENT = VNP if (FTM%PREV_WGHT .gt. 0.5_sp) current = VPP DO J =1,NRSF IND = RIVER_FORCING(I)%RIV_FILE2LOC(J) IF(IND /= 0) BIO(IND,15) = CURRENT(J) END DO DEALLOCATE(CURRENT) ENDIF ! RIVER BIOLOGICAL LOAD FOR BIO16 IF(NTT > 15)THEN VAR_N => RIVER_FORCING(I)%BIO16_N VAR_P => RIVER_FORCING(I)%BIO16_P CALL UPDATE_VAR_BRACKET(NCF,VAR_P,VAR_N,RIVTIME,STATUS) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPATE RIVER_FILE TIME BRACKET: BOUNDS EXCEEDED?") end if ALLOCATE(CURRENT(NRSF)) CALL NC_POINT_VAR(VAR_N,VNP) CALL NC_POINT_VAR(VAR_P,VPP) CURRENT = VNP if (FTM%PREV_WGHT .gt. 0.5_sp) current = VPP DO J =1,NRSF IND = RIVER_FORCING(I)%RIV_FILE2LOC(J) IF(IND /= 0) BIO(IND,16) = CURRENT(J) END DO DEALLOCATE(CURRENT) ENDIF ! RIVER BIOLOGICAL LOAD FOR BIO17 IF(NTT > 16)THEN VAR_N => RIVER_FORCING(I)%BIO17_N VAR_P => RIVER_FORCING(I)%BIO17_P CALL UPDATE_VAR_BRACKET(NCF,VAR_P,VAR_N,RIVTIME,STATUS) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPATE RIVER_FILE TIME BRACKET: BOUNDS EXCEEDED?") end if ALLOCATE(CURRENT(NRSF)) CALL NC_POINT_VAR(VAR_N,VNP) CALL NC_POINT_VAR(VAR_P,VPP) CURRENT = VNP if (FTM%PREV_WGHT .gt. 0.5_sp) current = VPP DO J =1,NRSF IND = RIVER_FORCING(I)%RIV_FILE2LOC(J) IF(IND /= 0) BIO(IND,17) = CURRENT(J) END DO DEALLOCATE(CURRENT) ENDIF ! RIVER BIOLOGICAL LOAD FOR BIO18 IF(NTT > 17)THEN VAR_N => RIVER_FORCING(I)%BIO18_N VAR_P => RIVER_FORCING(I)%BIO18_P CALL UPDATE_VAR_BRACKET(NCF,VAR_P,VAR_N,RIVTIME,STATUS) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPATE RIVER_FILE TIME BRACKET: BOUNDS EXCEEDED?") end if ALLOCATE(CURRENT(NRSF)) CALL NC_POINT_VAR(VAR_N,VNP) CALL NC_POINT_VAR(VAR_P,VPP) CURRENT = VNP if (FTM%PREV_WGHT .gt. 0.5_sp) current = VPP DO J =1,NRSF IND = RIVER_FORCING(I)%RIV_FILE2LOC(J) IF(IND /= 0) BIO(IND,18) = CURRENT(J) END DO DEALLOCATE(CURRENT) ENDIF ! RIVER BIOLOGICAL LOAD FOR BIO19 IF(NTT > 18)THEN VAR_N => RIVER_FORCING(I)%BIO19_N VAR_P => RIVER_FORCING(I)%BIO19_P CALL UPDATE_VAR_BRACKET(NCF,VAR_P,VAR_N,RIVTIME,STATUS) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPATE RIVER_FILE TIME BRACKET: BOUNDS EXCEEDED?") end if ALLOCATE(CURRENT(NRSF)) CALL NC_POINT_VAR(VAR_N,VNP) CALL NC_POINT_VAR(VAR_P,VPP) CURRENT = VNP if (FTM%PREV_WGHT .gt. 0.5_sp) current = VPP DO J =1,NRSF IND = RIVER_FORCING(I)%RIV_FILE2LOC(J) IF(IND /= 0) BIO(IND,19) = CURRENT(J) END DO DEALLOCATE(CURRENT) ENDIF ! RIVER BIOLOGICAL LOAD FOR BIO20 IF(NTT > 19)THEN VAR_N => RIVER_FORCING(I)%BIO20_N VAR_P => RIVER_FORCING(I)%BIO20_P CALL UPDATE_VAR_BRACKET(NCF,VAR_P,VAR_N,RIVTIME,STATUS) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPATE RIVER_FILE TIME BRACKET: BOUNDS EXCEEDED?") end if ALLOCATE(CURRENT(NRSF)) CALL NC_POINT_VAR(VAR_N,VNP) CALL NC_POINT_VAR(VAR_P,VPP) CURRENT = VNP if (FTM%PREV_WGHT .gt. 0.5_sp) current = VPP DO J =1,NRSF IND = RIVER_FORCING(I)%RIV_FILE2LOC(J) IF(IND /= 0) BIO(IND,20) = CURRENT(J) END DO DEALLOCATE(CURRENT) ENDIF END IF END IF ! END OF BIOLOGICAL MODEL # endif END DO ! FOR EACH FILE END SUBROUTINE UPDATE_RIVERS !==============================================================================| SUBROUTINE UPDATE_GROUNDWATER(NOW,GW_FLUX,GW_TEMP,GW_SALT) IMPLICIT NONE TYPE(TIME), INTENT(IN) :: NOW TYPE(TIME) :: GWTIME REAL(SP), ALLOCATABLE :: GW_FLUX(:) REAL(SP), ALLOCATABLE, OPTIONAL :: GW_SALT(:) REAL(SP), ALLOCATABLE, OPTIONAL :: GW_TEMP(:) TYPE(NCFTIME), POINTER :: FTM INTEGER :: STATUS REAL(SP), POINTER :: VNP(:), VPP(:) IF(.NOT. ALLOCATED(GW_FLUX)) CALL FATAL_ERROR & &("THE GROUNDWATER FLUX VARIABLE PASSED TO UPDATE IS NOT ALLOCATED") !=================================================== SELECT CASE(GROUNDWATER_KIND) !=================================================== CASE (CNSTNT) ! CONSTANT GROUND WATER FORCING IS ALWAYS A FLOW RATE (M/S)... ! CONVERT TO A FLUX GW_FLUX(1:MT) = GROUNDWATER_FLOW*ART1(1:MT) IF(GROUNDWATER_TEMP_ON .and. PRESENT(GW_TEMP)) THEN IF(.NOT. ALLOCATED(GW_TEMP)) CALL FATAL_ERROR & &("THE GROUNDWATER TEMPERATURE VARIABLE PASSED TO UPDATE IS NOT ALLOCATED") GW_TEMP(1:MT) = groundwater_temp END IF IF(GROUNDWATER_SALT_ON .and. PRESENT(GW_SALT)) THEN IF(.NOT. ALLOCATED(GW_SALT)) CALL FATAL_ERROR & &("THE GROUNDWATER SALINITY VARIABLE PASSED TO UPDATE IS NOT ALLOCATED") GW_SALT(1:MT) = groundwater_salt END IF RETURN CASE(STTC) CALL FATAL_ERROR("STATIC HEATING Not Set Up Yet") CASE(TMDPNDNT) CALL FATAL_ERROR("TIME DEPENDANT HEATING Not Set Up Yet") CASE(PRDC) ! TO SET ZERO TIME PHASE USING RUNFILE START TIME ! GWTIME= NOW - RUNFILE_StartTime ! TO USE ZERO AS THE PHASE OF THE FORCING GWTIME= NOW GWTIME = MOD(GWTIME,GWATER_PERIOD) CASE(VRBL) GWTIME = NOW END SELECT !=================================================== !=================================================== !=================================================== SELECT CASE(GWATER_FORCING_TYPE) !=================================================== CASE(GWATER_IS_FVCOMGRID) FTM => GWATER_FILE%FTIME ! GROUND WATER FLUX CALL UPDATE_VAR_BRACKET(GWATER_FILE,GWATER_FLUX_P,GWATER_FLUX_N,GWTIME,STATUS) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPATE GROUNDWATER_FILE TIME BRACKET: BOUNDS EXCEEDED?") end if CALL NC_POINT_VAR(GWATER_FLUX_N,VNP) CALL NC_POINT_VAR(GWATER_FLUX_P,VPP) GW_FLUX = FTM%NEXT_WGHT * VNP + FTM%PREV_WGHT * VPP ! IF THE GROUND WATER IS A FLOW RATE CONVERT TO A FLUX IF(GWATER_UNITS == GWATER_MS_1 ) GW_FLUX = GW_FLUX *ART1 ! GROUND WATER TEMP IF(GROUNDWATER_TEMP_ON .and. PRESENT(GW_TEMP)) THEN IF(.NOT. ALLOCATED(GW_TEMP)) CALL FATAL_ERROR & &("THE GROUNDWATER TEMPERATURE VARIABLE PASSED TO UPDATE IS NOT ALLOCATED") CALL UPDATE_VAR_BRACKET(GWATER_FILE,GWATER_TEMP_P,GWATER_TEMP_N,GWTIME,STATUS) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPATE GROUNDWATER_FILE TIME BRACKET: BOUNDS EXCEEDED?") end if CALL NC_POINT_VAR(GWATER_TEMP_N,VNP) CALL NC_POINT_VAR(GWATER_TEMP_P,VPP) GW_TEMP = FTM%NEXT_WGHT * VNP + FTM%PREV_WGHT * VPP END IF ! GROUND WATER SALT IF(GROUNDWATER_SALT_ON .and. PRESENT(GW_SALT)) THEN IF(.NOT. ALLOCATED(GW_SALT)) CALL FATAL_ERROR & &("THE GROUNDWATER SALINITY VARIABLE PASSED TO UPDATE IS NOT ALLOCATED") CALL UPDATE_VAR_BRACKET(GWATER_FILE,GWATER_SALT_P,GWATER_SALT_N,GWTIME,STATUS) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPATE GROUNDWATER_FILE TIME BRACKET: BOUNDS EXCEEDED?") end if CALL NC_POINT_VAR(GWATER_SALT_N,VNP) CALL NC_POINT_VAR(GWATER_SALT_P,VPP) GW_SALT = FTM%NEXT_WGHT * VNP + FTM%PREV_WGHT * VPP END IF CASE DEFAULT CALL FATAL_ERROR("UNKNOWN GROUNDWATER_FORCING_TYPE IN UPDATE GROUNDWATER") END SELECT END SUBROUTINE UPDATE_GROUNDWATER !==============================================================================| # if !defined (HEATING_CALCULATED) && !defined (HEATING_SOLAR) SUBROUTINE UPDATE_HEAT(NOW,HEAT_SWV,HEAT_NET) IMPLICIT NONE TYPE(TIME), INTENT(IN) :: NOW TYPE(TIME) :: HTIME REAL(SP), ALLOCATABLE :: HEAT_SWV(:), HEAT_NET(:) TYPE(NCFTIME), POINTER :: FTM INTEGER :: STATUS REAL(SP), POINTER :: VNP(:), VPP(:) IF(.NOT. ALLOCATED(HEAT_SWV)) CALL FATAL_ERROR & &("THE HEAT SHORTWAVE VARIABLE PASSED TO UPDATE IS NOT ALLOCATED") IF(.NOT. ALLOCATED(HEAT_NET)) CALL FATAL_ERROR & &("THE NET HEAT VARIABLE PASSED TO UPDATE IS NOT ALLOCATED") !=================================================== SELECT CASE(HEATING_KIND) !=================================================== CASE (CNSTNT) HEAT_SWV(1:MT) = HEATING_RADIATION HEAT_NET(1:MT) = HEATING_NETFLUX RETURN CASE(STTC) CALL FATAL_ERROR("STATIC HEATING Not Set Up Yet") CASE(TMDPNDNT) CALL FATAL_ERROR("TIME DEPENDANT HEATING Not Set Up Yet") CASE(PRDC) ! TO SET ZERO TIME PHASE USING RUNFILE START TIME ! HTIME= NOW - RUNFILE_StartTime ! TO USE ZERO AS THE PHASE OF THE FORCING HTIME= NOW HTIME = MOD(HTIME,HEAT_PERIOD) CASE(VRBL) HTIME = NOW END SELECT !=================================================== !=================================================== !=================================================== SELECT CASE(HEAT_FORCING_TYPE) !=================================================== CASE(HEAT_IS_WRFGRID) FTM => HEAT_FILE%FTIME ! SHORT WAVE RADIATION CALL UPDATE_VAR_BRACKET(HEAT_FILE,HEAT_SWV_P,HEAT_SWV_N,HTIME,STATUS,HEAT_INTP_N) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPATE HEAT_FILE TIME BRACKET: BOUNDS EXCEEDED?") end if CALL NC_POINT_VAR(HEAT_SWV_N,VNP) CALL NC_POINT_VAR(HEAT_SWV_P,VPP) HEAT_SWV = FTM%NEXT_WGHT * VNP + FTM%PREV_WGHT * VPP ! NET HEAT FLUX CALL UPDATE_VAR_BRACKET(HEAT_FILE,HEAT_NET_P,HEAT_NET_N,HTIME,STATUS,HEAT_INTP_N) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPATE HEAT_FILE TIME BRACKET: BOUNDS EXCEEDED?") end if CALL NC_POINT_VAR(HEAT_NET_N,VNP) CALL NC_POINT_VAR(HEAT_NET_P,VPP) HEAT_NET = FTM%NEXT_WGHT * VNP + FTM%PREV_WGHT * VPP CASE(HEAT_IS_FVCOMGRID) FTM => HEAT_FILE%FTIME ! SHORT WAVE RADIATION CALL UPDATE_VAR_BRACKET(HEAT_FILE,HEAT_SWV_P,HEAT_SWV_N,HTIME,STATUS) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPATE HEAT_FILE TIME BRACKET: BOUNDS EXCEEDED?") end if CALL NC_POINT_VAR(HEAT_SWV_N,VNP) CALL NC_POINT_VAR(HEAT_SWV_P,VPP) HEAT_SWV = FTM%NEXT_WGHT * VNP + FTM%PREV_WGHT * VPP ! NET HEAT FLUX CALL UPDATE_VAR_BRACKET(HEAT_FILE,HEAT_NET_P,HEAT_NET_N,HTIME,STATUS) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPATE HEAT_FILE TIME BRACKET: BOUNDS EXCEEDED?") end if CALL NC_POINT_VAR(HEAT_NET_N,VNP) CALL NC_POINT_VAR(HEAT_NET_P,VPP) HEAT_NET = FTM%NEXT_WGHT * VNP + FTM%PREV_WGHT * VPP CASE DEFAULT CALL FATAL_ERROR("UNKNOWN HEAT_FORCING_TYPE IN UPDATE HEAT") END SELECT END SUBROUTINE UPDATE_HEAT # endif !==============================================================================| !==============================================================================| # if defined (HEATING_CALCULATED) SUBROUTINE UPDATE_HEAT_CALCULATED(NOW,HEAT_SWV,HEAT_NET,HEAT_SENSIBLE,HEAT_LATENT,HEAT_RLN,& Cwave,HSC1,TAU_WIND,U_star,Cd) ! Siqi Li, 2021-01-27 ! SUBROUTINE UPDATE_HEAT_CALCULATED(NOW,HEAT_SWV,HEAT_NET,HEAT_SENSIBLE,HEAT_LATENT,HEAT_RLN) IMPLICIT NONE TYPE(TIME), INTENT(IN) :: NOW TYPE(TIME) :: HTIME REAL(SP), ALLOCATABLE :: HEAT_SWV(:), HEAT_NET(:) REAL(SP), ALLOCATABLE :: HEAT_SENSIBLE(:), HEAT_LATENT(:), HEAT_RLN(:) REAL(SP), ALLOCATABLE :: TAU_WIND(:), U_star(:), Cd(:), Cwave(:), HSC1(:) ! Siqi Li, 2021-01-27 REAL(SP), DIMENSION(0:MT) :: TAU_node, USR_node, Cd_node ! Siqi Li, 2021-01-27 TYPE(NCFTIME), POINTER :: FTM INTEGER :: STATUS,I,J REAL(SP), POINTER :: VNP(:), VPP(:) REAL(SP) :: WDS REAL(SP) :: HSB,HLB,TAU,USR,DTER REAL(SP), DIMENSION(0:NT) :: WDSN REAL(SP) :: t1k,ulw_airf ! ejw 8/16/2006 IF(.NOT. ALLOCATED(HEAT_SWV)) CALL FATAL_ERROR & &("THE HEAT SHORTWAVE VARIABLE PASSED TO UPDATE IS NOT ALLOCATED") IF(.NOT. ALLOCATED(HEAT_NET)) CALL FATAL_ERROR & &("THE NET HEAT VARIABLE PASSED TO UPDATE IS NOT ALLOCATED") IF(.NOT. ALLOCATED(HEAT_SENSIBLE)) CALL FATAL_ERROR & &("THE SENSIBLE HEAT VARIABLE PASSED TO UPDATE IS NOT ALLOCATED") IF(.NOT. ALLOCATED(HEAT_LATENT)) CALL FATAL_ERROR & &("THE LATENT HEAT VARIABLE PASSED TO UPDATE IS NOT ALLOCATED") IF(.NOT. ALLOCATED(HEAT_RLN)) CALL FATAL_ERROR & &("THE LONGWAVE HEAT VARIABLE PASSED TO UPDATE IS NOT ALLOCATED") IF(WIND_TYPE /= 'speed')CALL FATAL_ERROR("WIND_TYPE must be 'speed' for heat flux calculating") !=================================================== SELECT CASE(HEATING_CALCULATE_KIND) !=================================================== CASE (CNSTNT) T_AIR(1:MT) = AIR_TEMPERATURE RH_AIR(1:MT) = RELATIVE_HUMIDITY PA_AIR(1:MT) = SURFACE_PRESSURE DLW_AIR(1:MT) = LONGWAVE_RADIATION DSW_AIR(1:MT) = SHORTWAVE_RADIATION WDSN(1:NT) = SQRT(UUWIND(1:NT)*UUWIND(1:NT)+VVWIND(1:NT)*VVWIND(1:NT)) DO I=1,MT WDS = 0.0_SP DO J=1,NTVE(I) WDS = WDS + WDSN(NBVE(I,J)) END DO WDS = WDS/FLOAT(NTVE(I)) IF(TRIM(COARE_VERSION) == 'COARE26Z')THEN !---> Siqi Li, 2021-01-27 : add Cd CALL COARE26Z(WDS,ZUU,T_AIR(I),ZTT,RH_AIR(I),ZQQ,PA_AIR(I),T1(I,1), & DLW_AIR(I),DSW_AIR(I),TAU,HSB,HLB,CORR(I),USR,DTER,Cd_node(I)) ! CALL COARE26Z(WDS,ZUU,T_AIR(I),ZTT,RH_AIR(I),ZQQ,PA_AIR(I),T1(I,1), & ! DLW_AIR(I),DSW_AIR(I),TAU,HSB,HLB,CORR(I),USR,DTER) !MDR include USR, DTER TAU_node(I) = TAU USR_node(I) = USR !<--- Siqi Li, 2021-01-27 IF(.NOT. HEATING_FRESHWATER)THEN t1k=t1(i,1)+273.16_sp ulw_airf=-emmiss*StefBo*t1k*t1k*t1k*t1k HEAT_NET(I) = DLW_AIR(I)+DSW_AIR(I)+HSB+HLB+ulw_airf ! ejw 8/16/2006 based on ROMS HEAT_SWV(I) = DSW_AIR(I) !EJA edit - output sensible and latent heat flux HEAT_SENSIBLE(I) = HSB HEAT_LATENT(I) = HLB !g.l. 10/10/2017 HEAT_RLN(I) = DLW_AIR(I) HEAT_RLN(I) = DLW_AIR(I)+ulw_airf ELSE USRCOARE(I) = USR !MDR 3-19-2013 for wind wave mix ! t1k=t1(i,1)+273.16_sp !MDR 4-24-2013 t1k=t1(i,1)-DTER+273.16_sp !MDR 4-24-2013, include cool skin adjustment to surface temp !MDR ulw_airf=-emmiss*StefBo*t1k*t1k*t1k*t1k !MDR HEAT_NET(I) = DLW_AIR(I)+DSW_AIR(I)+HSB+HLB+ulw_airf ! ejw 8/16/2006 based on ROMS ulw_airf=-StefBo*t1k*t1k*t1k*t1k HEAT_NET(I) = DSW_AIR(I)+HSB+HLB+emmiss*(DLW_AIR(I)+ulw_airf) !MDR, apply emmiss to NET long wave, as in COARE HEAT_SWV(I) = DSW_AIR(I) !EJA edit - output sensible and latent heat flux HEAT_SENSIBLE(I) = HSB HEAT_LATENT(I) = HLB !g.l. 10/10/2017 HEAT_RLN(I) = DLW_AIR(I) HEAT_RLN(I) = emmiss*(DLW_AIR(I)+ulw_airf) END IF ELSE IF(TRIM(COARE_VERSION) == 'COARE40VN')THEN RAIN(I) = QPREC(I)*3600.0_SP*1000.0_SP ! change unit to mm/hr from m/s ZI40 = fmiss CP40 = Cwave(I) SIGH = HSC1(I) !---> Siqi Li, 2021-01-27 CALL COARE40VN(WDS,ZUU,T_AIR(I),ZTT,RH_AIR(I),ZQQ,PA_AIR(I),T1(I,1), & DLW_AIR(I),DSW_AIR(I),TAU,HSB,HLB,CORR(I),ZI40(I),RAIN(I),CP40(I),SIGH(I),fmiss,USR,DTER,Cd_node(I)) TAU_node(I) = TAU USR_node(I) = USR !<--- Siqi Li, 2021-01-27 IF(.NOT. HEATING_FRESHWATER)THEN t1k=t1(i,1)+273.16_sp ulw_airf=-emmiss*StefBo*t1k*t1k*t1k*t1k HEAT_NET(I) = DLW_AIR(I)+DSW_AIR(I)+HSB+HLB+ulw_airf ! ejw 8/16/2006 based on ROMS HEAT_SWV(I) = DSW_AIR(I) !EJA edit - output sensible and latent heat flux HEAT_SENSIBLE(I) = HSB HEAT_LATENT(I) = HLB !g.l. 10/10/2017 HEAT_RLN(I) = DLW_AIR(I) HEAT_RLN(I) = DLW_AIR(I)+ulw_airf ELSE USRCOARE(I) = USR !MDR 3-19-2013 for wind wave mix ! t1k=t1(i,1)+273.16_sp !MDR 4-24-2013 t1k=t1(i,1)-DTER+273.16_sp !MDR 4-24-2013, include cool skin adjustment to surface temp !MDR ulw_airf=-emmiss*StefBo*t1k*t1k*t1k*t1k !MDR HEAT_NET(I) = DLW_AIR(I)+DSW_AIR(I)+HSB+HLB+ulw_airf ! ejw 8/16/2006 based on ROMS ulw_airf=-StefBo*t1k*t1k*t1k*t1k HEAT_NET(I) = DSW_AIR(I)+HSB+HLB+emmiss*(DLW_AIR(I)+ulw_airf) !MDR, apply emmiss to NET long wave, as in COARE HEAT_SWV(I) = DSW_AIR(I) !EJA edit - output sensible and latent heat flux HEAT_SENSIBLE(I) = HSB HEAT_LATENT(I) = HLB !g.l. 10/10/2017 HEAT_RLN(I) = DLW_AIR(I) HEAT_RLN(I) = emmiss*(DLW_AIR(I)+ulw_airf) END IF ELSE CALL FATAL_ERROR("The value of COARE_VERSION should be 'COARE26Z' or 'COARE40VN'") END IF END DO !---> Siqi Li, 2021-01-27 DO I = 1, NT TAU_WIND(I) = (TAU_node(NV(I,1))+TAU_node(NV(I,2))+TAU_node(NV(I,3))) / 3.0_SP U_star(I) = (USR_node(NV(I,1))+USR_node(NV(I,2))+USR_node(NV(I,3))) / 3.0_SP Cd(I) = (Cd_node(NV(I,1))+Cd_node(NV(I,2))+Cd_node(NV(I,3))) / 3.0_SP END DO !<--- Siqi Li, 2021-01-27 RETURN CASE(STTC) CALL FATAL_ERROR("STATIC HEATING Not Set Up Yet") CASE(TMDPNDNT) CALL FATAL_ERROR("TIME DEPENDANT HEATING Not Set Up Yet") CASE(PRDC) ! TO SET ZERO TIME PHASE USING RUNFILE START TIME ! HTIME= NOW - RUNFILE_StartTime ! TO USE ZERO AS THE PHASE OF THE FORCING HTIME= NOW HTIME = MOD(HTIME,HEAT_PERIOD) CASE(VRBL) HTIME = NOW END SELECT !=================================================== !=================================================== !=================================================== SELECT CASE(HEAT_FORCING_TYPE) !=================================================== CASE(HEAT_IS_WRFGRID) FTM => HEAT_FILE%FTIME ! ! BULK AIR TEMPERATURE CALL UPDATE_VAR_BRACKET(HEAT_FILE,T_AIR_P,T_AIR_N,HTIME,STATUS,HEAT_INTP_N) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPATE HEAT_FILE TIME BRACKET: BOUNDS EXCEEDED?") end if CALL NC_POINT_VAR(T_AIR_N,VNP) CALL NC_POINT_VAR(T_AIR_P,VPP) T_AIR = FTM%NEXT_WGHT * VNP + FTM%PREV_WGHT * VPP ! ! RELATIVE HUMIDITY CALL UPDATE_VAR_BRACKET(HEAT_FILE,RH_AIR_P,RH_AIR_N,HTIME,STATUS,HEAT_INTP_N) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPATE HEAT_FILE TIME BRACKET: BOUNDS EXCEEDED?") end if CALL NC_POINT_VAR(RH_AIR_N,VNP) CALL NC_POINT_VAR(RH_AIR_P,VPP) RH_AIR = FTM%NEXT_WGHT * VNP + FTM%PREV_WGHT * VPP ! ! SURFACE PRESSURE CALL UPDATE_VAR_BRACKET(HEAT_FILE,PA_AIR_P,PA_AIR_N,HTIME,STATUS,HEAT_INTP_N) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPATE HEAT_FILE TIME BRACKET: BOUNDS EXCEEDED?") end if CALL NC_POINT_VAR(PA_AIR_N,VNP) CALL NC_POINT_VAR(PA_AIR_P,VPP) PA_AIR = FTM%NEXT_WGHT * VNP + FTM%PREV_WGHT * VPP PA_AIR = PA_AIR * Pair_unit_factor ! Siqi Li, 2021-01-27 ! ! DOWNWARD LONGWAVE RADIATION CALL UPDATE_VAR_BRACKET(HEAT_FILE,DLW_AIR_P,DLW_AIR_N,HTIME,STATUS,HEAT_INTP_N) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPATE HEAT_FILE TIME BRACKET: BOUNDS EXCEEDED?") end if CALL NC_POINT_VAR(DLW_AIR_N,VNP) CALL NC_POINT_VAR(DLW_AIR_P,VPP) DLW_AIR = FTM%NEXT_WGHT * VNP + FTM%PREV_WGHT * VPP ! ! DOWNWARD SHORTWAVE RADIATION CALL UPDATE_VAR_BRACKET(HEAT_FILE,DSW_AIR_P,DSW_AIR_N,HTIME,STATUS,HEAT_INTP_N) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPATE HEAT_FILE TIME BRACKET: BOUNDS EXCEEDED?") end if CALL NC_POINT_VAR(DSW_AIR_N,VNP) CALL NC_POINT_VAR(DSW_AIR_P,VPP) DSW_AIR = FTM%NEXT_WGHT * VNP + FTM%PREV_WGHT * VPP ! WDSN(1:NT) = SQRT(UUWIND(1:NT)*UUWIND(1:NT)+VVWIND(1:NT)*VVWIND(1:NT)) DO I=1,M WDS = 0.0_SP DO J=1,NTVE(I) WDS = WDS + WDSN(NBVE(I,J)) END DO WDS = WDS/FLOAT(NTVE(I)) IF(TRIM(COARE_VERSION) == 'COARE26Z')THEN !---> Siqi Li, 2021-01-27 : add Cd CALL COARE26Z(WDS,ZUU,T_AIR(I),ZTT,RH_AIR(I),ZQQ,PA_AIR(I),T1(I,1), & DLW_AIR(I),DSW_AIR(I),TAU,HSB,HLB,CORR(I),USR,DTER,Cd_node(I)) ! CALL COARE26Z(WDS,ZUU,T_AIR(I),ZTT,RH_AIR(I),ZQQ,PA_AIR(I),T1(I,1), & ! & DLW_AIR(I),DSW_AIR(I),TAU,HSB,HLB,CORR(I),USR,DTER) !MDR include USR, DTER TAU_node(I) = TAU USR_node(I) = USR !<--- Siqi Li, 2021-01-27 IF(.NOT. HEATING_FRESHWATER)THEN t1k=t1(i,1)+273.16_sp ulw_airf=-emmiss*StefBo*t1k*t1k*t1k*t1k HEAT_NET(I) = DLW_AIR(I)+DSW_AIR(I)+HSB+HLB+ulw_airf ! ejw 8/16/2006 based on ROMS HEAT_SWV(I) = DSW_AIR(I) !EJA edit - output sensible and latent heat flux HEAT_SENSIBLE(I) = HSB HEAT_LATENT(I) = HLB !g.l. 10/10/2017 HEAT_RLN(I) = DLW_AIR(I) HEAT_RLN(I) = DLW_AIR(I)+ulw_airf ELSE USRCOARE(I) = USR !MDR 3-19-2013 for wind wave mix ! t1k=t1(i,1)+273.16_sp !MDR 4-24-2013 t1k=t1(i,1)-DTER+273.16_sp !MDR 4-24-2013, include cool skin adjustment to surface temp !MDR ulw_airf=-emmiss*StefBo*t1k*t1k*t1k*t1k !MDR HEAT_NET(I) = DLW_AIR(I)+DSW_AIR(I)+HSB+HLB+ulw_airf ! ejw 8/16/2006 based on ROMS ulw_airf=-StefBo*t1k*t1k*t1k*t1k HEAT_NET(I) = DSW_AIR(I)+HSB+HLB+emmiss*(DLW_AIR(I)+ulw_airf) !MDR, apply emmiss to NET long wave, as in COARE HEAT_SWV(I) = DSW_AIR(I) !EJA edit - output sensible and latent heat flux HEAT_SENSIBLE(I) = HSB HEAT_LATENT(I) = HLB !g.l. 10/10/2017 HEAT_RLN(I) = DLW_AIR(I) HEAT_RLN(I) = emmiss*(DLW_AIR(I)+ulw_airf) END IF ELSE IF(TRIM(COARE_VERSION) == 'COARE40VN')THEN RAIN(I) = QPREC(I)*3600.0_SP*1000.0_SP ! change unit to mm/hr from m/s ZI40 = fmiss CP40 = Cwave(I) SIGH = HSC1(I) !---> Siqi Li, 2021-01-27 CALL COARE40VN(WDS,ZUU,T_AIR(I),ZTT,RH_AIR(I),ZQQ,PA_AIR(I),T1(I,1),& DLW_AIR(I),DSW_AIR(I),TAU,HSB,HLB,CORR(I),ZI40(I),RAIN(I),CP40(I),SIGH(I),fmiss,USR,DTER,Cd_node(I)) ! CALL COARE40VN(WDS,ZUU,T_AIR(I),ZTT,RH_AIR(I),ZQQ,PA_AIR(I),T1(I,1), & ! DLW_AIR(I),DSW_AIR(I),TAU,HSB,HLB,CORR(I),ZI40(I),RAIN(I),CP40(I),SIGH(I),fmiss,USR,DTER) !MDR include USR, DTER TAU_node(I) = TAU USR_node(I) = USR !<--- Siqi Li, 2021-01-27 IF(.NOT. HEATING_FRESHWATER)THEN t1k=t1(i,1)+273.16_sp ulw_airf=-emmiss*StefBo*t1k*t1k*t1k*t1k HEAT_NET(I) = DLW_AIR(I)+DSW_AIR(I)+HSB+HLB+ulw_airf ! ejw 8/16/2006 based on ROMS HEAT_SWV(I) = DSW_AIR(I) !EJA edit - output sensible and latent heat flux HEAT_SENSIBLE(I) = HSB HEAT_LATENT(I) = HLB !g.l. 10/10/2017 HEAT_RLN(I) = DLW_AIR(I) HEAT_RLN(I) = DLW_AIR(I)+ulw_airf ELSE USRCOARE(I) = USR !MDR 3-19-2013 for wind wave mix ! t1k=t1(i,1)+273.16_sp !MDR 4-24-2013 t1k=t1(i,1)-DTER+273.16_sp !MDR 4-24-2013, include cool skin adjustment to surface temp !MDR ulw_airf=-emmiss*StefBo*t1k*t1k*t1k*t1k !MDR HEAT_NET(I) = DLW_AIR(I)+DSW_AIR(I)+HSB+HLB+ulw_airf ! ejw 8/16/2006 based on ROMS ulw_airf=-StefBo*t1k*t1k*t1k*t1k HEAT_NET(I) = DSW_AIR(I)+HSB+HLB+emmiss*(DLW_AIR(I)+ulw_airf) !MDR, apply emmiss to NET long wave, as in COARE HEAT_SWV(I) = DSW_AIR(I) !EJA edit - output sensible and latent heat flux HEAT_SENSIBLE(I) = HSB HEAT_LATENT(I) = HLB !g.l. 10/10/2017 HEAT_RLN(I) = DLW_AIR(I) HEAT_RLN(I) = emmiss*(DLW_AIR(I)+ulw_airf) END IF ELSE CALL FATAL_ERROR("The value of COARE_VERSION should be 'COARE26Z' or 'COARE40VN'") END IF END DO CASE(HEAT_IS_FVCOMGRID) FTM => HEAT_FILE%FTIME ! ! BULK AIR TEMPERATURE CALL UPDATE_VAR_BRACKET(HEAT_FILE,T_AIR_P,T_AIR_N,HTIME,STATUS) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPATE HEAT_FILE TIME BRACKET: BOUNDS EXCEEDED?") end if CALL NC_POINT_VAR(T_AIR_N,VNP) CALL NC_POINT_VAR(T_AIR_P,VPP) T_AIR = FTM%NEXT_WGHT * VNP + FTM%PREV_WGHT * VPP ! ! RELATIVE HUMIDITY CALL UPDATE_VAR_BRACKET(HEAT_FILE,RH_AIR_P,RH_AIR_N,HTIME,STATUS) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPATE HEAT_FILE TIME BRACKET: BOUNDS EXCEEDED?") end if CALL NC_POINT_VAR(RH_AIR_N,VNP) CALL NC_POINT_VAR(RH_AIR_P,VPP) RH_AIR = FTM%NEXT_WGHT * VNP + FTM%PREV_WGHT * VPP ! ! SURFACE PRESSURE CALL UPDATE_VAR_BRACKET(HEAT_FILE,PA_AIR_P,PA_AIR_N,HTIME,STATUS) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPATE HEAT_FILE TIME BRACKET: BOUNDS EXCEEDED?") end if CALL NC_POINT_VAR(PA_AIR_N,VNP) CALL NC_POINT_VAR(PA_AIR_P,VPP) PA_AIR = FTM%NEXT_WGHT * VNP + FTM%PREV_WGHT * VPP PA_AIR = PA_AIR * Pair_unit_factor ! Siqi Li, 2021-01-27 ! ! DOWNWARD LONGWAVE RADIATION CALL UPDATE_VAR_BRACKET(HEAT_FILE,DLW_AIR_P,DLW_AIR_N,HTIME,STATUS) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPATE HEAT_FILE TIME BRACKET: BOUNDS EXCEEDED?") end if CALL NC_POINT_VAR(DLW_AIR_N,VNP) CALL NC_POINT_VAR(DLW_AIR_P,VPP) DLW_AIR = FTM%NEXT_WGHT * VNP + FTM%PREV_WGHT * VPP ! ! DOWNWARD SHORTWAVE RADIATION CALL UPDATE_VAR_BRACKET(HEAT_FILE,DSW_AIR_P,DSW_AIR_N,HTIME,STATUS) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPATE HEAT_FILE TIME BRACKET: BOUNDS EXCEEDED?") end if CALL NC_POINT_VAR(DSW_AIR_N,VNP) CALL NC_POINT_VAR(DSW_AIR_P,VPP) DSW_AIR = FTM%NEXT_WGHT * VNP + FTM%PREV_WGHT * VPP ! WDSN(1:NT) = SQRT(UUWIND(1:NT)*UUWIND(1:NT)+VVWIND(1:NT)*VVWIND(1:NT)) DO I=1,M WDS = 0.0_SP DO J=1,NTVE(I) WDS = WDS + WDSN(NBVE(I,J)) END DO WDS = WDS/FLOAT(NTVE(I)) IF(TRIM(COARE_VERSION) == 'COARE26Z')THEN !---> Siqi Li, 2021-01-27 : add Cd CALL COARE26Z(WDS,ZUU,T_AIR(I),ZTT,RH_AIR(I),ZQQ,PA_AIR(I),T1(I,1), & DLW_AIR(I),DSW_AIR(I),TAU,HSB,HLB,CORR(I),USR,DTER,Cd_node(I)) ! CALL COARE26Z(WDS,ZUU,T_AIR(I),ZTT,RH_AIR(I),ZQQ,PA_AIR(I),T1(I,1),& ! & DLW_AIR(I),DSW_AIR(I),TAU,HSB,HLB,CORR(I),USR,DTER) !MDR include USR, DTER TAU_node(I) = TAU USR_node(I) = USR !<--- Siqi Li, 2021-01-27 IF(.NOT. HEATING_FRESHWATER)THEN t1k=t1(i,1)+273.16_sp ulw_airf=-emmiss*StefBo*t1k*t1k*t1k*t1k HEAT_NET(I) = DLW_AIR(I)+DSW_AIR(I)+HSB+HLB+ulw_airf ! ejw 8/16/2006 based on ROMS HEAT_SWV(I) = DSW_AIR(I) !EJA edit - output sensible and latent heat flux HEAT_SENSIBLE(I) = HSB HEAT_LATENT(I) = HLB !g.l. 10/10/2017 HEAT_RLN(I) = DLW_AIR(I) HEAT_RLN(I) = DLW_AIR(I)+ulw_airf ELSE USRCOARE(I) = USR !MDR 3-19-2013 for wind wave mix ! t1k=t1(i,1)+273.16_sp !MDR 4-24-2013 t1k=t1(i,1)-DTER+273.16_sp !MDR 4-24-2013, include cool skin adjustment to surface temp !MDR ulw_airf=-emmiss*StefBo*t1k*t1k*t1k*t1k !MDR HEAT_NET(I) = DLW_AIR(I)+DSW_AIR(I)+HSB+HLB+ulw_airf ! ejw 8/16/2006 based on ROMS ulw_airf=-StefBo*t1k*t1k*t1k*t1k HEAT_NET(I) = DSW_AIR(I)+HSB+HLB+emmiss*(DLW_AIR(I)+ulw_airf) !MDR, apply emmiss to NET long wave, as in COARE HEAT_SWV(I) = DSW_AIR(I) !EJA edit - output sensible and latent heat flux HEAT_SENSIBLE(I) = HSB HEAT_LATENT(I) = HLB !g.l. 10/10/2017 HEAT_RLN(I) =DLW_AIR(I) HEAT_RLN(I) =emmiss*(DLW_AIR(I)+ulw_airf) END IF ELSE IF(TRIM(COARE_VERSION) == 'COARE40VN')THEN RAIN(I) = QPREC(I)*3600.0_SP*1000.0_SP ! change unit to mm/hr from m/s ZI40 = fmiss CP40 = Cwave(I) SIGH = HSC1(I) !---> Siqi Li, 2021-01-27 CALL COARE40VN(WDS,ZUU,T_AIR(I),ZTT,RH_AIR(I),ZQQ,PA_AIR(I),T1(I,1),& DLW_AIR(I),DSW_AIR(I),TAU,HSB,HLB,CORR(I),ZI40(I),RAIN(I),CP40(I),SIGH(I),fmiss,USR,DTER,Cd_node(I)) ! CALL COARE40VN(WDS,ZUU,T_AIR(I),ZTT,RH_AIR(I),ZQQ,PA_AIR(I),T1(I,1), & ! DLW_AIR(I),DSW_AIR(I),TAU,HSB,HLB,CORR(I),ZI40(I),RAIN(I),CP40(I),SIGH(I),fmiss,USR,DTER) !MDR include USR, DTER TAU_node(I) = TAU USR_node(I) = USR !<--- Siqi Li, 2021-01-27 IF(.NOT. HEATING_FRESHWATER)THEN t1k=t1(i,1)+273.16_sp ulw_airf=-emmiss*StefBo*t1k*t1k*t1k*t1k HEAT_NET(I) = DLW_AIR(I)+DSW_AIR(I)+HSB+HLB+ulw_airf ! ejw 8/16/2006 based on ROMS HEAT_SWV(I) = DSW_AIR(I) !EJA edit - output sensible and latent heat flux HEAT_SENSIBLE(I) = HSB HEAT_LATENT(I) = HLB !g.l. 10/10/2017 HEAT_RLN(I) = DLW_AIR(I) HEAT_RLN(I) = DLW_AIR(I)+ulw_airf ELSE USRCOARE(I) = USR !MDR 3-19-2013 for wind wave mix ! t1k=t1(i,1)+273.16_sp !MDR 4-24-2013 t1k=t1(i,1)-DTER+273.16_sp !MDR 4-24-2013, include cool skin adjustment to surface temp !MDR ulw_airf=-emmiss*StefBo*t1k*t1k*t1k*t1k !MDR HEAT_NET(I) = DLW_AIR(I)+DSW_AIR(I)+HSB+HLB+ulw_airf ! ejw 8/16/2006 based on ROMS ulw_airf=-StefBo*t1k*t1k*t1k*t1k HEAT_NET(I) = DSW_AIR(I)+HSB+HLB+emmiss*(DLW_AIR(I)+ulw_airf) !MDR, apply emmiss to NET long wave, as in COARE HEAT_SWV(I) = DSW_AIR(I) !EJA edit - output sensible and latent heat flux HEAT_SENSIBLE(I) = HSB HEAT_LATENT(I) = HLB !g.l. 10/10/2017 HEAT_RLN(I) =DLW_AIR(I) HEAT_RLN(I) =emmiss*(DLW_AIR(I)+ulw_airf) END IF ELSE CALL FATAL_ERROR("The value of COARE_VERSION should be 'COARE26Z' or 'COARE40VN'") END IF END DO CASE DEFAULT CALL FATAL_ERROR("UNKNOWN HEAT_FORCING_TYPE IN UPDATE HEAT") END SELECT !---> Siqi Li, 2021-01-27 !# if defined (MULTIPROCESSOR) ! IF(PAR) CALL AEXCHANGE(NC,MYID,NPROCS,TAU_node) ! IF(PAR) CALL AEXCHANGE(NC,MYID,NPROCS,USR_node) !# endif DO I = 1, N TAU_WIND(I) = (TAU_node(NV(I,1))+TAU_node(NV(I,2))+TAU_node(NV(I,3))) / 3.0_SP U_star(I) = (USR_node(NV(I,1))+USR_node(NV(I,2))+USR_node(NV(I,3))) / 3.0_SP Cd(I) = (Cd_node(NV(I,1))+Cd_node(NV(I,2))+Cd_node(NV(I,3))) / 3.0_SP END DO !<--- Siqi Li, 2021-01-27 RETURN END SUBROUTINE UPDATE_HEAT_CALCULATED # endif !==============================================================================| !==============================================================================| # if defined (HEATING_SOLAR) SUBROUTINE UPDATE_HEAT_SOLAR(NOW,HEAT_SWV,HEAT_NET,HEAT_SENSIBLE,HEAT_LATENT,HEAT_RLN) IMPLICIT NONE TYPE(TIME), INTENT(IN) :: NOW TYPE(TIME) :: HTIME REAL(SP), ALLOCATABLE :: HEAT_SWV(:), HEAT_NET(:) REAL(SP), ALLOCATABLE :: HEAT_SENSIBLE(:), HEAT_LATENT(:), HEAT_RLN(:) TYPE(NCFTIME), POINTER :: FTM INTEGER :: STATUS,I,J INTEGER :: JULDAY REAL(SP), POINTER :: VNP(:), VPP(:) REAL(SP) :: WDS,CLOUD_TMP,TDEW_TMP REAL(SP) :: TANUM,TWAT,TDIFF,LATIT,LONGI REAL(SP) :: SOLHR,CHEAT,CDMOM !EJA - Add HS,HL,RLN to variable list REAL(SP) :: SURFLXC,Q0,HS,HL,RLN REAL(SP) :: UZLZ0,UZLFL REAL(SP), DIMENSION(0:NT) :: WDSN INTEGER :: year_now,month_now,day_now INTEGER :: cc_now,yy_now IF(.NOT. ALLOCATED(HEAT_SWV)) CALL FATAL_ERROR & &("THE HEAT SHORTWAVE VARIABLE PASSED TO UPDATE IS NOT ALLOCATED") IF(.NOT. ALLOCATED(HEAT_NET)) CALL FATAL_ERROR & &("THE NET HEAT VARIABLE PASSED TO UPDATE IS NOT ALLOCATED") IF(.NOT. ALLOCATED(HEAT_SENSIBLE)) CALL FATAL_ERROR & &("THE SENSIBLE HEAT VARIABLE PASSED TO UPDATE IS NOT ALLOCATED") IF(.NOT. ALLOCATED(HEAT_LATENT)) CALL FATAL_ERROR & &("THE LATENT HEAT VARIABLE PASSED TO UPDATE IS NOT ALLOCATED") IF(.NOT. ALLOCATED(HEAT_RLN)) CALL FATAL_ERROR & &("THE LONGWAVE HEAT VARIABLE PASSED TO UPDATE IS NOT ALLOCATED") IF(WIND_TYPE /= 'speed')CALL FATAL_ERROR("WIND_TYPE must be 'speed' for heat flux calculating") !=================================================== SELECT CASE(HEATING_SOLAR_KIND) !=================================================== CASE (CNSTNT) CALL FATAL_ERROR("CONSTANT HEATING Not Available") CASE(STTC) CALL FATAL_ERROR("STATIC HEATING Not Set Up Yet") CASE(TMDPNDNT) CALL FATAL_ERROR("TIME DEPENDANT HEATING Not Set Up Yet") CASE(PRDC) CALL FATAL_ERROR("PERIODIC HEATING Not Set Up Yet") ! ! TO SET ZERO TIME PHASE USING RUNFILE START TIME !! HTIME= NOW - RUNFILE_StartTime ! ! TO USE ZERO AS THE PHASE OF THE FORCING ! HTIME= NOW ! HTIME = MOD(HTIME,HEAT_PERIOD) CASE(VRBL) HTIME = NOW END SELECT !=================================================== !=================================================== !=================================================== SELECT CASE(HEAT_FORCING_TYPE) !=================================================== CASE(HEAT_IS_WRFGRID) FTM => HEAT_FILE%FTIME ! ! AIR TEMPERATURE CALL UPDATE_VAR_BRACKET(HEAT_FILE,T_AIR_P,T_AIR_N,HTIME,STATUS,HEAT_INTP_N) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPATE HEAT_FILE TIME BRACKET: BOUNDS EXCEEDED?") end if CALL NC_POINT_VAR(T_AIR_N,VNP) CALL NC_POINT_VAR(T_AIR_P,VPP) T_AIR = FTM%NEXT_WGHT * VNP + FTM%PREV_WGHT * VPP ! ! DEW POINT CALL UPDATE_VAR_BRACKET(HEAT_FILE,TDEW_P,TDEW_N,HTIME,STATUS,HEAT_INTP_N) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPATE HEAT_FILE TIME BRACKET: BOUNDS EXCEEDED?") end if CALL NC_POINT_VAR(TDEW_N,VNP) CALL NC_POINT_VAR(TDEW_P,VPP) TDEW = FTM%NEXT_WGHT * VNP + FTM%PREV_WGHT * VPP ! ! CLOUD COVER CALL UPDATE_VAR_BRACKET(HEAT_FILE,CCOV_P,CCOV_N,HTIME,STATUS,HEAT_INTP_N) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPATE HEAT_FILE TIME BRACKET: BOUNDS EXCEEDED?") end if CALL NC_POINT_VAR(CCOV_N,VNP) CALL NC_POINT_VAR(CCOV_P,VPP) CLOUD = FTM%NEXT_WGHT * VNP + FTM%PREV_WGHT * VPP ! WDSN(1:NT) = SQRT(UUWIND(1:NT)*UUWIND(1:NT)+VVWIND(1:NT)*VVWIND(1:NT)) LATIT = LATITUDE_REFERENCE LONGI = LONGITUDE_REFERENCE SOLHR = HTIME%MuSOD/dble(million)/3600. JULDAY = HTIME%MJD - JULDAY0 + JULDAY_ADJUST + 1 CALL NOW_2_month_days(HTIME,year_now,month_now,day_now) IF(JULDAY > 365)THEN ! CALL NOW_2_month_days(HTIME,year_now,month_now,day_now) cc_now = INT(year_now/100) yy_now = year_now - cc_now*100 CALL GDAY2(1,1,yy_now,cc_now,JULDAY0) JULDAY = HTIME%MJD - JULDAY0 + JULDAY_ADJUST + 1 END IF DO I=1,M WDS = 0.0_SP DO J=1,NTVE(I) WDS = WDS + WDSN(NBVE(I,J)) END DO WDS = WDS/FLOAT(NTVE(I)) # if defined (SPHERICAL) LATIT = LAT(I) LONGI = LON(I) IF(LONGI > 180.0) LONGI = 360.0 - LONGI IF(LONGI < 0.0) LONGI = ABS(LONGI) # endif TANUM = T_AIR(I) TWAT = T1(I,1) TDIFF = TANUM - TWAT IF(ABS(TDIFF) .GT. 50.) WRITE(IPT,*)'1NODE : ',I IF(ABS(TDIFF) .GT. 50.) WRITE(IPT,*)'1TDIFF : ',TDIFF IF(ABS(TDIFF) .GT. 50.) WRITE(IPT,*)'1TANUM : ',TANUM IF(ABS(TDIFF) .GT. 50.) WRITE(IPT,*)'1TWAT : ',TWAT CLOUD_TMP = CLOUD(I) TDEW_TMP = TDEW(I) CALL UZL(WDS,ZM,TDIFF,CDMOM,CHEAT,UZLZ0,UZLFL) !EJA - add HS,HL,RLN to return variable list from SOLAR CALL SOLAR(TANUM,TDEW_TMP,WDS,CLOUD_TMP,TWAT,CHEAT,CDMOM,LATIT,LONGI,JULDAY,MONTH_NOW,SOLHR,SURFLXC,Q0,HS,HL,RLN) HEAT_NET(I) = SURFLXC HEAT_SWV(I) = Q0 !EJA - add HS,HL,RLN HEAT_SENSIBLE(I) = HS HEAT_LATENT(I) = HL HEAT_RLN(I) = RLN END DO # if defined (MULTIPROCESSOR) !*** Edit to fix halo-element problem (output heatflux into NetCDF to verify) - based on Xueming Zhu's analysis - EJA 6/17/2013 ***" IF(PAR) CALL AEXCHANGE(NC,MYID,NPROCS,HEAT_NET,HEAT_SWV) !EJA - add HS,HL,RLN IF(PAR) CALL AEXCHANGE(NC,MYID,NPROCS,HEAT_SENSIBLE,HEAT_LATENT,HEAT_RLN) # endif CASE(HEAT_IS_FVCOMGRID) FTM => HEAT_FILE%FTIME ! ! AIR TEMPERATURE CALL UPDATE_VAR_BRACKET(HEAT_FILE,T_AIR_P,T_AIR_N,HTIME,STATUS) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPATE HEAT_FILE TIME BRACKET: BOUNDS EXCEEDED?") end if CALL NC_POINT_VAR(T_AIR_N,VNP) CALL NC_POINT_VAR(T_AIR_P,VPP) T_AIR = FTM%NEXT_WGHT * VNP + FTM%PREV_WGHT * VPP ! ! DEW POINT CALL UPDATE_VAR_BRACKET(HEAT_FILE,TDEW_P,TDEW_N,HTIME,STATUS) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPATE HEAT_FILE TIME BRACKET: BOUNDS EXCEEDED?") end if CALL NC_POINT_VAR(TDEW_N,VNP) CALL NC_POINT_VAR(TDEW_P,VPP) TDEW = FTM%NEXT_WGHT * VNP + FTM%PREV_WGHT * VPP ! ! CLOUD COVER CALL UPDATE_VAR_BRACKET(HEAT_FILE,CCOV_P,CCOV_N,HTIME,STATUS) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPATE HEAT_FILE TIME BRACKET: BOUNDS EXCEEDED?") end if CALL NC_POINT_VAR(CCOV_N,VNP) CALL NC_POINT_VAR(CCOV_P,VPP) CLOUD = FTM%NEXT_WGHT * VNP + FTM%PREV_WGHT * VPP ! WDSN(1:NT) = SQRT(UUWIND(1:NT)*UUWIND(1:NT)+VVWIND(1:NT)*VVWIND(1:NT)) LATIT = LATITUDE_REFERENCE LONGI = LONGITUDE_REFERENCE SOLHR = HTIME%MuSOD/dble(million)/3600. JULDAY = HTIME%MJD - JULDAY0 + JULDAY_ADJUST + 1 CALL NOW_2_month_days(HTIME,year_now,month_now,day_now) IF(JULDAY > 365)THEN ! CALL NOW_2_month_days(HTIME,year_now,month_now,day_now) cc_now = INT(year_now/100) yy_now = year_now - cc_now*100 CALL GDAY2(1,1,yy_now,cc_now,JULDAY0) JULDAY = HTIME%MJD - JULDAY0 + JULDAY_ADJUST + 1 END IF DO I=1,M WDS = 0.0_SP DO J=1,NTVE(I) WDS = WDS + WDSN(NBVE(I,J)) END DO WDS = WDS/FLOAT(NTVE(I)) # if defined (SPHERICAL) LATIT = LAT(I) LONGI = LON(I) IF(LONGI > 180.0) LONGI = 360.0 - LONGI IF(LONGI < 0.0) LONGI = ABS(LONGI) # endif TANUM = T_AIR(I) TWAT = T1(I,1) TDIFF = TANUM - TWAT IF(ABS(TDIFF) .GT. 50.) WRITE(IPT,*)'1NODE : ',I IF(ABS(TDIFF) .GT. 50.) WRITE(IPT,*)'1TDIFF : ',TDIFF IF(ABS(TDIFF) .GT. 50.) WRITE(IPT,*)'1TANUM : ',TANUM IF(ABS(TDIFF) .GT. 50.) WRITE(IPT,*)'1TWAT : ',TWAT CLOUD_TMP = CLOUD(I) TDEW_TMP = TDEW(I) CALL UZL(WDS,ZM,TDIFF,CDMOM,CHEAT,UZLZ0,UZLFL) !EJA - add HS,HL,RLN to return variable list from SOLAR CALL SOLAR(TANUM,TDEW_TMP,WDS,CLOUD_TMP,TWAT,CHEAT,CDMOM,LATIT,LONGI,JULDAY,MONTH_NOW,SOLHR,SURFLXC,Q0,HS,HL,RLN) HEAT_NET(I) = SURFLXC HEAT_SWV(I) = Q0 !EJA - add HS,HL,RLN HEAT_SENSIBLE(I) = HS HEAT_LATENT(I) = HL HEAT_RLN(I) = RLN END DO # if defined (MULTIPROCESSOR) !*** Edit to fix halo-element problem (output heatflux into NetCDF to verify) - based on Xueming Zhu's analysis - EJA 6/17/2013 ***" IF(PAR) CALL AEXCHANGE(NC,MYID,NPROCS,HEAT_NET,HEAT_SWV) !EJA - add HS,HL,RLN IF(PAR) CALL AEXCHANGE(NC,MYID,NPROCS,HEAT_SENSIBLE,HEAT_LATENT,HEAT_RLN) # endif CASE DEFAULT CALL FATAL_ERROR("UNKNOWN HEAT_FORCING_TYPE IN UPDATE HEAT") END SELECT RETURN END SUBROUTINE UPDATE_HEAT_SOLAR # endif !==============================================================================| SUBROUTINE UPDATE_WIND(NOW,wstrx,wstry) IMPLICIT NONE TYPE(TIME), INTENT(IN) :: NOW TYPE(TIME) :: WTIME REAL(SP), ALLOCATABLE :: wstrx(:),wstry(:) REAL(SP), POINTER :: VNP(:), VPP(:) TYPE(NCFTIME), POINTER :: FTM INTEGER :: STATUS IF(.NOT. ALLOCATED(wstrx)) CALL FATAL_ERROR & &("THE WIND VARIABLE PASSED TO UPDATE IS NOT ALLOCATED") IF(.NOT. ALLOCATED(wstry)) CALL FATAL_ERROR & &("THE WIND VARIABLE PASSED TO UPDATE IS NOT ALLOCATED") !=================================================== SELECT CASE(WIND_KIND) !=================================================== CASE (CNSTNT) wstrx(1:NT) = WIND_X wstry(1:NT) = WIND_Y RETURN CASE(STTC) CALL FATAL_ERROR("STATIC WIND Not Set Up Yet") CASE(TMDPNDNT) CALL FATAL_ERROR("TIME DEPENDANT WIND Not Set Up Yet") CASE(PRDC) ! TO SET ZERO TIME PHASE USING RUNFILE START TIME ! WTIME= NOW - RUNFILE_StartTime ! TO USE ZERO AS THE PHASE OF THE FORCING WTIME= NOW WTIME = MOD(WTIME,WINDS_PERIOD) CASE(VRBL) WTIME = NOW END SELECT !=================================================== !=================================================== !=================================================== SELECT CASE(WINDS_FORCING_TYPE) !=================================================== CASE(WINDS_ARE_WRFGRID) FTM => WINDS_FILE%FTIME ! THE X DIRECTION WIND STRESS CALL UPDATE_VAR_BRACKET(WINDS_FILE,WINDS_STRX_P,WINDS_STRX_N,WTIME,STATUS,WINDS_INTP_C) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPATE WIND X BRACKET: BOUNDS EXCEEDED?") end if CALL NC_POINT_VAR(WINDS_STRX_N,VNP) CALL NC_POINT_VAR(WINDS_STRX_P,VPP) WSTRX = FTM%NEXT_WGHT * VNP + FTM%PREV_WGHT * VPP ! THE Y DIRECTION WIND STRESS CALL UPDATE_VAR_BRACKET(WINDS_FILE,WINDS_STRY_P,WINDS_STRY_N,WTIME,STATUS,WINDS_INTP_C) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPATE WIND Y BRACKET: BOUNDS EXCEEDED?") end if CALL NC_POINT_VAR(WINDS_STRY_N,VNP) CALL NC_POINT_VAR(WINDS_STRY_P,VPP) WSTRY = FTM%NEXT_WGHT * VNP + FTM%PREV_WGHT * VPP !=================================================== CASE(WINDS_ARE_FVCOMGRID) !=================================================== FTM => WINDS_FILE%FTIME ! THE X DIRECTION WIND STRESS CALL UPDATE_VAR_BRACKET(WINDS_FILE,WINDS_STRX_P,WINDS_STRX_N,WTIME,STATUS) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPATE WIND X BRACKET: BOUNDS EXCEEDED?") end if CALL NC_POINT_VAR(WINDS_STRX_N,VNP) CALL NC_POINT_VAR(WINDS_STRX_P,VPP) WSTRX = FTM%NEXT_WGHT * VNP + FTM%PREV_WGHT * VPP ! THE Y DIRECTION WIND STRESS CALL UPDATE_VAR_BRACKET(WINDS_FILE,WINDS_STRY_P,WINDS_STRY_N,WTIME,STATUS) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPATE WIND Y BRACKET: BOUNDS EXCEEDED?") end if CALL NC_POINT_VAR(WINDS_STRY_N,VNP) CALL NC_POINT_VAR(WINDS_STRY_P,VPP) WSTRY = FTM%NEXT_WGHT * VNP + FTM%PREV_WGHT * VPP !=================================================== CASE(WINDS_ARE_PT_SOURCE) !=================================================== FTM => WINDS_FILE%FTIME ! THE X DIRECTION WIND STRESS CALL UPDATE_VAR_BRACKET(WINDS_FILE,WINDS_STRX_P,WINDS_STRX_N,WTIME,STATUS) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPATE WIND X BRACKET: BOUNDS EXCEEDED?") end if CALL NC_POINT_VAR(WINDS_STRX_N,VNP) CALL NC_POINT_VAR(WINDS_STRX_P,VPP) WSTRX(1:NT) = FTM%NEXT_WGHT * VNP(1) + FTM%PREV_WGHT * VPP(1) ! THE Y DIRECTION WIND STRESS CALL UPDATE_VAR_BRACKET(WINDS_FILE,WINDS_STRY_P,WINDS_STRY_N,WTIME,STATUS) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPATE WIND Y BRACKET: BOUNDS EXCEEDED?") end if CALL NC_POINT_VAR(WINDS_STRY_N,VNP) CALL NC_POINT_VAR(WINDS_STRY_P,VPP) WSTRY(1:NT) = FTM%NEXT_WGHT * VNP(1) + FTM%PREV_WGHT * VPP(1) !=================================================== CASE DEFAULT CALL FATAL_ERROR("UNKNOWN WINDS_FORCING_TYPE IN UPDATE WIND") END SELECT !=================================================== END SUBROUTINE UPDATE_WIND # if defined (WAVE_CURRENT_INTERACTION) && (WAVE_ONLY) !==============================================================================| SUBROUTINE UPDATE_ICEIN(NOW,wicec) IMPLICIT NONE TYPE(TIME), INTENT(IN) :: NOW TYPE(TIME) :: WTIME REAL(SP), ALLOCATABLE :: wicec(:) REAL(SP), POINTER :: VNP(:), VPP(:) TYPE(NCFTIME), POINTER :: FTM INTEGER :: STATUS IF(.NOT. ALLOCATED(wicec)) CALL FATAL_ERROR & &("THE ICE VARIABLE PASSED TO UPDATE IS NOT ALLOCATED") !=================================================== SELECT CASE(WIND_KIND) !=================================================== CASE (CNSTNT) wicec(1:MT) = CICE RETURN CASE(STTC) CALL FATAL_ERROR("STATIC WIND Not Set Up Yet") CASE(TMDPNDNT) CALL FATAL_ERROR("TIME DEPENDANT WIND Not Set Up Yet") CASE(PRDC) ! TO SET ZERO TIME PHASE USING RUNFILE START TIME ! WTIME= NOW - RUNFILE_StartTime ! TO USE ZERO AS THE PHASE OF THE FORCING !WTIME= NOW CALL FATAL_ERROR("TIME DEPENDANT WIND Not Set Up Yet") !WTIME = MOD(WTIME,WINDS_PERIOD) CASE(VRBL) WTIME = NOW END SELECT !PRINT *, "ICEINS_FORCING_TYPE",ICEINS_FORCING_TYPE !=================================================== SELECT CASE(ICEINS_FORCING_TYPE) !=================================================== CASE(ICEINS_ARE_FVCOMGRID) !=================================================== FTM => ICEINS_FILE%FTIME CALL UPDATE_VAR_BRACKET(ICEINS_FILE,ICEINS_ICEC_P,ICEINS_ICEC_N,WTIME,STATUS) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPATE ICEIN: BOUNDS EXCEEDED?") end if CALL NC_POINT_VAR(ICEINS_ICEC_N,VNP) CALL NC_POINT_VAR(ICEINS_ICEC_P,VPP) WICEC = FTM%NEXT_WGHT * VNP + FTM%PREV_WGHT * VPP !=================================================== CASE DEFAULT CALL FATAL_ERROR("UNKNOWN ICEIN IN UPDATE WIND") END SELECT !=================================================== END SUBROUTINE UPDATE_ICEIN # endif # if defined (OFFLINE_SEDIMENT) !==============================================================================| SUBROUTINE UPDATE_OFFLINE_FORCING(NOW,offline_u, offline_v, offline_w& &,offline_s1, offline_t1, offline_el,offline_kh& # if defined (GOTM) &,offline_teps & # else &,offline_q2, offline_q2l & # endif &,offline_wn, offline_wc) IMPLICIT NONE TYPE(TIME), INTENT(IN) :: NOW TYPE(TIME) :: WTIME REAL(SP), ALLOCATABLE :: offline_u(:,:),offline_v(:,:),offline_w(:,:),offline_s1(:,:),offline_t1(:,:) REAL(SP), ALLOCATABLE :: offline_el(:), offline_kh(:,:) # if defined (GOTM) REAL(SP), ALLOCATABLE :: offline_teps(:,:) # else REAL(SP), ALLOCATABLE :: offline_q2(:,:), offline_q2l(:,:) # endif INTEGER , ALLOCATABLE :: offline_wn(:), offline_wc(:) REAL(SP), POINTER :: VNP(:), VPP(:) REAL(SP), POINTER :: VNP_ARR(:,:), VPP_ARR(:,:) INTEGER , POINTER :: VNP_INT(:), VPP_INT(:) TYPE(NCFTIME), POINTER :: FTM INTEGER :: STATUS,I IF(.NOT. ALLOCATED(offline_u)) CALL FATAL_ERROR & &("THE offline_u VARIABLE PASSED TO UPDATE IS NOT ALLOCATED") IF(.NOT. ALLOCATED(offline_v)) CALL FATAL_ERROR & &("THE offline_v VARIABLE PASSED TO UPDATE IS NOT ALLOCATED") IF(.NOT. ALLOCATED(offline_w)) CALL FATAL_ERROR & &("THE offline_w VARIABLE PASSED TO UPDATE IS NOT ALLOCATED") IF(.NOT. ALLOCATED(offline_s1)) CALL FATAL_ERROR & &("THE offline_s1 VARIABLE PASSED TO UPDATE IS NOT ALLOCATED") IF(.NOT. ALLOCATED(offline_t1)) CALL FATAL_ERROR & &("THE offline_t1 VARIABLE PASSED TO UPDATE IS NOT ALLOCATED") IF(.NOT. ALLOCATED(offline_el)) CALL FATAL_ERROR & &("THE offline_el VARIABLE PASSED TO UPDATE IS NOT ALLOCATED") IF(.NOT. ALLOCATED(offline_kh)) CALL FATAL_ERROR & &("THE offline_kh VARIABLE PASSED TO UPDATE IS NOT ALLOCATED") IF(.NOT. ALLOCATED(offline_wn)) CALL FATAL_ERROR & &("THE offline_wn VARIABLE PASSED TO UPDATE IS NOT ALLOCATED") IF(.NOT. ALLOCATED(offline_wc)) CALL FATAL_ERROR & &("THE offline_wc VARIABLE PASSED TO UPDATE IS NOT ALLOCATED") # if defined (GOTM) IF(.NOT. ALLOCATED(offline_teps)) CALL FATAL_ERROR & &("THE offline_teps VARIABLE PASSED TO UPDATE IS NOT ALLOCATED") # else IF(.NOT. ALLOCATED(offline_q2)) CALL FATAL_ERROR & &("THE offline_q2 VARIABLE PASSED TO UPDATE IS NOT ALLOCATED") IF(.NOT. ALLOCATED(offline_q2l)) CALL FATAL_ERROR & &("THE offline_q2l VARIABLE PASSED TO UPDATE IS NOT ALLOCATED") # endif !=================================================== WTIME = NOW !=================================================== !=================================================== !=================================================== ! CASE(WINDS_ARE_FVCOMGRID) !=================================================== FTM => SEDIMENTS_FILE%FTIME ! THE X DIRECTION U VELOCITY CALL UPDATE_VAR_BRACKET(SEDIMENTS_FILE,SEDIMENTS_U_P,SEDIMENTS_U_N,WTIME,STATUS) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPATE SEDIMENT_U BRACKET: BOUNDS EXCEEDED?") end if CALL NC_POINT_VAR(SEDIMENTS_U_N,VNP_ARR) CALL NC_POINT_VAR(SEDIMENTS_U_P,VPP_ARR) OFFLINE_U = FTM%NEXT_WGHT * VNP_ARR + FTM%PREV_WGHT * VPP_ARR ! THE Y DIRECTION V VELOCITY CALL UPDATE_VAR_BRACKET(SEDIMENTS_FILE,SEDIMENTS_V_P,SEDIMENTS_V_N,WTIME,STATUS) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPATE SEDIMENT_V BRACKET: BOUNDS EXCEEDED?") end if CALL NC_POINT_VAR(SEDIMENTS_V_N,VNP_ARR) CALL NC_POINT_VAR(SEDIMENTS_V_P,VPP_ARR) OFFLINE_V = FTM%NEXT_WGHT * VNP_ARR + FTM%PREV_WGHT * VPP_ARR ! THE Z DIRECTION W VELOCITY CALL UPDATE_VAR_BRACKET(SEDIMENTS_FILE,SEDIMENTS_W_P,SEDIMENTS_W_N,WTIME,STATUS) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPATE SEDIMENT_W BRACKET: BOUNDS EXCEEDED?") end if CALL NC_POINT_VAR(SEDIMENTS_W_N,VNP_ARR) CALL NC_POINT_VAR(SEDIMENTS_W_P,VPP_ARR) OFFLINE_W = FTM%NEXT_WGHT * VNP_ARR + FTM%PREV_WGHT * VPP_ARR ! THE SALINITY CALL UPDATE_VAR_BRACKET(SEDIMENTS_FILE,SEDIMENTS_S1_P,SEDIMENTS_S1_N,WTIME,STATUS) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPATE SEDIMENT_S1 BRACKET: BOUNDS EXCEEDED?") end if CALL NC_POINT_VAR(SEDIMENTS_S1_N,VNP_ARR) CALL NC_POINT_VAR(SEDIMENTS_S1_P,VPP_ARR) OFFLINE_S1 = FTM%NEXT_WGHT * VNP_ARR + FTM%PREV_WGHT * VPP_ARR ! THE TEMPERATURE CALL UPDATE_VAR_BRACKET(SEDIMENTS_FILE,SEDIMENTS_T1_P,SEDIMENTS_T1_N,WTIME,STATUS) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPATE SEDIMENT_T1 BRACKET: BOUNDS EXCEEDED?") end if CALL NC_POINT_VAR(SEDIMENTS_T1_N,VNP_ARR) CALL NC_POINT_VAR(SEDIMENTS_T1_P,VPP_ARR) OFFLINE_T1 = FTM%NEXT_WGHT * VNP_ARR + FTM%PREV_WGHT * VPP_ARR ! THE EL CALL UPDATE_VAR_BRACKET(SEDIMENTS_FILE,SEDIMENTS_EL_P,SEDIMENTS_EL_N,WTIME,STATUS) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPATE SEDIMENT_EL BRACKET: BOUNDS EXCEEDED?") end if CALL NC_POINT_VAR(SEDIMENTS_EL_N,VNP) CALL NC_POINT_VAR(SEDIMENTS_EL_P,VPP) OFFLINE_EL = FTM%NEXT_WGHT * VNP + FTM%PREV_WGHT * VPP ! THE KH CALL UPDATE_VAR_BRACKET(SEDIMENTS_FILE,SEDIMENTS_KH_P,SEDIMENTS_KH_N,WTIME,STATUS) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPATE SEDIMENT_KH BRACKET: BOUNDS EXCEEDED?") end if CALL NC_POINT_VAR(SEDIMENTS_KH_N,VNP_ARR) CALL NC_POINT_VAR(SEDIMENTS_KH_P,VPP_ARR) OFFLINE_KH = FTM%NEXT_WGHT * VNP_ARR + FTM%PREV_WGHT * VPP_ARR # if defined (GOTM) ! THE TEPS CALL UPDATE_VAR_BRACKET(SEDIMENTS_FILE,SEDIMENTS_TEPS_P,SEDIMENTS_TEPS_N,WTIME,STATUS) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPATE SEDIMENT_KH BRACKET: BOUNDS EXCEEDED?") end if CALL NC_POINT_VAR(SEDIMENTS_TEPS_N,VNP_ARR) CALL NC_POINT_VAR(SEDIMENTS_TEPS_P,VPP_ARR) OFFLINE_TEPS = FTM%NEXT_WGHT * VNP_ARR + FTM%PREV_WGHT * VPP_ARR # else ! THE Q2 CALL UPDATE_VAR_BRACKET(SEDIMENTS_FILE,SEDIMENTS_Q2_P,SEDIMENTS_Q2_N,WTIME,STATUS) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPATE SEDIMENT_KH BRACKET: BOUNDS EXCEEDED?") end if CALL NC_POINT_VAR(SEDIMENTS_Q2_N,VNP_ARR) CALL NC_POINT_VAR(SEDIMENTS_Q2_P,VPP_ARR) OFFLINE_Q2 = FTM%NEXT_WGHT * VNP_ARR + FTM%PREV_WGHT * VPP_ARR ! THE Q2L CALL UPDATE_VAR_BRACKET(SEDIMENTS_FILE,SEDIMENTS_Q2L_P,SEDIMENTS_Q2L_N,WTIME,STATUS) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPATE SEDIMENT_KH BRACKET: BOUNDS EXCEEDED?") end if CALL NC_POINT_VAR(SEDIMENTS_Q2L_N,VNP_ARR) CALL NC_POINT_VAR(SEDIMENTS_Q2L_P,VPP_ARR) OFFLINE_Q2L = FTM%NEXT_WGHT * VNP_ARR + FTM%PREV_WGHT * VPP_ARR # endif # if defined (WET_DRY) ! THE WET NODES CALL UPDATE_VAR_BRACKET(SEDIMENTS_FILE,SEDIMENTS_WN_P,SEDIMENTS_WN_N,WTIME,STATUS) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPATE SEDIMENT_WN BRACKET: BOUNDS EXCEEDED?") end if CALL NC_POINT_VAR(SEDIMENTS_WN_N,VNP_INT) CALL NC_POINT_VAR(SEDIMENTS_WN_P,VPP_INT) DO I=1,MT OFFLINE_WN(I)=VNP_INT(I)*VPP_INT(I) END DO ! THE WET CELLS CALL UPDATE_VAR_BRACKET(SEDIMENTS_FILE,SEDIMENTS_WC_P,SEDIMENTS_WC_N,WTIME,STATUS) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPATE SEDIMENT_WC BRACKET: BOUNDS EXCEEDED?") end if CALL NC_POINT_VAR(SEDIMENTS_WC_N,VNP_INT) CALL NC_POINT_VAR(SEDIMENTS_WC_P,VPP_INT) DO I=1,MT OFFLINE_WC(I)=VNP_INT(I)*VPP_INT(I) END DO # endif END SUBROUTINE UPDATE_OFFLINE_FORCING # endif # if defined (OFFLINE_BIOLOGY) !==============================================================================| SUBROUTINE UPDATE_OFFLINE_BIOLOGY_FORCING(NOW,offline_u, offline_v, offline_w& &,offline_s1, offline_t1,offline_el,offline_kh& # if defined (GOTM) &,offline_teps & # else &,offline_q2, offline_q2l & # endif &,offline_wn, offline_wc) IMPLICIT NONE TYPE(TIME), INTENT(IN) :: NOW TYPE(TIME) :: WTIME REAL(SP), ALLOCATABLE :: offline_u(:,:),offline_v(:,:),offline_w(:,:),offline_s1(:,:),offline_t1(:,:) REAL(SP), ALLOCATABLE :: offline_el(:), offline_kh(:,:) # if defined (GOTM) REAL(SP), ALLOCATABLE :: offline_teps(:,:) # else REAL(SP), ALLOCATABLE :: offline_q2(:,:), offline_q2l(:,:) # endif INTEGER , ALLOCATABLE :: offline_wn(:), offline_wc(:) REAL(SP), POINTER :: VNP(:), VPP(:) REAL(SP), POINTER :: VNP_ARR(:,:), VPP_ARR(:,:) INTEGER , POINTER :: VNP_INT(:), VPP_INT(:) TYPE(NCFTIME), POINTER :: FTM INTEGER :: STATUS,I IF(.NOT. ALLOCATED(offline_u)) CALL FATAL_ERROR & &("THE offline_u VARIABLE PASSED TO UPDATE IS NOT ALLOCATED") IF(.NOT. ALLOCATED(offline_v)) CALL FATAL_ERROR & &("THE offline_v VARIABLE PASSED TO UPDATE IS NOT ALLOCATED") IF(.NOT. ALLOCATED(offline_w)) CALL FATAL_ERROR & &("THE offline_w VARIABLE PASSED TO UPDATE IS NOT ALLOCATED") IF(.NOT. ALLOCATED(offline_s1)) CALL FATAL_ERROR & &("THE offline_s1 VARIABLE PASSED TO UPDATE IS NOT ALLOCATED") IF(.NOT. ALLOCATED(offline_t1)) CALL FATAL_ERROR & &("THE offline_t1 VARIABLE PASSED TO UPDATE IS NOT ALLOCATED") IF(.NOT. ALLOCATED(offline_el)) CALL FATAL_ERROR & &("THE offline_el VARIABLE PASSED TO UPDATE IS NOT ALLOCATED") IF(.NOT. ALLOCATED(offline_kh)) CALL FATAL_ERROR & &("THE offline_kh VARIABLE PASSED TO UPDATE IS NOT ALLOCATED") IF(.NOT. ALLOCATED(offline_wn)) CALL FATAL_ERROR & &("THE offline_wn VARIABLE PASSED TO UPDATE IS NOT ALLOCATED") IF(.NOT. ALLOCATED(offline_wc)) CALL FATAL_ERROR & &("THE offline_wc VARIABLE PASSED TO UPDATE IS NOT ALLOCATED") # if defined (GOTM) IF(.NOT. ALLOCATED(offline_teps)) CALL FATAL_ERROR & &("THE offline_teps VARIABLE PASSED TO UPDATE IS NOT ALLOCATED") # else IF(.NOT. ALLOCATED(offline_q2)) CALL FATAL_ERROR & &("THE offline_q2 VARIABLE PASSED TO UPDATE IS NOT ALLOCATED") IF(.NOT. ALLOCATED(offline_q2l)) CALL FATAL_ERROR & &("THE offline_q2l VARIABLE PASSED TO UPDATE IS NOT ALLOCATED") # endif !=================================================== WTIME = NOW !=================================================== !=================================================== !=================================================== ! CASE(WINDS_ARE_FVCOMGRID) !=================================================== FTM => BIOLOGY_FILE%FTIME ! THE X DIRECTION U VELOCITY CALL UPDATE_VAR_BRACKET(BIOLOGY_FILE,BIOLOGY_U_P,BIOLOGY_U_N,WTIME,STATUS) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPATE BIOLOGY_U BRACKET: BOUNDS EXCEEDED?") end if CALL NC_POINT_VAR(BIOLOGY_U_N,VNP_ARR) CALL NC_POINT_VAR(BIOLOGY_U_P,VPP_ARR) OFFLINE_U = FTM%NEXT_WGHT * VNP_ARR + FTM%PREV_WGHT * VPP_ARR ! THE Y DIRECTION V VELOCITY CALL UPDATE_VAR_BRACKET(BIOLOGY_FILE,BIOLOGY_V_P,BIOLOGY_V_N,WTIME,STATUS) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPATE BIOLOGY_V BRACKET: BOUNDS EXCEEDED?") end if CALL NC_POINT_VAR(BIOLOGY_V_N,VNP_ARR) CALL NC_POINT_VAR(BIOLOGY_V_P,VPP_ARR) OFFLINE_V = FTM%NEXT_WGHT * VNP_ARR + FTM%PREV_WGHT * VPP_ARR ! THE Z DIRECTION W VELOCITY CALL UPDATE_VAR_BRACKET(BIOLOGY_FILE,BIOLOGY_W_P,BIOLOGY_W_N,WTIME,STATUS) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPATE BIOLOGY_W BRACKET: BOUNDS EXCEEDED?") end if CALL NC_POINT_VAR(BIOLOGY_W_N,VNP_ARR) CALL NC_POINT_VAR(BIOLOGY_W_P,VPP_ARR) OFFLINE_W = FTM%NEXT_WGHT * VNP_ARR + FTM%PREV_WGHT * VPP_ARR ! THE SALINITY CALL UPDATE_VAR_BRACKET(BIOLOGY_FILE,BIOLOGY_S1_P,BIOLOGY_S1_N,WTIME,STATUS) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPATE BIOLOGY_S1 BRACKET: BOUNDS EXCEEDED?") end if CALL NC_POINT_VAR(BIOLOGY_S1_N,VNP_ARR) CALL NC_POINT_VAR(BIOLOGY_S1_P,VPP_ARR) OFFLINE_S1 = FTM%NEXT_WGHT * VNP_ARR + FTM%PREV_WGHT * VPP_ARR ! THE TEMPERATURE CALL UPDATE_VAR_BRACKET(BIOLOGY_FILE,BIOLOGY_T1_P,BIOLOGY_T1_N,WTIME,STATUS) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPATE BIOLOGY_T1 BRACKET: BOUNDS EXCEEDED?") end if CALL NC_POINT_VAR(BIOLOGY_T1_N,VNP_ARR) CALL NC_POINT_VAR(BIOLOGY_T1_P,VPP_ARR) OFFLINE_T1 = FTM%NEXT_WGHT * VNP_ARR + FTM%PREV_WGHT * VPP_ARR ! THE EL CALL UPDATE_VAR_BRACKET(BIOLOGY_FILE,BIOLOGY_EL_P,BIOLOGY_EL_N,WTIME,STATUS) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPATE BIOLOGY_EL BRACKET: BOUNDS EXCEEDED?") end if CALL NC_POINT_VAR(BIOLOGY_EL_N,VNP) CALL NC_POINT_VAR(BIOLOGY_EL_P,VPP) OFFLINE_EL = FTM%NEXT_WGHT * VNP + FTM%PREV_WGHT * VPP ! THE KH CALL UPDATE_VAR_BRACKET(BIOLOGY_FILE,BIOLOGY_KH_P,BIOLOGY_KH_N,WTIME,STATUS) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPATE BIOLOGY_KH BRACKET: BOUNDS EXCEEDED?") end if CALL NC_POINT_VAR(BIOLOGY_KH_N,VNP_ARR) CALL NC_POINT_VAR(BIOLOGY_KH_P,VPP_ARR) OFFLINE_KH = FTM%NEXT_WGHT * VNP_ARR + FTM%PREV_WGHT * VPP_ARR # if defined (GOTM) ! THE TEPS CALL UPDATE_VAR_BRACKET(BIOLOGY_FILE,BIOLOGY_TEPS_P,BIOLOGY_TEPS_N,WTIME,STATUS) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPATE BIOLOGY_KH BRACKET: BOUNDS EXCEEDED?") end if CALL NC_POINT_VAR(BIOLOGY_TEPS_N,VNP_ARR) CALL NC_POINT_VAR(BIOLOGY_TEPS_P,VPP_ARR) OFFLINE_TEPS = FTM%NEXT_WGHT * VNP_ARR + FTM%PREV_WGHT * VPP_ARR # else ! THE Q2 CALL UPDATE_VAR_BRACKET(BIOLOGY_FILE,BIOLOGY_Q2_P,BIOLOGY_Q2_N,WTIME,STATUS) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPATE BIOLOGY_KH BRACKET: BOUNDS EXCEEDED?") end if CALL NC_POINT_VAR(BIOLOGY_Q2_N,VNP_ARR) CALL NC_POINT_VAR(BIOLOGY_Q2_P,VPP_ARR) OFFLINE_Q2 = FTM%NEXT_WGHT * VNP_ARR + FTM%PREV_WGHT * VPP_ARR ! THE Q2L CALL UPDATE_VAR_BRACKET(BIOLOGY_FILE,BIOLOGY_Q2L_P,BIOLOGY_Q2L_N,WTIME,STATUS) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPATE BIOLOGY_KH BRACKET: BOUNDS EXCEEDED?") end if CALL NC_POINT_VAR(BIOLOGY_Q2L_N,VNP_ARR) CALL NC_POINT_VAR(BIOLOGY_Q2L_P,VPP_ARR) OFFLINE_Q2L = FTM%NEXT_WGHT * VNP_ARR + FTM%PREV_WGHT * VPP_ARR # endif # if defined (WET_DRY) ! THE WET NODES CALL UPDATE_VAR_BRACKET(BIOLOGY_FILE,BIOLOGY_WN_P,BIOLOGY_WN_N,WTIME,STATUS) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPATE BIOLOGY_WN BRACKET: BOUNDS EXCEEDED?") end if CALL NC_POINT_VAR(BIOLOGY_WN_N,VNP_INT) CALL NC_POINT_VAR(BIOLOGY_WN_P,VPP_INT) DO I=1,MT OFFLINE_WN(I)=VNP_INT(I)*VPP_INT(I) END DO ! THE WET CELLS CALL UPDATE_VAR_BRACKET(BIOLOGY_FILE,BIOLOGY_WC_P,BIOLOGY_WC_N,WTIME,STATUS) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPATE BIOLOGY_WC BRACKET: BOUNDS EXCEEDED?") end if CALL NC_POINT_VAR(BIOLOGY_WC_N,VNP_INT) CALL NC_POINT_VAR(BIOLOGY_WC_P,VPP_INT) DO I=1,MT OFFLINE_WC(I)=VNP_INT(I)*VPP_INT(I) END DO # endif END SUBROUTINE UPDATE_OFFLINE_BIOLOGY_FORCING # endif !==============================================================================| SUBROUTINE UPDATE_PRECIPITATION(NOW,Qprec,Qevap) IMPLICIT NONE TYPE(TIME), INTENT(IN) :: NOW TYPE(TIME) :: PTIME REAL(SP), ALLOCATABLE :: QEVAP(:),QPREC(:) REAL(SP), POINTER :: VNP(:), VPP(:) TYPE(NCFTIME), POINTER :: FTM INTEGER :: STATUS IF(.NOT. ALLOCATED(Qprec)) CALL FATAL_ERROR & &("THE PRECIPITATION VARIABLE PASSED TO UPDATE IS NOT ALLOCATED") IF(.NOT. ALLOCATED(Qevap)) CALL FATAL_ERROR & &("THE EVAPORATION VARIABLE PASSED TO UPDATE IS NOT ALLOCATED") !=================================================== SELECT CASE(PRECIPITATION_KIND) !=================================================== CASE (CNSTNT) Qprec(1:MT) = PRECIPITATION_PRC Qevap(1:MT) = PRECIPITATION_EVP RETURN CASE(STTC) CALL FATAL_ERROR("STATIC PRECIP Not Set Up Yet") CASE(TMDPNDNT) CALL FATAL_ERROR("TIME DEPENDANT PRECIP Not Set Up Yet") CASE(PRDC) ! TO SET ZERO TIME PHASE USING RUNFILE START TIME ! PTIME= NOW - RUNFILE_StartTime ! TO USE ZERO AS THE PHASE OF THE FORCING PTIME= NOW PTIME = MOD(PTIME,PRECIP_PERIOD) CASE(VRBL) PTIME = NOW END SELECT !=================================================== !=================================================== !=================================================== SELECT CASE(PRECIP_FORCING_TYPE) !=================================================== CASE(PRECIP_IS_WRFGRID) FTM => PRECIP_FILE%FTIME ! PRECIPITATION CALL UPDATE_VAR_BRACKET(PRECIP_FILE,PRECIP_PRE_P,PRECIP_PRE_N,PTIME,STATUS,PRECIP_INTP_N) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPATE PRECIP BRACKET: BOUNDS EXCEEDED?") end if CALL NC_POINT_VAR(PRECIP_PRE_N,VNP) CALL NC_POINT_VAR(PRECIP_PRE_P,VPP) Qprec = FTM%NEXT_WGHT * VNP + FTM%PREV_WGHT * VPP ! EVAPORATION CALL UPDATE_VAR_BRACKET(PRECIP_FILE,PRECIP_EVP_P,PRECIP_EVP_N,PTIME,STATUS,PRECIP_INTP_N) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPATE EVAP BRACKET: BOUNDS EXCEEDED?") end if CALL NC_POINT_VAR(PRECIP_EVP_N,VNP) CALL NC_POINT_VAR(PRECIP_EVP_P,VPP) Qevap = FTM%NEXT_WGHT * VNP + FTM%PREV_WGHT * VPP !=================================================== CASE(PRECIP_IS_FVCOMGRID) !=================================================== FTM => PRECIP_FILE%FTIME ! PRECIPITATION CALL UPDATE_VAR_BRACKET(PRECIP_FILE,PRECIP_PRE_P,PRECIP_PRE_N,PTIME,STATUS) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPATE PRECIP BRACKET: BOUNDS EXCEEDED?") end if CALL NC_POINT_VAR(PRECIP_PRE_N,VNP) CALL NC_POINT_VAR(PRECIP_PRE_P,VPP) Qprec = FTM%NEXT_WGHT * VNP + FTM%PREV_WGHT * VPP ! EVAPORATION CALL UPDATE_VAR_BRACKET(PRECIP_FILE,PRECIP_EVP_P,PRECIP_EVP_N,PTIME,STATUS) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPATE EVAP BRACKET: BOUNDS EXCEEDED?") end if CALL NC_POINT_VAR(PRECIP_EVP_N,VNP) CALL NC_POINT_VAR(PRECIP_EVP_P,VPP) Qevap = FTM%NEXT_WGHT * VNP + FTM%PREV_WGHT * VPP CASE DEFAULT CALL FATAL_ERROR("UNKNOWN WINDS_FORCING_TYPE IN UPDATE PRECIPITATION") END SELECT END SUBROUTINE UPDATE_PRECIPITATION !==============================================================================| !==============================================================================| SUBROUTINE UPDATE_WAVE(NOW,WHS,WDIR,WPER,WLENGTH,WPER_BOT,WUB_BOT) IMPLICIT NONE TYPE(TIME), INTENT(IN) :: NOW TYPE(TIME) :: PTIME REAL(SP), ALLOCATABLE :: WHS(:),WDIR(:),WPER(:),WLENGTH(:),WPER_BOT(:),WUB_BOT(:) REAL(SP), POINTER :: VNP(:), VPP(:) TYPE(NCFTIME), POINTER :: FTM INTEGER :: STATUS REAL :: X1,X2,Y1,Y2,X0,Y0,ANGLE INTEGER :: I real:: a2, K2,H2,T2,Ub2,w2 IF(.NOT. ALLOCATED(WHS)) CALL FATAL_ERROR & &("THE WAVE HEIGHT VARIABLE PASSED TO UPDATE IS NOT ALLOCATED") IF(.NOT. ALLOCATED(WDIR)) CALL FATAL_ERROR & &("THE WAVE DIRECTION VARIABLE PASSED TO UPDATE IS NOT ALLOCATED") IF(.NOT. ALLOCATED(WPER)) CALL FATAL_ERROR & &("THE WAVE PERIOD VARIABLE PASSED TO UPDATE IS NOT ALLOCATED") IF(.NOT. ALLOCATED(WLENGTH)) CALL FATAL_ERROR & &("THE WAVE LENGTH VARIABLE PASSED TO UPDATE IS NOT ALLOCATED") IF(.NOT. ALLOCATED(WPER_BOT)) CALL FATAL_ERROR & &("THE BOTTOM WAVE PERIOD VARIABLE PASSED TO UPDATE IS NOT ALLOCATED") IF(.NOT. ALLOCATED(WUB_BOT)) CALL FATAL_ERROR & &("THE BOTTOM WAVE ORBITAL VELOCITY VARIABLE PASSED TO UPDATE IS NOT ALLOCATED") !=================================================== SELECT CASE(WAVE_KIND) !=================================================== CASE (CNSTNT) WHS(1:MT) = WAVE_HEIGHT WDIR(1:MT) = WAVE_DIRECTION WPER(1:MT) = WAVE_PERIOD WLENGTH(1:MT) = WAVE_LENGTH WPER_BOT(1:MT) = WAVE_PER_BOT WUB_BOT(1:MT) = WAVE_UB_BOT RETURN CASE(STTC) CALL FATAL_ERROR("STATIC PRECIP Not Set Up Yet") CASE(TMDPNDNT) CALL FATAL_ERROR("TIME DEPENDANT PRECIP Not Set Up Yet") CASE(PRDC) ! TO SET ZERO TIME PHASE USING RUNFILE START TIME ! PTIME= NOW - RUNFILE_StartTime ! TO USE ZERO AS THE PHASE OF THE FORCING PTIME= NOW PTIME = MOD(PTIME,PRECIP_PERIOD) CASE(VRBL) PTIME = NOW END SELECT !=================================================== !=================================================== !=================================================== SELECT CASE(WAVES_FORCING_TYPE) !=================================================== CASE(WAVES_ARE_WRFGRID) !=================================================== CASE(WAVES_ARE_FVCOMGRID) !=================================================== FTM => WAVES_FILE%FTIME ! WAVE HEIGHT CALL UPDATE_VAR_BRACKET(WAVES_FILE,WAVES_HEIGHT_P,WAVES_HEIGHT_N,PTIME,STATUS) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPATE WAVE HEIGHT BRACKET: BOUNDS EXCEEDED?") end if CALL NC_POINT_VAR(WAVES_HEIGHT_N,VNP) CALL NC_POINT_VAR(WAVES_HEIGHT_P,VPP) WHS = FTM%NEXT_WGHT * VNP + FTM%PREV_WGHT * VPP ! WAVE DIRECTIION CALL UPDATE_VAR_BRACKET(WAVES_FILE,WAVES_DIRECTION_P,WAVES_DIRECTION_N,PTIME,STATUS) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPATE WAVE DIRECTION BRACKET: BOUNDS EXCEEDED?") end if CALL NC_POINT_VAR(WAVES_DIRECTION_N,VNP) CALL NC_POINT_VAR(WAVES_DIRECTION_P,VPP) WDIR = FTM%NEXT_WGHT * VNP + FTM%PREV_WGHT * VPP DO I=1,MT X1 = COS(VNP(I)*3.1415926/180.0) X2 = COS(VPP(I)*3.1415926/180.0) Y1 = SIN(VNP(I)*3.1415926/180.0) Y2 = SIN(VPP(I)*3.1415926/180.0) X0 = FTM%NEXT_WGHT * X1 + FTM%PREV_WGHT * X2 Y0 = FTM%NEXT_WGHT * Y1 + FTM%PREV_WGHT * Y2 ANGLE = ATAN2(Y0,X0) IF(ANGLE<0)ANGLE = ANGLE + 3.1415926*2.0 WDIR(I) = ANGLE*180.0/3.1415926 END DO ! WAVE LENGTH CALL UPDATE_VAR_BRACKET(WAVES_FILE,WAVES_LENGTH_P,WAVES_LENGTH_N,PTIME,STATUS) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPATE WAVE LENGTH BRACKET: BOUNDS EXCEEDED?") end if CALL NC_POINT_VAR(WAVES_LENGTH_N,VNP) CALL NC_POINT_VAR(WAVES_LENGTH_P,VPP) WLENGTH = FTM%NEXT_WGHT * VNP + FTM%PREV_WGHT * VPP ! WAVE PERIOD CALL UPDATE_VAR_BRACKET(WAVES_FILE,WAVES_PERIOD_P,WAVES_PERIOD_N,PTIME,STATUS) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPATE WAVE PERIOD BRACKET: BOUNDS EXCEEDED?") end if CALL NC_POINT_VAR(WAVES_PERIOD_N,VNP) CALL NC_POINT_VAR(WAVES_PERIOD_P,VPP) WPER = FTM%NEXT_WGHT * VNP + FTM%PREV_WGHT * VPP ! BOTTOM WAVE PERIOD CALL UPDATE_VAR_BRACKET(WAVES_FILE,WAVES_PER_BOT_P,WAVES_PER_BOT_N,PTIME,STATUS) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPATE BOTTOM WAVE PERIOD BRACKET: BOUNDS EXCEEDED?") end if CALL NC_POINT_VAR(WAVES_PER_BOT_N,VNP) CALL NC_POINT_VAR(WAVES_PER_BOT_P,VPP) WPER_BOT = FTM%NEXT_WGHT * VNP + FTM%PREV_WGHT * VPP ! BOTTOM ORBITAL VELOCITY CALL UPDATE_VAR_BRACKET(WAVES_FILE,WAVES_UB_BOT_P,WAVES_UB_BOT_N,PTIME,STATUS) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPATE BOTTOM ORBITAL VELOCITY BRACKET: BOUNDS EXCEEDED?") end if CALL NC_POINT_VAR(WAVES_UB_BOT_N,VNP) CALL NC_POINT_VAR(WAVES_UB_BOT_P,VPP) WUB_BOT = FTM%NEXT_WGHT * VNP + FTM%PREV_WGHT * VPP ! print*,whs(36),wper(36),wlength(36) !---------------------------------------------------------------------! ! Test bottom orbital velocity !---------------------------------------------------------------------! ! a2=0.5*whs(159) ! K2=2.0*3.1415926/wlength(159) ! H2=10.0 ! T2=wper(159) ! w2=sqrt(9.8*K2*SINH(K2*H2)/COSH(K2*H2)) ! Ub2=a2*W2/sinh(H2*K2) ! print*,whs(159),ub2 CASE DEFAULT CALL FATAL_ERROR("UNKNOWN WAVES_FORCING_TYPE IN UPDATE WAVE") END SELECT END SUBROUTINE UPDATE_WAVE !==============================================================================| !==============================================================================| SUBROUTINE UPDATE_AIRPRESSURE(NOW,PA_AIR) IMPLICIT NONE TYPE(TIME), INTENT(IN) :: NOW TYPE(TIME) :: ATIME REAL(SP), ALLOCATABLE :: PA_AIR(:) REAL(SP), POINTER :: VNP(:), VPP(:) TYPE(NCFTIME), POINTER :: FTM INTEGER :: STATUS IF(.NOT. ALLOCATED(PA_AIR)) CALL FATAL_ERROR & &("THE AIR PRESSURE VARIABLE PASSED TO UPDATE IS NOT ALLOCATED") !=================================================== SELECT CASE(AIRPRESSURE_KIND) !=================================================== CASE (CNSTNT) PA_AIR(1:MT) = AIRPRESSURE_VALUE RETURN CASE(STTC) CALL FATAL_ERROR("STATIC AIR PRESSURE Not Set Up Yet") CASE(TMDPNDNT) CALL FATAL_ERROR("TIME DEPENDANT AIR PRESSURE Not Set Up Yet") CASE(PRDC) ! TO SET ZERO TIME PHASE USING RUNFILE START TIME ! ATIME= NOW - RUNFILE_StartTime ! TO USE ZERO AS THE PHASE OF THE FORCING ATIME= NOW ATIME = MOD(ATIME,AIRPRESSURE_PERIOD) CASE(VRBL) ATIME = NOW END SELECT !=================================================== !=================================================== !=================================================== SELECT CASE(AIRPRESSURE_FORCING_TYPE) !=================================================== CASE(AIRPRESSURE_IS_WRFGRID) FTM => AIRPRESSURE_P_FILE%FTIME ! AIR PRESSURE CALL UPDATE_VAR_BRACKET(AIRPRESSURE_P_FILE,AIR_PRESSURE_P,AIR_PRESSURE_N,ATIME,STATUS,AIRPRESSURE_INTP_N) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPATE AIR PRESSURE BRACKET: BOUNDS EXCEEDED?") end if CALL NC_POINT_VAR(AIR_PRESSURE_N,VNP) CALL NC_POINT_VAR(AIR_PRESSURE_P,VPP) PA_AIR = FTM%NEXT_WGHT * VNP + FTM%PREV_WGHT * VPP PA_AIR = PA_AIR * Pair_unit_factor ! Siqi Li, 2021-01-27 !=================================================== CASE(AIRPRESSURE_IS_FVCOMGRID) !=================================================== FTM => AIRPRESSURE_P_FILE%FTIME ! AIR PRESSURE CALL UPDATE_VAR_BRACKET(AIRPRESSURE_P_FILE,AIR_PRESSURE_P,AIR_PRESSURE_N,ATIME,STATUS) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPATE AIR PRESSURE BRACKET: BOUNDS EXCEEDED?") end if CALL NC_POINT_VAR(AIR_PRESSURE_N,VNP) CALL NC_POINT_VAR(AIR_PRESSURE_P,VPP) PA_AIR = FTM%NEXT_WGHT * VNP + FTM%PREV_WGHT * VPP PA_AIR = PA_AIR * Pair_unit_factor ! Siqi Li, 2021-01-27 CASE DEFAULT CALL FATAL_ERROR("UNKNOWN AIRPRESSURE_FORCING_TYPE IN UPDATE AIR PRESSURE") END SELECT END SUBROUTINE UPDATE_AIRPRESSURE !==============================================================================| SUBROUTINE UPDATE_TIDE(NOW,BND_ELV) IMPLICIT NONE TYPE(TIME), INTENT(IN) :: NOW REAL(SP), ALLOCATABLE :: BND_ELV(:) REAL(SP), POINTER :: VNP(:), VPP(:) TYPE(NCFTIME), POINTER :: FTM INTEGER :: STATUS IF(.NOT. ALLOCATED(BND_ELV)) CALL FATAL_ERROR & &("THE BOUNDARY ELEVATION VARIABLE PASSED TO UPDATE IS NOT ALLOCATED") SELECT CASE(TIDE_FORCING_TYPE) CASE(TIDE_FORCING_TIMESERIES) FTM => TIDE_FILE%FTIME ! PRECIPITATION CALL UPDATE_VAR_BRACKET(TIDE_FILE,TIDE_ELV_P,TIDE_ELV_N,NOW,STATUS) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPATE TIDE ELVATION BRACKET: BOUNDS EXCEEDED?") end if CALL NC_POINT_VAR(TIDE_ELV_N,VNP) CALL NC_POINT_VAR(TIDE_ELV_P,VPP) BND_ELV = FTM%NEXT_WGHT * VNP + FTM%PREV_WGHT * VPP CASE DEFAULT CALL FATAL_ERROR("UNKNOWN TIDAL FORCING FILE TYPE IN UPDATE_TIDE") END SELECT END SUBROUTINE UPDATE_TIDE !==============================================================================| SUBROUTINE UPDATE_OBC_SALT(NOW,SALT) IMPLICIT NONE TYPE(TIME), INTENT(IN) :: NOW REAL(SP), ALLOCATABLE :: SALT(:,:) REAL(SP), POINTER :: VNP(:,:), VPP(:,:) TYPE(NCFTIME), POINTER :: FTM INTEGER :: STATUS IF(.NOT. ALLOCATED(SALT)) CALL FATAL_ERROR & &("THE BOUNDARY SALINITY VARIABLE PASSED TO UPDATE IS NOT ALLOCATED") SELECT CASE(OBC_S_TYPE) CASE(OBC_S_SIGMA) FTM => OBC_S_FILE%FTIME ! OBC_SALT CALL UPDATE_VAR_BRACKET(OBC_S_FILE,OBC_S_P,OBC_S_N,NOW,STATUS) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPATE OBC SALINITY BRACKET: BOUNDS EXCEEDED?") end if CALL NC_POINT_VAR(OBC_S_N,VNP) CALL NC_POINT_VAR(OBC_S_P,VPP) SALT = FTM%NEXT_WGHT * VNP + FTM%PREV_WGHT * VPP CASE DEFAULT CALL FATAL_ERROR("UNKNOWN OBC SALINITY FILE TYPE IN UPDATE_OBC_SALT") END SELECT END SUBROUTINE UPDATE_OBC_SALT !==============================================================================| SUBROUTINE UPDATE_OBC_TEMP(NOW,TEMP) IMPLICIT NONE TYPE(TIME), INTENT(IN) :: NOW REAL(SP), ALLOCATABLE :: TEMP(:,:) REAL(SP), POINTER :: VNP(:,:), VPP(:,:) TYPE(NCFTIME), POINTER :: FTM INTEGER :: STATUS IF(.NOT. ALLOCATED(TEMP)) CALL FATAL_ERROR & &("THE BOUNDARY TEMPERATURE VARIABLE PASSED TO UPDATE IS NOT ALLOCATED") SELECT CASE(OBC_T_TYPE) CASE(OBC_T_SIGMA) FTM => OBC_T_FILE%FTIME ! PRECIPITATION CALL UPDATE_VAR_BRACKET(OBC_T_FILE,OBC_T_P,OBC_T_N,NOW,STATUS) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPATE OBC TEMPERATURE BRACKET: BOUNDS EXCEEDED?") end if CALL NC_POINT_VAR(OBC_T_N,VNP) CALL NC_POINT_VAR(OBC_T_P,VPP) TEMP = FTM%NEXT_WGHT * VNP + FTM%PREV_WGHT * VPP CASE DEFAULT CALL FATAL_ERROR("UNKNOWN OBC TEMPERATURE FILE TYPE IN UPDATE_OBC_TEMP") END SELECT END SUBROUTINE UPDATE_OBC_TEMP !==============================================================================| # if defined (WATER_QUALITY) SUBROUTINE UPDATE_OBC_WQM(NOW,WQM) ! USE MOD_WQM IMPLICIT NONE TYPE(TIME), INTENT(IN) :: NOW REAL(SP), ALLOCATABLE :: WQM(:,:,:) REAL(SP), POINTER :: VNP(:,:), VPP(:,:) TYPE(NCFTIME), POINTER :: FTM INTEGER :: STATUS IF(.NOT. ALLOCATED(WQM)) CALL FATAL_ERROR & &("THE BOUNDARY WATER QUALITY VARIABLE PASSED TO UPDATE IS NOT ALLOCATED") SELECT CASE(OBC_W_TYPE) CASE(OBC_W_SIGMA) FTM => OBC_W_FILE%FTIME CALL UPDATE_VAR_BRACKET(OBC_W_FILE,OBC_W_P1,OBC_W_N1,NOW,STATUS) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPDATE OBC WATER QUALITY BRACKET: BOUNDS EXCEEDED?") end if CALL NC_POINT_VAR(OBC_W_N1,VNP) CALL NC_POINT_VAR(OBC_W_P1,VPP) WQM(:,:,1) = FTM%NEXT_WGHT * VNP + FTM%PREV_WGHT * VPP CALL UPDATE_VAR_BRACKET(OBC_W_FILE,OBC_W_P2,OBC_W_N2,NOW,STATUS) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPDATE OBC WATER QUALITY BRACKET: BOUNDS EXCEEDED?") end if CALL NC_POINT_VAR(OBC_W_N2,VNP) CALL NC_POINT_VAR(OBC_W_P2,VPP) WQM(:,:,2) = FTM%NEXT_WGHT * VNP + FTM%PREV_WGHT * VPP CALL UPDATE_VAR_BRACKET(OBC_W_FILE,OBC_W_P3,OBC_W_N3,NOW,STATUS) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPDATE OBC WATER QUALITY BRACKET: BOUNDS EXCEEDED?") end if CALL NC_POINT_VAR(OBC_W_N3,VNP) CALL NC_POINT_VAR(OBC_W_P3,VPP) WQM(:,:,3) = FTM%NEXT_WGHT * VNP + FTM%PREV_WGHT * VPP CALL UPDATE_VAR_BRACKET(OBC_W_FILE,OBC_W_P4,OBC_W_N4,NOW,STATUS) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPDATE OBC WATER QUALITY BRACKET: BOUNDS EXCEEDED?") end if CALL NC_POINT_VAR(OBC_W_N4,VNP) CALL NC_POINT_VAR(OBC_W_P4,VPP) WQM(:,:,4) = FTM%NEXT_WGHT * VNP + FTM%PREV_WGHT * VPP CALL UPDATE_VAR_BRACKET(OBC_W_FILE,OBC_W_P5,OBC_W_N5,NOW,STATUS) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPDATE OBC WATER QUALITY BRACKET: BOUNDS EXCEEDED?") end if CALL NC_POINT_VAR(OBC_W_N5,VNP) CALL NC_POINT_VAR(OBC_W_P5,VPP) WQM(:,:,5) = FTM%NEXT_WGHT * VNP + FTM%PREV_WGHT * VPP CALL UPDATE_VAR_BRACKET(OBC_W_FILE,OBC_W_P6,OBC_W_N6,NOW,STATUS) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPDATE OBC WATER QUALITY BRACKET: BOUNDS EXCEEDED?") end if CALL NC_POINT_VAR(OBC_W_N6,VNP) CALL NC_POINT_VAR(OBC_W_P6,VPP) WQM(:,:,6) = FTM%NEXT_WGHT * VNP + FTM%PREV_WGHT * VPP CALL UPDATE_VAR_BRACKET(OBC_W_FILE,OBC_W_P7,OBC_W_N7,NOW,STATUS) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPDATE OBC WATER QUALITY BRACKET: BOUNDS EXCEEDED?") end if CALL NC_POINT_VAR(OBC_W_N7,VNP) CALL NC_POINT_VAR(OBC_W_P7,VPP) WQM(:,:,7) = FTM%NEXT_WGHT * VNP + FTM%PREV_WGHT * VPP CALL UPDATE_VAR_BRACKET(OBC_W_FILE,OBC_W_P8,OBC_W_N8,NOW,STATUS) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPDATE OBC WATER QUALITY BRACKET: BOUNDS EXCEEDED?") end if CALL NC_POINT_VAR(OBC_W_N8,VNP) CALL NC_POINT_VAR(OBC_W_P8,VPP) WQM(:,:,8) = FTM%NEXT_WGHT * VNP + FTM%PREV_WGHT * VPP CASE DEFAULT CALL FATAL_ERROR("UNKNOWN OBC WATER QUALITY FILE TYPE IN UPDATE_OBC_WQM") END SELECT END SUBROUTINE UPDATE_OBC_WQM # endif !==============================================================================| # if defined (BioGen) SUBROUTINE UPDATE_OBC_BIO(NOW,BIO) USE MOD_1D IMPLICIT NONE TYPE(TIME), INTENT(IN) :: NOW REAL(SP), ALLOCATABLE :: BIO(:,:,:) REAL(SP), POINTER :: VNP(:,:), VPP(:,:) TYPE(NCFTIME), POINTER :: FTM INTEGER :: STATUS IF(.NOT. ALLOCATED(BIO)) CALL FATAL_ERROR & &("THE BOUNDARY BIOLOGICAL VARIABLE PASSED TO UPDATE IS NOT ALLOCATED") SELECT CASE(OBC_B_TYPE) CASE(OBC_B_SIGMA) FTM => OBC_B_FILE%FTIME IF(NTT > 0)THEN CALL UPDATE_VAR_BRACKET(OBC_B_FILE,OBC_B_P1,OBC_B_N1,NOW,STATUS) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPDATE OBC BIOLOGICAL BRACKET: BOUNDS EXCEEDED?") end if CALL NC_POINT_VAR(OBC_B_N1,VNP) CALL NC_POINT_VAR(OBC_B_P1,VPP) BIO(:,:,1) = FTM%NEXT_WGHT * VNP + FTM%PREV_WGHT * VPP END IF IF(NTT > 1)THEN CALL UPDATE_VAR_BRACKET(OBC_B_FILE,OBC_B_P2,OBC_B_N2,NOW,STATUS) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPDATE OBC BIOLOGICAL BRACKET: BOUNDS EXCEEDED?") end if CALL NC_POINT_VAR(OBC_B_N2,VNP) CALL NC_POINT_VAR(OBC_B_P2,VPP) BIO(:,:,2) = FTM%NEXT_WGHT * VNP + FTM%PREV_WGHT * VPP END IF IF(NTT > 2)THEN CALL UPDATE_VAR_BRACKET(OBC_B_FILE,OBC_B_P3,OBC_B_N3,NOW,STATUS) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPDATE OBC BIOLOGICAL BRACKET: BOUNDS EXCEEDED?") end if CALL NC_POINT_VAR(OBC_B_N3,VNP) CALL NC_POINT_VAR(OBC_B_P3,VPP) BIO(:,:,3) = FTM%NEXT_WGHT * VNP + FTM%PREV_WGHT * VPP END IF IF(NTT > 3)THEN CALL UPDATE_VAR_BRACKET(OBC_B_FILE,OBC_B_P4,OBC_B_N4,NOW,STATUS) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPDATE OBC BIOLOGICAL BRACKET: BOUNDS EXCEEDED?") end if CALL NC_POINT_VAR(OBC_B_N4,VNP) CALL NC_POINT_VAR(OBC_B_P4,VPP) BIO(:,:,4) = FTM%NEXT_WGHT * VNP + FTM%PREV_WGHT * VPP END IF IF(NTT > 4)THEN CALL UPDATE_VAR_BRACKET(OBC_B_FILE,OBC_B_P5,OBC_B_N5,NOW,STATUS) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPDATE OBC BIOLOGICAL BRACKET: BOUNDS EXCEEDED?") end if CALL NC_POINT_VAR(OBC_B_N5,VNP) CALL NC_POINT_VAR(OBC_B_P5,VPP) BIO(:,:,5) = FTM%NEXT_WGHT * VNP + FTM%PREV_WGHT * VPP END IF IF(NTT > 5)THEN CALL UPDATE_VAR_BRACKET(OBC_B_FILE,OBC_B_P6,OBC_B_N6,NOW,STATUS) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPDATE OBC BIOLOGICAL BRACKET: BOUNDS EXCEEDED?") end if CALL NC_POINT_VAR(OBC_B_N6,VNP) CALL NC_POINT_VAR(OBC_B_P6,VPP) BIO(:,:,6) = FTM%NEXT_WGHT * VNP + FTM%PREV_WGHT * VPP END IF IF(NTT > 6)THEN CALL UPDATE_VAR_BRACKET(OBC_B_FILE,OBC_B_P7,OBC_B_N7,NOW,STATUS) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPDATE OBC BIOLOGICAL BRACKET: BOUNDS EXCEEDED?") end if CALL NC_POINT_VAR(OBC_B_N7,VNP) CALL NC_POINT_VAR(OBC_B_P7,VPP) BIO(:,:,7) = FTM%NEXT_WGHT * VNP + FTM%PREV_WGHT * VPP END IF IF(NTT > 7)THEN CALL UPDATE_VAR_BRACKET(OBC_B_FILE,OBC_B_P8,OBC_B_N8,NOW,STATUS) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPDATE OBC BIOLOGICAL BRACKET: BOUNDS EXCEEDED?") end if CALL NC_POINT_VAR(OBC_B_N8,VNP) CALL NC_POINT_VAR(OBC_B_P8,VPP) BIO(:,:,8) = FTM%NEXT_WGHT * VNP + FTM%PREV_WGHT * VPP END IF IF(NTT > 8)THEN CALL UPDATE_VAR_BRACKET(OBC_B_FILE,OBC_B_P9,OBC_B_N9,NOW,STATUS) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPDATE OBC BIOLOGICAL BRACKET: BOUNDS EXCEEDED?") end if CALL NC_POINT_VAR(OBC_B_N9,VNP) CALL NC_POINT_VAR(OBC_B_P9,VPP) BIO(:,:,9) = FTM%NEXT_WGHT * VNP + FTM%PREV_WGHT * VPP END IF IF(NTT > 9)THEN CALL UPDATE_VAR_BRACKET(OBC_B_FILE,OBC_B_P10,OBC_B_N10,NOW,STATUS) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPDATE OBC BIOLOGICAL BRACKET: BOUNDS EXCEEDED?") end if CALL NC_POINT_VAR(OBC_B_N10,VNP) CALL NC_POINT_VAR(OBC_B_P10,VPP) BIO(:,:,10) = FTM%NEXT_WGHT * VNP + FTM%PREV_WGHT * VPP END IF IF(NTT > 10)THEN CALL UPDATE_VAR_BRACKET(OBC_B_FILE,OBC_B_P11,OBC_B_N11,NOW,STATUS) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPDATE OBC BIOLOGICAL BRACKET: BOUNDS EXCEEDED?") end if CALL NC_POINT_VAR(OBC_B_N11,VNP) CALL NC_POINT_VAR(OBC_B_P11,VPP) BIO(:,:,11) = FTM%NEXT_WGHT * VNP + FTM%PREV_WGHT * VPP END IF IF(NTT > 11)THEN CALL UPDATE_VAR_BRACKET(OBC_B_FILE,OBC_B_P12,OBC_B_N12,NOW,STATUS) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPDATE OBC BIOLOGICAL BRACKET: BOUNDS EXCEEDED?") end if CALL NC_POINT_VAR(OBC_B_N12,VNP) CALL NC_POINT_VAR(OBC_B_P12,VPP) BIO(:,:,12) = FTM%NEXT_WGHT * VNP + FTM%PREV_WGHT * VPP END IF IF(NTT > 12)THEN CALL UPDATE_VAR_BRACKET(OBC_B_FILE,OBC_B_P13,OBC_B_N13,NOW,STATUS) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPDATE OBC BIOLOGICAL BRACKET: BOUNDS EXCEEDED?") end if CALL NC_POINT_VAR(OBC_B_N13,VNP) CALL NC_POINT_VAR(OBC_B_P13,VPP) BIO(:,:,13) = FTM%NEXT_WGHT * VNP + FTM%PREV_WGHT * VPP END IF IF(NTT > 13)THEN CALL UPDATE_VAR_BRACKET(OBC_B_FILE,OBC_B_P14,OBC_B_N14,NOW,STATUS) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPDATE OBC BIOLOGICAL BRACKET: BOUNDS EXCEEDED?") end if CALL NC_POINT_VAR(OBC_B_N14,VNP) CALL NC_POINT_VAR(OBC_B_P14,VPP) BIO(:,:,14) = FTM%NEXT_WGHT * VNP + FTM%PREV_WGHT * VPP END IF IF(NTT > 14)THEN CALL UPDATE_VAR_BRACKET(OBC_B_FILE,OBC_B_P15,OBC_B_N15,NOW,STATUS) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPDATE OBC BIOLOGICAL BRACKET: BOUNDS EXCEEDED?") end if CALL NC_POINT_VAR(OBC_B_N15,VNP) CALL NC_POINT_VAR(OBC_B_P15,VPP) BIO(:,:,15) = FTM%NEXT_WGHT * VNP + FTM%PREV_WGHT * VPP END IF IF(NTT > 15)THEN CALL UPDATE_VAR_BRACKET(OBC_B_FILE,OBC_B_P16,OBC_B_N16,NOW,STATUS) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPDATE OBC BIOLOGICAL BRACKET: BOUNDS EXCEEDED?") end if CALL NC_POINT_VAR(OBC_B_N16,VNP) CALL NC_POINT_VAR(OBC_B_P16,VPP) BIO(:,:,16) = FTM%NEXT_WGHT * VNP + FTM%PREV_WGHT * VPP END IF IF(NTT > 16)THEN CALL UPDATE_VAR_BRACKET(OBC_B_FILE,OBC_B_P17,OBC_B_N17,NOW,STATUS) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPDATE OBC BIOLOGICAL BRACKET: BOUNDS EXCEEDED?") end if CALL NC_POINT_VAR(OBC_B_N17,VNP) CALL NC_POINT_VAR(OBC_B_P17,VPP) BIO(:,:,17) = FTM%NEXT_WGHT * VNP + FTM%PREV_WGHT * VPP END IF IF(NTT > 17)THEN CALL UPDATE_VAR_BRACKET(OBC_B_FILE,OBC_B_P18,OBC_B_N18,NOW,STATUS) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPDATE OBC BIOLOGICAL BRACKET: BOUNDS EXCEEDED?") end if CALL NC_POINT_VAR(OBC_B_N18,VNP) CALL NC_POINT_VAR(OBC_B_P18,VPP) BIO(:,:,18) = FTM%NEXT_WGHT * VNP + FTM%PREV_WGHT * VPP END IF IF(NTT > 18)THEN CALL UPDATE_VAR_BRACKET(OBC_B_FILE,OBC_B_P19,OBC_B_N19,NOW,STATUS) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPDATE OBC BIOLOGICAL BRACKET: BOUNDS EXCEEDED?") end if CALL NC_POINT_VAR(OBC_B_N19,VNP) CALL NC_POINT_VAR(OBC_B_P19,VPP) BIO(:,:,19) = FTM%NEXT_WGHT * VNP + FTM%PREV_WGHT * VPP END IF IF(NTT > 19)THEN CALL UPDATE_VAR_BRACKET(OBC_B_FILE,OBC_B_P20,OBC_B_N20,NOW,STATUS) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPDATE OBC BIOLOGICAL BRACKET: BOUNDS EXCEEDED?") end if CALL NC_POINT_VAR(OBC_B_N20,VNP) CALL NC_POINT_VAR(OBC_B_P20,VPP) BIO(:,:,20) = FTM%NEXT_WGHT * VNP + FTM%PREV_WGHT * VPP END IF IF(NTT > 20)THEN CALL FATAL_ERROR & & ("MOD_FORCE NOT SETUP FOR NTT > 20 REVISE") ENDIF CASE DEFAULT CALL FATAL_ERROR("UNKNOWN OBC BIOLOGICAL FILE TYPE IN UPDATE_OBC_BIO") END SELECT END SUBROUTINE UPDATE_OBC_BIO # endif !==============================================================================| !==============================================================================| SUBROUTINE UPDATE_ICE(NOW,SAT,SWV,SPQ,CLD) IMPLICIT NONE TYPE(TIME), INTENT(IN) :: NOW TYPE(TIME) :: WTIME REAL(SP), ALLOCATABLE :: SAT(:) REAL(SP), ALLOCATABLE :: SWV(:) REAL(SP), ALLOCATABLE :: SLP(:) REAL(SP), ALLOCATABLE :: SPQ(:) REAL(SP), ALLOCATABLE :: CLD(:) REAL(SP), POINTER :: VNP(:), VPP(:) TYPE(NCFTIME), POINTER :: FTM INTEGER :: STATUS IF(.NOT. ALLOCATED(SAT)) CALL FATAL_ERROR & &("THE Sea Surface Air Temperature VARIABLE PASSED TO UPDATE ICE IS NOT ALLOCATED") IF(.NOT. ALLOCATED(SWV)) CALL FATAL_ERROR & &("THE SHORTWAVE RADIATION VARIABLE PASSED TO UPDATE ICE IS NOT ALLOCATED") IF(.NOT. ALLOCATED(SPQ)) CALL FATAL_ERROR & &("THE SPECIFIC HUMIDIY VARIABLE PASSED TO UPDATE ICE IS NOT ALLOCATED") IF(.NOT. ALLOCATED(CLD)) CALL FATAL_ERROR & &("THE CLOUD COVER VARIABLE PASSED TO UPDATE ICE IS NOT ALLOCATED") !=================================================== SELECT CASE(ICE_FORCING_KIND) !=================================================== CASE (CNSTNT) SAT(1:MT) = ICE_AIR_TEMP SPQ(1:MT) = ICE_SPEC_HUMIDITY CLD(1:MT) = ICE_CLOUD_COVER SWV(1:MT) = ICE_SHORTWAVE RETURN CASE(STTC) CALL FATAL_ERROR("STATIC ICE FORCING Not Set Up Yet") CASE(TMDPNDNT) CALL FATAL_ERROR("TIME DEPENDANT ICE FORCING Not Set Up Yet") CASE(PRDC) ! TO SET ZERO TIME PHASE USING RUNFILE START TIME ! WTIME= NOW - RUNFILE_StartTime ! TO USE ZERO AS THE PHASE OF THE FORCING WTIME= NOW WTIME = MOD(WTIME,ICE_PERIOD) CASE(VRBL) WTIME = NOW END SELECT !=================================================== SELECT CASE(ICE_FORCING_TYPE) !=================================================== CASE(ICE_IS_WRFGRID) !=================================================== FTM => ICE_FILE%FTIME ! THE SEA SURFACE AIR TEMP CALL UPDATE_VAR_BRACKET(ICE_FILE,ICE_SAT_P,ICE_SAT_N,WTIME,STATUS,ICE_INTP_N) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPATE ICE Surface Air Temp BRACKET: BOUNDS EXCEEDED?") end if CALL NC_POINT_VAR(ICE_SAT_N,VNP) CALL NC_POINT_VAR(ICE_SAT_P,VPP) SAT = FTM%NEXT_WGHT * VNP + FTM%PREV_WGHT * VPP ! SHORT WAVE # if !defined (ICE_FRESHWATER) ! afm 20151112 & EJA 20160921 - commented out for solar ! With SOLAR, use SOLAR-derived shortwave ! Without SOLAR, use shortwave from forcing data ! CALL UPDATE_VAR_BRACKET(ICE_FILE,ICE_SWV_P,ICE_SWV_N,WTIME,STATUS,ICE_INTP_N) CALL UPDATE_VAR_BRACKET(HEAT_FILE,ICE_SWV_P,ICE_SWV_N,WTIME,STATUS,ICE_INTP_N) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPDATE ICE SHORTWAVE BRACKET: BOUNDS EXCEEDED?") end if CALL NC_POINT_VAR(ICE_SWV_N,VNP) CALL NC_POINT_VAR(ICE_SWV_P,VPP) SWV = FTM%NEXT_WGHT * VNP + FTM%PREV_WGHT * VPP # endif ! THE SPECIFIC HUMIDITY CALL UPDATE_VAR_BRACKET(ICE_FILE,ICE_SPQ_P,ICE_SPQ_N,WTIME,STATUS,ICE_INTP_N) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPATE ICE SPECIFIC HUMIDITY BRACKET: BOUNDS EXCEEDED?") end if CALL NC_POINT_VAR(ICE_SPQ_N,VNP) CALL NC_POINT_VAR(ICE_SPQ_P,VPP) SPQ = FTM%NEXT_WGHT * VNP + FTM%PREV_WGHT * VPP ! THE CLOUD COVER CALL UPDATE_VAR_BRACKET(ICE_FILE,ICE_CLD_P,ICE_CLD_N,WTIME,STATUS,ICE_INTP_N) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPATE ICE CLOUD COVER BRACKET: BOUNDS EXCEEDED?") end if CALL NC_POINT_VAR(ICE_CLD_N,VNP) CALL NC_POINT_VAR(ICE_CLD_P,VPP) CLD = FTM%NEXT_WGHT * VNP + FTM%PREV_WGHT * VPP !=================================================== !JQI CASE(ICING_IS_FVCOMGRID) CASE(ICE_IS_FVCOMGRID) !=================================================== !JQI FTM => ICING_FILE%FTIME FTM => ICE_FILE%FTIME ! THE SEA SURFACE AIR TEMP CALL UPDATE_VAR_BRACKET(ICE_FILE,ICE_SAT_P,ICE_SAT_N,WTIME,STATUS) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPATE ICE Surface Air Temp BRACKET: BOUNDS EXCEEDED?") end if CALL NC_POINT_VAR(ICE_SAT_N,VNP) CALL NC_POINT_VAR(ICE_SAT_P,VPP) SAT = FTM%NEXT_WGHT * VNP + FTM%PREV_WGHT * VPP ! SHORT WAVE # if !defined (ICE_FRESHWATER) ! afm 20151001 commented out for solar ! With SOLAR, use SOLAR-derived shortwave ! Without SOLAR, use shortwave from forcing data ! CALL UPDATE_VAR_BRACKET(ICE_FILE,ICE_SWV_P,ICE_SWV_N,WTIME,STATUS) CALL UPDATE_VAR_BRACKET(HEAT_FILE,ICE_SWV_P,ICE_SWV_N,WTIME,STATUS) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPDATE ICE SHORTWAVE BRACKET: BOUNDS EXCEEDED?") end if CALL NC_POINT_VAR(ICE_SWV_N,VNP) CALL NC_POINT_VAR(ICE_SWV_P,VPP) SWV = FTM%NEXT_WGHT * VNP + FTM%PREV_WGHT * VPP # endif ! THE SPECIFIC HUMIDITY CALL UPDATE_VAR_BRACKET(ICE_FILE,ICE_SPQ_P,ICE_SPQ_N,WTIME,STATUS) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPATE ICE SPECIFIC HUMIDITY BRACKET: BOUNDS EXCEEDED?") end if CALL NC_POINT_VAR(ICE_SPQ_N,VNP) CALL NC_POINT_VAR(ICE_SPQ_P,VPP) SPQ = FTM%NEXT_WGHT * VNP + FTM%PREV_WGHT * VPP ! THE CLOUD COVER CALL UPDATE_VAR_BRACKET(ICE_FILE,ICE_CLD_P,ICE_CLD_N,WTIME,STATUS) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPATE ICE CLOUD COVER BRACKET: BOUNDS EXCEEDED?") end if CALL NC_POINT_VAR(ICE_CLD_N,VNP) CALL NC_POINT_VAR(ICE_CLD_P,VPP) CLD = FTM%NEXT_WGHT * VNP + FTM%PREV_WGHT * VPP !=================================================== CASE DEFAULT CALL FATAL_ERROR("UNKNOWN ICING_FORCING_TYPE IN UPDATE ICING") END SELECT !=================================================== END SUBROUTINE UPDATE_ICE !==============================================================================| !==============================================================================| SUBROUTINE UPDATE_ICING(NOW,SAT,WSPDX,WSPDY) IMPLICIT NONE TYPE(TIME), INTENT(IN) :: NOW TYPE(TIME) :: WTIME REAL(SP), ALLOCATABLE :: SAT(:) REAL(SP), ALLOCATABLE :: WSPDX(:) REAL(SP), ALLOCATABLE :: WSPDY(:) REAL(SP), POINTER :: VNP(:), VPP(:) TYPE(NCFTIME), POINTER :: FTM INTEGER :: STATUS REAL(SP), PARAMETER :: K2C = 273.15_SP IF(.NOT. ALLOCATED(SAT)) CALL FATAL_ERROR & &("THE Sea Surface Air Temperature VARIABLE PASSED TO UPDATE IS NOT ALLOCATED") IF(.NOT. ALLOCATED(WSPDX) .or. .NOT.ALLOCATED(WSPDY)) CALL FATAL_ERROR & &("THE WIND SPEED VARIABLES PASSED TO UPDATE ARE NOT ALLOCATED") !=================================================== SELECT CASE(ICING_FORCING_KIND) !=================================================== CASE (CNSTNT) WSPDX(1:MT) = ICING_WSPD WSPDY=0.0_SP ! WEATHER DATA NEEDS TO HAVE WIND VELOCITY, MUST USE RECORD ! VECTOR BUT THE MODEL ONLY NEEDS A MAGNITUDE. SAT(1:MT) = ICING_AIR_TEMP RETURN CASE(STTC) CALL FATAL_ERROR("STATIC ICING Not Set Up Yet") CASE(TMDPNDNT) CALL FATAL_ERROR("TIME DEPENDANT ICING Not Set Up Yet") CASE(PRDC) ! TO SET ZERO TIME PHASE USING RUNFILE START TIME ! WTIME= NOW - RUNFILE_StartTime ! TO USE ZERO AS THE PHASE OF THE FORCING WTIME= NOW WTIME = MOD(WTIME,ICING_PERIOD) CASE(VRBL) WTIME = NOW END SELECT !=================================================== SELECT CASE(ICING_FORCING_TYPE) !=================================================== CASE(ICING_IS_WRFGRID) !=================================================== FTM => ICING_FILE%FTIME ! THE X DIRECTION WIND SPEED CALL UPDATE_VAR_BRACKET(ICING_FILE,ICING_WSPX_P,ICING_WSPX_N,WTIME,STATUS,ICING_INTP_N) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPATE WIND SPEED X BRACKET: BOUNDS EXCEEDED?") end if CALL NC_POINT_VAR(ICING_WSPX_N,VNP) CALL NC_POINT_VAR(ICING_WSPX_P,VPP) ! ALLOCATE(WSPDX(0:MT)) WSPDX = FTM%NEXT_WGHT * VNP + FTM%PREV_WGHT * VPP ! THE Y DIRECTION WIND SPEED CALL UPDATE_VAR_BRACKET(ICING_FILE,ICING_WSPY_P,ICING_WSPY_N,WTIME,STATUS,ICING_INTP_N) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPATE WIND SPEED Y BRACKET: BOUNDS EXCEEDED?") end if CALL NC_POINT_VAR(ICING_WSPY_N,VNP) CALL NC_POINT_VAR(ICING_WSPY_P,VPP) ! ALLOCATE(WSPDY(0:MT)) WSPDY = FTM%NEXT_WGHT * VNP + FTM%PREV_WGHT * VPP ! WSPD = sqrt(wspdy**2 + wspdx**2) ! wspd(0) = 0.0_sp ! deallocate(wspdy,wspdx) ! THE SEA SURFACE AIR TEMP CALL UPDATE_VAR_BRACKET(ICING_FILE,ICING_SAT_P,ICING_SAT_N,WTIME,STATUS,ICING_INTP_N) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPATE Surface Air Temp BRACKET: BOUNDS EXCEEDED?") end if CALL NC_POINT_VAR(ICING_SAT_N,VNP) CALL NC_POINT_VAR(ICING_SAT_P,VPP) SAT = FTM%NEXT_WGHT * VNP + FTM%PREV_WGHT * VPP - K2C !=================================================== CASE(ICING_IS_FVCOMGRID) !=================================================== FTM => ICING_FILE%FTIME ! THE X DIRECTION WIND SPEED CALL UPDATE_VAR_BRACKET(ICING_FILE,ICING_WSPX_P,ICING_WSPX_N,WTIME,STATUS) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPATE WIND SPEED X BRACKET: BOUNDS EXCEEDED?") end if CALL NC_POINT_VAR(ICING_WSPX_N,VNP) CALL NC_POINT_VAR(ICING_WSPX_P,VPP) ! ALLOCATE(WSPDX(0:MT)) WSPDX = FTM%NEXT_WGHT * VNP + FTM%PREV_WGHT * VPP ! THE Y DIRECTION WIND SPEED CALL UPDATE_VAR_BRACKET(ICING_FILE,ICING_WSPY_P,ICING_WSPY_N,WTIME,STATUS) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPATE WIND SPEED Y BRACKET: BOUNDS EXCEEDED?") end if CALL NC_POINT_VAR(ICING_WSPY_N,VNP) CALL NC_POINT_VAR(ICING_WSPY_P,VPP) ! ALLOCATE(WSPDY(0:MT)) WSPDY = FTM%NEXT_WGHT * VNP + FTM%PREV_WGHT * VPP ! WSPD = sqrt(wspdy**2 + wspdx**2) ! wspd(0) = 0.0_sp ! deallocate(wspdy,wspdx) ! THE SEA SURFACE AIR TEMP CALL UPDATE_VAR_BRACKET(ICING_FILE,ICING_SAT_P,ICING_SAT_N,WTIME,STATUS) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPATE Surface Air Temp BRACKET: BOUNDS EXCEEDED?") end if CALL NC_POINT_VAR(ICING_SAT_N,VNP) CALL NC_POINT_VAR(ICING_SAT_P,VPP) SAT = FTM%NEXT_WGHT * VNP + FTM%PREV_WGHT * VPP -K2C !=================================================== CASE DEFAULT CALL FATAL_ERROR("UNKNOWN ICING_FORCING_TYPE IN UPDATE ICING") END SELECT !=================================================== END SUBROUTINE UPDATE_ICING !===================================================================== ! !===================================================================== # if defined (EQUI_TIDE) SUBROUTINE ASTRONOMY IMPLICIT NONE !S2: EQUI_ASTR(1)%II = 2 EQUI_ASTR(1)%JJ = 2 EQUI_ASTR(1)%KK = -2 EQUI_ASTR(1)%LL = 0 EQUI_ASTR(1)%MM = 0 EQUI_ASTR(1)%NN = 0 EQUI_ASTR(1)%SEMI = 0.0D0 EQUI_ASTR(1)%NJ = 3 EQUI_ASTR(1)%LDEL(1) = 0 EQUI_ASTR(1)%MDEL(1) = -1 EQUI_ASTR(1)%NDEL(1) = 0 EQUI_ASTR(1)%PH(1) = 0.0D0 EQUI_ASTR(1)%EE(1) = 0.0022D0 EQUI_ASTR(1)%IR(1) = 0 EQUI_ASTR(1)%LDEL(2) = 1 EQUI_ASTR(1)%MDEL(2) = 0 EQUI_ASTR(1)%NDEL(2) = 0 EQUI_ASTR(1)%PH(2) = 0.75D0 EQUI_ASTR(1)%EE(2) = 0.0001D0 EQUI_ASTR(1)%IR(2) = 2 EQUI_ASTR(1)%LDEL(3) = 2 EQUI_ASTR(1)%MDEL(3) = 0 EQUI_ASTR(1)%NDEL(3) = 0 EQUI_ASTR(1)%PH(3) = 0.0D0 EQUI_ASTR(1)%EE(3) = 0.0001D0 EQUI_ASTR(1)%IR(3) = 0 !M2: EQUI_ASTR(2)%II = 2 EQUI_ASTR(2)%JJ = 0 EQUI_ASTR(2)%KK = 0 EQUI_ASTR(2)%LL = 0 EQUI_ASTR(2)%MM = 0 EQUI_ASTR(2)%NN = 0 EQUI_ASTR(2)%SEMI = 0.0D0 EQUI_ASTR(2)%NJ = 9 EQUI_ASTR(2)%LDEL(1) = -1 EQUI_ASTR(2)%MDEL(1) = -1 EQUI_ASTR(2)%NDEL(1) = 0 EQUI_ASTR(2)%PH(1) = 0.75D0 EQUI_ASTR(2)%EE(1) = 0.0001D0 EQUI_ASTR(2)%IR(1) = 2 EQUI_ASTR(2)%LDEL(2) = -1 EQUI_ASTR(2)%MDEL(2) = 0 EQUI_ASTR(2)%NDEL(2) = 0 EQUI_ASTR(2)%PH(2) = 0.75D0 EQUI_ASTR(2)%EE(2) = 0.0004D0 EQUI_ASTR(2)%IR(2) = 2 EQUI_ASTR(2)%LDEL(3) = 0 EQUI_ASTR(2)%MDEL(3) = -2 EQUI_ASTR(2)%NDEL(3) = 0 EQUI_ASTR(2)%PH(3) = 0.0D0 EQUI_ASTR(2)%EE(3) = 0.0005D0 EQUI_ASTR(2)%IR(3) = 0 EQUI_ASTR(2)%LDEL(4) = 0 EQUI_ASTR(2)%MDEL(4) = -1 EQUI_ASTR(2)%NDEL(4) = 0 EQUI_ASTR(2)%PH(4) = 0.5D0 EQUI_ASTR(2)%EE(4) = 0.0373D0 EQUI_ASTR(2)%IR(4) = 0 EQUI_ASTR(2)%LDEL(5) = 1 EQUI_ASTR(2)%MDEL(5) = -1 EQUI_ASTR(2)%NDEL(5) = 0 EQUI_ASTR(2)%PH(5) = 0.25D0 EQUI_ASTR(2)%EE(5) = 0.0001D0 EQUI_ASTR(2)%IR(5) = 2 EQUI_ASTR(2)%LDEL(6) = 1 EQUI_ASTR(2)%MDEL(6) = 0 EQUI_ASTR(2)%NDEL(6) = 0 EQUI_ASTR(2)%PH(6) = 0.75D0 EQUI_ASTR(2)%EE(6) = 0.0009D0 EQUI_ASTR(2)%IR(6) = 2 EQUI_ASTR(2)%LDEL(7) = 1 EQUI_ASTR(2)%MDEL(7) = 1 EQUI_ASTR(2)%NDEL(7) = 0 EQUI_ASTR(2)%PH(7) = 0.75D0 EQUI_ASTR(2)%EE(7) = 0.0002D0 EQUI_ASTR(2)%IR(7) = 2 EQUI_ASTR(2)%LDEL(8) = 2 EQUI_ASTR(2)%MDEL(8) = 0 EQUI_ASTR(2)%NDEL(8) = 0 EQUI_ASTR(2)%PH(8) = 0.0D0 EQUI_ASTR(2)%EE(8) = 0.0006D0 EQUI_ASTR(2)%IR(8) = 0 EQUI_ASTR(2)%LDEL(9) = 2 EQUI_ASTR(2)%MDEL(9) = 1 EQUI_ASTR(2)%NDEL(9) = 0 EQUI_ASTR(2)%PH(9) = 0.0D0 EQUI_ASTR(2)%EE(9) = 0.0002D0 EQUI_ASTR(2)%IR(9) = 0 !N2: EQUI_ASTR(3)%II = 2 EQUI_ASTR(3)%JJ = -1 EQUI_ASTR(3)%KK = 0 EQUI_ASTR(3)%LL = 1 EQUI_ASTR(3)%MM = 0 EQUI_ASTR(3)%NN = 0 EQUI_ASTR(3)%SEMI = 0.0D0 EQUI_ASTR(3)%NJ = 4 EQUI_ASTR(3)%LDEL(1) = -2 EQUI_ASTR(3)%MDEL(1) = -2 EQUI_ASTR(3)%NDEL(1) = 0 EQUI_ASTR(3)%PH(1) = 0.5D0 EQUI_ASTR(3)%EE(1) = 0.0039D0 EQUI_ASTR(3)%IR(1) = 0 EQUI_ASTR(3)%LDEL(2) = -1 EQUI_ASTR(3)%MDEL(2) = 0 EQUI_ASTR(3)%NDEL(2) = 1 EQUI_ASTR(3)%PH(2) = 0.0D0 EQUI_ASTR(3)%EE(2) = 0.0008D0 EQUI_ASTR(3)%IR(2) = 0 EQUI_ASTR(3)%LDEL(3) = 0 EQUI_ASTR(3)%MDEL(3) = -2 EQUI_ASTR(3)%NDEL(3) = 0 EQUI_ASTR(3)%PH(3) = 0.0D0 EQUI_ASTR(3)%EE(3) = 0.0005D0 EQUI_ASTR(3)%IR(3) = 0 EQUI_ASTR(3)%LDEL(4) = 0 EQUI_ASTR(3)%MDEL(4) = -1 EQUI_ASTR(3)%NDEL(4) = 0 EQUI_ASTR(3)%PH(4) = 0.5D0 EQUI_ASTR(3)%EE(4) = 0.0373D0 EQUI_ASTR(3)%IR(4) = 0 !K2: EQUI_ASTR(4)%II = 2 EQUI_ASTR(4)%JJ = 2 EQUI_ASTR(4)%KK = 0 EQUI_ASTR(4)%LL = 0 EQUI_ASTR(4)%MM = 0 EQUI_ASTR(4)%NN = 0 EQUI_ASTR(4)%SEMI = 0.0D0 EQUI_ASTR(4)%NJ = 5 EQUI_ASTR(4)%LDEL(1) = -1 EQUI_ASTR(4)%MDEL(1) = 0 EQUI_ASTR(4)%NDEL(1) = 0 EQUI_ASTR(4)%PH(1) = 0.75D0 EQUI_ASTR(4)%EE(1) = 0.0024D0 EQUI_ASTR(4)%IR(1) = 2 EQUI_ASTR(4)%LDEL(2) = -1 EQUI_ASTR(4)%MDEL(2) = 1 EQUI_ASTR(4)%NDEL(2) = 0 EQUI_ASTR(4)%PH(2) = 0.75D0 EQUI_ASTR(4)%EE(2) = 0.0004D0 EQUI_ASTR(4)%IR(2) = 2 EQUI_ASTR(4)%LDEL(3) = 0 EQUI_ASTR(4)%MDEL(3) = -1 EQUI_ASTR(4)%NDEL(3) = 0 EQUI_ASTR(4)%PH(3) = 0.5D0 EQUI_ASTR(4)%EE(3) = 0.0128D0 EQUI_ASTR(4)%IR(3) = 0 EQUI_ASTR(4)%LDEL(4) = 0 EQUI_ASTR(4)%MDEL(4) = 1 EQUI_ASTR(4)%NDEL(4) = 0 EQUI_ASTR(4)%PH(4) = 0.0D0 EQUI_ASTR(4)%EE(4) = 0.2980D0 EQUI_ASTR(4)%IR(4) = 0 EQUI_ASTR(4)%LDEL(5) = 0 EQUI_ASTR(4)%MDEL(5) = 2 EQUI_ASTR(4)%NDEL(5) = 0 EQUI_ASTR(4)%PH(5) = 0.0D0 EQUI_ASTR(4)%EE(5) = 0.0324D0 EQUI_ASTR(4)%IR(5) = 0 !K1: EQUI_ASTR(5)%II = 1 EQUI_ASTR(5)%JJ = 1 EQUI_ASTR(5)%KK = 0 EQUI_ASTR(5)%LL = 0 EQUI_ASTR(5)%MM = 0 EQUI_ASTR(5)%NN = 0 EQUI_ASTR(5)%SEMI = -0.75D0 EQUI_ASTR(5)%NJ = 10 EQUI_ASTR(5)%LDEL(1) = -2 EQUI_ASTR(5)%MDEL(1) = -1 EQUI_ASTR(5)%NDEL(1) = 0 EQUI_ASTR(5)%PH(1) = 0.0D0 EQUI_ASTR(5)%EE(1) = 0.0002D0 EQUI_ASTR(5)%IR(1) = 0 EQUI_ASTR(5)%LDEL(2) = -1 EQUI_ASTR(5)%MDEL(2) = -1 EQUI_ASTR(5)%NDEL(2) = 0 EQUI_ASTR(5)%PH(2) = 0.75D0 EQUI_ASTR(5)%EE(2) = 0.0001D0 EQUI_ASTR(5)%IR(2) = 1 EQUI_ASTR(5)%LDEL(3) = -1 EQUI_ASTR(5)%MDEL(3) = 0 EQUI_ASTR(5)%NDEL(3) = 0 EQUI_ASTR(5)%PH(3) = 0.25D0 EQUI_ASTR(5)%EE(3) = 0.0007D0 EQUI_ASTR(5)%IR(3) = 1 EQUI_ASTR(5)%LDEL(4) = -1 EQUI_ASTR(5)%MDEL(4) = 1 EQUI_ASTR(5)%NDEL(4) = 0 EQUI_ASTR(5)%PH(4) = 0.75D0 EQUI_ASTR(5)%EE(4) = 0.0001D0 EQUI_ASTR(5)%IR(4) = 1 EQUI_ASTR(5)%LDEL(5) = 0 EQUI_ASTR(5)%MDEL(5) = -2 EQUI_ASTR(5)%NDEL(5) = 0 EQUI_ASTR(5)%PH(5) = 0.0D0 EQUI_ASTR(5)%EE(5) = 0.0001D0 EQUI_ASTR(5)%IR(5) = 0 EQUI_ASTR(5)%LDEL(6) = 0 EQUI_ASTR(5)%MDEL(6) = -1 EQUI_ASTR(5)%NDEL(6) = 0 EQUI_ASTR(5)%PH(6) = 0.5D0 EQUI_ASTR(5)%EE(6) = 0.0198D0 EQUI_ASTR(5)%IR(6) = 0 EQUI_ASTR(5)%LDEL(7) = 0 EQUI_ASTR(5)%MDEL(7) = 1 EQUI_ASTR(5)%NDEL(7) = 0 EQUI_ASTR(5)%PH(7) = 0.0D0 EQUI_ASTR(5)%EE(7) = 0.1356D0 EQUI_ASTR(5)%IR(7) = 0 EQUI_ASTR(5)%LDEL(8) = 0 EQUI_ASTR(5)%MDEL(8) = 2 EQUI_ASTR(5)%NDEL(8) = 0 EQUI_ASTR(5)%PH(8) = 0.5D0 EQUI_ASTR(5)%EE(8) = 0.0029D0 EQUI_ASTR(5)%IR(8) = 0 EQUI_ASTR(5)%LDEL(9) = 1 EQUI_ASTR(5)%MDEL(9) = 0 EQUI_ASTR(5)%NDEL(9) = 0 EQUI_ASTR(5)%PH(9) = 0.25D0 EQUI_ASTR(5)%EE(9) = 0.0002D0 EQUI_ASTR(5)%IR(9) = 1 EQUI_ASTR(5)%LDEL(10) = 1 EQUI_ASTR(5)%MDEL(10) = 1 EQUI_ASTR(5)%NDEL(10) = 0 EQUI_ASTR(5)%PH(10) = 0.25D0 EQUI_ASTR(5)%EE(10) = 0.0001D0 EQUI_ASTR(5)%IR(10) = 1 !P1: EQUI_ASTR(6)%II = 1 EQUI_ASTR(6)%JJ = 1 EQUI_ASTR(6)%KK = -2 EQUI_ASTR(6)%LL = 0 EQUI_ASTR(6)%MM = 0 EQUI_ASTR(6)%NN = 0 EQUI_ASTR(6)%SEMI = -0.25D0 EQUI_ASTR(6)%NJ = 6 EQUI_ASTR(6)%LDEL(1) = 0 EQUI_ASTR(6)%MDEL(1) = -2 EQUI_ASTR(6)%NDEL(1) = 0 EQUI_ASTR(6)%PH(1) = 0.0D0 EQUI_ASTR(6)%EE(1) = 0.0008D0 EQUI_ASTR(6)%IR(1) = 0 EQUI_ASTR(6)%LDEL(2) = 0 EQUI_ASTR(6)%MDEL(2) = -1 EQUI_ASTR(6)%NDEL(2) = 0 EQUI_ASTR(6)%PH(2) = 0.5D0 EQUI_ASTR(6)%EE(2) = 0.0112D0 EQUI_ASTR(6)%IR(2) = 0 EQUI_ASTR(6)%LDEL(3) = 0 EQUI_ASTR(6)%MDEL(3) = 0 EQUI_ASTR(6)%NDEL(3) = 2 EQUI_ASTR(6)%PH(3) = 0.5D0 EQUI_ASTR(6)%EE(3) = 0.0004D0 EQUI_ASTR(6)%IR(3) = 0 EQUI_ASTR(6)%LDEL(4) = 1 EQUI_ASTR(6)%MDEL(4) = 0 EQUI_ASTR(6)%NDEL(4) = 0 EQUI_ASTR(6)%PH(4) = 0.75D0 EQUI_ASTR(6)%EE(4) = 0.0004D0 EQUI_ASTR(6)%IR(4) = 1 EQUI_ASTR(6)%LDEL(5) = 2 EQUI_ASTR(6)%MDEL(5) = 0 EQUI_ASTR(6)%NDEL(5) = 0 EQUI_ASTR(6)%PH(5) = 0.5D0 EQUI_ASTR(6)%EE(5) = 0.0015D0 EQUI_ASTR(6)%IR(5) = 0 EQUI_ASTR(6)%LDEL(6) = 2 EQUI_ASTR(6)%MDEL(6) = 1 EQUI_ASTR(6)%NDEL(6) = 0 EQUI_ASTR(6)%PH(6) = 0.5D0 EQUI_ASTR(6)%EE(6) = 0.0003D0 EQUI_ASTR(6)%IR(6) = 0 !O1: EQUI_ASTR(7)%II = 1 EQUI_ASTR(7)%JJ = -1 EQUI_ASTR(7)%KK = 0 EQUI_ASTR(7)%LL = 0 EQUI_ASTR(7)%MM = 0 EQUI_ASTR(7)%NN = 0 EQUI_ASTR(7)%SEMI = -0.25D0 EQUI_ASTR(7)%NJ = 8 EQUI_ASTR(7)%LDEL(1) = -1 EQUI_ASTR(7)%MDEL(1) = 0 EQUI_ASTR(7)%NDEL(1) = 0 EQUI_ASTR(7)%PH(1) = 0.25D0 EQUI_ASTR(7)%EE(1) = 0.0003D0 EQUI_ASTR(7)%IR(1) = 1 EQUI_ASTR(7)%LDEL(2) = 0 EQUI_ASTR(7)%MDEL(2) = -2 EQUI_ASTR(7)%NDEL(2) = 0 EQUI_ASTR(7)%PH(2) = 0.5D0 EQUI_ASTR(7)%EE(2) = 0.0058D0 EQUI_ASTR(7)%IR(2) = 0 EQUI_ASTR(7)%LDEL(3) = 0 EQUI_ASTR(7)%MDEL(3) = -1 EQUI_ASTR(7)%NDEL(3) = 0 EQUI_ASTR(7)%PH(3) = 0.0D0 EQUI_ASTR(7)%EE(3) = 0.1885D0 EQUI_ASTR(7)%IR(3) = 0 EQUI_ASTR(7)%LDEL(4) = 1 EQUI_ASTR(7)%MDEL(4) = -1 EQUI_ASTR(7)%NDEL(4) = 0 EQUI_ASTR(7)%PH(4) = 0.25D0 EQUI_ASTR(7)%EE(4) = 0.0004D0 EQUI_ASTR(7)%IR(4) = 1 EQUI_ASTR(7)%LDEL(5) = 1 EQUI_ASTR(7)%MDEL(5) = 0 EQUI_ASTR(7)%NDEL(5) = 0 EQUI_ASTR(7)%PH(5) = 0.75D0 EQUI_ASTR(7)%EE(5) = 0.0029D0 EQUI_ASTR(7)%IR(5) = 1 EQUI_ASTR(7)%LDEL(6) = 1 EQUI_ASTR(7)%MDEL(6) = 1 EQUI_ASTR(7)%NDEL(6) = 0 EQUI_ASTR(7)%PH(6) = 0.25D0 EQUI_ASTR(7)%EE(6) = 0.0004D0 EQUI_ASTR(7)%IR(6) = 1 EQUI_ASTR(7)%LDEL(7) = 2 EQUI_ASTR(7)%MDEL(7) = 0 EQUI_ASTR(7)%NDEL(7) = 0 EQUI_ASTR(7)%PH(7) = 0.5D0 EQUI_ASTR(7)%EE(7) = 0.0064D0 EQUI_ASTR(7)%IR(7) = 0 EQUI_ASTR(7)%LDEL(8) = 2 EQUI_ASTR(7)%MDEL(8) = 1 EQUI_ASTR(7)%NDEL(8) = 0 EQUI_ASTR(7)%PH(8) = 0.5D0 EQUI_ASTR(7)%EE(8) = 0.0010D0 EQUI_ASTR(7)%IR(8) = 0 !Q1: EQUI_ASTR(8)%II = 1 EQUI_ASTR(8)%JJ = -2 EQUI_ASTR(8)%KK = 0 EQUI_ASTR(8)%LL = 1 EQUI_ASTR(8)%MM = 0 EQUI_ASTR(8)%NN = 0 EQUI_ASTR(8)%SEMI = -0.25D0 EQUI_ASTR(8)%NJ = 10 EQUI_ASTR(8)%LDEL(1) = -2 EQUI_ASTR(8)%MDEL(1) = -3 EQUI_ASTR(8)%NDEL(1) = 0 EQUI_ASTR(8)%PH(1) = 0.5D0 EQUI_ASTR(8)%EE(1) = 0.0007D0 EQUI_ASTR(8)%IR(1) = 0 EQUI_ASTR(8)%LDEL(2) = -2 EQUI_ASTR(8)%MDEL(2) = -2 EQUI_ASTR(8)%NDEL(2) = 0 EQUI_ASTR(8)%PH(2) = 0.5D0 EQUI_ASTR(8)%EE(2) = 0.0039D0 EQUI_ASTR(8)%IR(2) = 0 EQUI_ASTR(8)%LDEL(3) = -1 EQUI_ASTR(8)%MDEL(3) = -2 EQUI_ASTR(8)%NDEL(3) = 0 EQUI_ASTR(8)%PH(3) = 0.75D0 EQUI_ASTR(8)%EE(3) = 0.0010D0 EQUI_ASTR(8)%IR(3) = 1 EQUI_ASTR(8)%LDEL(4) = -1 EQUI_ASTR(8)%MDEL(4) = -1 EQUI_ASTR(8)%NDEL(4) = 0 EQUI_ASTR(8)%PH(4) = 0.75D0 EQUI_ASTR(8)%EE(4) = 0.0115D0 EQUI_ASTR(8)%IR(4) = 1 EQUI_ASTR(8)%LDEL(5) = -1 EQUI_ASTR(8)%MDEL(5) = 0 EQUI_ASTR(8)%NDEL(5) = 0 EQUI_ASTR(8)%PH(5) = 0.75D0 EQUI_ASTR(8)%EE(5) = 0.0292D0 EQUI_ASTR(8)%IR(5) = 1 EQUI_ASTR(8)%LDEL(6) = 0 EQUI_ASTR(8)%MDEL(6) = -2 EQUI_ASTR(8)%NDEL(6) = 0 EQUI_ASTR(8)%PH(6) = 0.5D0 EQUI_ASTR(8)%EE(6) = 0.0057D0 EQUI_ASTR(8)%IR(6) = 0 EQUI_ASTR(8)%LDEL(7) = -1 EQUI_ASTR(8)%MDEL(7) = 0 EQUI_ASTR(8)%NDEL(7) = 1 EQUI_ASTR(8)%PH(7) = 0.0D0 EQUI_ASTR(8)%EE(7) = 0.0008D0 EQUI_ASTR(8)%IR(7) = 0 EQUI_ASTR(8)%LDEL(8) = 0 EQUI_ASTR(8)%MDEL(8) = -1 EQUI_ASTR(8)%NDEL(8) = 0 EQUI_ASTR(8)%PH(8) = 0.0D0 EQUI_ASTR(8)%EE(8) = 0.1884D0 EQUI_ASTR(8)%IR(8) = 0 EQUI_ASTR(8)%LDEL(9) = 1 EQUI_ASTR(8)%MDEL(9) = 0 EQUI_ASTR(8)%NDEL(9) = 0 EQUI_ASTR(8)%PH(9) = 0.75D0 EQUI_ASTR(8)%EE(9) = 0.0018D0 EQUI_ASTR(8)%IR(9) = 1 EQUI_ASTR(8)%LDEL(10) = 2 EQUI_ASTR(8)%MDEL(10) = 0 EQUI_ASTR(8)%NDEL(10) = 0 EQUI_ASTR(8)%PH(10) = 0.5D0 EQUI_ASTR(8)%EE(10) = 0.0028D0 EQUI_ASTR(8)%IR(10) = 0 END SUBROUTINE ASTRONOMY # endif # if defined (WAVE_CURRENT_INTERACTION) !================================================================ SUBROUTINE SURFACE_WIND2WAVE(IGRD) USE SWCOMM2 IMPLICIT NONE ! SOME NC POINTERS TYPE(NCATT), POINTER :: ATT, ATT_DATE TYPE(NCDIM), POINTER :: DIM TYPE(NCVAR), POINTER :: VAR LOGICAL :: FOUND REAL(SP), POINTER :: STORAGE_ARR(:,:), storage_vec(:) TYPE(TIME) :: TIMETEST INTEGER :: LATS, LONS, I, Ntimes INTEGER :: STATUS CHARACTER(len=60) :: xstr, ystr INTEGER :: IGRD IF(DBG_SET(DBG_SBR)) write(IPT,*) "START SURFACE_WIND2WAVE" NULLIFY(ATT,DIM,VAR,STORAGE_ARR,STORAGE_VEC) IF (.NOT. WIND_ON ) THEN IF(DBG_SET(DBG_LOG)) write(IPT,*) "! SURFACE WIND FORCING IS OFF!" ALLOCATE(WINDS_FORCING_COMMENTS(1)) WINDS_FORCING_COMMENTS(1) = "SURFACE WIND FORCING IS OFF" RETURN END IF IF (WIND_TYPE /= SPEED) CALL FATAL_ERROR& &("YOU MUST SELECT A WIND TYPE IN THE RUNFILE: "//TRIM(SPEED)) ! DETERMINE HOW TO LOAD THE DATA SELECT CASE(WIND_KIND) CASE (CNSTNT) IF (WIND_TYPE == SPEED)THEN RETURN ELSEIF(WIND_TYPE == STRESS)THEN CALL FATAL_ERROR("WIND_TYPE MUST BE SPEED FOR THIS CASE") END IF CASE(STTC) CALL FATAL_ERROR("STATIC WIND Not Set Up Yet") CASE(TMDPNDNT) CALL FATAL_ERROR("TIME DEPENDANT WIND Not Set Up Yet") CASE(PRDC) CALL FATAL_ERROR("PERIODIC SURFACE WIND FORCING Not Set Up Yet for Wave Model") CASE(VRBL) WINDS_FILE => FIND_FILE(FILEHEAD,trim(WIND_FILE),FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("COULD NOT FIND SURFACE WIND BOUNDARY CONDINTION FILE OBJECT",& & "FILE NAME: "//TRIM(WIND_FILE)) ! DETERMINE GRID TYPE BASED ON SOURCE ATTRIBUTE ATT => FIND_ATT(WINDS_FILE,"source",FOUND) IF(.not. FOUND) ATT => FIND_ATT(WINDS_FILE,"Source",FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN SURFACE WIND BOUNDARY CONDITION FILE OBJECT",& & "FILE NAME: "//TRIM(WIND_FILE),& &"COULD NOT FIND GLOBAL ATTRIBURE: 'source'") ! LOOK FOR THE DIMENSIONS DIM => FIND_UNLIMITED(WINDS_FILE,FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN SURFACE WIND BOUNDARY CONDITION FILE OBJECT",& & "FILE NAME: "//TRIM(WIND_FILE),& &"COULD NOT FIND THE UNLIMITED DIMENSION") NTIMES = DIM%DIM ! CHECK THE FILE TIME AND COMPARE WITH MODEL RUN TIME TIMETEST = get_file_time(WINDS_FILE,1) IF(TIMETEST > STARTTIME) CALL FATAL_ERROR & & ("IN SURFACE WIND BOUNDARY CONDITION FILE OBJECT",& & "FILE NAME: "//TRIM(WIND_FILE),& &"THE MODEL RUN STARTS BEFORE THE FORCING TIME SERIES") IFLBEG(IGRD) = SECONDS(TIMETEST) TIMETEST = get_file_time(WINDS_FILE,ntimes) IF(TIMETEST < ENDTIME) CALL FATAL_ERROR & & ("IN SURFACE WIND BOUNDARY CONDITION FILE OBJECT",& & "FILE NAME: "//TRIM(WIND_FILE),& &"THE MODEL RUN ENDS AFTER THE FORCING TIME SERIES") IFLEND(IGRD) = SECONDS(TIMETEST) IFLEND(IGRD) = IFLEND(IGRD)-IFLBEG(IGRD)+3600.0 IFLBEG(IGRD) = 0.0 IFLINT(IGRD) = (IFLEND(IGRD) - IFLBEG(IGRD))/NTIMES CASE DEFAULT CALL FATAL_ERROR("SURFACE_WINDSTRESS: UNKNOWN WIND KIND?") END SELECT !============================================================== SELECT CASE(WINDS_FORCING_TYPE) !============================================================== CASE(WINDS_ARE_WRFGRID) !============================================================== IF(DBG_SET(DBG_LOG)) WRITE(IPT,*) & & "! SETTING UP WIND STRESS FORCING FROM A 'wrf grid' FILE" DIM => FIND_DIM(WINDS_FILE,'south_north',FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN SURFACE WIND BOUNDARY CONDITION FILE OBJECT",& & "FILE NAME: "//TRIM(WIND_FILE),& & "COULD NOT FIND DIMENSION 'south_north'") LATS = DIM%DIM DIM => FIND_DIM(WINDS_FILE,'west_east',FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN SURFACE WIND BOUNDARY CONDITION FILE OBJECT",& & "FILE NAME: "//TRIM(WIND_FILE),& & "COULD NOT FIND DIMENSION 'west_east'") LONS = DIM%DIM CALL SET_FILE_INTERP_bilinear(WINDS_FILE,WINDW_INTP_N,WINDW_INTP_C) ! SETUP THE ACTUAL VARIABLES USED TO LOAD DATA! IF (WIND_TYPE == SPEED)THEN ! WIND SPEED IN THE X or EAST-WEST DIRECTION VAR => FIND_VAR(WINDS_FILE,"uwind_speed",FOUND) IF(.not. FOUND) VAR => FIND_VAR(WINDS_FILE,"U10",FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN SURFACE WIND BOUNDARY CONDITION FILE OBJECT",& & "FILE NAME: "//TRIM(WIND_FILE),& & "COULD NOT FIND VARIABLE 'uwind_speed' or 'U10'") ELSEIF(WIND_TYPE == STRESS)THEN END IF ! MAKE SPACE FOR THE DATA FROM THE FILE ALLOCATE(STORAGE_ARR(lons,lats), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN SURFACE WINDSTRESS") WINDW_STRX_N => reference_var(var) CALL NC_CONNECT_PVAR(WINDW_STRX_N,STORAGE_ARR) NULLIFY(STORAGE_ARR) ! MAKE SPACE FOR THE INTERPOLATED DATA ALLOCATE(STORAGE_VEC(0:NT), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN SURFACE WINDSTRESS") CALL NC_CONNECT_PVAR(WINDW_STRX_N,STORAGE_VEC) NULLIFY(STORAGE_VEC) ! MAKE SPACE FOR THE DATA FROM THE FILE ALLOCATE(STORAGE_ARR(lons,lats), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN SURFACE WINDSTRESS") WINDW_STRX_P => reference_var(var) CALL NC_CONNECT_PVAR(WINDW_STRX_P,STORAGE_ARR) NULLIFY(STORAGE_ARR) ! MAKE SPACE FOR THE INTERPOLATED DATA ALLOCATE(STORAGE_VEC(0:NT), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN SURFACE WINDSTRESS") CALL NC_CONNECT_PVAR(WINDW_STRX_P,STORAGE_VEC) NULLIFY(STORAGE_VEC) IF (WIND_TYPE == SPEED)THEN ! WIND SPEED IN THE Y or NORTH SOUTH DIRECTION VAR => FIND_VAR(WINDS_FILE,"vwind_speed",FOUND) IF(.not. FOUND) VAR => FIND_VAR(WINDS_FILE,"V10",FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN SURFACE WIND BOUNDARY CONDITION FILE OBJECT",& & "FILE NAME: "//TRIM(WIND_FILE),& & "COULD NOT FIND VARIABLE 'vwind_speed' or 'V10'") ELSEIF(WIND_TYPE == STRESS)THEN END IF ! MAKE SPACE FOR THE DATA FROM THE FILE ALLOCATE(STORAGE_ARR(lons,lats), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN SURFACE WINDSTRESS") WINDW_STRY_N => reference_var(var) CALL NC_CONNECT_PVAR(WINDW_STRY_N,STORAGE_ARR) NULLIFY(STORAGE_ARR) ! MAKE SPACE FOR THE INTERPOLATED DATA ALLOCATE(STORAGE_VEC(0:NT), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN SURFACE WINDSTRESS") CALL NC_CONNECT_PVAR(WINDW_STRY_N,STORAGE_VEC) NULLIFY(STORAGE_VEC) ! MAKE SPACE FOR THE DATA FROM THE FILE ALLOCATE(STORAGE_ARR(lons,lats), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN SURFACE WINDSTRESS") WINDW_STRY_P => reference_var(var) CALL NC_CONNECT_PVAR(WINDW_STRY_P,STORAGE_ARR) NULLIFY(STORAGE_ARR) ! MAKE SPACE FOR THE INTERPOLATED DATA ALLOCATE(STORAGE_VEC(0:NT), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN SURFACE WINDSTRESS") CALL NC_CONNECT_PVAR(WINDW_STRY_P,STORAGE_VEC) NULLIFY(STORAGE_VEC) !============================================================== CASE(WINDS_ARE_FVCOMGRID) !============================================================== IF(DBG_SET(DBG_LOG)) WRITE(IPT,*) & & "! SETTING UP WIND STRESS FORCING FROM A 'FVCOM GRID' FILE" DIM => FIND_DIM(WINDS_FILE,'node',FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN SURFACE WIND BOUNDARY CONDITION FILE OBJECT",& & "FILE NAME: "//TRIM(WIND_FILE),& & "COULD NOT FIND DIMENSION 'node'") if (mgl /= dim%dim) CALL FATAL_ERROR& &("Surface Windstress: the number of nodes in the file does not match the fvcom grid?") DIM => FIND_DIM(WINDS_FILE,'nele',FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN SURFACE WIND BOUNDARY CONDITION FILE OBJECT",& & "FILE NAME: "//TRIM(WIND_FILE),& & "COULD NOT FIND DIMENSION 'nele'") if (ngl /= dim%dim) CALL FATAL_ERROR& &("Surface Windstress: the number of elements in the file does not match the fvcom grid?") ! SETUP THE ACTUAL VARIABLES USED TO LOAD DATA! IF (WIND_TYPE == SPEED)THEN ! WIND SPEED IN THE X or EAST-WEST DIRECTION VAR => FIND_VAR(WINDS_FILE,"uwind_speed",FOUND) IF(.not. FOUND) VAR => FIND_VAR(WINDS_FILE,"U10",FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN SURFACE WIND BOUNDARY CONDITION FILE OBJECT",& & "FILE NAME: "//TRIM(WIND_FILE),& & "COULD NOT FIND VARIABLE 'uwind_speed' or 'U10'") ELSEIF(WIND_TYPE == STRESS)THEN END IF ! MAKE SPACE FOR THE DATA FROM THE FILE WINDW_STRX_N => reference_var(var) ALLOCATE(STORAGE_VEC(0:NT), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN SURFACE WINDSTRESS") CALL NC_CONNECT_PVAR(WINDW_STRX_N,STORAGE_VEC) NULLIFY(STORAGE_VEC) ! MAKE SPACE FOR THE DATA FROM THE FILE WINDW_STRX_P => reference_var(var) ALLOCATE(STORAGE_VEC(0:NT), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN SURFACE WINDSTRESS") CALL NC_CONNECT_PVAR(WINDW_STRX_P,STORAGE_VEC) NULLIFY(STORAGE_VEC) IF (WIND_TYPE == SPEED)THEN ! WIND SPEED IN THE Y or NORTH SOUTH DIRECTION VAR => FIND_VAR(WINDS_FILE,"vwind_speed",FOUND) IF(.not. FOUND) VAR => FIND_VAR(WINDS_FILE,"V10",FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN SURFACE WIND BOUNDARY CONDITION FILE OBJECT",& & "FILE NAME: "//TRIM(WIND_FILE),& & "COULD NOT FIND VARIABLE 'vwind_speed' or 'V10'") ELSEIF(WIND_TYPE == STRESS)THEN END IF ! MAKE SPACE FOR THE DATA FROM THE FILE WINDW_STRY_N => reference_var(var) ALLOCATE(STORAGE_VEC(0:NT), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN SURFACE WINDSTRESS") CALL NC_CONNECT_PVAR(WINDW_STRY_N,STORAGE_VEC) NULLIFY(STORAGE_VEC) ! MAKE SPACE FOR THE DATA FROM THE FILE WINDW_STRY_P => reference_var(var) ALLOCATE(STORAGE_VEC(0:NT), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN SURFACE WINDSTRESS") CALL NC_CONNECT_PVAR(WINDW_STRY_P,STORAGE_VEC) NULLIFY(STORAGE_VEC) !============================================================== CASE(WINDS_ARE_PT_SOURCE) !============================================================== IF(DBG_SET(DBG_LOG)) WRITE(IPT,*) & & "! SETTING UP WIND STRESS FORCING FROM A 'FVCOM GRID' FILE" ! SETUP THE ACTUAL VARIABLES USED TO LOAD DATA! IF (WIND_TYPE == SPEED)THEN ! WIND SPEED IN THE X or EAST-WEST DIRECTION VAR => FIND_VAR(WINDS_FILE,"uwind_speed",FOUND) IF(.not. FOUND) VAR => FIND_VAR(WINDS_FILE,"U10",FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN SURFACE WIND BOUNDARY CONDITION FILE OBJECT",& & "FILE NAME: "//TRIM(WIND_FILE),& & "COULD NOT FIND VARIABLE 'uwind_speed' or 'U10'") ELSEIF(WIND_TYPE == STRESS)THEN END IF ! MAKE SPACE FOR THE DATA FROM THE FILE WINDW_STRX_N => reference_var(var) ALLOCATE(STORAGE_VEC(1), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN SURFACE WINDSTRESS") CALL NC_CONNECT_PVAR(WINDW_STRX_N,STORAGE_VEC) NULLIFY(STORAGE_VEC) ! MAKE SPACE FOR THE DATA FROM THE FILE WINDW_STRX_P => reference_var(var) ALLOCATE(STORAGE_VEC(1), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN SURFACE WINDSTRESS") CALL NC_CONNECT_PVAR(WINDW_STRX_P,STORAGE_VEC) NULLIFY(STORAGE_VEC) IF (WIND_TYPE == SPEED)THEN ! WIND SPEED IN THE Y or NORTH SOUTH DIRECTION VAR => FIND_VAR(WINDS_FILE,"vwind_speed",FOUND) IF(.not. FOUND) VAR => FIND_VAR(WINDS_FILE,"V10",FOUND) IF(.not. FOUND) CALL FATAL_ERROR & & ("IN SURFACE WIND BOUNDARY CONDITION FILE OBJECT",& & "FILE NAME: "//TRIM(WIND_FILE),& & "COULD NOT FIND VARIABLE 'vwind_speed' or 'V10'") ELSEIF(WIND_TYPE == STRESS)THEN END IF ! MAKE SPACE FOR THE DATA FROM THE FILE WINDW_STRY_N => reference_var(var) ALLOCATE(STORAGE_VEC(1), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN SURFACE WINDSTRESS") CALL NC_CONNECT_PVAR(WINDW_STRY_N,STORAGE_VEC) NULLIFY(STORAGE_VEC) ! MAKE SPACE FOR THE DATA FROM THE FILE WINDW_STRY_P => reference_var(var) ALLOCATE(STORAGE_VEC(1), stat = status) IF(STATUS /= 0) CALL FATAL_ERROR("ALLOCATION ERROR IN SURFACE WINDSTRESS") CALL NC_CONNECT_PVAR(WINDW_STRY_P,STORAGE_VEC) NULLIFY(STORAGE_VEC) !============================================================== CASE DEFAULT !============================================================== CALL FATAL_ERROR("CAN NOT RECOGNIZE WIND FILE TYPE!") !============================================================== END SELECT !============================================================== ! ---------- new: 2016 , april, Karsten Lettmann after Hint by Qi ------------------------- ! Initialize some variables ! afm 20150914 ! Need initialization. Otherwise, random values are asigned ! and cause a hanging problem of MPI job in UPDATE_VAR_BRACKET ! This problem reported with Intel15.0.3. windw_strx_n%curr_stkcnt = 0; windw_strx_p%curr_stkcnt = 0 windw_stry_n%curr_stkcnt = 0; windw_stry_p%curr_stkcnt = 0 ! -------- end new --------------------------------------------- IF(DBG_SET(DBG_SBR)) write(IPT,*) "END SURFACE_WIND2WAVE" END SUBROUTINE SURFACE_WIND2WAVE !==============================================================================| SUBROUTINE UPDATE_WIND2WAVE(NOW,wstrx,wstry) IMPLICIT NONE TYPE(TIME), INTENT(IN) :: NOW TYPE(TIME) :: WTIME REAL(SP), ALLOCATABLE :: wstrx(:),wstry(:),wstrxy(:) REAL(SP), POINTER :: UNP(:),UPP(:),VNP(:), VPP(:) REAL(SP), ALLOCATABLE :: UVNP(:),UVPP(:),UVXY(:) TYPE(NCFTIME), POINTER :: FTM INTEGER :: STATUS IF(.NOT. ALLOCATED(wstrx)) CALL FATAL_ERROR & &("THE WIND VARIABLE PASSED TO UPDATE IS NOT ALLOCATED") IF(.NOT. ALLOCATED(wstry)) CALL FATAL_ERROR & &("THE WIND VARIABLE PASSED TO UPDATE IS NOT ALLOCATED") !=================================================== SELECT CASE(WIND_KIND) !=================================================== CASE (CNSTNT) wstrx(1:NT) = WIND_X wstry(1:NT) = WIND_Y RETURN CASE(STTC) CALL FATAL_ERROR("STATIC WIND Not Set Up Yet") CASE(TMDPNDNT) CALL FATAL_ERROR("TIME DEPENDANT WIND Not Set Up Yet") CASE(PRDC) ! TO SET ZERO TIME PHASE USING RUNFILE START TIME ! WTIME= NOW - RUNFILE_StartTime ! TO USE ZERO AS THE PHASE OF THE FORCING WTIME= NOW WTIME = MOD(WTIME,WINDS_PERIOD) CASE(VRBL) WTIME = NOW END SELECT !=================================================== !=================================================== !=================================================== SELECT CASE(WINDS_FORCING_TYPE) !=================================================== CASE(WINDS_ARE_WRFGRID) FTM => WINDS_FILE%FTIME ! THE X DIRECTION WIND STRESS CALL UPDATE_VAR_BRACKET(WINDS_FILE,WINDW_STRX_P,WINDW_STRX_N,WTIME,STATUS,WINDW_INTP_C) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPATE WIND X BRACKET: BOUNDS EXCEEDED?") end if CALL NC_POINT_VAR(WINDW_STRX_N,UNP) CALL NC_POINT_VAR(WINDW_STRX_P,UPP) WSTRX = FTM%NEXT_WGHT * UNP + FTM%PREV_WGHT * UPP ! THE Y DIRECTION WIND STRESS CALL UPDATE_VAR_BRACKET(WINDS_FILE,WINDW_STRY_P,WINDW_STRY_N,WTIME,STATUS,WINDW_INTP_C) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPATE WIND Y BRACKET: BOUNDS EXCEEDED?") end if CALL NC_POINT_VAR(WINDW_STRY_N,VNP) CALL NC_POINT_VAR(WINDW_STRY_P,VPP) WSTRY = FTM%NEXT_WGHT * VNP + FTM%PREV_WGHT * VPP ALLOCATE(UVNP(0:NT)) ALLOCATE(UVPP(0:NT)) ALLOCATE(UVXY(0:NT)) ALLOCATE(WSTRXY(0:NT)) UVNP = UNP*UNP+VNP*VNP UVPP = UPP*UPP+VPP*VPP UVNP = SQRT(UVNP) UVPP = SQRT(UVPP) WSTRXY = FTM%NEXT_WGHT * UVNP + FTM%PREV_WGHT * UVPP UVXY = WSTRX*WSTRX + WSTRY*WSTRY UVXY = SQRT(UVXY) + 1.0e-4_SP WSTRX = WSTRXY*WSTRX/UVXY WSTRY = WSTRXY*WSTRY/UVXY DEALLOCATE(UVNP,UVPP,UVXY,WSTRXY) !=================================================== CASE(WINDS_ARE_FVCOMGRID) !=================================================== FTM => WINDS_FILE%FTIME ! THE X DIRECTION WIND STRESS CALL UPDATE_VAR_BRACKET(WINDS_FILE,WINDW_STRX_P,WINDW_STRX_N,WTIME,STATUS) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPATE WIND X BRACKET: BOUNDS EXCEEDED?") end if CALL NC_POINT_VAR(WINDW_STRX_N,UNP) CALL NC_POINT_VAR(WINDW_STRX_P,UPP) WSTRX = FTM%NEXT_WGHT * UNP + FTM%PREV_WGHT * UPP ! THE Y DIRECTION WIND STRESS CALL UPDATE_VAR_BRACKET(WINDS_FILE,WINDW_STRY_P,WINDW_STRY_N,WTIME,STATUS) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPATE WIND Y BRACKET: BOUNDS EXCEEDED?") end if CALL NC_POINT_VAR(WINDW_STRY_N,VNP) CALL NC_POINT_VAR(WINDW_STRY_P,VPP) WSTRY = FTM%NEXT_WGHT * VNP + FTM%PREV_WGHT * VPP ALLOCATE(UVNP(0:NT)) ALLOCATE(UVPP(0:NT)) ALLOCATE(UVXY(0:NT)) ALLOCATE(WSTRXY(0:NT)) UVNP = UNP*UNP+VNP*VNP UVPP = UPP*UPP+VPP*VPP UVNP = SQRT(UVNP) UVPP = SQRT(UVPP) WSTRXY = FTM%NEXT_WGHT * UVNP + FTM%PREV_WGHT * UVPP UVXY = WSTRX*WSTRX + WSTRY*WSTRY UVXY = SQRT(UVXY) + 1.0e-4_SP WSTRX = WSTRXY*WSTRX/UVXY WSTRY = WSTRXY*WSTRY/UVXY DEALLOCATE(UVNP,UVPP,UVXY,WSTRXY) !=================================================== CASE(WINDS_ARE_PT_SOURCE) !=================================================== FTM => WINDS_FILE%FTIME ! THE X DIRECTION WIND STRESS CALL UPDATE_VAR_BRACKET(WINDS_FILE,WINDW_STRX_P,WINDW_STRX_N,WTIME,STATUS) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPATE WIND X BRACKET: BOUNDS EXCEEDED?") end if CALL NC_POINT_VAR(WINDW_STRX_N,VNP) CALL NC_POINT_VAR(WINDW_STRX_P,VPP) WSTRX(1:NT) = FTM%NEXT_WGHT * VNP(1) + FTM%PREV_WGHT * VPP(1) ! THE Y DIRECTION WIND STRESS CALL UPDATE_VAR_BRACKET(WINDS_FILE,WINDW_STRY_P,WINDW_STRY_N,WTIME,STATUS) IF (STATUS /= 0) THEN CALL FATAL_ERROR("COULD NOT UPATE WIND Y BRACKET: BOUNDS EXCEEDED?") end if CALL NC_POINT_VAR(WINDW_STRY_N,VNP) CALL NC_POINT_VAR(WINDW_STRY_P,VPP) WSTRY(1:NT) = FTM%NEXT_WGHT * VNP(1) + FTM%PREV_WGHT * VPP(1) !=================================================== CASE DEFAULT CALL FATAL_ERROR("UNKNOWN WINDS_FORCING_TYPE IN UPDATE WIND") END SELECT !=================================================== END SUBROUTINE UPDATE_WIND2WAVE # endif !==============================================================================| !======================================================================== SUBROUTINE GDAY2(IDD,IMM,IYY,ICC,KD) ! ! given day,month,year and century(each 2 digits), gday returns ! the day#, kd based on the gregorian calendar. ! the gregorian calendar, currently 'universally' in use was ! initiated in europe in the sixteenth century. note that gday ! is valid only for gregorian calendar dates. ! ! kd=1 corresponds to january 1, 0000 ! ! note that the gregorian reform of the julian calendar ! omitted 10 days in 1582 in order to restore the date ! of the vernal equinox to march 21 (the day after ! oct 4, 1582 became oct 15, 1582), and revised the leap ! year rule so that centurial years not divisible by 400 ! were not leap years. ! ! this routine was written by eugene neufeld, at ios, in june 1990. ! integer idd, imm, iyy, icc, kd integer ndp(13) integer ndm(12) data ndp/0,31,59,90,120,151,181,212,243,273,304,334,365/ data ndm/31,28,31,30,31,30,31,31,30,31,30,31/ ! ! test for invalid input: if(icc.lt.0)then ! write(11,5000)icc call pstop endif if(iyy.lt.0.or.iyy.gt.99)then ! write(11,5010)iyy call pstop endif if(imm.le.0.or.imm.gt.12)then ! write(11,5020)imm call pstop endif if(idd.le.0)then ! write(11,5030)idd call pstop endif if(imm.ne.2.and.idd.gt.ndm(imm))then ! write(11,5030)idd call pstop endif if(imm.eq.2.and.idd.gt.29)then ! write(11,5030)idd call pstop endif 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 ! write(11,5030)idd call pstop endif 5000 format(' input error. icc = ',i7) 5010 format(' input error. iyy = ',i7) 5020 format(' input error. imm = ',i7) 5030 format(' input error. idd = ',i7) ! ! calculate day# of last day of last century: kd = icc*36524 + (icc+3)/4 ! ! calculate day# of last day of last year: kd = kd + iyy*365 + (iyy+3)/4 ! ! adjust for century rule: ! (viz. no leap-years on centurys except when the 2-digit ! century is divisible by 4.) if(iyy.gt.0.and.(icc-(icc/4)*4).ne.0) kd=kd-1 ! kd now truly represents the day# of the last day of last year. ! ! calculate day# of last day of last month: kd = kd + ndp(imm) ! ! adjust for leap years: 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 ! kd now truly represents the day# of the last day of the last ! month. ! ! calculate the current day#: kd = kd + idd RETURN END SUBROUTINE GDAY2 END MODULE MOD_FORCE