Skip to content
Snippets Groups Projects
Commit c98e66b7 authored by Stéphane Del Pino's avatar Stéphane Del Pino
Browse files

Add documentation of writer module

parent bb0a6809
No related branches found
No related tags found
1 merge request!145git subrepo clone git@gitlab.com:OlMon/org-themes.git packages/org-themes
......@@ -4106,8 +4106,8 @@ Sets verbosity mode to ~true~ or ~false~ for linear solvers.
*** The ~writer~ module
This module provides functionalities to numerical results to files for
post processing.
This module provides functionalities to write numerical results to
files for post processing.
It provides the following functions and types.
#+NAME: get-module-info-writer
......@@ -4116,7 +4116,610 @@ It provides the following functions and types.
#+END_SRC
#+RESULTS: get-module-info-writer
**** ~writer~ provided types
***** ~output~
This type is used to describe output of discrete functions (of type
~Vh~). Mainly, it associates a name to the discrete function.
#+BEGIN_note
At writing, ~pugs~ checks that the names in an ~output~ list are all
different.
#+END_note
***** ~writer~
Variables of this type manage outputs: which format is used and
eventually writing policy. This policy sets for instance the time
period of for time dependent post processing.
**** ~writer~ provided functions
***** ~name_output: Vh*string -> output~
This function give a name to a discrete function.
#+BEGIN_SRC pugs :exports both :results none
import mesh;
import scheme;
import writer;
let m:mesh, m = cartesianMesh([0], [1], 100);
let identity:R^1 -> R, x -> x[0];
let xh:Vh, xh = interpolate(m, P0(), identity);
let x2h:Vh, x2h = xh*xh;
write(gnuplot_writer("writer-example1"), name_output(x2h, "x_square"));
#+END_SRC
See section [[gnuplot-writers]] for details about these writers family.
#+NAME: writer-example1-img
#+BEGIN_SRC gnuplot :exports results :file (substitute-in-file-name "${PUGS_SOURCE_DIR}/doc/writer-example1.png")
reset
set grid
set border
unset key
set xtics
set ytics
set square
set terminal png truecolor enhanced size 640,640
plot '<(sed "" $PUGS_SOURCE_DIR/doc/writer-example1.gnu)' lw 2 w l
#+END_SRC
#+CAPTION: Simple illustration of the output.
#+NAME: fig:writer-example1
#+ATTR_LATEX: :width 0.38\textwidth
#+ATTR_HTML: :width 300px;
#+RESULTS: writer-example1-img
#+BEGIN_warning
It can be convenient to define variables or lists of ~output~. However,
one has to pay attention of the following fact. When declaring an
output variable, a reference *to the data* of the discrete function is
done. It is not a reference to the language variable (or
expression).
#+END_warning
Let us illustrate it by an important second example.
#+BEGIN_SRC pugs :exports both :results none
import mesh;
import scheme;
import writer;
import math;
let m:mesh, m = cartesianMesh([0], [1], 100);
let identity:R^1 -> R, x -> x[0];
let fh:Vh, fh = interpolate(m, P0(), identity);
let gh:Vh, gh = fh*fh;
let pi:R, pi = acos(-1);
let output_list:(output),
output_list = (name_output(fh, "f"),
name_output(gh, "g"),
name_output(sin(pi*fh), "sin"));
let abs_cos:R^1 -> R, x -> abs(cos(pi*x[0]));
fh = interpolate(m, P0(), abs_cos); // fh now refers to another function
write(gnuplot_writer("writer-example2"), output_list);
output_list = (name_output(fh, "f"),
name_output(gh, "g"));
write(gnuplot_writer("writer-example2-2"), output_list);
#+END_SRC
Running this code produces the gnuplot file displayed on Figure
[[fig:writer-example2]]. One sees that ~f~ is the $\mathbb{P}_0(\mathbb{R})$
function corresponding to the function $x \to x$ and not to the function
$x -> |\cos(\pi x)|$. This later function is plotted on Figure
[[fig:writer-example2-2]] since ~output_list~ is set with the updated value
of ~fh~.
#+NAME: writer-example2-img
#+BEGIN_SRC gnuplot :exports results :file (substitute-in-file-name "${PUGS_SOURCE_DIR}/doc/writer-example2.png")
reset
set grid
set border
set key
set xtics
set ytics
set square
set terminal png truecolor enhanced size 640,640
plot '<(sed "" $PUGS_SOURCE_DIR/doc/writer-example2.gnu)' u 1:2 lw 2 t "f" w l, '<(sed "" $PUGS_SOURCE_DIR/doc/writer-example2.gnu)' u 1:3 lw 2 t "g" w l, '<(sed "" $PUGS_SOURCE_DIR/doc/writer-example2.gnu)' u 1:4 lw 2 t "sin(pi*f)" w l
#+END_SRC
#+CAPTION: Illustration of the life time of variables. The output for ~fh~ corresponds to its value when ~output_list~ is created: the interpolation of $x -> x$.
#+NAME: fig:writer-example2
#+ATTR_LATEX: :width 0.38\textwidth
#+ATTR_HTML: :width 300px;
#+RESULTS: writer-example2-img
#+NAME: writer-example2-2-img
#+BEGIN_SRC gnuplot :exports results :file (substitute-in-file-name "${PUGS_SOURCE_DIR}/doc/writer-example2-2.png")
reset
set grid
set border
set key
set xtics
set ytics
set square
set terminal png truecolor enhanced size 640,640
plot '<(sed "" $PUGS_SOURCE_DIR/doc/writer-example2-2.gnu)' u 1:2 lw 2 t "f" w l, '<(sed "" $PUGS_SOURCE_DIR/doc/writer-example2-2.gnu)' u 1:3 lw 2 t "g" w l
#+END_SRC
#+CAPTION: Illustration of the life time of variables. ~output_list~ is updated after ~fh~ has been updated.
#+NAME: fig:writer-example2-2
#+ATTR_LATEX: :width 0.38\textwidth
#+ATTR_HTML: :width 300px;
#+RESULTS: writer-example2-2-img
***** ~gnuplot~ writers <<gnuplot-writers>>
There is two ~gnuplot~ writers. One is dedicated to output of dimension
1 results (~gnuplot_1d_writer~) and the other allows post processing in
dimension 1 and 2 (~gnuplot_writer~).
Both of these writers can be used for single output or time series
output. In the case of single output, the filename is completed by
adding the extension ~.gnu~, in the case of time series, the filename is
extending by adding ~.abcd.gnu~, where ~abcd~ is the number of the output
in the series.
#+BEGIN_note
The ~gnuplot~ writers are implemented in parallel.
The ~gnuplot~ post processing of produced files is the same whichever is
the number of processors (as soon as the saved data is also the same,
which is warrantied by ~pugs~ for explicit methods).
#+END_note
For an obvious practical reason, each ~gnuplot~ file starts with a
preamble that indicates running information.
This information contains, the production date of the file. The ~pugs~
version (including the hash key of the last commit) and a summary of
the output data to easy its use. For ~gnuplot~ files, this is the
location where the provided name (to the discrete function) is used.
In the case of time series the "physical" time of output is also
stored as a comment before the variable list.
Here is an example of preamble of a produced ~gnuplot~ file.
#+NAME: head-gnuplot-txt
#+BEGIN_SRC shell :exports results :results output
head -n 8 writer-example1.gnu
#+END_SRC
#+RESULTS: head-gnuplot-txt
****** ~gnuplot_1d_writer~ functions
This writer family make only sense in 1d.
#+BEGIN_note
In parallel, as soon as the saved data themselves are the same, the
~gnuplot_1d_writer~ generates *exactly* the same files since the
coordinates of the post processed data are sorted according to growing
abscissa.
#+END_note
******* ~gnuplot_1d_writer: string -> writer~
Defines a ~gnuplot~ writer for 1d data. This is a single file writer in
the sense that it does not take care of time series.
Let us consider an example.
#+BEGIN_SRC pugs :exports both :results none
import mesh;
import scheme;
import writer;
import math;
let m:mesh, m = cartesianMesh([0], [1], 5);
let identity:R^1 -> R, x -> x[0];
let xh:Vh, xh = interpolate(m, P0(), identity);
let gp:writer, gp = gnuplot_1d_writer("gp_1d_example");
write(gp, (name_output(xh*xh, "x^2"), name_output(3*xh+2, "3x+2")));
#+END_SRC
The produced file (~"gp_1d_example.gnu"~) contains the following
#+NAME: gp-1d-example-txt
#+BEGIN_SRC shell :exports results :results output
cat gp_1d_example.gnu
#+END_SRC
#+RESULTS: gp-1d-example-txt
As one can see the output for $\mathbb{P}_0$ data consists in saving
the values at cell centers in the order of growing abscissa. This
allows to plot "smoother" curves than the ~gnuplot_writer~ (see
[[gnuplot-writer-function]]).
A typical use of this writer is the following.
#+BEGIN_SRC pugs :exports both :results none
import mesh;
import scheme;
import writer;
import math;
let m:mesh, m = cartesianMesh([0], [2], 20);
let pi:R, pi = acos(-1);
let sin_pi_x:R^1 -> R, x -> sin(pi*x[0]);
let fh:Vh, fh = interpolate(m, P0(), sin_pi_x);
write(gnuplot_1d_writer("gp_1d_sin"), name_output(fh, "f"));
#+END_SRC
#+NAME: writer-gp-1d-sin-img
#+BEGIN_SRC gnuplot :exports results :file (substitute-in-file-name "${PUGS_SOURCE_DIR}/doc/gp-1d-sin.png")
reset
set grid
set border
unset key
set xtics
set ytics
set square
set terminal png truecolor enhanced size 628,400
plot '<(sed "" $PUGS_SOURCE_DIR/doc/gp_1d_sin.gnu)' lw 2 w lp
#+END_SRC
#+CAPTION: Example of produced gnuplot results from the ~gnuplot_1d_writer~. Since data are stored by growing abscissa, one can use the ~w lp~ plotting option in ~gnuplot~.
#+NAME: fig:writer-gp-1d-sin
#+ATTR_LATEX: :width 0.38\textwidth
#+ATTR_HTML: :width 300px;
#+RESULTS: writer-gp-1d-sin-img
******* ~gnuplot_1d_writer: string*R -> writer~ <<gnuplot-1d-series>>
This writer differs from the previous one by handling output
series. The real value argument defines the period to respect between
two outputs. It can be viewed as an helper to outputs.
Let us give an example to fix ideas.
#+BEGIN_SRC pugs :exports both :results none
import mesh;
import scheme;
import writer;
import math;
let m:mesh, m = cartesianMesh([0], [1], 20);
let pi:R, pi = acos(-1);
let t:R, t = 0;
let tmax:R, tmax = 1;
let dt:R, dt = 3.7e-2;
let period:R, period = 0.15; // sets the period output
let gp:writer, gp = gnuplot_1d_writer("gp_1d_exp_sin", period);
let f: R^1 -> R, x -> exp(-t)*sin(2*pi*x[0]);
let fh:Vh, fh = interpolate(m, P0(), f);
write(gp, name_output(fh, "f"), 0);
do {
if (dt > tmax-t) {
dt = tmax-t;
}
t +=dt;
write(gp, name_output(fh, "f"), t);
} while(t<tmax);
#+END_SRC
Running this example produces the following files
#+NAME: ls-produced-gp-1d-series
#+BEGIN_SRC shell :exports results :results output
ls gp_1d_exp_sin.*.gnu
#+END_SRC
#+RESULTS: ls-produced-gp-1d-series
Each of these file contains the numerical solution at following saving
times:
#+NAME: times-in-gp-1d-series
#+BEGIN_SRC shell :exports results :results output
grep -n "# time = " gp_1d_exp_sin.*.gnu | cut -d '=' -f 2
#+END_SRC
#+RESULTS: times-in-gp-1d-series
****** ~gnuplot_writer~ functions <<gnuplot-writer-function>>
This writer differs from the previous one since it draws the cells and
affects the cell value to the nodes. This produces larger files but
allow 2d representation. Also, if the saved data is exactly the same
in parallel, the order of the cells is generally different since they
are written processor by processor.
Additionally, this writer allows to write 2d meshes, see paragraph
[[write-mesh]].
******* ~gnuplot_writer: string -> writer~
Here is an illustrating example in dimension 1, see the result on
Figure [[fig:writer-gp-sin]].
#+BEGIN_SRC pugs :exports both :results none
import mesh;
import scheme;
import writer;
import math;
let m:mesh, m = cartesianMesh([0], [2], 20);
let pi:R, pi = acos(-1);
let sin_pi_x:R^1 -> R, x -> sin(pi*x[0]);
let fh:Vh, fh = interpolate(m, P0(), sin_pi_x);
write(gnuplot_writer("gp_sin"), name_output(fh, "f"));
#+END_SRC
#+NAME: writer-gp-sin-img
#+BEGIN_SRC gnuplot :exports results :file (substitute-in-file-name "${PUGS_SOURCE_DIR}/doc/gp-sin.png")
reset
set grid
set border
unset key
set xtics
set ytics
set square
set terminal png truecolor enhanced size 628,400
plot '<(sed "" $PUGS_SOURCE_DIR/doc/gp_sin.gnu)' lw 2 w lp
#+END_SRC
#+CAPTION: Example of produced gnuplot results from the ~gnuplot_writer~. One can compare ths produced result to the one of the ~gnuplot_1d_writer~ given on Figure [[fig:writer-gp-1d-sin]]
#+NAME: fig:writer-gp-sin
#+ATTR_LATEX: :width 0.38\textwidth
#+ATTR_HTML: :width 300px;
#+RESULTS: writer-gp-sin-img
Let use give a 2d example.
#+BEGIN_SRC pugs :exports both :results none
import mesh;
import scheme;
import writer;
import math;
let m:mesh, m = cartesianMesh(-[1,1], [1,1], (40,40));
let pi:R, pi = acos(-1);
let f:R^2 -> R, x -> cos(pi*x[0])*sin(pi*x[1]);
write(gnuplot_writer("gp_2d_cos_sin"),
name_output(interpolate(m,P0(), f), "f"));
#+END_SRC
The gnuplot result is displayed on Figure [[fig:writer-gp-2d-cos-sin]].
#+NAME: writer-gp-2d-cos-sin-img
#+BEGIN_SRC gnuplot :exports results :file (substitute-in-file-name "${PUGS_SOURCE_DIR}/doc/gp-2d-cos-sin.png")
reset
set grid
set border
unset key
set xtics
set ytics
set square
unset colorbox
set palette rgb 33,13,10
set terminal png truecolor enhanced size 300,300
plot '<(sed "" $PUGS_SOURCE_DIR/doc/gp_2d_cos_sin.gnu)' w filledcurves closed palette, '<(sed "" $PUGS_SOURCE_DIR/doc/gp_2d_cos_sin.gnu)' lc rgb 0 w l
#+END_SRC
#+CAPTION: Example of 2d plot from the ~gnuplot_writer~
#+NAME: fig:writer-gp-2d-cos-sin
#+ATTR_LATEX: :width 0.38\textwidth
#+ATTR_HTML: :width 300px;
#+RESULTS: writer-gp-2d-cos-sin-img
******* ~gnuplot_writer: string*R -> writer~
This is the time series function in the case of the ~gnuplot_writer~. It
behaves the same as [[gnuplot-1d-series]].
***** ~vtk~ writers
For more complex post processing (including 3d), ~pugs~ can generate ~vtk~
outputs.
The used format is one file in the ~vtu~ format for each parallel domain
(and eventually each time). The output is done using binary data for
performance reasons. For each time step a ~pvtu~ file is generate to
handle parallelism. And for a complete time series, a ~pvd~ file is
produced. This is the file that should be loaded.
Observe that each of these files (~vtu~, ~pvti~ and ~pvd~) contains a
comment that contains the creation date and the version of ~pugs~ that
was run.
The use is exactly the same than for ~gnuplot~ writers so we do not
provide full examples.
~vtk~ writers are compatible with the ~write_mesh~ function, see paragraph
[[write-mesh]].
****** ~vtk_writer: string -> writer~
One should use this writer for single output (no time series). The
produced ~pvd~ file is built by adding ~.pvd~ to the provided ~string~.
****** ~vtk_writer: string*R -> writer~
This function follows the same rule. One just specifies the output
period. The generated ~pvd~ file is built the same way, one adds ~.pvd~ to
the provided ~string~.
***** ~write~, ~force_write~ and ~write_mesh~ functions
One a mesh writer has been defined, these functions are called to
effectively generate the post processing files.
****** ~write: writer*(output) -> void~
As a parameter, it takes a ~writer~ that is not a time series one and a
list of ~output~ (which are named discrete functions that are defined on
the *same* mesh).
There have already shown a lot of examples of use of the ~write~
function. So let us focus on improper calls.
Trying to use a time series ~writer~
#+NAME: cannot-use-time-series-writer
#+BEGIN_SRC pugs-error :exports both :results output
import mesh;
import scheme;
import writer;
import math;
let m:mesh, m = cartesianMesh([0], [2], 20);
let pi:R, pi = acos(-1);
let sin_pi_x:R^1 -> R, x -> sin(pi*x[0]);
let fh:Vh, fh = interpolate(m, P0(), sin_pi_x);
let vtk:writer, vtk = vtk_writer("vtk_time_series", 0);
write(vtk, name_output(fh, "f"));
#+END_SRC
produces the following runtime error
#+results: cannot-use-time-series-writer
Trying to use variables defined on different meshes
#+NAME: cannot-use-diffrent-meshes-in-writer
#+BEGIN_SRC pugs-error :exports both :results output
import mesh;
import scheme;
import writer;
import math;
let m0:mesh, m0 = cartesianMesh([0], [2], 20);
let m1:mesh, m1 = cartesianMesh([0], [2], 20);
let pi:R, pi = acos(-1);
let sin_pi_x:R^1 -> R, x -> sin(pi*x[0]);
let fh:Vh, fh = interpolate(m0, P0(), sin_pi_x);
let gh:Vh, gh = interpolate(m1, P0(), sin_pi_x);
let vtk:writer, vtk = vtk_writer("vtk_different_meshes");
write(vtk, (name_output(fh, "f"), name_output(gh, "g")));
#+END_SRC
gives the runtime error
#+results: cannot-use-diffrent-meshes-in-writer
****** ~write: writer*(output)*R -> void~
This ~write~ function is used to save time series data. The real
parameter (of type ~R~) is the current time.
One cannot use a ~writer~ that does not support time series.
Trying to use a non time series ~writer~
#+NAME: cannot-use-non-time-series-writer
#+BEGIN_SRC pugs-error :exports both :results output
import mesh;
import scheme;
import writer;
import math;
let m:mesh, m = cartesianMesh([0], [2], 20);
let pi:R, pi = acos(-1);
let sin_pi_x:R^1 -> R, x -> sin(pi*x[0]);
let fh:Vh, fh = interpolate(m, P0(), sin_pi_x);
let vtk:writer, vtk = vtk_writer("vtk_time_series");
write(vtk, name_output(fh, "f"), 1.2);
#+END_SRC
gives the runtime error
#+results: cannot-use-non-time-series-writer
****** ~force_write: writer*(output)*R -> void~
One probably noticed that using the ~write~ function with a time series
~writer~, last time of the calculation may not be written (see section
[[gnuplot-1d-series]]). The ~force_write~ function does not check that the
saving time has been reached. It just checks that the current time has
not already been saved.
Let us improve slightly the example given in section
[[gnuplot-1d-series]].
#+BEGIN_SRC pugs :exports both :results none
import mesh;
import scheme;
import writer;
import math;
let m:mesh, m = cartesianMesh([0], [1], 20);
let pi:R, pi = acos(-1);
let t:R, t = 0;
let tmax:R, tmax = 1;
let dt:R, dt = 3.7e-2;
let period:R, period = 0.15; // sets the period output
let gp:writer, gp = gnuplot_1d_writer("gp_1d_exp_sin_force", period);
let f: R^1 -> R, x -> exp(-t)*sin(2*pi*x[0]);
let fh:Vh, fh = interpolate(m, P0(), f);
write(gp, name_output(fh, "f"), 0);
do {
if (dt > tmax-t) {
dt = tmax-t;
}
t +=dt;
fh = interpolate(m, P0(), f);
if (t<tmax) {
write(gp, name_output(fh, "f"), t);
} else {
force_write(gp, name_output(fh, "f"), t);
}
} while(t<tmax);
#+END_SRC
Running this example produces the following files
#+NAME: ls-produced-gp-1d-series-force
#+BEGIN_SRC shell :exports results :results output
ls gp_1d_exp_sin_force.*.gnu
#+END_SRC
#+RESULTS: ls-produced-gp-1d-series-force
One can see the additional file.
Each of these file contains the numerical solution at following saving
times:
#+NAME: times-in-gp-1d-series-force
#+BEGIN_SRC shell :exports results :results output
grep -n "# time = " gp_1d_exp_sin_force.*.gnu | cut -d '=' -f 2
#+END_SRC
#+RESULTS: times-in-gp-1d-series-force
The last post processing time is now 1.
****** ~write_mesh: writer*mesh -> void~ <<write-mesh>>.
This function just saves a ~mesh~ using a ~writer~. The ~gnuplot_1d_writer~
cannot write mesh. And the ~writer~ argument must not be time series
~writer~.
[fn:pugs-def] ~pugs~: Parallel Unstructured Grid Solvers
[fn:MPI-def] ~MPI~: Message Passing Interface
[fn:DSL-def] ~DSL~: Domain Specific Language~
[fn:DSL-def] ~DSL~: Domain Specific Language
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment