Help:Sandkasten

From BlueM
Revision as of 08:02, 18 October 2006 by Froehlich (talk | contribs) (GeSHi Highlight Test)
Jump to navigation Jump to search

<fortran>

     MODULE MODBF

CXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX c c MODUL: BODENFEUCHTEBERECHNUNG c ============================= c Systemzustände: [letzter Zeitschritt wird gespeichert] c Extern: c Intern: - c Attribute: CXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

     USE MODCON
     IMPLICIT none

! ------------------------------------------------------------- ! ----------------------- Oeffentlicher Teil ------------------ ! -------------------------------------------------------------

! --- Konstanten -> const.for ! --- Datentypen -> types.for ! --- Variablen ---

     LOGICAL  :: BF_error
     LOGICAL  :: BF_warn

! ------------------------------------------------------------- ! ----------------------- Privater Teil ----------------------- ! -------------------------------------------------------------

! --- Konstanten -> const.for

     REAL, PARAMETER, PRIVATE    :: BF_MODUL_VERSION = 1.0

c Berechnungskonstanten

     REAL,    PARAMETER, PRIVATE :: BF_MAX_BILERR  = 0.01
     REAL,    PARAMETER, PRIVATE :: BF_DELTARATE   = 0.001
     REAL,    PARAMETER, PRIVATE :: BF_DELTAX      = 0.5
     REAL,    PARAMETER, PRIVATE :: BF_XMAX_FAKTOR = 1.0 + BF_DELTAX
     REAL,    PARAMETER, PRIVATE :: BF_YMAX_FAKTOR = FKT_MGRENZ *
    +                                                BF_DELTAX

c Prozessfunktionen, Funktionsverläufe:

     INTEGER, PARAMETER, PRIVATE :: BF_MAXSTZ     = MAXSTZ         !maximale Stuetzstellenzahl einer Funktion
     INTEGER, PARAMETER, PRIVATE :: BF_STZ_START  = 2              !Beginn der richtigen Funktionsverläufe
     INTEGER, PARAMETER, PRIVATE :: BF_STZ_REST   = 2              !Restliche Stützstellen nach Ende der richtigen Funktionsverläufe
     INTEGER, PARAMETER, PRIVATE :: BF_FKTSTZ     = BF_MAXSTZ      !Anzahl Stützstellen für Funktionsverläufe
    +                                             - BF_STZ_START+1
    +                                             - BF_STZ_REST
     REAL(KIND=8), PARAMETER, PRIVATE :: BF_LAST_YWERT = 0.0       !letzter (normierter) Y-Wert aller Funktionen

c Bodenaufbau / -Schichten: Anzahl, ID, Mindestdicken

     INTEGER, PARAMETER, PRIVATE :: BF_MAX_SCHICHTEN = 6
     INTEGER, PARAMETER, PRIVATE :: BOD_InfSchichtID  = 1
     INTEGER, PARAMETER, PRIVATE :: BOD_WESchichtID   = 2
     INTEGER, PARAMETER, PRIVATE :: BOD_TRSSchichtID  = 3
     REAL, PARAMETER, PRIVATE    :: BOD_dInfSchicht   = 0.2
     REAL, PARAMETER, PRIVATE    :: BOD_minD_WESchicht = 0.05
     REAL, PARAMETER, PRIVATE    :: BOD_minD_TRSSchicht = 0.05
     REAL, PARAMETER, PRIVATE    :: BOD_minDicke =  BOD_dInfSchicht +
    +                                            BOD_mind_WESchicht +
    +                                            BOD_mind_TRSSchicht
     ! Bodenarten
     INTEGER, PARAMETER, PRIVATE :: BF_ANZ_BOART  = 3
     INTEGER, PARAMETER, PRIVATE :: BF_TypSand    = 1
     INTEGER, PARAMETER, PRIVATE :: BF_TypSchluff = 2
     INTEGER, PARAMETER, PRIVATE :: BF_TypTon     = 3
     ! Bodenphysikalische Prozesse: Anzahl, ID, Bezeichnung, Vorzeichen, Berechnungskonstanten
     INTEGER, PARAMETER, PRIVATE :: BF_ANZ_FKT  = 6 + 1         !6 Bodenprozesse + 1 Funktion fuer Überlauf = Oberflächenabfluss oder Rückstau
     INTEGER, PARAMETER, PRIVATE :: BF_ANZ_DGL  = 5
     INTEGER, PARAMETER, PRIVATE :: BF_LEN_FKTNAME = 6
     ! Bezug zu WP, FK, nFK, GPV ...
     INTEGER, PARAMETER, PRIVATE :: BF_ANZ_BEZUG  = 5
     INTEGER, PARAMETER, PRIVATE :: wpBF  = 1
     INTEGER, PARAMETER, PRIVATE :: fkBF  = 2
     INTEGER, PARAMETER, PRIVATE :: nfkBF = 3
     INTEGER, PARAMETER, PRIVATE :: gpvBF = 4
     INTEGER, PARAMETER, PRIVATE :: lkBF  = 5
     ! ID der Prozesse
     INTEGER, PARAMETER, PRIVATE :: BF_ConstID  = 0             !Konstanter Funktionsverlauf
     INTEGER, PARAMETER, PRIVATE :: BF_InfID    = 1             !Infiltration
     INTEGER, PARAMETER, PRIVATE :: BF_ExxID    = 2             !Exfiltration / Perkolation
     INTEGER, PARAMETER, PRIVATE :: BF_IntID    = 3             !Interflow
     INTEGER, PARAMETER, PRIVATE :: BF_KapID    = 4             !Kapillar Aufstieg
     INTEGER, PARAMETER, PRIVATE :: BF_EvaID    = 5             !Evaporation
     INTEGER, PARAMETER, PRIVATE :: BF_EtaID    = 6             !Transpiration
     INTEGER, PARAMETER, PRIVATE :: BF_MaxID    = 7             !Überlauffunktion wenn Bodenschicht voll ist
     INTEGER, PARAMETER, PRIVATE :: BF_ZInID    = 7             !Zufluss Interflow (wird nicht benutzt, nur bei RASTER)
     ! Vorzeichen
     REAL, PARAMETER, PRIVATE    :: BF_InfVorz  = 1.0
     REAL, PARAMETER, PRIVATE    :: BF_ExxVorz  = -1.0
     REAL, PARAMETER, PRIVATE    :: BF_IntVorz  = -1.0
     REAL, PARAMETER, PRIVATE    :: BF_KapVorz  = 1.0
     REAL, PARAMETER, PRIVATE    :: BF_EvaVorz  = -1.0
     REAL, PARAMETER, PRIVATE    :: BF_EtaVorz  = -1.0
     REAL, PARAMETER, PRIVATE    :: BF_MaxVorz  = -1.0
     REAL, PARAMETER, PRIVATE    :: BF_ZInVorz  = -1.0
     ! Verdunstungsansätze
     REAL, PARAMETER, PRIVATE    :: LNZ_HAUDEFAK_CONST  = 0.135  !Faktor für unbewachsenen Boden
     INTEGER, PARAMETER, PRIVATE :: EVA_HaudeID   = 1
     INTEGER, PARAMETER, PRIVATE :: EVA_BelmansID = 2
     INTEGER, PARAMETER, PRIVATE :: EVA_PotentiellID = 3
     INTEGER, PARAMETER, PRIVATE :: ETP_LinearID  = 1
     INTEGER, PARAMETER, PRIVATE :: ETP_AlbertID  = 2

! --- Datentypen --- c Bodenart

     TYPE BOA_type
        REAL     WP,
    +            FK,
    +            GPV,
    +            KF,
    +            MAXINF,
    +            MAXKAP
        INTEGER  BOAID,
    +            BOART
     END TYPE
     TYPE BOA_ptr_type
        TYPE (BOA_type), POINTER :: ptrboa
     END TYPE
     TYPE (BOA_ptr_type),DIMENSION(:),ALLOCATABLE,PRIVATE :: BOACONT

c Bodentyp

     TYPE BOD_type
        REAL     Dicke(BF_MAX_SCHICHTEN)
        INTEGER  BODID,
    +            NBOA,
    +            BoaID(BF_MAX_SCHICHTEN)
     END TYPE
     TYPE BOD_ptr_type
        TYPE (BOD_type), POINTER :: ptrbod
     END TYPE
     TYPE (BOD_ptr_type),DIMENSION(:),ALLOCATABLE,PRIVATE :: BODCONT

c Landnutzung

     TYPE LNZ_type
        REAL     HaudeFak(ANZMONATE),
    +            WE,
    +            BG,
    +            BFI,
    +            VG,
    +            KST
        INTEGER  LNZID,
    +            BGJGG,
    +            BFIJGG,
    +            HaudeFakJGG
     END TYPE
     TYPE LNZ_ptr_type
        TYPE (LNZ_type), POINTER :: ptrlnz
     END TYPE
     TYPE (LNZ_ptr_type),DIMENSION(:),ALLOCATABLE,PRIVATE :: LNZCONT

! --- Variablen ---

     LOGICAL, PRIVATE                                   :: DLL_MODE
     LOGICAL, PRIVATE                                   :: BF_INIT
     INTEGER, PRIVATE                                   :: BOD_anz
     INTEGER, PRIVATE                                   :: BOD_aktanz
     INTEGER, DIMENSION(:), ALLOCATABLE, PRIVATE        :: BOD_ID
     INTEGER, PRIVATE                                   :: BOA_anz
     INTEGER, PRIVATE                                   :: BOA_aktanz
     INTEGER, DIMENSION(:), ALLOCATABLE, PRIVATE        :: BOA_ID
     INTEGER, PRIVATE                                   :: LNZ_anz
     INTEGER, PRIVATE                                   :: LNZ_aktanz
     INTEGER, DIMENSION(:), ALLOCATABLE, PRIVATE        :: LNZ_ID
     !Start- Endepositionen Funktionsverläufe, Prozessnamen
     REAL, DIMENSION(BF_ANZ_FKT),PRIVATE              :: BF_VORZEICHEN
     REAL, DIMENSION(BF_ANZ_FKT, BF_ANZ_BOART),
    +      PRIVATE :: BF_FKT_StartX
     REAL, DIMENSION(BF_ANZ_FKT, BF_ANZ_BOART),
    +      PRIVATE :: BF_FKT_StartY
     REAL, DIMENSION(BF_ANZ_FKT, BF_ANZ_BOART),
    +      PRIVATE :: BF_FKT_EndeX
     REAL, DIMENSION(BF_ANZ_FKT, BF_ANZ_BOART),
    +      PRIVATE :: BF_FKT_EndeY
     REAL, DIMENSION(BF_ANZ_FKT, BF_ANZ_BOART),
    +      PRIVATE :: BF_FKT_EXPO
     INTEGER, DIMENSION(BF_ANZ_FKT, BF_ANZ_BOART),
    +         PRIVATE :: BF_FKT_StartBezug
     INTEGER, DIMENSION(BF_ANZ_FKT, BF_ANZ_BOART),
    +         PRIVATE :: BF_FKT_EndeBezug
     CHARACTER(LEN=BF_LEN_FKTNAME), DIMENSION(BF_ANZ_FKT),
    +         PRIVATE :: BF_FKTNAME

c Verdunstunsfaktoren

     REAL, DIMENSION (ANZMONATE) :: LNZ_HAUDEFAK_GRAS

! --- Inits ---

     DATA  BF_error     / .FALSE. /
     DATA  BF_warn      / .FALSE. /
     DATA  DLL_MODE     / .FALSE. /
     DATA  BF_INIT      / .FALSE. /
     DATA  BOD_anz      / 0 /
     DATA  BOD_aktanz   / 0 /
     DATA  BOA_anz      / 0 /
     DATA  BOA_aktanz   / 0 /
     DATA  LNZ_anz      / 0 /
     DATA  LNZ_aktanz   / 0 /

! ------------------------------------------------------------- ! ----------------------- Methoden ---------------------------- ! -------------------------------------------------------------

     CONTAINS

CXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX c Festlegen des Modus: DLL_MODE=false => Aufruf unter DOS c DLL_MODE=true => Aufruf unter WinNT c DLL - Statement

     SUBROUTINE BF_MODE (MODE)

c .................................................................

     LOGICAL  :: MODE

c .................................................................

     DLL_MODE = MODE

c ................................................................. 10000 RETURN

     END SUBROUTINE  BF_MODE

cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

CXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX c Initialisiere die Funktionswerte fuer die Bodenfeuchtesimulation c DLL - Statement

     SUBROUTINE BF_FKT_INI (LWRITE)

c .................................................................

     LOGICAL  :: LWRITE

c ................................................................. C -- Parameter fuer Funktionsermittlung sind wie folgende Matrix zu lesen C -- (negative Zahl deutet an: Eintrag wird nicht benutzt) C | infil, exfil, inter, kapauf, evap, transp, Überlauf c -----|--------------------------------------------------- C Sand | C Lehm | C Ton | c .................................................................

     BF_INIT = .TRUE.

c Startwerte der einzelnen Prozesse in Bezug auf Bodenfeuchte c Änderung (HL, 11.03.2000): Wegen zu geringer Verdunstung aus Infil-Schicht c Original: evap = 1.0 wpBF fuer alle Zeilen

     BF_FKT_StartX =
    +  RESHAPE (
    +       (/0.1, 0.40, 0.40, 1.0, 0.9, 0.01, 1.0,
    +         0.1, 0.70, 0.70, 1.0, 0.9, 0.01, 1.0,
    +         0.1, 0.75, 0.75, 1.0, 0.9, 0.01, 1.0  /),
    +       (/BF_ANZ_FKT, BF_ANZ_BOART/))

c Bezug für die Startwerte der einzelnen Prozesse

     BF_FKT_StartBezug =
    +  RESHAPE (
    +      (/ nfkBF, nfkBF, nfkBF, wpBF, wpBF, nfkBF, gpvBF,
    +         nfkBF, nfkBF, nfkBF, wpBF, wpBF, nfkBF, gpvBF,
    +         nfkBF, nfkBF, nfkBF, wpBF, wpBF, nfkBF, gpvBF  /),
    +       (/BF_ANZ_FKT, BF_ANZ_BOART/))

c Endwerte der einzelnen Prozesse in Bezug auf Bodenfeuchte c Änderung (HL, 11.03.2000): Wegen zu geringer Verdunstung aus Infil-Schicht c Original: evap = 0.9 nfkBF fuer alle Zeilen

     BF_FKT_EndeX =
    +  RESHAPE (
    +      (/ 1.0, 0.70, 0.70, 0.40, 1.0, 1.0, BF_XMAX_FAKTOR,
    +         1.0, 0.83, 0.90, 0.70, 1.0, 1.0, BF_XMAX_FAKTOR,
    +         1.0, 0.85, 0.90, 0.75, 1.0, 1.0, BF_XMAX_FAKTOR  /),
    +       (/BF_ANZ_FKT, BF_ANZ_BOART/))

c Bezug der Endwerte der einzelnen Prozesse

     BF_FKT_EndeBezug =
    +  RESHAPE (
    +      (/ gpvBF, nfkBF, nfkBF, nfkBF, wpBF, fkBF, gpvBF,
    +         gpvBF, nfkBF, nfkBF, nfkBF, wpBF, fkBF, gpvBF,
    +         gpvBF, nfkBF, nfkBF, nfkBF, wpBF, fkBF, gpvBF  /),
    +       (/BF_ANZ_FKT, BF_ANZ_BOART/))

c Funktionswerte der einzelnen Prozesse

     BF_FKT_StartY =
    +  RESHAPE (
    +       (/1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0,
    +         1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0,
    +         1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0  /),
    +       (/BF_ANZ_FKT, BF_ANZ_BOART/))

c Funktionswerte der einzelnen Prozesse

     BF_FKT_EndeY =
    +  RESHAPE (
    +       (/0.0, 1.0, 1.0, 0.0, 1.0, 1.0, 1.0,
    +         0.0, 1.0, 1.0, 0.0, 1.0, 1.0, 1.0,
    +         0.0, 1.0, 1.0, 0.0, 1.0, 1.0, 1.0  /),
    +       (/BF_ANZ_FKT, BF_ANZ_BOART/))
     BF_FKT_Expo =
    +  RESHAPE (
    +      (/ 1.4, 3.0, 2.0, -1.0, 1.0, 1.0, 1.0,
    +         1.4, 7.0, 7.0, -1.0, 1.0, 1.0, 1.0,
    +         1.4, 9.0, 7.0, -1.0, 1.0, 1.0, 1.0  /),
    +       (/BF_ANZ_FKT, BF_ANZ_BOART/))
     BF_FKTNAME =
    +  RESHAPE (
    +       (/ ' Infil', ' Exfil', ' Inter', 'KapAuf', '  Evap',
    +          'Transp', 'Overfl' /),
    +       (/ BF_ANZ_FKT /) )
     LNZ_HAUDEFAK_GRAS =
    +  RESHAPE (
    +       (/ 0.2025, 0.2025,   0.21, 0.2925, 0.2925, 0.2775,
    +          0.2625, 0.2475, 0.2325, 0.2175, 0.2025, 0.2025 /),
    +       (/ANZMONATE/) )
     BF_VORZEICHEN =
    +  RESHAPE (
    +       (/ BF_InfVorz, BF_ExxVorz, BF_IntVorz, BF_KapVorz,
    +          BF_EvaVorz, BF_EtaVorz, BF_MaxVorz  /),
    +       (/BF_ANZ_FKT/) )

c Testausgabe fuer Bodenfeuchteberechnung vorbereiten 100 FORMAT(1X, A3, A5, 100(A15))

     LBFOUT = LWRITE
     IF (LBFOUT) CALL BF_OPENFILE(datTSTBF)
     GOTO 10000

