Skip to content
Snippets Groups Projects
daily.f 23.8 KiB
Newer Older
Petra Lasch-Born's avatar
Petra Lasch-Born committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743
!*****************************************************************!
!*                                                               *!
!*                    4C  Simulation Model                       *!
!*                                                               *!
!*                                                               *!
!*                    Subroutines for:                           *!
!*       Simulation of processes at subannual resolution         *!
!*                                                               *!
!*                                                               *!
!* Contains subroutines:                                         *!
!*                                                               *!
!* STAND_DAILY                                                   *!
!* SET_PS                                                        *!
!* DROUGHT     : Calculation of drought stress indices           *!
!* FIRE_RISK                                                     *!
!* calc_frost_index  : calculation of indices for frost damage   *!
!* calc_endbb   : calculation of end of the vegetation period    *!
!*                                                               *!
!*                  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                *!
!*                                                               *!
!*****************************************************************!

SUBROUTINE stand_daily

  !*** Declaration part ***!

  USE data_stand
  USE data_simul
  USE data_species
  USE data_climate
  USE data_site
  USE data_soil_cn
  USE data_out
  USE data_par
  USE data_evapo
  USE data_soil
  use data_manag

  IMPLICIT NONE

  REAL    :: aveT,   &  ! average of temperature for PS/NPP models
             avDL,   &  ! average of daylength for PS/NPP model
             avRD,   &  ! average of radiation
             avPR,   &  ! average of pressure (hPa)
             PAR        ! average of PAR for PS/NPP model [mol quanta d-1]
  
  REAL    :: hdfr, hdt, hprs
  INTEGER :: i, jd, k, d, week, monthday, ns_pro_help
  

  real                  :: p_help, t_help

  REAL     :: photoper

  p_help=0.
  t_help=0.

  irelpool_ll=0.
  bgpool_ll=0.

  !*** Calculation part ***!

  week     = 0
  monthday = 0 
  monat    = 1
  woche    = 1

  ! daily loop
  DO jd = 1, recs(time)

    iday = jd
    monthday=monthday+1
   
    ! input of daily climate data
    CALL day_ini
    
    if(anz_coh .gt. 0) then     ! if no cohort, then no phaenology necessary
        IF(all_leaves_on==0) CALL pheno_begin
        CALL pheno_count
        IF(leaves_on) CALL pheno_shed
    endif
    IF(phen_flag==1 .OR. (.not.flag_tree .and. leaves_on)) THEN

       ! Calculate this year's crown geometry for each cohort, followed by
       ! leaf area and light profiles across the canopy
       CALL CANOPY
       if (anz_coh.eq.0) then
           irelpool_ll = 1.
       end if
       if(all_leaves_on.eq.1) then
           irelpool_ll = irelpool(0)
           bgpool_ll = bgpool(2)
       end if
       IF(flag_end.EQ.3) RETURN

       ! update of stand variables (LAI, cover)
       CALL standup
       phen_flag=0;
    END IF

   !call distubance after start day
    select case(flag_dis)
     case(1,2)
      if (dis_control(1,1) .eq. 1) then
        if(all_leaves_on .eq. 1 .and. dis_start(dis_control(1,2)) .eq. iday) then
         CALL disturbance_defoliator
         CALL CANOPY
         CALL stand_balance
         CALL standup
        endif
      endif
      if (dis_control(2,1) .eq. 1) then
        if(all_leaves_on .eq. 1 .and. dis_start(dis_control(2,2)) .eq. iday) CALL disturbance_xylem
      endif
      if (dis_control(3,1) .eq. 1) then
        if(dis_start(dis_control(3,2)) .eq. iday) CALL disturbance_phloem
      endif
      if (dis_control(4,1) .eq. 1) then
        if(dis_start(dis_control(4,2)) .eq. iday) then
         CALL disturbance_root
         CALL stand_balance
         CALL standup
        endif
      endif
      if (dis_control(5,1) .eq. 1) then
        if(dis_start(dis_control(5,2)) .eq. iday) CALL disturbance_stem
      endif
    end select
    ns_pro_help = ns_pro
    ! set ns_pro_help to length of last photosynthesis period at end of year
    IF(iday >int(recs(time)/ns_pro)*ns_pro .and. (MOD( iday, ns_pro )==1)) THEN
       ns_pro_help = recs(time) - int(recs(time)/ns_pro)*ns_pro
    END IF
    
    ! optimum photosynthesis submodel
    IF (ns_pro==1.OR.(MOD( iday, ns_pro )==1) .or. iday.eq.1) THEN
      ! assign averaged input variables for PS model
      aveT = 0.
      avDL = 0.
      avRD = 0.
      avPR = 0.
      hdfr = 0.
      ns_day = 1
      DO k = 1, ns_pro_help     ! this calculates 365 or 366, but is not included as a wwek value
                                ! ==> last week of the year is recieving this amount
        d = iday-1+k
        hdt  = Q10_T**((tp(d,time) - 15.) / 10.)
        hdfr = hdfr + hdt
        dayfract(k) = hdt
        aveT = aveT + tp(d,time) + deltaT
        avRD = avRD + rd(d,time)
            hprs = prs(d,time)
            if (hprs .lt. 800.) then
                  hprs = 1013
            endif
        avPR = avPR + hprs
        avDL = avDL + photoper( FLOAT(d), xLat )
      END DO
      aveT = aveT / ns_pro_help
      avDL = avDL / ns_pro_help
      avRD = avRD / ns_pro_help
      avPR = avPR / ns_pro_help
      ! PAR that is coming in stand reflection is substracted
      PAR    = (1.-pfref)* GR_in_PAR * avRD
      if (iday .gt. 364) then
        dayfract = 1.   ! at the last days of the year no temperature depending daily fraction of flux
      else
        dayfract = ns_pro * dayfract / hdfr   ! temperature depending daily fraction of flux, calc. from sum of ns_pro days
      endif
      CALL OPT_PS( aveT, avDL, PAR, avPR )
    ENDIF

    ! aggregation of stomatal conductance of the canopy
    gp_can_mean = gp_can_mean + gp_can
    gp_can_min  = min(gp_can_min, gp_can)
    gp_can_max  = max(gp_can_max, gp_can)

    ! soil submodel
    CALL SOIL
    CALL  drought

    ! NPP submodel
    IF (ns_pro==1.OR.(MOD( (iday-1), ns_pro )==0) .or. iday .eq. recs(time) .or. iday.eq.1) THEN
       CALL NPP( aveT, avDL, PAR, ns_pro_help )
       IF(.not.flag_tree .and. leaves_on.and.flag_sprout.eq.1)  CALL growth_seed_week (ns_pro_help)
       ! daily output every ns_pro days of dips- and gsdps-files
       IF (flag_dayout .ge. 1) CALL coh_out_d(2)
    ENDIF
    
    CALL calc_fire_risk
