next up previous contents 34
Nächste Seite: C. Source-Code des hexagonalen Aufwärts: Gitterbasierte Modellierung zur Simulation Vorherige Seite: A. Symbole und Modellvariablen   Inhalt


B. Source-Code des eindimensionalen Modells

% %1
% Start des Programms.
% #
BEGIN
  Comment       VERSION 1.0
  ---------------------------------------- Started :  SEP 1999 ------


     S     -------------      **********************************
           - K - m - O -      *  Kompost miete eindimensional  *
     I     -------------      **********************************

     M
               * * *      --- Model of a grid-based Compost plant ---
     U         * K *
               * * *         --- with one-dimensinal reaction  ---
     L
                          --- cells and their occasional merging  ---
     A

     Version  - 1.0 -
      LINUX
  ---------------------------------------------- State: March 2000 ---;



% %2
% Deklaration der globalen Parameter.
% #
  REAL    Y_HEIGHT;       Comment Höhe der Miete;
  REAL    SIM_TIME,       Comment Dauer der Simulation;
          TIMESTEP,       Comment Zeitschritt der Berechnungen;
          UPD_INTERVAL;   Comment Zeitintervall, mit dem der Wassergehalt
                                  nach dem Wenden angepasst wird;
  REAL    WAT_CHANGE;     Comment Rate der Anpassung des Wassergehaltes an den
                                  Standardwert;
  INTEGER RST, RST_0;     Comment random start;
  REAL    LIST_INTERV,    Comment Intervall der Listen Ausgabe;
          DRAW_INTERV;    Comment Intervall der graphischen Ausgabe;
  REAL OXY_DIFF_RATE,     Comment Diffusionskoeffizient von Sauerstoff in Luft
                                  in [m^2/s];
       THON,              Comment  Theoretischer Sauerstoffbedarf für die
                                   Mineralisierung von 1g Diesleöl in g;
       PORO_TOTAL,        Comment Geasmtporosität;
       DENS_GRA,          Comment Dichte der festen Phase;
       DENS_WAT,          Comment Dichte von Wasser;
       WATER_CONT_MAX,    Comment Maximaler Wassergehalt in [kg/kgTS];
       WATER_CONT_MIN,    Comment Minimaler Wassergehalt;       
       RATE_BIOD_MAX,     Comment Maximale  Abbaurate [kg/m^3/Tag];
       K_C,               Comment Halbsättigungskonstante für die Dieselöl-
                                  Konzentration in der Substratkinetik;
       K_SO;              Comment Halbsättigungskonstante für die Sauerstoff-
                                  Konzentration in der Substratkinetik;
  REAL CELL_HEIGHT;               Comment Zellhöhe;
  REAL PI;                Comment Pi;

  INTEGER Y_CELLS;        Comment Anzahl der Zellen;
  INTEGER Y_HALF;         Comment Y_Cells / 2;
  REAL SUM_VOL;           Comment Hilfsvariable zur Berechnug von Volumen-
                                anteilen der Miete;
  REAL WATER_DIFF;        Comment Maximaler Wassergradient in der Miete;
  INTEGER L,M;            Comment Hilfsvariablen für Schleifen; 
  BOOLEAN MERGE;          Comment Boolsche Variable, die angibt ob gewendet
                                  wurde;
  REAL UPD_COUNT;         Comment Hilfsvariable, mit der ermittelt wird, ob der
                                  Wassergehalt an den Standardwert angepasst
                                  werden muss;
  REF (Infile)  INF;      Comment Referenzen auf die Input und Output-Files;
  REF (OutFile) hin, hmi, hou, oth, ave;
  REF (outfile) hyd, oxy, ore, hre, wre;