c ................................................................. c ................................................................. 10000 RETURN

     END SUBROUTINE BF_FKT_INI

cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

CXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX c Initialisiere das Modul fuer die Bodenarten c DLL - Statement

     FUNCTION BOA_INI (ANZAHL) RESULT (LOK)

c .................................................................

     USE MODERR
     INTEGER  :: ANZAHL, i, alloc
     LOGICAL  :: LOK

c .................................................................

     LOK = .FALSE.
     BOA_anz = ANZAHL

c Speicherallokierung und Fehlercheck

     ALLOCATE (BOACONT(BOA_anz), STAT=alloc)
     IF (alloc > 0) GOTO 9999
     ALLOCATE (BOA_ID(BOA_anz), STAT=alloc)
     IF (alloc > 0) GOTO 9999

c Kennzeichne vor dem Einlesen alle Eintraege als "unbesetzt"

     DO i = 1, BOA_anz
        NULLIFY (BOACONT(i) % ptrboa)
        BOA_ID (i) = 0
     END DO
     LOK = .TRUE.
     GOTO 10000

c ................................................................. c Fehlerbehandlung 9999 If (.NOT. DLL_MODE) BF_error = FEHLER(50, 'BOA ', ' ', 0)

     Goto 10000

c ................................................................. 10000 RETURN

     END FUNCTION BOA_INI

cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

CXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX c Initialisiere das Modul fuer die Bodentypen c DLL - Statement

     FUNCTION BOD_INI (ANZAHL) RESULT (LOK)

c .................................................................

     USE MODERR
     INTEGER  :: ANZAHL, i, alloc
     LOGICAL  :: LOK

c .................................................................

     LOK = .FALSE.
     BOD_anz = ANZAHL

c Speicherallokierung und Fehlercheck

     ALLOCATE (BODCONT(BOD_anz), STAT=alloc)
     IF (alloc > 0) GOTO 9999
     ALLOCATE (BOD_ID(BOD_anz), STAT=alloc)
     IF (alloc > 0) GOTO 9999

c Kennzeichne vor dem Einlesen alle Eintraege als "unbesetzt"

     DO i = 1, BOD_anz
        NULLIFY (BODCONT(i) % ptrbod)
        BOD_ID (i) = 0
     END DO
     LOK = .TRUE.
     GOTO 10000

c ................................................................. c Fehlerbehandlung 9999 If (.NOT. DLL_MODE) BF_error = FEHLER(50, 'BOD ', ' ', 0)

     Goto 10000

c ................................................................. 10000 RETURN

     END FUNCTION BOD_INI

cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

CXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX c Initialisiere das Modul fuer die Landnutzungen c DLL - Statement

     FUNCTION LNZ_INI (ANZAHL) RESULT (LOK)

c .................................................................

     USE MODERR
     INTEGER  :: ANZAHL, i, alloc
     LOGICAL  :: LOK

c .................................................................

     LOK = .FALSE.
     LNZ_anz = ANZAHL

c Speicherallokierung und Fehlercheck

     ALLOCATE (LNZCONT(LNZ_anz), STAT=alloc)
     IF (alloc > 0) GOTO 9999
     ALLOCATE (LNZ_ID(LNZ_anz), STAT=alloc)
     IF (alloc > 0) GOTO 9999

c Kennzeichne vor dem Einlesen alle Eintraege als "unbesetzt"

     DO i = 1, LNZ_anz
        NULLIFY (LNZCONT(i) % ptrlnz)
        LNZ_ID (i) = 0
     END DO
     LOK = .TRUE.
     GOTO 10000

c ................................................................. c Fehlerbehandlung 9999 If (.NOT. DLL_MODE) BF_error = FEHLER(50, 'LNZ ', ' ', 0)

     Goto 10000

c ................................................................. 10000 RETURN

     END FUNCTION LNZ_INI

cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

CXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX c Die naechste freie ID ermitteln c DLL - Statement

     FUNCTION BOA_CREATE() RESULT (ID)

c .................................................................

     USE MODERR
     INTEGER  :: ID, i, itmp

c .................................................................

     ID = 0
     DO i = 1, BOA_anz
        IF (BOA_ID(i).EQ.0) THEN
           itmp = i
           GOTO 80
      END IF
     END DO
     If (.NOT. DLL_MODE)
    +   BF_error = FEHLER (50, 'BOA ', '    ', BOA_anz)
     GOTO 10000

80 BOA_ID(itmp) = itmp

     ID = itmp
     GOTO 10000

c ................................................................. 10000 RETURN

     END FUNCTION BOA_CREATE

cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

CXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX c Die naechste freie ID ermitteln c DLL - Statement

     FUNCTION BOD_CREATE() RESULT (ID)

c .................................................................

     USE MODERR
     INTEGER  :: ID, i, itmp

c .................................................................

     ID = 0
     DO i = 1, BOD_anz
        IF (BOD_ID(i).EQ.0) THEN
           itmp = i
           GOTO 80
      END IF
     END DO
     If (.NOT. DLL_MODE)
    +   BF_error = FEHLER (50, 'BOD ', '    ', BOD_anz)
     GOTO 10000

80 BOD_ID(itmp) = itmp

     ID = itmp
     GOTO 10000

c ................................................................. 10000 RETURN

     END FUNCTION BOD_CREATE

cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

CXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX c Die naechste freie ID ermitteln c DLL - Statement

     FUNCTION LNZ_CREATE() RESULT (ID)

c .................................................................

     USE MODERR
     INTEGER  :: ID, i, itmp

c .................................................................

     ID = 0
     DO i = 1, LNZ_anz
        IF (LNZ_ID(i).EQ.0) THEN
           itmp = i
           GOTO 80
      END IF
     END DO
     If (.NOT. DLL_MODE)
    +   BF_error = FEHLER (50, 'LNZ ', '    ', LNZ_anz)
     GOTO 10000

80 LNZ_ID(itmp) = itmp

     ID = itmp
     GOTO 10000

c ................................................................. 10000 RETURN

     END FUNCTION LNZ_CREATE

cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

CXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX C Neue Bodenart einrichten c DLL - Statement

     FUNCTION BOA_NEU (ID, BOAID, BodenArt, WP, FK, GPV, KF,
    +                  MAXINF, MAXKAP)
    +RESULT (LOK)

c .................................................................

     USE MODERR
     TYPE (BOA_type), POINTER   :: objptr
     REAL     :: WP, FK, GPV, KF, MAXINF, MAXKAP
     INTEGER  :: ID, BOAID, BodenArt, alloc
     LOGICAL  :: LOK

c .................................................................

     LOK = .FALSE.

C Neue Bodenart einrichten

     ALLOCATE (objptr, STAT=alloc)
     IF (alloc > 0) THEN
        If (.NOT. DLL_MODE) BF_error = FEHLER (50, 'BOA ', '    ', 0)
        GOTO 10000
     END IF
     BOACONT(ID) % ptrboa  => objptr
     BOA_aktanz = BOA_aktanz + 1
     objptr % BOAID = BOAID
     objptr % BOART = BodenArt
     objptr % WP = WP
     objptr % FK = FK
     objptr % GPV = GPV
     objptr % KF = KF
     objptr % MAXINF = MAXINF
     objptr % MAXKAP = MAXKAP
     LOK = .TRUE.
     Goto 10000

c ................................................................. 10000 RETURN

     END FUNCTION BOA_NEU

cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

CXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX C Neuer Bodentyp einrichten c DLL - Statement

     FUNCTION BOD_NEU (ID, BODID, NBOA, D, BoaID) RESULT (LOK)

c .................................................................

     USE MODERR
     TYPE (BOD_type), POINTER   :: objptr
     INTEGER  :: ID, BODID, NBOA, i, alloc
     INTEGER  :: BoaID(NBOA)
     REAL     :: D(NBOA)
     LOGICAL  :: LOK

c .................................................................

     LOK = .FALSE.

C Neuer Bodentyp einrichten

     ALLOCATE (objptr, STAT=alloc)
     IF (alloc > 0) THEN
        If (.NOT. DLL_MODE) BF_error = FEHLER (50, 'BOD ', '    ', 0)
        GOTO 10000
     END IF
     BODCONT(ID) % ptrbod  => objptr
     BOD_aktanz = BOD_aktanz + 1
     objptr % BODID = BODID
     objptr % NBOA = NBOA
     DO i=1,NBOA
        objptr % Dicke(i) = D(i)
        objptr % BoaID(i) = BoaID(i)
     END DO
     DO i=NBOA+1,BF_MAX_SCHICHTEN
        objptr % Dicke(i) = 0.0
        objptr % BoaID(i) = 0
     END DO
     LOK = .TRUE.
     Goto 10000

c ................................................................. 10000 RETURN

     END FUNCTION BOD_NEU

cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

CXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX C Neue Landnutzung einrichten c DLL - Statement

     FUNCTION LNZ_NEU (ID, LNZID, WE, BG, BGJGG, BFI, BFIJGG,
    +                  VG, Kst, HaudeFakJGG, HaudeFak)
    +RESULT (LOK)

c .................................................................

     USE MODERR
     USE MODGGL
     TYPE (LNZ_type), POINTER   :: objptr
     REAL     :: WE, BG, BFI, VG, Kst, HaudeFak(ANZMONATE)
     INTEGER  :: ID, LNZID, BGJGG, BFIJGG, HaudeFakJGG, i, alloc
     LOGICAL  :: LOK

c .................................................................

     LOK = .FALSE.

C Neue Landnutzung einrichten

     ALLOCATE (objptr, STAT=alloc)
     IF (alloc > 0) THEN
        If (.NOT. DLL_MODE) BF_error = FEHLER (50, 'LNZ ', '    ', 0)
        GOTO 10000
     END IF
     LNZCONT(ID) % ptrlnz  => objptr
     LNZ_aktanz = LNZ_aktanz + 1
     objptr % LNZID = LNZID
     objptr % WE = WE
     objptr % BG = BG
     objptr % BGJGG = BGJGG
     objptr % BFI = BFI
     objptr % BFIJGG = BFIJGG
     objptr % VG = VG
     IF (Kst.LE.0.0) THEN
        objptr % Kst = 7.
     ELSE
        objptr % Kst = Kst
     END IF
     objptr % HaudeFakJGG = HaudeFakJGG
     DO i=1,ANZMONATE
        objptr % HaudeFak(i) = HaudeFak(i)
     END DO

c Die Haudefaktoren sind optional, setze die Faktoren von Gras, falls Blank oder 0:

     IF (ALL(HaudeFak .LE. 0.0)) THEN
        objptr % HaudeFak = LNZ_HAUDEFAK_GRAS
     ELSE
        objptr % HaudeFak = HaudeFak
     END IF
     LOK = .TRUE.
     Goto 10000

c ................................................................. 10000 RETURN

     END FUNCTION LNZ_NEU

cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

CXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX C Anzahl der Bodenarten lesen

     FUNCTION BOA_ANZAHL (datnr) RESULT (N)

c .................................................................

     INTEGER  :: datnr, BoaID, N
     CHARACTER (LEN=1) :: c

c .................................................................

     N = 0

c ================================================================= C Anzahl der BOA-Elemente c =================================================================

 100 FORMAT(A1, 2X, I4)
  50 READ(datnr, 100, ERR=50, END=10000) c, BoaID
     IF (c.EQ.cKOMMENTAR) GOTO 50
     IF (BoaID.EQ.0) GOTO 50
     N = N + 1
     GOTO 50

c ................................................................. 10000 REWIND(datnr)

     RETURN
     END FUNCTION BOA_ANZAHL

cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

CXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX C Anzahl der Bodentypen lesen

     FUNCTION BOD_ANZAHL (datnr) RESULT (N)

c .................................................................

     INTEGER  :: datnr, BodID, N
     CHARACTER (LEN=1) :: c

c .................................................................

     N = 0

c ================================================================= C Anzahl der BOD-Elemente c =================================================================

 100 FORMAT(A1, 2X, I4)
  50 READ(datnr, 100, ERR=50, END=10000) c, BodID
     IF (c.EQ.cKOMMENTAR) GOTO 50
     IF (BodID.EQ.0) GOTO 50
     N = N + 1
     GOTO 50

c ................................................................. 10000 REWIND(datnr)

     RETURN
     END FUNCTION BOD_ANZAHL

cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

CXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX C Anzahl der Landnutzungen lesen

     FUNCTION LNZ_ANZAHL (datnr) RESULT (N)

c .................................................................

     INTEGER  :: datnr, LnzID, N
     CHARACTER (LEN=1) :: c

c .................................................................

     N = 0

c ================================================================= C Anzahl der LNZ-Elemente c =================================================================

 100 FORMAT(A1, 2X, I4)
  50 READ(datnr, 100, ERR=50, END=10000) c, LnzID
     IF (c.EQ.cKOMMENTAR) GOTO 50
     IF (LnzID.EQ.0) GOTO 50
     N = N + 1
     GOTO 50

c ................................................................. 10000 REWIND(datnr)

     RETURN
     END FUNCTION LNZ_ANZAHL

cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

CXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX c Bodenarten lesen

     FUNCTION BOA_SYS (datnr, KNTRLL, LWARN)
    +RESULT (LOK)

c .................................................................

     USE MODERR
     REAL                :: WP, FK, GPV, KF, MAXINF, MAXKAP
     INTEGER             :: ID, datnr, BoaID, BodTyp
     LOGICAL             :: LOK, LTMP, KNTRLL, LWARN
     CHARACTER (LEN = 1) :: ctmp

c .................................................................

     LOK = .FALSE.

c ================================================================= C Lesen des aktuellen Zeile c =================================================================

 100 FORMAT(A1, 2X, I4, 3X, I1, 6(1X,F6.0))
  50 READ(datnr, 100, ERR=50, END=9000) ctmp,
    +    BoaID, BodTyp, WP, FK, GPV, KF, MAXINF, MAXKAP
     IF (ctmp.EQ.cKOMMENTAR) GOTO 50

c ================================================================= C Pruefung der Kenngroessen c ================================================================= c ID-Kontrolle c ============

     IF (BoaID.LT.1) KNTRLL = FEHLER (3300, 'BOA ', 'BOA ', BoaID)

C Bodenart-Typ-Kontrolle C ======================

     IF (BodTyp.LT.BF_TypSand .OR. BodTyp.GT.BF_TypTon)
    +   KNTRLL = FEHLER (3301, 'BOA ', 'BOA ', BoaID)

C Zulässige Werte C ===============

     IF (WP.LE.NULL)
    +   KNTRLL = FEHLER (3302, 'WP  ', '    ', BoaID)
     IF (FK.LE.NULL)
    +   KNTRLL = FEHLER (3302, 'FK  ', '    ', BoaID)
     IF (GPV.LE.NULL)
    +   KNTRLL = FEHLER (3302, 'GPV ', '    ', BoaID)
     IF (KF.LE.NULL)
    +   KNTRLL = FEHLER (3302, 'KF  ', '    ', BoaID)
     IF (MAXINF.LE.NULL)
    +   KNTRLL = FEHLER (3302, 'INF ', '    ', BoaID)

c IF (MAXKAP.LT.NULL) c + KNTRLL = FEHLER (3302, 'KAP ', ' ', BoaID)

C Richtige Groessen C =================

     IF (WP.GE.FK)
    +   KNTRLL = FEHLER (3303, 'WP  ', 'FK  ', BoaID)
     IF (FK.GE.GPV)
    +   KNTRLL = FEHLER (3303, 'FK  ', 'GPV ', BoaID)
     IF (KF.GE.MAXINF)
    +   KNTRLL = FEHLER (3303, 'KF  ', 'INF ', BoaID)
     IF (KNTRLL) GOTO 10000

c ================================================================== C Neue Bodenart einrichten c ================================================================== c DLL - Statement

     ID = BOA_CREATE()
     IF (ID.EQ.0) GOTO 10000

c DLL - Statement

     LTMP = BOA_NEU (ID, BOAID, BodTyp, WP, FK, GPV, KF,
    +                MAXINF, MAXKAP)
     IF (.NOT.LTMP) GOTO 10000
     IF (KNTRLL) GOTO 10000
     GOTO 50

9000 LOK = .TRUE.

     Goto 10000

c ................................................................. 10000 REWIND datnr

     RETURN
     END FUNCTION BOA_SYS

cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

CXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX c Bodentypen lesen

     FUNCTION BOD_SYS (datnr, KNTRLL, LWARN)
    +RESULT (LOK)

c .................................................................

     USE MODERR
     REAL                :: D(BF_MAX_SCHICHTEN), SummeD
     INTEGER             :: ID, datnr, BodID, NBOA,
    +                       BoaID(BF_MAX_SCHICHTEN), i
     LOGICAL             :: LOK, LTMP, KNTRLL, LWARN
     CHARACTER (LEN = 1) :: ctmp

c .................................................................

     LOK = .FALSE.

c ================================================================= C Lesen des aktuellen Zeile c =================================================================

 100 FORMAT(A1, 2X, I4, 3X, I3, 1X, 6(1X,F4.0,1X,I4))
  50 READ(datnr, 100, ERR=50, END=9000) ctmp,
    +    BodID, NBoa, (D(i), BoaID(i), i=1,BF_MAX_SCHICHTEN)
     IF (ctmp.EQ.cKOMMENTAR) GOTO 50

c ================================================================= C Pruefung der Kenngroessen c ================================================================= c ID-Kontrolle c ============

     IF (BodID.LT.1) KNTRLL = FEHLER (3310, 'BOD ', '    ', BodID)