! calculation of the start of vegetation period 
    if(flag_vegper.eq.0) then
      if(airtemp.le.5. .and. flag_tveg .ne.0)  then
        flag_tveg=0
      else if(airtemp.gt.5. .and. flag_tveg.eq.0) then
        flag_tveg =1
      else if(airtemp.gt.5. .and. flag_tveg.eq.1) then
        flag_tveg =2
      else if(airtemp.gt.5. .and. flag_tveg.eq.2) then
        flag_tveg =3
      else  if(airtemp.gt.5. .and. flag_tveg.eq.3)then
         flag_tveg =4
      else if(airtemp.gt.5. .and. flag_tveg.eq.4) then
         flag_tveg =5
     end if

     if(flag_tveg .eq.5) then
       flag_vegper=1
       iday_vegper = iday
     end if
   endif
    
 ! call of SR for calculation of various indices for the frost index
   if(airtemp_min .gt. -90.) call calc_frost_index
 ! Calculation of maximal radiation (for information only)
    call glob_rad(dlength, iday, lat, rad_max)
    Cout%NEE(iday)      = respsoil - dailyNPP_C    ! g C/m²
    Cout%Resp_aut(iday) = dailyautresp_C * dayfract(ns_day)
    NPP_day          = dailyNPP_C * dayfract(ns_day)
    GPP_day          = (dailyNPP_C + dailyautresp_C) * dayfract(ns_day)
    TER_day          = dailyautresp_C * dayfract(ns_day) + respsoil
    
    IF (flag_dayout .ge. 1) CALL outday(1)
    IF (ns_pro==1.OR.(MOD( iday, ns_pro )==0) .or. iday .eq. recs(time) )  CALL SET_PS
  ! Wochen- und Monatswerte berechnen
    aet_mon(monat)  = aet_mon(monat) + aet
    aet_week(woche) = aet_week(woche) + aet
    pet_mon(monat)  = pet_mon(monat) + pet
    pet_week(woche) = pet_week(woche) + pet
    temp_mon(monat)  = temp_mon(monat) + airtemp
    temp_week(woche) = temp_week(woche) + airtemp
    prec_mon(monat)  = prec_mon(monat) + prec
    prec_week(woche) = prec_week(woche) + prec
    rad_mon(monat)   = rad_mon(monat) + rad
    hum_mon(monat)   = hum_mon(monat) + hum
    perc_mon(monat)  = perc_mon(monat) + perc(nlay)
    perc_week(woche) = perc_week(woche) + perc(nlay)
    resps_mon(monat) = resps_mon(monat) + respsoil
    resps_week(woche)= resps_week(woche) + respsoil
    GPP_mon(monat)   = GPP_mon(monat) + dailyNPP_C + dailyautresp_C
    GPP_week(woche)  = GPP_week(woche) + dailyNPP_C + dailyautresp_C
    NEE_mon(monat)   = NEE_mon(monat) + Cout%NEE(iday)                      ! g C/m²
    NPP_mon(monat)   = NPP_mon(monat) + dailyNPP_C
    NPP_week(woche)  = NPP_week(woche) + dailyNPP_C
    TER_mon(monat)   = TER_mon(monat) + dailyautresp_C + respsoil
    TER_week(woche)  = TER_week(woche) + dailyautresp_C + respsoil
    tempmean_mo(monat)   = tempmean_mo(monat) + airtemp   ! long-term monthly means
    
   ! summation output with variabel time steps
    photsum   = photsum + phot_C
    npppotsum = npppotsum + dailypotNPP_C
    nppsum    = nppsum + dailyNPP_C
    resosum   = resosum + respsoil
    nee       = nee + respsoil - dailyNPP_C
	gppsum    = gppsum + GPP_day
	sumGPP    = sumGPP + dailyNPP_C + dailyautresp_C
	sumTER    = sumTER + dailyautresp_C + respsoil 
	resautsum = resautsum + dailyautresp_C
    precsum   = precsum + prec
    tempmean  = tempmean + airtemp
	tempmeanh = tempmeanh +airtemp
	aet_sum   = aet_sum + aet
	pet_sum   = pet_sum + pet
    perc_sum  = perc_sum + perc(nlay)

    if(monthday==monrec(monat)) then
       tempmeanh = tempmeanh/monrec(monat)
	   if(monat.eq.1) med_air_cm = tempmeanh
	   if(tempmeanh.lt.med_air_cm) med_air_cm = tempmeanh
	   if(tempmeanh.gt.med_air_wm) med_air_wm = tempmeanh
	   tempmeanh = 0.

	   temp_mon(monat) = temp_mon(monat) / monrec(monat)
	   rad_mon(monat)  = rad_mon(monat) / monrec(monat)
	   hum_mon(monat)  = hum_mon(monat) / monrec(monat)
	   if(temp_mon(monat).lt.med_air_cm) med_air_cm = temp_mon(monat)
	   if(temp_mon(monat).gt.med_air_wm) med_air_wm = temp_mon(monat)       
	end if

	   if(airtemp.ge.10.) then
	       t_help= t_help + airtemp
	       p_help= p_help + prec
	   end if

    ns_day = ns_day + 1
 
  ! daily output
    IF(flag_sum .eq. 1) THEN
        write(unit_sum,'(2I5,13F10.3)') iday,time_cur,photsum,npppotsum,nppsum,resosum,     &
                                        lightsum,nee,abslightsum,precsum,tp(iday,time),     &
                                        exp(0.069*(tp(iday,time)-15.)), sumGPP, sumTER, resautsum
        photsum=0.;npppotsum=0.;nppsum=0.;resosum=0.;lightsum=0.;nee=0.;abslightsum=0.; precsum=0.
		sumGPP = 0.
		sumTER = 0.
        resautsum = 0.
    ENDIF
   ! output with time step of photosynthesis
    IF(flag_sum .eq. 2 .and. mod(iday,ns_pro)==0) THEN
        week = week + 1
        write(unit_sum,'(2I6,17F10.3)') week,time_cur,time_cur+(week-0.5)/52.,photsum,npppotsum,nppsum,resosum,    &
                                        lightsum,nee,abslightsum,precsum,aveT,exp(0.069*(aveT-15.)), &
                                        aet_sum, pet_sum, perc_sum, sumGPP, sumTER, resautsum
        photsum=0.;npppotsum=0.;nppsum=0.;resosum=0.;lightsum=0.;nee=0.;abslightsum=0.; precsum=0.
		aet_sum  = 0.; pet_sum = 0.
        perc_sum = 0.
		sumGPP = 0.
		sumTER = 0.
        resautsum = 0.
    ENDIF

    if(mod(iday,7) .eq. 0) then
        woche = woche + 1
    endif
     
    if(monthday .eq. monrec(monat)) then 
        IF(flag_sum .eq. 3 ) THEN
            tempmean = tempmean/monrec(monat)
	        if( temp_mon(monat) .le. 0.) then
		         ind_cout_mo = 12.* prec_mon(monat)
		         ind_cout_mo = 12*precsum
		    else
			     ind_cout_mo = 12.* prec_mon(monat) /(temp_mon(monat) + 10.)
			     ind_cout_mo = 12*precsum/(tempmean+10)
		    end if
		    if(temp_mon(monat) .le. 0.) then
		          ind_wiss_mo = 12.* prec_mon(monat)
		          ind_wiss_mo = 12*precsum
		    else
	             ind_wiss_mo = 12.* prec_mon(monat) /(temp_mon(monat) + 7.)
	             ind_wiss_mo = 12*precsum/(tempmean+7)
	        end if
		    if(ind_arid_mo.ne.0.) then
		       
		        ind_arid_mo = prec_mon(monat)/pet_sum
		    else
		        ind_arid_mo=0.
		    end if
    	    cwb_mo = prec_mon(monat) - pet_sum
     	    ind_cout_an = ind_cout_an + ind_cout_mo
    	    ind_wiss_an = ind_wiss_an + ind_wiss_mo
            write(unit_sum,'(I7,I5,20F10.3)') monat,time_cur,time_cur+(monat-0.5)/12.,photsum,npppotsum,nppsum,resosum,   &
                                            lightsum,nee,abslightsum, precsum, tempmean, aet_sum, pet_sum, ind_cout_mo, ind_wiss_mo, &
										    ind_arid_mo, cwb_mo, perc_sum, sumGPP, sumTER, resautsum
            photsum=0.;npppotsum=0.;nppsum=0.;resosum=0.;lightsum=0.;nee=0.;abslightsum=0.; precsum=0.; tempmean = 0.
		    aet_sum  = 0.; pet_sum = 0.; ind_cout_mo = 0.; ind_wiss_mo=0.; ind_arid_mo=0.; cwb_mo = 0.
            perc_sum = 0.
		    sumGPP = 0.
		    sumTER = 0.
            resautsum = 0.
        ENDIF   ! flag_sum

        monat    = monat+1
        monthday = 0
 
    endif  ! monthday
  END DO ! iday daily loop