% %3
% Darstellung eines Titelbildschirms.
% #
OutImage;
OutImage;
OutImage;
Outtext ("      UFT_KmO_KmO_KmO_KmO_KmO_KmO_KmO_KmO_KmO_KmO_UFT"); OutImage;
Outtext ("      U                                             T"); OutImage;
Outtext ("      U                                             T"); OutImage;
Outtext ("      U                 ------------                T"); OutImage;
Outtext ("      U               /  - K m O -   \              T"); OutImage;
Outtext ("      U              /    Vers.       \             T"); OutImage;
Outtext ("      U             /  K O M P O S T   \            T"); OutImage;
Outtext ("      U            /       MIETE        \           T"); OutImage;
Outtext ("      U  _________/     ONEDIMENSIONAL   \________  T"); OutImage;
Outtext ("      U                                             T"); OutImage;
Outtext ("      U                                             T"); OutImage;
Outtext ("      U        Programm to Simulate a Compost       T"); OutImage;
Outtext ("      U      Plant, which Degrades Hydrocarbons     T"); OutImage;
Outtext ("      U          through Microbial Activity.        T"); OutImage;
Outtext ("      U                                             T"); OutImage;
Outtext ("      UFT (Oliver Loenker, Broder Breckling)      UFT"); OutImage;
OutText ("                       March. 2000                   "); OutImage;
                                                                   OutImage;
Outtext ("      The Programm Reads the Infile  -> KmO1.INF <- "); OutImage;
Outtext ("                                                     "); OutImage;


% %4
% Einlesen der Parameterwerte, mit denen die Simulation initialisiert
% wird, aus einer externen Datei.
% #
  INF :- NEW Infile("kmo1.inf");
  INF.Open (Blanks (120) );  Inf.InImage;
  Y_HEIGHT    := Inf.InReal;  Inf.InImage;
  SIM_TIME    := Inf.InReal; Inf.InImage;
  TIMESTEP    := Inf.InReal; Inf.InImage;
  UPD_INTERVAL:= inf.InReal; inf.InImage;
  WAT_CHANGE  := inf.InReal; inf.InImage;
  Rst         := Inf.InInt;  Inf.InImage;
    Rst_0     := Rst;  Comment RST-Wert wird konserviert.;
  LIST_INTERV := Inf.Inreal; Inf.InImage;
  DRAW_INTERV := Inf.InReal; Inf.InImage;
  OXY_DIFF_RATE := Inf.InReal; Inf.InImage;
  THON := Inf.InReal; Inf.InImage;
  PORO_TOTAL := Inf.InReal; Inf.InImage;
  DENS_GRA := Inf.InReal; Inf.InImage;
  DENS_WAT := Inf.InReal; Inf.InImage;
  WATER_CONT_MAX := Inf.InReal; Inf.InImage;
  WATER_CONT_MIN := Inf.InReal; INf.InImage;
  RATE_BIOD_MAX := Inf.InReal; Inf.InImage;
  K_C := Inf.InReal; Inf.InImage;
  K_SO := Inf.InReal; inf.InImage;
  CELL_HEIGHT := Inf.InReal; Inf.InImage;
  PI := Inf.InReal; Inf.InImage;

  INF.Close;

  SUM_VOL := 0;
  MERGE := FALSE;
  Y_CELLS := Y_HEIGHT/CELL_HEIGHT;
  WATER_DIFF := WATER_CONT_MAX - WATER_CONT_MIN;

% %5
% Start der Programmklasse Simulation
% #
   SIMULATION BEGIN

     REF (Pore) POR;
     REF (Pore) ARRAY PPP ( 0 : Y_CELLS + 1 );
     REF (Head) POREN_1;

% %6
% Instantiierung der Porenzellen und einer Peripherie um die
% Simulationsmiete.
% Die Sauerstoffkonzentration in der Außenluft wird auf 999.9 gesetzt.
% An diesem unrealistischen Wert können die Peripheriezellen an der
% Oberfläche erkannt werden.
% #
      PROCEDURE Generate_Pores; BEGIN
        INTEGER L;
          For L :=  0 step 1 until  Y_CELLS + 1 do BEGIN
            PPP (L):- NEW PORE (L); Comment integer -> real;
            PPP(L).P_OXY := 999.9;
          END of for;