C Zulässige Werte C ===============

     SummeD = 0.
     IF (NBOA.LT.1 .OR. NBOA.GT.BF_MAX_SCHICHTEN)
    +   KNTRLL = FEHLER (3311, 'BOD ', '    ', BodID)
     DO i=1,NBOA
        IF (D(i).LE.NULL)
    +      KNTRLL = FEHLER (3312, 'D   ', '    ', BodID)
        LTMP = BOA_CHECK_ID(BoaID(i))
        IF (.NOT.LTMP)
    +      KNTRLL = FEHLER (3313, '    ', '    ', BodID)
        SummeD = SummeD + D(i)
     END DO

C Bodendicke c ==========

     IF (SummeD.LE.BOD_minDicke)
    +   KNTRLL = FEHLER (3314, '    ', '    ', BodID)
     IF (KNTRLL) GOTO 10000

c ================================================================== C Neuer Bodentyp einrichten c ================================================================== c DLL - Statement

     ID = BOD_CREATE()
     IF (ID.EQ.0) GOTO 10000

c DLL - Statement

     LTMP = BOD_NEU (ID, BODID, NBOA, D, BoaID)
     IF (.NOT.LTMP) GOTO 10000
     IF (KNTRLL) GOTO 10000
     GOTO 50

9000 LOK = .TRUE.

     Goto 10000

c ................................................................. 10000 REWIND datnr

     RETURN
     END FUNCTION BOD_SYS

cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

CXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX c Landnutzungen lesen

     FUNCTION LNZ_SYS (datnr, KNTRLL, LWARN, LJGANG)
    +RESULT (LOK)

c .................................................................

     USE MODERR
     REAL                :: WE, BG, BFI, VG, Kst,
    +                       HaudeFak(ANZMONATE)
     INTEGER             :: ID, datnr, LnzID, BGJGG, BFIJGG,
    +                       HaudeFakJGG
     LOGICAL             :: LOK, LTMP, KNTRLL, LWARN, LJGANG
     CHARACTER (LEN = 1) :: ctmp

c .................................................................

     LOK = .FALSE.

c ================================================================= C Lesen der aktuellen Zeile c =================================================================

 100 FORMAT(A1, 2X, I4, 2X, F5.0, 2(1X,F5.0,1X,I3), 1X, I3, 1X,
    +       F3.0, 1X, F5.0)
  50 READ(datnr, 100, ERR=50, END=9000) ctmp,
    +    LnzID, WE, BG, BGJGG, BFI, BFIJGG, HaudeFakJGG, VG, Kst
     IF (ctmp.EQ.cKOMMENTAR) GOTO 50

c ================================================================= C Pruefung der Kenngroessen c ================================================================= c ID-Kontrolle c ============

     IF (LnzID.LT.1) KNTRLL = FEHLER (3320, 'LNZ ', 'LNZ ', LnzID)

C Ganglinienkontrolle C ===================

     IF (BGJGG.GT.0 .AND. .NOT. LJGANG)
    +   KNTRLL = FEHLER (157, 'BOD ', 'JGG ', 0)
     IF (BFIJGG.GT.0 .AND. .NOT. LJGANG)
    +   KNTRLL = FEHLER (157, 'BOD ', 'JGG ', 0)
     IF (HaudeFakJGG.GT.0 .AND. .NOT. LJGANG)
    +   KNTRLL = FEHLER (157, 'BOD ', 'JGG ', 0)

C Zulässige Werte C ===============

     IF (WE.LE.NULL)
    +   KNTRLL = FEHLER (3322, 'WE  ', '    ', LnzID)
     IF (BG.LE.NULL .OR. BG.GT.100.)
    +   KNTRLL = FEHLER (3322, 'BG  ', '    ', LnzID)
     IF (BFI.LE.NULL)
    +   KNTRLL = FEHLER (3322, 'BFI ', '    ', LnzID)
     IF (VG.LT.0. .OR. VG.GT.100.)
    +   KNTRLL = FEHLER (3322, 'VG  ', '    ', LnzID)
     IF (Kst.LT.0.)
    +   KNTRLL = FEHLER (3322, 'Kst ', '    ', LnzID)
     IF (KNTRLL) GOTO 10000

c ================================================================== C Neue Landnutzung einrichten c ================================================================== c DLL - Statement

     ID = LNZ_CREATE()
     IF (ID.EQ.0) GOTO 10000

c DLL - Statement

     LTMP = LNZ_NEU (ID, LNZID, WE, BG, BGJGG, BFI, BFIJGG,
    +                VG, Kst, HaudeFakJGG, HaudeFak)
     IF (.NOT.LTMP) GOTO 10000
     IF (KNTRLL) GOTO 10000
     GOTO 50

9000 LOK = .TRUE.

     Goto 10000

c ................................................................. 10000 REWIND datnr

     RETURN
     END FUNCTION LNZ_SYS

cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

CXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX C Anfangsbedingungen der Bodenarten setzen

     FUNCTION BOD_START (ID) RESULT (LOK)

c ................................................................. c TYPE (BOA_type), POINTER  :: objptr

     INTEGER ::  ID
     LOGICAL :: LOK

c .................................................................

     LOK = .FALSE.
     LOK = .TRUE.
     GOTO 10000

c ................................................................. 10000 RETURN

     END FUNCTION BOD_START

cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

CXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX C Berechnung einer Bodensäule: Bodenfeuchtesimulation c 1) Bodenwerte werden in 1/100mm umgerechnet aufgrund mathematischer Probleme bei c kleinen Zahlen !!! (HL: 15. Juli 2001) c 2) Bodenwerte werden in 1/1000mm umgerechnet aufgrund mathematischer Probleme bei c kleinen Zahlen !!! (HL: 11. November 2002) c Dicke wird nicht mit dem Skalierungsfaktor belegt (HL: 11. November 2002) c Haude-Faktoren <= Null abgefangen (HL: 11. November 2002) c INPUT: c ------ c Aktdatum = aktuelles Datum [jjjjmmtt hh:mm] c imon = aktueller Monat [1..12] c izschr = Zeitschritt [sek] c KENSYS = in Bearbeitung befindliches Element [A100, ...] c EFLID = ID der Elementarfläche c EvaKng = Kennung, Ansatz zur Berechnung der Evaporation c EtpKng = Kennung, Ansatz zur Berechnung der Transpiration c VerdFak = Monatsfaktor der Verdunstung bei Haude-Verdunstung c NSCH = Anzahl der Schichten c Gef = Gefälle [-] c Dicke = Schichtdicken [m] c WP = Welkepunkt [mm/m] c FK = Feldkapazität [mm/m] c GPV = Gesamtporenvolumen [mm/m] c BF = aktuelle Bodenfeuchte der n-Schichten [mm/m] c Nied = Niederschlag [mm/dt] c ETp = Potentielle Verdunstung [mm/dt] c LAI = Blattflächenindex [mm/d] c MaxInf = Max. Infiltrationsrate [mm/h] c kf = Durchlässigkeit [mm/h] c MaxKap = Max. Kapillaraufstieg [mm/h] c OUTPUT: c ------- c Runoff = Oberflächenabfluss [mm/dt] c ETa = aktuelle Verdunstung [mm/dt] c Infil = Infiltration (oberste Schicht) [mm/dt] c Interflow = Zwischenabfluss (oberste Schicht) [mm/dt] c Baseflow = Perkolation (Grundwasserneubildung, unterste Schicht) [mm/dt] c *****************************************************************

     FUNCTION BF_WEL (LWRITE, Aktdatum, imon, izschr,
    +                 KENSYS, EFLID, EvaKng, EtpKng, HaudeFak,
    +                 NSCH, Gef, inDicke, BOART, inWP, inFK, inGPV, BF,
    +                 inNied, inETp, LAI, inMaxInf, inkf, inMaxKap,
    +                 Runoff, ETa, Infil, Interflow, Baseflow)
    +RESULT (LOK)

c .................................................................

     USE MODMISC
     REAL, PARAMETER :: BFFak = 1000     !Umrechnung von mm/s auf [(1/1000 mm)/s]
     INTEGER       :: EFLID, imon, izschr, NSCH, EvaKng, ETpKng,
    +                 anzzr, anzfun, anzstz(BF_ANZ_FKT),
    +                 isch, iProzess, iproz, NSTZ, tmpNSTZ
     REAL (KIND=8) :: SkalX(SPE_MAXZR+BF_ANZ_FKT),
    +                 SkalY(SPE_MAXZR+BF_ANZ_FKT),
    +                 X(BF_MAXSTZ,BF_ANZ_FKT),
    +                 Y(BF_MAXSTZ,BF_ANZ_FKT),
    +                 m(BF_MAXSTZ,BF_ANZ_FKT),
    +                 ProzRate(BF_ANZ_FKT,NSCH),
    +                 Proz(BF_ANZ_FKT), BFakt(NSCH), BFtmp(NSCH),
    +                 dRate,
    +                 BFMax, tmpEva, tmpETa
     REAL (KIND=4) :: inDicke(NSCH), inWP(NSCH), inFK(NSCH),
    +                 inGPV(NSCH), Dicke(NSCH), BF(NSCH),
    +                 WP(NSCH), FK(NSCH), GPV(NSCH),
    +                 inkf(NSCH), kf(NSCH),
    +                 inMaxKap(NSCH), MaxKap(NSCH),
    +                 inNied, Nied, inETp, ETp, inMaxInf, MaxInf,
    +                 Gef, LAI, fak, HaudeFak,
    +                 Runoff, Infil, Interflow, Baseflow, ETa
     INTEGER       :: BOART(NSCH), iProzKng
     LOGICAL       :: LOK, LTMP, LWRITE, LBILANZ
     CHARACTER (LEN=*) :: Aktdatum
     CHARACTER (LEN=*) :: KENSYS

c .................................................................

     LOK = .FALSE.
     Runoff = 0.0
     ETa = 0.0
     Infil = 0.0
     Interflow = 0.0
     Baseflow = 0.0
     LBILANZ = .TRUE.
     !Variable, die eine Testausgabe bestimmt
     IF (LBFOUT) THEN
        CALL BF_OPENFILE(datTSTBF)
     END IF

c ----------------------------------------------------------------- c Verdunstung (Umrechnung in ((1/1000mm)/s) mm/s) c -----------------------------------------------------------------

     fak = (86400.0 / REAL(izschr))        !von [mm/dt] auf [mm/d]

c Evaporation

     IF (EvaKng.EQ.EVA_HaudeID) THEN
        IF (ABS(HaudeFak).GT.NULL) THEN
           tmpEva = DBLE(inETp * (LNZ_HAUDEFAK_CONST / HaudeFak))   !Bodenverdunstung wird auf unbewachsenen Boden bezogen
        ELSE
           tmpEva = DBLE(inETp)                                     !HaudFak = 0 : Keine Pflanzen, alles steht für die Bodenevaporation zur Verfügung
        END IF
     ELSEIF (EvaKng.EQ.EVA_BelmansID) THEN
        tmpEva = DBLE((inETp*fak) * EXP(-0.6*LAI))    ![mm/d]
        tmpEva = tmpEva / fak                         ![mm/dt]
     ELSEIF (EvaKng.EQ.EVA_PotentiellID) THEN
        tmpEva = inETp
     END IF
     tmpEva = (tmpEva / REAL(izschr)) * BfFak         ![1/1000mm / s]       [mm/s]

c ----------------------------------------------------------------- c Anpassung der Belastung und Bodenkennwerte auf [1/1000 mm/s] [mm/s] c -----------------------------------------------------------------

     Nied = BfFak * inNied / REAL(izschr)                     !von [mm/dt] auf [1/1000 mm/s] [mm/s]
     ETp = BfFak * (inETp) / REAL(izschr)                     !von [mm/dt] auf [1/1000 mm/s] [mm/s]
     DO isch = 1,NSCH
        kf(isch) =  BfFak * inkf(isch) / 3600.0               !von [mm/h] auf [1/1000 mm/s] [mm/s]
        MaxInf = BfFak * inMaxInf / 3600.0                    !von [mm/h] auf [1/1000 mm/s] [mm/s]
        MaxKap(isch) =  BfFak * inMaxKap(isch) / 3600.0       !von [mm/h] auf [1/1000 mm/s] [mm/s]
     END DO

c ----------------------------------------------------------------- c Initialisierung c ----------------------------------------------------------------- c Zuerst ist nur der Niederschlag als konstanter Input vorhanden

     anzzr = 1

c Anzahl der Bodenprozesse

     anzfun = BF_ANZ_FKT

c Übergabe der letzten Bodenfeuchtewerte [mm/m] und Umrechnung in [1/100 mm] [mm]

     DO isch = 1,NSCH
        WP(isch) = BfFak * inWP(isch)
        FK(isch) = BfFak * inFK(isch)
        GPV(isch) = BfFak * inGPV(isch)
        Dicke(isch) = inDicke(isch)
        BFakt(isch) = BfFak * DBLE(BF(isch) * inDicke(isch))
        BFtmp(isch) = BFakt(isch)
     END DO

c Skalierung auf Null setzen

     DO iproz = 1,anzzr
        SkalY(iproz) = 0.0
     END DO

c ----------------------------------------------------------------- c Alle Schichten von oben nach unten berechnen c -----------------------------------------------------------------

     DO isch = 1,NSCH
        BFMax = 0.0
        SkalY(anzzr) = 0.0
        NSTZ = 1
        iProzKng = BF_ExxID     !Annahme: Exfiltration dominiert Kapillaraufstieg

c ======================================== c Funktionsverläufe + Skalierung ermitteln c ========================================

        DO iproz = 1,anzfun
           iProzess = iproz

c ---------------- c Funktionsverlauf c ----------------

           !Infiltration nur bei InfiltrationsSchicht als Funktion wirksam,
           !ansonsten konstanter Funktionsverlauf
           IF (iproz.EQ.BF_InfID .AND. isch.NE.BOD_InfSchichtID) THEN
              iProzess = BF_ConstID
           END IF

c Funktionsverlauf: X-Werte der Funktion

           tmpNSTZ = BF_FKT_X (BOART(isch), iProzess, inDicke(isch),
    +                          WP(isch), FK(isch), GPV(isch),
    +                          X(1,iproz))
           IF (tmpNSTZ.EQ.0) THEN
              ERR_KENNUNG = ERR_BOD_FKT
              GOTO 10000
           END IF

c Funktionsverlauf: Y-Werte der Funktion

           anzstz(iproz) = BF_FKT_Y (isch, BOART(isch), iProzess,
    +                         ETpKng, MaxInf, kf(isch), MaxKap(isch),
    +                         tmpNSTZ, X(1,iproz), Y(1,iproz),
    +                         SkalY(anzzr+iproz))

c Steigungen der Funktion

           LTMP = CALC_STEIGUNG(anzstz(iproz), x(1,iproz), y(1,iproz),
    +                           m(1,iproz))
           IF (.NOT.LTMP) GOTO 10000

c Maximale Anzahl an Stützstellen

           IF (anzstz(iproz).GT.NSTZ) NSTZ = anzstz(iproz)

c Maximale Bodenfeuchte (Speicherinhalt)

           SkalX(anzzr+iproz) = 1.0
           IF (X(anzstz(iproz),iproz).GT.BFMax)
    +         BFMax = X(anzstz(iproz),iproz)

c ------------ c Y-Skalierung (Nur anwenden, wenn aus dem Funktionsverlauf der Skal-Faktor > 0) c ------------

           IF (ABS(SkalY(anzzr+iproz)).GT.0.) THEN
              SELECT CASE (iproz)
                 !Infiltration:
                 !in Infiltrationsschicht: Funktion nach Holtan -> Skalierung in der Y-Fkt enthalten
                 !alle anderen Schichten : konstante Funktion; mit aktueller Schicht (i) gilt:
                 !                         wenn Exx*(i-1) <  kf(i) -> Skalierung ist Exx(i-1)
                 !                         wenn Exx*(i-1) >= kf(i) -> Skalierung ist kf(i) [STAUEFFEKT !!!]
                 !                         Exx* = Exx - Kap
                 CASE (BF_InfID)
                     !für alle Schichten ausser Infiltrationsschicht gilt:
                     IF (isch.NE.BOD_InfSchichtID) THEN
                        !Infiltration zu Null gesetzt, Unabhängiger Input übernimmt
                        SkalY(anzzr+iproz) = 0.0
                        dRate = ABS(ProzRate(BF_ExxID,isch-1)) -
    +                           ABS(ProzRate(BF_KapID,isch-1))
                        !maßgebender Prozess? (Default: Perkolation)
                        iProzKng = BF_ExxID
                        IF (dRate.LT.0.) THEN
                           iProzKng = BF_KapID
                        END IF
                        IF (dRate.LT.kf(isch)) THEN
                           SkalY(anzzr) = dRate
                        !Staueffekt
                        ELSE
                           SkalY(anzzr) = kf(isch)
                        END IF
                     END IF
                 !Interflow (nur Infiltrationsschicht)
                 CASE (BF_IntID)
                     SkalY(anzzr+iproz) = SkalY(anzzr+iproz) *
    +                                     DBLE(Gef/(SQRT(1.+Gef**2.)))
                 !Evaporation (nur Infiltrationsschicht)
                 CASE (BF_EvaID)
                     SkalY(anzzr+iproz) = tmpEva
                 !Transpiration (nur WE-Schicht)
                 CASE (BF_EtaID)
                     tmpETa = ETp -
    +                         ABS(ProzRate(BF_EvaID,BOD_InfSchichtID))
                     tmpETa = MAX(0.0, tmpETa)
                     SkalY(anzzr+iproz) = tmpETa
              END SELECT
           END IF