!calculate the mean stress factor for root growth
if (flag_wurz .eq. 4 .or. flag_wurz .eq. 6) then
    do i=1,nlay
         do k=1,nspecies
	        svar(k)%Smean(i)=svar(k)%Smean(i)/recs(time)
         enddo
    enddo
endif
ind_shc = p_help/(t_help/10)

END SUBROUTINE stand_daily

!***************************************************************

SUBROUTINE SET_PS

  USE data_stand
  TYPE(coh_obj), POINTER :: p
  p => pt%first
  DO WHILE (ASSOCIATED(p))
! reset drought index & day counter to zero for next time step
    p%coh%drIndPS = 0.
    p%coh%nDaysPS = 0.
    p => p%next
  END DO

END SUBROUTINE SET_PS

!**************************************************************

 SUBROUTINE drought

! Calculation of drought stress indices
! Sum up of RedN
USE data_simul
USE data_stand
USE data_par
USE data_species

implicit none
integer i, ii
real, dimension(1:nspecies):: rhelp

rhelp = 0.
! drought index of trees
zeig => pt%first
do while (associated(zeig))
   ns = zeig%coh%species
  ! calculation of daily drought index
  if (zeig%coh%demand .gt. 10E-6) then
      if (ns.eq.nspec_tree+2) then                ! set drought index to 1 for mistletoe (no drought)
      zeig%coh%drIndD = 1
    else
      zeig%coh%drIndD = zeig%coh%supply / zeig%coh%demand
    endif
  else
    zeig%coh%drIndD = 1.
  endif

  select case (flag_limi)
  case (4, 5, 6, 7, 8, 9)
    rhelp(ns) = rhelp(ns) + zeig%coh%ntreeA * zeig%coh%RedNc  ! mean annual RedN 
  end select
   
  IF ((iday .ge. zeig%coh%day_bb) .AND. (iday .le. spar(zeig%coh%species)%end_bb)) THEN
     zeig%coh%drIndPS = zeig%coh%drIndPS + zeig%coh%drIndD
     zeig%coh%drIndAl = zeig%coh%drIndAl + zeig%coh%drIndD

    drIndD = drIndD + zeig%coh%ntreeA * zeig%coh%drIndD
  ENDIF

  zeig => zeig%next
