Date post: | 22-Mar-2016 |
Category: |
Documents |
Upload: | robin-lenogue |
View: | 235 times |
Download: | 1 times |
ARCHITECTURE DEVELOPMENT FOR SIMULTANEOUS MULTIPLE NUMERICAL CODES
BY
ROBIN LENOGUE
AN INTERNSHIP REPORT SUBMITTED TO THE FACULTY OF
PIERRE AND MARIE CURIE UNIVERSITY & OBSERVATORY OF PARIS
IN PARTIAL FULFILLMENT OF THE REQUIREMENTS FOR THE DEGREE OF
MASTERS OF SCIENCE DEGREE IN ASTRONOMY AND SPACE-BASED SYSTEMS ENGINEERING
SUPERVISOR: VINCENT CHEVRIER, ASSISTANT PROFESSOR
ARKANSAS CENTER FOR SPACE AND PLANETARY SCIENCE
FELD 202, UNIVERSITY OF ARKANSAS, 72701 FAYETTEVILLE AR, USA
SEPTEMBER 2012
Internship report: architecture development for simultaneous multiple numerical codes
M2 OSAE 2012 2
Internship report: architecture development for simultaneous multiple numerical codes
M2 OSAE 2012 3
ABSTRACT
ARCHITECTURE DEVELOPMENT FOR SIMULTANEOUS MULTIPLE NUMERICAL CODES
Robin Lenogue
Pierre and Marie Curie University, Observatory of Paris
Masters of Science degree in astronomy and space-based systems engineering
In the field of planetary science, surface processes are traditionally modeled using thermodynamic
numerical codes like Geochemist's Workbench or Frezchem. These codes determine the mineralogical
assemblages resulting from various processes such as evaporation, freezing, hydrothermalism, etc. Recently,
Vincent Chevrier et Al. have developed a new mass and heat transfer code to analyze volatile stability and
distribution on the surface of various planets and satellites (Mars, Iapetus, Titan, etc.). This code can be used
especially on Mars to determine the evolution and lifetime of paleolakes or other aqueous formations.
However, most of these codes are disconnected from each other and they are often written in different
languages (Matlab, Fortran and C++ mostly), which make some problems very hard to resolve. Typically,
kinetic problems involving complex compositional changes are almost impossible to resolve with the existing
single codes, and, on the other side, GWB or Frezchem do not carry the temporal dimension.
The aim of this project is to develop an architecture allowing multiple codes to be run simultaneously.
This involves developing routines (most likely pipes) allowing data and variable transfer between
thermodynamic and kinetic codes, so they can be run simultaneously. A parallel part of the project is also to
develop a user and graphic interface or documentation for using the combined codes without specific
computing knowledge, and to represent the data. The end product will be used by the researchers from the
Space Center on specific projects like the stability and evolution of Martian paleolakes, which is especially
relevant with the recent MSL mission that landed in Gale Crater, a well-known paleolake.
By developing programs and routines allowing data and variables to be exchanged between two or more
programs in a time efficient way, we show that the use of this architecture between different programs
requires time, mistakes, and a large panel of tests problems which result is already known.
Internship report: architecture development for simultaneous multiple numerical codes
M2 OSAE 2012 4
RESUME
DEVELOPPEMENT D'UNE ARCHITECTURE SYSTEME DE MULTI-CODES NUMERIQUES APPLIQUES AUX
SCIENCES PLANETAIRES
Robin Lenogue
Université Pierre and Marie Curie, Observatoire de Paris
Master 2 Outils et systèmes de l’astronomie et de l’espace
Dans le domaine des sciences planétaires, les processus de surface sont traditionnellement modélisés à
partir de codes numériques thermodynamiques comme Geochemist's Workbench (GWB) ou FREZCHEM. Ces
codes déterminent les groupes minéralogiques résultant de divers procédés tels que l'évaporation, la
congélation, etc. Récemment, Vincent Chevrier et son équipe ont mis au point un code de transfert
thermodynamique inédit pour analyser la stabilité et la distribution des volatiles à la surface de différentes
planètes et satellites (Mars, Japet, Titan, etc.). Ce code peut être utilisé en particulier sur Mars afin de
déterminer l'évolution et la durée de vie de paléo-lacs ou autres formations aqueuses. Cependant, la plupart
de ces codes sont déconnectés les uns des autres et sont souvent écrits dans des langages différents
(Matlab, Fortran et C++ pour la plupart), ce qui rend certains problèmes difficiles à résoudre : une cinétique
complexe impliquant des changements de composition est presque impossible à analyser avec les codes
indépendants actuels, mais GWB ou FREZCHEM ne proposent, eux, pas d’analyse à dimension temporelle.
Le but de ce projet est donc de développer une architecture système permettant à de multiples codes de
fonctionner simultanément. Il implique le développement de routines (« pipes », entre autres) permettant le
transfert de données et de variables entre codes thermodynamique et cinétique, de sorte qu'ils puissent
être utilisés simultanément. L’un des objectifs secondaires du projet est aussi de développer une
documentation utilisateur ou interface graphique pour permettre l’utilisation de ces codes sans
connaissance informatique spécifique, et en extraire les données. Le produit final sera utilisé par les
chercheurs du Space Center sur des projets spécifiques tels que les études de stabilité et d'évolution de
paléo-lacs martiens, particulièrement en vogue depuis la récente mission MSL qui a atterri dans le cratère
Gale, un paléo-lac Martien bien connu.
En développant des programmes et routines permettant l’échange optimisé de données et variables
entre deux ou plusieurs programmes, nous montrons que l'utilisation d’une architecture entre différents
entités nécessite du temps, des erreurs, et un grand panel de tests dont les résultats sont déjà connus.
Internship report: architecture development for simultaneous multiple numerical codes
M2 OSAE 2012 5
TABLE OF CONTENTS
1. CONTEXT & INTRODUCTION ................................................................................................... 6
1.1. CONTEXT ........................................................................................................................................ 6
1.2. INTRODUCTION ................................................................................................................................ 6
1.2.1. THE PROJECT ............................................................................................................................... 6
1.2.2. CONCEPT OF OPERATION ............................................................................................................... 7
1.2.3. INTRODUCTION EN FRANÇAIS ......................................................................................................... 8
1.3. JURISDICTION AND SECURITY ............................................................................................................. 9
1.4. FUNDING ........................................................................................................................................ 9
1.5. ACRONYMS ..................................................................................................................................... 9
2. PROJECT DEVELOPMENT ........................................................................................................ 9
2.1. INITIAL SCOPE STATEMENT ............................................................................................................... 11
2.1.1. REQUIREMENTS ......................................................................................................................... 11
2.1.2. SPECIFICATIONS ......................................................................................................................... 12
2.2. FIRST ADDENDUM TO INITIAL SCOPE STATEMENT ................................................................................. 16
2.2.1. REQUIREMENTS ......................................................................................................................... 16
2.2.2. SPECIFICATIONS ......................................................................................................................... 17
2.3. SECOND ADDENDUM AND FINAL SCOPE STATEMENT ............................................................................. 20
2.3.1. REQUIREMENTS ......................................................................................................................... 20
2.3.2. SPECIFICATIONS ......................................................................................................................... 21
2.3.3. INTEGRATION TESTS AND SYSTEM VALIDATION ................................................................................. 25
2.3.4. OPERATION DOCUMENTATION ..................................................................................................... 27
3. OPERATION AND APPLICATION .............................................................................................. 30
3.1. SYSTEM OPERATION ........................................................................................................................ 30
3.2. CONCLUSION ................................................................................................................................. 31
3.3. CONCLUSION EN FRANÇAIS .............................................................................................................. 32
BIBLIOGRAPHY ............................................................................................................................... 33
APPENDICES .................................................................................................................................. 35
Internship report: architecture development for simultaneous multiple numerical codes
M2 OSAE 2012 6
1. CONTEXT & INTRODUCTION
1.1. CONTEXT
This document, which is hereby referred to as “internship report” or “project report”, presents both the
specification and development methodology of the internship project named “architecture development for
simultaneous multiple numerical codes”. It describes the requirements of the project in a contractual way,
and mentions the objectives, resources, issues, boundaries, jurisdiction, self-evaluation, and implementing
rules of the required work.
The architecture development for simultaneous multiple numerical codes is a project proposed by, and
created for the Arkansas Center for Space and Planetary Science of the University of Arkansas in Fayetteville,
henceforth abbreviated as “SPAC”. It is supervised by Vincent Chevrier, further referred to as “supervisor”,
as detailed in the APPENDIX 1. The development of the project is led by Robin Lenogue (further denoted
“developer” or “programmer”), in partial fulfillment of the requirements for the degree of Masters of
Science Degree in astronomy and space-based systems engineering of the Observatory of Paris.
1.2. INTRODUCTION
1.2.1. THE PROJECT
The project “architecture development for simultaneous multiple numerical codes” consists of the
implementation of an architecture involving different computer programming developments related to
thermo-dynamical and chemical models of planetary science. As much as possible, each one of them will
follow the empowered computer programming system advancement represented by the V-model graph in
Figure 1.
As a matter of fact, this project answers the need of a contracting authority, the SPAC. This authority
defines the concepts and requirements and guides the programmer towards the expected detailed design of
the project. It is tested in multiple ways and validated before its delivery or use. Moreover, due to the
project’s tight bond between both the fundamental science and engineering fields, it is expected that the
actual use and operation of the different programs implemented will be followed by the programmer for any
explanation or necessary maintenance.
Figure 1: V model representing the development process of the project
Internship report: architecture development for simultaneous multiple numerical codes
M2 OSAE 2012 7
1.2.2. CONCEPT OF OPERATION
The explicit purpose of this project is the development of a C++ program arranged as an intermediate
entity between different software or numerical codes for thermodynamic chemical modeling of the soil-
atmosphere interactions in solar system planets.
The project is addressed to the scientists and engineers of the SPAC needing simultaneous operation of
the codes they already know and may already use.
It requires the manipulation of various numerical codes concurrently, the use of designed entries to
specific software (such as pipes), and the integration of the different numerical, technical and procedural
requirements of each programming language or software.
The C++ program must be able to be used by Matlab, which itself contains the thermodynamic and
kinetic routines of the planetology science of this project. The chemical side of the system presents two
software entities:
- Geochemist's Workbench (henceforth referred to GWB) is the reference in geochemical modeling[1]
used for solving a wide range of problems in aqueous chemistry. It features a set of interactive
software tools for manipulating chemical reactions, modeling reactive transport, calculating the
equilibrium states of natural waters and stability diagrams, tracing reaction processes, and plotting
the results of these calculations.
- FREZCHEM (FREeZing CHEMistry) is a FORTRAN numerical code simulating and predicting the
behavior of substances at extremely cold temperatures[2]. The potential applications are numerous,
including examining the possibility of life on other planets, mine reclamation in cold regions, gas
hydration stability in oceans, or even commercial refrigeration processes. In the environment of the
SPAC at the University of Arkansas[3], FREZCHEM has been proven to possess the ability to reach low
temperatures that have not been reached with GWB yet.
The figure below presents this system as a black box scheme.
Figure 2: Black box scheme of the studied system
When used along with Matlab, this intermediate program is embedded in a proprietary Matlab code
written by Edgard G. Rivera-Valentin from Brown University. This Matlab routine models the evolution of a
Martian paleolake system which accounts for dissolved salts[4] and the evolution of the lake's salinity over
time. It can be applied to expected aqueous systems on Mars such as polyhydrated sulfate[5] and salts that
have been found within distinctive rings in Columbus Crater, Mars (c.f. Figure 3). It is hypothesized that
these rings are formed during the evolution of a saline Martian lake[6]. As the lake freezes and water is
removed from the liquid phase to the solid phase, the salinity of the liquid increases thus decreasing its
activity and freezing temperature. When the eutectic temperature of a salt in solution is reached, it
precipitates (comes out of solution) and is emplaced on solid surfaces (e.g. crater wall, or ice)[7]. By applying
this code, one can test if the distinctive hydrated rings within Columbus Crater can be attributed to an
evolving saline lake.
C++ program Matlab
GWB
FREZCHEM
Internship report: architecture development for simultaneous multiple numerical codes
M2 OSAE 2012 8
Figure 3: Sedimentary Layers in the northeast inner wall of Columbus Crater - NASA/JPL/University of Arizona[8]
However, the Matlab code itself does not account for the various salt phases and kinetics[9]. This is well
modeled by GWB or FREZCHEM, and can easily be read through the variable of water activity. Those latter
codes cannot model the evolving characteristics of a paleolake though, which supports the linking of these
numerical codes together.
1.2.3. INTRODUCTION EN FRANÇAIS
Le projet “Développement d'une architecture système de multi-codes numériques appliqués aux
sciences planétaires” est proposé par le Centre pour les Sciences de l’Espace et la Planétologie de
l’Université d’Arkansas (SPAC), situé à Fayetteville, aux Etats-Unis. Il est mené par Robin Lenogue dans le
cadre d’un stage de fin de formation Master OSAE (Outils et systèmes de l’astronomie et de l’espace) à
l’Observatoire de Paris.
Le but de ce projet est le développement d’une architecture système impliquant différents codes
numériques, routines ou programmes liés à des codes thermodynamiques et chimiques utilisés en sciences
planétaires. L’objectif premier est l’implémentation d’un programme C++ faisant l’intermédiaire entre
différents codes ou logiciels de modélisation chimique et cinétique de l’interaction sol-atmosphère des
planètes du système solaire.
Ce projet est adressé aux scientifiques et chercheurs du SPAC nécessiteux d’utiliser simultanément des
codes dont ils ont déjà connaissance. Le programme intermédiaire doit donc pouvoir être utilisé par Matlab
qui lui-même détient les routines thermodynamiques et cinétiques de planétologie liées à ce projet. Le coté
chimique du système peut être représenté par deux codes numériques : Geochemist’s Workbench (GWB) et
FREZCHEM. Ce sont deux puissants logiciels de modélisation de chimie aqueuse, multi-application pour l’un
et spécialiste des températures extrêmement froides pour l’autre.
Le principal code nécessiteux du programme C++ intermédiaire est une routine Matlab confidentielle
écrite par Edgard G. Rivera-Valentin. Ce programme modélise l’évolution d’un paléo-lac en considérant ses
sels dissous et l’évolution de sa salinité au cours du temps. Il peut aisément être appliqué aux systèmes
aqueux Martiens, comme les sulfates poly hydratés et les sels découverts sur anneaux bien particuliers du
Internship report: architecture development for simultaneous multiple numerical codes
M2 OSAE 2012 9
Columbus Crater, sur Mars (cf. Figure 3). Il existe une hypothèse selon laquelle ces anneaux se seraient
formés au travers de l’évolution d’un lac salé Martien. En appliquant le code Matlab à ce problème
spécifique, il est possible de tester si les anneaux hydratés de Colombus peuvent être attribués à un lac salin
en cours d’évolution.
Cependant, les codes Matlab ne prennent pas en compte les différentes phases minérales et cinétiques.
Celles-ci sont parfaitement modélisées par GWB ou FREZCHEM et peuvent aisément être obtenues par le
biais de l’activité de l’eau. Ces deux logiciels, eux, ne peuvent pas modéliser les caractéristiques fluctuantes
d’un paléo-lac, ce qui les rend très naturellement complémentaires.
1.3. JURISDICTION AND SECURITY
The project is led and completed under the only jurisdiction of its sponsor, supervisor and users. No
confidential material nor proprietary code is presented in the project report and will not be used nor kept by
the programmer – unless owner of such material – beyond the boundaries of the project.
The project’s safety is primarily provided by the user of the computer program in question. The project
itself is subjected to numerous tests throughout its implementation. Therefore, this document guarantees
the responsibility of the programmer in the stages of design and development of the program, and is free
from any liability following this period of development: March 3, 2012 – August 24, 2012. However, the
programmer remains available for advice related to the use of the program for a period of 6 months after
delivery of the product, by electronic request at [email protected].
1.4. FUNDING
The project is not sponsored individually. It is part of an internship partly funded by Pierre and Marie
Curie University and the Observatory of Paris, France. This internship is graciously hosted by the University
of Arkansas in Fayetteville, AR. The SPAC provides the programmer with the status of intern and the benefits
that comply with it in terms of training, premises and monitoring. Therefore, the programmer is aware that
the majority of the project is developed on the computer machines, operating systems and software made
available by and on the premises of the SPAC, courtesy of the University of Arkansas.
1.5. ACRONYMS
The acronyms and abbreviations used in this document are enumerated in the APPENDIX 2 and hereby
employed in the rest of the internship report
2. PROJECT DEVELOPMENT
The project at this phase can be represented as a global FAST-like diagram (c.f. Figure 4). This graph
dissects the subject matter under study and converts the “activities” performed in a system into the
functions performed by the system for its customers [10]. The purpose of the project and the techniques to
reach its purpose are thus clarified: the development of an intermediary program between the thermo-
dynamical part of the system and its kinetic and chemical part appears significant.
Internship report: architecture development for simultaneous multiple numerical codes
M2 OSAE 2012 10
Mo
del
th
oro
ugh
ly t
he
evo
luti
on
of
a M
arti
an
pal
eola
ke o
ver
tim
e
Mo
del
th
erm
od
ynam
ical
ly
the
lake
's s
alin
ity
and
d
isso
lve
salt
s
Stu
dy
the
po
lyh
ydra
ted
su
lfat
e an
d s
alts
of
dis
tin
ctiv
e ri
ngs
of
Co
lum
bu
s C
rate
r
Mo
del
th
e p
reci
pit
atio
n o
f th
e sa
lts
in s
olu
tio
n a
nd
its
tim
e ev
olu
tio
n
Lack
kin
etic
an
alys
is
Allo
w o
ne
mo
del
to
co
mm
un
icat
e w
ith
th
e se
con
d
Det
erm
ine
the
min
eral
ogi
cal
asse
mb
lage
s re
sult
ing
fro
m a
gi
ven
th
erm
od
ynam
ic
pro
cess
Res
olv
e ki
net
ic a
nal
ysis
of
chan
gin
g co
mp
osi
tio
ns
Lack
a t
emp
ora
l dim
ensi
on
C++
pro
gram
Mat
lab
pro
gram
GW
B /
FREZ
CH
EM
cod
es
Figure 4: FAST diagram of the system
Internship report: architecture development for simultaneous multiple numerical codes
M2 OSAE 2012 11
The first chemical software chosen to be linked to the C++ program is the Geochemist's Workbench. This
choice is logically made from the quantity and quality of information found in the GWB Reference Manual[11]
and the possibility to contact some engineers from the GWB online support and GWB development team
(later in the project and after numerous conversations with these engineers, it also appeared that GWB
might in fact be able to deal with freezing temperatures as well as FREZCHEM). The black box scheme of the
project can thus be drawn as below.
Figure 5: Black box scheme of the simplified system
2.1. INITIAL SCOPE STATEMENT
The scope statement of the project is summed up and written down by the programmer after oral
statements and discussions with his supervisor. Working in the field of science and scientific research, it is
expected that the project in itself may evolve, or that its potential users’ perception of the context in which
it is developed change its initial purpose. In any way, the programmer prepares the specifications resulting
from the requirements stated by the supervisor, the algorithm, and the programming developments, for
each evolution of the initial project.
2.1.1. REQUIREMENTS
R1. Using the chapter « Remote Control » of the GWB Reference Manual, a program is to be developed
in C++ in order to communicate with the application React of the software GWB (further referred to simply
as GWB). This tool can calculate speciation in aqueous fluids and trace reaction paths involving fluids,
minerals, and gases. It also helps predicting fractionation of stable isotopes during reaction processes.
R2. It is commendable to embed this C++ program in a Matlab code for it to be run in preexisting Matlab
routines. In this context, the program shall be executed many times in a row; each time is to be called one
“iteration”.
R3. The first part of the code shall take into account a given sample script (shown in Figure 6) that is to
be run by GWB through the means of pipes. This script can naturally be used in GWB directly for
transparency and understanding purposes. The C++ program shall easily get the following parameters and
apply them to the initial script in order to modify it as wanted:
- Path of the log file where to save the data
- Temperature
- Water for the system to react
- Time step
- Iteration number
R4. The water activity computed by GWB shall be outputted at the end of the simulation. This main
output shall be extracted from the C++ program in order to be seen by the user and eventually reached by
an external software (such as Matlab), but it shall also be saved in a log file (or output file) along with the
script sent. As a matter of fact, the whole result of the simulation shall be saved every time the program is
called and run (whether run once or in a series of simulations).
C++ program Matlab GWB
Internship report: architecture development for simultaneous multiple numerical codes
M2 OSAE 2012 12
The thoroughness of the program and the programming details are left up to the programmer, but shall
be relevant for the purpose of the project.
2.1.2. SPECIFICATIONS
S1. Given the specificity of the chemical program to be used in the project, it is approved that the project
– developed along with the scope statement – shall follow the Gantt diagram visible in Figure 7.
S2. The C++ program uses the pipe mentioned in the GWB Reference Manual along with the sample
script visible in Figure 6, property of Vincent F. Chevrier. This sample script, once sent to GWB, initializes the
current parameters in the React software and starts the chemical simulation once it reaches the command
“go”. Each of the lines forms a command, and each of them can be entered one by one in the actual GWB
software.
Figure 6: Sample script used for initial scope statement
S3. A period of familiarization with the GWB tools and conversations with the GWB support settles the
command used to output the water activity from the GWB simulation to be “report watact”.
S4. In order to take into account the parameters required in the scope statement (R3), the C++ program
shall take them as arguments of the main function. It then mainly needs to initialize the script as shown in
Figure 6 with the value of these arguments, send it to GWB and report the water activity from GWB as well,
without forgetting to copy the script sent every iteration (the “current script”) along with its own output into
an external log file.
Architecture
The architecture of the program can be represented as shown in the Figure 10. This flowchart outlines
that the C++ program is able to be used by an external program such as Matlab through a “system”
command (c.f. R2). It is eventually run by a Matlab routine monitoring the requested parameters and setting
them up as arguments of the executable program.
Design
The C++ program is compiled as an executable file called “pipe_GWB.exe”. As stated in the requirement
R3, it accepts the six arguments enumerated below, that are all treated as character arrays. Their length
shall not be bigger than 200 characters.
Internship report: architecture development for simultaneous multiple numerical codes
M2 OSAE 2012 13
Argument number Argument Used in
1 Path of the log file C++ program and GWB
2 Temperature (in ) GWB through C++ program
3 Water to react (in ) GWB through C++ program
5 Time step GWB through C++ program
6 Iteration number C++ program only
As required in the paragraph R4 of the initial scope statement, the first part of the program sets up a log
file – named “Output_pipe_GWB” – and opens it as writing stream, under the path entered as first
argument. The iteration number is written right away at the end of this text file in case any error should
occur during this given iteration.
The script is written in an array of character pointers, with each pointer corresponding to a line (a GWB
command) of the script. The lines dealing with the parameters present as arguments of the program
naturally take into account the values of these arguments.
The second part of the program deals with the pipe communicating with the software GWB (c.f. R1). It
uses a helper program, called RC_helper and provided by the GWB support, that allows working a pipe with
GWB through the class Pipe (initializing a named pipe with the considered target) and the methods
SendCommand and OpenGwbApplic. Using these class and methods, the application React is opened and its
directory is set up under the path entered as first argument of the executable file. The script is sent pointer
by pointer (command by command) and saved in the log file as one goes along. The requested report
(watact), specified as specification S3, is produced through the same pipe and sent to the standard output
“cout”, for the water activity to be available to the user of the program. This output is saved in the log file as
well.
The last part of the program deals with the chemical log file, a text file produced by GWB on its own and
named “React_output.txt” by GWB itself. It needs to be duplicated in order for the pipe_GWB program to
save the data resulting from each iteration in its entirety (requirement R4). Therefore, the program copies
“React_output.txt” at the end of another file, that it calls “React_output_ALL.txt”.
The program ends up resetting the GWB application’s working directory and closing the software. It also
deletes the files produced by GWB on its own: “React_output.txt”, and another file called “React_plot.gtp”,
which is created by GWB to be read by its application GTplot. These files are to be removed because they
would only belong to the one last simulation of a series, if the C++ program were to be used to run many
iterations (like the Matlab program intent to do). Keeping them in the working directory would be more
likely to deceive the user, since the rest of the files in this directory would reflect the global simulation.
Executable program
The first development of the project, set in specification S1, was interrupted by several adjunctions to
the initial scope statement. Its development is to be carried on along with these modifications.
Internship report: architecture development for simultaneous multiple numerical codes
M2 OSAE 2012 14
Figure 7: Gantt diagram of the project according to the initial scope statement
Figure 8: Gantt diagram of the project according to the first addendum to initial scope statement
Figure 9: Gantt diagram of the project, according to the last update of the scope statement
Figure 10: Flowchart of the project according to the initial scope statement
Internship report: architecture development for simultaneous multiple numerical codes
M2 OSAE 2012 15
Figure 11: Flowchart of the project after the first addendum to initial scope statement
Figure 12: Flowchart of the project according to the final scope statement
Internship report: architecture development for simultaneous multiple numerical codes
M2 OSAE 2012 16
2.2. FIRST ADDENDUM TO INITIAL SCOPE STATEMENT
After the early results of the program pipe_GWB.exe and as consequence of the existence of such a tool,
the initial scope statement is modified and appended. This addendum involves more complicated
requirements towards the update of GWB’s script from one iteration to the next. On top of that, the
programmer is notified of a new release of the software GWB. Working on an implementation of the key
features of this release 9.0 allows the supervisor to obtain a discount on this new software as well as a trial
version of 90 days. The program developed for GWB release 8.0 can be applied to 9.0 and show
improvements that are worth to be taken into account.
2.2.1. REQUIREMENTS
R5. As a continuity of the C++ program developed for the software GWB release 8.0, some changes must
be added to the pipe involving the communication of Matlab codes with GWB. On top of these changes
detailed below, an updated program shall be developed for the same purpose to be achieved within the
release 9.0 of the software GWB. The C++ program working with GWB release 8.0 shall be called
pipe_GWB8.exe and the one updated for GWB release 9.0 shall be called pipe_GWB9.exe.
R6. A deeper understanding of the system implies some specific chemical elements (reported by GWB
after an iteration) to be taken into account from one iteration to the next. The minerals used by the script
shall then be reported from GWB at the end of iteration , stored, and inputted at iteration as script
update (along with the changes coming from the parameters). The parameters themselves shall now be the
following ones, and shall naturally modify the corresponding lines of the script:
- Path of the working directory
- Temperature
- Mass of water for the system to react
- Delta , the time-related precision step of GWB
- Time step
- Iteration number
R7. The implementation shall make sure that the value of Delta remains smaller than |Water mass
reacted|, for the integrity of the GWB simulation.
R8. Three lines shall be added to the initial script:
- suppress Hematite
- suppress Lepidocrocite
- suppress Goethite
R9. The script itself shall be run by the GWB software within a supported thermo database. This
database is called thermo_phrqpitz_v8_Vincent_Low T - 120 minerals - 07-19-2011.dat, property of Vincent
F. Chevrier.
R10. The water activity shall remain the main output, and the only one directly extracted from the C++
program. This output shall also be saved in a log file called “Output_pipe_GWB.txt” along with the script
sent. The chemical log file, created by GWB itself during every simulation, shall also be saved in a global
chemical log file called “React_output_ALL.txt”. It shall also be updated every time the program is called.
Internship report: architecture development for simultaneous multiple numerical codes
M2 OSAE 2012 17
2.2.2. SPECIFICATIONS
S5. The significant addendum to the initial scope entails the scheduling of a new implementation. This
implementation shall thus follow the Gantt diagram shown in Figure 8.
S6. The requirement R6 stating the necessary update, every new iteration, of the chemical species
present in the script – along with the parameters coming from Matlab – makes the system more
complicated. The table below thus shows that starting at the very first iteration, the C++ program shall
extract from GWB an independent set of data that shall be stored externally, in order to update the script of
the next iteration. Moreover, this update shall not be executed by the C++ program during the very first
iteration, since it would require a set of data that would be most likely to be inexistent yet.
Commands of the full script (c.f. Figure 13)
Commands modified by Matlab (through arguments of program)
Commands that will be modified (next iteration) by GWB reports
reset
temperature = 24.9 ×
swap e- for O2(aq)
swap CO2(g) for HCO3-
1 free kg H2O
13.05 pe
.006 fugacity CO2(g)
balance on H+
.1 mg/kg H+ ×
230 mg/kg Cl- ×
200 mg/kg Ca++ ×
243 mg/kg Mg++ ×
27 mg/kg K+ ×
447 mg/kg Fe++ ×
2000 mg/kg SO4-- ×
184 mg/kg Na+ ×
react -999.999 gram of H2O ×
fix Eh
fix fugacity of CO2(g)
delxi = .001 linear ×
step_increase = 1 ×
suppress Hematite
suppress Lepidocrocite
suppress Goethite
Go
S7. On top of a special behavior upon the very first iteration, the C++ program shall then manipulate a
new external file, in which the updated molalities of the chemical species present in the script shall be stored
every iteration.
S8. After a thorough research on how to report systematic quantities in GWB, it is verified that only a
molality can be outputted from GWB, through the command “report molality <specie>”. Since these
repetitive reports extract the quantity of the considered species in mole, the initial minerals present in the
script also have to be converted from concentration to molality (i.e. from gram to mole).
: molality (unit [mol/kgH2O])
: density of solute (unit less)
Internship report: architecture development for simultaneous multiple numerical codes
M2 OSAE 2012 18
: density of water
: molar mass of solute (unit [g/mol]: needs to be converted to [kg/mol])
: molar mass of solute in [kg/mol]
: concentration (unit [kg/kgH2O]1: unit less)
For a given mineral, the conversion comes from the following formula[12]:
S9. After conversion, the new initial script becomes:
Figure 13: Sample script used for the first addendum to initial scope statement
S10. At last, the command used in GWB to set up an existing database is “data "<database>" ”. Given
that the database considered in the requirement of the project is located in the database folder of GWB, the
command line sent to GWB through pipe shall then be “data "thermo_phrqpitz_v8_Vincent_Low T - 120
minerals - 07-19-2011.dat" ”.
Architecture
According to the specifications above, the architecture of the program can be updated as displayed on
the Figure 11. This flowchart shows that the arguments of the program have changed according to the
requirement R6, and that it now requires a condition upon the iteration number (c.f. S6), depending on
which it adds to the current script the molalities (from the GWB reports of the last iteration) or not.
1 Unit conversion for concentrations: [kg/kgH2O] = [mg/kgH2O] .
Internship report: architecture development for simultaneous multiple numerical codes
M2 OSAE 2012 19
Design
The preexisting C++ program is now compiled as an executable file called “pipe_GWB8.exe”. It accepts
the seven arguments enumerated below (according to requirement R6), that are still treated as character
arrays whose length shall not be bigger than 200 characters.
Argument number Argument Used in
1 Path of working directory C++ program and GWB
2 Temperature (in ) GWB through C++ program
3 Mass of water to react (in ) GWB through C++ program
5 Delta (unit less) GWB through C++ program
6 Time step (unit less) GWB through C++ program
7 Iteration number(unit less) C++ program only
The design of the first part of the C++ program remains unchanged for the most part. It still sets up a log
file named “Output_pipe_GWB.txt” as required in the addendum R10 to the scope statement, and defines
the current script as an array of character pointers, taking into account the values of the parameters coming
from Matlab.
The second part of the code opens and sets up the pipe with GWB, adding the database setting (c.f. S10),
and sends each command line of the current script through the pipe. It then evaluates if the iteration
number is different from 0 (zero). If so, it also sends the temporary file “tmpScriptChanges_Gwb.dat”
prepared during the last iteration (see below) to GWB through the opened pipe, and copied to the log file in
order to be saved. Indeed, an external file can also be read by GWB, through the command “read <file>”.
The molalities that are reported after that (c.f. S7) are saved in the foreseen tmpScriptChanges_Gwb.dat,
opened as a writing stream, in the current working directory. The writing of this particular file erases its
previous content (i.e. “temporary” file), which keeps the simulation set as expected.
The other report is kept unchanged: the pipe_GWB8 program extracts the water activity from GWB and
through the standard output, and saves it in the log file “Output_pipe_GWB.txt” as stated in requirement
R10. The chemical log file is copied and saved as well, and the pipe is reset and closed. Eventually, the
working directory is cleaned from the files coming from GWB on its own.
Executable program
The updated executable program, called pipe_GWB9.exe, is at first written in order to fit a feature of the
new release of the GWB software, GWB9 (c.f. R5). This “plug-in feature” requires a very different
architecture, and has the flaw of being developed under and linked to Microsoft Visual Studio 2008. It uses
the peculiar linker of this integrated development environment to be bonded to a library created by GWB as
well. Given the range of problems that this feature still contains, a patch is released for RC_helper to be
updated and used with GWB9. The only difference with GWB8 is that it only supports unnamed pipes.
Both the C++ pipe programs are now developed at once, but the last addendum to the scope statement
prevents the test phase to be terminated. The outcomes of the initial integration tests are taken into
accounts in the next addendum.
Internship report: architecture development for simultaneous multiple numerical codes
M2 OSAE 2012 20
2.3. SECOND ADDENDUM AND FINAL SCOPE STATEMENT
The second addendum to the initial scope statement expands the outreach of the project. Instead of
applying to one particular script, this final scope statement proposes to make the intermediary C++ program
a comprehensive tool. The project becomes adaptable and eventually gives the opportunity to complete the
modeling system.
2.3.1. REQUIREMENTS
R11. The pipe_GWB programs, both versions complying with GWB8 and GWB9, shall be updated in
order to embrace a broad range of scripts. Starting with the following original script, competitive and ideal
for the geochemical modeling systems, the C++ program shall be able to modify the main parameters that
define most scripts and update their chemical species’ values over time (from iteration to iteration).
Figure 14: Script used in the final scope statement
R12. The list of chemical species that shall be supported by the C++ programs is: Cl-, HCO3-, ClO4-, ClO3-, NO3-, SO4--, Br-, F-, H+, Li+, Na+, K+, Ca++, Sr++, Ba++, Mg++, Fe++, Mn++, Al+++, Fe+++, B(OH)3, SiO2(aq), O2(aq).
R13. The definite list of parameters that modify the corresponding command lines of the script is the
following:
- Path of the working directory
- Path of the database
- Path of the script
- Initial temperature (in )
- Final temperature (in )
- Mass of free water in the system (in )
- Mass of water for the system to react (in )
- Delta , the time-related precision step of GWB (unit less)
- Iteration number (unit less)
R14. The implementation, within the C++ program or not, shall make sure that the value of Delta
remains smaller than |Mass of water to react|, for the integrity of the GWB simulation.
Internship report: architecture development for simultaneous multiple numerical codes
M2 OSAE 2012 21
R15. The water activity shall still remain the main output, and the only one directly outputted from the
C++ program. This output shall also be saved in a log file called “Output_pipe_GWB.txt” along with the script
sent, and for every iteration. The chemical log file, created by GWB itself during every simulation, shall also
be saved in a global chemical log file called “React_output_ALL.txt”. It shall as well be updated every time
the program is called.
R16. This last update of the scope statement is particularly oriented to significant models, working a
considerable number of simulations. It shall also be easy to use, or at least well explain through a graphic
interface or user documentation.
2.3.2. SPECIFICATIONS
S11. The Gantt diagram corresponding to this last addendum to the scope statement is visible on the
Figure 9.
S12. The last requirement scope complicates again the considered system. For clarity and understanding
purposes, the next figure displays graphically the extent of the communication between the two sides of the
project:
Figure 15: Scheme of the dual system (the C++ program could naturally be located in the middle) at the final scope statement
S13. After the last implementation and operation of the pipe_GWB8 and pipe_GWB9 programs, it is
tested and noticed that the pipe with GWB only reads – or at least takes into account – one file per iteration.
Also, for 2 values of the same parameter sent in a row, the application React of GWB only acknowledges the
last value.
S14. An end-of-line (EOL) character is necessary at the end of the original script if another part of the
script is to be copied at its end. After a series of comparative tests, it is proven that the presence of a “go” in
the middle of a full script doesn’t change the water activity output of this script, though it makes the GWB
simulation last longer.
Internship report: architecture development for simultaneous multiple numerical codes
M2 OSAE 2012 22
S15. After numerous attempts, it is confirmed that the use of the pipe in a function of the C++ program
other than the “main” function does not process. The methods SendCommand and OpenGwbApplic shall
thus be used in the main function of the pipe_GWB program.
S16. The requirement R14 states that from a kinetic point of vue, the value of the parameter delta
must remain smaller than the absolute value of the mass of water to react. Since delta is a parameter sent
as argument of the program (most likely from Matlab), it is tested in Matlab as well. A routine is developed
for the value of delta to be reduced as much as the requirement R14 entails it. The Matlab routine is
shown in APPENDIX 3 and detailed later in this document.
Architecture
According to the requirement R11 stating that the program shall be adequate for different types of
scripts (most likely predefined, and already tested in GWB directly), the pipe_GWB program’s architecture is
widely modified. In fact, and given the test conducted in the GWB application and described above, the
script that is entered as argument of the executable file can be duplicated and appended with the different
changes coming:
- from Matlab,
- and from the GWB chemical reports performed the last iteration.
The entirety of the needed data is thus gathered in one temporary file (that shall be called
“tmpScriptChanges.dat”), which shall be read by GWB through the pipe (c.f. S13). This file is temporary
because it only comply with the last iteration occurred.
This resolution involves a set of manipulations to execute on the different files prior to calling for the
actual pipe with GWB. This set of manipulations is represented on the sub-process block (below the “start”
terminator block) of the flowchart in Figure 12.
This sub-process is now detailed in the waterfall diagram of the Figure 16. The C++ program shall indeed
set up the log file Output_pipe_GWB.txt, check the script file in order to add an EOL if it needs any (c.f. S14),
and create the current script (proper to the current iteration) tmpScriptChanges.dat consecutively. At this
point, the current script shall only be made out of the original script and the changes coming from Matlab. It
is only if the condition “Iteration n ≠ 1” is true that the molalities coming from the previous iteration are
appended to tmpScriptChanges.dat. The report of these molalities is executed every iteration with respect to
the requirement R12 and is still saved into the temporary file tmpScriptChanges_GWB.dat.
Internship report: architecture development for simultaneous multiple numerical codes
M2 OSAE 2012 23
Figure 16: Graph explaining the sub-process visible in Figure 12
In this final scope statement, the main concern is thus to use every single file of the system at the right
time, i.e. before erasing its content (e.g. tmpScriptChanges_GWB.dat) or after having updated it (e.g.
tmpScriptChanges.dat).
For this reason, every file of the project shall be called a sub-system. This allows us to draw the following
scheme:
Figure 17: Scheme of the system pipe_GWB.exe with its numerous sub-systems.
Following this motive and in compliance with the requirement R16, the implementation shall let this
system hierarchy appear. The pipe_GWB programs (for both GWB releases 8.0 and 9.0) shall thus use the
class File, with attribute m_filePath (corresponding to the path of the given File instance), through the
methods:
- writeCurrentIteration - sendErrorOpeningOutputFile
Internship report: architecture development for simultaneous multiple numerical codes
M2 OSAE 2012 24
- noEOL - sendErrorOpeningStream - Test - getFilePath
Design
The C++ program accepts the ten arguments enumerated below, as stated in the requirement R13. They
are still treated as character arrays whose length shall not be bigger than 200 characters.
Argument number Argument Used in
1 Path of working directory C++ program and GWB
2 Path of database GWB through C++ program
3 Path of script C++ program only
4 Initial temperature (in ) GWB through C++ program
5 Final temperature (in ) GWB through C++ program
6 Mass of free water (in ) GWB through C++ program
7 Mass of water to react (in ) GWB through C++ program
8 Delta (unit less) GWB through C++ program
9 Time step (unit less) GWB through C++ program
10 Iteration number(unit less) C++ program only
The programs pipe_GWB8.exe is designed to begin by initializing the paths of the different files it is to
use. It builds the file objects one by one, as they are needed.
Through the methods of the class File and a set of additional functions, the first part of the program
features the following actions:
- the current iteration is written in the main log file (Output_pipe_GWB.txt)
- the end of original script file is checked and an EOL is added if it is needed
- the current script (tmpScriptChanges.dat) is built in the working directory out of the original script
and the arguments of the main function (of the executable file).
All along the pipe_GWB program, any possible error is reported is the log file, unless it occurs before this
file is set up (usage error or log file’s opening permission error only). An error is followed by a direct
interruption in the process, but is first outputted in the standard output (cout) for legibility and transparency
purposes (c.f. R16). A warning informs the user of something that does not put into question the integrity
and the course of the simulation: it is only reported in the log file and does not stop the program.
The second part of the program sets up the pipe with GWB with the current directory and the thermo
database present as arguments of the program. It copies the tmpScriptChanges_GWB.dat file to
tmpScriptChanges.dat if the iteration number is different from zero. Whether this latter condition is true or
not, the program then adds a command “go” to the current script (c.f. S14) and copies it to the log file
before sending this current script to GWB through the pipe. The possible output from GWB (e.g. a warning, a
problem in the command lines of the script, an inner parameter out of the range of the thermo database,
etc.) is copied to the log file. In the pipe_GWB9.exe program, the pipe actually reports the whole simulation
at this moment, including the script entered before the actual simulation: this is the only difference between
the two programs, besides the use of named and unnamed pipes.
Internship report: architecture development for simultaneous multiple numerical codes
M2 OSAE 2012 25
Once the GWB simulation is done, the program reports the molality of the species enumerated in
requirement R12 if they exist (this allows to only save in tmpScriptChanges_GWB.dat the relevant data), and
then the water activity. This latter one is printed in cout and saved in the main log file as well.
The end of the program copies the file React_output.txt to React_output_ALL.txt and quit the application
GWB. The removing of the files coming directly from GWB (sub-systems visible in Figure 17: Scheme of the
system pipe_GWB.exe with its numerous sub-systems.) is cancelled since the last scope statement involves
some other temporary files created by the C++ program itself. All the files React_output.txt, React_plot.gtp,
tmpScriptChanges.dat and tmpScriptChanges_Gwb.dat comply with the last iteration run by GWB through
the C++ program, but they can all be useful in case of any occurring error.
Executable program
The final programs pipe_GWB8.exe and pipe_GWB9.exe show the differences mentioned above and are
respectively available in APPENDIX 4 and 5.
2.3.3. INTEGRATION TESTS AND SYSTEM VALIDATION
As shown in the Figure 1, the project is tested and integrated all along its implementation and until a
valuable executable program needs validation and verification. Many mistakes, omissions, and practical
improvement are made and corrected when necessary. The script test used for most of the integration tests
is shown in Figure 18: Test script used during the integration test of the project. It features a very easy and
predictable chemical system containing only 2 minerals.
Figure 18: Test script used during the integration test of the project
The system validation of the project is executed through a comprehensive list of particular tests focusing
on every error, warning or external problem that could occur to the program pipe_GWB.exe. Naturally, this
series of tests is applied to both programs pipe_GWB8 and pipe_GWB9. Unfortunately, the end of the trial
version of GWB release 9.0 prevents the programmer to finish the different tests scheduled. Through the use
of GWB8, the program pipe_GWB9.exe is eventually validated, and may be used if the SPAC happens to
update GWB to the release 9.0. However, the end of the internship report only complies with the program
pipe_GWB8.exe, around which the project is based until the end.
The different tests applied to the program are enumerated in the table below, but only the tests that
involve a change in the final scope statement and the program itself are detailed.
Name of the test Function Expected behavior of
the program Actual behavior of
the program
00TestOtherWorkingDirectory Testing a random working directory as argument of
the C++ program
Normal behavior, simulation executing
from the given directory
Expected behavior
01TestUsage
Testing a mistake in the usage of the executable
program (e.g. 11 arguments instead of 10)
Usage error Expected behavior
Internship report: architecture development for simultaneous multiple numerical codes
M2 OSAE 2012 26
02TestOutputFile
Changing the writing permissions of the log file in
the middle of a series of simulation
Stream opening error Expected behavior
03TestOutputFile_Hidden
Changing the property attribute of the log file in the middle of a series of
simulation
Normal behavior, simulation executing
without problem Expected behavior
04TestScriptFile_Relocation Changing the location of the script file in the middle of a
series of simulation Stream opening error Expected behavior
05TestScriptFile
Changing the writing permissions of the script file in the middle of a series of
simulation
Stream opening error Expected behavior
06TestScriptFile_NoEOL Removing the EOL at the
end of the script file
EOL warning in log file only, and addition of an EOL at the end
of the script file
Expected behavior
07TestScriptChanges
Changing the writing permissions of the
tmpScriptChanges.dat file in the middle of a series of
simulation
Copy error Expected behavior
08TestDatabase
Typing the name of an inexistent database as the database argument of the
C++ program
GWB’s normal behavior: prompting a window where to
select a valid database file
Expected behavior
09TestScriptChanges_Gwb
Changing the writing permissions of the
tmpScriptChanges_GWB.dat file in the middle of a series
of simulation
Stream opening error Expected behavior
10TestGwb
Running a script that leads to a chemical saturation
and an internal interruption of process in GWB
GWB’s error message (Most likely “Error: Run not finished”)
Expected behavior
11TestReactOutput
Changing the writing permissions of the
React_output.txt file in the middle of a series of
simulation
Stream opening error
GWB freezes
because it cannot access its main
chemical log file
12TestReactOutputAll
Changing the writing permissions of the
React_output_ALL.txt file in the middle of a series of
simulation
Copy warning present in log file
only Expected behavior
Internship report: architecture development for simultaneous multiple numerical codes
M2 OSAE 2012 27
The problem occurring with the React_output.txt file is that it is used by GWB before being copied in the
C++ program itself. To resolve this matter, a manipulation is added to the set described in Figure 16, which
means in the first part of the C++ program, right before the pipe with GWB is opened. This figure can then be
updated as the Figure 19.
Figure 19: Updated graph explaining the sub-process visible in Figure 12
This update is taken into account in the APPENDIX 6.
According to the system validation process, the program is proven verified and validated. The last
requirement of the project (c.f. R16) mentions the development of a documentation, user-friendly and
comprehensive about the use of the program pipe_GWB8.exe. This file is written for, and presented to the
supervisor of the project, validated by him and eventually formatted to a 2-page documentation.
This documentation is presented below and available upon request.
2.3.4. OPERATION DOCUMENTATION
Internship report: architecture development for simultaneous multiple numerical codes
M2 OSAE 2012 28
Internship report: architecture development for simultaneous multiple numerical codes
M2 OSAE 2012 29
Internship report: architecture development for simultaneous multiple numerical codes
M2 OSAE 2012 30
3. OPERATION AND APPLICATION
The main operation and utilization of the program pipe_GWB.exe is implemented in the Matlab routine
written by Edgard G. Rivera-Valentin from Brown University, under his management.
3.1. SYSTEM OPERATION
The pipe_GWB.exe program can be run through console, but can also easily be embedded in an external
numerical code, such as the Matlab programs used in this project. Although confidential, these Matlab
programs use the C++ program developed during this internship the same way as the pipe host routine
presented in APPENDIX 3 of this internship report.
This routine defines the variable pipePg, database and script to initialize the path of each of these files.
The Matlab function system can initialize the C++ program’s parameter working directory as the “current
folder” used by Matlab. It is this same system function that allows the user, once the other parameters are
initialized, to run the pipe_GWB8.exe program. A loop system can be built around the code for it to react all
the water of a given system, in 10 or iterations (with a Matlab variable). The rule according which delta
must always remain smaller than the absolute value of the Water mass to react is verified before the lines
calling the executable file itself are executed. One can display the list of parameters’ values sent for each
iteration, the output extracted from the C++ program or the possible error that can occur during the process.
In the end, the Matlab function str2double allows to convert the string outputted from pipe_GWB8.exe to a
double in order to use it in another code.
It is a similar routine that is embedded in the thermo-dynamic Matlab codes. The inner purpose of these
Freezing and Evaporation codes run consecutively is to detail the evolution of the water activity in a given
system established by the particular script sent to GWB. Once fully reacted, the water present in the system
and the chemical and kinetic properties of the system itself can display the water activity as shown in Figure
20.
Figure 20: Water activity evolution with respect to water mass, in a system defined by the GWB script shown in Figure 14 Graph displayed with the GTplot application of GWB, release 9.0
Internship report: architecture development for simultaneous multiple numerical codes
M2 OSAE 2012 31
These Matlab codes divide this curve in infinitesimal parts and use, through the intermediary
pipe_GWB8.exe program, the GWB simulation and especially the evolution of its water activity output to
indirectly link it with the temporal dimension. As a whole, such a simulation would compute the age of a
Martian paleolake of a certain chemical composition, or at least the time lasted for it to disappear.
The current simulation starts as expected, following the curve visible on Figure 20: Water activity
evolution with respect to water mass, in a system defined by the GWB script shown in Figure 14
Graph displayed with the GTplot application of GWB, release 9.0 for about 900 iterations (around 2 hours),
during which the activity shows a normal behavior: it smoothly increases for the first hundred iterations or
so, then decreases very slowly until it reaches about the 850th iteration. There, the water activity falls visibly
from about 0.98 to 0.73 in less than 50 iterations. Arrived at the 900th one, the simulations’ output goes
down to 0.001 in 4 or 5 iterations, despite the fact that it should even more slowly follow the curve. This
problem is related to large concentrations of water, coming from Matlab and unsupported by GWB. The
variable substitution in between these two codes is thus still in development.
The C++ program has brought a new eye on the system it completes. The improvements reached by the
implementation of the C++ program are especially beneficial to the Matlab programs. Its development is
ensured by both the supervisor and the coordinator, with the guaranteed remote help of the programmer of
this project. This system can now count on the intermediary program that bonds both its numerical codes.
3.2. CONCLUSION
The project “architecture development for simultaneous multiple numerical codes” is a system multi-
codes related to chemical and thermo-dynamical modeling. It involves different software and different
programming languages. Its main purpose is to develop a system linking thermodynamic Matlab codes to
kinetic and chemical applications, using a program written in C++.
This program is created and called pipe_GWB8.exe. It is tested, validated and its purpose is verified
through different tasks and tests. Its documentation is ready to use and certified as well. An update is also
developed and called pipe_GWB9.exe. These files allow together many chemical simulations to run and to
open the opportunity to model the evolution of Martian paleolakes. The difficulties related to this outcome
are identified, as variable substitutions and large concentrations. They will both be applied to develop and
improve both numerical codes on each side of the system.
Through the implementation of an original C++ pipe program communicating with the software
Geochemist’s Workbench and controlled by Matlab codes, we show that a system involving many entities,
updates, and a variety of numerical codes requires some time, some organization and a great
communication in between each party.
Internship report: architecture development for simultaneous multiple numerical codes
M2 OSAE 2012 32
3.3. CONCLUSION EN FRANÇAIS
Le projet « développement d'une architecture système de multi-codes numériques appliqués aux
sciences planétaires » est un système de codes multiples de modélisation chimique et thermodynamique. Il
décrit une l’architecture système de différents logiciels et de langages de programmation variés. L’objectif
principal du projet est de développer un programme C++ pour faire communiquer des routines
thermodynamiques Matlab à des simulations chimique et cinétique par le biais du logiciel Geochemist’s
Workbench.
Ce programme est créé et répond aux spécifications qui le définissent. Il est appelé pipe_GWB8.exe, son
fonctionnement est validé par le biais de nombreux tests et vérifications. Sa documentation est rédigée et
certifiée de même. Une mise à jour, nommée pipe_GWB9.exe, est également développée afin d’assurer son
adaptation à la sortie imminente d’un nouveau logiciel GWB. Ces programmes inédits dans ce domaine de la
science ouvrent de nombreuses opportunité d’utilisation, des simulations chimiques conjuguées à la
modélisation de l’évolution des paléo-lacs Martien. Les difficultés liées à cette actuelle modélisation sont
identifiées, et sont la conséquence de l’utilisation de trop grandes concentrations et de modifications de
variables d’un programme à l’autre. L’ensemble de ces problèmes viennent enrichir et développer les deux
codes numériques et sont, en particulier, un savoir à l’ampleur considérable pour la modélisation de
l’évolution temporelle des paléo-lacs Martiens.
A travers l’implémentation d’un program C++ original communiquant avec le logiciel GWB et contrôlé
par des codes numériques Matlab, nous démontrons qu’un système incluant plusieurs entités, usages, mises
à jour, et toute une variété de codes numérique exige du temps, de l’organisation, ainsi qu’une importante
communication entre chaque acteur.
Internship report: architecture development for simultaneous multiple numerical codes
M2 OSAE 2012 33
BIBLIOGRAPHY
Internship report: architecture development for simultaneous multiple numerical codes
M2 OSAE 2012 34
[1] C.M. Bethke, Geochemical Reaction Modeling, 1996
[2] G.M. Marion, D.C. Catling, J.S. Kargel, Modeling aqueous ferrous iron chemistry at low temperatures
with application to Mars, Geochim. Cosmochim. Acta, 67(22), 4251-4266, 2003
[3] G.M. Marion, D.C. Catling, M. Claire, K.J. Zahnle, Modeling aqueous perchlorate chemistries with
application to Mars, Lunar and planetary Science Conference, XL(1959), 2009
[4] E.G. Rivera-Valentin, D.G. Blackburn, R.Ulrich, Revisiting the thermal inertia of Iapetus: Clues to the
thickness of the dark material, Icarus, 216, 347-358, 2011
[5] V. Chevrier, T.S. Altheide, Low Temperature Aqueous Ferric Sulfate Solutions on the Surface of Mars,
Geophys. Res. Lett., 35(L22101), 2008
[6] V. Chevrier, T.S. Altheide, J. Hanley, Stability of perchlorate hydrates and their liquid solutions at the
Phoenix Landing site, Mars, Geophys. Res. Lett., 36(L10202), 2009
[7] R. Ulrich, T. Kral, V. Chevrier, R. Pilgrim, L.A. Roe, Dynamic temperature fields under the Mars landing
sites and implications for supporting microbial life Astrobiology, 10(6), 643-650, 2010
[8] Scientific Frontline [Online] http://www.sflorg.com/mars_missions/mro12_2008/mro122008_05_01,
Credit NASA/JPL/University of Arizona, Source University of Arizona, 2008
[9] A. Kereszturi, E.G. Rivera-Valentin, Locations of thin liquid water layers on present-day Mars, In press.
Icarus, doi: 10.1016/j.icarus.2012.08.004, 2012
[10] J.E. Bartolomei, T. Miller, Functional Analysis System Technique (F.A.S.T.) as a Group Knowledge
Elicitation Method for Model Building, 2001
[11] C.M. Bethke, The Geochemist’s Workbench Release 6.0 Reference Manual, Remote Control, 2006
[12] M. Nic, J. Jirat, B. Kosata, molality, [Online ed.] IUPAC Compendium of Chemical Terminology, 2006,
doi:10.1351/goldbook.M03970, ISBN 0-9678550-9-8
Internship report: architecture development for simultaneous multiple numerical codes
M2 OSAE 2012 35
APPENDICES
Internship report: architecture development for simultaneous multiple numerical codes
M2 OSAE 2012 36
APPENDIX N°1: CONTRACTING OWNER AND PROJECT MANAGEMENT
The different actors of the project “architecture development for simultaneous multiple numerical
codes” are enumerated here, and belong either with the SPAC of the University of Arkansas or the M2 OSAE
of the Observatory of Paris.
Contractor: SPAC, University of Arkansas
Supervisor: Vincent F. Chevrier
Coordinator: Edgard G. Rivera-Valentin
Developer: Robin Lenogue
APPENDIX N°2: GLOSSARY
- SPAC: acronym for Arkansas Center for Space and Planetary Science of the University of
Arkansas at Fayetteville.
- Project: term referring to the project “architecture development for simultaneous multiple
numerical codes”.
- V model: diagram of a software development process.
- Matlab: acronym of matrix laboratory, a high-level technical computing language and an
interactive programming environment for algorithm development, data analysis, visualization,
and numerical computation.
- GWB: acronym of the Geochemist's Workbench, geochemical software used for aqueous
chemistry modeling.
- FREZCHEM: acronym of FREeZing CHEMistry, a numerical code used for modeling geochemistry
at extremely cold temperatures.
- FAST: acronym of Functional Analysis System Technique, a rigorous method for understanding
complex systems by transforming the product services functions into technical functions.
- Flowchart: diagram representing an algorithm or process through a sequence of operations
shown as boxes and arrows of various kinds.
- RC_helper: acronym of Remote Control helper, a routine that defines a pipe with the software
GWB. Its framework basically makes the pipe work like a buffer. When a GWB application is
called with the “–pipe” option, this application opens the buffer and waits for anything to be
written to it. When something (a command) is sent in the pipe with the method
“SendCommand”, the GWB application reads and executes it. GWB then prints the results of the
command back to the buffer and adds a token saying it is <ready>. When the SendCommand
sees the <ready> token, it returns the GWB application output that was written to the pipe.
- Scope statement: document presenting, in a contracting form, what is expected from a given
project or assignment. The scope statement details the project deliverables and describes the
major objectives of this work.
- EOL: end-of-line character, qualified by a carriage return.
Internship report: architecture development for simultaneous multiple numerical codes
M2 OSAE 2012 37
APPENDIX N°3: PIPE HOST ROUTINE – MATLAB PROGRAM
%{ This program masters a C++_controlled pipe with GWB. Author: Robin Lenogue ([email protected]) Date: 05/13/12 Updated: 08/11/12 by Robin Lenogue %}
clear all close all clc tic
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Input initialization %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
pipePg = 'C:\Users\Robin\Documents\pipe_GWB8\Debug\pipe_GWB8.exe'; % string, e.g. 'pipe_GWB.exe' database = 'C:\Users\Robin\Desktop\thermo_phrqpitz_v8_Vincent_LowT-120minerals-07-19-2011.dat'; script = 'C:\Users\Robin\Desktop\script_test.txt'; % The script should not contain GO at its end, for a faster simulation. It must end with EOL tough.
% Getting MatLab current directory to use it as working directory [~, currdir] = system('cd'); % e.g. "C:\Users\Robin\Documents\MATLAB " workDir = (currdir(1:end-1)); % e.g. "C:\Users\Robin\Documents\MATLAB"
temp_initial = 7; % Temperature in Celsius temp_final = 10.9; % Temperature in Celsius water_mass_total = 1; % mass [in kg] of Free water delta_water_mass = 999.999; %999.999; % mass [in gram] of water to react delxi = .001; % Precision of GWB's calculation step, will later decrease if > than |delta_water_mass|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Cutting the simulation in 10 parts %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Array synthesis Water_mass = zeros(1, 100); % Initial settings Water_mass(1) = 1; %[kg] rate = 100; % [g per loop] swtch = 0; i = 1;
while swtch == 0 i = i+1; Water_mass(i) = Water_mass(i-1) - (rate / 1000); % [kg]
if Water_mass(i-1) <= 0 swtch = 1; else iteration = (i-2); % NEEDS TO start at 0 water_mass_total = Water_mass(i-1); % mass [in kg] of Free water delta_water_mass = rate; % mass [in gram] of H2O to react if delxi > delta_water_mass; % delxi (initialized .001) will decrease if > than |ΔWaterMass| while delta_water_mass < delxi; delxi = delxi/10; fprintf('delxi = %d\n', delxi); end end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Code calling GWB and outputting Data %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
fprintf(' Iteration %i\n\t%s = %.2f -> %.2f\n\t%s = %d\n\t%s = %d\n\t%s = %d\n\tCOMUNICATION
WITH GWB...', iteration, 'temperature', temp_initial, temp_final, 'water_mass_total(kg)',
water_mass_total, 'delta_water_mass(g)', delta_water_mass, 'delxi', delxi); % NOTE: if program is frozen, try last script ("tmpScriptChanges.dat") directly in GWB lineSystem = ([pipePg,' ',workDir,' ',database,' ',script,' ',num2str(temp_initial),'
',num2str(temp_final),' ',num2str(water_mass_total),' ',num2str(delta_water_mass),'
',num2str(delxi),' ',num2str(iteration)]); [status output] = system(lineSystem); if status ~= 0; fprintf('...output: \n%s \n\nSystem process did not return 0, check pipe program! \n',
output(1:end-1)); % Display the output, with Warnings or Errors may them happen
Internship report: architecture development for simultaneous multiple numerical codes
M2 OSAE 2012 38
swtch = 1; % switch to leave the while loop elseif length (output) > 13; % Actual max length of an numbered output fprintf('...output: \n%s \n\nOutput is unusual, check pipe program! \n', output(1:end-
1)); % “output” without the last carriage return swtch = 1; % switch to leave the while loop else fprintf('...\toutput = %s \n', output(1:end-1)); end end end
% str2double(output) % work on this output for the loop to be useful
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Clean cd from tmp files (optional) %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % lineSystem = (['del ',workDir,'\tmpScriptChanges.dat']); % [~, ~] = system(lineSystem); % Delete the tmp Matlab file that come from the c++ pipe program % lineSystem = (['del ',workDir,'\tmpScriptChanges_Gwb.dat']); % [~, ~] = system(lineSystem); % Delete the tmp Gwb files that come from the c++ pipe program % lineSystem = (['del ',workDir,'\React_output.txt']); % [~, ~] = system(lineSystem); % Delete the Gwb tmp output that come from Gwb % lineSystem = (['del ',workDir,'\React_plot.gtp']); % [~, ~] = system(lineSystem); % Delete the Gwb tmp plot output that come from Gwb
toc
Internship report: architecture development for simultaneous multiple numerical codes
M2 OSAE 2012 39
APPENDIX N°4: MAIN FUNCTION OF THE PROGRAM PIPE_GWB8.EXE AT THE PHASE OF FINAL SCOPE
STATEMENT
// pipe_GWB8.cpp //===================================================================================== // This program works as a pipe communicating with Geochemist's Workbench, release 8.0 // It can be controlled and run by an external software such as Matlab. // Author: Robin Lenogue ([email protected]) // Date: 08/09/12 //===================================================================================== #include <iostream> #include <fstream> #include "RC_helper.h" #include "filing.h" int main(int argc, char *argv[]){ if (argc != 10) { // argc should be 10 for correct execution std::cout << "\n\tusage: " << argv[0] << " <WorkingDirectory> <database> <script> <temp_initial [C]> <temp_final [C]> <free_water [kg]> <water_mass to react [g]> <delxi> <iteration [starting at 0]> \n" << "\t*** END OF PROCESS ***\n\n"; // argv[0] should be the program name return 1; // Stop program until arguments are in required number } // Parameters char line[250]; // Used to report every needed output or edit needed parameters double result; // Used to report every needed result and use them char outputFilePath[250]; sprintf(outputFilePath, "%s\\Output_pipe_GWB.txt", argv[1]); // Building the output file location, for 200-max-size argv[3], e.g. "C:\Users\Robin\Documents\pipe_GWB9\Debug" char scriptPath[201]; sprintf(scriptPath, "%s", argv[3]); // e.g. "C:\Users\Robin\Desktop\script.txt" for 200-max-size argv[3] char scriptChangesPath[250]; sprintf(scriptChangesPath, "%s\\tmpScriptChanges.dat", argv[1]); // Building the scriptChanges file location char scriptChanges_GwbPath[250]; sprintf(scriptChanges_GwbPath, "%s\\tmpScriptChanges_Gwb.dat", argv[1]); // Building the scriptChanges_Gwb file location char react_output_Path[250]; sprintf(react_output_Path, "%s\\React_output.txt", argv[1]); // Building GWB's React_output file location char react_output_ALL_Path[250]; sprintf(react_output_ALL_Path, "%s\\React_output_ALL.txt", argv[1]); // Building the React_output_ALL file location Pipe pipe("pipe"); // we use named pipes // Setting up output file File output(outputFilePath); if (!output.writeCurrentIteration(argv[9])) { output.sendErrorOpeningOutputFile("file cannot be opened for writing purpose"); return 1; // Stop program before upcoming fatal errors } // Checking the EOL ending of original script file File script(scriptPath); if (script.noEOL(output, argv[1])==1) // 1: ERROR, 2: NoEOL, 0: endsWithEOL return 1; // Stop program if errors while checking for EOL else if (script.noEOL(output, argv[1])==2) { // The script file needs to end with EOL script.addEOL(); output.sendWarning(script, "file must end with an empty line, it has been added"); } //else 0: endsWithEOL // Building current script as independent .dat file, out of initial script file AND external modifications (arguments of this program) File scriptChange(scriptChangesPath); if (!script.copyTo(scriptChange)) { // Copying the content of script.txt to scriptChanges.dat output.sendErrorCopying(script, scriptChange, argv[1]); return 1; // Stop program if error while copying (scriptChange: file directly sent to GWB) } scriptChange.add(argv[4], argv[5], argv[6], argv[7], argv[8]); // Adding the external modifications // ***GWB SIMULATION*** // Opening React and setting up its current working directory and Thermo Database OpenGwbApplic(pipe, "\\Program Files (x86)\\Gwb\\React.exe"); // Opening the pipe sprintf_s(line, "cd %s", argv[1]); // e.g. "cd C:\Users\Robin\Documents\pipe_GWB8\Debug" SendCommand(pipe, line); // Taking control of current working directory to save React_output.txt directly in it sprintf_s(line, "data \"%s\"", argv[2]); // Database SendCommand(pipe, line); // GWB will ask for another file if pb
Internship report: architecture development for simultaneous multiple numerical codes
M2 OSAE 2012 40
// Sending and saving script along with its modifications (AFTER THE FIRST ITERATION => changes from last GWB simulation need to be applied) File scriptChange_Gwb(scriptChanges_GwbPath); // Possible updates from GWB's previous iteration if (argv[9][0] != '0') { // IF, and only IF "iteration" parameter is NOT "0" if (!scriptChange_Gwb.copyAppTo(scriptChange)) { // scriptChanges_GwbPath will exist after the 1st iteration output.sendErrorCopying(scriptChange_Gwb, scriptChange, argv[1]); return 1; // Stop program if error while copying } } std::ofstream scriptChanges; scriptChanges.open(scriptChangesPath, std::ios::app); // Opening the scriptChanges file & setting the initial position at its end scriptChanges << "go" << std::endl << std::endl; std::ofstream outputFile; outputFile.open(outputFilePath, std::ios::app); // Opening the output file in writing mode & setting the initial position at its end if (!scriptChange.copyAppTo(output)) output.sendWarningCopying(scriptChange, output); // If problem while copying sprintf_s(line, "read %s", scriptChangesPath); int size = 276447232; // Max size for the pointer outputting the long GWB output // Set by the IDE char *outputGwb=new char[size]; // Used to report the long GWB output SendCommand(pipe, line, outputGwb, size); // Sending the sciptChanges file and starts the simulation outputFile << outputGwb << std::endl << std::endl; // Saving in output file the possible GWB pbs delete [] outputGwb; // Saving next script modifications coming from GWB as independent .dat file (used for next iteration if there is one) std::ofstream scriptChanges_Gwb(scriptChanges_GwbPath); // Opening\emptying the scriptChanges_Gwb file if (!scriptChanges_Gwb) { // If stream cannot be openend output.sendErrorOpeningStream(scriptChange_Gwb, "writing", argv[1]); return 1; // scriptChange: file directly sent to GWB } sprintf_s(line, "report molality Cl-"); SendCommand(pipe, line, line, sizeof(line)); if (sscanf(line, "%lg", &result)) scriptChanges_Gwb << result << " mol/kg Cl-" << std::endl; // If valid, the data outputted is saved in the scriptChanges file sprintf_s(line, "report molality HCO3-"); SendCommand(pipe, line, line, sizeof(line)); if (sscanf(line, "%lg", &result)) scriptChanges_Gwb << result << " mol/kg HCO3-" << std::endl; sprintf_s(line, "report molality ClO4-"); SendCommand(pipe, line, line, sizeof(line)); if (sscanf(line, "%lg", &result)) scriptChanges_Gwb << result << " mol/kg ClO4-" << std::endl; sprintf_s(line, "report molality ClO3-"); SendCommand(pipe, line, line, sizeof(line)); if (sscanf(line, "%lg", &result)) scriptChanges_Gwb << result << " mol/kg ClO3-" << std::endl; sprintf_s(line, "report molality NO3-"); SendCommand(pipe, line, line, sizeof(line)); if (sscanf(line, "%lg", &result)) scriptChanges_Gwb << result << " mol/kg NO3-" << std::endl; sprintf_s(line, "report molality SO4--"); SendCommand(pipe, line, line, sizeof(line)); if (sscanf(line, "%lg", &result)) scriptChanges_Gwb << result << " mol/kg SO4--" << std::endl; sprintf_s(line, "report molality Br-"); SendCommand(pipe, line, line, sizeof(line)); if (sscanf(line, "%lg", &result)) scriptChanges_Gwb << result << " mol/kg Br-" << std::endl; sprintf_s(line, "report molality F-"); SendCommand(pipe, line, line, sizeof(line)); if (sscanf(line, "%lg", &result)) scriptChanges_Gwb << result << " mol/kg F-" << std::endl; sprintf_s(line, "report molality H+"); SendCommand(pipe, line, line, sizeof(line)); if (sscanf(line, "%lg", &result)) scriptChanges_Gwb << result << " mol/kg H+" << std::endl; sprintf_s(line, "report molality Li+"); SendCommand(pipe, line, line, sizeof(line)); if (sscanf(line, "%lg", &result)) scriptChanges_Gwb << result << " mol/kg Li+" << std::endl; sprintf_s(line, "report molality Na+"); SendCommand(pipe, line, line, sizeof(line)); if (sscanf(line, "%lg", &result)) scriptChanges_Gwb << result << " mol/kg Na+" << std::endl; sprintf_s(line, "report molality K+"); SendCommand(pipe, line, line, sizeof(line)); if (sscanf(line, "%lg", &result)) scriptChanges_Gwb << result << " mol/kg K+" << std::endl; sprintf_s(line, "report molality Ca++"); SendCommand(pipe, line, line, sizeof(line)); if (sscanf(line, "%lg", &result)) scriptChanges_Gwb << result << " mol/kg Ca++" << std::endl; sprintf_s(line, "report molality Sr++"); SendCommand(pipe, line, line, sizeof(line)); if (sscanf(line, "%lg", &result)) scriptChanges_Gwb << result << " mol/kg Sr++" << std::endl; sprintf_s(line, "report molality Ba++"); SendCommand(pipe, line, line, sizeof(line)); if (sscanf(line, "%lg", &result)) scriptChanges_Gwb << result << " mol/kg Ba++" << std::endl; sprintf_s(line, "report molality Mg++"); SendCommand(pipe, line, line, sizeof(line)); if (sscanf(line, "%lg", &result)) scriptChanges_Gwb << result << " mol/kg Mg++" << std::endl; sprintf_s(line, "report molality Fe++"); SendCommand(pipe, line, line, sizeof(line)); if (sscanf(line, "%lg", &result)) scriptChanges_Gwb << result << " mol/kg Fe++" << std::endl; sprintf_s(line, "report molality Mn++"); SendCommand(pipe, line, line, sizeof(line)); if (sscanf(line, "%lg", &result)) scriptChanges_Gwb << result << " mol/kg Mn++" << std::endl; sprintf_s(line, "report molality Al+++"); SendCommand(pipe, line, line, sizeof(line)); if (sscanf(line, "%lg", &result)) scriptChanges_Gwb << result << " mol/kg Al+++" << std::endl; sprintf_s(line, "report molality Fe+++"); SendCommand(pipe, line, line, sizeof(line)); if (sscanf(line, "%lg", &result)) scriptChanges_Gwb << result << " mol/kg Fe+++" << std::endl;
Internship report: architecture development for simultaneous multiple numerical codes
M2 OSAE 2012 41
sprintf_s(line, "report molality B(OH)3"); SendCommand(pipe, line, line, sizeof(line)); if (sscanf(line, "%lg", &result)) scriptChanges_Gwb << result << " mol/kg B(OH)3" << std::endl; sprintf_s(line, "report molality SiO2(aq)"); SendCommand(pipe, line, line, sizeof(line)); if (sscanf(line, "%lg", &result)) scriptChanges_Gwb << result << " mol/kg SiO2(aq)" << std::endl; sprintf_s(line, "report molality O2(aq)"); SendCommand(pipe, line, line, sizeof(line)); if (sscanf(line, "%lg", &result)) scriptChanges_Gwb << result << " mol/kg O2(aq)" << std::endl; // Printing out requested output and saving it in output file sprintf_s(line, "report watact"); SendCommand(pipe, line, line, sizeof(line)); if (!sscanf(line, "%lg", &result)) { output.sendError(line, argv[1]); return 1; // Stop program if problem while outputting watact } std::cout << result << std::endl; // Printing out the result, an external will be able to reach it outputFile << "\t--- Data outputted " << argv[9] << " ---" << std::endl // Saved in the output file << "\treport watact: " << result << std::endl << std::endl << std::endl << "****************************" << std::endl; // End of the interesting info printed out in output file // Saving chemical output from React (txt file with complete data) File react_output_ALL(react_output_ALL_Path); if (!react_output.copyAppTo(react_output_ALL)) // Copying the content of React_output.txt at the end of React_output_ALL.txt output.sendWarningCopying(react_output, react_output_ALL); // The react software is closed - End of program SendCommand(pipe, "cd ~"); // Resetting the working directory to default SendCommand(pipe, "quit"); // Quiting GWB //sprintf(line,"del %s\\React_output.txt",argv[1]); system(line); // Deleting the remaining React_output.txt //sprintf(line,"del %s\\React_plot.gtp",argv[1]); system(line); // Deleting the remaining React_plot.gtp //sprintf(line,"del %s",scriptChangesPath); system(line); // Deleting the “temporary” file tmpScriptChanges.txt //sprintf(line,"del %s",scriptChanges_GwbPath); system(line); // Deleting the “temporary” file tmpScriptChanges_Gwb.txt return 0; }
Internship report: architecture development for simultaneous multiple numerical codes
M2 OSAE 2012 42
APPENDIX N°5: MAIN FUNCTION OF THE PROGRAM PIPE_GWB9.EXE AT THE PHASE OF FINAL SCOPE
STATEMENT
// pipe_GWB9.cpp //=========================================================================================== // This program works as an unnamed pipe communicating with Geochemist's Workbench, release 9.0 // It can be controlled and run by an external software such as Matlab. // Author: Robin Lenogue ([email protected]) // Date: 08/09/12 //=========================================================================================== #include <iostream> #include <fstream> #include "RC_helper.h" #include "filing.h" int main(int argc, char *argv[]){ if (argc != 10) { // argc should be 10 for correct execution std::cout << "\n\tusage: " << argv[0] << " <WorkingDirectory> <database> <script> <temp_initial [C]> <temp_final [C]> <free_water [kg]> <water_mass to react [g]> <delxi> <iteration [starting at 0]> \n" << "\t*** END OF PROCESS ***\n\n"; // argv[0] should be the program name return 1; // Stop program until arguments are in required number } // Parameters char line[250]; // Used to report every needed output or edit needed parameters double result; // Used to report every needed result and use them char outputFilePath[250]; sprintf(outputFilePath, "%s\\Output_pipe_GWB.txt", argv[1]); // Building the output file location, for 200-max-size argv[3], e.g. "C:\Users\Robin\Documents\pipe_GWB9\Debug" char scriptPath[200]; sprintf(scriptPath, "%s", argv[3]); // e.g. "C:\Users\Robin\Desktop\script.txt" for 200-max-size argv[3] char scriptChangesPath[250]; sprintf(scriptChangesPath, "%s\\tmpScriptChanges.dat", argv[1]); // Building the scriptChanges file location char scriptChanges_GwbPath[250]; sprintf(scriptChanges_GwbPath, "%s\\tmpScriptChanges_Gwb.dat", argv[1]); // Building the scriptChanges_Gwb file location char react_output_Path[250]; sprintf(react_output_Path, "%s\\React_output.txt", argv[1]); // Building GWB's React_output file location char react_output_ALL_Path[250]; sprintf(react_output_ALL_Path, "%s\\React_output_ALL.txt", argv[1]); // Building the React_output_ALL file location // Setting up output file File output(outputFilePath); if (!output.writeCurrentIteration(argv[9])) { output.sendErrorOpeningOutputFile("file cannot be opened for writing purpose"); return 1; // Stop program before upcoming fatal errors } // Checking the EOL ending of script file File script(scriptPath); if (script.noEOL(output, argv[1])==1) // 1: ERROR, 2: NoEOL, 0: endsWithEOL return 1; // Stop program if errors while checking for EOL else if (script.noEOL(output, argv[1])==2) { // The script file needs to end with EOL script.addEOL(); output.sendWarning(script, "file must end with an empty line, it has been added"); // Warning } //else 0: endsWithEOL // Building current script as independent .dat file, out of initial script file AND external modifications File scriptChange(scriptChangesPath); if (!script.copyTo(scriptChange)) { // Copying the content of script.txt to scriptChanges.dat output.sendErrorCopying(script, scriptChange, argv[1]); return 1; // Stop program if error while copying (scriptChange: file directly sent to GWB) } scriptChange.add(argv[4], argv[5], argv[6], argv[7], argv[8]); // Adding the external modifications // ***GWB SIMULATION*** // Opening React and setting up its current working directory and Thermo Database OpenGwbApplic("\\Program Files (x86)\\Gwb9\\gwb.exe react"); // Opening the pipe sprintf_s(line, "cd %s", argv[1]); // e.g. "cd C:\Users\Robin\Documents\pipe_GWB8\Debug" SendCommand(line); // Taking control of current working directory to save React_output.txt in it sprintf_s(line, "data \"%s\"", argv[2]); SendCommand(line, line, sizeof(line)); // Setting the thermo database as wanted char errorLine[10]; sprintf(errorLine, "Error"); // Error in Gwb if (strncmp(line,errorLine,4) == 0) { // A zero value indicates that the characters compared in both strings are all equal output.sendError(line, argv[1]); // If required database isn't valid return 1; // Stop program if error in setting the required Database }
Internship report: architecture development for simultaneous multiple numerical codes
M2 OSAE 2012 43
// Sending script along with the modifications (AFTER THE FIRST iteration => changes from last GWB simulation need to be applied) File scriptChange_Gwb(scriptChanges_GwbPath); // Possible updates from GWB's previous iteration if (argv[9][0] != '0') { // IF, and only IF "iteration" parameter is NOT "0" if (!scriptChange_Gwb.copyAppTo(scriptChange)) { // Copying the content of scriptChanges_Gwb.dat at the end of scriptChanges.dat (the Gwb one will exist after the 1st iteration) output.sendErrorCopying(scriptChange_Gwb, scriptChange, argv[1]); return 1; // Stop program if error while copying } } std::ofstream scriptChanges; scriptChanges.open(scriptChangesPath, std::ios::app); // Opening the scriptChanges file & setting the initial position at its end scriptChanges << "go" << std::endl; sprintf_s(line, "read %s", scriptChangesPath); int size = 276447232; // Max size for the pointer outputting the long GWB output // Set by the IDE char *outputGwb=new char[size]; // Used to report the long GWB output SendCommand(line, outputGwb, size); // Sending the sciptChanges file and starts the simulation // Saving current script read by GWB in output file std::ofstream outputFile; outputFile.open(outputFilePath, std::ios::app); // Opening the output file in writing mode & setting the initial position at its end outputFile << outputGwb << std::endl << std::endl; delete [] outputGwb; // Saving next script modifications coming from GWB as independent .dat file (used for next iteration if there is one) std::ofstream scriptChanges_Gwb(scriptChanges_GwbPath); // Opening\emptying the scriptChanges_Gwb file if (!scriptChanges_Gwb) { output.sendErrorOpeningStream(scriptChange_Gwb, "writing", argv[1]); return 1; // Stop program if error while writing in the scriptChange file } sprintf_s(line, "report molality Cl-"); SendCommand(line, line, sizeof(line)); if (sscanf(line, "%lg", &result)) scriptChanges_Gwb << result << " mol/kg Cl-" << std::endl; sprintf_s(line, "report molality HCO3-"); SendCommand(line, line, sizeof(line)); if (sscanf(line, "%lg", &result)) scriptChanges_Gwb << result << " mol/kg HCO3-" << std::endl; sprintf_s(line, "report molality ClO4-"); SendCommand(line, line, sizeof(line)); if (sscanf(line, "%lg", &result)) scriptChanges_Gwb << result << " mol/kg ClO4-" << std::endl; sprintf_s(line, "report molality ClO3-"); SendCommand(line, line, sizeof(line)); if (sscanf(line, "%lg", &result)) scriptChanges_Gwb << result << " mol/kg ClO3-" << std::endl; sprintf_s(line, "report molality NO3-"); SendCommand(line, line, sizeof(line)); if (sscanf(line, "%lg", &result)) scriptChanges_Gwb << result << " mol/kg NO3-" << std::endl; sprintf_s(line, "report molality SO4--"); SendCommand(line, line, sizeof(line)); if (sscanf(line, "%lg", &result)) scriptChanges_Gwb << result << " mol/kg SO4--" << std::endl; sprintf_s(line, "report molality Br-"); SendCommand(line, line, sizeof(line)); if (sscanf(line, "%lg", &result)) scriptChanges_Gwb << result << " mol/kg Br-" << std::endl; sprintf_s(line, "report molality F-"); SendCommand(line, line, sizeof(line)); if (sscanf(line, "%lg", &result)) scriptChanges_Gwb << result << " mol/kg F-" << std::endl; sprintf_s(line, "report molality H+"); SendCommand(line, line, sizeof(line)); if (sscanf(line, "%lg", &result)) scriptChanges_Gwb << result << " mol/kg H+" << std::endl; sprintf_s(line, "report molality Li+"); SendCommand(line, line, sizeof(line)); if (sscanf(line, "%lg", &result)) scriptChanges_Gwb << result << " mol/kg Li+" << std::endl; sprintf_s(line, "report molality Na+"); SendCommand(line, line, sizeof(line)); if (sscanf(line, "%lg", &result)) scriptChanges_Gwb << result << " mol/kg Na+" << std::endl; sprintf_s(line, "report molality K+"); SendCommand(line, line, sizeof(line)); if (sscanf(line, "%lg", &result)) scriptChanges_Gwb << result << " mol/kg K+" << std::endl; sprintf_s(line, "report molality Ca++"); SendCommand(line, line, sizeof(line)); if (sscanf(line, "%lg", &result)) scriptChanges_Gwb << result << " mol/kg Ca++" << std::endl; sprintf_s(line, "report molality Sr++"); SendCommand(line, line, sizeof(line)); if (sscanf(line, "%lg", &result)) scriptChanges_Gwb << result << " mol/kg Sr++" << std::endl; sprintf_s(line, "report molality Ba++"); SendCommand(line, line, sizeof(line)); if (sscanf(line, "%lg", &result)) scriptChanges_Gwb << result << " mol/kg Ba++" << std::endl; sprintf_s(line, "report molality Mg++"); SendCommand(line, line, sizeof(line)); if (sscanf(line, "%lg", &result)) scriptChanges_Gwb << result << " mol/kg Mg++" << std::endl; sprintf_s(line, "report molality Fe++"); SendCommand(line, line, sizeof(line)); if (sscanf(line, "%lg", &result)) scriptChanges_Gwb << result << " mol/kg Fe++" << std::endl; sprintf_s(line, "report molality Mn++"); SendCommand(line, line, sizeof(line)); if (sscanf(line, "%lg", &result)) scriptChanges_Gwb << result << " mol/kg Mn++" << std::endl; sprintf_s(line, "report molality Al+++"); SendCommand(line, line, sizeof(line)); if (sscanf(line, "%lg", &result)) scriptChanges_Gwb << result << " mol/kg Al+++" << std::endl; sprintf_s(line, "report molality Fe+++"); SendCommand(line, line, sizeof(line)); if (sscanf(line, "%lg", &result)) scriptChanges_Gwb << result << " mol/kg Fe+++" << std::endl; sprintf_s(line, "report molality B(OH)3"); SendCommand(line, line, sizeof(line)); if (sscanf(line, "%lg", &result)) scriptChanges_Gwb << result << " mol/kg B(OH)3" << std::endl;
Internship report: architecture development for simultaneous multiple numerical codes
M2 OSAE 2012 44
sprintf_s(line, "report molality SiO2(aq)"); SendCommand(line, line, sizeof(line)); if (sscanf(line, "%lg", &result)) scriptChanges_Gwb << result << " mol/kg SiO2(aq)" << std::endl; sprintf_s(line, "report molality O2(aq)"); SendCommand(line, line, sizeof(line)); if (sscanf(line, "%lg", &result)) scriptChanges_Gwb << result << " mol/kg O2(aq)" << std::endl; // Printing out requested output and saving it in output file sprintf_s(line, "report watact"); SendCommand(line, line, sizeof(line)); if (!sscanf(line, "%lg", &result)) { output.sendError(line, argv[1]); // If problem while outputting watact return 1; // Stop program if problem while outputting watact } std::cout << result << std::endl; // Printing out the result, an external will be able to reach it outputFile << "\t--- Data outputted " << argv[9] << "---" << std::endl // Saved in the output file << "\treport watact: " << result << std::endl << std::endl << std::endl << "****************************" << std::endl; // End of the interesting info printed out in output file // Saving chemical output from React (txt file with complete data) File react_output_ALL(react_output_ALL_Path); if (!react_output.copyAppTo(react_output_ALL)) // Copying the content of React_output.txt at the end of React_output_ALL.txt output.sendWarningCopying(react_output, react_output_ALL); // The react software is closed - End of program SendCommand("cd ~"); // Resetting the working directory to default SendCommand("quit"); // Quiting GWB //sprintf(line,"del %s\\React_output.txt",argv[1]); system(line); // Deleting the remaining React_output.txt //sprintf(line,"del %s\\React_plot.gtp",argv[1]); system(line); // Deleting the remaining React_plot.gtp //sprintf(line,"del %s",scriptChangesPath); system(line); // Deleting the temporary file tmpScriptChanges.txt //sprintf(line,"del %s",scriptChanges_GwbPath); system(line); // Deleting the temporary file tmpScriptChanges_Gwb.txt return 0; }
Internship report: architecture development for simultaneous multiple numerical codes
M2 OSAE 2012 45
APPENDIX N°6: MAIN FUNCTION OF THE FINAL PROGRAM PIPE_GWB8.EXE – WITHOUT COMMENTS
#include <iostream> #include <fstream> #include "RC_helper.h" #include "filing.h" int main(int argc, char *argv[]){ if (argc != 10) { std::cout << "\n\tusage: " << argv[0] << " <WorkingDirectory> <database> <script> <temp_initial [C]> <temp_final [C]> <free_water [kg]> <water_mass to react [g]> <delxi> <iteration [starting at 0]> \n" << "\t*** END OF PROCESS ***\n\n"; return 1; } // Parameters char line[250]; double result; char outputFilePath[250]; sprintf(outputFilePath, "%s\\Output_pipe_GWB.txt", argv[1]); char scriptPath[201]; sprintf(scriptPath, "%s", argv[3]); char scriptChangesPath[250]; sprintf(scriptChangesPath, "%s\\tmpScriptChanges.dat", argv[1]); char scriptChanges_GwbPath[250]; sprintf(scriptChanges_GwbPath, "%s\\tmpScriptChanges_Gwb.dat", argv[1]); char react_output_Path[250]; sprintf(react_output_Path, "%s\\React_output.txt", argv[1]); char react_output_ALL_Path[250]; sprintf(react_output_ALL_Path, "%s\\React_output_ALL.txt", argv[1]); Pipe pipe("pipe"); // Setting up output file File output(outputFilePath); if (!output.writeCurrentIteration(argv[9])) { output.sendErrorOpeningOutputFile("file cannot be opened for writing purpose"); return 1; } // Checking the EOL ending of original script file File script(scriptPath); if (script.noEOL(output, argv[1])==1) // 1: ERROR, 2: NoEOL, 0: endsWithEOL return 1; else if (script.noEOL(output, argv[1])==2) { script.addEOL(); output.sendWarning(script, "file must end with an empty line, it has been added"); } // Building current script as independent .dat file, out of initial script file AND external modifications (arguments of this program) File scriptChange(scriptChangesPath); if (!script.copyTo(scriptChange)) { output.sendErrorCopying(script, scriptChange, argv[1]); return 1; } scriptChange.add(argv[4], argv[5], argv[6], argv[7], argv[8]); // ***GWB SIMULATION*** // Opening React and setting up its current working directory and Thermo Database OpenGwbApplic(pipe, "\\Program Files (x86)\\Gwb\\React.exe"); sprintf_s(line, "cd %s", argv[1]); SendCommand(pipe, line); sprintf_s(line, "data \"%s\"", argv[2]); SendCommand(pipe, line); // Sending and saving script along with its modifications (AFTER THE FIRST ITERATION => changes from last GWB simulation need to be applied) File scriptChange_Gwb(scriptChanges_GwbPath); if (argv[9][0] != '0') { if (!scriptChange_Gwb.copyAppTo(scriptChange)) { output.sendErrorCopying(scriptChange_Gwb, scriptChange, argv[1]); return 1; } } std::ofstream scriptChanges; scriptChanges.open(scriptChangesPath, std::ios::app); scriptChanges << "go" << std::endl << std::endl; std::ofstream outputFile; outputFile.open(outputFilePath, std::ios::app); if (!scriptChange.copyAppTo(output)) output.sendWarningCopying(scriptChange, output);
Internship report: architecture development for simultaneous multiple numerical codes
M2 OSAE 2012 46
sprintf_s(line, "read %s", scriptChangesPath); int size = 276447232; char *outputGwb=new char[size]; SendCommand(pipe, line, outputGwb, size); outputFile << outputGwb << std::endl << std::endl; delete [] outputGwb; // Saving next script modifications coming from GWB as independent .dat file (used for next iteration) std::ofstream scriptChanges_Gwb(scriptChanges_GwbPath); if (!scriptChanges_Gwb) { output.sendErrorOpeningStream(scriptChange_Gwb, "writing", argv[1]); return 1; } sprintf_s(line, "report molality Cl-"); SendCommand(pipe, line, line, sizeof(line)); if (sscanf(line, "%lg", &result)) scriptChanges_Gwb << result << " mol/kg Cl-" << std::endl; sprintf_s(line, "report molality HCO3-"); SendCommand(pipe, line, line, sizeof(line)); if (sscanf(line, "%lg", &result)) scriptChanges_Gwb << result << " mol/kg HCO3-" << std::endl; sprintf_s(line, "report molality ClO4-"); SendCommand(pipe, line, line, sizeof(line)); if (sscanf(line, "%lg", &result)) scriptChanges_Gwb << result << " mol/kg ClO4-" << std::endl; sprintf_s(line, "report molality ClO3-"); SendCommand(pipe, line, line, sizeof(line)); if (sscanf(line, "%lg", &result)) scriptChanges_Gwb << result << " mol/kg ClO3-" << std::endl; sprintf_s(line, "report molality NO3-"); SendCommand(pipe, line, line, sizeof(line)); if (sscanf(line, "%lg", &result)) scriptChanges_Gwb << result << " mol/kg NO3-" << std::endl; sprintf_s(line, "report molality SO4--"); SendCommand(pipe, line, line, sizeof(line)); if (sscanf(line, "%lg", &result)) scriptChanges_Gwb << result << " mol/kg SO4--" << std::endl; sprintf_s(line, "report molality Br-"); SendCommand(pipe, line, line, sizeof(line)); if (sscanf(line, "%lg", &result)) scriptChanges_Gwb << result << " mol/kg Br-" << std::endl; sprintf_s(line, "report molality F-"); SendCommand(pipe, line, line, sizeof(line)); if (sscanf(line, "%lg", &result)) scriptChanges_Gwb << result << " mol/kg F-" << std::endl; sprintf_s(line, "report molality H+"); SendCommand(pipe, line, line, sizeof(line)); if (sscanf(line, "%lg", &result)) scriptChanges_Gwb << result << " mol/kg H+" << std::endl; sprintf_s(line, "report molality Li+"); SendCommand(pipe, line, line, sizeof(line)); if (sscanf(line, "%lg", &result)) scriptChanges_Gwb << result << " mol/kg Li+" << std::endl; sprintf_s(line, "report molality Na+"); SendCommand(pipe, line, line, sizeof(line)); if (sscanf(line, "%lg", &result)) scriptChanges_Gwb << result << " mol/kg Na+" << std::endl; sprintf_s(line, "report molality K+"); SendCommand(pipe, line, line, sizeof(line)); if (sscanf(line, "%lg", &result)) scriptChanges_Gwb << result << " mol/kg K+" << std::endl; sprintf_s(line, "report molality Ca++"); SendCommand(pipe, line, line, sizeof(line)); if (sscanf(line, "%lg", &result)) scriptChanges_Gwb << result << " mol/kg Ca++" << std::endl; sprintf_s(line, "report molality Sr++"); SendCommand(pipe, line, line, sizeof(line)); if (sscanf(line, "%lg", &result)) scriptChanges_Gwb << result << " mol/kg Sr++" << std::endl; sprintf_s(line, "report molality Ba++"); SendCommand(pipe, line, line, sizeof(line)); if (sscanf(line, "%lg", &result)) scriptChanges_Gwb << result << " mol/kg Ba++" << std::endl; sprintf_s(line, "report molality Mg++"); SendCommand(pipe, line, line, sizeof(line)); if (sscanf(line, "%lg", &result)) scriptChanges_Gwb << result << " mol/kg Mg++" << std::endl; sprintf_s(line, "report molality Fe++"); SendCommand(pipe, line, line, sizeof(line)); if (sscanf(line, "%lg", &result)) scriptChanges_Gwb << result << " mol/kg Fe++" << std::endl; sprintf_s(line, "report molality Mn++"); SendCommand(pipe, line, line, sizeof(line)); if (sscanf(line, "%lg", &result)) scriptChanges_Gwb << result << " mol/kg Mn++" << std::endl; sprintf_s(line, "report molality Al+++"); SendCommand(pipe, line, line, sizeof(line)); if (sscanf(line, "%lg", &result)) scriptChanges_Gwb << result << " mol/kg Al+++" << std::endl; sprintf_s(line, "report molality Fe+++"); SendCommand(pipe, line, line, sizeof(line)); if (sscanf(line, "%lg", &result)) scriptChanges_Gwb << result << " mol/kg Fe+++" << std::endl; sprintf_s(line, "report molality B(OH)3"); SendCommand(pipe, line, line, sizeof(line)); if (sscanf(line, "%lg", &result)) scriptChanges_Gwb << result << " mol/kg B(OH)3" << std::endl; sprintf_s(line, "report molality SiO2(aq)"); SendCommand(pipe, line, line, sizeof(line)); if (sscanf(line, "%lg", &result)) scriptChanges_Gwb << result << " mol/kg SiO2(aq)" << std::endl; sprintf_s(line, "report molality O2(aq)"); SendCommand(pipe, line, line, sizeof(line)); if (sscanf(line, "%lg", &result)) scriptChanges_Gwb << result << " mol/kg O2(aq)" << std::endl;
// Printing out requested output and saving it in output file sprintf_s(line, "report watact"); SendCommand(pipe, line, line, sizeof(line)); if (!sscanf(line, "%lg", &result)) { output.sendError(line, argv[1]); return 1; } std::cout << result << std::endl; outputFile << "\t--- Data outputted " << argv[9] << " ---" << std::endl << "\treport watact: " << result << std::endl << std::endl << std::endl << "****************************" << std::endl; // Saving chemical output from React (txt file with complete data) File react_output_ALL(react_output_ALL_Path); if (!react_output.copyAppTo(react_output_ALL)) output.sendWarningCopying(react_output, react_output_ALL); // The react software is closed - End of program SendCommand(pipe, "cd ~"); SendCommand(pipe, "quit"); return 0; }