% %7
% Die Parameterwerte der Porenzellen werden gesetzt.
% Die Sauerstoffkonzentration in der Aussenluft wird auf den Wert bei
% 20°C gesetzt.
% Die Höhe der Kontamination wird festgelegt.
% #
       For L :=  1 step 1 until  Y_CELLS  do BEGIN
            PPP (L).Inside := true;
            PPP (L).UPDATE_NEIGHBOURS;
            PPP (L).Update_Volume;
            PPP (L).Update_Area;
            PPP (L).Update_Dry_Weight;
            PPP (L).P_OXY := 0.275;
            PPP (L).C_HYDRO := 10;
            PPP (L).S_OXY_OLD := 0;
            PPP (L).UPDATE_WATER_CONTENT;
            PPP (L).Water_Content := PPP(L).WAT_CONT_STANDARD;
            PPP (L).UPDATE_DIFF_COEFF;          
         END of for;
% /8
% Die Sauerstoffkonzentration an der Mietenunterseite wird auf
% -999.9 gesetzt. An diesem Wert können die Peripherie_Zellen unter
% der Miete erkannt werden
% #
         For L :=  0 do BEGIN
           PPP(L).P_OXY := -999.9;
         END of for;
% /9
% Nach Initialisierung der Porenparameter wird der Titelbildschirm
% vervollständigt.
% #
         OutText("                  Simulation is running ...");
         OutImage;OutImage;
         OutText("          Number of Pore Cells in Plant  : ");
         BreakOutImage;
         OutInt(Y_CELLS,0); OutImage;
% /10   
% Schließlich werden die Porenzellen initialisiert.
% #
         For L :=  1 step 1 until  Y_CELLS  do BEGIN
          ACTIVATE PPP (L);
         END of for;

      END of generate_pores;

% %11
% Die Prozessklasse PORE wird instantiiert.
% Die Variablen, die ein Poren-Objekt repräsentieren, werden
% deklariert.
% #
      PROCESS CLASS PORE (Y); INTEGER Y; BEGIN

        BOOLEAN Inside; Comment Boolsche Variable, die angibt, ob sich
                                eine Zelle in der Miete befindet;
        REAL VOLUME,    Comment Volumen der Zelle;
             AREA_UP,   Comment Oberfläche zur nächst höheren Zelle;
             AREA_DOWN, Comment Oberfläche zur nächst unteren Zelle;
             TS_PORE,   Comment Trockensubstanz in einer Zelle in kg;
             P_OXY,     Comment Sauerstoffkonzentration in der Porenluft
                                 in  [kg/m^3];
                        
                        
             R_Oxy,      Comment Rate, mit der sich der absolute Sauer- 
                                 stoffgehalt in einem Zeitschritt ändert;
             S_OXY,      Comment Sauerstoff in Lösung [g/l = g/kg];
             S_OXY_OLD,  Comment Sauerstoff in Lösung bei t-1;
             P_HYDRO,    Comment Dieselölgehalt [g/Zelle];
             C_HYDRO,    Comment Dieselölkonzentration [g/kg TS];
             R_HYDRO,    Comment Hydrocarbon Rate;
             WATER_CONTENT, Comment Wassergehalt der Zelle;
             WAT_CONT_STANDARD, Comment Wassergehalt bei t=0;
             OXY_DIFF_EFF,  comment Effektiver Diffusionskoeffizient;
             PORO_AIR,   Comment Luftpotosität;
             PORO_WAT, Comment Wasserporosität;
             AIR_VOL,    Comment Luftvolumen;
             WATER_VOL,  Comment Wasservolumen;
             RANDOM_HOLD;Comment Zufallsvariable;
% /12
% Referenz auf die Nachbarzellen.
% #
        REF (Pore) NEI_UP,
                   NEI_DOWN;

% %13
% Prozedur zur Ermittlung der Nachbarzellen.
% #
        PROCEDURE Update_Neighbours; BEGIN
            Nei_up         :- PPP (Y+1 );
            Nei_down       :- PPP (Y-1 );
        END of update_neighbours;