enddo  ! zeig (cohorts)
if (flag_limi .ge. 4 .and. flag_limi .le. 9) then
    do i=1,anrspec 
        ii = nrspec(i)
        svar(ii)%RedN = rhelp(ii) * 10000. / (svar(ii)%sum_nTreeA * kpatchsize)    ! durch Anz. Tree pro patchsize teilen
    enddo
endif
do i=1,anrspec 
    ii = nrspec(i)
    svar(ii)%RedNm = svar(ii)%RedNm + svar(ii)%RedN
enddo
if(anz_tree.ne.0) then
    drIndD = drIndD / anz_tree
endif
END   subroutine drought

!***************************************************************

SUBROUTINE calc_fire_risk

!calculation of fire risk index
  USE data_biodiv
  USE data_climate
  USE data_simul
  USE data_soil
  USE data_species
  USE data_stand

implicit none
integer i, ii, nshelp
real hsum, hday, Tcrit_bi, cdays
real svp_13, vp_13, vpd_13, relhum_13
real k_prec      ! constant depending on precipitation
real k_phen
real  hh

if (iday.eq.1) then
    prec_flag1 = 0
    prec_flag2 = 0
    tsumrob    = 0.
    day_bb_rob = 0
    tsumbi     = 0.
    day_bb_bi  = -999.
    cdays      = 0.
    Tcrit_bi   = 0.