c Wenn Funktionsausgabe gesetzt: Funktionen in Datei schreiben c ------------------------------------------------------------

           IF (LBFFKT) THEN
              LTMP = BF_FKT_WRITE (datBFFKT, izschr, iProz,
    +                              KENSYS, EFLID, isch,
    +                              inWP(isch), inFK(isch), inGPV(isch),
    +                              Dicke(isch), BFFak,
    +                              anzstz(iproz),
    +                              X(1,iproz), Y(1,iproz),
    +                              SkalY(anzzr+iproz),
    +                              BF_VORZEICHEN(iproz))
           END IF
        END DO

c ================= c Schicht berechnen c =================

        !Schichtberechnung
        LTMP = BF_CALC_SCHICHT (KENSYS, EFLID, isch,
    +                  Aktdatum, izschr,
    +                  anzzr, anzfun, BF_MAXSTZ, anzstz, X, Y, m,
    +                  BFMax, BFtmp(isch), BFakt(isch),
    +                  SkalX, SkalY, Proz)
        IF (.NOT.LTMP) GOTO 10000
        !Zuweisen des Inputs an die Infiltration
        IF (isch.NE.BOD_InfSchichtID) THEN    !Vorsicht, wenn KapAufstieg dominiert ist SkalY(anzzr) < 0
           Proz(BF_InfID) = SkalY(anzzr) ! * BF_VORZEICHEN(BF_InfID)
        END IF

c ========= c Kontrolle c =========

        SELECT CASE (isch)
         CASE (BOD_InfSchichtID)

c Infiltrationsschicht - Kontrolle: Niederschlag < pot. Infiltration ?

             IF (Nied.LT.ABS(Proz(BF_InfID))) THEN
                BFakt(isch) = BFtmp(isch)
                SkalY(anzzr) = Nied
                SkalY(anzzr+BF_InfID) = 0.0
                LTMP = BF_CALC_SCHICHT (KENSYS, EFLID, isch,
    +                          Aktdatum, izschr,
    +                          anzzr, anzfun, BF_MAXSTZ,
    +                          anzstz, X, Y, m,
    +                          BFMax, BFtmp(isch), BFakt(isch),
    +                          SkalX, SkalY, Proz)
                IF (.NOT.LTMP) GOTO 10000
                Proz(BF_InfID) = DBLE(Nied) * BF_VORZEICHEN(BF_InfID)
             END IF
        END SELECT
        !Korrektur der untersten Schicht, wenn Überlauf > 0 ist
        !------------------------------------------------------
        IF (isch.EQ.NSCH .AND. ABS(Proz(BF_MaxID)).GT.0.) THEN
           CALL BF_BILANZ_SCHICHT (izschr, BFtmp(isch), BFakt(isch),
    +                              anzfun, Proz)
        END IF

c Übergabe der Prozessraten !Vorsicht, wenn KapAufstieg dominiert ist Proz(BF_InID) < 0 c -------------------------

        DO iproz = 1,anzfun
           ProzRate(iproz,isch) = ABS(Proz(iproz)) *
    +                             DBLE(BF_VORZEICHEN(iproz))
           IF (iproz.EQ.BF_InfID) THEN
              IF (     isch.NE.BOD_InfSchichtID
    +             .AND. iProzKng.EQ.BF_KapID) THEN
                 ProzRate(iproz,isch) = Proz(iproz)
              END IF
           END IF
        END DO

c Neue Bodenfeuchte mit Kontigleichung berechnen (Ausgleich von Bilanzfehlern) c ----------------------------------------------

        CALL BF_KONTI_SCHICHT (izschr,
    +                          BFtmp(isch), BFakt(isch),
    +                          anzfun, ProzRate(1,isch))

c Wenn Bodenausgabe gesetzt: Bodenfeuchte u. Prozessraten in Datei schreiben c --------------------------------------------------------------------------

        IF (LBFOUT) THEN
           LTMP = BF_PROZ_WRITE (datTSTBF, Kensys, EFLID,
    +                            'o_u', izschr, isch, BfFak,
    +                            DBLE(Dicke(isch)),
    +                            BFtmp(isch), BFakt(isch),
    +                            anzfun, ProzRate(1,isch), Nied,
    +                            Runoff, ETa, Interflow, Baseflow)
           IF (.NOT.LTMP) GOTO 10000
        END IF
     END DO

c --------------------------------------------------------------------- c Korrekturrechnung: Schichten von unten nach oben berechnen (Abgleich) c ---------------------------------------------------------------------

     DO isch = NSCH-1,1,-1
        !Maßgebender Prozess
        !-------------------
        !Perkolation aus der aktuellen Schicht
        dRate = (ABS(ProzRate(BF_ExxID,isch)) -
    +            ABS(ProzRate(BF_KapID,isch)))
        !maßgebender Prozess? (Default: Perkolation)
        iProzKng = BF_ExxID
        IF (dRate.LT.0.) iProzKng = BF_KapID
        !Korrekturrechnung wenn Verbindungsraten ungleich oder Überlauf > 0
        !------------------------------------------------------------------
        !Kontrolle: Sind die Wasserströme zwischen den Schichten gleich ?
        LTMP = .FALSE.
        IF ((ABS(ProzRate(BF_InfID,isch+1)-dRate)*REAL(izschr))
    +       .GT.BF_DELTARATE)
    +      LTMP = .TRUE.
        !Kontrolle: Liegt ein Überlauf in dieser Schicht vor ?
        IF (ABS(ProzRate(BF_MaxID,isch)).GT.0.) LTMP = .TRUE.
        !Korrekturrechnung erforderlich (Staueffekt oder Überlauf liegt vor)
        IF (LTMP) THEN
           BFakt(isch) = BFtmp(isch)
           BFMax = 0.0
           SkalY(anzzr) = 0.0
           NSTZ = 1

c ======================================== c Funktionsverläufe + Skalierung ermitteln c ========================================

           DO iproz = 1,anzfun
              iProzess = iproz

c ---------------- c Funktionsverlauf c ----------------

              !Infiltration nur bei Infiltrationsschicht als Funktion wirksam
              !Ansonsten konstanter Funktionsverlauf, Skalierung mit Exx/Kap aus darüberliegender Schicht
              IF (iproz.EQ.BF_InfID.AND.isch.NE.BOD_InfSchichtID) THEN
                 iProzess = BF_ConstID
              END IF
              !Bei Korrekturberechnung sind Perkolation bzw. kapillarer Aufstieg konstante Funktionen
              !Exfiltration ist die Infiltrationskapazität der darunterliegenden Schicht
              IF (iproz.EQ.BF_ExxID) iProzess = BF_ConstID
              IF (iproz.EQ.BF_KapID) iProzess = BF_ConstID

c Funktionsverlauf: X-Werte der Funktion

              tmpNSTZ = BF_FKT_X (BOART(isch), iProzess, inDicke(isch),
    +                             WP(isch), FK(isch), GPV(isch),
    +                             X(1,iproz))
              IF (tmpNSTZ.EQ.0) THEN
                 ERR_KENNUNG = ERR_BOD_FKT
                 GOTO 10000
              END IF

c Funktionsverlauf: Y-Werte der Funktion

              anzstz(iproz) = BF_FKT_Y (isch, BOART(isch), iProzess,
    +                           ETpKng, MaxInf, kf(isch), MaxKap(isch),
    +                           tmpNSTZ, X(1,iproz), Y(1,iproz),
    +                           SkalY(anzzr+iproz))

c Steigungen der Funktion

              LTMP = CALC_STEIGUNG(anzstz(iproz), x(1,iproz),
    +                              y(1,iproz), m(1,iproz))
              IF (.NOT.LTMP) GOTO 10000

c Maximale Anzahl an Stützstellen

              IF (anzstz(iproz).GT.NSTZ) NSTZ = anzstz(iproz)

c Maximale Bodenfeuchte (Speicherinhalt)

              SkalX(anzzr+iproz) = 1.0
              IF (X(anzstz(iproz),iproz).GT.BFMax)
    +             BFMax = X(anzstz(iproz),iproz)

c ------------ c Y-Skalierung (Nur, wenn aus dem Funktionsverlauf der Skal-Faktor > 0) c ------------

              IF (ABS(SkalY(anzzr+iproz)).GT.0.) THEN
                 SELECT CASE (iproz)
                    !Infiltration:
                    !in Infiltrationsschicht: Funktion nach Holtan -> Skalierung in der Y-Fkt enthalten
                    !alle anderen Schichten : konstante Funktion; mit aktueller Schicht (i) gilt:
                    !                         wenn Exx*(i-1) <  kf(i) -> Skalierung ist Exx(i-1)
                    !                         wenn Exx*(i-1) >= kf(i) -> Skalierung ist kf(i) [STAUEFFEKT !!!]
                    !                         Exx* = Exx - Kap
                    CASE (BF_InfID)
                        !für alle Schichten ausser Infiltrationsschicht gilt:
                        IF (isch.NE.BOD_InfSchichtID) THEN
                           !Infiltration zu Null gesetzt, Unabhängiger Input übernimmt
                           SkalY(anzzr+iproz) = 0.0
                           dRate = ABS(ProzRate(BF_ExxID,isch-1)) -
    +                              ABS(ProzRate(BF_KapID,isch-1))
                           IF (dRate.LT.kf(isch)) THEN
                              SkalY(anzzr) = dRate
                           !Staueffekt
                           ELSE
                              SkalY(anzzr) = kf(isch)
                           END IF
                        END IF
                    !Perkolation
                    CASE (BF_ExxID)
                        IF (iProzKng.EQ.BF_ExxID) THEN
                           SkalY(anzzr+iproz)=
    +                                  ABS(ProzRate(BF_InfID,isch+1))
                        ELSE
                           SkalY(anzzr+iproz) = 0.0
                        END IF
                    !Kappilarer Aufstieg
                    CASE (BF_KapID)
                        IF (iProzKng.EQ.BF_KapID) THEN
                           SkalY(anzzr+iproz)=ProzRate(BF_InfID,isch+1)
                        ELSE
                           SkalY(anzzr+iproz) = 0.0
                        END IF
                    !Interflow (nur Infiltrationsschicht)
                    CASE (BF_IntID)
                        SkalY(anzzr+iproz) = SkalY(anzzr+iproz) *
    +                                      DBLE(Gef/(SQRT(1.+Gef**2.)))
                    !Evaporation (nur Infiltrationsschicht)
                    CASE (BF_EvaID)
                        dRate = ETp-ProzRate(BF_EtaID,BOD_WESchichtID)
                        SkalY(anzzr+iproz) = SkalY(anzzr+iproz) *
    +                                        MAX(0.0, dRate)
                    !Transpiration (nur WE-Schicht)
                    CASE (BF_EtaID)
                        SkalY(anzzr+iproz) = tmpETa
                 END SELECT
              END IF

c Wenn Funktionsausgabe gesetzt: Funktionen in Datei schreiben c ------------------------------------------------------------

              IF (LBFFKT) THEN
                 LTMP = BF_FKT_WRITE (datBFFKT, izschr, iProz,
    +                                 KENSYS, EFLID, isch,
    +                            inWP(isch), inFK(isch), inGPV(isch),
    +                                 Dicke(isch), BFFak,
    +                                 anzstz(iproz),
    +                                 X(1,iproz), Y(1,iproz),
    +                                 SkalY(anzzr+iproz),
    +                                 BF_VORZEICHEN(iproz))
              END IF
           END DO

c ================= c Schicht berechnen c ================= c Infiltrationbetrag plus Überschuss aus unterhalb liegender Schicht ist unabhängiger Input

           SkalY(anzzr) = SkalY(anzzr) + ProzRate(BF_MaxID,isch+1)
           LTMP = BF_CALC_SCHICHT (KENSYS, EFLID, isch,
    +                     Aktdatum, izschr,
    +                     anzzr, anzfun, BF_MAXSTZ, anzstz, X, Y, m,
    +                     BFMax, BFtmp(isch), BFakt(isch),
    +                     SkalX, SkalY, Proz)
           IF (.NOT.LTMP) GOTO 10000
           !Zuweisen des Inputs an die Infiltration  !Vorsicht, wenn KapAufstieg dominiert ist SkalY(anzzr) < 0
           IF (isch.NE.BOD_InfSchichtID) THEN
              Proz(BF_InfID) = (SkalY(anzzr)-ProzRate(BF_MaxID,isch+1))

c + * BF_VORZEICHEN(BF_InfID)

           END IF

c ========= c Kontrolle c =========

           SELECT CASE (isch)
            CASE (BOD_InfSchichtID)

c Infiltrationsschicht - Kontrolle: Niederschlag < pot. Infiltration ?

               IF (Nied.LT.ABS(Proz(BF_InfID))) THEN
                  BFakt(isch) = BFtmp(isch)

c Niederschlag plus Überschuss aus unterhalb liegender Schicht ist unabhängiger Input

                  SkalY(anzzr) = Nied + ProzRate(BF_MaxID,isch+1)
                  SkalY(anzzr+BF_InfID) = 0.0
                  LTMP = BF_CALC_SCHICHT (KENSYS, EFLID, isch,
    +                           Aktdatum, izschr,
    +                           anzzr, anzfun, BF_MAXSTZ,
    +                           anzstz, X, Y, m,
    +                           BFMax, BFtmp(isch), BFakt(isch),
    +                           SkalX, SkalY, Proz)
                  IF (.NOT.LTMP) GOTO 10000
                  Proz(BF_InfID) = DBLE(Nied) * BF_VORZEICHEN(BF_InfID)
               END IF
           END SELECT
           !Korrektur der Schicht, wenn Überlauf > 0 ist
           !--------------------------------------------
           IF (ABS(Proz(BF_MaxID)).GT.0.) THEN
              CALL BF_BILANZ_SCHICHT (izschr, BFtmp(isch), BFakt(isch),
    +                                 anzfun, Proz)
           END IF

c Übergabe der Prozessraten !Vorsicht, wenn KapAufstieg dominiert ist Proz(BF_InID) < 0 c -------------------------

           DO iproz = 1,anzfun
              ProzRate(iproz,isch) = ABS(Proz(iproz)) *
    +                                DBLE(BF_VORZEICHEN(iproz))
              IF (iproz.EQ.BF_InfID) THEN
                 IF (     isch.NE.BOD_InfSchichtID
    +                .AND. iProzKng.EQ.BF_KapID) THEN
                    ProzRate(iproz,isch) = Proz(iproz)
                 END IF
              END IF
           END DO

c Neue Bodenfeuchte mit Kontigleichung berechnen (Ausgleich von Bilanzfehlern) c ----------------------------------------------

           CALL BF_KONTI_SCHICHT (izschr, BFtmp(isch), BFakt(isch),
    +                             anzfun, ProzRate(1,isch))

c Prozessraten in Testergebnisdatei schreiben c -------------------------------------------

           IF (LBFOUT) THEN
              LTMP = BF_PROZ_WRITE (datTSTBF, Kensys, EFLID,
    +                            'u_o', izschr, isch, BfFak,
    +                            DBLE(Dicke(isch)),
    +                            BFtmp(isch), BFakt(isch),
    +                            anzfun, ProzRate(1,isch), inNied,
    +                            Runoff, ETa, Interflow, Baseflow)
              IF (.NOT.LTMP) GOTO 10000
           END IF
        END IF
     END DO

c ----------------------------------------------------------------- c Übergabe der letzten Bodenfeuchtewerte [mm/m] c -----------------------------------------------------------------

     DO isch = 1,NSCH
        BF(isch) = SNGL(BFakt(isch) / DBLE(Dicke(isch)))
     END DO

c IF (LWRITE) WRITE(datTSTBF,*)

c ----------------------------------------------------------------- c Übergabe der Abflussbildung [mm/dt] c -----------------------------------------------------------------

     dRate = (Nied - ABS(ProzRate(BF_InfID,BOD_InfSchichtID)))

c + + ProzRate(BF_MaxID,BOD_InfSchichtID)

     Runoff = MAX(0.0, dRate)
     Runoff = (Runoff * REAL(izschr)) / BfFak
     Baseflow = (ABS(ProzRate(BF_ExxID,BOD_TRSSchichtID)) -
    +           ABS(ProzRate(BF_KapID,BOD_TRSSchichtID))) *
    +           REAL(izschr)
     Baseflow = Baseflow / BfFak
     ETa = 0.0
     Interflow = 0.0
     DO isch = 1,NSCH
        ETa = ETa + ABS(ProzRate(BF_EvaID,isch)) +
    +               ABS(ProzRate(BF_EtaID,isch))
        Interflow = Interflow + ABS(ProzRate(BF_IntID,isch))
     END DO
     ETa = ETa * REAL(izschr) / BfFak
     Infil = (ABS(ProzRate(BF_InfID, BOD_InfSchichtID)) * REAL(izschr))
    +         / BfFak
     Interflow = (Interflow * REAL(izschr)) / BfFak

c ----------------------------------------------------------------- c Schreiben der Ergebnisse c -----------------------------------------------------------------

     IF (LBFOUT) THEN
        WRITE(datTSTBF, '(1X,A,I5)', ERR=9999) KENSYS, EFLID
        WRITE(datTSTBF, '(A4, 1X, I3, 1X, 5(A10))') Kensys, EFLID,
    +  'HN    [mm]', 'HNeff[mm]', ' ETa [mm]', 'Int  [mm]', 'Base [mm]'
        WRITE(datTSTBF, '(A4, 1X, I3, 1X, 8(F10.3))') KENSYS, EFLID,
    +         inNied, Runoff, ETa, Interflow, Baseflow,
    +        (BF(isch), isch=1,NSCH)
        DO isch = 1,NSCH
           LTMP = BF_PROZ_WRITE (datTSTBF, Kensys, EFLID,
    +                            'erg', izschr, isch, BfFak,
    +                            DBLE(Dicke(isch)),
    +                            BFtmp(isch), BFakt(isch),
    +                            anzfun, ProzRate(1,isch), inNied,
    +                            Runoff, ETa, Interflow, Baseflow)
           IF (.NOT.LTMP) GOTO 10000
        END DO
     END IF
     IF (LBILANZ) THEN

