Skip to content

Commit

Permalink
pyfeelpp documentation (#222)
Browse files Browse the repository at this point in the history
* write doc about :
- parameters
- petsc vectors
- petsc matrix
Write documentation on python x feel++ modules #151
[ci skip]

* add documentation about parameters

see commit feelpp/feelpp@9512e77
[ci skip]

* add documentation about ModelProperties in python #151

* add documentation about functions wrapped in feelpp/feelpp@84a845d

* up doc about `feelpp.mor._mor.ParameterSpace.New`
[ci skip]

* update doc according to feelpp/feelpp@2f3b94a

* write documentation about online / offline usage

* add title to the page

[ci skip]

* write doc about last modifications

* move modelproperties to right directory

* add details for `generate_basis`
(and fix table of content)

* fix nav to display rbm
[ci skip]

* doc : complete documentation about `reducedbasis` :
offline and online

* Update reducedbasis_online.adoc

* add more details about reducedbasis in python #219 #151
/cc @prudhomm

* fixes of some typos and remove files in double
close #151
  • Loading branch information
thomas-saigre authored Nov 16, 2022
1 parent a5fb45b commit 5dffdc7
Show file tree
Hide file tree
Showing 14 changed files with 297 additions and 59 deletions.
1 change: 1 addition & 0 deletions docs/math/antora.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@ nav:
- modules/analyse-fonctionnelle/nav.adoc
- modules/fem/nav.adoc
- modules/hdg/nav.adoc
- modules/rbm/nav.adoc
1 change: 1 addition & 0 deletions docs/mor/modules/ROOT/nav.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@
** xref:pbdw.adoc#_using_pbdw[Using PBDW]
* xref:index.adoc#_cases[Cases]
** xref:opusheat:index.adoc[OpusHeat]
** xref:thermalfin:index.adoc[ThermalFin]
1 change: 1 addition & 0 deletions docs/mor/modules/ROOT/pages/index.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,4 @@ The Parametrized Background Data Weak (xref:pbdw.adoc[PBDW]) method has also bee
== Cases

- xref:opusheat:index.adoc[OpusHeat]
- xref:thermalfin:index.adoc[ThermalFin]
1 change: 1 addition & 0 deletions docs/mor/modules/thermalfin/nav.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
* xref:index.adoc[Thermal fin]
3 changes: 3 additions & 0 deletions docs/mor/modules/thermalfin/pages/index.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
= Thermal fin

The redaction of this page is in progress.
4 changes: 3 additions & 1 deletion docs/user/modules/python/nav.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@
*** xref:pyfeelpptoolboxes/fluid.adoc[Fluid Mechanics]
*** xref:pyfeelpptoolboxes/solid.adoc[Solid Mechanics]
** xref:pyfeelppmor/index.adoc[{pyfeelppmor}]
*** xref:pyfeelppmor/parameters.adoc[Parameters]
*** xref:pyfeelppmor/parameterSpace.adoc[Parameter space]
*** xref:pyfeelppmor/parameters.adoc[Parameters]
*** xref:pyfeelppmor/petscDouble.adoc[PETSc vector and matrix]
*** xref:pyfeelppmor/toolboxmor.adoc[Toolbox MOR]
*** xref:pyfeelppmor/reducedbasis.adoc[Python module `reducedbasis`]
**** xref:pyfeelppmor/reducedbasis_offline.adoc[Offline stage]
46 changes: 23 additions & 23 deletions docs/user/modules/python/pages/pyfeelpp/filters.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -24,30 +24,30 @@ app = feelpp.Environment(["myapp"],config=feelpp.localRepository("")) # <1>

[source,python]
----
app.setLogVerbosityLevel(0) # <0>
app.setLogVerbosityLevel(0) # <1>
geofilename=feelpp.download( "github:{repo:feelpp,path:feelpp/quickstart/laplacian/cases/feelpp2d/feelpp2d.geo}", worldComm=app.worldCommPtr() )[0]
mesh = feelpp.load(feelpp.mesh(dim=2,realdim=2), name=geofilename, h=0.1, verbose=1) # <1>
Xh=feelpp.functionSpace(mesh=mesh,space="Pch",order=1) # <2>
P0h=feelpp.functionSpace(mesh=mesh,space="Pdh",order=0) # <3>
u=Xh.element() # <4>
u.on(range=feelpp.elements(mesh), expr=feelpp.expr("sin(2*pi*x)*cos(pi*y):x:y")) # <5>
e = feelpp.exporter(mesh=mesh) # <6>
e.addScalar("a_scalar", 1.) # <7>
e.addP1c("u",u) # <8>
e.addP0d("pid",feelpp.pid( P0h )) # <9>
e.save() # <10>
mesh = feelpp.load(feelpp.mesh(dim=2,realdim=2), name=geofilename, h=0.1, verbose=1) # <2>
Xh=feelpp.functionSpace(mesh=mesh,space="Pch",order=1) # <3>
P0h=feelpp.functionSpace(mesh=mesh,space="Pdh",order=0) # <4>
u=Xh.element() # <5>
u.on(range=feelpp.elements(mesh), expr=feelpp.expr("sin(2*pi*x)*cos(pi*y):x:y")) # <6>
e = feelpp.exporter(mesh=mesh) # <7>
e.addScalar("a_scalar", 1.) # <8>
e.addP1c("u",u) # <9>
e.addP0d("pid",feelpp.pid( P0h )) # <10>
e.save() # <11>
----
<0> The verbosity level is set to 0 (only `VLOG(level)` with `level <= 0` are displayed)
<1> The mesh is loaded from the {uri-github-feelpp} repository
<2> The function space stem:[X_h] is built from the mesh stem:[mesh] and the space stem:[Pch] and order stem:[1]
<3> The function space stem:[P0_h] is built from the mesh stem:[mesh] and the space stem:[Pdh] and order stem:[0]
<4> The element stem:[u] is built from the function space stem:[X_h]
<5> The element stem:[u] is interpolated with the expression stem:[{sin(2*pi*x)*cos(pi*y)}:x:y]
<6> The exporter is built from the mesh stem:[mesh]
<7> The scalar stem:[a_scalar] is added to the exporter stem:[e]
<8> The element stem:[u] is added to the exporter stem:[e]
<9> The element stem:[pid] is added to the exporter stem:[e]
<10> The exporter stem:[e] is saved to the disk
<1> The verbosity level is set to 0 (only `VLOG(level)` with `level <= 0` are displayed)
<2> The mesh is loaded from the {uri-github-feelpp} repository
<3> The function space stem:[X_h] is built from the mesh `mesh` and the space `Pch` and order `1`
<4> The function space stem:[P0_h] is built from the mesh `mesh` and the space `Pdh` and order `0`
<5> The element `u` is built from the function space `Xh`
<6> The element `u` is interpolated with the expression `{sin(2*pi*x)*cos(pi*y)}:x:y`
<7> The exporter is built from the mesh `mesh`
<8> The scalar `a_scalar` is added to the exporter `e`
<9> The element `u` is added to the exporter `e`
<10> The element `pid` is added to the exporter `e`
<11> The exporter `e` is saved to the disk


[%collapsible.result]
Expand All @@ -59,7 +59,7 @@ e.save() # <10>
----
====
The results are stored in the directory `feelppdb`` and can be visualized with {paraview-website} or {ensight}.
The results are stored in the directory `feelppdb` and can be visualized with {paraview-website} or {ensight}.
INFO: The file `exports/ensightgold/myapp/myapp.case` can be opened directly in {paraview} or {ensight} to visualize the mesh and the fields.
Expand Down
2 changes: 1 addition & 1 deletion docs/user/modules/python/pages/pyfeelpp/mesh.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -208,4 +208,4 @@ i1 = [3.24282386], i2 = [149.465], i3 = [0.]
== Next steps

- [x] xref:pyfeelpp/discr.adoc[Manipulate functions and function spaces]
- [x] Export to paraview
- [x] xref:pyfeelpp/filters.adoc[Export to paraview]
1 change: 0 additions & 1 deletion docs/user/modules/python/pages/pyfeelppmor/index.adoc
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
= {feelpp} model order reduction in Python
include::user:ROOT:partial$header-macros.adoc[]

This sections present the modules developped and the function implemented to handle {feelpp} MOR objects in Python. The script link:https://github.com/feelpp/feelpp/blob/develop/mor/pyfeelpp-mor/feelpp/mor/toolboxmor.py[toolboxmor.py] presents the main features, on the case opus-heat.
18 changes: 9 additions & 9 deletions docs/user/modules/python/pages/pyfeelppmor/petscDouble.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@ Class `VectorPetscDouble` (`feelpp._alg.VectorPetscDouble`)

=== Methods

* `__init__(*args, **kwargs)` : Overloaded function.
* `\\__init__(*args, **kwargs)` : Overloaded function.

1. `__init__()`. The vector created is empty.
2. `__init__(arg0: int, arg1: feelpp._core.WorldComm)`. The vector created has a size `arg0`.
3. `__init__(arg0: int, arg1: int, arg2: feelpp._core.WorldComm)`. The vector created has a global size `arg0`, and a local size `arg1`.
4. `__init__(arg0: feelpp._alg.DataMap, arg1: bool)`
1. `\\__init__()`. The vector created is empty.
2. `\\__init__(arg0: int, arg1: feelpp._core.WorldComm)`. The vector created has a size `arg0`.
3. `\\__init__(arg0: int, arg1: int, arg2: feelpp._core.WorldComm)`. The vector created has a global size `arg0`, and a local size `arg1`.
4. `\\__init__(arg0: feelpp._alg.DataMap, arg1: bool)`
* `clear()` : clear PETSc vector
* `size()` -> `int` : return PETSc Vector size
* `vec()` -> `vec` : return a PETSc Vector that can be manipulated with funciton of the module https://pypi.org/project/petsc4py/[petsc4py]. The functions of this class can be found on the https://www.mcs.anl.gov/petsc/petsc4py-current/docs/apiref/petsc4py.PETSc.Vec-class.html[documentation of PETSc4py].
Expand All @@ -26,10 +26,10 @@ Class `MatrixPetscDouble` (`feelpp._alg.MatrixPetscDouble`). The methods of this

=== Methods

* `__init__(*args, **kwargs)` : Overloaded function.
1. `__init__(arg0: feelpp._core.WorldComm)`
2. `__init__(arg0: feelpp._alg.DataMap, arg1: feelpp._alg.DataMap)`
3. `__init__(arg1: feelpp._alg.DataMap, arg2: feelpp._core.WorldComm)`
* `\\__init__(*args, **kwargs)` : Overloaded function.
1. `\\__init__(arg0: feelpp._core.WorldComm)`
2. `\\__init__(arg0: feelpp._alg.DataMap, arg1: feelpp._alg.DataMap)`
3. `\\__init__(arg1: feelpp._alg.DataMap, arg2: feelpp._core.WorldComm)`
* `clear()` : clear PETSc matrix
* `mat(...)` -> `mat` : return a PETSc sparse matrix. See https://www.mcs.anl.gov/petsc/petsc4py-current/docs/apiref/petsc4py.PETSc.Mat-class.html[the documentation].
* `rowStart()` -> `int` : return PETSc Matrix row start. This method is usefull is the matrix is shared with many processors, as the following.
Expand Down
44 changes: 35 additions & 9 deletions docs/user/modules/python/pages/pyfeelppmor/reducedbasis.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -20,19 +20,24 @@ To set the environment, those module also need to be imported :
[source, python]
----
import sys, os
from feelpp.toolboxes.heat import *
import feelpp.toolboxes.core as core
from feelpp.operators import mass
import feelpp.mor as mor
from feelpp.toolboxes.heat import * <1>
import feelpp.toolboxes.core as core <2>
from feelpp.operators import mass <3>
import feelpp.mor as mor <4>
import feelpp
----

<1> The toolbox heat is used to simulate the heat equation on the case studied.
<2> The module `core` is used to set the environment.
<3> The `mass` function is needed to create the mass matrix if we work on a time-dependent case.
<4> The module `mor` is used to get the functions neededd by the toolbox mor.


== Set the environment

[source, python]
----
config = feelpp.globalRepository("reducedbasis")
config = feelpp.localRepository("reducedbasis")
sys.argv = ["reducedbasis"]
o = core.toolboxes_options("heat")
o.add(mor.makeToolboxMorOptions())
Expand All @@ -43,22 +48,39 @@ e = feelpp.Environment(sys.argv, opts=o, config=config)

== Set the model

=== Description of the model

In this document, the cases used is `thermal-fin` in 2D, with a stem:[\mathbb{P}_1] discretization and stationnary.
This model is described in xref:mor:thermalfin:index.adoc[this page].

The usage would be the same for another case.


=== Code

Set the parameters nedded to the model :

- `config_file` : path to the cfg file
- `dim` : the dimension of the case
- `order` : the order of discretization (`1` for stem:[\mathbb{P}_1], `2` for stem:[\mathbb{P}_2])
- `time_dependant` : is the case stationnary or transient ? (for now always to `False`)
- `time_depedent` : is the case stationnary or transient ? (for now always to `False`)
- `name` : name of the CRB case



[source,python]
----
config_file = "thermal-fin.cfg"
dim = 2
order = 1
time_dependant = False
time_depedent = False
name = "thermalfin-2d"
----

The configuration files for this case are available on github : https://raw.githubusercontent.com/feelpp/feelpp/develop/mor/cases/thermal-fin/2d/fin.geo[geometry file], https://raw.githubusercontent.com/feelpp/feelpp/develop/mor/cases/thermal-fin/2d/thermal-fin.cfg[cfg file], and https://raw.githubusercontent.com/feelpp/feelpp/develop/mor/cases/thermal-fin/2d/thermal-fin.json[json file].

Then, we can create the model :

[source,python]
----
cfg = feelpp.readCfg(config_file)
Expand Down Expand Up @@ -118,7 +140,7 @@ default_parameter = modelParameters.toParameterValues()

[source, python]
----
model = mor.toolboxmor(name=name, dim=dim, time_dependent=time_dependant)
model = mor.toolboxmor(name=name, dim=dim, time_dependent=time_depedent)
model.setFunctionSpaces( Vh=heatBox.spaceTemperature() )
def assembleDEIM(mu):
Expand Down Expand Up @@ -305,6 +327,8 @@ rb.computeOfflineErrorRhs()
rb.computeOfflineError()
----

The script `generate_basis.py` run this offline part. See the xref:pyfeelppmor/reducedbasis_offline.adoc[dedicated page] for more details.

== Online phase

[source, python]
Expand Down Expand Up @@ -355,4 +379,6 @@ rb.getSolutionsFE(mu, k=0)
----
====

The two functions `getSolutions` (resp. `getSolutionsFE`) return the solution stem:[u_N(\mu)] (resp. stem:[u(\mu)]) and the value of the output stem:[s_N^k(\mu)] (res. stem:[s^k(\mu)]).
The two functions `getSolutions` (resp. `getSolutionsFE`) return the solution stem:[u_N(\mu)] (resp. stem:[u(\mu)]) and the value of the output stem:[s_N^k(\mu)] (res. stem:[s^k(\mu)]).
See xref:pyfeelppmor/parameters.adoc[the dedicated page] for the API of `ParameterSpaceElement`.

146 changes: 146 additions & 0 deletions docs/user/modules/python/pages/pyfeelppmor/reducedbasis_offline.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
= Usage of Feelpp / Mor : Offline part

:stem: latexmath

== Usage

This part can be run in parallel.

.Usage of `generate_basis` script
[source, bash]
----
[mpirun -np <nproc>] python3 generate_basis.py
--config-file <path to cfg file>
--odir <path to export directory>
--dim <DIM>
--case <name of the case>
[--algo {0|1|2}]
[--train-size <size>]
[--tol <tol>]
[--time-dependant={True | False}]
----

[[parameters]]
.Parameters
[cols="1,1,1"]
|===
|Name|Description|Default value

|`config-file`
|path to config `cfg` file
|_mandatory_

|`odir`
|path to output directory, where data will be saved
|_mandatory_

|`case`
|name of the case
|`generate_basis`

|`dim`
|dimension of the case (must be `2` or `3`)
|_mandatory_

|`algo`
|algorithm used to generate a basis, see <<Algorithms, table below>>
|`1`

|`train-size`
|Size of the train set (depending on algorithm used)
|`40`

|`tol`
|tolerance used for generating (depends on algorithm)
|`1e-6`

|`time-dependant`
|time dependant case
|`False`
|===



[[Algorithms]]
== Algorithms


.Algorithms
[cols='1,2,5']
|===
|Value|Algorithm|Description

|`0`
|From sample
|Generates a basis of size stem:[N=]`train-size` elements, [log-]randomly taken in the space.

|`1`
|Greedy algorithm
|Run the greedy algorithm on a train set of element of size `train-size`. This algorithm also stores the evolution of the maximal error bound at each step.

|`2`
|POD generation
|Takes the largest POD modes from a basis of size `train-size`. The resulting basis will have a size stem:[N\leqslant]`train-size`. This algorithm also stores the evolution of the maximal error bound at each step.

|===

WARNING: For now, the computation of error bound is only valid when the decomposition is coercive (_i.e._ stem:[A(\mu)=\displaystyle\sum_{q}\beta_A(\mu)A^q], with stem:[\beta_A(\mu)\geqslant 0])

[[offline]]
== Exported files

Here is a description of the generated files :

1. A `JSON` file, exported in `odir` directory, containing the following informations :
- `Qa` : Size of the decomposition of stem:[A(\mu)]
- `Qf` : Size of the decomposition of stem:[F(\mu)]
- `QLk` : Sizes of the decompositions of stem:[L_k(\mu)] for stem:[k\in\{1,n_\text{output}\}], gathers in a list.
- `N_output` : Number of output described in the JSON (`CRBOutput`)
- `output_names` : names of those outputs
- `N` : Size of the reduced basis
- `path` : Path where `h5` file is stored
- `mubar` : Values of stem:[\bar{\mu}]

2. A `h5` file, containing all the matrices used in the online part (of « small » size).


== Documentation for developpers

The function to call to generate the basis is `generatebasis` :

[source, python]
----
import feelpp.mor.generate_basis as g # import the module
g.generatebasis(worldcomm=worldcomm, config=config) # run the script
----

Where :

1. `worldcomm` is a pointer to the MPI communicator. This argument is optionnal. If none (or `None`) is given, the function will get the communicaotr from `feelpp.Environment`.

2. `config` is an object of type `g.generateBasisConfig`. It contains the paramters used by the script to generate the application.

[source, python]
----
config = generateBasisConfig(dim, config_file, time_dependant, odir, case, algo, size, tol)
----

The description and the default values of those parameters are descirbed <<parameters,above>>.

If `odir` contains `$name`, this expression will be replaced by the _name_ of the case, defined by concatenation `<case>-np_<nproc>`, where `case` is the name of the case given in the configuration, and `nproc` is the number of processors where the simulation is run.


[[files]]
== Files created by {feelpp}

Some files are created by {feelpp}. The emplacement of those file is important because they are used by the online part. In the following list, `<feel-dir>` represents the path to the `feel` directory. If nothing has been change in `~/.feelppconfig`, the path to the `<feel-dir>` is `~/feel`.

* Model repository : `<feel-dir>/crbdb/<name>/<uuid>`, where :
** `<name>` is the name of the case, defined by the option `--case`.
** `<uuid>` is a unique identifier of the model, computed by the toolbox.
This repository contains the meshes for the EIM decomposition.

* DEIM and MDEIM sampling files : `<feel-dir>/generate_basis-<name>/np_<nproc>/DmuDEim-P<dim>-Ne<size>-generated-by-master-proc` :
** `<dim>` is the dimension of the parameter space.
** `<size>` is the size of the train set used on the EIM algorithm. This corresponds to the option `toolboxmor.trainset-deim-size` and `trainset-mdeim-size` in the cfg file.
Those two files (one for the EIM decomposition of the matrix, and one for the EIM decomposition of the right-hand side) are generated by the toolbox, and contain the values of the parameters used to generate the basis.
Loading

0 comments on commit 5dffdc7

Please sign in to comment.