end if

!  calculation of day_bb for 'Robinie'
if(day_bb_rob.lt.1) then
    if(airtemp.gt.9.3) tsumrob = tsumrob + airtemp
    if(tsumrob.gt.537.) then
         day_bb_rob = iday
    end if
end if

!  calculation of day_bb for birch
nshelp = 5
! Temperature sum model Schaber 2002
if(day_bb_bi.lt.-99) then
   if(airtemp > spar(nshelp)%LTbT.and. iday.gt.47) then     
      tsumbi = tsumbi + airtemp - spar(nshelp)%LTbT
   end if
    if(tsumbi > spar(nshelp)%LTcrit) then
      day_bb_bi = iday
   end if
end if
! if birch is simulated
zeig=>pt%first
DO

   IF (.not.ASSOCIATED(zeig)) exit
      if(zeig%coh%species.eq.5) day_bb_bi  = zeig%coh%day_bb
       zeig=>zeig%next
END DO

!  fire index west
if (iday .ge. 60 .and. iday .lt. 270) then
   hday = iday/30.
   ii   = int(hday) - 1  ! month index
   hsum = SUM(clim_waterb)
   i = 1
   do i=1,4
      if (hsum .gt. risk_class(i,ii)) then
         fire_indw  = i
         fire(1)%index = i
         exit
      endif
      fire_indw  = 5
      fire(1)%index = 5
   enddo
    fd_fire_indw(fire_indw)=fd_fire_indw(fire_indw)+1
   fire(1)%frequ(fire(1)%index) = fire(1)%frequ(fire(1)%index) + 1