c !Summe der Bodenfeuchte über alle Schichten c SumBFalt = 0.0 c SumBFneu = 0.0 c DO isch=1,NSCH c SumBFalt = SumBFalt + BFtmp(isch) c SumBFneu = SumBFneu + BFakt(isch) c END DO c dRate = SumBFneu - SumBFalt c  !

     END IF
     LOK = .TRUE.
     GOTO 10000

c ................................................................. 9999 ERR_KENNUNG = datTSTBF

     GOTO 10000

10000 RETURN

     END FUNCTION BF_WEL

cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

CXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX C Berechnung einer Bodensäule: Bodenfeuchtesimulation c izschr = Zeitschritt [sek] c NSCH = Anzahl der Schichten c Gef = Gefälle [-] c Dicke = Schichtdicken [m] c WP = Welkepunkt [mm/m] c FK = Feldkapazität [mm/m] c GPV = Gesamtporenvolumen [mm/m] c BF = aktuelle Bodenfeuchte der n-Schichten [mm/m] c Nied = Niederschlag [mm/dt] c ETp = Potentielle Verdunstung [mm/dt] c LAI = Blattflächenindex [mm/d] c MaxInf = Max. Infiltrationsrate [mm/h] c kf = Durchlässigkeit [mm/h] c MaxKap = Max. Kapillaraufstieg [mm/h] c *****************************************************************

     FUNCTION BF_WELOK (LWRITE, Aktdatum, imon, izschr, EvaKng, EtpKng,
    +                 NSCH, Gef, Dicke, BOART, WP, FK, GPV, BF,
    +                 inNied, inETp, LAI, inMaxInf, inkf, inMaxKap,
    +                 Runoff, ETa, Interflow, Baseflow)
    +RESULT (LOK)

c .................................................................

     USE MODMISC
     INTEGER       :: imon, izschr, NSCH, EvaKng, ETpKng,
    +                 anzzr, anzfun, anzstz(BF_ANZ_FKT),
    +                 isch, iProzess, iproz, NSTZ, tmpNSTZ
     REAL (KIND=8) :: SkalX(SPE_MAXZR+BF_ANZ_FKT),
    +                 SkalY(SPE_MAXZR+BF_ANZ_FKT),
    +                 X(BF_MAXSTZ,BF_ANZ_FKT),
    +                 Y(BF_MAXSTZ,BF_ANZ_FKT),
    +                 m(BF_MAXSTZ,BF_ANZ_FKT),
    +                 ProzRate(BF_ANZ_FKT,NSCH),
    +                 Proz(BF_ANZ_FKT), BFakt(NSCH), BFtmp(NSCH),
    +                 BFMax, tmpEva, tmpETa
     REAL (KIND=4) :: Dicke(NSCH), WP(NSCH), FK(NSCH),
    +                 GPV(NSCH), BF(NSCH),
    +                 inkf(NSCH), kf(NSCH),
    +                 inMaxKap(NSCH), MaxKap(NSCH),
    +                 inNied, Nied, inETp, ETp, inMaxInf, MaxInf,
    +                 Gef, LAI, kfExx, fak,
    +                 Runoff, Interflow, Baseflow, ETa
     INTEGER       :: BOART(NSCH)
     LOGICAL       :: LOK, LTMP, LWRITE
     CHARACTER (LEN=*) :: Aktdatum

c .................................................................

     LOK = .FALSE.
     Runoff = 0.0
     ETa = 0.0
     Interflow = 0.0
     Baseflow = 0.0

c ----------------------------------------------------------------- c Verdunstung (Umrechnung in mm/s) c -----------------------------------------------------------------

     fak = 86400.0 / REAL(izschr)                     !von [mm/dt] auf [mm/d]

c Evaporation

     IF (EvaKng.EQ.EVA_HaudeID) THEN
        tmpEva = DBLE((inETp / LNZ_HAUDEFAK_GRAS(imon)) *
    +                  LNZ_HAUDEFAK_CONST)
     ELSEIF (EvaKng.EQ.EVA_BelmansID) THEN
        tmpEva = DBLE((inETp*fak) * EXP(-0.6*LAI))    ![mm/d]
        tmpEva = tmpEva / fak                         ![mm/dt]
     END IF
     tmpEva = tmpEva / REAL(izschr)                   ![mm/s]

c ----------------------------------------------------------------- c Anpassung der Belastung und Bodenkennwerte auf [mm/s] c -----------------------------------------------------------------

     Nied = inNied / REAL(izschr)                     !von [mm/dt] auf [mm/s]
     ETp = inETp / REAL(izschr)                       !von [mm/dt] auf [mm/s]
     MaxInf = inMaxInf / REAL(izschr)                 !von [mm/dt] auf [mm/s]
     DO isch = 1,NSCH
        kf(isch) =  inkf(isch) / 3600.0               !von [mm/h] auf [mm/s]
        MaxKap(isch) =  inMaxKap(isch) / 3600.0       !von [mm/h] auf [mm/s]
     END DO

c ----------------------------------------------------------------- c Initialisierung c ----------------------------------------------------------------- c Zuerst ist nur der Niederschlag als konstanter Input vorhanden

     anzzr = 1
     anzfun = BF_ANZ_FKT

c Übergabe der letzten Bodenfeuchtewerte [mm/m]

     DO isch = 1,NSCH
        BFakt(isch) = DBLE(BF(isch) * Dicke(isch))
        BFtmp(isch) = BFakt(isch)
     END DO
     DO iproz = 1,anzzr
        SkalY(iproz) = 1.0
     END DO

c ----------------------------------------------------------------- c Alle Schichten von oben nach unten berechnen c -----------------------------------------------------------------

     DO isch = 1,NSCH
        BFMax = 0.0
        NSTZ = 1

c ======================================== c Funktionsverläufe + Skalierung ermitteln c ========================================

        DO iproz = 1,anzfun
           iProzess = iproz
           !Infiltration nur bei InfiltrationsSchicht als Funktion wirksam
           !Ansonsten konstanter Funktionsverlauf, Skalierung mit Exx aus darüberliegender Schicht
           IF (iproz.EQ.BF_InfID .AND. isch.NE.BOD_InfSchichtID) THEN
              iProzess = BF_ConstID
           END IF

c Funktionsverlauf c ---------------- c X-Werte der Funktion

           tmpNSTZ = BF_FKT_X (BOART(isch), iProzess, Dicke(isch),
    +                          WP(isch), FK(isch), GPV(isch),
    +                          X(1,iproz))
           IF (tmpNSTZ.EQ.0) THEN
              ERR_KENNUNG = ERR_BOD_FKT
              GOTO 10000
           END IF

c Y-Werte der Funktion

           kfExx = kf(isch)
           IF (isch.LT.NSCH) kfExx = kf(isch+1)
           anzstz(iproz) = BF_FKT_Y(isch, BOART(isch), iProzess,
    +                               ETpKng, MaxInf, kf(isch),
    +                               MaxKap(isch),
    +                               tmpNSTZ, X(1,iproz),
    +                               Y(1,iproz), SkalY(anzzr+iproz))

c Steigungen der Funktion

           LTMP = CALC_STEIGUNG(anzstz(iproz), x(1,iproz), y(1,iproz),
    +                           m(1,iproz))
           IF (.NOT.LTMP) GOTO 10000

c Maximale Anzahl an Stützstellen

           IF (anzstz(iproz).GT.NSTZ) NSTZ = anzstz(iproz)

c Maximale Bodenfeuchte (Speicherinhalt)

           SkalX(anzzr+iproz) = 1.0
           IF (X(anzstz(iproz),iproz).GT.BFMax)
    +          BFMax = X(anzstz(iproz),iproz)

c Y-Skalierungsfaktoren: Nur, wenn aus dem Funktionsverlauf der Skal-Faktor > 0 c -----------------------------------------------------------------------------

           IF (ABS(SkalY(anzzr+iproz)).GT.0.) THEN
              SELECT CASE (iProzess)
                 !Interflow (nur Infiltrationsschicht)
                 CASE (BF_IntID)
                     SkalY(anzzr+iproz) = SkalY(anzzr+iproz) *
    +                                     DBLE(Gef/(SQRT(1.+Gef**2.)))
                 !Evaporation (nur Infiltrationsschicht)
                 CASE (BF_EvaID)
                     SkalY(anzzr+iproz) = tmpEva
                 !Transpiration (nur WE-Schicht)
                 CASE (BF_EtaID)
                     tmpETa = MAX(0.0, ETp -
    +                             ProzRate(BF_EvaID,BOD_InfSchichtID))
                     SkalY(anzzr+iproz) = tmpETa
              END SELECT
           END IF

c IF (LTSTOUT) THEN c LTMP = BF_FKT_WRITE (datTST, izschr, iProz, c + anzstz(iproz), c + X(1,iproz), Y(1,iproz), c + SkalY(anzzr+iproz), c + BF_VORZEICHEN(iproz)) c END IF

        END DO

c ======================================= c Schichten von oben nach unten berechnen c =======================================

        SkalY(anzzr) = 0.0
        If (isch.NE.BOD_InfSchichtID) THEN
           !Skalierung zur Infiltration ist Exfiltration aus darüberliegender Schicht
           SkalY(anzzr+BF_InfID) = ABS(ProzRate(BF_ExxID,isch-1))
        END IF

c LTMP = BF_CALC_SCHICHT (Aktdatum, izschr, c + anzzr, anzfun, NSTZ, anzstz, X, Y, m, c + BFMax, BFtmp(isch), BFakt(isch), c + SkalX, SkalY, Proz)

        IF (.NOT.LTMP) GOTO 10000
        SELECT CASE (isch)

c Infiltrationsschicht

         CASE (BOD_InfSchichtID)

c Kontrolle: Niederschlag < pot. Infiltration

             IF (Nied.LT.ABS(Proz(BF_InfID))) THEN
                BFakt(isch) = BFtmp(isch)
                SkalY(anzzr) = Nied
                SkalY(anzzr+BF_InfID) = 0.0

c LTMP = BF_CALC_SCHICHT (Aktdatum, izschr, c + anzzr, anzfun, NSTZ, anzstz, X, Y, m, c + BFMax, BFtmp(isch), BFakt(isch), c + SkalX, SkalY, Proz)

                IF (.NOT.LTMP) GOTO 10000
                Proz(BF_InfID) = DBLE(Nied) * BF_VORZEICHEN(BF_InfID)
             END IF
        END SELECT
        !Bei Überlauf: Bodenschicht übergesättigt, Überlauf wird von BF abgezogen
        LTMP = BF_CORRECT_SCHICHT (.FALSE., izschr, Nied,
    +                     BFtmp(isch), BFakt(isch), anzfun, Proz)

c Übergabe der Prozessraten c -------------------------

        DO iproz = 1,anzfun
           ProzRate(iproz,isch) = ABS(Proz(iproz))
        END DO

c IF (LWRITE) THEN c LTMP = BF_PROZ_WRITE (datTSTBF, 'o_u', izschr, isch, c + DBLE(Dicke(isch)), c + BFtmp(isch), BFakt(isch), c + anzfun, ProzRate(1,isch), inNied, c + Runoff, ETa, Interflow, Baseflow) c IF (.NOT.LTMP) GOTO 10000 c END IF

     END DO

c ----------------------------------------------------------------- c Korrekturrechnung: Schichten von unten nach oben berechnen als Abgleich c -----------------------------------------------------------------

     DO isch = NSCH-1,1,-1
        !Staueffekt: Exfiltration(isch) ist groesser als Infiltration(isch+1)
        IF (ProzRate(BF_ExxID,isch).GT.ProzRate(BF_InfID,isch+1)) THEN
           BFakt(isch) = BFtmp(isch)
           BFMax = 0.0
           NSTZ = 1

c ======================================== c Funktionsverläufe + Skalierung ermitteln c ========================================

           DO iproz = 1,anzfun
              iProzess = iproz
              !Infiltration nur bei InfiltrationsSchicht als Funktion wirksam
              !Ansonsten konstanter Funktionsverlauf, Skalierung mit Exx aus darüberliegender Schicht
              IF (iproz.EQ.BF_InfID.AND.isch.NE.BOD_InfSchichtID) THEN
                 iProzess = BF_ConstID
              END IF
              !Exfiltration ist die Infiltrationskapazität der darunterliegenden Schicht
              !bei konstantem Funktionsverlauf
              IF (iproz.EQ.BF_ExxID.AND.isch.NE.BOD_TRSSchichtID) THEN
                 iProzess = BF_ConstID
              END IF

c Funktionsverlauf c ---------------- c X-Werte der Funktion

              tmpNSTZ = BF_FKT_X (BOART(isch), iProzess, Dicke(isch),
    +                             WP(isch), FK(isch), GPV(isch),
    +                             X(1,iproz))
              IF (tmpNSTZ.EQ.0) THEN
                 ERR_KENNUNG = ERR_BOD_FKT
                 GOTO 10000
              END IF

c Y-Werte der Funktion

              kfExx = kf(isch)
              IF (isch.LT.NSCH) kfExx = kf(isch+1)
              anzstz(iproz) = BF_FKT_Y(isch, BOART(isch), iProzess,
    +                                  ETpKng, MaxInf, kf(isch),
    +                                  MaxKap(isch),
    +                                  tmpNSTZ, X(1,iproz),
    +                                  Y(1,iproz), SkalY(anzzr+iproz))

c Steigungen der Funktion

              LTMP = CALC_STEIGUNG(anzstz(iproz), x(1,iproz),
    +                              y(1,iproz), m(1,iproz))
              IF (.NOT.LTMP) GOTO 10000

c Maximale Anzahl an Stützstellen

              IF (anzstz(iproz).GT.NSTZ) NSTZ = anzstz(iproz)

c Maximale Bodenfeuchte (Speicherinhalt)

              SkalX(anzzr+iproz) = 1.0
              IF (X(anzstz(iproz),iproz).GT.BFMax)
    +             BFMax = X(anzstz(iproz),iproz)

c Y-Skalierungsfaktoren: Nur, wenn aus dem Funktionsverlauf der Skal-Faktor > 0 c -----------------------------------------------------------------------------

              IF (ABS(SkalY(anzzr+iproz)).GT.0.) THEN
                 SELECT CASE (iProzess)
                    !Interflow (nur Infiltrationsschicht)
                    CASE (BF_IntID)
                        SkalY(anzzr+iproz) = SkalY(anzzr+iproz) *
    +                                      DBLE(Gef/(SQRT(1.+Gef**2.)))
                    !Evaporation (nur Infiltrationsschicht)
                    CASE (BF_EvaID)
                        SkalY(anzzr+iproz) = SkalY(anzzr+iproz) *
    +                              MAX(0.0, ETp -
    +                              ProzRate(BF_EtaID,BOD_WESchichtID))
                    !Transpiration (nur WE-Schicht)
                    CASE (BF_EtaID)
                        SkalY(anzzr+iproz) = tmpETa
                 END SELECT
              END IF

c IF (LWRITE) THEN c LTMP = BF_FKT_WRITE (datTSTBF, izschr, iProz, c + anzstz(iproz), c + X(1,iproz), Y(1,iproz), c + SkalY(anzzr+iproz), c + BF_VORZEICHEN(iproz)) c END IF

           END DO

c ======================================= c Schichten von unten nach oben berechnen c =======================================

           SkalY(anzzr) = 0.0
           !Exfiltration ist Infiltration aus darunterliegender Schicht
           SkalY(anzzr+BF_ExxID) = ABS(ProzRate(BF_InfID,isch+1))

c LTMP = BF_CALC_SCHICHT (Aktdatum, izschr, c + anzzr, anzfun, NSTZ, anzstz, X, Y, m, c + BFMax, BFtmp(isch), BFakt(isch), c + SkalX, SkalY, Proz)

           IF (.NOT.LTMP) GOTO 10000
           !Falls jetzt Exx(isch) < Inf(isch+1) dann setze:
           !a) Inf(isch) = Exx(isch-1) b) Inf(isch) = Niederschlag bei Infiltrationsschicht
           If (     ABS(Proz(BF_ExxID))
    +          .LT. ABS(ProzRate(BF_InfID,isch+1))) THEN
              !Inf und Exx werden nicht über Funktionen berechnet, sondern als fester Input
              !Exfiltration:
              SkalY(anzzr+BF_ExxID) = 0.0
              SkalY(anzzr) = ProzRate(BF_InfID,isch+1) *
    +                        BF_VORZEICHEN(BF_ExxID)
             !Infiltration
              SELECT CASE (isch)
                  CASE (BOD_InfSchichtID)
                      IF (ABS(Proz(BF_InfID)) .GT. DBLE(Nied)) THEN
                         SkalY(anzzr+BF_InfID) = 0.0
                         SkalY(anzzr) = SkalY(anzzr) + Nied
                      END IF
                  CASE DEFAULT
                      IF (     ABS(Proz(BF_InfID))
    +                     .GT. ProzRate(BF_ExxID,isch-1)) THEN
                         SkalY(anzzr+BF_InfID) = 0.0
                         SkalY(anzzr) = SkalY(anzzr) +
    +                                   ProzRate(BF_ExxID,isch-1)
                      END IF
              END SELECT
              !auf letzte Bodenfeuchte zurücksetzen
              BFakt(isch) = BFtmp(isch)