% %14
% Prozedur, mit welcher der das Volumen der Zelle ermittelt wird.
% #
        PROCEDURE Update_VOLUME; BEGIN
          VOLUME := 0.5 * pi * CELL_HEIGHT * ((Y*CELL_HEIGHT)**2 - ((y-1)*CELL_HEIGHT)*
       END of Update_VOLUME;
% %15   
% Prozedur, welche die Oberflächen zu den nachbarzellen berechnet.
% #
        PROCEDURE Update_Area; BEGIN
           AREA_UP := pi * (y *CELL_HEIGHT) * CELL_HEIGHT;
           AREA_DOWN := pi * ((y-1) * CELL_HEIGHT) * CELL_HEIGHT;
        END of Area;

% %16
% Berechnung des Trockengewichts einer Zelle.
% #
        PROCEDURE Update_Dry_Weight; BEGIN
           TS_PORE := Dens_Gra * VOLUME * (1-PORO_TOTAL);
        END;
% %17
% Prozedur zur Berechnung des Wassergehaltes zu verschieden Zeitpunkten
% der Simulation.
% #
        PROCEDURE Update_WATER_CONTENT;
        BEGIN
           REAL d,y_Max,vek_y;
           y_Max :=  Y_CELLS;
           d := WATER_DIFF / Y_MAX;
           Vek_Y := (y_max -y)* d;
           WAT_CONT_STANDARD := WATER_CONT_MIN + Vek_Y;
           if WAT_CONT_STANDARD < 0.1 then WAT_CONT_STANDARD := 0.1;
        END of Update_WATER_CONTENT;
        
% %18
% Prozedur, mit welcher der effektive Diffusionskoeffizient für jede
% Zelle zu verschieden Zeitpunkten der Simulation bestimmt wird.
% Dabei wird die Luftporosität, die Wasserporosität, das Lustvolumen
% und das Wasservolumen jedesmal neu berechnet.
% #
        PROCEDURE Update_Diff_Coeff;
        BEGIN
           REAL v;
            PORO_WAT := WATER_CONTENT * ((1 - PORO_TOTAL) * DENS_GRA)/DENS_WAT;
            PORO_AIR := PORO_TOTAL - PORO_WAT;
            AIR_VOL := VOLUME * PORO_AIR;
            WATER_VOL := VOLUME * PORO_WAT;
            v := PORO_AIR**1.33;
            OXY_DIFF_EFF := Oxy_Diff_Rate * ((PORO_AIR/PORO_TOTAL)**2) * v;
         END of Update_Diff_Coeff;
% %19
% Berechnung der Sauerstoffdiffusion mit einer Nachbarzelle.
% #
        PROCEDURE Oxy_Diffusion (Neighbour,area); REF (Pore) NEIGHBOUR;
        REAL area; BEGIN
        REAL FROM_TO;       Comment Flux;

          If Neighbour.P_OXY < 999.0 then BEGIN
            Comment Trifft zu, wenn Nachbarzelle nicht Luftoberfläche ist;
          If Neighbour.P_OXY > -999.0 then BEGIN
            Comment Trifft zu, wenn Nachbarzelle nicht Mietenuntergrund ist;
% /20
% Aufruf der Prozedur rk (Runge-Kutta-Integration)
% #
              From_To := rk4(Neighbour.P_OXY,P_OXY,Area);
              Neighbour.R_Oxy := Neighbour.R_OXY - From_To;
              R_Oxy := R_Oxy +  From_To;
          END ELSE BEGIN
             Comment Trifft zu, wenn Nachbarzelle Mietenuntergrund ist,
                     nichts passiert;
          END of if;
          END of if ELSE BEGIN
              Comment Trifft zu wenn Nachbarzelle Luftoberfläche ist
              From_To :=  rk4(0.275,P_OXY,Area);
              R_Oxy := R_Oxy +  From_To;
           END of if;
        END of Oxy_Diffusion ;
% %21
% Prozedur, die den Abbau des Dieselöls kalkuliert.
% #
        PROCEDURE Biodegradation;
        BEGIN
           REAL RATE_BIOD;
           RATE_BIOD := (RATE_BIOD_MAX *TIMESTEP / ( 86400 ))*
              (S_OXY**10 / (K_SO**10 + S_OXY**10));
           R_HYDRO := RATE_BIOD * (C_Hydro**2 / (C_Hydro**2 + K_C**2)) * TS_PORE
        
        END of Biodegradation;
% %22   
% Kalkulation des Sauerstoffverbrauchs in Abhängigkeit
% von der Biodegradation.
% #
        PROCEDURE Oxy_Usage;
         BEGIN
           REAL USED_OXY; Comment Verbrauchter Sauerstoff pro Zelle;
           USED_OXY := R_HYDRO * THON;
           S_OXY_OLD := (S_OXY  * WATER_VOL*1000 - USED_OXY) / (WATER_VOL*1000);
           IF S_OXY_OLD < 0 THEN S_OXY_OLD := 0;
        END;
% %23
% Runge-Kutta-Integrationsverfahren zweiter Ordnung.
% #
   REAL PROCEDURE rk4(N_O,O, area); Real N_O, O, area;
      BEGIN
        REAL k1, k2, k3, k4, t_half, y, y_N;
        t_half := TIMESTEP/2;
        k1 := OXY_DIFF_EFF * AREA *((N_O - O) / CELL_HEIGHT) * t_half;
        y := O + k1;
        y_N := N_O - k1;
        rk4 := OXY_DIFF_EFF * AREA * ((y_N - y) / CELL_HEIGHT) * TIMESTEP ;
        END of rk4;
% %24   
% Passt den Wassergehalt nach Durchmischung in vorgegebenen
% Intervallen wieder dem Standardwert an.
% #
   PROCEDURE upd_wat_merge;
        BEGIN
           REAL change;
           change := (WATER_CONTENT - WAT_CONT_STANDARD)*WAT_CHANGE;
           WATER_CONTENT := WATER_CONTENT - change;
        END;
        
% %25
% Porenzellen werden auf ihre Aktivität vorbereitet.
% #
        Into (Poren_1);
        WHILE true do BEGIN
% /26
% Aufruf der Prozedur Oxy_Diffusion mit zur
% Berechnung des Sauerstofftransfers mit den
% beiden Nachbarzellen.
% #
          Oxy_Diffusion (Nei_up,AREA_UP);
          Oxy_Diffusion (Nei_down,AREA_DOWN);
% /27
% Der Sauerstoffflux wird zum Pool addiert.
% Falls die Konzentration unter Null sinkt, wird die
% Simulation abgebrochen und eine Fehlermeldung
% ausgegeben.
% #
          P_OXY := (P_OXY * AIR_VOL + R_Oxy) / AIR_VOL;
          IF P_OXY < 0 THEN Error ("Kompartiment Overflow !");
% /28
% Berechnung des in Wasser gelösten Sauerstoffs mit dem
% Henry'schen Gesetz. 1 mol Luft nimmt bei 20°C 24,5 l
% Volumen ein, die Henry-Konstante hat den
% Wert: 0.0013 mol/(kg * bar).
% Anschließend wird der gelöste Sauerstoff aus der
% Porenluft subtrahiert, wobei der noch gelöste
% Sauerstoff aus dem vorigen Zeitschritt addiert
% wird.
% #
          S_OXY := 0.0013 * 24.5  * P_OXY;
          P_OXY := (P_OXY * AIR_VOL -  WATER_VOL * (S_OXY - S_OXY_OLD))
                   / AIR_VOL;
          R_Oxy := 0.0;
% /29
% Das Dieselölpool in der Zelle wird aus der
% Konzentration ermittelt.
% Danach wird die Prozedur Biodegradation aufgerufen.
% #
          P_HYDRO := C_Hydro * TS_PORE;
          Biodegradation;
% /30   
% Update des Dieselölpools und der Konzentration.
% #
          P_HYDRO := P_HYDRO - R_HYDRO;
          C_Hydro := P_HYDRO / TS_PORE;
% /31           
% Aufruf der Prozedur Oxy_Usage.
% #
          OXY_USAGE;

          R_HYDRO := 0;
          R_OXY := 0;
          S_OXY := 0;
% /32
% Abfrage, ob der Wassergehalt angepasst werden muss.
% Wenn ja, wird die Prozedur Upd_wat_merge und
% Update_Diff_Coeff aufgerufen.
% #
          UPD_COUNT := Mod(Time,UPD_INTERVAL);
          IF MERGE AND UPD_COUNT = 0 THEN BEGIN
                Upd_Wat_Merge;
                Update_Diff_Coeff;
             END;
% /33
% Ermittlung der Zufallszahl Random_Hold.
% Durch wird bei jedem Zeitschritt eine
% andere reihenfolge der Berechnung in den
% einzelnen Poren ermöglicht, um numerische
% Artefakte zu vermeiden.
% #
          Random_Hold := UNIFORM (0.0, TIMESTEP , Rst);
          HOLD (Random_Hold);
          HOLD (TIMESTEP - Random_Hold);

        END of WHILE;
      END of pore;
% %34
% Prozessklasse Merge_Kompost wird instantiiert.
% Mit ihr werden zu bestimmten Zeitpunkten die
% Zellen durchmischt. Aus dem Dieselölgehalt
% wird ein Mittelwert gebildet, während die
% Wassergehalte zufällig verteilt werden.
% #
      Process CLASS Merge_Compost; BEGIN
      REAL add,add2, wadd, avec, avew;
         FOR L:= 1 STEP 1 UNTIL Y_CELLS DO BEGIN
             add := add + PPP(L).C_Hydro * PPP(L).TS_PORE;
             add2 := add2 + PPP(L).TS_PORE;
             wadd := wadd + PPP(L).TS_PORE * PPP(L).WATER_CONTENT;
          END of for;
         aveC := add / add2;
         aveW := wadd /add2;
         FOR L:= 1 STEP 1 UNTIL Y_CELLS  DO BEGIN
             PPP(L).C_Hydro := aveC;
             PPP(L).WATER_CONTENT := aveW;
             PPP(L).P_OXY := 0.275;
             PPP(L).S_OXY_OLD := 0;
             PPP(L).Update_diff_Coeff;
          END of for;
         MERGE := TRUE;
      END of Merge_Compost;
% %35
% Nach Aktivierung dieser Klasse werden in bestimmten
% Intervallen die Sauerstoffgehalte der Zellen in
% einen File geschrieben.
% #
      process class List_Oxy; BEGIN
        OXY :- NEW Outfile ("oxy.dat");
        If (Y_CELLS * 7) < 120 then BEGIN
          OXY.Open (Blanks (120));
        END ELSE BEGIN
          OXY.Open (Blanks (Y_CELLS * 7));
        END;
        WHILE true do BEGIN
           oxy.outtext("Time:  "); oxy.breakoutimage;
           oxy.outint(time/86400,0);oxy.outimage;
         For L := 1 step 1 until  (Y_CELLS) do BEGIN
            oxy.outint(L,0);oxy.breakoutimage;
            oxy.outtext("    ");oxy.breakoutimage;
          OXY.OutReal(PPP (L).P_OXY,4 , 15);
             oxy.outimage;
            END of for;
        oxy.outimage;oxy.outimage;
        HOLD (list_Interv);
        END of WHILE;
      END of List_Oxy;
% %36
% Nach Aktivierung dieser Klasse werden in bestimmten
% Intervallen die Dieselölgehalte der Zellen in
% einen File geschrieben.
% #
      process class List_Hydro; BEGIN
        HYD :- NEW Outfile ("hydro.dat");
        If (Y_CELLS * 7) < 120 then BEGIN
          HYD.Open (Blanks (120));
        END ELSE BEGIN
          HYD.Open (Blanks (Y_CELLS * 7));
        END;
        WHILE true do BEGIN
           hyd.outtext("Time:  "); hyd.breakoutimage;
           hyd.outint(time/86400,0);hyd.outimage;
         For L := 1 step 1 until  (Y_CELLS) do BEGIN
            hyd.outint(L,0);hyd.breakoutimage;
            hyd.outtext("    ");hyd.breakoutimage;
            HYD.OutReal(PPP (L).C_Hydro,4 , 15);
            hyd.outimage;
         END of for;
        hyd.outimage;hyd.outimage;
        HOLD (list_Interv);
        END of WHILE;
      END of list_hydro;
% %37
% Nach Aktivierung dieser Klasse wird in bestimmten
% Intervallen der durchschnittliche Dieselöl-
% gehalt in der Gesamtmiete in einen File
% geschrieben.
% #
       PROCESS CLASS List_Observer_average; BEGIN
        REAL add, add2;
        AVE :- NEW Outfile ("average.dat");
        If (Y_CELLS * 7) < 120 then BEGIN
          AVE.Open (Blanks (120));
        END ELSE BEGIN
          AVE.Open (Blanks (Y_CELLS * 7));
        END;
        WHILE true do BEGIN
              add := 0;
              add2 := 0;
              For L :=  1 STEP 1 UNTIL Y_CELLS  do BEGIN
                 add := add + PPP(L).C_Hydro * PPP(L).TS_PORE;
                 add2 := add2 + PPP(L).TS_PORE;
          END of for;
            add := add / add2;
            AVE.OutFix(Time/86400,0,0); AVE.BreakOutImage;
            AVE.OutText("    "); AVE.BreakOutImage;
            AVE.OutReal(add,4,12); AVE.OutImage;
          HOLD (List_Interv);
        END of WHILE;
      END of list_observer_average;
% %38
% Nach Aktivierung dieser Klasse wird in bestimmten
% Intervallen der durchschnittliche Dieselöl-
% gehalt im inneren Mietendrittel in einen File
% geschrieben.
% #
       PROCESS CLASS List_Observer_inner; BEGIN
        REAL add, add2;
        HIN :- NEW Outfile ("inner.dat");
        If (Y_CELLS * 7) < 120 then BEGIN
          HIN.Open (Blanks (120));
        END ELSE BEGIN
          HIN.Open (Blanks (Y_CELLS * 7));
        END;
        WHILE true do BEGIN
              add := 0;
              add2 := 0;
              m:= Y_CELLS /3;
              For L :=  1 STEP 1 UNTIL m  do BEGIN
                 add := add + PPP(L).C_Hydro * PPP(L).TS_PORE;
                 add2 := add2 + PPP(L).TS_PORE;
          END of for;
            add := add / add2;
            HIN.OutFix(time/86400,0,0); HIN.BreakOutImage;
            HIN.OutText("    "); HIN.BreakOutImage;
            HIN.OutReal(add,4,12); HIN.OutImage;
          HOLD (List_Interv);
        END of WHILE;
      END of list_observer_inner;
% %39
% Nach Aktivierung dieser Klasse wird in bestimmten
% Intervallen der durchschnittliche Dieselöl-
% gehalt im mittleren Mietendrittel in einen
% File geschrieben.
% #
       PROCESS CLASS List_Observer_mid; BEGIN
        INTEGER k;
        REAL add, add2;
        HMI :- NEW Outfile ("mid.dat");
        If (Y_CELLS * 7) < 120 then BEGIN
          HMI.Open (Blanks (120));
        END ELSE BEGIN
          HMI.Open (Blanks (Y_CELLS * 7));
        END;
        WHILE true do BEGIN
              add := 0;
              add2 := 0;
              m:= Y_CELLS /3 +1 ;
              k:= 2*Y_CELLS /3;
              For L :=  m STEP 1 UNTIL k  do BEGIN
                 add := add + PPP(L).C_Hydro * PPP(L).TS_PORE;
                 add2 := add2 + PPP(L).TS_PORE;
          END of for;
            add := add / add2;
            HMI.OutFix(time/86400,0,0); HMI.BreakOutImage;
            HMI.OutText("    "); HMI.BreakOutImage;
            HMI.OutReal(add,4,12); HMI.OutImage;
          HOLD (List_Interv);
        END of WHILE;
      END of list_observer_inner;
% %40
% Nach Aktivierung dieser Klasse wird in bestimmten
% Intervallen der durchschnittliche Dieselöl-
% gehalt im äußeren Mietendrittel in einen
% File geschrieben.
% #
       PROCESS CLASS List_Observer_outer; BEGIN
        REAL add, add2;
        HOU :- NEW Outfile ("outer.dat");
        If (Y_CELLS * 7) < 120 then BEGIN
          HOU.Open (Blanks (120));
        END ELSE BEGIN
          HOU.Open (Blanks (Y_CELLS * 7));
        END;
        WHILE true do BEGIN
              add := 0;
              add2 := 0;
              m:= 2 * Y_CELLS /3 +1;
              For L :=  m STEP 1 UNTIL Y_CELLS  do BEGIN
                 add := add + PPP(L).C_Hydro * PPP(L).TS_PORE;
                 add2 := add2 + PPP(L).TS_PORE;
          END of for;
            add := add / add2;
            HOU.OutFix(time/86400,0,0); HOU.BreakOutImage;
            HOU.OutText("    "); HOU.BreakOutImage;
            HOU.OutReal(add,4,12); HOU.OutImage;
          HOLD (List_Interv);
        END of WHILE;
      END of list_observer_inner;
% %41
% Nach Aktivierung dieser Klasse wird in bestimmten
% Intervallen der Wassergehalt in den Zellen
% in einen File geschrieben.
% #
      Process CLASS  List_Water_Content; BEGIN
        OTH :- NEW Outfile ("water.dat");
        If (Y_CELLS * 7) < 120 then BEGIN
          OTH.Open (Blanks (120));
        END ELSE BEGIN
          OTH.Open (Blanks (Y_CELLS * 7));
        END;
        WHILE TRUE DO BEGIN
        OTH.OutInt(Time/86400,0);oth.OutImage;
            For L := 1 step 1 until Y_CELLS  do BEGIN
            oth.outint(L,0);oth.breakoutimage;
            oth.outtext("    ");oth.breakoutimage;
            OTH.OutReal(PPP (L).WATER_CONTENT,4 , 0);
             oth.outimage;
            END of for;
            oth.OutImage;
            Hold(UPD_INTERVAL);
         END of WHILE;
         END of list_WATER_CONTENT;


% %42
% Ende der Deklarationen.
% Die Prozedur Generate_Pores wird aufgerufen und
% die Simulation dadurch gestartet.
% Die für den Output zuständigen Prozess-
% klassen werden anschließend aktiviert.
% #
     Poren_1 :- NEW Head;
     GENERATE_PORES;
     ACTIVATE NEW List_Oxy;
     ACTIVATE NEW List_Hydro;
     ACTIVATE NEW List_Water_Content;
     ACTIVATE NEW List_Observer_average;
     ACTIVATE NEW List_Observer_INNER;
     ACTIVATE NEW List_Observer_mid;
     ACTIVATE NEW List_Observer_outer;
% /43
% Aktivierung der Prozessklasse Merge_Compost
% zu bestimmten Zeitpunkten der Simulation.
% #
     ACTIVATE NEW Merge_Compost at 4838400; Comment 8 Wochen;
     ACTIVATE NEW Merge_Compost at 9676800; Comment 16 Wochen;
     ACTIVATE NEW Merge_Compost at 14515200; Comment 24 Wochen;
     ACTIVATE NEW Merge_Compost at 19353600; Comment 32 Wochen;
     ACTIVATE NEW Merge_Compost at 24192000; Comment 40 Wochen;
     ACTIVATE NEW Merge_Compost at 29030400; Comment 48 Wochen;

% /44
% Abschließend wird die Simulationsdauer festgelegt.
% #
     HOLD (SIM_TIME); Comment setting duration of the simulation;

    END of simulation;
END of program;



Oliver Loenker