else
   fire(1)%index = 0
endif

if(airtemp_max .gt. -90.) then
    !  fire index east
    if (iday .ge. 46 .and. iday .lt. 275) then
       svp_13    = 6.1078 * exp(17.62 * airtemp_max / (243.12+airtemp_max)) ! saturated vapour pressure at 13.00
    ! estimation actual vapour pressure derived from mean air humidity 
       vp_13  = svp_13*hum/100
       vpd_13    = svp_13 - vp_13      ! vapour pressure deficit at 13.00 
       relhum_13 = 100. * vp_13 / svp_13

       if ((prec .ge. 1.0 .and. prec .lt. 5.0) .or. (snow_day .eq. 1)) then
          k_prec = 0.5
       else if ((prec .ge. 5.0 .and. prec .lt. 10.0) .or. (snow_day .eq. 2)) then
          k_prec = 0.25
       else if ((prec .ge. 10.0) .or. (snow_day .gt. 2)) then
          k_prec = 0.0
       else
          k_prec = 1.0
       endif

        if (iday .lt. day_bb_bi .or. day_bb_bi.eq.-999) then
          k_phen = 3.
        else if (prec.lt. 5 .and. iday .le. 227 .and. day_bb_rob.ne.0 .and. prec_flag1.eq.0) then
          k_phen = 2.
        else if (prec.ge. 5 .and. day_bb_rob.ne.0 .and. iday .gt. day_bb_rob .and. iday .lt. 227 .or. (prec_flag1.eq.1.and.iday.le.227)) then
          k_phen = 1.
          prec_flag1 = 1
       else if( day_bb_rob.eq.0) then
          k_phen = 2
       else if (iday.ge. 227.and. prec.ge. 5) then
          k_phen = 0.5
          prec_flag2 = 1
        else if(prec_flag2 .eq.1 .or. iday .gt. 243) then
          k_phen = 0.5
       else
          k_phen = 1.  ! no modification of forest fire index
       endif

      hh = (airtemp_max + 10)*vpd_13 
      fire_indi = k_prec * fire_indi + k_phen*(airtemp_max + 10)*vpd_13      
       if (fire_indi .gt. 4000) fire_indi_day = fire_indi_day + 1
       fire_indi_max = max(fire_indi, fire_indi_max)

       ! fire hazard level east
       if (fire_indi .le. 500.) then
          fire(2)%index = 1      ! no alarm level
       else if (fire_indi .le. 2000.) then
          fire(2)%index = 2      ! alarm level 1
       else if (fire_indi .le. 4000.) then
          fire(2)%index = 3      ! alarm level 2
       else if (fire_indi .le. 7000.) then
          fire(2)%index = 4      ! alarm level 3
       else
          fire(2)%index = 5      ! alarm level 4
       endif
       fire(2)%frequ(fire(2)%index) = fire(2)%frequ(fire(2)%index) + 1
    else
       fire_indi = 0.
       fire(2)%index = 0
    endif

    ! fire index Bruschek
    if (iday > 90 .AND. iday < 275) then
       if(airtemp_max .ge. 25.) Ndayshot = Ndayshot + 1  
       Psum_FP = Psum_FP + prec
    endif

    ! fire index Nesterov
    ! only calulated for vegetation and snow free period
    if (iday .ge. 60 .and. iday .lt. 275 .and. snow .lt. 0.01 .and. airtemp_max .gt. 0.) then
        if (prec .lt. 3.) then
            day_nest = day_nest + 1
            p_nest = p_nest + (airtemp_max -  dptemp) * airtemp_max 
        else
            day_nest = 0
            p_nest = 0.
        endif
       if (p_nest .le. 300.) then
          fire(3)%index = 1      ! minimal
       else if (p_nest .le. 1000.) then
          fire(3)%index = 2      ! moderate
       else if (p_nest .le. 4000.) then
          fire(3)%index = 3      ! high
       else 
          fire(3)%index = 4      ! extreme
       endif
       fire(3)%frequ(fire(3)%index) = fire(3)%frequ(fire(3)%index) + 1
    else
       p_nest = 0.
       fire(3)%index = 0
    endif
