Zur Einbindung eines Moduls in ArcEGMO sind drei Arbeitsschritte notwendig:
- Erstellung und Kompilierung des Moduls und Einbindung in die Bibliothek module.lib,
- Anpassung der Deklarationsroutine mod_dec.cund anschließende Kompilierung und
- Linken des Gesamtsystems.
8.3.1 Erstellung eines Moduls
Jedes Modul setzt sich aus einer Deklarationsroutine und einer Folge von Subroutinen zur Beschreibung von hydrologischen Teilprozessen zusammen.
In dieser Deklarationsroutine wird eine Struktur belegt und an ArcEGMO übergeben, mit folgendem Inhalt:
- Name des Moduls,
- Raumdiskretisierungen, für die das Modul angewendet werden kann und
- Funktionspointer von Routinen, die dann an definierten Stellen innerhalb der Simulationshierarchie aufgerufen werden.
In Abbildung 8.3‑1 ist beispielhaft die Deklarationsroutine des Moduls EFL_MOD1 wiedergegeben. Es wird empfohlen, für die Integration eigener Module neben der folgenden Beschreibung auch ein Muster (z.B. …\Module\abi\efl_mod1.c) als Vorlage zu verwenden bzw. in einer Kopie dieser Vorlage direkt die gewünschten Änderungen vorzunehmen.
Über den hier angegebenen Modulnamen EFL_MOD1 (s. 4. in Abbildung 8.3‑1) wird das zu aktivierende Modul (s. Steuerdatei ARC_EGMO.STE – Kapitel 3) beim Programmstart ausgewählt. Gleichzeitig wird bei Start überprüft, ob die für die Simulation gewählte Raumdiskretisierung mit diesem Modul realisiert werden kann. Dazu werden die zulässigen Raumdiskretisierungen innerhalb der Deklarationsroutine vorgegeben (s. 3.).
Über den Namen der Deklarationsroutine wird diese dem System bekanntgemacht. Aus Gründen der Übersichtlichkeit sollte der Name dieser Routine (s. 2.) ebenso wie der Name der Datei, in der das Modul gespeichert ist, gleich dem Modulnamen sein.
Insgesamt können für ein Modul 6 Eintrittspunkte bereitgestellt werden. Diese Eintrittspunkte sind Funktionen, die vor, während und nach der Simulationszeitschleife aktiviert werden und für verschiedene Aufgaben wie die Parameterermittlung, die eigentliche Simulation und das Freigeben allokierter Speicherbereiche vorgesehen sind. Tabelle 8.3‑1 gibt einen Überblick.
Weiterhin besteht die Möglichkeit, über eine weitere Funktion, die an den Pointer ModulDT gebunden wird, die (aktuelle) Zeitdiskretisierung bzw. Berechnungszeitschrittweite des Moduls abzufragen.
#include <ben_lib.h> |
Abbildung 8.3‑1: Auszug aus dem Modul EFL_MOD1 – Moduldeklaration
Tabelle 8.3‑1: Moduleintrittspunkte
Funktionspointer | Beispiel | Aufruf | Aufgabe |
int ModulBIni (int) | EflMod1BIni(n_efl) | vor Zeitschleife, außerhalb Ortsschleife | Modulinitialisierung, Speicherallokation |
int ModulIni (int,int) | EflMod1Ini(i_efl,i_rb) | vor Zeitschleife, innerhalb Ortsschleife | Parameterermittlung, Anfangswertfestlegung |
int ModulBRun (int) | EflMod1BRun(n_efl) | in Zeitschleife, vor Ortsschleife | |
int ModulRun (int,int) | EflMod1Run(n_efl,i_rb) | in Zeitschleife, innerhalb Ortsschleife | Simulation |
int ModulERun (int) | EflMod1Run(n_efl) | in Zeitschleife, nach Ortsschleife | |
int ModulClear(int) | EflMod1Clear(n_efl) | nach Zeitschleife | Speicherfreigabe |
double* ModulDT() | Met_DTd() | in Zeitschleife | Festlegung der Berechnungszeitschrittweite |
n_efl – Anzahl der Elementarflächen,i_efl – aktuelle Elementarfläche,i_rb – übergeordneter Raumbezug, z.B. i_tg (nur bei Hydrotopklassenbezogener Modellierung interessant) |
Abbildung 8.3‑2 zeigt am Beispiel des Moduls EFL_MOD1 die Routinen, die als Eintrittspunkte dienen.
/**************************************************************************/ |
Abbildung 8.3‑2: Auszug aus dem Modul EFL_MOD1 – Eintrittspunkte
Weiterhin sind, dies ist aber eine generelle Empfehlung bei C-Programmen, die lokalen Funktionsprototypen innerhalb des Moduls im Dateikopf festzuhalten, entweder direkt oder über eine Include-Datei (EFL_MOD1.cpo – s. 1. in Abbildung 8.3‑1). Gleiches gilt für die Prototypen der globalen Funktionen. Diese müssen dem Gesamtsystem bekannt gemacht werden. Dies erfolgt durch einen Eintrag in die Datei …modulemodule.pro (s. Abbildung 8.3‑3), wiederum entweder über direkte Einträge oder über eine Include-Datei (siehe …includeEFL_MOD1.gpo – Abbildung 8.3‑4).
#include „efl_mod1.gpo“ |
Abbildung 8.3‑3: Prototypen-Datei module.pro
1 /* Prototypes generated by mkpro – do not edit! */ |
Abbildung 8.3‑4: Prototypen-Datei EFL_MOD1.GPO
Um Namenskonflikte zu vermeiden, ist bei der Erstellung eines Moduls anzustreben, dass nur wenige Routinen „global“ bekannt sind. Unter- bzw. nachgeordnete Routinen sollten deshalb „static“ deklariert werden, können aber sonst frei gestaltet werden. Sofern untergeordnete Subroutinen auch in anderen Modulen verwendet werden sollen, sind sie im Verzeichnis COMMON zu verwalten.
8.3.2 Anpassung der Deklarationsroutine
Über die Deklarationsroutine mod_dec.c (s. Abbildung 8.3‑5) wird ArcEGMO mitgeteilt, welche Module in der Bibliothek verfügbar sind.
Programmtechnisch werden dazu die in den Deklarationsroutinen der Module angelegten, einzelnen Pointerstrukturen auf ein Feld mdgespeichert. Die Belegungsreihenfolge ist unerheblich, ein neues Modul würde so im Beispiel auf die Feldadresse 13 gespeichert werden. Die Felddimension ANZ_MOD wäre dazu auf 14 zu erhöhen.
Beim Start von ArcEGMO werden aus der Modulbibliothek die zu aktivierenden Module gemäß den angegeben Namen in der Steuerdatei ARC_EGMO.STE ausgewählt.
#include <ben_lib.h> #include „arc_egmo.h“ #define ANZ_MOD 13 static ModulDeclare *md[ANZ_MOD]; static FILE *fd_steu; /**************************************************************************/ void ModulDeclaration() { md[ 0] = SiWaE(); md[ 1] = Efl_Mod0(); md[ 2] = Efl_Mod1(); md[ 3] = Efl_Mod2(); md[ 4] = EGMO_NA(); md[ 5] = EGMO_WH(); md[ 6] = Rd_Simp(); md[ 7] = KinWave(); md[ 8] = EGMO_GW(); md[10] = Q_ELS(); return; } |
Abbildung 8.3‑5: Subroutine mod_dec.c
8.3.3 Linken des Gesamtsystems
Zur Erstellung eines ausführbaren Programms sind im Rahmen eines Link-Laufes die folgenden Dateien miteinander zu verknüpfen:
- Hauptprogramm arc_egmo.obj,
- Definitionsroutine mod_dec.obj,
- betriebssystemspezifische Ausgabefunktion prn_test.obj,
- ArcEGMO Bibliothek arc_egmo.lib und
- Modulbibliothek module.lib.