BEGIN % %1 % Start des Programms % # Comment VERSION 1.0 ---------------------------------------- Started : SEP 1999 ------ S ------------- ***************************** - K - m - H - * Kompost miete Hexagonal * I ------------- ***************************** M * * * --- Model of a grid-based Compost plant --- U * K * * * * --- with hexagonally arranged reaction --- L --- cells and their occasional merging --- A Version - 1.0 - LINUX ---------------------------------------------- State: MARCH 2000 ---; Comment vers. 0.2: Änderung der Porennummerierung; comment vers. 0.3: Integration der Diffusionsgleichung; comment vers. 0.4: Integration von Bodenparamtern (porosität etc); comment vers. 0.5: Integration der Kohlenwasserstoffkinetik; comment vers. 0.6: Umwandlung der rechteckigen Versuchsmiete in ein Trapez; comment vers. 0.7: Änderung der Reaktionskinetik; comment vers. 0.8: Integration eines Wassergradienten; comment vers. 0.9: Programmierung neuer Output-Klassen; comment vers. 0.10: Integration des Recovery-Systems; comment vers. 0.11: Runge-Kuttka 2.Ordnung; comment vers. 0.12: Anpassung des Wassergehaltes nach dem Wenden; % /2 % Deklaration der externen Klasse GRPS, die einen graphischen % Output ermöglicht. % # EXTERNAL CLASS GRPS; % %3 % Deklaration der globalen Parameter. % # REAL X_TOP, Comment Breite des Trapez oben; X_BOTTOM, Comment Breite der Trapez unten; Y_HEIGHT; Comment Höhe der Miete; REAL SIM_TIME, Comment Dauer der Simualtion; TIMESTEP, Comment Zeitschritt der Berechnungen; REC_INT, Comment Intervall des Recovery-Outputs; UPD_INTERVAL; Comment Zeitintervall mit dem der Wassergehalt nach dem Wenden angepasst wird; REAL WAT_CHANGE; Comment Rate der Anpassung des Wassergehalts 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 HYDRO_BLACK, Comment O2-Konzentration minimal. Darstellung in der Graphik schwarz; HYDRO_WHITE; Comment O2-Konzentration maximal. Darstellung in der Graphik weiss; INTEGER OUTP_OPT1, Comment Optionen de graphischen Outputs; OUTP_OPT2; 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 PI; Comment Pi; INTEGER ROWS; Comment Anzahl der Zellreihen in der Mietet; INTEGER X_CELLS; Comment Maximale Anzahl der Zellen pro Reihe; INTEGER X_CperR; Comment Anzahl der Zellen pro individueller Reihe; INTEGER Y_HALF; Comment ROWS / 2; REAL HEX, Comment Seitenlänge eines Hexagons; HEX_VOL, Comment Volumen eines Hexagons; AREA, Comment Oberfläche, durch die Diffusion zur Nachbarzelle stattfinden kann; DIST, Comment Abstand zwischen zwei Porenzentren; WATER_DIFF; Comment Maximaler Wassergradient in der Miete; REAL TS_PORE; Comment Trockengewicht einer Pore in kg; INTEGER y_05, y_10; Comment Hilfsvariablen zur Einteilung der Miete in drei vertikale Zonen; REAL UPD_COUNT; Comment Hilfsvariable, mit ermittelt wird, ob der Wassergehalt an den Standardwert angepasst werden muss; BOOLEAN MERGE; Comment Boolsche Variable, dei angibt, ob gewendet wurde; TEXT T; Comment Hilfsvariable für Textausgabe; INTEGER K, L, M, N,a, b, f, g; Comment Hilfsvariablen für Schleifen; REAL add_o, add_m , add_i, ave_o, ave_m, ave_i; Comment Hilfsvariablen; INTEGER counter_o, counter_m, counter_i; Comment Hilfsvariablen; REF (Infile) INF; Comment Referenzen auf die Input und Output-Files; REF (Outfile) OTF1, OTF2, OTF3; REF (OutFile) OTH1, OTH2, OTH3, oth, ave; ref (outfile) hyd, oxy, ore, hre, wre; % %4 % Darstellung eines Titelbildschirms. % # OutImage; OutImage; OutImage; Outtext (" UFT_KmH_KmH_KmH_KmH_KmH_KmH_KmH_KmH_KmH_KmH_UFT"); OutImage; Outtext (" U T"); OutImage; Outtext (" U T"); OutImage; Outtext (" U ------------ T"); OutImage; Outtext (" U / - K m H - \ T"); OutImage; Outtext (" U / Vers. 10 \ T"); OutImage; Outtext (" U / K O M P O S T \ T"); OutImage; Outtext (" U / MIETE HEXAGONAL \ T"); OutImage; Outtext (" U _________/ CELLULAR AUTOMATON \________ 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 (" 1999, 2000 "); OutImage; OutImage; Outtext (" The Programm Reads the Infile -> KMH1.INF <- "); OutImage; Outtext (" "); OutImage; % %5 % Einlesen der Parameterwerte, mit denen die Simulation initialisiert % wird, aus einer externen Datei. % # INF :- NEW Infile("kmh1.inf"); INF.Open (Blanks (120) ); Inf.InImage; X_TOP := Inf.InReal; Inf.InImage; X_BOTTOM := Inf.InReal; Inf.InImage; Y_HEIGHT := Inf.InReal; Inf.InImage; SIM_TIME := Inf.InReal; Inf.InImage; REC_INT := 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; HYDRO_BLACK := Inf.InReal; Inf.InImage; HYDRO_WHITE := Inf.InReal; Inf.InImage; Outp_Opt1 := Inf.InInt; Inf.InImage; Outp_Opt2 := Inf.InInt; 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; HEX := Inf.InReal; Inf.InImage; pi := Inf.InReal; Inf.InImage; INF.Close; % %6 % Die Werte einiger globaler Variablen werden gesetzt: % # % /7 % Boolsche Variable merge wird auf falsch gesetzt. % # MERGE := FALSE; % /8 % Kalkulation der maximalen Anzahl der X- und Y_Zellen. % # ROWS := (Y_HEIGHT / (2* HEX * Sin(pi/3))) - 0.5 * HEX * Sin(pi/3); X_CELLS := (2/3) * (X_BOTTOM / HEX - 0.5); Y_Half := ROWS/2; % /9 % Kalkulation der Y-Koordinaten i bei 1/3 und 2/3 der Mietenhöhe. % # y_10 := ROWS - ROWS / 3; y_05 := ROWS - 2*ROWS / 3; % /10 % Kalkulation der Entfernung zwischen zwei Porenzentren. % # DIST := SQRT(3) * HEX; % /11 % Kalkulation des Volumens eines Hexagons mit einer Tiefe von 0.01 m. % # HEX_VOL := 0.03 * cos(pi/6) * (HEX**2); % /12 % Kalkulation der Oberfläche zwischen zwei Poren-Nachbarn. % # AREA := HEX * 0.01; % /13 % Kalkulation des Trockengewichts einer Pore; % # TS_PORE := DENS_GRA * HEX_VOL * (1 - PORO_TOTAL); % /14 % Kalkulation des maximalen Wassergradienten in der Miete. % # WATER_DIFF := WATER_CONT_MAX - WATER_CONT_MIN; % %15 % Die Grenzen des graphischen Outputs werden festgelegt und die % Programmklasse GRPS wird gestartet. % # GRPS (0.0, 0.0, (X_CELLS + 1), (2.5*ROWS + 1) , 0.0, 0.0, "gr") BEGIN % %16 % Start der Programmklasse Simulation % # SIMULATION BEGIN Comment Nachbarschastschema: 2 4 4 4 6 4 8 2 1 4 3 4 5 4 7 4 2 3 4 3 6 3 8 2 1 3 3 3 5 3 7 3 2 2 4 2 6 2 8 2 1 2 3 2 5 2 7 2 2 1 4 1 6 1 8 1 1 1 3 1 5 1 7 1 Nachbarschaft Nachbarschaft (x gerade) (x ungerade) oben x y + 1 x y + 1 unten x y - 1 x y - 1 oben rechts x + 1 y + 1 x + 1 y unten rechts x + 1 y x + 1 y - 1 oben links x - 1 y + 1 x - 1 y unten links x - 1 y x - 1 y - 1 Nachbarschaftskodierung: u , d oben, unten u ru rechts oben lu ru rd rechts unten Pore lu links oben ld rd ld links unten d ; % /17 % Simulationsvariablen % # REF (Pore) POR; REF (Pore) ARRAY PPP ( 0 : X_CELLS + 1, 0 : ROWS + 1); REF (Head) POREN_1, POREN_2; INTEGER counter; REAL X_OFFSET, Y_OFFSET, X_OFFS_HALF, Y_OFFS_HALF, X_OFFS_3_4; REF (Legend) LEG; % %18 % Prozedur, welche die graphischen grenzen eines Hexagons % ermittelt. % # PROCEDURE Scaling; BEGIN X_OffSet := 0.6666666 * 0.9; Y_OffSet := 0.5 * 0.9; X_Offs_Half := X_OffSet / 2.0 ; Y_Offs_Half := Y_OffSet / 2.0 ; X_Offs_3_4 := X_Offs_Half + (X_Offs_Half / 2.0); END of Scaling; % %19 % Prozedur, welche die Anzahl der X-Zellen in Abhängigkeit von % dem Y-Wert berechnet. % # INTEGER PROCEDURE Update_X(F); INTEGER F; BEGIN REAL T_B, X_Upd, Y_Upd, x_Int; T_B := X_BOTTOM - X_TOP; Y_Upd := Y_HEIGHT - F * 2 * Sin(pi/3) * HEX - 0.5*Hex*Sin(pi/3); X_Int := 2 * X_Upd + X_TOP; UPDATE_X := (2/3) * (X_INT / HEX - 0.5); END of Update_X; % %20 % Prozedur, welche die Koordinaten der Poren in bestimmten Höhen % und bei gegebener Anzahl der X-Zellen im Trapez ermittelt. % # PROCEDURE Centralize(F,a,b);Name a,b; INTEGER F,a,b; BEGIN a:= (X_CELLS - F)/2; b := a + F -1; END of Centralize; % %21 % Instantiierung der Porenzellen und einer Peripherie um die % Simulationsmiete. % # PROCEDURE Generate_Pores; BEGIN INTEGER K, L; FOR K := 0 step 1 until X_CELLS + 1 do BEGIN FOR L := 0 step 1 until ROWS + 1 do BEGIN PPP (K, L):- NEW PORE (K, L); Comment integer -> real; % /22 % 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. % # PPP(K, L).P_OXY := 999.9; END of FOR; END of FOR; % /23 % Berechnung der maximalen Anzahl von X-Zellen; % # X_CperR := Update_X(1); Centralize(X_CperR,a,b); X_CELLS := b; counter := 1; % %24 % 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 ROWS do BEGIN X_CperR := Update_X(L); Centralize(X_CperR,a,b); IF a = 0 THEN a:=1; FOR K := a step 1 until b do BEGIN counter := counter + 1; PPP (K, L).Inside := true; PPP (K, L).Update_Pore_Center; PPP (K, L).Update_Neighbours; PPP (K,L).P_OXY := 0.275; PPP (k,L).C_HYDRO := 10; PPP (K,L).S_OXY_OLD := 0; PPP (K,L).Update_Water_Content; PPP (K,L).WATER_CONTENT := PPP(K,L).WAT_CONT_STANDARD; PPP (K,L).Update_Diff_COEFF; END of FOR; END of FOR; % /25 % Die Sauerstoffkonzentration an der Mietenunterseite wird auf % -999.9 gesetzt. An diesem Wert können die Peripherie-Zellen unter % der Miete erkannt werden % # FOR K := 0 step 1 until X_CELLS + 1 do BEGIN FOR L := 0 do BEGIN PPP(K, L).P_OXY := -999.9; END of FOR; END of FOR; % /26 % Nach Initialisierung der Porenparameter wird der Titelbildschirm % vervollständigt. % # OutText(" Simulation is running ..."); OutImage;OutImage; OutText(" Number of Pore Cells in Plant : "); BreakOutImage; OutInt(counter,0); OutImage; % /27 % Die Porenzellen werden aktiviert: % # FOR K := 1 step 1 until X_CELLS do BEGIN FOR L := 1 step 1 until ROWS do BEGIN If PPP(K,L).Inside then ACTIVATE PPP (K, L); END of FOR; END of FOR; END of Generate_Pores; % %28 % Die Prozessklasse PORE wird instantiiert. % # PROCESS CLASS PORE (X, Y); INTEGER X, Y; BEGIN BOOLEAN INSIDE, Comment Boolsche Variable, die angibt, ob sich eine Zelle in der Miete befindet; UNEVEN; Comment Boolsche Variable, mit der verschiedene Nachbarschaftsverhältnisse unterschieden werden können; REAL X_CENTER, Comment Koordinaten des Zentrums der Pore; Y_CENTER, P_OXY, Comment Sauerstoffkonzentration in der Porenluft in [kg/m^3]; R_OXY, Comment Rate, mit der sich der absolute Sauer- 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 Water_Content of the Cell; WAT_CONT_STANDARD, Comment water-content at t=0; Oxy_Diff_Eff, comment Effektiver Diffusionskoeffizient; PORO_AIR, Comment Luftpotosität; PORO_WAT, Comment Wasserporosität; AIR_VOL, Comment Luftvolumenn; WATER_VOL, Comment Wasservolumen; RANDOM_HOLD;Comment Zufallsvariable; % /29 % Referenzen zu den 6 Nachbarn. % # REF (Pore) NEI_UP, NEI_DOWN, NEI_RIGHT_UP, NEI_RIGHT_DOWN, NEI_LEFT_UP, NEI_LEFT_DOWN; % %30 % Prozedur, mit welcher das Poren-Zentrum in seine hexagonale % Position gerückt wird. % # PROCEDURE Update_Pore_Center; BEGIN Comment defining cell center, moving it to hexagonal position; X_Center := X; Comment integer -> real; Y_Center := Y; If MOD (X, 2) = 0 then BEGIN Y_Center := Y_Center + 0.5; END of if mod 2; END of update_pore_center; % %31 % Prozedur zur Ermittlung der Nachbarzellen. % # PROCEDURE Update_Neighbours; BEGIN If MOD (X, 2) = 1 then Uneven := true ELSE Uneven := false; If Uneven then BEGIN Comment Trifft zu, wenn Y ungerade ist; Nei_up :- PPP (X , Y+1 ); Nei_down :- PPP (X , Y-1 ); Nei_right_up :- PPP (X+1, Y+1 ); Nei_right_down :- PPP (X+1, Y ); Nei_left_up :- PPP (X-1, Y+1 ); Nei_left_down :- PPP (X-1, Y ); END if uneven ELSE BEGIN Comment Trifft zu, wenn Y gerade ist; Nei_up :- PPP (X , Y+1 ); Nei_down :- PPP (X , Y-1 ); Nei_right_up :- PPP (X+1, Y ); Nei_right_down :- PPP (X+1, Y-1 ); Nei_left_up :- PPP (X-1, Y ); Nei_left_down :- PPP (X-1, Y-1 ); END of if even; END of Update_Neighbours; % %32 % Prozedur zur Berechnung des Wassergehaltes. % # PROCEDURE Update_Water_Content; BEGIN INTEGER ARRAY count(1:X_CELLS); REAL res,c,d, x_Max, y_Max, vek_x, vek_y; INTEGER X_C,a,b; x_Max := ( X_CELLS) / 2 + 0.5; y_Max := ROWS; x_CperR := Update_X(y); c := WATER_DIFF / X_Max; d := WATER_DIFF / Y_MAX; FOR L := 1 step 1 until ROWS do BEGIN X_C := Update_X(L); Centralize(X_C,a,b); IF a = 0 THEN a:=1; FOR K := a step 1 until b do BEGIN count(K) := count(K)+1; END of FOR; END of FOR; IF x > x_Max THEN BEGIN Vek_X := ((X_CELLS -x -1) - (X_CELLS - X_CperR)/2) * c; END ELSE BEGIN IF x < x_Max THEN BEGIN Vek_X := (x -(X_CELLS - X_CperR)/2) * c; END ELSE BEGIN Vek_X := (x_Max -(X_CELLS - X_CperR)/2) * c; END of IF; END of IF; Vek_Y := (count(x) -y)* d; IF Vek_x < 0 THEN Vek_x :=0; WAT_CONT_STANDARD := WATER_CONT_MIN + Sqrt(Vek_X * Vek_Y); if WAT_CONT_STANDARD < 0.1 then WAT_CONT_STANDARD := 0.1; END of Update_Water_Content; % %33 % Prozedur, mit welcher der effektive Diffusionskoeffizient % berechnet wird. % Dabei wird die Luftporosität, die Wasserporosität, das Lustvolumen % und das Wasservolumen ermittelt. % # 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 := HEX_VOL * PORO_AIR; WATER_VOL := HEX_VOL * PORO_WAT; v := PORO_AIR**1.33; Oxy_Diff_Eff := OXY_DIFF_RATE * ((PORO_AIR/PORO_TOTAL)**2) * v; END of Update_Diff_COeff; % %34 % Berechnung der Sauerstoffdiffusion mit einer Nachbarzelle. % # PROCEDURE Oxy_Diffusion (Neighbour); REF (Pore) NEIGHBOUR; BEGIN REAL FROM_TO; 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; % /35 % Aufruf der Prozedur rk (Runge-Kutta-Integration). % # From_To := rk4(Neighbour.P_OXY,P_OXY); 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, rk4 wird aufgerufen; From_To := rk4(0.275,P_OXY); R_OXY := R_OXY + From_To; END of if; END of Oxy_Diffusion ; % %36 % 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; % %37 % Kalkulation des Sauerstoffverbrauchs in Abhängigkeit % von der Biodegradation. % # PROCEDURE Oxy_Usage; BEGIN REAL USED_OXY; USED_OXY := R_HYDRO * THON; S_OXY_OLD := (S_OXY * WATER_VOL * 1000 - USED_OXY) / (WATER_VOL*1000 END of Oxy_Usage; % %38 % Runge-Kutta-Integrationsverfahren zweiter Ordnung. % # REAL procedure rk4(N_O,O); REAL N_O, O; BEGIN REAL k1, k2, k3, k4, t_half, y, y_N; t_half := TIMESTEP/2; k1 := OXY_DIFF_Eff * AREA * ((N_O - O) / DIST) * t_half; y := O + k1; y_N := N_O - k1; rk4 := OXY_DIFF_Eff * AREA * ((y_N - y) / DIST) * TIMESTEP ; END of rk4; % %39 % 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; % %40 % Porenzellen werden auf ihre Aktivität vorbereitet. % # Into (Poren_1); WHILE true do BEGIN % /41 % Aufruf der Prozedur Oxy_Diffusion mit zur % Berechnung des Sauerstofftransfers mit den % beiden Nachbarzellen. % # Oxy_Diffusion (NEI_UP ); Oxy_Diffusion (NEI_DOWN ); Oxy_Diffusion (NEI_RIGHT_UP ); Oxy_Diffusion (NEI_RIGHT_DOWN); Oxy_Diffusion (NEI_LEFT_UP ); Oxy_Diffusion (NEI_LEFT_DOWN ); % /42 % 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 !"); % /43 % 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 substrahiert, wobei der noch gelöste % Sauerstoff aus dem vorigen Zeitschritt addiert % wird. % # S_OXY := 0.0013 * 22.4 * P_OXY; P_OXY := (P_OXY * AIR_VOL - WATER_VOL * (S_OXY - S_OXY_OLD)) / AIR_VOL; R_OXY := 0.0; % /44 % Das Dieselölpool in der Zelle wird aus der % Konzentration ermittelt. % Danach wird die Prozedur Biodegradation aufgerufen. % # P_HYDRO := C_HYDRO * TS_PORE; Biodegradation; % /45 % Update des Dieselölpools und der Konzentration. % # P_HYDRO := P_HYDRO - R_HYDRO; C_HYDRO := P_HYDRO / TS_PORE; % /46 % Aufruf der Prozedur Oxy_Usage. % # Oxy_Usage; R_HYDRO := 0; R_OXY := 0; % /47 % 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; % /48 % Ermittlung der Zufallszahl Random_Hold. % Durch sie 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); S_OXY := 0; END of WHILE; END of pore; % %49 % 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 REF (Pore) POR; INTEGER K, L, M, N; WHILE Poren_1.Cardinal > 5 do BEGIN N := RANDINT (1, Poren_1.Cardinal - 1, Rst); Por :- Poren_1.first; FOR M := 1 Step 1 until N do Por :- Por.Suc; Por.Into (Poren_2); END of WHILE; WHILE not Poren_1.Empty do BEGIN Por :- Poren_2.first; N := RANDINT (1, Poren_2.Cardinal - 1, Rst); FOR M := 1 Step 1 until N do Por :- Por.Suc; Poren_1.First.Follow(Por); END of WHILE; FOR L := 1 step 1 until ROWS do BEGIN X_CperR := Update_X(L); Centralize(X_CperR,a,b); IF a = 0 THEN a:=1; FOR K := a step 1 until b do BEGIN Por :- Poren_2.First; Por.X := K; Por.Y := L; Por.Into (Poren_1); PPP (K, L) :- Por; END of FOR; END of FOR; FOR L := 1 step 1 until ROWS do BEGIN X_CperR := Update_X(L); Centralize(X_CperR,a,b); IF a = 0 THEN a:=1; FOR K := a step 1 until b do BEGIN PPP (K, L).Update_Pore_Center; PPP (K, L).Update_Neighbours; PPP (K, L).Update_Water_Content; PPP (K, L).P_OXY := 0.275; PPP (k, L).S_OXY := 0.0013 * 22.4 * PPP (K, L).P_OXY; PPP (K, L).S_OXY_OLD := 0; END of FOR; END of FOR; MERGE:= TRUE; END of merge_compost; % %50 % Nach Aktivierung dieser Klasse wird in bestimmten % Intervallen ein graphischer Output im % Postscript-Format erstellt. % Die Hexagone werden mit einer Graustufe in % Abhängigkeit vom Dieselölgehalt gefüllt. % Außerdem können optional die Zellkoordinaten % ausgegeben werden. % Am Ende wird eine Legende geschrieben. % # PROCESS CLASS GRAPHIC_OBSERVER; BEGIN INTEGER L, M; REAL HYDRO_SHIFT, HYDRO_SHRINK; TEXT T; REF (Point) P1, P2, POI; REF (Polygon) Pol; REF (Legend) LEG, LEG1, LEG2; HYDRO_SHIFT := - HYDRO_BLACK; HYDRO_SHRINK := 1.0 / (HYDRO_WHITE - HYDRO_BLACK); WHILE true do BEGIN If Outp_opt1 = 1 then BEGIN Comment Darstellung der Dieselölgehalte in Graustufen; FOR M := 1 step 1 until ROWS do BEGIN X_CperR := Update_X(M); Centralize(X_CperR,a,b); IF a = 0 THEN a:=1; FOR L := a step 1 until b do BEGIN Pol :- NEW Polygon; Inspect PPP (L, M) do BEGIN Comment Exkpunkte des Hexagons werden generiert; P1 :- NEW Point (X_Center - X_OffSet, Y_Center ); P1.PutInto (Pol); P1 :- NEW Point (X_Center - X_OffS_Half, Y_Center + Y_OffSet ); P1.PutInto (Pol); P1 :- NEW Point (X_Center + X_OffS_Half, Y_Center + Y_OffSet ); P1.PutInto (Pol); P1 :- NEW Point (X_Center + X_OffSet, Y_Center ); P1.PutInto (Pol); P1 :- NEW Point (X_Center + X_OffS_Half, Y_Center - Y_OffSet ); P1.PutInto (Pol); P1 :- NEW Point (X_Center - X_OffS_Half, Y_Center - Y_OffSet ); P1.PutInto (Pol); P1 :- NEW Point (X_Center - X_OffSet, Y_Center ); P1.PutInto (Pol); Comment Graustufe wir in Abhängigkeit vom Sauerstoffgehalt ermittelt; Pol.Gray := (C_HYDRO - HYDRO_BLACK) * HYDRO_SHRINK; Pol.Fill := true; Pol.Display; END of inspect; END of FOR; END of FOR; END of outp_opt1; If Outp_opt2 = 1 then BEGIN Comment Koordinarten werdem in Graphik ausgegeben; REF (Legend) Leg; TEXT TTT; TTT :- Blanks(2); FOR L := 1 step 1 until (X_CELLS) do BEGIN FOR M := 1 step 1 until (ROWS) do BEGIN P1 :- NEW Point (PPP (L, M).X_Center + X_OffS_Half, PPP (L, M).Y_Center - Y_OffS_Half ); TTT.PutInt (L); Leg :- NEW Legend (P1, TTT); Leg. Size := 0.3; Leg.Display; P1 :- NEW Point (PPP (L, M).X_Center - X_OffS_Half, PPP (L, M).Y_Center - Y_OffS_Half ); TTT.PutInt (M); Leg :- NEW Legend (P1, TTT); Leg. Size := 0.3; Leg.Display; END of FOR; END of FOR; END of if outp_opt2; Poi :- NEW Point (0.0, -2.5); T :- Blanks (80); T := "Kompostmiete Hexagonal, Format X: 1 ... ,Y: 1 ... "; T. Sub(42,4).PutInt (X_CELLS); T. Sub(58,4).PutInt (ROWS); Leg :- NEW Legend (Poi, T); Leg.Size := 0.5; Leg.display; Poi :- NEW Point (0.0, -1.5); T :- Blanks (120); T := " Time: "; T. Sub(15,9).PutFix (Time,0); Leg :- NEW Legend (Poi, T); Leg.Size := 0.5; Leg.display; NEW_PAGE; HOLD (Draw_Interv); END of WHILE; END of GRAPHIC_OBSERVER; % %51 % Nach Aktivierung dieser Klasse werden in bestimmten % Intervallen die Dieselölgehalte aller Porenzellen % in einen Output-File geschrieben: % # PROCESS CLASS List_Hydro; BEGIN TEXT T; HYD :- NEW Outfile ("hydro.dat"); If (X_CELLS * 7) < 120 then BEGIN HYD.Open (Blanks (120)); END ELSE BEGIN HYD.Open (Blanks (X_CELLS * 7)); END; WHILE true do BEGIN hyd.outtext("Time: "); hyd.breakoutimage; hyd.outint(time,0);hyd.outimage; FOR L := ROWS STEP -1 UNTIL 1 do BEGIN X_CperR := Update_X(L); Centralize(X_CperR,a,b); IF a = 0 THEN a:=1; FOR M := a step 1 until b do BEGIN hyd.outint(L,0);hyd.breakoutimage; hyd.outtext(" ");hyd.breakoutimage; hyd.outint(M,0);hyd.breakoutimage; hyd.outtext(" ");hyd.breakoutimage; HYD.OutReal(PPP (L, M).C_HYDRO,4 , 15); hyd.outimage; END of FOR; END of FOR; hyd.outimage;hyd.outimage; HOLD (draw_Interv); END of WHILE; END of List_Hydro; % %52 % Nach Aktivierung dieser Klasse werden in bestimmten % Intervallen die gelösten Sauerstoffgehalte aller % Porenzellen in einen Output-File geschrieben: % # PROCESS CLASS List_Oxy; BEGIN OXY :- NEW Outfile ("oxy.dat"); If (X_CELLS * 7) < 120 then BEGIN OXY.Open (Blanks (120)); END ELSE BEGIN OXY.Open (Blanks (X_CELLS * 7)); END; WHILE true do BEGIN oxy.outtext("Time: "); oxy.breakoutimage; oxy.outint(time,0);oxy.outimage; FOR L := ROWS STEP -1 UNTIL 1 do BEGIN X_CperR := Update_X(L); Centralize(X_CperR,a,b); IF a = 0 THEN a:=1; FOR M := a step 1 until b do BEGIN oxy.outint(L,0);oxy.breakoutimage; oxy.outtext(" ");oxy.breakoutimage; oxy.outint(M,0);oxy.breakoutimage; oxy.outtext(" ");oxy.breakoutimage; OXY.OutReal(PPP (L, M).S_OXY_OLD,4 , 15); oxy.outimage; END of FOR; END of FOR; oxy.outimage;oxy.outimage; HOLD (draw_Interv); END of WHILE; END of List_Oxy; % %53 % Nach Aktivierung dieser Klasse wird in bestimmten % Intervallen der durchschnittliche Dieselölgehalt % in der Gesamtmiete in einen File geschrieben. % # PROCESS CLASS List_Observer_average; BEGIN INTEGER counter; REAL add; AVE :- NEW Outfile ("average.dat"); If (X_CELLS * 7) < 120 then BEGIN AVE.Open (Blanks (120)); END ELSE BEGIN AVE.Open (Blanks (X_CELLS * 7)); END; WHILE true do BEGIN add := 0; counter := 0; FOR M := ROWS STEP -1 UNTIL 1 do BEGIN X_CperR := Update_X(M); Centralize(X_CperR,a,b); IF a = 0 THEN a:=1; FOR L := a step 1 until b do BEGIN counter := counter +1; add := add + PPP(L, M).C_HYDRO; END of FOR; END of FOR; add := add / counter; AVE.OutFix(Time,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; % %54 % Nach Aktivierung dieser Klasse wird in bestimmten % Intervallen der durchschnittliche Dieselölgehalt % im inneren Mietendrittel in einen File geschrieben. % # PROCESS CLASS List_Observer_Hydro_inner; BEGIN OTH3 :- NEW Outfile ("hydro05.dat"); If (X_CELLS * 7) < 120 then BEGIN OTH3.Open (Blanks (120)); END ELSE BEGIN OTH3.Open (Blanks (X_CELLS * 7)); END; OTH3.OutImage; WHILE true do BEGIN counter_i := 0; add_i := 0; FOR M := Y_05 STEP -1 UNTIL 1 do BEGIN X_CperR := Update_X(M); Centralize(X_CperR,a,b); IF a = 0 THEN a:=1; f:= X_CperR/6 * 2 +a; g:= b - X_CperR/6 *2; FOR L := f step 1 until g do BEGIN counter_i := counter_i +1; add_i := add_i + PPP(L, M).C_HYDRO; END of FOR; END of FOR; ave_i := add_i / counter_i; OTH3.Outint(Time,0); OTH3.BreakOutImage; OTH3.OutText(" "); OTH3.BreakOutImage; OTH3.OutReal(ave_i,4,12); OTH3.OutImage; HOLD (List_Interv); END of WHILE; END of List_Observer_inner; % %55 % Nach Aktivierung dieser Klasse wird in bestimmten % Intervallen der durchschnittliche Dieselölgehalt % im mittleren Mietendrittel in einen File geschrieben. % # PROCESS CLASS List_Observer_Hydro_medium; BEGIN OTH2 :- NEW Outfile ("hydro10.dat"); If (X_CELLS * 7) < 120 then BEGIN OTH2.Open (Blanks (120)); END ELSE BEGIN OTH2.Open (Blanks (X_CELLS * 7)); END; OTH2.OutImage; WHILE true do BEGIN counter_m := 0; add_m := 0; FOR M := Y_10 STEP -1 UNTIL 1 do BEGIN X_CperR := Update_X(M); Centralize(X_CperR,a,b); IF a = 0 THEN a:=1; f:= X_CperR/6 * +a; g:= b - X_CperR/6; FOR L := a step 1 until b do BEGIN counter_m:= counter_m +1; add_m := add_m + PPP(L, M).C_HYDRO; END of FOR; END of FOR; ave_m := (add_m - add_i) / (counter_m - counter_i); OTH2.Outint(Time,0); OTH2.BreakOutImage; OTH2.OutText(" "); OTH2.BreakOutImage; OTH2.OutReal(ave_m,4,12); OTH2.OutImage; HOLD (List_Interv); END of WHILE; END of List_Observer; % %56 % Nach Aktivierung dieser Klasse wird in bestimmten % Intervallen der durchschnittliche Dieselölgehalt % im äußeren Mietendrittel in einen File geschrieben. % # PROCESS CLASS List_Observer_Hydro_outer; BEGIN OTH1 :- NEW Outfile ("hydro15.dat"); If (X_CELLS * 7) < 120 then BEGIN OTH1.Open (Blanks (120)); END ELSE BEGIN OTH1.Open (Blanks (X_CELLS * 7)); END; OTH1.OutImage; WHILE true do BEGIN counter_o := 0; add_o := 0; FOR M := ROWS STEP -1 UNTIL 1 do BEGIN X_CperR := Update_X(M); Centralize(X_CperR,a,b); IF a = 0 THEN a:=1; FOR L := a step 1 until b do BEGIN counter_o := counter_o +1; add_o := add_o + PPP(L, M).C_HYDRO; END of FOR; END of For; ave_o := (add_o - add_m) / (counter_o -counter_m); OTH1.Outint(Time,0); OTH1.BreakOutImage; OTH1.OutText(" "); OTH1.BreakOutImage; OTH1.OutReal(ave_o,4,12); OTH1.OutImage; HOLD (List_Interv); END of WHILE; END of List_Observer; % %57 % Nach Aktivierung dieser Klasse wird in bestimmten % Intervallen der durchschnittliche gelöste Sauer- % stoffgehalt im inneren Mietendrittel in einen % File geschrieben. % # PROCESS CLASS List_Oberserver_Oxy_inner; BEGIN OTF3 :- NEW Outfile ("oxy05.dat"); If (X_CELLS * 7) < 120 then BEGIN OTF3.Open (Blanks (120)); END ELSE BEGIN OTF3.Open (Blanks (X_CELLS * 7)); END; OTF3.OutImage; WHILE true do BEGIN counter_i := 0; add_i := 0; FOR M := Y_05 STEP -1 UNTIL 1 do BEGIN X_CperR := Update_X(M); Centralize(X_CperR,a,b); IF a = 0 THEN a:=1; f:= X_CperR/6 * 2 +a; g:= b - X_CperR/6 *2; FOR L := f step 1 until g do BEGIN counter_i := counter_i +1; add_i := add_i + PPP(L, M).S_OXY; END of FOR; END of FOR; ave_i := add_i / counter_i; OTF3.Outint(Time,0); OTF3.BreakOutImage; OTF3.OutText(" "); OTF3.BreakOutImage; OTF3.OutReal(ave_i,4,12); OTF3.OutImage; HOLD (List_Interv); END of WHILE; END of List_Observer_inner; % %58 % Nach Aktivierung dieser Klasse wird in bestimmten % Intervallen der durchschnittliche gelöste Sauer- % stoffgehalt im mittleren Mietendrittel in einen % File geschrieben. % # PROCESS CLASS List_Oberserver_Oxy_medium; BEGIN OTF2 :- NEW Outfile ("oxy10.dat"); If (X_CELLS * 7) < 120 then BEGIN OTF2.Open (Blanks (120)); END ELSE BEGIN OTF2.Open (Blanks (X_CELLS * 7)); END; OTF2.OutImage; WHILE true do BEGIN counter_m := 0; add_m := 0; FOR M := Y_10 STEP -1 UNTIL 1 do BEGIN X_CperR := Update_X(M); Centralize(X_CperR,a,b); IF a = 0 THEN a:=1; f:= X_CperR/6 +a; g:= b - X_CperR/6; FOR L := f step 1 until g do BEGIN counter_m:= counter_m +1; add_m := add_m + PPP(L, M).S_OXY; END of FOR; END of FOR; ave_m := (add_m - add_i) / (counter_m - counter_i); OTF2.Outint(Time,0); OTF2.BreakOutImage; OTF2.OutText(" "); OTF2.BreakOutImage; OTF2.OutReal(ave_m,4,12); OTF2.OutImage; HOLD (List_Interv); END of WHILE; END of List_Observer; % %59 % Nach Aktivierung dieser Klasse wird in bestimmten % Intervallen der durchschnittliche gelöste Sauer- % stoffgehalt im äußeren Mietendrittel in einen % File geschrieben. % # PROCESS CLASS List_Oberserver_Oxy_outer; BEGIN OTF1 :- NEW Outfile ("oxy15.dat"); If (X_CELLS * 7) < 120 then BEGIN OTF1.Open (Blanks (120)); END ELSE BEGIN OTF1.Open (Blanks (X_CELLS * 7)); END; OTF1.OutImage; WHILE true do BEGIN counter_o := 0; add_o := 0; FOR M := ROWS STEP -1 UNTIL 1 do BEGIN X_CperR := Update_X(M); Centralize(X_CperR,a,b); IF a = 0 THEN a:=1; FOR L := a step 1 until b do BEGIN counter_o := counter_o +1; add_o := add_o + PPP(L, M).S_OXY; END of FOR; END of FOR; ave_o := (add_o - add_m) / (counter_o -counter_m); OTF1.Outint(Time,0); OTF1.BreakOutImage; OTF1.OutText(" "); OTF1.BreakOutImage; OTF1.OutReal(ave_o,4,12); OTF1.OutImage; HOLD (List_Interv); END of WHILE; END of List_Observer; % %60 % Nach Aktivierung dieser Klasse werden in bestimmten % Intervallen die Wassergehalte aller Porenzellen % in einen File geschrieben: % # PROCESS CLASS List_Water_Content; BEGIN OTH :- NEW Outfile ("water.dat"); If (X_CELLS * 7) < 120 then BEGIN OTH.Open (Blanks (120)); END ELSE BEGIN OTH.Open (Blanks (X_CELLS * 7)); END; WHILE TRUE DO BEGIN OTH.OutInt(Time,0);oth.OutImage; FOR M := 1 step 1 until ROWS do BEGIN X_CperR := Update_X(M); Centralize(X_CperR,a,b); IF a = 0 THEN a:=1; FOR L := a step 1 until b do BEGIN oth.outint(L,0);oth.breakoutimage; oth.outtext(" ");oth.breakoutimage; oth.outint(M,0);oth.breakoutimage; oth.outtext(" ");oth.breakoutimage; OTH.OutReal(PPP (L, M).WATER_CONTENT,4 , 0); oth.outimage; END of FOR; END of FOR; oth.OutImage; Hold(UPD_INTERVAL); END of WHILE; END of List_Water_Content; % %61 % Nach Aktivierung dieser Klasse werden in bestimmten % Intervallen die Sauerstoffgehalte aller Zellen in % einen File geschrieben. Es werden jeweils nur die % aktuellen Werte im File gespeichert, frühere Auf- % zeichnungen werden überschrieben. % Mit diesen Werten kann die Simulation nach einem % Abbruch wieder gestartet werden. % # PROCESS CLASS Recover_Oxy; BEGIN WHILE TRUE DO BEGIN ore :- NEW OutFile ("oxy_rec.dat"); ore.Open (Blanks (X_CELLS * 7)); ore.OutInt(Time,0);ore.OutImage; FOR L := 1 step 1 until ROWS do BEGIN X_CperR := Update_X(L); Centralize(X_CperR,a,b); IF a = 0 THEN a:=1; FOR K := a step 1 until b do BEGIN ore.OutReal(PPP(K,L).P_OXY,3,12); ore.OutImage; END of FOR ; END of FOR; ore.Close; hold(REC_INT); END of WHILE; END of Recover_Oxy; % %62 % Nach Aktivierung dieser Klasse werden in bestimmten % Intervallen die Dieselölgehalte aller Zellen in % einen File geschrieben. Es werden jeweils nur die % aktuellen Werte im File gespeichert, frühere Auf- % zeichnungen werden überschrieben. % Mit diesen Werten kann die Simulation nach einem % Abbruch wieder gestartet werden. % # PROCESS CLASS Recover_Hydro; BEGIN WHILE TRUE DO BEGIN hre :- NEW OutFile ("hyd_rec.dat"); hre.Open (Blanks (X_CELLS * 7)); hre.OutInt(Time,0); hre.OutImage; FOR L := 1 step 1 until ROWS do BEGIN X_CperR := Update_X(L); Centralize(X_CperR,a,b); IF a = 0 THEN a:=1; FOR K := a step 1 until b do BEGIN hre.OutReal(PPP(K,L).C_HYDRO,3,12); hre.OutImage; END of FOR; END of FOR; hre.Close; Hold(REC_INT); END of WHILE; END of Recover_Hydro; % %63 % Nach Aktivierung dieser Klasse werden in bestimmten % Intervallen die Wassergehalte aller Zellen in % einen File geschrieben. Es werden jeweils nur die % aktuellen Werte im File gespeichert, frühere Auf- % zeichnungen werden überschrieben. % Mit diesen Werten kann die Simulation nach einem % Abbruch wieder gestartet werden. % # PROCESS CLASS Recover_WAT; BEGIN WHILE TRUE DO BEGIN wre :- NEW OutFile ("wat_rec.dat"); wre.Open (Blanks (X_CELLS * 7)); wre.OutInt(Time,0);wre.OutImage; FOR L := 1 step 1 until ROWS do BEGIN X_CperR := Update_X(L); Centralize(X_CperR,a,b); IF a = 0 THEN a:=1; FOR K := a step 1 until b do BEGIN wre.OutReal(PPP(K,L).WATER_CONTENT,3,12); wre.OutImage; END of FOR ; END of FOR; wre.Close; Hold(REC_INT); END of WHILE; END of Recover_wat; % %64 % Ende der Deklarationen. % Die Prozedur Scaling und 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; Poren_2 :- NEW Head; Scaling; Generate_Pores; ACTIVATE NEW List_Water_Content; ACTIVATE NEW Recover_Oxy; ACTIVATE NEW Recover_Hydro; ACTIVATE NEW Recover_Wat; ACTIVATE NEW List_Oxy; ACTIVATE NEW List_Hydro; ACTIVATE NEW List_Observer_Hydro_inner; ACTIVATE NEW List_Observer_Hydro_medium; ACTIVATE NEW List_Observer_Hydro_outer; ACTIVATE NEW List_Oberserver_Oxy_inner; ACTIVATE NEW List_Oberserver_Oxy_medium; ACTIVATE NEW List_Oberserver_Oxy_outer; ACTIVATE NEW List_Observer_average; ACTIVATE NEW Graphic_Observer; % %65 % 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; % %66 % Festlegung der Simulationsdauer. % # HOLD (SIM_TIME); Comment setting duration of the simulation; % %67 % Files werden geschlossen. % # oth.Close; OTH1.Close; OTH2.Close; OTH3.Close; OTF1.Close; OTF2.Close; OTF3.Close; ave.Close; hyd.Close; oxy.Close; END of simulation; END of grawing; END of program;