c LTMP = BF_CALC_SCHICHT (Aktdatum, izschr, c + anzzr, anzfun, NSTZ, anzstz, X, Y, m, c + BFMax, BFtmp(isch), BFakt(isch), c + SkalX, SkalY, Proz)

              IF (.NOT.LTMP) GOTO 10000
              !Infiltration zuweisen
              SELECT CASE (isch)
                  CASE (BOD_InfSchichtID)
                      Proz(BF_InfID) = DBLE(Nied) *
    +                                  BF_VORZEICHEN(BF_InfID)
                  CASE DEFAULT
                      Proz(BF_InfID) = ProzRate(BF_ExxID,isch-1) *
    +                                  BF_VORZEICHEN(BF_InfID)
              END SELECT
              !Exfiltration zuweisen
              Proz(BF_ExxID) = ProzRate(BF_InfID,isch+1) *
    +                          BF_VORZEICHEN(BF_ExxID)
           END IF
          !Bei Überlauf: Bodenschicht übergesättigt, Überlauf wird von BF abgezogen
          LTMP = BF_CORRECT_SCHICHT (.FALSE., izschr, Nied,
    +                       BFtmp(isch), BFakt(isch), anzfun, Proz)
           SELECT CASE (isch)

c Infiltrationsschicht

            CASE (BOD_InfSchichtID)

c Kontrolle: Niederschlag < pot. Infiltration

                IF (Nied.LT.ABS(Proz(BF_InfID))) THEN
                   BFakt(isch) = BFtmp(isch)
                   SkalY(anzzr+BF_InfID) = 0.0
                   SkalY(anzzr+BF_ExxID) = 0.0
                   SkalY(anzzr) = Nied + ProzRate(BF_InfID,isch+1) *
    +                                    BF_VORZEICHEN(BF_ExxID)

c LTMP = BF_CALC_SCHICHT (Aktdatum, izschr, c + anzzr, anzfun, NSTZ, anzstz, X, Y, m, c + BFMax, BFtmp(isch), BFakt(isch), c + SkalX, SkalY, Proz)

                   IF (.NOT.LTMP) GOTO 10000
                   Proz(BF_InfID) = DBLE(Nied)*BF_VORZEICHEN(BF_InfID)
                   Proz(BF_ExxID) = ProzRate(BF_InfID,isch+1) *
    +                               BF_VORZEICHEN(BF_ExxID)
                END IF
           END SELECT
          !Bei Überlauf: Bodenschicht übergesättigt, Überlauf wird von BF abgezogen
          LTMP = BF_CORRECT_SCHICHT (.FALSE., izschr, Nied,
    +                       BFtmp(isch), BFakt(isch), anzfun, Proz)

c Übergabe der Prozessraten c -------------------------

           DO iproz = 1,anzfun
              ProzRate(iproz,isch) = ABS(Proz(iproz))
           END DO

c Prozessraten in Testergebnisdatei schreiben c -------------------------------------------

           IF (LWRITE) THEN

c LTMP = BF_PROZ_WRITE (datTSTBF, 'u_o', izschr, isch, c + DBLE(Dicke(isch)), c + BFtmp(isch), BFakt(isch), c + anzfun, ProzRate(1,isch), inNied, c + Runoff, ETa, Interflow, Baseflow) c IF (.NOT.LTMP) GOTO 10000

           END IF
        END IF
     END DO

c ----------------------------------------------------------------- c Übergabe der letzten Bodenfeuchtewerte [mm/m] c -----------------------------------------------------------------

     DO isch = 1,NSCH
        BF(isch) = SNGL(BFakt(isch) / DBLE(Dicke(isch)))
     END DO
     IF (LWRITE) WRITE(datTSTBF,*)

c ----------------------------------------------------------------- c Übergabe der Abflussbildung [mm/dt] c -----------------------------------------------------------------

     Runoff = MAX(0.0, Nied - ProzRate(BF_InfID,BOD_InfSchichtID))
    +         * REAL(izschr)
     Baseflow = ProzRate(BF_ExxID,BOD_TRSSchichtID) * REAL(izschr)
     ETa = 0.0
     Interflow = 0.0
     DO isch = 1,NSCH
        ETa = ETa + ProzRate(BF_EvaID,isch) + ProzRate(BF_EtaID,isch)
        Interflow = Interflow + ProzRate(BF_IntID,isch)
     END DO
     ETa = ETa * REAL(izschr)
     Interflow = Interflow * REAL(izschr)

c ----------------------------------------------------------------- c Schreiben der Ergebnisse c -----------------------------------------------------------------

     IF (LWRITE) THEN
        DO isch = 1,NSCH

c LTMP = BF_PROZ_WRITE (datTSTBF, 'erg', izschr, isch, c + DBLE(Dicke(isch)), c + BFtmp(isch), BFakt(isch), c + anzfun, ProzRate(1,isch), inNied, c + Runoff, ETa, Interflow, Baseflow) c IF (.NOT.LTMP) GOTO 10000

        END DO
     END IF
     LOK = .TRUE.

c ................................................................. 10000 RETURN

     END FUNCTION BF_WELOK

cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

CXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX C Eine Schicht berechnen

     FUNCTION BF_CALC_SCHICHT (KENSYS, EFLID, isch, Aktdatum, izschr,
    +                          anzzr, anzfun, NSTZ, anzstz, X, Y, m,
    +                          BFMax, BFalt, BFneu, SkalX, SkalY,
    +                          Prozmit)
    +RESULT (LOK)

c .................................................................

     USE MODMISC
     INTEGER       :: EFLID, isch, anzzr, anzfun, NSTZ, izschr, i,
    +                 imyKng
     REAL (KIND=8) :: X(NSTZ, anzfun),
    +                 Y(NSTZ, anzfun),
    +                 m(NSTZ, anzfun),
    +                 SkalX(anzzr + anzfun),
    +                 SkalY(anzzr + anzfun), BFMax, BFalt, BFneu,
    +                 S1, S2, Prozmit(anzfun),
    +                 volfunge, volzrge, Bilanz
     INTEGER, DIMENSION(anzfun) :: anzstz, vorzfun
     INTEGER, DIMENSION(anzzr)  :: vorzzrei
     LOGICAL :: LOK, LERROR, zrevor, unstimm
     CHARACTER (LEN=*) :: Aktdatum
     CHARACTER (LEN=*)  :: KENSYS

c .................................................................

     LOK = .FALSE.

c Input vorhanden

     zrevor = .FALSE.
     IF (anzzr.GT.0) zrevor = .TRUE.

c Vorzeichen des Inputs

     DO i=1,anzzr
        vorzzrei(i) = 1
     END DO

c Vorzeichen der Abgaben

     DO i=1,anzfun
        vorzfun(i) = INT(BF_VORZEICHEN(i))
     END DO

c Inhalt

     S1 = BFalt
     S2 = S1

c Berechnung: nicht-linearer Speicher

     imyKng = KNGBF
     LERROR = SPEIBELI(imyKng, Aktdatum, izschr,
    +          BFMax, S1, S2,
    +          zrevor, anzzr, vorzzrei,
    +          anzfun, anzstz, vorzfun,
    +          X, Y, m, SkalY, SkalX,
    +          unstimm, prozmit,
    +          volfunge, volzrge, Bilanz)
     IF (LERROR) GOTO 10000

c Inhaltszuordnung

     BFneu = S2
     LOK = .TRUE.
     GOTO 10000

c ................................................................. 10000 RETURN

     END FUNCTION BF_CALC_SCHICHT

cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

CXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX c Deallokieren

     SUBROUTINE BF_DELETE()

c .................................................................

     INTEGER  :: i

c ................................................................. c Bodenarten

     DO i=1,BOA_aktanz
        NULLIFY (BOACONT(i) % ptrboa)
     END DO
     IF (BOA_anz.GT.0) THEN
        DEALLOCATE (BOACONT)
        DEALLOCATE (BOA_ID)
     END IF
     BOA_anz = 0
     BOA_aktanz = 0

c Bodentypen

     DO i=1,BOD_aktanz
        NULLIFY (BODCONT(i) % ptrbod)
     END DO
     IF (BOD_anz.GT.0) THEN
        DEALLOCATE (BODCONT)
        DEALLOCATE (BOD_ID)
     END IF
     BOD_anz = 0
     BOD_aktanz = 0

c Landnutzung

     DO i=1,LNZ_aktanz
        NULLIFY (LNZCONT(i) % ptrlnz)
     END DO
     IF (LNZ_anz.GT.0) THEN
        DEALLOCATE (LNZCONT)
        DEALLOCATE (LNZ_ID)
     END IF
     LNZ_anz = 0
     LNZ_aktanz = 0
     IF (BF_INIT) THEN
        BF_INIT = .FALSE.

c DEALLOCATE (BF_FKT_StartX) c DEALLOCATE (BF_FKT_StartBezug) c DEALLOCATE (BF_FKT_EndeX) c DEALLOCATE (BF_FKT_EndeBezug) c DEALLOCATE (BF_FKT_StartY) c DEALLOCATE (BF_FKT_EndeY) c DEALLOCATE (BF_FKT_Expo) c DEALLOCATE (BF_FKTNAME) c DEALLOCATE (LNZ_HAUDEFAK_GRAS) c DEALLOCATE (BF_VORZEICHEN)

     END IF

c ................................................................. 10000 RETURN

     END SUBROUTINE BF_DELETE

cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

CXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX C Eine Schicht nach Überlauf korrigieren c LKORR = .FALSE. : Korrektur nur bei Überlauf c LKORR = .TRUE.  : Bilanzausgleich

     FUNCTION BF_CORRECT_SCHICHT (LKORR, izschr, Nied, BFalt, BFakt,
    +                             N, Proz)
    +RESULT (LOK)

c .................................................................

     INTEGER       :: izschr, iproz, N
     REAL (KIND=8) :: Proz(N), BFalt, BFakt, SumProz, Fehler
     REAL (KIND=4) :: Nied
     LOGICAL :: LOK, LKORR

c .................................................................

     LOK = .FALSE.
     IF (ABS(Proz(BF_MaxID)).GT.0.0 .OR. LKORR) THEN
        IF (.NOT.LKORR) THEN

c Infiltration zurücknehmen

           Proz(BF_InfID) = MAX(0.0, BF_VORZEICHEN(BF_InfID) *
    +                      (ABS(Proz(BF_InfID)) - ABS(Proz(BF_MaxID))))

c Overflow aus Null zurücknehmen

           Proz(BF_MaxID) = 0.0
        END IF

c Bilanz prüfen

        SumProz = 0.0
        DO iproz = 1,N
           SumProz = SumProz + ABS(Proz(iproz)) *
    +                          REAL(BF_VORZEICHEN(iproz))
        END DO
        Fehler = BFalt - BFakt + SumProz * REAL(izschr)
        IF (Fehler.NE.0.0) THEN
           Proz(BF_InfID) = Proz(BF_InfID) - Fehler / REAL(izschr)
           IF (ABS(Proz(BF_InfID)).GT.DBLE(Nied)) THEN
              Proz(BF_InfID) = DBLE(Nied) * BF_VORZEICHEN(BF_InfID)
           ELSEIF (ABS(Proz(BF_InfID)).LT.0.0) THEN
              Proz(BF_InfID) = 0.0
           END IF
        END IF
     END IF
     LOK = .TRUE.
     GOTO 10000

c ................................................................. 10000 RETURN

     END FUNCTION BF_CORRECT_SCHICHT

cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

CXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX C Bei einem Überlauf einer Bodenschicht wird die Infiltration um c den Betrag des Überlaufes reduziert, soweit wie möglich. c Überlauf bleibt erhalten als zusätzlicher Input für die c darüberliegende Schicht

     SUBROUTINE BF_BILANZ_SCHICHT (izschr, BFalt, BFakt, N, Proz)

c .................................................................

     INTEGER       :: izschr, N
     REAL (KIND=8) :: Proz(N), BFalt, BFakt

c ................................................................. c Infiltration um den Betrag des Überlaufs zurücknehmen

     IF (ABS(Proz(BF_MaxID)).GT.0. .AND. Proz(BF_InfID).GT.0.) THEN
        Proz(BF_InfID) = ABS(Proz(BF_InfID)) - ABS(Proz(BF_MaxID))
        IF (Proz(BF_InfID).LT.0.) Proz(BF_InfID) = 0.0
     END IF

c ................................................................. 10000 RETURN

     END SUBROUTINE BF_BILANZ_SCHICHT

cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

CXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX c neue Bodenfeuchte aus den Bodenprozessen mit einfacher c Kontigleichung berechnen

     SUBROUTINE BF_KONTI_SCHICHT (izschr, BFalt, BFakt,
    +                             N, Proz)

c .................................................................

     INTEGER       :: izschr, iproz, N
     REAL (KIND=8) :: Proz(N), BFalt, BFakt, SumProz

c .................................................................

     SumProz = 0.0
     DO iproz=1,N
        IF (iproz.NE.BF_MaxID) THEN
              SumProz = SumProz + Proz(iproz) * REAL(izschr)
        END IF
     END DO
     BFakt = BFalt + SumProz

c ................................................................. 10000 RETURN

     END SUBROUTINE BF_KONTI_SCHICHT

cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

     FUNCTION BOA_CHECK_ID (ID) RESULT (LOK)

c .................................................................

     INTEGER  :: ID, i
     LOGICAL  :: LOK

c .................................................................

     LOK = .FALSE.
     DO i=1,BOA_aktanz
        IF (BOACONT(i) % ptrboa % BOAID.EQ.ID) THEN
           LOK = .TRUE.
           GOTO 10000
        END IF
     END DO

c ................................................................. 10000 RETURN

     END FUNCTION BOA_CHECK_ID

cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

     FUNCTION BOD_CHECK_ID (ID) RESULT (LOK)

c .................................................................

     INTEGER  :: ID, i
     LOGICAL  :: LOK

c .................................................................

     LOK = .FALSE.
     DO i=1,BOD_aktanz
        IF (BODCONT(i) % ptrbod % BODID.EQ.ID) THEN
           LOK = .TRUE.
           GOTO 10000
        END IF
     END DO

c ................................................................. 10000 RETURN

     END FUNCTION BOD_CHECK_ID

cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

     FUNCTION LNZ_CHECK_ID (ID) RESULT (LOK)

c .................................................................

     INTEGER  :: ID, i
     LOGICAL  :: LOK

c .................................................................

     LOK = .FALSE.
     DO i=1,LNZ_aktanz
        IF (LNZCONT(i) % ptrlnz % LNZID.EQ.ID) THEN
           LOK = .TRUE.
           GOTO 10000
        END IF
     END DO

c ................................................................. 10000 RETURN

     END FUNCTION LNZ_CHECK_ID

cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

     FUNCTION BOA_GET_ATTRIB (BOAID, BoArt, WP, FK, GPV, kf,
    +                         MaxInf, MaxKap)
    +RESULT (LOK)

c .................................................................

     TYPE (BOA_type), POINTER   :: objptr
     REAL     :: WP, FK, GPV, kf, MaxInf, MaxKap
     INTEGER  :: ID, BOAID, BoArt
     LOGICAL  :: LOK

c .................................................................

     LOK = .FALSE.
     WP = 0.0
     FK = 0.0
     GPV = 0.0
     kf = 0.0
     MaxInf = 0.0
     MaxKap = 0.0
     BoArt = 0
     ID = BOA_GET_ID (BOAID)
     IF (ID.GT.0) THEN
        objptr => BOA_IDObj (ID)
        WP = objptr % WP
        FK = objptr % FK
        GPV = objptr % GPV
        kf = objptr % kf
        MaxInf = objptr % MaxInf
        MaxKap = objptr % MaxKap
        BoArt = objptr % BOART
        LOK = .TRUE.
     END IF

c ................................................................. 10000 RETURN

     END FUNCTION BOA_GET_ATTRIB

cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

     FUNCTION LNZ_GET_WE (LNZID) RESULT (WE)

c .................................................................

     TYPE (LNZ_type), POINTER   :: objptr
     REAL     :: WE
     INTEGER  :: LNZID, ID

c .................................................................

     WE = 0.0
     ID = LNZ_GET_ID(LNZID)
     IF (ID.GT.0) THEN
        objptr => LNZ_IDObj (ID)
        WE = objptr % WE
     END IF

c ................................................................. 10000 RETURN

     END FUNCTION LNZ_GET_WE

cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

     FUNCTION LNZ_GET_HAUDEFAK (LNZID, imon) RESULT (FAK)

c .................................................................

     USE MODGGL
     TYPE (LNZ_type), POINTER   :: objptr
     REAL     :: FAK, tmp
     INTEGER  :: LNZID, ID, imon

c .................................................................

     FAK = LNZ_HAUDEFAK_CONST
     ID = LNZ_GET_ID(LNZID)
     IF (ID.GT.0) THEN
        objptr => LNZ_IDObj (ID)
        If (objptr % HaudeFakJGG.GT.0) THEN
           tmp = GGL_WERT (1.0, imon, 1, 1, 1,
    +                      objptr % HaudeFakJGG, 0, 0)
           IF (tmp.LT.NULL) THEN
              FAK = 1.0             !Haudefaktor = 0: Es darf keine Veränderung an der pot. Verdunstung geben
           ELSE
              FAK = tmp / LNZ_HAUDEFAK_GRAS(imon) !Haudefaktor > 0: Pot. Verdunstung erfährt Veränderung
           END IF
        ELSE
           FAK = LNZ_HAUDEFAK_CONST / LNZ_HAUDEFAK_GRAS(imon)
        ENDIF
     END IF

