!*****************************************************************! !* *! !* 4C (FORESEE) Simulation Model *! !* *! !* *! !* Subroutine canopy for: *! !* Calculation of canopy geometry & light absorption *! !* with *! !* CALC_LA *! !* LIGHT_GROWTH *! !* COV_AREA *! !* Light_1 *! !* Light_2 *! !* Light_3 *! !* Light_4 *! !* L_3_COH_LOOP *! !* L_4_COH_LOOP *! !* LIGHT_OUT_2 *! !* CROWN_PROJ *! !* *! !* 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 CANOPY *! !**********************************! SUBROUTINE CANOPY !*** Declaration part ***! USE data_out USE data_species USE data_simul USE data_stand IMPLICIT NONE integer i ! If no Cohorts on the patch, initialize properly IF( anz_coh == 0 ) THEN lowest_layer=0 highest_layer=0 vStruct%cumLAI= 0. vStruct%Irel = 0. vStruct%sumBG = 0. Irelpool = 0. BGpool = 0. LAI = 0. ! full light on the ground (layer = 0) ! Lightroutine 1,2 vStruct(highest_layer)%Irel=1 ! Lightroutine 3,4 Irelpool(highest_layer)=1 ! the whole patch is availabe for recruitment BGpool(highest_layer+1)=1 BGpool(highest_layer+2)=1 all_leaves_on=0 ! Calculation of leaf area, lowest and highest layer, etc. ! for all cohorts in all respective layers CALL CALC_LA ! leaf area etc. always calculate RETURN END IF ! Calculation of leaf area, lowest and highest layer, etc. ! for all cohorts in all respective layers CALL CALC_LA IF(flag_end.EQ.3) RETURN IF( flag_light == 1 )THEN CALL LIGHT_1 ELSE IF ( flag_light == 2 ) THEN CALL LIGHT_2 ELSE IF ( flag_light == 3 ) THEN CALL LIGHT_3 ELSE IF ( flag_light == 4 ) THEN CALL LIGHT_4 END IF DO i=1,anrspec ns = nrspec(i) IF(svar(ns)%act_sum_lai > svar(ns)%sum_lai) svar(ns)%sum_lai = svar(ns)%act_sum_lai ENDDO ! Determine relative light in the middle of each cohort canopy, the sla ! and the totFPAR per square meter patch and the total FPAR on the patch CALL LIGHT_GROWTH ! print relevant light parameters for the canopy for each layer and cohort if (time_out.gt.0 .and. out_flag_light.ne.0) CALL LIGHT_OUT_2 !------------------------------------------------ !------------------- SUBROUTINES ---------------- !------------------------------------------------ CONTAINS SUBROUTINE CALC_LA ! Calculation of leaf area, lowest and highest layer, etc. ! for all cohorts in all respective layers !*** Declaration part ***! USE data_species USE data_simul USE data_stand IMPLICIT NONE ! variables required for technical reasons INTEGER :: nl, i TYPE(Coh_Obj), Pointer :: p ! pointer to cohort list ! auxiliary variable REAL :: x ! leaf area per crown unit [m**2/cm] vStruct%LA = 0. ! structure of the canopy is determined once at the start of the year ! initialisation IF(iday==1) THEN lowest_layer=250 highest_layer=0 END IF do i = 1, anrspec svar(nrspec(i))%act_sum_lai = 0. enddo p => pt%first DO WHILE (ASSOCIATED(p)) ns = p%coh%species ! cohort loop for determination of lowest and highest canopy layer of the tree crown ! structure of the canopy must only be determined once at the start of the year IF(iday==1) THEN ! determine bottom of the crown in terms of number of layers p%coh%botLayer = INT( p%coh%x_hbole / dz ) + 1 ! determine top of the crown in terms of number of layers IF (MODULO(p%coh%height,dz)==0.) THEN p%coh%topLayer = INT( p%coh%height / dz ) ELSE p%coh%topLayer = INT( p%coh%height / dz ) + 1 END IF ! remember the highest layer IF(p%coh%topLayer > highest_layer .AND. p%coh%toplayer < 250) THEN highest_layer=p%coh%topLayer ELSE IF(p%coh%toplayer >= 250) THEN if (.not.flag_mult8910) then CALL stop_mess(time,'FATAL EXCEPTION RAISED IN CANOPY CALC_LA') CALL error_mess(time,'maximal tree height of 125 m reached by cohort No.',REAL(p%coh%ident)) endif flag_end=3 RETURN END IF !remember the lowest layer of the stand IF(p%coh%botLayer < lowest_layer) THEN lowest_layer=p%coh%botLayer END IF END IF p%coh%leafarea = 0. ! total leaf area of a tree in this cohort [m**2] IF((iday >= p%coh%day_bb) .AND. (iday <= spar(ns)%end_bb)) THEN p%coh%t_leaf = p%coh%med_sla * p%coh%x_fol ! amount of leaf area per tree in layers IF (p%coh%topLayer-p%coh%botLayer.GE.1) THEN ! now calculate leaf area per crown unit of this tree [m**2/cm] x = p%coh%t_leaf / ( p%coh%height - p%coh%x_hbole ) p%coh%leafArea( p%coh%botLayer ) = ( dz - MODULO( p%coh%x_hbole, dz ) ) * x IF (MODULO(p%coh%height,dz)==0.) THEN p%coh%leafArea( p%coh%topLayer ) = dz * x ELSE p%coh%leafArea( p%coh%topLayer ) = MODULO( p%coh%height, dz ) * x END IF DO nl = p%coh%botLayer+1, p%coh%topLayer-1 p%coh%leafArea(nl) = x * dz END DO ELSE p%coh%leafArea(p%coh%botLayer) = p%coh%t_leaf END IF ! Update vertical patch leaf area profile of the canopy DO nl = p%coh%botLayer, p%coh%topLayer vStruct(nl)%LA = vStruct(nl)%LA + p%coh%leafArea(nl) * p%coh%nTreeA END DO ELSE p%coh%leafArea=0. ENDIF IF(iday<=spar(ns)%end_bb) svar(ns)%act_sum_lai = svar(ns)%act_sum_lai + p%coh%ntreea*p%coh%t_leaf/kpatchsize p => p%next END DO END SUBROUTINE CALC_LA !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! SUBROUTINE LIGHT_GROWTH ! Determine relative light in the middle of each cohort canopy, the sla, ! the total FPAR on the patch !*** Declaration part ***! USE data_species USE data_simul USE data_stand IMPLICIT NONE integer help TYPE(Coh_Obj), Pointer :: p ! pointer to cohort list totFPARsum=0 ! sum of all totFPAR's totFPARcan=0 ! sum of all totFPAR's for the canopy p => pt%first DO WHILE (ASSOCIATED(p)) ns=p%coh%species ! the new average specific leaf area per cohort depends ! on the light regime in the middle of the canopy ! this is the SLA which is used for the leaf area distr. in the next year ! the new average specific leaf area per cohort depends on the ! mean light regime in the middle in the canopy ! IrelCan modifies the growthfunction IF(all_leaves_on==1) THEN select case (flag_light) case (1,2) p%coh%med_sla = spar(ns)%psla_min+spar(ns)%psla_a*& (1-(vStruct(p%coh%toplayer)%Irel+vStruct(p%coh%botlayer)%Irel)/2.) p%coh%IrelCan = vStruct(p%coh%toplayer)%Irel case default p%coh%med_sla = spar(ns)%psla_min+spar(ns)%psla_a*& (1-(p%coh%Irel(p%coh%topLayer)+p%coh%Irel(p%coh%botLayer))/2.) select case (ns) case (10) ! Douglas fir help = p%coh%botLayer+2*(p%coh%toplayer - p%coh%botLayer) / 3 p%coh%IrelCan = p%coh%Irel(help) case default help = vStruct(p%coh%toplayer)%SumBG if (help .gt. 0.) then p%coh%IrelCan = p%coh%Irel(p%coh%toplayer)*MIN(kpatchsize/help, 1.) else p%coh%IrelCan = p%coh%Irel(p%coh%toplayer) endif end select ! ns end select ! flag_light END IF totFPARsum = totFPARsum + p%coh%totFPAR*p%coh%nTreeA IF (p%coh%species .le. nspec_tree .or. p%coh%species.eq.nspec_tree+2) totFPARcan = totFPARcan + p%coh%totFPAR*p%coh%nTreeA p => p%next END DO END SUBROUTINE LIGHT_GROWTH !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! SUBROUTINE COV_AREA ! calculate coverage-area as fraction of the patchsize per tree and layer !*** Declaration part ***! USE data_climate USE data_par USE data_stand USE data_site IMPLICIT NONE ! variables required for technical reasons INTEGER :: i ! Variables to test restriction in light model 4 REAL :: y ! potential shadow cast of the cohort [m] REAL :: w ! effective shadow cast of the cohort [m] REAL :: l ! side length of a coort layer [m] REAL :: reqarea ! area of the patch required for the shadow cast for all cohorts per layer INTEGER :: layer_flag ! remember the highest layer where first LM4 restriction occurs TYPE(Coh_Obj), Pointer :: p ! pointer to cohort list y = dz/100/TAN(beta) lm3layer=0 layer_flag=0 DO i = highest_layer, lowest_layer, -1 reqarea=0. p => pt%first DO WHILE (ASSOCIATED(p)) p%coh%BG(i) = 0. ! only those trees that have leaves IF((iday >= p%coh%day_bb) .AND. (iday <= spar(p%coh%species)%end_bb) .AND. & i <= p%coh%topLayer .AND. i >= p%coh%botLayer) THEN IF (vStruct(i)%sumBG > kpatchsize) THEN p%coh%BG(i)=p%coh%crown_area/vStruct(i)%sumBG ELSE p%coh%BG(i)=p%coh%crown_area/kpatchsize END IF l = SQRT(p%coh%BG(i)*kpatchsize) reqarea = reqarea + l*y*p%coh%nTreeA END IF p => p%next END DO ! cohorts IF( kpatchsize > vStruct(i)%sumBG .AND. reqarea /= 0) THEN w = y*(kpatchsize-vStruct(i)%sumBG)/reqarea ELSE w = 0 END IF p => pt%first DO WHILE (ASSOCIATED(p) .AND. layer_flag.EQ.0) ! only those trees that have leaves IF((iday >= p%coh%day_bb) .AND. (iday <= spar(p%coh%species)%end_bb) .AND. & i <= p%coh%topLayer .AND. i >= p%coh%botLayer) THEN l = SQRT(p%coh%BG(i)*kpatchsize) ! layer from that on light model 3 is used instead of light model 4 ! because of LM4 restrictions IF( y-w > w+l ) THEN layer_flag=1 lm3layer = i EXIT ! do loop END IF END IF p => p%next END DO END DO ! layers END SUBROUTINE COV_AREA !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! SUBROUTINE LIGHT_1 !*** Declaration part ***! USE data_species USE data_simul USE data_stand IMPLICIT NONE ! variables required for technical reasons INTEGER :: i, nl TYPE(Coh_Obj), Pointer :: p ! pointer to cohort list ! auxiliary variables REAL :: radSum ! sum of absorbed radiation (help variable) REAL :: pfext=0.6 ! extinction coefficient. Only for one specie. !*** Calculation part ***! ! Intialization radiation summator radSum = 0. vStruct%cumLAI = 0. vStruct%Irel = 0. ! Calculate cumulative leaf area index and absorbed radiation per layer ! using Lambert-Beer vStruct(highest_layer)%Irel=1 DO i = highest_layer, lowest_layer, -1 vStruct(i)%cumLAI = vStruct(i)%LA/kPatchsize + vStruct(i+1)%cumLAI vStruct( i )%radFrac = 1. - Exp(-pfext * vStruct(i)%cumLAI) - radSum radSum = radSum + vStruct(i)%radFrac vStruct(i-1)%Irel=vStruct(i)%Irel-vStruct(i)%radFrac END DO ! Light intensitiy unto the ground DO i = lowest_layer - 2, 0, -1 vStruct(i)%Irel=vStruct(i+1)%Irel END DO ! total LAI is simply the value of cumLAI at the forest floor LAI = vStruct(lowest_layer)%cumLAI IF(lai>laimax) laimax=lai ! Determine layer-specific & total fraction of PAR absorbed by this tree p => pt%first DO WHILE (ASSOCIATED(p)) p%coh%totFPAR = 0. p%coh%FPAR = 0. DO nl = p%coh%botLayer, p%coh%topLayer p%coh%FPAR(nl) = p%coh%leafArea(nl) / vStruct(nl)%LA * vStruct(nl)%radFrac p%coh%totFPAR = p%coh%totFPAR + p%coh%FPAR(nl) END DO p => p%next END DO IF(all_leaves_on==1) THEN p => pt%first DO WHILE (ASSOCIATED(p)) DO i = highest_layer, lowest_layer, -1 p%coh%antFPAR(i)=p%coh%FPAR(i)/p%coh%totFPAR p%coh%sleafarea(i)=p%coh%leafarea(i) END DO ! end layer loop p => p%next END DO ! cohort loop ENDIF END SUBROUTINE LIGHT_1 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! SUBROUTINE LIGHT_2 !*** Declaration part ***! USE data_species USE data_simul USE data_stand IMPLICIT NONE ! variables required for technical reasons INTEGER :: i real :: help TYPE(Coh_Obj), Pointer :: p ! pointer to cohort list !*** Calculation part ***! vStruct%cumLAI = 0. vStruct%Irel = 0. ! cohort loop p => pt%first DO WHILE (ASSOCIATED(p)) p%coh%FPAR = 0. p%coh%totFPAR = 0. p => p%next END DO ! cohort loop ! Now calculate crown projection per tree and layer and ! the coverage sum over all layers CALL CROWN_PROJ ! now calculate coverage-area as fraction of the patchsize per tree and layer CALL COV_AREA vStruct(highest_layer)%Irel=1 DO i = highest_layer, lowest_layer, -1 p => pt%first help=0. vStruct(i)%cumLAI = vStruct(i)%LA/kpatchsize + vStruct(i+1)%cumLAI DO WHILE (ASSOCIATED(p)) ns=p%coh%species IF (p%coh%BG(i).ne.0.) THEN ! faction of absorbed light rel. to the light at the top of this layer ! the reference area is the whole patch (weighted by BG(i))! p%coh%FPAR(i)=(1-exp(-spar(ns)%pfext*p%coh%leafArea(i)/& kpatchsize/p%coh%BG(i)))*p%coh%BG(i) ! sum up the total absorbed fraction of this cohort, ! the total fraction of absorbed light in this layer ! is the fraction absorbed* fraction of light*BG ! the reference area is the whole patch! p%coh%totFPAR=p%coh%totFPAR+vStruct(i)%Irel*p%coh%FPAR(i)*& (1+(0.5-vStruct(i)%Irel)*spar(ns)%fpar_mod/0.5) ! at first sum all the absorbed light fractions over the cohorts help=help+p%coh%FPAR(i)*p%coh%nTreeA ELSE p%coh%FPAR(i)=0. END IF p => p%next END DO ! then calculate the fraction of light which is available for the next layer vStruct(i-1)%Irel=vStruct(i)%Irel*(1-help) END DO ! Light intensitiy unto the ground DO i = lowest_layer - 2, 0, -1 vStruct(i)%Irel=vStruct(i+1)%Irel END DO IF(all_leaves_on==1) THEN p => pt%first DO WHILE (ASSOCIATED(p)) DO i = highest_layer, lowest_layer, -1 p%coh%antFPAR(i)=vStruct(i)%Irel*p%coh%FPAR(i)*(1+(0.5-vStruct(i)%Irel)*spar(ns)%fpar_mod/0.5)/p%coh%totFPAR p%coh%sleafarea(i)=p%coh%leafarea(i) END DO ! end layer loop p => p%next END DO ! cohort loop ENDIF ! total LAI is simply the value of cumLAI at the forest floor LAI = vStruct(lowest_layer)%cumLAI IF(lai>laimax) laimax=lai END SUBROUTINE LIGHT_2 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! SUBROUTINE L_3_COH_LOOP(i,j) !*** Declaration part ***! USE data_species USE data_simul USE data_stand IMPLICIT NONE ! variables required for technical reasons TYPE(Coh_Obj), Pointer :: p ! pointer to cohort list INTEGER :: i, j ! i= Schicht, j= Variante REAL :: help p => pt%first ! cohort loop in layer i DO WHILE (ASSOCIATED(p)) ns=p%coh%species IF((iday < p%coh%day_bb) .OR. (iday > spar(ns)%end_bb)) GOTO 1313 IF (i<=p%coh%toplayer.AND.i>=p%coh%botlayer) THEN p%coh%FPAR(i)=1-exp(-spar(ns)%pfext*p%coh%leafArea(i)/& kpatchsize/p%coh%BG(i)) ! FPAR is related to the projection area and has to be modified ! by the same factor by that the projection area is being modified ! in case sumBG > patchsize p%coh%FPAR(i)=p%coh%FPAR(i)*MIN(kpatchsize/vStruct(i)%sumBG,1.) ! test wether the cohort is new, was there before or will not be ! represented in the next layer IF (i == p%coh%toplayer) THEN p%coh%Irel(i)=Irelpool(i) ! totFPAR per patch! Since the projection area changes totFPAR has to ! be related to the patch in each layer p%coh%totFPAR=p%coh%totFPAR+p%coh%Irel(i)*p%coh%FPAR(i)*p%coh%BG(i) ! light available for this cohort in the next layer p%coh%Irel(i-1)=p%coh%Irel(i)*(1-p%coh%FPAR(i)) ELSE IF (i == p%coh%botlayer) THEN IF( j == 2 ) THEN help=p%coh%BG(i)-p%coh%BG(i+1) p%coh%Irel(i)=(1/(p%coh%BG(i)))*& (p%coh%Irel(i)*p%coh%BG(i+1)+Irelpool(i)*help) END IF ! totFPAR per patch! Since the projection area changes totFPAR has to ! be related to the patch in each layer p%coh%totFPAR=p%coh%totFPAR+p%coh%Irel(i)*p%coh%FPAR(i)*p%coh%BG(i) ! light available for this cohort in the next layer p%coh%Irel(i-1)=p%coh%Irel(i)*(1-p%coh%FPAR(i)) ! The light which leaves the cohort is fed into the pool ! the light intensitiy is weighted by the overall BG of this cohort Irelpool(i-1)=(1/(p%coh%BG(i)*p%coh%nTreeA+BGpool(i)))*& (p%coh%BG(i)*p%coh%nTreeA*p%coh%Irel(i-1)+BGpool(i)*Irelpool(i-1)) ! BG of the pool available for the next layer increases BGpool(i)=BGpool(i)+p%coh%BG(i)*p%coh%nTreeA ELSE IF( j == 2 ) THEN help=p%coh%BG(i)-p%coh%BG(i+1) p%coh%Irel(i)=(1/(p%coh%BG(i)))*& (p%coh%Irel(i)*p%coh%BG(i+1)+Irelpool(i)*help) END IF ! totFPAR per patch! Since the projection area changes totFPAR has to ! be related to the patch in each layer p%coh%totFPAR=p%coh%totFPAR+p%coh%Irel(i)*p%coh%FPAR(i)*p%coh%BG(i) ! light available for this cohort in the next layer p%coh%Irel(i-1)=p%coh%Irel(i)*(1-p%coh%FPAR(i)) END IF END IF ! Layer test 1313 CONTINUE p => p%next END DO ! cohort loop END SUBROUTINE L_3_COH_LOOP !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! SUBROUTINE LIGHT_3 !*** Declaration part ***! USE data_species USE data_simul USE data_stand IMPLICIT NONE ! variables required for technical reasons INTEGER :: i REAL :: help TYPE(Coh_Obj), Pointer :: p ! pointer to cohort list !*** Calculation part ***! vStruct%cumLAI = 0. Irelpool = 0. BGpool = 0. vStruct%Irel = 0. ! test variable for the light balance in layers vStruct%radFrac = 0. ! test variable for the light balance in layers ! cohort loop p => pt%first DO WHILE (ASSOCIATED(p)) p%coh%FPAR = 0. p%coh%totFPAR = 0. p%coh%Irel = 0. p => p%next END DO ! cohort loop ! Now calculate crown projection per tree and layer and ! the coverage sum over all layers CALL CROWN_PROJ ! now calculate coverage-area as fraction of the patchsize per tree and layer CALL COV_AREA ! ----------------------------------------------------------- ! now calculate per tree and layer the effective LAI ! this gives the absorbed light per tree and layer ! this gives the total fraction absorbes light per tree ! further each tree and each layer has an individual light regime. The area ! which is not covered by trees is treated as a pool ! ! reference area for the total fracation absorbed is the patch area ! above the canopy there is 100 % rel. light Irelpool(highest_layer)=1. ! the size of the pool is defined as the fraction of the patch ! which can potentially be used by new cohorts in the next layer. ! Therefore is is the patch-fraction which is free anyway plus the ! fraction coverd by cohorts that will not be present in the next layer ! this means, the light intensity Irelpool(i) is available on the ! area BGpool(i+1) BGpool(highest_layer+1)=1. DO i = highest_layer, lowest_layer, -1 vStruct(i)%cumLAI = vStruct(i)%LA/kpatchsize + vStruct(i+1)%cumLAI ! two cases: ! first case: sumBG increases in this layer or remains the same IF (vStruct(i+1)%sumBG<=vStruct(i)%sumBG) THEN ! three subcases: ! first subcase of 'sumBG increases': sumBG stays below patchsize ! ( no BG modification) or does not change IF ((vStruct(i+1)%sumBG.LT.kpatchsize.AND.vStruct(i)%sumBG.LE.kpatchsize).OR.& vStruct(i+1)%sumBG == vStruct(i)%sumBG) THEN ! At the beginning the light intensity of the pool remains the same ! but it will be updated when cohorts drop out Irelpool(i-1)=Irelpool(i) ! until there are cohorts dropping out BGpool(i)=MAX((kpatchsize-vStruct(i)%sumBG)/kpatchsize,0.) CALL L_3_COH_LOOP(i,1) ! second and third subcase of 'sumBG increases or remains the same' ! the BG's of the cohorts change because sumBG exceeds patchsize. ! second subcase: sumBG was < patchsize before ! third subcase: sumBG was > patchsize before ELSE ! BG and light intensitiy of the pool for the next(!) layer ! is 0 as long as there are no cohorts dropping out Irelpool(i-1)=0. BGpool(i)=0. p => pt%first ! cohort loop 1 DO WHILE (ASSOCIATED(p)) ! calculate the new fraction covered by the pool ! which is the old pool plus the fractions which are lost ! by the old cohorts due to new BG's ! this also changes the light intensity of the pool ! This pool will all be used by the new cohorts ! consider only cohorts that have been there before (i<toplayer) IF (i<p%coh%toplayer.AND.i>=p%coh%botlayer .AND.& iday >= p%coh%day_bb .AND. iday <= spar(p%coh%species)%end_bb) THEN help=BGpool(i+1)+(p%coh%BG(i+1)-p%coh%BG(i))*p%coh%nTreeA Irelpool(i)=(1/help)*(Irelpool(i)*BGpool(i+1)+p%coh%Irel(i)*& (p%coh%BG(i+1)-p%coh%BG(i))*p%coh%nTreeA) BGpool(i+1)=help END IF ! layer test p => p%next END DO ! cohort loop1 CALL L_3_COH_LOOP(i,1) END IF ! subcases of 'sumBG increases ! second case: sumBG decreases ELSE ! two subcases ! first subcase of 'sumBG decrease': sumBG < patchsize before and after ! i.e. BG's do not change ! i.e. all projection area requirements can be fulfilled in the next layer IF (vStruct(i+1)%sumBG.LT.kpatchsize) THEN ! At the beginning the light intensity of the pool remains the same ! but it will be updated when cohorts drop out Irelpool(i-1)=Irelpool(i) ! until there are cohorts dropping out BGpool(i)=(kpatchsize-vStruct(i)%sumBG)/kpatchsize CALL L_3_COH_LOOP(i,1) ! second subcase of 'sumBG decrease': sumBG remains > patchsize or ! sumBG was > patchsize, i.e. BG's do change ELSE ! BG of the pool for the next layer as long as there are ! no cohorts dropping out BGpool(i)=MAX((kpatchsize-vStruct(i)%sumBG)/kpatchsize,0.) Irelpool(i-1)=Irelpool(i) CALL L_3_COH_LOOP(i,2) END IF ! subcases END IF ! three main cases END DO ! end layer loop ! ----------------------------------------------------------- IF(all_leaves_on==1) THEN p => pt%first DO WHILE (ASSOCIATED(p)) DO i = highest_layer, lowest_layer, -1 p%coh%antFPAR(i)=p%coh%Irel(i)*p%coh%FPAR(i)*p%coh%BG(i)/p%coh%totFPAR p%coh%sleafarea(i)=p%coh%leafarea(i) END DO ! end layer loop p => p%next END DO ! cohort loop ENDIF ! total LAI is simply the value of cumLAI at the lowest layer LAI = vStruct(lowest_layer)%cumLAI IF(lai>laimax) laimax=lai ! light intensitiy and free patch space unto the ground DO i = lowest_layer - 2, 0, -1 Irelpool(i)=Irelpool(i+1) BGpool(i+1)=BGpool(i+2) END DO END SUBROUTINE LIGHT_3 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! SUBROUTINE L_4_COH_LOOP(i,j,beta,y) !*** Declaration part ***! USE data_species USE data_simul USE data_stand IMPLICIT NONE ! variables required for technical reasons TYPE(Coh_Obj), Pointer :: p ! pointer to cohort list INTEGER :: i, j ! i= layer, j= type REAL :: y ! potential shadow cast of a cohort layer [m] REAL :: l ! side length of a cohort layer [m] REAL :: w ! effective shadow cast of a cohort layer [m] REAL :: helplai ! LAI per layer and cohort REAL :: help REAL :: beta ! sun inclination REAL :: dropoutpool ! relative area covered by cohort dropping out REAL :: f1,f2,f3,f4,f5,f6,f7,f8 ! average fraction of absorbed radiation in different ! regions of the tree layer according to the 4C description paper REAL :: k ! extintion coefficient REAL :: reqarea ! area of the patch required for the shadow cast for all cohorts per layer reqarea=0. ! cohort loop p => pt%first DO WHILE (ASSOCIATED(p)) IF (i<=p%coh%toplayer.AND.i>=p%coh%botlayer) THEN l = SQRT(p%coh%BG(i)*kpatchsize) reqarea = reqarea + l*y*p%coh%nTreeA END IF p => p%next END DO ! cohort loop ! the size of the pool is defined as the fraction of ! the patch which is not covered by cohorts. This is the ! area covered by the sum of the 'shadows' of the cohorts, ! i.e. y's or rather w's + the area of cohorts dropping out in the next layer + ! the are that exeeds the maximal required area by the shadow-cast. ! This is updated in each layer ! w is the width of the shadow-cast of the cohorts that is maximal y. ! This maximal y also defines the maximal required area for all shadows ! 'reqarea' = required area ! When the maximal y cannot be satisfied, then this area is reduced by the ! relative share of the available space not covered by cohorts to the ! maximal required area for shadow cast IF( kpatchsize > vStruct(i)%sumBG ) THEN if (reqarea .gt. 1E-08) then w = y*(kpatchsize-vStruct(i)%sumBG)/reqarea else w = y*kpatchsize endif ELSE w = 0 END IF BGpool(i)=0. dropoutpool=0 p => pt%first ! cohort loop in layer i DO WHILE (ASSOCIATED(p)) ns=p%coh%species IF((iday < p%coh%day_bb) .OR. (iday > spar(ns)%end_bb)) GOTO 1313 k = spar(ns)%pfext IF (i<=p%coh%toplayer.AND.i>=p%coh%botlayer) THEN l = SQRT(p%coh%BG(i)*kpatchsize) if( p%coh%BG(i).ne.0) then helplai=p%coh%leafArea(i)/kpatchsize/p%coh%BG(i) if (helplai .le. 0.) then continue endif else helplai = 0. end if IF (i == p%coh%toplayer) THEN p%coh%Irel(i)=Irelpool(i) ELSE IF( j == 2 .AND. i /= p%coh%toplayer ) THEN help=p%coh%BG(i)-p%coh%BG(i+1) p%coh%Irel(i)=(1/(p%coh%BG(i)))*& (p%coh%Irel(i)*p%coh%BG(i+1)+Irelpool(i)*help) END IF ! two main cases: ! first case : all light from the side comes from the pool ! second case : light from the side comes partially from the cohort itself IF( w >= y ) THEN ! subcases : 1.: light from the side of the layer ! does only leave at the bottom of the layer ! 2: light from the side does also leave on the other side ! totFPAR per patch! Since the projection area changes totFPAR has to ! be related to the patch in each layer IF( y <= l ) THEN f1 = 1-exp(-k*helplai/SIN(beta)) if (helplai .lt. 1.E-6) then f2 = 0. else f2 = 1-SIN(beta)/(k*helplai)*f1 if (f2 .lt. 0.) then continue f2 = 0. endif endif p%coh%totFPAR=p%coh%totFPAR+(1/kpatchsize)*& ((l-y)*l*p%coh%Irel(i)*f1+& ! max. LAI ! exits layer at the side y*l*f2*p%coh%Irel(i)+& ! from the side to the next layer y*l*f2*Irelpool(i)) p%coh%FPAR(i)=p%coh%totFPAR ! average light leaving the bottom of the cohort p%coh%Irel(i-1)=(1/l)*& ! max. LAI ((l-y)*p%coh%Irel(i)*(1-f1)+& ! from the side to the next layer y*(1-f2)*Irelpool(i)) ! Light in the pool. IF(i /= p%coh%botlayer) THEN Irelpool(i-1)=1/(BGpool(i)*kpatchsize+y*l*p%coh%nTreeA)*& ! amount present in the pool (BGpool(i)*kpatchsize*Irelpool(i-1)+& ! exits layer at the side y*l*p%coh%nTreeA*(1-f2)*p%coh%Irel(i)) BGpool(i)=BGpool(i)+y*l*p%coh%nTreeA/kpatchsize ELSE Irelpool(i-1)=1/(BGpool(i)*kpatchsize+(y+l)*l*p%coh%nTreeA)*& ! amount present in the pool (BGpool(i)*kpatchsize*Irelpool(i-1)+& ! exits layer at the side y*l*p%coh%nTreeA*(1-f2)*p%coh%Irel(i)+& ! from layer onto next layer l*l*p%coh%nTreeA*p%coh%Irel(i-1)) ! BG of the pool available for the next layer increases BGpool(i)=BGpool(i)+p%coh%nTreeA*(y*l/kpatchsize+p%coh%BG(i)) dropoutpool=dropoutpool+p%coh%nTreeA*p%coh%BG(i) END IF ! y > l ELSE f3 = 1-exp(-k*helplai*l/(SIN(beta)*y)) f4 = 1-SIN(beta)*y/(l*k*helplai)*f3 p%coh%totFPAR=p%coh%totFPAR+(1/kpatchsize)*& ((y-l)*l*f3*Irelpool(i)+& ! red. max. LAI ! exits layer at the side l*l*f4*p%coh%Irel(i)+& ! from the side to next layer l*l*f4*Irelpool(i)) p%coh%FPAR(i)=p%coh%totFPAR ! average light leaving the cohort p%coh%Irel(i-1)=(1-f4)*Irelpool(i) ! Light in the pool. Even when the area of the pool is ! equal to zero, there is virtual light in the pool ! which is used as light coming from the side ! the area weighted mean over all y is calculated IF(i /= p%coh%botlayer) THEN Irelpool(i-1)=1/(BGpool(i)*kpatchsize+y*l*p%coh%nTreeA)*& ! amount present in pool (BGpool(i)*kpatchsize*Irelpool(i-1)+& ! red. max. LAI (y-l)*l*p%coh%nTreeA*(1-f3)*Irelpool(i)+& ! exits layer at side l*l*p%coh%nTreeA*(1-f4)*p%coh%Irel(i)) BGpool(i)=BGpool(i)+y*l*p%coh%nTreeA/kpatchsize ELSE Irelpool(i-1)=1/(BGpool(i)*kpatchsize+(l+y)*l*p%coh%nTreeA)*& ! amount present in the pool (BGpool(i)*kpatchsize*Irelpool(i-1)+& ! red. max. LAI (y-l)*l*p%coh%nTreeA*(1-f3)*Irelpool(i)+& ! exits layer at side l*l*p%coh%nTreeA*(1-f4)*p%coh%Irel(i)+& ! from layer to next layer l*l*p%coh%nTreeA*p%coh%Irel(i-1)) ! BG of the pool available for the next layer increases BGpool(i)=BGpool(i)+p%coh%nTreeA*(y*l/kpatchsize+p%coh%BG(i)) dropoutpool=dropoutpool+p%coh%nTreeA*p%coh%BG(i) END IF ! bottom layer or not END IF ! light entering sideways also leaving sideways or not ! second main case : light from the side comes partially from the ! cohort itself ELSE ! Exit, when average light from the side needs itself as input ! should not happen because this is taken care for in COV_AREA IF( y-w > w+l ) THEN if (.not.flag_mult8910) then CALL stop_mess(time,'FATAL EXCEPTION RAISED IN CANOPY LIGHT ROUTINE 4') CALL error_mess(time,'Light leaving the side of cohort needs itself as input. Cohort No.',REAL(p%coh%ident)) CALL error_mess(time,'Try decreasing layer height dz or increasing average sun inclination.',0.) endif STOP END IF ! subcases : 1.: light from the side of the layer ! does only leave at the bottom of the layer ! 2: light from the side does also leave on the other side but light from the top ! still goes into the pool ! 3. light from the side does also leave on the other side and light from the top ! is all used as input again ! totFPAR per patch! because the projection area changes totFPAR has to ! be related to the patch in each layer IF( y <= l ) THEN IF( w /= 0 ) THEN ! max LAI f1 = 1-exp(-k*helplai/SIN(beta)) ! edge piece f5 = 1+SIN(beta)*y/((y-w)*k*helplai)*(exp(-k*helplai*(y-w)/(SIN(beta)*y))-1) ! red. LAI f6 = 1+SIN(beta)*y/(w*k*helplai)*(1-f1-exp(-k*helplai*(y-w)/(SIN(beta)*y))) ELSE ! max LAI f1 = 1-exp(-k*helplai/SIN(beta)) f5 = 1+SIN(beta)*y/((y-w)*k*helplai)*(exp(-k*helplai*(y-w)/(SIN(beta)*y))-1) f6 = 0 END IF p%coh%totFPAR=p%coh%totFPAR+(1/kpatchsize)*& ! enters from above into the pool (w*l*f6*p%coh%Irel(i)+& ! from above on own side (y-w)*l*f5*p%coh%Irel(i)+& ! max. LAI (l-y)*l*f1*p%coh%Irel(i)+& ! from pool to next layer w*l*f6*Irelpool(i)+& ! from the side to the next layer (y-w)*l*(1-f5)*f5*p%coh%Irel(i)) p%coh%FPAR(i)=p%coh%totFPAR ! average light leaving the bottom of the cohort p%coh%Irel(i-1)=(1/l)*& ! max. LAI ((l-y)*(1-f1)*p%coh%Irel(i)+& ! from pool to next layer w*(1-f6)*Irelpool(i)+& ! from the sides to the next layer (y-w)*(1-f5)*(1-f5)*p%coh%Irel(i)) ! Light in the pool. IF(i /= p%coh%botlayer .AND. w/=0) THEN Irelpool(i-1)=1/(BGpool(i)*kpatchsize+w*l*p%coh%nTreeA)*& ! present in the pool (BGpool(i)*kpatchsize*Irelpool(i-1)+& ! exits layer at the side w*l*p%coh%nTreeA*(1-f6)*p%coh%Irel(i)) BGpool(i)=BGpool(i)+w*l*p%coh%nTreeA/kpatchsize ELSE IF(i == p%coh%botlayer) THEN Irelpool(i-1)=1/(BGpool(i)*kpatchsize+(w+l)*l*p%coh%nTreeA)*& ! present in pool (BGpool(i)*kpatchsize*Irelpool(i-1)+& ! exits layer to the side w*l*p%coh%nTreeA*(1-f6)*p%coh%Irel(i)+& ! from layer to next layer l*l*p%coh%nTreeA*p%coh%Irel(i-1)) ! BG of the pool available for the next layer increases BGpool(i)=BGpool(i)+p%coh%nTreeA*(w*l/kpatchsize+p%coh%BG(i)) dropoutpool=dropoutpool+p%coh%nTreeA*p%coh%BG(i) END IF ! light from the top still goes into the pool. ! The case w=0 is no longer permissible ELSE IF(y > l .AND. w >= y-l) THEN IF( w /= y-l ) THEN f3 = 1-exp(-k*helplai*l/(SIN(beta)*y)) f5 = 1+SIN(beta)*y/((y-w)*k*helplai)*(exp(-k*helplai*(y-w)/(SIN(beta)*y))-1) f7 = 1+SIN(beta)*y/((l-y+w)*k*helplai)*(exp(-k*helplai*l/(SIN(beta)*y))-& exp(-k*helplai*(y-w)/(SIN(beta)*y))) ELSE f3 = 1-exp(-k*helplai*l/(SIN(beta)*y)) f5 = 1+SIN(beta)*y/((y-w)*k*helplai)*(exp(-k*helplai*(y-w)/(SIN(beta)*y))-1) f7 = 0 END IF p%coh%totFPAR=p%coh%totFPAR+(1/kpatchsize)*& ! enters pool from above ((l-y+w)*l*f7*p%coh%Irel(i)+& ! from above into own side (y-w)*l*f5*p%coh%Irel(i)+& ! red. max. LAI (y-l)*l*f3*Irelpool(i)+& ! from the side into the next layer (l-y+w)*l*f7*Irelpool(i)+& ! from the side into the next layer (y-w)*l*f5*(1-f5)*p%coh%Irel(i)) p%coh%FPAR(i)=p%coh%totFPAR ! average light leaving the cohort p%coh%Irel(i-1)=(1/l)*((l-y+w)*((1-f7)*Irelpool(i)+& (y-w)*(1-f5)*(1-f5)*p%coh%Irel(i))) ! Light in the pool. IF(i /= p%coh%botlayer) THEN Irelpool(i-1)=1/(BGpool(i)*kpatchsize+w*l*p%coh%nTreeA)*& ! present in the pool (BGpool(i)*kpatchsize*Irelpool(i-1)+& ! exits from top to the side (l-y+w)*l*p%coh%nTreeA*(1-f7)*p%coh%Irel(i)+& ! from the side into the pool (y-l)*l*p%coh%nTreeA*(1-f3)*Irelpool(i)) BGpool(i)=BGpool(i)+w*l*p%coh%nTreeA/kpatchsize ELSE IF (i == p%coh%botlayer) THEN Irelpool(i-1)=1/(BGpool(i)*kpatchsize+(l+w)*l*p%coh%nTreeA)*& ! present in the pool (BGpool(i)*kpatchsize*Irelpool(i-1)+& ! exits from the sides (l-y+w)*l*p%coh%nTreeA*(1-f7)*p%coh%Irel(i)+& ! enters from the sied into the pool (y-l)*l*p%coh%nTreeA*(1-f3)*Irelpool(i)+& ! from layer to next layer l*l*p%coh%nTreeA*p%coh%Irel(i-1)) ! BG of the pool available for the next layer increases BGpool(i)=BGpool(i)+p%coh%nTreeA*(w*l/kpatchsize+p%coh%BG(i)) dropoutpool=dropoutpool+p%coh%nTreeA*p%coh%BG(i) END IF ! bottom layer or not ! light from the top still goes into the pool ELSE IF(y > l .AND. w < y-l) THEN f3 = 1-exp(-k*helplai*l/(SIN(beta)*y)) f4 = 1-SIN(beta)*y/(l*k*helplai)*f3 f8 = 1/(y-w)*(l*f4+(y-w-l)*f3) p%coh%totFPAR=p%coh%totFPAR+(1/kpatchsize)*& ! from above to own side (l*l*f4*p%coh%Irel(i)+& ! from side to the own side and into the pool y*l*f3*Irelpool(i)+& ! from the side to the next layer and into the pool l*f8*(1-f8)*(l*p%coh%Irel(i)+(y-w-l)*Irelpool(i))) p%coh%FPAR(i)=p%coh%totFPAR ! average light leaving the cohort p%coh%Irel(i-1)=(1-f4)*(1-f8)*(l*p%coh%Irel(i)+(y-w-l)*Irelpool(i)) ! Light in the pool. IF(i /= p%coh%botlayer) THEN Irelpool(i-1)=1/(BGpool(i)*kpatchsize+w*l*p%coh%nTreeA)*& ! present in the pool (BGpool(i)*kpatchsize*Irelpool(i-1)+& ! from the side into the pool (2*w-y+l)*l*p%coh%nTreeA*(1-f3)*Irelpool(i)+& (y-w-l)*l*p%coh%nTreeA*(1-f3)*(1-f8)*& (l*p%coh%Irel(i)+(y-w-l)*Irelpool(i))) BGpool(i)=BGpool(i)+w*l*p%coh%nTreeA/kpatchsize ELSE IF (i == p%coh%botlayer) THEN Irelpool(i-1)=1/(BGpool(i)*kpatchsize+(l+w)*l*p%coh%nTreeA)*& ! present in the pool (BGpool(i)*kpatchsize*Irelpool(i-1)+& ! from the side into the pool (2*w-y+l)*l*p%coh%nTreeA*(1-f3)*Irelpool(i)+& (y-w-l)*l*p%coh%nTreeA*(1-f3)*(1-f8)*& (l*p%coh%Irel(i)+(y-w-l)*Irelpool(i))+& ! from layer to next layer l*l*p%coh%nTreeA*(1-f4)*(1-f8)*& (l*p%coh%Irel(i)+(y-w-l)*Irelpool(i))) ! BG of the pool available for the next layer increases BGpool(i)=BGpool(i)+p%coh%nTreeA*(w*l/kpatchsize+p%coh%BG(i)) dropoutpool=dropoutpool+p%coh%nTreeA*p%coh%BG(i) END IF ! bottom layer or not END IF ! light entering sideways also leaving sideways or not END IF ! two main cases END IF 1313 CONTINUE if (p%coh%FPAR(i) .lt. 0. .or. p%coh%totFPAR .lt. 0.) then continue p%coh%FPAR(i) = 0. ! intercept negative radiation p%coh%totFPAR = 0. endif p => p%next END DO ! cohort loop ! Treelayers are distributed on the patch such that their y's ! cover the free space as good as possible IF( w > y ) THEN Irelpool(i-1)=1/(kpatchsize*(1+dropoutpool)-vStruct(i)%sumBG)*& (BGpool(i)*kpatchsize*Irelpool(i-1)+& (kpatchsize-vStruct(i)%sumBG-(BGpool(i)-dropoutpool)*kpatchsize)*Irelpool(i)) BGpool(i)=(kpatchsize-vStruct(i)%sumBG)/kpatchsize + dropoutpool END IF END SUBROUTINE L_4_COH_LOOP !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! SUBROUTINE LIGHT_4 !*** Declaration part ***! USE data_climate USE data_par USE data_species USE data_stand use data_site IMPLICIT NONE ! variables required for technical reasons INTEGER :: i REAL :: help REAL :: y ! potential shadow cast of the stand [m] TYPE(Coh_Obj), Pointer :: p ! pointer to cohort list !*** Calculation part ***! vStruct%cumLAI = 0. Irelpool = 0. BGpool = 0. vStruct%Irel = 0. ! test variable for the balance in layers vStruct%radFrac = 0. ! test variable for the balance in layers y = dz/100/TAN(beta) ! cohort loop p => pt%first DO WHILE (ASSOCIATED(p)) p%coh%FPAR = 0. p%coh%totFPAR = 0. p%coh%Irel = 0. p => p%next END DO ! cohort loop if (time .eq. 8 .and. iday .eq. 134) then continue endif ! Now calculate crown projection per tree and layer and ! the coverage sum over all layers CALL CROWN_PROJ ! now calculate coverage-area as fraction of the patchsize per tree and layer CALL COV_AREA ! ----------------------------------------------------------- ! now calculate per tree and layer the effective LAI ! this gives the absorbed light per tree and layer ! this gives the total fraction absorbes light per tree ! further each tree and each layer has an individual light regime. The area ! which is not covered by trees is treated as a pool ! whose light is available for all new cohorts. ! reference area for the total fraction absorbed is the patch area. ! GBpool is exactly defined in subroutine L_4_COH_LOOP BGpool(highest_layer+1)=1. ! above the canopy there is 100 % rel. light Irelpool(highest_layer)=1. DO i = highest_layer, lowest_layer, -1 vStruct(i)%cumLAI = vStruct(i)%LA/kpatchsize + vStruct(i+1)%cumLAI ! two cases: ! first case: sumBG increases in this layer or remains the same IF (vStruct(i+1)%sumBG<=vStruct(i)%sumBG) THEN ! three subcases: ! first subcase of 'sumBG increases': sumBG stays below patchsize ! ( no BG modification) or does not change IF ((vStruct(i+1)%sumBG.LT.kpatchsize.AND.vStruct(i)%sumBG.LE.kpatchsize).OR.& vStruct(i+1)%sumBG == vStruct(i)%sumBG) THEN !until light model 4 restriction apply IF ( i <= lm3layer ) THEN ! At the beginning the light intensity of the pool remains the same ! but it will be updated when cohorts drop out Irelpool(i-1)=Irelpool(i) ! until there are cohorts dropping out BGpool(i)=MAX((kpatchsize-vStruct(i)%sumBG)/kpatchsize,0.) CALL L_3_COH_LOOP(i,1) ! FPAR in light model 3 defined differently has ! to be redefined here to cause no conflict in crown.f p => pt%first DO WHILE (ASSOCIATED(p)) p%coh%FPAR(i)=p%coh%totFPAR p => p%next END DO ! cohort loop1 ELSE CALL L_4_COH_LOOP(i,1,beta,y) END IF ! second and third subcase of 'sumBG increases or remains the same' ! the BG's of the cohorts change because sumBG exceeds patchsize. ! second subcase: sumBG was < patchsize before ! third subcase: sumBG was > patchsize before ELSE p => pt%first ! cohort loop 1 DO WHILE (ASSOCIATED(p)) ! calculate the new fraction covered by the pool ! which is the old pool plus the fractions which are lost ! by the old cohorts due to new BG's ! this also changes the light intensity of the pool ! consider only cohorts that have been there before (i<toplayer) ! consider only cohorts that have leafed out already, otherwise ! it may happen that help=0 IF (i<p%coh%toplayer.AND.i>=p%coh%botlayer .AND.& iday >= p%coh%day_bb .AND. iday <= spar(p%coh%species)%end_bb) THEN help=BGpool(i+1)+(p%coh%BG(i+1)-p%coh%BG(i))*p%coh%nTreeA if( help.ne.0) then Irelpool(i)=(1/help)*(Irelpool(i)*BGpool(i+1)+p%coh%Irel(i)*& (p%coh%BG(i+1)-p%coh%BG(i))*p%coh%nTreeA) BGpool(i+1)=help end if END IF ! layer test p => p%next END DO ! cohort loop1 !until light model 4 restriction apply IF ( i <= lm3layer ) THEN CALL L_3_COH_LOOP(i,1) ! FPAR in light model 3 defined differently has ! to be redefined here to cause no conflict in crown.f p => pt%first DO WHILE (ASSOCIATED(p)) p%coh%FPAR(i)=p%coh%totFPAR p => p%next END DO ! cohort loop1 ELSE CALL L_4_COH_LOOP(i,1,beta,y) END IF END IF ! subcases of 'sumBG increases ! second case: sumBG decreases ELSE ! two subcases ! first subcase of 'sumBG decrease': sumBG < patchsize before and after ! i.e. BG's do not change ! i.e. all projection area requirements can be fulfilled in the next layer IF (vStruct(i+1)%sumBG.LT.kpatchsize) THEN !until light model 4 restriction apply IF ( i <= lm3layer ) THEN ! At the beginning the light intensity of the pool remains the same ! but it will be updated when cohorts drop out Irelpool(i-1)=Irelpool(i) ! until there are cohorts dropping out BGpool(i)=(kpatchsize-vStruct(i)%sumBG)/kpatchsize CALL L_3_COH_LOOP(i,1) ! FPAR in light model 3 defined differently has ! to be redefined here to cause no conflict in crown.f p => pt%first DO WHILE (ASSOCIATED(p)) p%coh%FPAR(i)=p%coh%totFPAR p => p%next END DO ! cohort loop1 ELSE CALL L_4_COH_LOOP(i,1,beta,y) END IF ! second subcase of 'sumBG decrease': sumBG remains > patchsize or ! sumBG was > patchsize, i.e. BG's do increase ELSE !until light model 4 restriction apply IF ( i <= lm3layer ) THEN ! BG of the pool for the next layer as long as there are ! no cohorts dropping out BGpool(i)=MAX((kpatchsize-vStruct(i)%sumBG)/kpatchsize,0.) Irelpool(i-1)=Irelpool(i) CALL L_3_COH_LOOP(i,2) ! FPAR in light model 3 defined differently has ! to be redefined here to cause no conflict in crown.f p => pt%first DO WHILE (ASSOCIATED(p)) p%coh%FPAR(i)=p%coh%totFPAR p => p%next END DO ! cohort loop1 ELSE CALL L_4_COH_LOOP(i,2,beta,y) END IF END IF ! subcases END IF ! three main cases END DO ! end layer loop ! ----------------------------------------------------------- IF(all_leaves_on==1) THEN p => pt%first DO WHILE (ASSOCIATED(p)) p%coh%bes = 0. DO i = highest_layer, lowest_layer, -1 if(p%coh%totFPAR.ne.0) p%coh%antFPAR(i)=(p%coh%FPAR(i)-p%coh%FPAR(i+1))/p%coh%totFPAR p%coh%sleafarea(i)=p%coh%leafarea(i) ! besetting here weighted with relative leaf area in layer, could also be done with nimber of layers IF((vstruct(i)%sumBG > kpatchsize) .and. (p%coh%t_leaf .gt. zero)) p%coh%bes = p%coh%bes + p%coh%leafarea(i)/p%coh%t_leaf*(vstruct(i)%sumBG/kpatchsize) END DO ! end layer loop p => p%next END DO ! cohort loop ENDIF ! total LAI is simply the value of cumLAI at the lowest canopy layer LAI = vStruct(lowest_layer)%cumLAI IF(lai>laimax) laimax=lai ! light intensitiy and free patch space unto the ground DO i = lowest_layer - 2, 0, -1 Irelpool(i)=Irelpool(i+1) BGpool(i+1)=BGpool(i+2) END DO END SUBROUTINE LIGHT_4 END SUBROUTINE CANOPY !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ! writes essential light paramerter into light.res1 ! seperated to cohorts and layers SUBROUTINE LIGHT_OUT_2 use data_simul USE data_out USE data_stand USE data_species INTEGER:: i=0,j=0 TYPE(Coh_Obj), Pointer :: p ! pointer to cohort list ! Header write(unit_light,'(2A5,5A9)') 'YEAR ','layer ',' Coh1 ', & ' Coh2 ',' Coh3 ',' Coh4 ','...' p => pt%first WRITE(unit_light,'(i3,A)',ADVANCE='NO') time,' ' ! the crown cover area for cohorts DO WHILE (ASSOCIATED(p)) WRITE(unit_light,'(F8.2)',ADVANCE='NO') p%coh%crown_area p => p%next END DO WRITE(unit_light,'(A)') ' ' WRITE(unit_light,'(A)') '-----------------------------------------------------------------------' SELECT CASE (flag_light) CASE(3,4) DO i = highest_layer, lowest_layer, -1 IF(i.EQ.lm3layer) WRITE(unit_light,'(A)',ADVANCE='NO') 'ab hier LM3!' WRITE(unit_light,'(A,i3)',ADVANCE='NO') 'IREL ',i ! relativ light intensity that hits layers and cohorts p => pt%first DO j=1, anz_coh IF (p%coh%Irel(i) == 0.) THEN WRITE(unit_light,'(F8.2)',ADVANCE='NO') -99.99 ELSE WRITE(unit_light,'(F8.4)',ADVANCE='NO') p%coh%Irel(i) END IF p => p%next END DO WRITE(unit_light,'(A)') ' ' WRITE(unit_light,'(A,A7)',ADVANCE='NO') 'BG',' ' ! cover degree per cohort and layer p => pt%first DO j=1, anz_coh IF (p%coh%BG(i) == 0.) THEN WRITE(unit_light,'(F8.2)',ADVANCE='NO') -99.99 ELSE WRITE(unit_light,'(F8.4)',ADVANCE='NO') p%coh%BG(i) END IF p => p%next END DO WRITE(unit_light,'(A)') ' ' WRITE(unit_light,'(A,A5)',ADVANCE='NO') 'FPAR',' ' ! the fraction absorbed by corhort and layer p => pt%first DO j=1, anz_coh IF (p%coh%FPAR(i) == 0.) THEN WRITE(unit_light,'(F8.2)',ADVANCE='NO') -99.99 ELSE WRITE(unit_light,'(F8.4)',ADVANCE='NO') p%coh%FPAR(i) END IF p => p%next END DO WRITE(unit_light,'(A)') ' ' WRITE(unit_light,'(A,F8.4)') 'BGpool in dieser schicht :', BGpool(i) WRITE(unit_light,'(A,F8.4)') 'relative Ueberdeckung in dieser Schicht :', vStruct(i)%sumBG/kpatchsize WRITE(unit_light,'(A,F8.4)') 'Summer der Ueberdeckungen :', BGpool(i)+vStruct(i)%sumBG/kpatchsize WRITE(unit_light,'(A)') ' ' WRITE(unit_light,'(A,F8.4)') 'Rel. Licht unter dieser schicht :', VStruct(i)%Irel WRITE(unit_light,'(A,F8.4)') 'totFparsum bis zu dieser schicht :', VStruct(i)%radFrac WRITE(unit_light,'(A,F8.4)') ' Lichtbilanz : ', vStruct(i)%Irel+VStruct(i)%radFrac WRITE(unit_light,'(A)') ' ' WRITE(unit_light,'(A)') '-----------------------------------------------------------------------' END DO ! layers loop CASE(2) DO i = highest_layer, lowest_layer, -1 WRITE(unit_light,'(A,i3)',ADVANCE='NO') 'Irel ',i ! relative light intensity that hits the layer and cohorts DO j=1, anz_coh WRITE(unit_light,'(F8.4)',ADVANCE='NO') vStruct(i)%Irel END DO WRITE(unit_light,'(A)') ' ' ! cover degree per cohort and layers p => pt%first WRITE(unit_light,'(A,A7)',ADVANCE='NO') 'BG',' ' DO j=1, anz_coh IF (p%coh%BG(i) == 0.) THEN WRITE(unit_light,'(F8.2)',ADVANCE='NO') -99.99 ELSE WRITE(unit_light,'(F8.4)',ADVANCE='NO') p%coh%BG(i) END IF p => p%next END DO WRITE(unit_light,'(A)') ' ' WRITE(unit_light,'(A,A5)',ADVANCE='NO') 'FPAR',' ' ! fraction absorbed by cohort and layer p => pt%first DO j=1, anz_coh IF (p%coh%FPAR(i) == 0.) THEN WRITE(unit_light,'(F8.2)',ADVANCE='NO') -99.99 ELSE WRITE(unit_light,'(F8.4)',ADVANCE='NO') p%coh%FPAR(i) END IF p => p%next END DO WRITE(unit_light,'(A)') ' ' WRITE(unit_light,'(A)') '-----------------------------------------------------------------------' END DO CASE(1) DO i = highest_layer, lowest_layer, -1 WRITE(unit_light,'(A,i3)',ADVANCE='NO') 'IREL ',i ! relative light inensity that hits layers and cohorts DO j=1, anz_coh WRITE(unit_light,'(F8.4)',ADVANCE='NO') vStruct(i)%Irel END DO WRITE(unit_light,'(A)') ' ' WRITE(unit_light,'(A,A5)',ADVANCE='NO') 'FPAR',' ' ! fraction absirbed by cohort and layer p => pt%first DO j=1, anz_coh IF (p%coh%FPAR(i) == 0.) THEN WRITE(unit_light,'(F8.2)',ADVANCE='NO') -99.99 ELSE WRITE(unit_light,'(F8.4)',ADVANCE='NO') p%coh%FPAR(i) END IF p => p%next END DO WRITE(unit_light,'(A)') ' ' WRITE(unit_light,'(A)') '-----------------------------------------------------------------------' END DO END SELECT WRITE(unit_light,'(A,A2)',ADVANCE='NO') 'totFPAR',' ' p => pt%first DO j=1, anz_coh WRITE(unit_light,'(F8.5)',ADVANCE='NO') p%coh%totFPAR p => p%next END DO WRITE(unit_light,'(A)') ' ' WRITE(unit_light,'(A,F8.4)') 'Summe totFPAR : ',totFPARsum SELECT CASE(flag_light) CASE(3,4) WRITE(unit_light,'(A,F8.4)') 'Irel(lowest-1) : ', Irelpool(lowest_layer-1) WRITE(unit_light,'(A,F8.4)') ' Lichtbilanz : ', Irelpool(lowest_layer-1)+totFPARsum CASE(1,2) WRITE(unit_light,'(A,F8.4)') 'Irel(lowest-1) : ', vStruct(lowest_layer-1)%Irel WRITE(unit_light,'(A,F8.4)') ' Lichtbilanz : ', vStruct(lowest_layer-1)%Irel+totFPARsum END SELECT WRITE(unit_light,'(A)') ' ' WRITE(unit_light,'(A)') ' ' WRITE(unit_light,'(A)') ' ' WRITE(unit_light,'(A)') ' ' WRITE(unit_light,'(A)') '------------------------------------------------------------------------------------' WRITE(unit_light,'(A)') ' ' WRITE(unit_light,'(A)') ' ' END SUBROUTINE LIGHT_OUT_2 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! SUBROUTINE CROWN_PROJ ! Now calculate crown projection per tree and layer and ! the coverage sum over all layers !*** Declaration part ***! USE data_par USE data_species USE data_simul USE data_stand IMPLICIT NONE ! variables required for technical reasons INTEGER :: i real :: help, help1 TYPE(Coh_Obj), Pointer :: p ! pointer to cohort list vStruct%sumBG=0. p => pt%first DO WHILE (ASSOCIATED(p)) ns=p%coh%species ! SMALL TREES OR GROUND VEGETATION IF (p%coh%height.lt.thr_height .or. ns .eq. nspec_tree+1) THEN p%coh%crown_area = p%coh%t_leaf ! small trees or ground vegetation ELSEIF (p%coh%species.eq.nspec_tree+2) then ! Case mistletoe p%coh%crown_area=pi*(real(p%coh%nTreeA)*0.000475)**(0.6666) ! 1 big ball: volume = sum of mistletoe standard balls (10 years, pfiz 2000) ! V=4/3*Pi*r^3 , r= (3*V/4*PI)^1/3, (set V=n*4/3*Pi*512, with r=0.08 standard ball), r=(n*5.12*10-4)^1/3,A=pi*(n*5.12*10-4)^2/3 ELSE ! Formel nach Biber 1996 S. 121, Kronenradius [dm]= a*DBH [cm]+b help1 = MIN(spar(ns)%crown_c,spar(ns)%crown_a*(p%coh%diam)+spar(ns)%crown_b) help=PI*(help1)**2 ! adaptation of seedling crown projected area IF(p%coh%ca_ini.GT.help) THEN p%coh%crown_area=p%coh%ca_ini ELSE IF (p%coh%ca_ini.LT.help.AND.p%coh%diam == 0) THEN if(p%coh%height_ini.eq.137. .or. p%coh%height.eq.p%coh%height_ini) then p%coh%crown_area=p%coh%ca_ini else p%coh%crown_area=(p%coh%height-p%coh%height_ini)/(137.-p%coh%height_ini)*& (PI*(spar(ns)%crown_b)**2-p%coh%ca_ini)+p%coh%ca_ini end if ELSE p%coh%crown_area=help END IF END IF if(p%coh%crown_area.lt.0) then p%coh%crown_area = p%coh%ca_ini end if DO i=p%coh%topLayer,p%coh%botLayer,-1 vStruct(i)%sumBG=vStruct(i)%sumBG+p%coh%crown_area*p%coh%nTreeA END DO p => p%next END DO END SUBROUTINE CROWN_PROJ