else
    fire(2)%index = -99.0
    fire(3)%index = -99.0
endif ! airtemp_max          

END   subroutine calc_fire_risk

!*******************************************************************************

subroutine calc_frost_index

USE data_frost
USE data_climate
USE data_simul
USE data_stand

implicit none
integer     :: day_bb, j, t, m, ii

!  absolute and annual last frost day during spring/ summer
if(airtemp_min .lt. temp_frost .and. iday .lt. 200 ) then
    if(iday.gt.dlfabs ) dlfabs = iday 
    if(iday.gt.date_lftot(time)) date_lftot(time)=iday
end if    

! annual number of frost days after start of the vegetation period and  annual last frost day
if(flag_vegper.eq.1. .and. iday.lt.200) then
    if(airtemp_min .lt. temp_frost) then
        dnlf(time) = dnlf(time) +1
! calculation  of last frost day after beginning of vegetation period due to 5°C threshold for the case of needle trees
       if( waldtyp.eq.10 .or. waldtyp.eq.40.or.waldtyp.eq.90 .and. iday.gt. date_lf(time)) date_lf(time)= iday
    end if
 end if
! calculation of the number of the actual month
  j= time_cur
  ii = iday
  call tzinda(t,m,j,ii)
  iday = ii
 
 if(m.eq.4 .or. m.eq.5 .or. m.eq.6) then
    if(airtemp_min .lt.0) then
        anzdlf(time)=anzdlf(time)+1
        sumtlf(time) = sumtlf(time) + airtemp_min
    end if
 endif
 ! annual minimum temperature may for year time
 if(airtemp_min.lt.tminmay_ann(time).and. m.eq.5) tminmay_ann(time) = airtemp_min
 ! absolute minimum temperature May

 if( airtemp_min .lt. tminmay .and. m.eq.5) tminmay = airtemp_min
 ! assuming mono species stand !!!
 zeig=>pt%first
DO
   IF (.not.ASSOCIATED(zeig)) exit
      taxnum= zeig%coh%species
      day_bb  = zeig%coh%day_bb
      exit
      zeig=>zeig%next
END DO

! caculation not for conifer stands (pine, spruce, douglas fir)
if(waldtyp .ne. 10 .and. waldtyp .ne. 40 .and. waldtyp .ne.90)then
   if(all_leaves_on.eq.1) then  
     if (iday.ge.day_bb .and. iday.lt.200) then
! calculation of number of frost day during vegetation period (bud burst) for year time
       if(airtemp_min .lt. temp_frost ) then
         dnlf_sp(time) = dnlf_sp(time) +1
   ! calculagtion of last frost day after beginning of vegetation period by bud burst
        if(iday .gt. date_lf(time)) date_lf(time)= iday

       end if
    end if
  end if   ! all_leaves_on
end if  ! waldtyp
  
END subroutine calc_frost_index

!*******************************************************************************

Subroutine calc_endbb

use data_climate
use data_stand
use data_species
use data_simul

implicit none
integer    :: tax,fl

if(iday.gt.180) then
zeig => pt%first
do while (associated(zeig))
   tax = zeig%coh%species
   fl = zeig%coh%flag_vegend
   if(spar(tax)%end_bb.ne.366) then
    if(spar(ns)%flag_endbb.eq.0) then
      if(airtemp.ge.5. .and. fl .ne.0)  then
       fl=0
      else if(airtemp.lt.5. .and. fl.eq.0) then
        fl =1
      else if(airtemp.lt.5. .and. fl.eq.1) then
        fl =2
      else if(airtemp.lt.5. .and. fl.eq.2) then
        fl =3
      else  if(airtemp.lt.5. .and. fl.eq.3)then
         fl =4
      else if(airtemp.lt.5. .and. fl.eq.4) then
         fl =5
      end if
      zeig%coh%flag_vegend = fl
     if(fl .eq.5) then
       spar(tax)%flag_endbb=1
       spar(tax)%end_bb = iday
       write(666,*) time, iday
     end if
   end if
   zeig => zeig%next
  end if
end do
end if
end subroutine calc_endbb