c ................................................................. 10000 RETURN

     END FUNCTION LNZ_GET_HAUDEFAK

cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

     FUNCTION LNZ_ETP_ADJUST (EvaKng, ETpIn, HaudeVerdFak)
    +RESULT (ETpOut)

c .................................................................

     REAL     :: ETpIn, ETpOut, HaudeVerdFak
     INTEGER  :: EvaKng

c .................................................................

     IF (EvaKng.EQ.EVA_HaudeID) THEN
        ETpOut = DBLE(ETpIn * HaudeVerdFak)
     ELSEIF (EvaKng.EQ.EVA_BelmansID) THEN
        ETpOut = ETpIn
     ELSEIF (EvaKng.EQ.EVA_PotentiellID) THEN
        ETpOut = ETpIn
     END IF

c ................................................................. 10000 RETURN

     END FUNCTION LNZ_ETP_ADJUST

cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx


cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

     FUNCTION LNZ_GET_PARA (LNZID, imon, MaxINTC, LAI, BedGrad,
    +                       HaudeFak)
    +RESULT(LOK)

c .................................................................

     USE MODGGL
     TYPE (LNZ_type), POINTER   :: objptr
     REAL     :: LAI, MaxINTC, BedGrad, HaudeFak
     INTEGER  :: ID, LNZID, imon
     LOGICAL  :: LOK

c .................................................................

     LOK = .FALSE.
     ID = LNZ_GET_ID(LNZID)
     IF (ID.GT.0) THEN
        objptr => LNZ_IDObj(ID)
        LAI = GGL_WERT (objptr % BFI, imon, 1, 1, 1,
    +                   objptr % BFIJGG, 0, 0)
        MAXINTC = 0.935 + 0.498 * LAI - 0.00575 * LAI * LAI
        BedGrad = GGL_WERT (objptr % BG, imon, 1, 1, 1,
    +                       objptr % BGJGG, 0, 0)
        If (objptr % HaudeFakJGG.GT.0) THEN
           HaudeFak = GGL_WERT (1.0, imon, 1, 1, 1,
    +                           objptr % HaudeFakJGG, 0, 0)
        ELSE
           HaudeFak = LNZ_HAUDEFAK_GRAS(imon)
        ENDIF
        LOK = .TRUE.
     END IF

c ................................................................. 10000 RETURN

     END FUNCTION LNZ_GET_PARA

cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

     SUBROUTINE BF_GET_ETPANSATZ (EvaKng, ETpKng)

c .................................................................

     INTEGER  :: EvaKng, ETpKng

c .................................................................

     EvaKng = EVA_HaudeID

c EVA_BelmansID c EvaKng = EVA_PotentiellID

     ETpKng = ETP_LinearID

c ................................................................. 10000 RETURN

     END SUBROUTINE BF_GET_ETPANSATZ

cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx c Aggregation des Simulationsbodens aus den Eingangsdaten

     FUNCTION BF_BODEN_PREPARE (BODID, WE, Dicke,
    +                           SimBOART, SimWP, SimFK, SimGPV,
    +                           SimKF, SimMaxInf, SimMaxKap)
    +RESULT(iKNG)

c .................................................................

     TYPE (BOD_type), POINTER   :: objptr
     REAL    :: Gewicht(BF_MAX_SCHICHTEN, BF_SIM_SCHICHTEN),
    +           SimWP(BF_SIM_SCHICHTEN), SimFK(BF_SIM_SCHICHTEN),
    +           SimGPV(BF_SIM_SCHICHTEN), Simkf(BF_SIM_SCHICHTEN),
    +           SimMaxInf(BF_SIM_SCHICHTEN),
    +           SimMaxKap(BF_SIM_SCHICHTEN),
    +           Dicke(BF_SIM_SCHICHTEN),
    +           WE
     INTEGER :: SimBOART(BF_SIM_SCHICHTEN), BODID, ID, iKNG, iTMP

c .................................................................

     iKNG = ERR_BOD_PARAMETER
     iTMP = 0
     ID = BOD_GET_ID (BODID)
     IF (ID.GT.0) THEN
        objptr => BOD_IDObj (ID)
        iTMP = BF_SCHICHT_PARA (objptr, WE, Dicke(1), Gewicht(1,1))
        IF (iTMP.LT.0) GOTO 9999
        iTMP = BF_BODEN_PARA (objptr, Gewicht(1,1), SimBOART(1),
    +                         SimWP(1), SimFK(1), SimGPV(1), SimKF(1),
    +                         SimMaxInf(1), SimMaxKap(1))
        IF (iTMP.LT.0) GOTO 9999
        iKNG = 0
     END IF
     IF (LBFOUT) THEN
        CALL BF_BODEN_WRITE(ID, datTSTBF,
    +                       BF_SIM_SCHICHTEN, SimBOART,
    +                       Dicke, SimWP, SimFK, SimGPV,
    +                       SimKF, SimMaxInf, SimMaxKap)
     END IF
     GOTO 10000

c ................................................................. 9999 iKNG = iTMP

     GOTO 10000

c ................................................................. 10000 RETURN

     END FUNCTION BF_BODEN_PREPARE

cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx c Berechnung der Bodendicken und Wichtungsfaktoren zur Simulation c (nach Marcus Lempert + Stefan Bente), modifiziert (HL)

     FUNCTION BF_SCHICHT_PARA (objptr, WE, SimDicke, Gewicht)
    +RESULT(iKNG)

c .................................................................

     USE MODERR
     TYPE (BOD_type), POINTER   :: objptr
     INTEGER :: iKng, i, j, istart
     REAL    :: Gewicht(BF_MAX_SCHICHTEN, BF_SIM_SCHICHTEN),
    +           SimDicke(BF_SIM_SCHICHTEN),
    +           dA(BF_MAX_SCHICHTEN), dE(BF_MAX_SCHICHTEN),
    +           dASim(BF_SIM_SCHICHTEN), dESim(BF_SIM_SCHICHTEN),
    +           WE, dAnf, dEnd, dD, GesDicke, Summe
     LOGICAL :: LTMP

c .................................................................

     iKng = ERR_BOD_PARAMETER

c Gesamtdicke des original Bodens

     GesDicke = objptr % Dicke(1)
     dA(1) = 0
     DO i=2,objptr % NBOA
        dE(i-1) = GesDicke
        dA(i) = dE(i-1)
        GesDicke = GesDicke + objptr % Dicke(i)
     END DO
     dE(objptr % NBOA) = GesDicke

c Schichtdicken des Simulationsbodens c Wurzeltiefe ausreichend!

     IF (WE.LT.(BOD_dInfSchicht + BOD_minD_WESchicht)) THEN
        Err_Kennung = ERR_LNZ_PARAMETER
        If (.NOT.DLL_MODE) THEN
           LTMP = FEHLER(3323, 'WE  ', '    ', objptr % BodID)
           GOTO 9999
        END IF
     END IF

c Wurzeltiefe zu gross

     IF (WE.GT.GesDicke) WE = GesDicke

c Gesamtdicke ausreichend!

     IF (GesDicke.LT.(BOD_dInfSchicht +
    +                 BOD_minD_WESchicht +
    +                 BOD_minD_TRSSchicht)) THEN
        Err_Kennung = ERR_LNZ_PARAMETER
        GOTO 9999
     END IF

c Berechnungsschichtdicken zuweisen

     SimDicke(BOD_InfSchichtID) = BOD_dInfSchicht
     SimDicke(BOD_WESchichtID)  = WE - SimDicke(BOD_InfSchichtID)
     SimDicke(BOD_TRSSchichtID) = GesDicke -
    +                            (SimDicke(BOD_InfSchichtID) +
    +                             SimDicke(BOD_WESchichtID))

c Berechnungsschichtdicke TRS-Schicht prüfen

     IF (SimDicke(BOD_TRSSchichtID).LT.BOD_minD_TRSSchicht) THEN
        SimDicke(BOD_WESchichtID) = SimDicke(BOD_WESchichtID) -
    +                               BOD_minD_TRSSchicht
        SimDicke(BOD_TRSSchichtID) = BOD_minD_TRSSchicht
     END IF

c Gesamtdicke des Simulationsbodens

     DO j=1,objptr % NBOA
        Gewicht(j,1) = 0.0
     END DO
     GesDicke = SimDicke(1)
     dASim(1) = 0
     DO i=2,BF_SIM_SCHICHTEN
        dESim(i-1) = Gesdicke
        dASim(i) = dESim(i-1)
        GesDicke = GesDicke + SimDicke(i)
        DO j=1,objptr % NBOA
           Gewicht(j,i) = 0.0
        END DO
     END DO
     dESim(BF_SIM_SCHICHTEN) = GesDicke

c Berechnung der Anteile der jeweiligen Bodenschicht an der Simulationsschicht

     istart = 1
     DO i=1,BF_SIM_SCHICHTEN
        j = istart
        DO WHILE (dE(j).LE.dASim(i))
           j = j + 1
           IF (j.GT.objptr % NBOA) EXIT
        END DO
        IF (j.GT.objptr % NBOA) j = j - 1
        DO WHILE (dA(j).LT.dESim(i))
           dAnf = MAX(0.,dASim(i) - dA(j))
           dD = dE(j) - dA(j)
           dEnd = MAX(0.,dE(j) - dESim(i))
           Gewicht(j,i) = (dD - dAnf - dEnd) / (dESim(i) - dASim(i))
           j = j + 1
           IF (j.GT.objptr % NBOA) EXIT
        END DO
        istart = j - 1
     END DO

c Wichtungsfaktoren müssen in der Summe 1 ergeben

     DO i=1,BF_SIM_SCHICHTEN
        Summe = 0.
        DO j = 1, objptr % NBOA
           Summe = Summe + Gewicht(j, i)
        END DO
        IF (ABS (1.-Summe) .GT. NULL) THEN
           ERR_KENNUNG = ERR_BOD_PARAMETER
           GOTO 9999
        END IF
     END DO
     iKng = 0
     GOTO 10000

c ................................................................. 9999 iKng = Err_Kennung

     GOTO 10000

c ................................................................. 10000 RETURN

     END FUNCTION BF_SCHICHT_PARA

cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx c Berechnung der Bodengroessen aus Wichtungsfaktoren zur Simulation c (nach Marcus Lempert + Stefan Bente)

     FUNCTION BF_BODEN_PARA (objptr, Gewicht, SimBOART,
    +                        SimWP, SimFK, SimGPV, SimKF,
    +                        SimMaxInf, SimMaxKap)
    +RESULT(iKNG)

c .................................................................

     TYPE (BOD_type), POINTER   :: objptr
     INTEGER :: SimBOART(BF_SIM_SCHICHTEN), BodenArt, i, j, iKNG
     REAL    :: Gewicht(BF_MAX_SCHICHTEN, BF_SIM_SCHICHTEN),
    +           SimWP(BF_SIM_SCHICHTEN), SimFK(BF_SIM_SCHICHTEN),
    +           SimGPV(BF_SIM_SCHICHTEN), Simkf(BF_SIM_SCHICHTEN),
    +           SimMaxKap(BF_SIM_SCHICHTEN),
    +           SimMaxInf(BF_SIM_SCHICHTEN),
    +           WP, FK, GPV, kf, MaxInf, MaxKap, tmpBoart
     LOGICAL :: LTMP

c .................................................................

     iKNG = ERR_BOD_PARAMETER
     DO i=1,BF_SIM_SCHICHTEN
        tmpBoart = 0.0
        SimWP(i) = 0.0
        SimFK(i) = 0.0
        SimGPV(i) = 0.0
        SimKf(i) = 0.0
        SimMaxInf(i) = 0.0
        SimMaxKap(i) = 0.0
        DO j=1,objptr % NBOA
           LTMP = BOA_GET_ATTRIB (objptr % BOAID(j), BodenArt,
    +                             WP, FK, GPV, kf, MaxInf, MaxKap)
           IF (.NOT.LTMP) GOTO 9999
           SimWP(i) = SimWP(i) + WP * Gewicht(j,i)
           SimFK(i) = SimFK(i) + FK * Gewicht(j,i)
           SimGPV(i) = SimGPV(i) + GPV * Gewicht(j,i)
           tmpBoart = tmpBoart + REAL(BodenArt) * Gewicht(j,i)
           SimBOART(i) = MIN(SimBOART(i),BF_ANZ_BOART)
           SimBOART(i) = MAX(SimBOART(i),1)
           IF (kf.GT.GLOBAL_NULL) THEN
              SimKf(i) = SimKf(i) + Gewicht(j,i) / kf
           END IF
           IF (MaxKap.GT.GLOBAL_NULL) THEN
              SimMaxKap(i) = SimMaxKap(i) + Gewicht(j,i) / MaxKap
           END IF
           !Nur die SimInfSchicht erhält die MaxInf aus der obersten Schicht
           If (i.EQ.BOD_InfSchichtID) SimMaxInf(i) = MaxInf
        END DO
        tmpBoart = MAX(1.0,(tmpBoart/REAL(objptr % NBOA)))
        SimBOART(i) = NINT(MIN(REAL(BF_ANZ_BOART), tmpBOART))

c kf-Wert Aggregation nach Prinzip Erhaltung der Kontinuität der Strömung /H.Lohr (1993), Vertieferarbeit, S. 73/

        If (SimKf(i).GT.GLOBAL_NULL) THEN
           SimKf(i) = 1.0 / SimKf(i)
        ELSE
           ERR_KENNUNG = ERR_BOD_PARAMETER
           GOTO 9999
        END IF

c MaxKap-Wert Aggregation nach Prinzip Erhaltung der Kontinuität der Strömung /H.Lohr (1993), Vertieferarbeit, S. 73/

        If (SimMaxKap(i).GT.GLOBAL_NULL) THEN
           SimMaxKap(i) = 1.0 / SimMaxKap(i)
        ELSE
           SimMaxKap(i) = 0.0
        END IF
     END DO
     iKNG = 0
     GOTO 10000

c ................................................................. 9999 iKNG = ERR_KENNUNG

     GOTO 10000

c ................................................................. 10000 RETURN

     END FUNCTION BF_BODEN_PARA

cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

CXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX C Funktionsverlauf fuer Bodenart/Prozess bestimmen

     FUNCTION BF_FKT_X (BOART, iProzess, XSkal, WP, FK, GPV, X)
    +RESULT (NSTZ)

c .................................................................

     REAL (KIND=8) :: X(BF_MAXSTZ), BFWert(BF_ANZ_BEZUG),
    +                 dX, BFMax1, BFMax2, nFK, BFStart, BFEnd, xEnd
     REAL (KIND=4) :: XSkal, WP, FK, GPV
     INTEGER       :: BOART, iProzess, istz, istart, NSTZ

c .................................................................

     NSTZ = 0
     BFWert(wpBF) = DBLE(WP)
     BFWert(fkBF) = DBLE(FK)
     BFWert(nfkBF) = DBLE(FK - WP)
     BFWert(gpvBF) = DBLE(GPV)

c Maximalen X-Wert festlegen

     BFMax1 = DBLE(BF_XMAX_FAKTOR * GPV)
     BFMax2 = DBLE(GPV) * DBLE(BF_XMAX_FAKTOR**2.)
     nFK = DBLE(FK - WP)

c Stützstellen festlegen, die für alle gültig sind

     istz = 1
     X(istz) = 0.0

c Konstanter Funktionsverlauf

     IF (iProzess.EQ.BF_ConstID) THEN
        istz = istz + 1
        X(istz) = 0.001
        istz = istz + 1
        X(istz) = BFWert(gpvBF) / 1.01
        GOTO 9000
     END IF

c Stützstellen festlegen: X-Werte sind zwischen 0 und BFMax definiert

     BFStart = BF_FKT_StartX(iProzess,BOART) *
    +          BFWert(BF_FKT_StartBezug(iProzess,BOART))
     !X-Werte zählen von BF=0 bis FK, obwohl nFk steht
     IF (BF_FKT_StartBezug(iProzess,BOART).EQ.nfkBF)
    +   BFStart = BFStart + BFWert(wpBF)
     !Startwert
     istart = BF_STZ_START
     X(istart) = BFStart
     !Endwert
     BFEnd = BF_FKT_EndeX(iProzess,BOART) *
    +        BFWert(BF_FKT_EndeBezug(iProzess,BOART))
     !X-Werte zählen von BF=0 bis FK, obwohl nFk steht
     IF (BF_FKT_EndeBezug(iProzess,BOART).EQ.nfkBF)
    +   BFEnd = BFEnd + BFWert(wpBF)
     !Fuer kap. Aufstieg gilt: Ende ist gleich Anfang von Exfil
     IF (iProzess.EQ.BF_KapID) THEN
        BFEnd = BF_FKT_StartX(BF_ExxID,BOART) *
    +           BFWert(BF_FKT_StartBezug(BF_ExxID,BOART))
        !X-Werte zählen von BF=0 bis FK, obwohl nFk steht
        IF (BF_FKT_StartBezug(BF_ExxID,BOART).EQ.nfkBF) THEN
           BFEnd = BFEnd + BFWert(wpBF)
        END IF
     END IF
     IF (iProzess.NE.BF_MaxID) THEN
        xEnd = BFEnd
        IF (xEnd.GE.BFWert(gpvBF)) xEnd = BFWert(gpvBF) / 1.01
        !X-Schrittweite als Verhältniszahl berechnen
        dX = (xEnd - BFStart) / DBLE(BF_FKTSTZ-BF_STZ_REST)
        istz = BF_STZ_START
        DO WHILE (X(istz).LT.xEnd)
           istz = istz + 1
           X(istz) = X(istz-1) + dX
           X(istz) = X(istz)
        END DO
        !Endwert des Funktionsverlaufes
        istz = istz - 1
        X(istz) = xEnd
        istz = istz + 1
        X(istz) = BFWert(gpvBF)
     ELSEIF (iProzess.EQ.BF_MaxID) THEN
        istz = istart
     END IF

