!*****************************************************************! !* *! !* 4C (FORESEE) Simulation Model *! !* *! !* *! !* SR photoper *! !* *! !* contains follow global units: *! !* photoper function for calculation of photoperiod *! !* daylength calculation of day length *! !* avg_sun_incl Calculates average sun declination for *! ! the season at the given latitude in degrees *! !* fixclimscen subroutine for calculation of delta T and P *! !* glob_rad Estimation of global radiation from sunshine *! !* frost_index_total subroutine for calculation of frost index *! !* *! !* Copyright (C) 1996-2018 *! !* Potsdam Institute for Climate Impact Reserach (PIK) *! !* Authors and contributors see AUTHOR file *! !* This file is part of 4C and is licensed under BSD-2-Clause *! !* See LICENSE file or under: *! !* http://www.https://opensource.org/licenses/BSD-2-Clause *! !* Contact: *! !* https://gitlab.pik-potsdam.de/foresee/4C *! !* *! !*****************************************************************! REAL FUNCTION PHOTOPER(d,xlatitude) ! by Thomas Kartschall 8.7.92 ! ! PhotoPeriod -Potential daily Sun Shine Period [h] ! d -Ordinal Number of Julian Date [Real!4] ! latitude -Latitude by Radiant [Real!4] ! Northern L>0; Southern L<0 ! ! Polarkreis bei je 66.55� bzw 66�33'36'' N/SL ! USE data_par USE data_simul real d, xlatitude, del, ws, ws2 ! ! Equator from 0,2� respectively 0�12' ! IF (abs(xlatitude).lt.0.0024) then photoper=12.0 return ENDIF ! !pole surrounding ab 89,8� bzw 89�48' ! IF (xlatitude.ge. 1.567305668)xlatitude= 1.567305668 IF (xlatitude.le.-1.567305668) xlatitude=-1.567305668 g=2*pi*(d-1.0)/365.25 del=0.006918-0.399912*cos(g) del=del+0.070257*sin(g)-0.006758*cos(g+g) del=del+0.000907*sin(g+g)-0.002697*cos(g+g+g) del=del+0.00148*sin(g+g+g) ws=sin(xlatitude)*sin(del) ws2=cos(xlatitude)*cos(del) ! !polar night duration per day no longer than 24h ! IF (ws/ws2.ge.1.0) ws=ws2 IF (ws/ws2.le.-1.0) ws=-ws2 ws=acos(ws/ws2) ws=12.*(1.-ws/pi) !day length is dopple the time between HighNoon and SunRise PHOTOPER=2.*(ws) RETURN END FUNCTION photoper !******************************************************************* FUNCTION DAYLENGTH(doy,hlat) USE data_par IMPLICIT NONE REAL :: hlat REAL :: daylength INTEGER :: doy REAL :: decl,arg decl = -23.45*(PI/180)*COS(2.*PI/365.*(doy+10)) ! latitude is converted to rad arg = -TAN(hlat*PI/180.)*TAN(decl); IF( arg < -1. ) THEN daylength = 24. ELSE IF ( arg > 1. ) THEN daylength = 0. ELSE daylength = (24./PI)*ACOS(arg) ENDIF END FUNCTION DAYLENGTH !******************************************************************* FUNCTION AVG_SUN_INCL(hlat) !Calculates average sun declination for the season ! at the given latitude in degrees use data_par implicit none REAL :: avg_sun_incl REAL :: hlat, h1, h2, h3 REAL :: decl, sumbeta, dl, sumdl INTEGER :: i, j REAL, EXTERNAL :: daylength sumdl = 0 sumbeta = 0 h1 = sin(PI*hlat/180) h2 = cos(PI*hlat/180) DO i=120,280,+1 decl = -23.45*(PI/180)*COS(2.*PI/365.*(i+10)) dl = DAYLENGTH(i,hlat) ! sun declination at noon h3 = h1*sin(decl)+h2*cos(decl) if(h3.gt.1.) h3 = 1 avg_sun_incl = 180/PI*asin(h3); sumbeta = sumbeta + avg_sun_incl*dl; sumdl = sumdl + dl; END DO avg_sun_incl = sumbeta/sumdl END FUNCTION AVG_SUN_INCL !******************************************************************* SUBROUTINE fixclimscen ! fixclimscen calculates deltaT and deltaPrec for climate change scenarios with ! fixed offsets in temperature and precipitation USE data_simul IMPLICIT NONE INTEGER :: dimTsteps, dimPsteps ! calculations dimTsteps = 1 + n_T_downsteps + n_T_upsteps dimPsteps = 1 + n_P_downsteps + n_P_upsteps deltaT = ((ip-1)/dimPsteps-n_T_downsteps)*step_sum_T deltaPrec = 1.+((ip-1)-((ip-1)/dimPsteps)*dimPsteps-n_P_downsteps)*step_fac_P CALL out_scen END SUBROUTINE fixclimscen !**************************************************************************** SUBROUTINE glob_rad(sd, iday, xlat, rad) ! Estimation of global radiation from sunshine duration ! (calculation after Angstrom) implicit none ! input: integer :: iday ! actual day real :: sd ! sunshine duration (h) real :: xlat ! latitude ! output: real :: rad ! global radiation (J/cm2) ! internal variables real :: rad_ex , & ! extraterrestrical radiation (J/cm2) dayl , & ! daylength dec , & ! declination of sun angle sinld, cosld, tanld, dsinb, dsinbe, & sc, radi, seas real :: pi = 3.141592654 real :: solc = 1367. ! solar constant (J/(m2*s) ! after P. Hupfer: "Klimasystem der Erde", 1991 ! change of units from degree to radians pi = 3.141592654 radi = pi/180. ! term of seasonality (10 days in front of calendar) seas = (iday+10.)/365. ! declination of sun angle ! (Spitters et al. 1986, equations transformed for use or radians) dec = -asin(sin(23.45*radi)*cos(2.*pi*seas)) ! some intermediate values sinld = sin(xlat*radi)*sin(dec) cosld = cos(xlat*radi)*cos(dec) tanld = amax1(-1., amin1(1., sinld/cosld)) ! daylength dayl = 12.*(1.+2.*asin(tanld)/pi) ! integral of sun elevation dsinb = 3600.*(dayl*sinld+24.*cosld*sqrt(1.-tanld*tanld)/pi) ! corrected integral of sun elevation dsinbe = 3600.*(dayl*(sinld+0.4*(sinld*sinld+cosld*cosld*0.5)) & +12.*cosld*(2.+3.*0.4*sinld)*sqrt(1.-tanld*tanld)/pi) ! intensity of radiation outside the atmosphere sc = solc/(1.-0.016729*cos((360./365.)*(iday-4.)*radi))**2. rad_ex = sc*(1.+0.033*cos(2.*pi*iday/365.))*dsinbe ! unit conversion in MJ/m2: rad_ex = rad_ex/1000000. ! unit conversion in J/cm2 rad_ex = rad_ex * 0.0001 if (sd.ge.0.) then rad = (0.231+0.539*sd/dayl)*rad_ex else write (*, '(A, I3, A)') ' RAD is out of range at day ', iday , & ' , RAD will be = 1000 J/cm2!' end if END SUBROUTINE glob_rad !**************************************************************************** subroutine frost_index_total use data_frost use data_simul use data_stand implicit none integer :: zaehl=0 integer :: i integer :: zaehl1 =0 integer :: t,m,j real :: mean_dnlf real :: mean_tminmay integer :: mean_date_lf integer :: mean_date_lftot real :: mean_dnlf_sp real :: mean_tminmay_sp integer :: mean_date_lf_sp real :: mean_anzdlf real :: mean_sumtlf integer :: ind1, ind2, ind3, ind4, ind5 integer :: ind1_sp zaehl=0 mean_tminmay = 0. mean_date_lf = 0 mean_date_lftot = 0 mean_dnlf = 0 mean_dnlf_sp = 0 mean_anzdlf = 0 mean_sumtlf = 0 do i =1,year if(tminmay_ann(i).ne.0) then zaehl = zaehl +1 mean_tminmay= mean_tminmay+tminmay_ann(i) end if end do if(zaehl.ne.0) then mean_tminmay = mean_tminmay/zaehl else mean_tminmay = 0. end if do i=1,year mean_anzdlf = mean_anzdlf + anzdlf(i) mean_sumtlf = mean_sumtlf + sumtlf(i) end do mean_anzdlf = mean_anzdlf/year mean_sumtlf = mean_sumtlf/year zaehl=0 do i =1,year if(date_lftot(i).ne.0) then zaehl = zaehl +1 mean_date_lftot = mean_date_lftot + date_lftot(i) end if end do if(zaehl.ne.0) then mean_date_lftot = mean_date_lftot/zaehl else mean_date_lftot = 0. end if mean_dnlf = 0. zaehl=0 do i =1,year if(dnlf(i).ne.0) then mean_dnlf = mean_dnlf + dnlf(i) zaehl = zaehl +1 end if end do if(zaehl.ne.0) then mean_dnlf = mean_dnlf/zaehl else mean_dnlf = 0 endif zaehl=0 do i =1,year if(date_lf(i).ne.0) then mean_date_lf = mean_date_lf + date_lf(i) zaehl = zaehl +1 end if enddo if(zaehl.ne.0) then mean_date_lf = mean_date_lf/zaehl else mean_date_lf = 0 end if zaehl1=0 do i =1,year if(dnlf_sp(i).ne.0) then zaehl1 = zaehl1 +1 mean_dnlf_sp = mean_dnlf_sp + dnlf_sp(i) end if enddo if (zaehl1.ne.0) then mean_dnlf_sp = mean_dnlf_sp/zaehl1 else mean_dnlf_sp = 0 endif if (mean_dnlf.le.2.5 .and. mean_tminmay.ge. -1.5 .and.tminmay.ge.-5.0 .and. mean_date_lf.lt.130 .and. dlfabs .lt. 156) lfind=1 if (mean_dnlf.ge.2.6 .and. mean_dnlf .le.3.5 .and. mean_tminmay.ge. -2.0 .and. mean_tminmay.lt.-1.5 .and. tminmay .ge.-6. .and. mean_date_lf .lt.135 .and. dlfabs .lt.161) lfind=2 if (mean_dnlf.gt.3.5 .and. mean_dnlf .le.4.5 .and. mean_tminmay.ge. -2.5 .and. mean_tminmay.lt.-2.0 .and. tminmay .ge.-6. .and. mean_date_lf .ge.135 .and. mean_date_lf .le. 140 .and. dlfabs .ge.162 .and. dlfabs.le.166) lfind=3 if (mean_dnlf.gt.4.5 .and. mean_dnlf .le.5.0 .and. mean_tminmay.ge. -3.0 .and. mean_tminmay.lt.-2.5 .and. tminmay .ge.-7. .and. mean_date_lf .ge.141 .and. mean_date_lf .le. 145 .and. dlfabs .ge.167 .and. dlfabs.le.171) lfind=4 if (mean_dnlf.gt.5.10 .and. mean_dnlf .le.5.5 .and. mean_tminmay.ge. -3.5 .and. mean_tminmay.lt.-3.0 .and. tminmay .ge.-8. .and. mean_date_lf .ge.141 .and. mean_date_lf .le. 145 .and. dlfabs .ge.172 .and. dlfabs.le.176) lfind=5 if (mean_dnlf.gt.5.5 .and. mean_tminmay.lt.-3.5 .and. tminmay .le.-8. .and. mean_date_lf .gt.145 .and. dlfabs .gt.176) lfind=6 ! index of number of late frost days since beginning of vegetation period if (mean_dnlf.le.2.5) then ind1 = 1 else if(mean_dnlf.le.3.5) then ind1 = 2 else if (mean_dnlf.le.4.5) then ind1 = 3 else if (mean_dnlf.le.5.0) then ind1 = 4 else if (mean_dnlf.le.5.5) then ind1 = 5 else ind1 = 6 endif ! index of number of late frost days since beginning of bud burst if (mean_dnlf_sp .le. 2.5) then ind1_sp= 1 else if(mean_dnlf_sp.le.3.5) then ind1_sp = 2 else if (mean_dnlf_sp.le.4.5) then ind1_sp = 3 else if (mean_dnlf.le.5.0) then ind1_sp = 4 else if (mean_dnlf_sp.le.5.5) then ind1_sp = 5 else ind1_sp = 6 endif ! index of mean minimum may temperature if(mean_tminmay.ge. -1.5) then ind2 = 1 else if (mean_tminmay.ge. -2.0) then ind2 = 2 else if (mean_tminmay.ge. -2.5) then ind2 = 3 else if (mean_tminmay.ge. -3.0) then ind2 = 4 else if (mean_tminmay.ge. -3.5) then ind2 = 5 else ind2 =6 endif ! index of absolute minimum may temperature if(tminmay.ge.-5.0) then ind3 = 1 else if(tminmay.ge.-6.0 .and. ind2 .le.2) then ind3 = 2 else if (tminmay.ge.-6.0 .and. ind2 .le.3) then ind3 =3 else if (tminmay.ge.-7.0) then ind3 = 4 else if (tminmay.ge.-8.0) then ind3 = 5 else ind3 = 6 end if ! index of mean date(number of the year) of late frost if (mean_date_lf.lt.130) then ind4 = 1 else if (mean_date_lf.lt.135) then ind4 = 2 else if (mean_date_lf.le.140 ) then ind4 = 3 else if (mean_date_lf.le.145 .and. ind2.le.4) then ind4 = 4 else if(mean_date_lf.le.145 .and. ind2.le.5) then ind4 = 5 else ind4 = 6 endif ! absolute last late frost (numbedr of the year) if (dlfabs .lt. 156) then ind5 = 1 else if (dlfabs .lt. 161) then ind5 = 2 else if (dlfabs .le. 162) then ind5 =3 else if (dlfabs .le. 171) then ind5 = 4 else if (dlfabs .le. 176) then ind5 = 5 else ind5 =6 endif mlfind = real((ind1 + ind2 + ind3 + ind4 + ind5)/5) mlfind_sp = (ind1_sp + ind2 + ind3 + ind4 + ind5)/5 if(waldtyp.eq. 10 .or. waldtyp .eq. 40 .or. waldtyp .eq.90) mlfind_sp = 0 end subroutine frost_index_total