@@ -11,7 +11,7 @@ defined in this [paper](https://zenodo.org/records/13838652).
1111- [ Building the project] ( #building-the-project )
1212- [ Using the CLI] ( #using-the-cli )
1313- [ Input files] ( #input-files )
14- - [ Dev container ] ( #dev-container )
14+ - [ Defining a new model ] ( #defining-a-new-model )
1515
1616## Project Structure
1717
@@ -25,6 +25,7 @@ The project is structured as follows:
2525 - ` dotmat-introspector/ ` : Console app to introspect the contents of a .mat file.
2626 - ` sacess/ ` : [ External proyect] ( https://bitbucket.org/DavidPenas/sacess-library ) adapted to enable the
2727 use of eSS in C.
28+ - ` mexpreval/ ` : Rust crate. Parses the model from the XML file to evaluate it.
2829- ` tests/ ` : Constains the tests of the cuqdyn-c library.
2930- ` CUQDyn/ ` : Contains the original Matlab project.
3031
@@ -47,28 +48,29 @@ When running this software, there is a chance of generating an inf or NaN value.
4748</ode_expr >
4849```
4950
50- If the value of ` p2 ` generated by the eSS solver is 0, the ODE will generate an inf value. To avoid this, when the
51- evaluation of the ODE generates an inf or NaN value, the software will set the value of the variable to 0. If you
52- want to change this behavior, you can set the value you want the variable to take when an inf or NaN value is
53- generated by setting the environment variable ` CUQDYN_DEF_YDOT ` to the value you want .
51+ If the value of ` p2 ` generated by the eSS solver is 0, the model eval produces an inf value. To avoid this, when the
52+ evaluation of the ODE generates a non finite value, the software will set the value of the variable to 0. If you
53+ want to change this behavior, you can set the value you want the variable to take when an invalid value is
54+ generated by setting the environment variable ` CUQDYN_DEF_YDOT ` to the desired value .
5455
5556### SACESS_SEED
5657
57- Set this variable if you want to set the seed used por the eSS solver instead of
58- picking a random one.
58+ Set this variable if you want to set the seed used by the eSS solver instead of
59+ generating a random one.
5960
6061## Building the project
6162
6263** GCC and GFortran v14 aren't supported by the project, so you need to use GCC v13 or lower.**
6364
64- The project has a ` build.sh ` .
65+ The project has a ` build.sh ` script .
6566` build-[variant]/ ` directories will be created, each one representing a variant
6667off the project they build. If you call the script without arguments, it will build
6768all the variants, but you can also specify the variant you want, passing it as the
6869first argument. The available variants are:
6970
7071- ` serial ` : Builds the project to only execute serial methods.
71- - ` mpi ` : Builds the project to execute parallel methods using MPI and OpenMP.
72+ - ` mpi ` : Builds the project to execute the sequential solver in parallel using MPI.
73+ - ` mpi2 ` : Builds the project to only include the MPI and OpenMP defined in sacess-library.
7274 After this, running ` test.sh ` is a good way to know if the cuqdyn library works as expected.
7375
7476## Using the CLI
@@ -138,15 +140,18 @@ There are three types of input files needed to run the cli:
138140 this [ link] ( https://bitbucket.org/DavidPenas/sacess-library/src/main/doc/manual/DOCUMENTATION_SACESS_SOFTWARE.pdf ) .
139141- ** cuqdyn config xml:**
140142 This file contains the configuration of the cuqdyn solver used in the cuqdyn-c library.
141- Right now, this file is just needed to define the rtol and atol used by the cvodes library.
143+ This file defines the rtol and atol used by the cvodes library inside the tolerances block
144+ and the ode model inside the ode_expr block. In the following example we define the Lotka Volterra model.
145+ There is an option to accelerate the process of evaluating the ODE by defining it inside the
146+ mevalexpr module. We will talk about this later.
142147 ``` xml
143148 <?xml version =" 1.0" encoding =" UTF-8" ?>
144149
145150 <cuqdyn-config >
146151 <tolerances >
147152 <rtol >1e-8</rtol >
148- <atol >1e-9, 1e-10</atol >
149- </tolerances >
153+ <atol >1e-9, 1e-10</atol >
154+ </tolerances >
150155 <ode_expr y_count =" 2" p_count =" 4" >
151156 y1 * (p1 - p2 * y2)
152157 -y2 * (p3 - p4 * y1)
@@ -168,10 +173,54 @@ There are three types of input files needed to run the cli:
168173 30 1e1 5e1
169174 ```
170175
171- ## Dev container
176+ ## Defining a new model
172177
173- There is a definition file for a singularity container + a ` dev_container.sh `
174- script that builds a dev container with all the dependencies needed to build
175- the project.
176- The container doesn't contain a valid python installation
177- to use the plot.py script, so this step should be done from the host.
178+ Using strings en evaluate them is slow compared to compiled instructions, so, to make this
179+ possible we designed a way to define the models in Rust and compile them to machine code.
180+
181+ Lets going to dig into it with an example of the Lotka Volterra model:
182+
183+ First of all, we need to write some Rust code. We will me using the following file
184+ ` modules/mexpreval/src/models.rs ` . Inside, we will create a new unit struct and implement
185+ the Model trait like this:
186+ ``` Rust
187+ #[derive(Default )]
188+ struct LotkaVolterra ;
189+
190+ impl Model for LotkaVolterra {
191+ fn eval (& self , _t : f64 , y : & [f64 ], ydot : & mut [f64 ], p : & [f64 ]) {
192+ ydot [0 ] = y [0 ] * (p [0 ] - p [1 ] * y [1 ]);
193+ ydot [1 ] = - y [1 ] * (p [2 ] - p [3 ] * y [0 ]);
194+ }
195+ }
196+ ```
197+
198+ Once the model is defined, we should give it an identifier:
199+ ``` Rust
200+ pub fn eval_model_fun (model : & str , ode_expr : & OdeExpr ) -> Box <dyn Model > {
201+ match model {
202+ " lotka-volterra" => Box :: new (LotkaVolterra :: default ()),
203+ " alpha-pinene" | " α-pinene" => Box :: new (AlphaPinene :: default ()),
204+ _ => Box :: new (GenericModel :: new (ode_expr ))
205+ }
206+ }
207+ ```
208+
209+ After you establish an identifier in the match, at the bottom of the file, them model can be
210+ used indicating the identifier in the XML config file like this:
211+
212+ ``` xml
213+ <?xml version =" 1.0" encoding =" UTF-8" ?>
214+
215+ <cuqdyn-config >
216+ <tolerances >
217+ <rtol >1e-8</rtol >
218+ <atol >1e-9, 1e-10</atol >
219+ </tolerances >
220+ <ode_expr y_count =" 2" p_count =" 4" >
221+ lotka-volterra
222+ </ode_expr >
223+ </cuqdyn-config >
224+ ```
225+
226+ Note that y_count and p_count are still present.
0 commit comments