c letzte Stützstellen ist immer groesser als GPV 9000 istz = istz + 1

     X(istz) = BFMax1
     istz = istz + 1
     X(istz) = BFMax2
     NSTZ = istz
     DO istz=1,NSTZ
        X(istz) = X(istz) * DBLE(XSkal)
     END DO

c ................................................................. 10000 RETURN

     END FUNCTION BF_FKT_X

cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

CXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX C Funktionsverlauf fuer Bodenart/Prozess bestimmen

     FUNCTION BF_FKT_Y(SchichtID, BOART, iProzess, EtpKng,
    +                  MaxInf, kf, MaxKap, ANZ, X, Y, SkalY)
    +RESULT (NSTZ)

c .................................................................

     INTEGER       :: SchichtID, BOART, iProzess, EtpKng,
    +                 NSTZ, ANZ, istz, istart, iend
     REAL (KIND=8) :: X(ANZ), Y(ANZ), SkalY, EndWert, LastFktWert
     REAL (KIND=4) :: MaxInf, kf, MaxKap

c .................................................................

     NSTZ = 0

c Letzter Funktionswert ist immer Null

     LastFktWert = BF_LAST_YWERT
     EndWert = BF_LAST_YWERT
     istart = BF_STZ_START
     iend = ANZ - BF_STZ_REST - 1

c Erster Funktionswert ist immer Null

     istz = 1
     Y(istz) = 0.0
     SELECT CASE (iProzess)
         CASE (BF_ConstID)
              !konstante Funktion
              DO istz=2,ANZ
                 Y(istz) = 1.0
              END DO
              SkalY = 1.0
         CASE (BF_InfID)
              !Ansatz nach Holtan: Inf = MaxInf * ((Xend-X)/Xend-Xstart)^expo + kf ; Skalierung = MaxInf+kf
              !X = 0; Y = ?
              Y(istz) = BF_FKT_StartY(iProzess,BOART)
              !Ester Wert des Funktionsverlaufes
              Y(istart) = BF_FKT_StartY(iProzess,BOART)
              DO istz = istart + 1, iend
                 Y(istz) = ((X(iend)-X(istz))/(X(iend)-X(istart)))**
    +                       BF_FKT_EXPO(iProzess,BOART)
                 Y(istz) = DBLE(MaxInf) * Y(istz)
                 Y(istz) = Y(istz) + DBLE(kf)
                 !Skalierung zwischen 0 und 1
                 IF ((MaxInf+kf).GT.GLOBAL_NULL) THEN
                    Y(istz) = Y(istz) / DBLE(MaxInf+kf)
                 ELSE
                    Y(istz) = 0.
                 END IF
              END DO
              SkalY = DBLE(MaxInf+kf)
         CASE (BF_ExxID)
              !Ansatz nach Irmay/Bear: Exx = kf*(X-Xstart)/Xend-Xstart)^expo ;   Skalierung = kf
              !X = 0; Y = ?
              Y(istz) = 0.0
              !Ester Wert des Funktionsverlaufes
              Y(istart) = BF_FKT_StartY(iProzess,BOART)
              DO istz = istart + 1, iend
                 !Y-Werte sind bereits zwischen 0 und 1 skaliert
                 Y(istz) = (X(istz)-X(istart)) / (X(iend)-X(istart))
                 Y(istz) = Y(istz) ** BF_FKT_EXPO(iProzess,BOART)
              END DO
              SkalY = DBLE(kf)
         CASE (BF_IntID)
              !X = 0; Y = ?
              Y(istz) = 0.0
              !Ester Wert des Funktionsverlaufes
              Y(istart) = BF_FKT_StartY(iProzess,BOART)
              DO istz = istart + 1, iend
                 !Y-Werte sind bereits zwischen 0 und 1 skaliert
                 Y(istz) = (X(istz)-X(istart)) / (X(iend)-X(istart))
                 Y(istz) = Y(istz) ** BF_FKT_EXPO(iProzess,BOART)
              END DO
              !Interflow nur in der Infiltrationsschicht:
              IF (SchichtID.EQ.BOD_InfSchichtID) THEN
                 SkalY = DBLE(kf)
              ELSE
                 SkalY = 0.0
              END IF
         CASE (BF_KapID)
              ! kap. Aufstieg geht linear auf 0 am Punkt, wo Exfil anfaengt!
              !X = 0; Y = ?
              Y(istz) = BF_FKT_StartY(iProzess,BOART)
              !Ester Wert des Funktionsverlaufes
              Y(istart) = BF_FKT_StartY(iProzess,BOART)
              DO istz = istart + 1, iend
                 !Y-Werte sind bereits zwischen 0 und 1 skaliert
                 Y(istz) = 1.0-(X(istz)-X(istart))/(X(iend)-X(istart))
              END DO
              !Kapauf nicht in der Infiltrationsschicht:
              IF (SchichtID.EQ.BOD_InfSchichtID) THEN
                 SkalY = 0.0
              ELSE
                 SkalY = DBLE(MaxKap)
              END IF
         CASE (BF_EvaID)
              ! Evaporation geht linear von 0.0 bei WP bis 1.0 bei FK; Skalierung in BF_WEL
              !X = 0; Y = ?
              Y(istz) = 0.0
              !Ester Wert des Funktionsverlaufes
              Y(istart) = BF_FKT_StartY(iProzess,BOART)
              DO istz = istart + 1, iend
                 Y(istz) = (X(istz)-X(istart)) / (X(iend)-X(istart))
              END DO
              !Evaporation nur in der Inf-Schicht:
              IF (SchichtID.EQ.BOD_InfSchichtID) THEN
                 SkalY = 1.0
              ELSE
                 SkalY = 0.0
              END IF
         CASE (BF_EtaID)
              !X = 0; Y = ?; Skalierung in BF_WEL
              Y(istz) = 0.0
              !Ester Wert des Funktionsverlaufes
              Y(istart) = BF_FKT_StartY(iProzess,BOART)
              ! Evapotranspiration geht linear von 0.0 bei WP bis 1.0
              IF (EtpKng.EQ.ETP_LinearID) THEN
                 DO istz = istart + 1, iend
                    Y(istz) = (X(istz)-X(istart)) / (X(iend)-X(istart))
                 END DO
              ELSEIF (EtpKng.EQ.ETP_AlbertID) THEN
                 DO istz = istart + 1, iend
                    Y(istz) = (X(istz)-X(istart)) / (X(iend)-X(istart))
                 END DO
              END IF
              !Evapotranspiration nur in der Wurzelschicht:
              IF (SchichtID.EQ.BOD_WESchichtID) THEN
                 SkalY = 1.0
              ELSE
                 SkalY = 0.0
              END IF
         CASE (BF_MaxID)
              Y(istz) = 0.0
              !Ester Wert des Funktionsverlaufes
              Y(istart) = BF_FKT_StartY(iProzess,BOART)
              !Letzter Wert des Funktionsverlaufes
              LastFktWert = 1.0
              EndWert = 1.0
              SkalY = BF_YMAX_FAKTOR
     END SELECT
     Y(ANZ-2) = Y(iend)

c vorletzte Stützstelle ist bereits auf BF_LAST_YWERT abgedreht

     Y(ANZ-1) = LastFktWert

c letzte Stützstellen ist immer BF_LAST_YWERT nach GPV: Abbrehen der Funktionen

     Y(ANZ) = EndWert
     NSTZ = ANZ
     Goto 10000

c ................................................................. 10000 RETURN

     END FUNCTION BF_FKT_Y

cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

CXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX C Funktionsverlauf fuer Bodenart/Prozess in Datei schreiben

     FUNCTION BF_FKT_WRITE (datnr, izschr, iProzess,
    +                       KENSYS, EFLID, isch,
    +                       WP, FK, GPV,
    +                       Dicke, BFFak,
    +                       N, X, Y, SkalY, Vorz)
    +RESULT (LOK)

c .................................................................

     INTEGER       :: datnr, izschr, N, iProzess, EFLID, isch, i
     REAL (KIND=8) :: X(N), Y(N), SkalY, tmpSkal, myX
     REAL (KIND=4) :: WP, FK, GPV, Dicke, BFFak, Vorz
     LOGICAL       :: LOK
     CHARACTER (LEN=*) :: KENSYS

c ................................................................. 100 FORMAT(1X, 2(1X, F35.10))

     LOK = .FALSE.

c tmpSkal = SkalY * REAL(izschr)

     tmpSkal = SkalY
     OPEN (UNIT=datnr, FILE=TRIM(BF_FKTNAME(iProzess))//'.FKT',
    +                  STATUS='UNKNOWN', POSITION='APPEND',  ERR=10000)

c WRITE(datnr, '(A)') '*FKT'

     WRITE(datnr, '(A,1X,A,I4,1X,I4,3(1X,F8.3))')
    +    TRIM(BF_FKTNAME(iProzess)), KENSYS, EFLID, isch,
    +                                WP, FK, GPV
     DO i=1,N
        myX = X(i) / (Dicke * BFFak)
        WRITE(datnr, 100) myX, Y(i) * tmpSkal * Vorz
     END DO
     LOK = .TRUE.

c .................................................................

     CLOSE(datnr)

10000 RETURN

     END FUNCTION BF_FKT_WRITE

cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

CXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX C Bodenprozesse in Datei schreiben

     FUNCTION BF_PROZ_WRITE (datnr, Kensys, EFLID, cKng, izschr, isch,
    +                        BfFak,
    +                        Dicke, BFalt, BF, N, Proz,
    +                        Nied, Runoff, ETa, Interflow, Baseflow)
    +RESULT (LOK)

c .................................................................

     INTEGER       :: datnr, izschr, EFLID, isch, N, i
     REAL (KIND=8) :: Proz(N), tmpProz(N),
    +                 Dicke, BF, BFalt, SumProz, Fehler
     REAL (KIND=4) :: Nied, Runoff, ETa, Interflow, Baseflow, BfFak
     LOGICAL       :: LOK
     CHARACTER (LEN=*) :: Kensys
     CHARACTER (LEN=*) :: cKng

c ................................................................. 100 FORMAT(1X, A4, I5, A3, I5, 100(F15.3))

     LOK = .FALSE.
     DO i=1,N
        tmpProz(i) = Proz(i) / BfFak
     END DO
     SumProz = 0.0

c Summe der Prozesse ohne Überlauf, da der in der Infiltration berücksichtigt wurde

     DO i=1,N
        IF (i.NE.BF_MaxID) THEN
           SumProz = SumProz + tmpProz(i)
        END IF
     END DO
     Fehler = Bfalt/BfFak - BF/BfFak + SumProz * DBLE(izschr)
     WRITE(datnr, 100) Kensys, EFLID, cKng, isch,
    +                  BF/Dicke, BFalt/BfFak, BF/BfFak,
    +                 (tmpProz(i)*REAL(izschr),i=1,N), Fehler

c IF (cKng.EQ.'erg' .AND. isch.EQ.BF_SIM_SCHICHTEN) THEN c WRITE(datnr, '(5(A10))') 'HN [mm]', 'HNeff[mm]', c + ' ETa [mm]', 'Int [mm]', 'Base [mm]' c WRITE(datnr, '(5(F10.3))') Nied, Runoff, ETa, c + Interflow, Baseflow c END IF

     LOK = .TRUE.

c ................................................................. 1000 RETURN

     END FUNCTION BF_PROZ_WRITE

cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

CXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX C Bodenschichtung in Datei schreiben

     SUBROUTINE BF_BODEN_WRITE (ID, datnr, N, BOART, DICKE,
    +                           WP, FK, GPV, KF, MaxInf, MaxKap)

c .................................................................

     INTEGER       :: ID, datnr, N, i
     INTEGER       :: BOART(N)
     REAL (KIND=4) :: Dicke(N), WP(N), FK(N), GPV(N),
    +                 KF(N), MaxInf(N), MaxKap(N)

c ................................................................. 100 FORMAT(1X, 3(I3), 7(F10.5))

     CALL BF_OPENFILE(datnr)
     DO i=1,N
        WRITE(datnr, 100) ID, i, BOART(i), Dicke(i),
    +                     WP(i), FK(i), GPV(i), KF(i),
    +                     MaxInf(i), maxKap(i)
     END DO
     WRITE(datnr, *)

c ................................................................. 1000 RETURN

     END SUBROUTINE BF_BODEN_WRITE

cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

CXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX C Mindestwurzeltiefe

     FUNCTION BF_LNZ_MINWE () RESULT (MinWE)

c .................................................................

     REAL      :: MinWE

c .................................................................

     MinWE = BOD_minDicke

c ................................................................. 10000 RETURN

     END FUNCTION BF_LNZ_MINWE

cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

CXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX C Versionsnummer des Moduls

     FUNCTION BF_VERSION () RESULT (VERSION)

c .................................................................

     REAL      :: VERSION

c .................................................................

     VERSION = BF_MODUL_VERSION

c ................................................................. 10000 RETURN

     END FUNCTION BF_VERSION

cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

CXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX C ID zu einer BOAID

     FUNCTION BOA_GET_ID (BOAID) RESULT (ID)

c .................................................................

     INTEGER  :: ID, BOAID, i

c .................................................................

     ID = 0
     DO i=1,BOA_aktanz
        IF (BOACONT(i) % ptrboa % BOAID.EQ.BOAID) THEN
           ID = i
           EXIT
        END IF
     END DO

c ................................................................. 10000 RETURN

     END FUNCTION BOA_GET_ID

cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

CXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX C ID zu einer BODID

     FUNCTION BOD_GET_ID (BODID) RESULT (ID)

c .................................................................

     INTEGER  :: ID, BODID, i

c .................................................................

     ID = 0
     DO i=1,BOD_aktanz
        IF (BODCONT(i) % ptrbod % BODID.EQ.BODID) THEN
           ID = i
           EXIT
        END IF
     END DO

c ................................................................. 10000 RETURN

     END FUNCTION BOD_GET_ID

cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

CXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX C ID zu einer LNZID

     FUNCTION LNZ_GET_ID (LNZID) RESULT (ID)

c .................................................................

     INTEGER  :: ID, LNZID, i

c .................................................................

     ID = 0
     DO i=1,LNZ_aktanz
        IF (LNZCONT(i) % ptrlnz % LNZID.EQ.LNZID) THEN
           ID = i
           EXIT
        END IF
     END DO

c ................................................................. 10000 RETURN

     END FUNCTION LNZ_GET_ID

cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

CXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX C Objekt zu einer ID

     FUNCTION BOA_IDObj(ID) RESULT (objptr)

c .................................................................

     TYPE (BOA_type), POINTER :: objptr
     INTEGER  :: ID

c .................................................................

     IF (ID.GE.1 .AND. ID.LE.BOA_aktanz) THEN
        objptr => BOACONT(ID) % ptrboa
        GOTO 10000
     END IF
     NULLIFY (objptr)
     GOTO 10000

c Fehlermeldungen c ................................................................. 10000 RETURN

     END FUNCTION BOA_IDObj

cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

CXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX C Objekt zu einer ID

     FUNCTION BOD_IDObj(ID) RESULT (objptr)

c .................................................................

     TYPE (BOD_type), POINTER :: objptr
     INTEGER  :: ID

c .................................................................

     IF (ID.GE.1 .AND. ID.LE.BOD_aktanz) THEN
        objptr => BODCONT(ID) % ptrbod
        GOTO 10000
     END IF
     NULLIFY (objptr)
     GOTO 10000

c Fehlermeldungen c ................................................................. 10000 RETURN

     END FUNCTION BOD_IDObj

cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

CXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX C Objekt zu einer ID

     FUNCTION LNZ_IDObj(ID) RESULT (objptr)

c .................................................................

     TYPE (LNZ_type), POINTER :: objptr
     INTEGER  :: ID

c .................................................................

     IF (ID.GE.1 .AND. ID.LE.LNZ_aktanz) THEN
        objptr => LNZCONT(ID) % ptrlnz
        GOTO 10000
     END IF
     NULLIFY (objptr)
     GOTO 10000

c ................................................................. 10000 RETURN

     END FUNCTION LNZ_IDObj

cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

CXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX c Bodenfeuchtetestausgabe

     SUBROUTINE BF_OPENFILE (datnr)

c .................................................................

     INTEGER  :: i, datnr
     LOGICAL  :: LTMP

c ................................................................. 100 FORMAT(1X, A4, A5, A3, A5, 100(A15))

     INQUIRE (UNIT = datnr, OPENED = LTMP)
     IF (.NOT.LTMP) THEN
        OPEN(UNIT=datnr, FILE=TST_FILENAMEBF,
    +        STATUS='unknown', ERR=10000)

c WRITE(datTSTBF, '(9X, 8(A10))') c + 'HN [mm]', 'HNeff[mm]', ' ETa [mm]', 'Int [mm]', c + ' Base [mm]', ' BF1 [mm]', ' BF2 [mm]', ' BF3 [mm]'

     END IF
     WRITE(datnr, 100) 'NAME', 'EFLID', 'Kng',' Sch ',
    +                     '      BF [mm/m]', '   BFStart [mm]',
    +                     '     BFEnd [mm]',
    +                     (BF_FKTNAME(i)//'[mm]',i=1,BF_ANZ_FKT),
    +                     '     Error [mm]'

c ................................................................. 10000 RETURN

     END SUBROUTINE BF_OPENFILE

cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx


     END MODULE

</fortran>