EAS3IOMOD ist die Fortran-Schnittstelle zum Schreiben und Lesen von EAS2/3-Daten. Sie ist bisher für die folgenden Plattformen implementiert (in Klammern sind die entprechenden Präprozessordefines im Makefile angegeben):
Im EAS3IOMOD wird eindeutig zwischen internem Datenformat (Datentypen im Speicher) und externem Datenformat (Datentypen auf der Datei) unterschieden. Jedes interne Datenformat kann auf jedes externe Datenformat abgebildet werden und umgekehrt. Bei Wandlung z.B. von 8-Byte- in 4-Byte-Datentypen wird es natürlich zu Genauigkeitsverlusten kommen. Der dabei gegebenenfalls auftretende Overflow/Underflow wird aber abgefangen.
REAL und INTEGER Daten im Kennsatz einer EAS3-Datei sind 8-Byte-Daten, unabhängig von der Genauigkeit der Daten auf den Parametern (alte Kennsätze mit 4-Byte-Daten können weiter gelesen werden). CHARACTER Daten nehmen jeweils 1 Byte pro Zeichen auf der Datei ein. Die Parameter selbst können wahlweise in 4 , 8 oder 16 Byte je Element geschrieben werden. Jedes externe Datenformat kann auf (fast) jeder Plattform geschrieben/gelesen werden (die T3E unterstützt keine 16-Byte Datentypen).
Das Modul kann in zwei Versionen compiliert werden:
Es wurde zunächst versucht diese zusätzlichen Routinen von 2. zu überladen und sie so vor dem Benutzer zu verbergen, um die Anwendung zu vereinfachen. Leider hat das Überladen der Routinen nicht gut funktioniert, weil KIND und RANG beim Überladen übereinstimmen müssen, um die entsprechend aufzurufende Routine zu bestimmen (=> die Angabe einer Startaddresse, wie sie in unseren Programmen häufig benutzt wird, reicht dann leider nicht mehr aus, um die entsprechende Routine beim Aufruf eindeutig zu identifizieren). Aus diesem Grund wurde auf das Überladen verzichtet. Stattdessen können wahlweise die Routinen mit expliziter Genauigkeitsangabe dazucompiliert werden (EAS3MULTIPREC).
Das EAS3IOMOD wird als Fortran90 Modul zur Verfügung gestellt. Entsprechend kann es mit
USE EAS3IOMOD
in eigene (mit f90 compilierte) Programme eingebunden werden. Fortran-Programme, die EAS3IOMOD benutzen, müssen intern das IEEE-Format verwenden, damit die geschriebenen Daten auch auf anderen Maschinen lesbar sind. Außerdem muß das Modul passend zum eigenen Programm compiliert werden (siehe Makefile für EAS3IOMOD für die entsprechenden Compiler-Optionen auf den verschiedenen Plattformen).
Der Kennsatz einer EAS3-Datei steht am ganz Anfang der Datei vor den Parametern und kann wesentlich mehr Informationen enthalten als ein EAS2-Kennsatz. Es werden das Dateiformat und das verwendete Binärformat abgespeichert. Neben den Informationen über die Dimensionierung der Daten (Anzahl der Zeitschritte, der Parameter, sowie der Elemente je Parameter) und dem Zeitschrittfeld können zusätzlich Attribute in Form von Zeichendaten für jede Dimension angegeben werden. Außerdem ist es möglich Daten über das verwendete Rechengitter im Kennsatz abzuspeichern. Als weitere Ergänzung sind noch benutzerdefinierte Felder (Character, Integer und Real) vorgesehen, welche es erlauben die Daten sehr aussagekräftig zu kommentieren. All diese Erweiterungen sind jedoch bei Bedarf auch abschaltbar.
Die Daten für den Kennsatz sind in einer Typdefinition als neuer
Datentyp eas3ks_t zusammengefaßt:
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Typdefinition fuer EAS3-Kennsatz!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!type eas3ks_t! obligatorische Parameterinteger :: dform ! Dateiformat (EAS3, EAS2)integer :: bform ! Binaerformat/Genauigkeit (IEEES, IEEED, IEEEQ)integer :: nzs ! Anzahl der Zeitschritte (>=1)integer :: npar ! Anzahl der Parameter je Zeitschritt (>=1)integer :: ndim1 ! Anzahl der Elemente der ersten Dimension (>=1)integer :: ndim2 ! Anzahl der Elemente der zweiten Dimension (>=1)integer :: ndim3 ! Anzahl der Elemente der dritten Dimension (>=1)integer, dimension(:), pointer :: zsf ! Zeitschrittfeld (Zeitschrittnummern)! (nach Allokierung nzs Eintraege)! erweiterte (optionale) Parameter! Attributmodusinteger :: amode ! (EAS3_NO_ATTR, EAS3_ALL_ATTR)! Zeitschrittattribute (nach Allokierung nzs Eintraege)character(LEN=ATTRLEN), dimension(:), pointer :: zsattr! Parameterattribute (nach Allokierung npar Eintraege)character(LEN=ATTRLEN), dimension(:), pointer :: parattr! Dimensionsattributecharacter(LEN=ATTRLEN) :: dim1attrcharacter(LEN=ATTRLEN) :: dim2attrcharacter(LEN=ATTRLEN) :: dim3attr! Geometriedaten (Startwerte und Schrittweiten oder Koordinatenangaben)integer, dimension(5) :: gmode ! Geometriemodus (je Dimension)! (EAS3_NO_G, EAS3_X0DX_G, EAS3_UDEF_G, EAS3_ALL_G)integer, dimension(5) :: ng ! Anzahl der Geometriedatentype(rptr1d_t), dimension(5) :: gf ! Geometriefeld (je Dimension)! 1,2,3,4,5 => Zeit, Parameter, Dim1, Dim2, Dim3! benutzerdefinierte Felderinteger :: umode ! Modus fuer benutzerdefinierte Daten! (EAS3_NO_UDEF, EAS3_ALL_UDEF, EAS3_INT_UDEF)integer, dimension(3) :: nu ! Anzahl der benutzerdefinierten Eintraege! (je benutzerdefiniertem Feld)! 1,2,3 => Characterfeld, Integerfeld, Realfeld! Feld fuer Zeichendatencharacter(LEN=UDEFLEN), dimension(:), pointer :: cf! Feld fuer Integerdaten (hierher wird auch das EAS2-Infofeld abgebildet)integer, dimension(:), pointer :: if! Feld fuer Realdatenreal, dimension(:), pointer :: rfend type eas3ks_t!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Typdefinition fuer Zeiger auf eindimensionales Realfeld!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!type rptr1d_treal, dimension(:), pointer :: dat ! Realdaten (Eintraege fuer Geometriefeld)! wird fuer gf-Felder benutztend type rptr1d_t!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
In Klammern sind bei einigen Variablen die zulässigen Werte angegeben. Es handelt sich bei den nicht numerischen Werten um die Namen definierter Konstanten, die von EAS3IOMOD zur Verfügung gestellt werden. Die Konstanten sind im nächsten Abschnitt Verzeichnis der definierten Konstanten vollständig aufgelistet und erklärt. Es wird stärkstens empfohlen die Konstanten und nicht ihre Werte direkt zu benutzen, da sich die interne Implementierung bei Erweiterungen ändern kann. Programme welche die Konstanten benutzen, sind dann jederzeit weiterverwendbar.
Die Typdefinition enhält einige Zeiger auf dynamische Felder, deren Größe erst zur Laufzeit des Programmes bekannt ist. Da es sehr aufwendig wäre vor dem schreiben eines Datensatzes jeweils alle diese Felder in entsprechender Größe zu allokieren, gibt es eine Routine eas3getks, die dies für den Anwender übernimmt. Sie liefert die Felder in der gewünschten Größe und belegt sie mit Defaultwerten. Der Benutzer sollte dann die Felder noch mit sinnvolleren Werten überschreiben, bevor der Kennsatz an die Routine eas3writeks übergeben wird. Beim Lesen von Daten liefert die Routine eas3readks direkt einen vollständig allokierten Datensatz, der den Kennsatz der eingelesenen Datei enthält.
Die Länge der Attribute ist durch die Konstante ATTRLEN festgelegt. Die Default-Attribute sind im Verzeichnis der definierten Konstanten erklärt.
Bei den Geometrieinformationen entsprechen den fünf Feldeinträgen gmode(i), ng(i) mit i=1..5 jeweils Angaben zur Zeitrichtung (i=1), zu den Parametern (i=2), zur ersten (i=3), zweiten (i=4) und dritten (i=5) Dimension des Datensatzes. Wie die Daten in den verschiedenen Geometriemodi zu interpretieren sind, wird bei der Definition der Konstanten Verzeichnis der definierten Konstanten erklärt.
Bei den benutzerdefinierten Feldern gilt, daß die drei Feldeinträge nu(i) mit i=1..3 jeweils als Längenangaben für das Characterfeld (i=1), das Integerfeld (i=2) und das Realfeld (i=3) festgelegt sind. Die Länge der Einträge des Feldes cf ist durch die konstante UDEFLEN festgelegt. Die verschiedenen Modi sind im Verzeichnis der definierten Konstanten erklärt.
Beim Schreiben oder Lesen von EAS2-Dateien (dmode=EAS2) wird das Infofeld von EAS2 auf das benutzerdefinerte Integer-Feld if abgebildet (umode=EAS3_INT_UDEF, falls ks%nu(2)>0 (also Länge des Infofeldes>0)). Alle anderen EAS2-Kennsatzdaten entsprechen den obligatorischen Daten des EAS3-Kennsatzes. Bei EAS2-Datensätzen muß sichergestellt werden, daß nur die ersten beiden Dimensionen ndim1 und ndim2 >= 1 sind, ndim3 muß bei EAS2-Daten gleich 1 sein.
Beispiel für die Benutzung des EAS3-Kennsatzes:
type (eas3ks_t) :: ks
ks%dform=EAS3 ! EAS3-Datensatz
ks%bform=IEEES ! IEEES Format auf Datei
.
.
ks%gf(3)%dat(2)=1. ! Zugriff auf das 2. Element des Geometriefeldes der ersten
! Dimension (nur wenn der Speicherplatz bereits allokiert wurde
! (z.B. durch eas3getks))
usw.
| Variable | definierte Konstanten | Erklärung und gegebenenfalls durch eas3getks gesetzte Defaultwerte |
| dform (Dateiformat) | EAS3 | EAS3-Datenformat |
| EAS2 | EAS2-Datenformat | |
| bform (Binärformat) | IEEES | IEEE single precision (32 Bit) |
| IEEED | IEEE double precision (64 Bit) | |
| IEEEQ | IEEE quadruple precision (128 Bit) (auf T3E nicht unterstützt) | |
| amode (Attributmodus) | EAS3_NO_ATTR | keine Attributangaben |
| Defaultwerte von eas3getks: | ||
| Zeiger mit NULLIFY initialisiert; Dimensionsattribute "" (leer) | ||
| EAS3_ALL_ATTR | Attributangaben für Zeitschritte, Parameter und Dimensionen | |
| Defaultwerte von eas3getks: | ||
| zsattr(i)="" mit i=1,nzs | ||
| parattr(i)="" mit i=1,npar | ||
| dim1attr=""; dim2attr=""; dim3attr="" | ||
| gmode(i=1:5) (Geometriemodus) | EAS3_NO_G | keine Geometrieangaben |
| Defaultwerte von eas3getks: | ||
| Zeiger mit NULLIFY initialisiert; ng(1:5)=0 | ||
| EAS3_X0DX_G | Angabe von Startwert auf gf(i)%dat(1) und Schrittweite auf gf(i)%dat(2) | |
| Defaultwerte von eas3getks: | ||
| ng(i)=2 | ||
| Startwert: gf(i)%dat(1)=0. | ||
| Schrittweite: gf(i)%dat(2)=1. | ||
| EAS3_UDEF_G | ng=Anzahl der Koordinatenangaben auf gf =>benutzerdefinierte Anzahl von Koordinatenangaben im gf-Feld (nf muß bei eas3getks angegeben werden) | |
| Defaultwerte von eas3getks: | ||
| gf(i)%dat(j)=0.0mit j=1,ng(i) | ||
| EAS3_ALL_G | eine Angabe für jedes Element der entsprechenden Dimension => ng(i)=Größe der i-ten Dimension und damit des entsprechenden Geometriefeldes | |
| Defaultwerte von eas3getks: | ||
| ng(1)=nzs; ng(2)=npar; ng(3)=ndim1; ng(4)=ndim2; ng(5)=ndim3 | ||
| gf(1:5)%dat(j)=0.0 mit j=1,ng(1:5) | ||
| umode | EAS3_NO_UDEF | keine benutzerdefinierten Angaben |
| Defautwerte: | ||
| Zeiger mit NULLIFY initialisiert; nu(1:3)=0 | ||
| EAS3_ALL_UDEF | Einträge auf allen benutzerdefinierbaren Feldern jeweils mit der Länge nu(i=1:3) für das entsprechende Feld | |
| Defaultwerte von eas3getks: | ||
| cf(i)="" mit i=1,nu(1); if(i)=0 mit i=1,nu(2); rf(i)=0.0 mit i=1,nu(3) | ||
| EAS3_INT_UDEF | nur Integerfeld mit nu(2) Einträgen (wird bei EAS2-Dateien für das Infofeld benutzt, falls nu(2)>0) (nu muß bei eas3getks bei diesem Modus zwingend angegeben werden) | |
| Defaultwerte von eas3getks: | ||
| nu(1)=0; nu(2)=Länge des Infofeldes; nu(3)=0; if(i)=0 mit i=1,nu(2) | ||
| - | EAS3_PR_ZS | Optionales Argument für eas3printks, schaltet Ausgabe des Zeitschrittfeldes und der Zeitschrittattribute ein (falls vorhanden) |
| - | EAS3_PR_PAR | Optionales Argument für eas3printks, schaltet Ausgabe der Parameterattribute ein (falls vorhanden) |
| - | EAS3_PR_DIM | Optionales Argument für eas3printks, schaltet Ausgabe der Dimensionsattribute ein (falls vorhanden) |
| - | EAS3_PR_GEO | Optionales Argument für eas3printks, schaltet Ausgabe der Geometriedaten ein (falls vorhanden) |
| - | EAS3_PR_UDEF | Optionales Argument für eas3printks, schaltet Ausgabe der benutzerdefinierten Datenfelder ein (falls vorhanden) |
| - | ATTRLEN=10 | Länge der Attribute (kann für Definition eigener Charactervariablen benutzt werden: CHARACTER(LEN=ATTRLEN) :: attr_var |
| - | UDEFLEN=20 | Länge der Einträge des cf-Feldes (kann für Definition eigener Charactervariablen benutzt werden: CHARACTER(LEN=UDEFLEN) :: udef_var |
| - | EAS3_RO | Dateimodusangabe: Datei nur zum Lesen geöffnet (eas3readks) |
| EAS3_RW | Dateimodusangabe: Datei zum Lesen und Schreiben geöffnet (eas3readks) | |
| EAS3_WO | Dateimodusangabe: Datei nur zum Schreiben geöffnet (eas3writeks) | |
| EAS3_WRA | Dateimodusangabe: Datei zum wahlfreien Schreibzugriff von Anfang an öffnen. Es wird beim Öffnen zunächst ein Nullfile geschrieben. (eas3writeks) | |
| - | FD_SRK | Konstante für Typdeklaration: KIND-Angabe für einfache Genauigkeit (4 Byte) |
| FD_DRK | Konstante für Typdeklaration: KIND-Angabe für doppelte Genauigkeit (8 Byte) | |
| FD_QRK | Konstante für Typdeklaration: KIND-Angabe für vierfache Genauigkeit (16 Byte) | |
| Beispiel: REAL(KIND=FD_DRK) :: real_var ! 8 Byte REAL Variable | ||
| - | MAXFILES | maximale Anzahl von eas3 verwalteter Datein |
| - | FNAMELEN | maximale Länge für Dateinamen, die von EAS3IOMOD verwaltet werden |
Neben den eigentlichen Konstanten, die mit Integerwerten belegt sind, gibt es auch die Möglichkeit aus den Werten dieser Konstanten den Namen der Konstanten zu erhalten. Dazu werden die folgenden Felder zur Verfügung gestellt:
dformchar, bformchar, amodechar, gmodechar, umodechar, fmodechar
Anwendungsbeispiel: Der Kennsatz ks für eine EAS2-Datei sei bereits vollständig durch eas3getks belegt. Dann liefern die folgenden Aufrufe jeweils Character als Ergebnis (abfragen von Feldeinträgen):
dformchar(ks%dform) => "EAS2" amodechar(ks%amode) => "EAS3_NO_ATTR" umodechar(ks%umode) => "EAS3_INT_UDEF"
analog für die anderen Felder
subroutine eas3writeks(filenr,fname,ks,fmode)
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
integer, intent(in) :: filenr ! Dateinummer (0..MAXFILES)
character(LEN=*), intent(in) :: fname ! Dateiname (max. FNAMELEN Zeichen)
type(eas3ks_t), intent(in) :: ks ! Kennsatz
integer, intent(in), optional :: fmode ! optionaler Schreibmodus der Datei (EAS3_WO, EAS3_WRA)
! Default-Modus: EAS3_WO
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
eas3writeks öffnet die angegebene Datei mit dem Namen fname ohne Angabe von fmode im Modus EAS3_WO und schreibt den Kennsatz ks auf die Datei. Alle Felder des Kennsatzes müssen bereits vollständig allokiert sein. Nach dem Aufruf von eas3writeks kann mit Hilfe der Dateinummer filenr auf die Datei zugegriffen werden.
Der Inhalt einer bereits vorhandenen Datei mit gleichem Namen wird beim Öffnen mit eas3writeks gelöscht.
Mit dem optionalen Argument fmode kann der Schreibmodus angegeben werden. Im Default-Modus EAS3_WO schreibt man die Parameter zunächst sequentiell auf die Datei. Bereits geschriebene Parameter können dann wahlfrei überschrieben werden. Prinzipiell kann man aber nicht hinter das aktuelle Dateiende (den letzten bereits geschriebenen Parameter) schreiben. Im Modus EAS3_WRA werden die Parameter der Datei zunächst automatisch mit Nullen beschrieben, so daß von Anfang an mit eas3write wahlfrei auf alle Parameter geschrieben werden kann. Dieser Modus sollte nur für Spezialanwendungen benutzt werden, bei denen der wahlfreie Schreibzugriff unabdingbar ist, da die effektive I/O-Leistung damit halbiert wird (die Datei wird zweimal auf die Platte geschrieben).
subroutine eas3write[_s|_d|_q](filenr,data,zsind,parind) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ! Zweck: schreibt Datensatz auf eine bereits geoeffnete Datei ! optional koennen der Zeitschritt- und Parameterindex angegeben werden !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! integer, intent(in) :: filenr ! Dateinummer ! Datensatz (mindestens ndim1*ndim2*ndim3 Elemente) real(KIND=CHOICE), dimension(*), intent(in) :: data integer, intent(in), optional :: zsind ! optionaler Zeitschrittindex integer, intent(in), optional :: parind ! optionaler Parameterindex ! !CHOICE=Default-Datentyp (keine Angabe von KIND) ! oder FD_SRK, FD_DRK, FD_QRK bei den _s, _d, _q Varianten !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
eas3write schreibt entweder den nächsten Datensatz, wenn die optionalen Indizes nicht angegeben sind, oder den durch die Indizes für Zeitschritt zsind und Parameter parind angebenen Datensatz auf die bereits geöffnete Datei mit der Nummer filenr. Der Datensatz wird im Feld data angegeben, das mindestens die Dimension ndim1*ndim2*ndim3 haben muß.
Wenn eine Datei im Modus EAS3_WO durch eas3writeks geöffnet wurde, können neue Parameter am Ende nur in sequentieller Reihenfolge zu den bereits geschriebenen Parametern hinzugefügt werden. Für alle bereits auf die Datei geschriebenen Parameter gilt dann aber die Möglichkeit des wahlfreien Zugriffs. Im Modus EAS3_RW (Datei geöffnet durch eas3readks) gilt wahlfreier Schreibzugriff auf alle Datensätze. Im Modus EAS3_RO (Datei geöffnet durch eas3readks) darf eas3write nicht benutzt werden. Es wird geprüft ob die Indizes im zulässigen Bereich liegen und ob das Dateiende beim Schreiben überschritten wird.
subroutine eas3readks(filenr,fname,ks,fmode)
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
integer, intent(in) :: filenr ! Dateinummer (0..MAXFILES)
character(LEN=*), intent(in) :: fname ! Dateiname (max. FNAMELEN Zeichen)
type(eas3ks_t), intent(inout) :: ks ! Kennsatz
integer, intent(in), optional :: fmode ! optionaler Lesemodus der Datei (EAS3_RO, EAS3_RW)
! Default-Modus: EAS3_RO
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
eas3readks öffnet die Datei mit dem Namen fname ohne Angabe von fmode im Modus EAS3_RO und liest den Kennsatz ks von der Datei. Alle Felder des Kennsatzes werden vollständig allokiert zurückgeliefert. Nach dem Aufruf von eas3readks kann mit Hilfe der Dateinummer filenr auf die Datei zugegriffen werden. Mit dem optionalen Argument fmode kann die Datei auch im Modus EAS3_RW geöffnet werden, bei dem auf die (bereits bestehende) Datei lesend und schreibend zugegriffen werden kann.
subroutine eas3read[_s|_d|_q](filenr,data,zsind,parind) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ! Zweck: liest Datensatz von einer bereits geoeffneten Datei ! optional koennen der Zeitschritt- und Parameterindex angegeben werden !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! integer, intent(in) :: filenr ! Dateinummer ! Datensatz (mindestens ndim1*ndim2*ndim3 Elemente) real(KIND=CHOICE), dimension(*), intent(inout) :: data integer, intent(in), optional :: zsind ! optionaler Zeitschrittindex integer, intent(in), optional :: parind ! optionaler Parameterindex ! !CHOICE=Default-Datentyp (keine Angabe von KIND) ! oder FD_SRK, FD_DRK, FD_QRK bei den _s, _d, _q Varianten !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
eas3read liest entweder den nächsten Datensatz, wenn die optionalen Indizes nicht angegeben sind, oder den durch die Indizes für Zeitschritt zsind und Parameter parind angebenen Datensatz von der bereits geöffneten Datei mit der Nummer filenr. Der Datensatz wird im Feld data zurückgeliefert, das mindestens die Dimension ndim1*ndim2*ndim3 haben muß.
Für alle Datensätze der Datei ist wahlfreier Zugriff möglich. Im Modus EAS3_WO (Datei geöffnet durch eas3writeks) darf eas3read nicht benutzt werden. Es wird geprüft ob die Indizes im zulässigen Bereich liegen und ob das Dateiende beim Lesen überschritten wird.
subroutine eas3readzs[_s|_d|_q](filenr,data,zsnr,parind) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ! Zweck: liest Datensatz nach Zeitschrittnummer und Parameterindex ! von einer bereits geoeffneten Datei !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! integer, intent(in) :: filenr ! Dateinummer ! Datensatz (mindestens ndim1*ndim2*ndim3 Elemente) real(KIND=CHOICE), dimension(*), intent(inout) :: data integer, intent(in) :: zsnr ! Zeitschrittnummer integer, intent(in) :: parind ! Parameterindex ! !CHOICE=Default-Datentyp (keine Angabe von KIND) ! oder FD_SRK, FD_DRK, FD_QRK bei den _s, _d, _q Varianten !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
eas3readzs liest die Daten des Zeitschrittes mit der Nummer zsnr aus dem Zeitschrittfeld und dem Parameterindex parind von der bereits geöffneten Datei mit der Nummer filenr. Der Datensatz wird im Feld data zurückgeliefert, das mindestens die Dimension ndim1*ndim2*ndim3 haben muß.
Für alle Datensätze der Datei ist wahlfreier Zugriff möglich. Im Modus EAS3_WO (Datei geöffnet durch eas3writeks) darf eas3readzs nicht benutzt werden. Es wird geprüft ob der Zeitschritt und der Parameterindex im zulässigen Bereich liegen.
subroutine eas3close(filenr,checkfile) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ! Zweck: Schliessen einer von EAS3IOMOD verwalteten Datei !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! integer, intent(in) :: filenr ! Nummer der zu schliessenden Datei logical, intent(in), optional :: checkfile ! Dateigroesse beim Schliessen ausgeben !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
eas3close schließt die von EAS3IOMOD verwaltete Datei mit der Nummer filenr.
Zur Unterstützung beim Debuggen wird bei Angabe des optionalen Arguments checkfile die Kennsatz-, Parameter- und Dateigröße ausgegeben. Entspricht die wahre Dateigröße nicht der Sollgröße, die sich aus der Dimensionierung der Datei errechnet, wird eine Warnung ausgegeben (eine Warnung wird also z.B. generiert, wenn nicht ausreichend viele Parameter oder Zeitschritte auf die Datei geschrieben wurden).
Achtung: eas3close sollte unbedingt vor dem Programmende für alle geöffneten Dateien benutzt werden. Die Ausgaben auf die Dateien werden z.T. vom Betriebssystem gepuffert, und was bei Programmabbruch mit den Puffern geschieht ist systemabhängig. Deswegen garantiert nur ein geordnetes Schließen der Dateien die ordnungsgemäße Leerung aller Puffer.
Falls eine Datei in einem neuen Modus mit eas3writeks/eas3readks geöffnet werden soll, muß sie vorher mit eas3close geschlossen werden.
subroutine eas3delete(fname) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ! Zweck: Loeschen einer Datei !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! character(LEN=*), intent(in) :: fname ! Dateiname (max. FNAMELEN Zeichen) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
eas3delete löscht die Datei mit dem Namen fname.
Die Datei darf nicht mehr von EAS3IOMOD benutzt werden, sie muß gegebenenfalls vorher mit eas3close geschlossen werden. Ansonsten kann die Routine auch beliebige Dateien und leere Verzeichnisse löschen.
logical function eas3isopen(filenr) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! integer, intent(in) :: filenr ! Dateinummer !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
oder:
logical function eas3isopen(fname) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! character(LEN=*), intent(in) :: fname ! Dateiname !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
eas3isopen liefert zurück ob eine Datei bereits geöffnet ist oder nicht. Das Argument kann eine Dateinummer (filenr) oder der Dateiname (fname) sein.
subroutine eas3getks(ks,dform,bform,nzs,npar,ndim1,ndim2,ndim3,amode,gmode,umode,ng,nu)
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
! Zweck: liefert einen Kennsatz mit entsprechend den Angaben allokierten und vorbelegten
! Feldern zurueck (restliche Daten muessen dann noch vom Benutzer geliefert werden)
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
type (eas3ks_t), intent(inout) :: ks ! Kennsatz der entsprechend vorbelegt werden soll
integer, intent(in) :: dform ! Dateiformat
integer, intent(in) :: bform ! Binaerformat
integer, intent(in) :: nzs ! Anzahl der Zeitschritte
integer, intent(in) :: npar ! Anzahl der Parameter
integer, intent(in) :: ndim1 ! Anzahl der Elemente in Dimension 1
integer, intent(in) :: ndim2 ! Anzahl der Elemente in Dimension 2
integer, intent(in) :: ndim3 ! Anzahl der Elemente in Dimension 3
integer, intent(in) :: amode ! Attributmodus
integer, dimension(5), intent(in) :: gmode ! Geometriemodi
integer, intent(in) :: umode ! Modus fuer benutzerdefinierte Felder
integer, dimension(5), intent(in), optional :: ng ! optionale Laengenangaben fuer die
! Geometriefelder
integer, dimension(3), intent(in), optional :: nu ! optionale Laengenangaben fuer
! benutzerdefinierte Felder
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
eas3getks liefert einen Kennsatz ks zurück, dessen dynamische Felder entsprechend den Dimensionierungs- und Modusangaben allokiert und mit Defaultwerten belegt wurden. Die Bedeutung der einzelnen Argumente wird durch die Beschreibung des Kennsatz-Datentyps klar. Die verwendbaren Werte für die einzelnen Argumente und die Default-Belegung der optionalen Felder sind im Verzeichnis der definierten Konstanten beschrieben. Für das Zeitschrittfeld werden nzs Elemente allokiert und es wird mit den Werten ks%zsf(i)=i mit i=1,nzs vorbelegt.
Im Modus EAS3_UDEF_G muß das Feld ng zwingend angegeben werden. Im Modus EAS3_INT_UDEF (für EAS2-Dateien bei denen das Infofeld benutzt wird, bei denen also ks%nu(2)>0 gilt) ist das Feld nu, insbesondere der Wert nu(2), zwingend erforderlich. In den anderen Modi sind diese Angaben nicht erforderlich und werden ignoriert. Falls nur das Feld nu und nicht das Feld ng angegeben wird, ist es erforderlich im aufrufenden Programm als Argument ...,nu=nu_var) anzugeben, damit erkannt wird, um welches optionale Argument es sich handelt.
eas3getks sollte benutzt werden, um für Aufruf von eas3writeks einen richtig allokierten Kennsatz übergeben zu können. Man kann zwar alles von Hand machen was eas3getks erledigt, aber es wäre vergleichsweise aufwendig. Anschließend sollten die Defaultwerte vom Benutzer noch mit sinnvolleren/aussagekräftigeren Werten überschrieben werden.
subroutine eas3printks(ks,choice) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ! Zweck: gibt einen Kennsatz formatiert auf die Standardausgabe aus !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! type (eas3ks_t), intent(in) :: ks ! auszugebender Kennsatz ! Optionale Strings zur Beschraenkung des Ausgabeumfangs character(LEN=80), optional :: choice !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
eas3printks erhält einen Kennsatz ks und optional eine Zeichenkette choice zur Spezifizierung der gewünschten Ausgabe als Parameter. Der Kennsatz muss der oben spezifizierten Form entsprechen und also am besten mit eas3getks erzeugt werden, oder z.B. ein von eas3readks gelieferter Kennsatz sein. Wird an eas3printks ein nicht allokierter Kennsatz übergeben, so führt dies unweigerlich zum Programmabsturz. Das optionale Argument choice ist eine Zeichenkette, die Schlüsselworte enthält. Auf diese Weise kann der Umfang der Ausgabe eingeschränkt werden. Zulässige Schlüssel sind:
Grundsätzlich gilt, daß jeweils die Felder ausgegeben
werden, deren Schlüssel angegeben ist. Beispiel:
eas3printks(ks, "geo,udef")
würde bewirken, daß Geometrie- und benutzerdefinierte Daten
ausgegeben werden, die Zeitschrittfelder jedoch nicht. Die
verschiedenen Schlüssel können beliebig zusammengehängt
werden. Dies gilt natürlich auch für die definierten
Konstanten: z.B. ist
eas3printks(ks, EAS3_PR_GEO // EAS3_PR_UDEF)
äquivalent mit der obigen Angabe mit Strings.
Wird kein Schlüssel angegeben, d. h., ist das optionale Argument nicht vorhanden, gibt die Routine alle Felder aus. Wird überhaupt keine Ausgabe der Kennsatzdatenfelder gewünscht, kann ein leerer String "" als Argument choice angegeben werden. In diesem Fall erscheinen nur die Informationen zu Datei- und Datenformat, jedoch keine Felddaten des Kennsatzes.
Außerdem ist die Ausgabe von den Konstanten abhängig, die von eas3getks bzw. eas3readks nach dem Allokieren der Datenfelder gesetzt werden. Für EAS2-Daten wird beispielsweise das alte Info-Feld auf das benutzerdefinierte Integerarray (EAS3) abgebildet, sowie die oben definierten Konstanten (EAS3_NO_ATTR,...) gesetzt. eas3printks gibt infolgedessen nur diejenigen Felder aus, die im Kennsatz auch belegt sind.
Besonderheit: Im Normalfall werden die drei benutzerdefinierten Felder unabhängig voneinander ausgegeben. Wenn die drei benutzerdefinierten Felder jedoch gleich lang sind, werden sie in einer gemeinsamen Tabelle nebeneinander ausgegeben. Diese Eigenschaft kann benutzt werden, um die Integer- bzw. Realfeldeinträge mit dem Characterfeld zu dokumentieren. Diese Ausgabemethode wird auch bei der Kennsatzausgabe in EAS3 benutzt (Befehl KENNSATZ).
subroutine eas3print(filenr,zsind,parind)
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ! Zweck: Fuenfspaltiger Ausdruck der Daten eines Zeitschrittes; werden die optionalen ! Parameter nicht angegeben, wird der erste Zeitschritt in der Datei filenr ! ausgegeben. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! integer, intent(in) :: filenr ! Dateinummer integer, intent(in), optional :: zsind ! Zeitschrittindex integer, intent(in), optional :: parind ! Parameterindex !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
eas3print gibt einen Datensatz vollständig aus. Die Datei mit der Nummer filenr muß bereits in einem der Modi EAS3_RO oder EAS3_RW (also mit eas3readks) geöffnet worden sein. Die optionalen Argumente parind und zsind ermöglichen die Auswahl bestimmter Parameter und Zeitschritte; fehlen diese Angaben, wird der nächste Datensatz ausgegeben. Die Ausgabe erfolgt in fünf Spalten. Falls eine dritte Dimension in den Datensätzen enthalten ist (ks%ndim3>1), wird diese in zusätzlichen Bildschirmseiten angezeigt (kann evtl. sehr lang werden). Es wird geprüft ob die Indizes im zulässigen Bereich liegen.
Hier seht eine aktuelle Version zum Download bereit. Man benötigt zum Compilieren auch die aktuelle Version von baselib. Das Skript Mkmf erzeugt ein Makefile. Im Makefile müssen noch die entsprechenden Optionen zum Compilieren aktiviert werden (Default ist eine Version mit intern einfacher Genauigkeit für 32-Bit SGI-Maschinen). Durch das Compilieren mit make wird auch ein Testprogramm eas3iotest erzeugt mit dem überprüft werden kann, ob die Übersetzung erfolgreich war. Der Quellcode des Testprogramms eas3iotest.f90 zeigt beispielhaft wie EAS2- bzw. EAS3-Dateien mit den neuen IO-Routinen geschrieben und gelesen werden.
| Version | Datum | Kommentar |
| 1.0.0 | 22.07.1999 | erste freigegebene Version |
| 1.0.1 | 02.08.1999 | Anpassungen für NEC und T3E |
| 1.0.2 | 24.08.1999 | Kennsatz-Ausgabe für Modus EAS3_ALL_G korrigiert; möglichen Under-/Overflow beim Einlesen von IEEED-, IEEEQ-Daten bei 32-Bit-Maschinen abgefangen |
| 1.0.3 | 09.11.1999 | die I/O-Routinen werden ab jetzt auch als Bibliothek
(libeas3iomod.a) zur Verfügung gestellt (keine Änderungen an den IO-Routinen gegenüber Version 1.0.2) |
| 1.1.0 | 07.12.1999 | zusätzlichen Schreibmodus EAS3_WRA für Spezialanwendungen implementiert, die wahlfreien Schreibzugriff für alle Zeitschritte/Parameter von Anfang an benötigen. |
| 1.1.1 | 22.12.1999 | Modus EAS3_INT_UDEF bei EAS2-Dateien nur noch gesetzt, wenn die Infofeldlaenge groesser als Null ist. |
| 1.1.2 | 17.01.2000 | Portierung auf HP-V-Class 64Bit; Ausgabe von eas3printks für EAS3-Daten überarbeitet |
| 1.1.3 | 09.02.2000 | Work Around für Compilerfehler auf T3E eingebaut
(interne Feldallokierung zum Zwischenspeichern des Zeitschrittfeldes
auf T3E umgangen); Fehler bei der Indizierung der Parameter beim Schreiben von EAS2-Datensätzen beseitigt. (Die Kennung vor dem eigentlichen Parameter wurde falsch geschrieben. Der Fehler ist jedoch unbedeutend, da weder das alte EAS2 noch das neue EAS3 diese Angaben beim Lesen intern verwenden.) |
| 1.1.4 | 11.04.2000 | Optimierung der Performance, falls interner Datentyp dem externen Datentyp entspricht: es wird dann kein Zwischenspeicher beim Schreiben/Lesen eines Parameters allokiert und kein Under-/Overflow abgefangen, weil das in diesem Fall nicht auftreten kann. |
| 1.2.0 | 07.06.2000 | Umstellung auf EAS3_I8R8-Kennsatz. Alle Datentypen im Kennsatz sind 8-Byte-Typen (Integer, Real), d.h. Daten des Kennsatzes können zwischen den Grossrechnern ohne Genauigkeitsverlust übertragen werden. Daten mit dem alten I4R4-Kennsatz können weiterhin gelesen werden. |
| 1.2.2 | 04.08.2000 | Implementierung der Inforoutine eas3isopen. |
| 1.3.0 | 12.03.2001 | Portierung auf Hitachi SR8000; Defaultwerte für Attribute auf Leerstrings umgestellt; wahlweiser Test/Ausgabe der Dateigröße bei eas3close für Debugging-Zwecke; Aufruf von fflush direkt nach der Kennsatzausgabe, damit bei Großen Rechnungen auf NEC der geschriebene Kennsatz noch während des Laufs angesehen werden kann. Umstellung von Makefile zu Kombination aus Mkmf-Skript und Makefile.base, um das Compilieren auf verschiedenen Plattformen zu erleichtern. |
| 1.3.1 | 21.09.2001 | Portierung auf Intel Itanium (IA64) mit sgif90-Compiler (inklusive little-/big-endian Konvertierung) |
| 1.3.2 | 25.09.2001 | Umstellung auf Nutzung von baselib und Portierung auf IA32 mit PGI-Compiler |
Sollen die Fortran-IO-Routinen in eigene Programme eingebunden werden, muß der Compiler den Pfad zu den EAS3IOMOD-Modulen (*.mod Dateien) beim Complieren dieses Programmes kennen. Beim Linken müssen alle Objektfiles des IO-Moduls oder alternativ die Bibliothek libeas3iomod.a eingebunden werden (die Bibliotheksvariante ist bequemer). Die Compileroptionen für die IO-Routinen und das eigene Programm müssen zusammenpassen (oft beschwert sich der Linker nicht wenn das nicht der Fall ist!). Um an einem Beispiel zu sehen, wie die Routinen in eigene Programme eingebunden werden, ist ein Blick in das Makefile von EAS3 (siehe dort) empfehlenswert.
Hier trotzdem ein kurzes Beispiel für ein Shellskript (wenn kein Makefile verwendet wird):
#!/bin/ksh
### Beispiel 1: einbinden der Bibliothek
EAS3IOMOD_DIR=~iagdanie/EAS3/eas3iomod # dieser Pfad ist entsprechend anzupassen
# Compilieren (das eas3iomod Verzeichnis muß mit "-I Pfad" dem Compiler zugänglich sein, damit die Modulfiles gefunden werden):
f90 .... -c fortranfile.f90 -I$EAS3IOMOD_DIR
# Linken (Bibliothekssuchpfad erweitern und Bibliothek einbinden):
f90 ... -o executable Objectfiles -L$EAS3IOMOD_DIR -leas3iomod
#!/bin/ksh
### Beispiel 2: einbinden aller Objectfiles
EAS3IOMOD_DIR=~iagdanie/EAS3/eas3iomod # dieser Pfad ist entsprechend anzupassen
EAS3IOMOD_OBJS="$EAS3IOMOD_DIR/eas3iokinddef.o $EAS3IOMOD_DIR/eas3iotypedef.o $EAS3IOMOD_DIR/eas3ioconstdef.o $EAS3IOMOD_DIR/eas3iompifmod.o $EAS3IOMOD_DIR/eas3ioerrormod.o $EAS3IOMOD_DIR/eas3ioc.o $EAS3IOMOD_DIR/eas3iomod.o"
# Compilieren (das eas3iomod Verzeichnis muß mit "-I Pfad" dem Compiler zugänglich sein, damit die Modulfiles gefunden werden):
f90 .... -c fortranfile.f90 -I$EAS3IOMOD_DIR
# Linken (alle Objectfiles müssen eingebunden werden):
f90 ... -o executable Objectfiles $EAS3IOMOD_OBJS -I$EAS3IOMOD_DIR
Es gibt bisher keine Routine, um die Felder des Kennsatzdatentyps wieder zu deallokieren. Das Problem liegt darin, daß das Programm abstürzt, wenn man einer solchen Routine unbeabsichtigt einen Kennsatz mit nicht allokierten Feldern übergibt. Das läßt sich leider auch nicht abfangen. Deshalb wurde auf eine solche Routine verzichtet. Dieses Problem ist allerdings nur relevant, wenn man eine Kennsatzvariable für mehrere verschiedene Kennsätze verwenden möchte. Man muß dann gegebenenfalls die die Felder von Hand deallokieren, um zu vermeiden, daß nicht mehr zugreifbare Speicherbereiche entstehen.