# Poisson equation

The main code for this tutorial can be found in poisson_global_rom.cpp, which accelerates the Poisson problem $$-\Delta u = f$$ with homogeneous Dirichlet boundary conditions. The numerical results can be found in Poisson Problem.

libROM assumes that you have a physics code, such as MFEM, SU2, and Laghos. Then, libROM can be integrated into the physics code to build ROM to accelerate physics simulation. For example, see numerical results in Examples and Gallery. This tutorial illustrates how various libROM objects and functions can be used to collect simulation data, build reduced basis, and construct reduced order model operator to accelerate and predict a target physics simulation.

The following tutorials are available:

• Tutorial 1: offline, Take and write simulation data with libROM.
• Tutorial 2: merge, Collect simulation data and build a reduced basis.
• Tutorial 3: online, Build a ROM operator, solve the ROM system, and restore the full order state.

## Building

Follow the building page to build the libROM library. You must build it with -m option to build MFEM library together.

~/libROM> ./scripts/compile.sh -m


## Tutorial 1

This tutorial demonstrates how to collect simulation data with libROM. The important object is BasisGenerator, which collects simulation data and computes reduced basis, using various singular value decomposition (SVD) algorithms, e.g., incremental SVD and static SVD. The incremental SVD is useful for time-dependent problems. Because the Poisson problem is a time-independent problem, we will focus on the usage of the static SVD. The definition of BasisGenerator class can be found in BasisGenerator.h.

You must include BasisGenerator.h in your physics code where the simulation data is generated. For example, BasisGenerator.h is included in Line 32 of poisson_global_rom.cpp for Poisson Problem.

#include "BasisGenerator.h"


A BasisGenerator pointer is defined in Line 216 of poisson_global_rom.cpp and the pointer is initiated in Line 231 of poisson_global_rom.cpp. The BasisGenerator requires four inputs to initialize, i.e., Options, boolean variable, string, and Database::formats. The object, Options, sets various options for the BasisGenerator, such as the basis dimension and singular value tolerance. The boolean variable determines if the incremental or static SVD will be used. For this tutorial, we choose the static SVD, so the boolean variable must be false. Finally, the string input specifies the name of the basis file and Database::formats specifies the file format for the basis file. The default format is Database::HDF5. The detailed description for inputs for Options and BasisGenerator can be found in Options.h and BasisGenerator.h. The specific inputs used for the Poisson problem can be found in Lines 209--218 of poisson_global_rom.cpp.

Now, the instantiated BasisGenerator, i.e., generator, collects the simulation data once it is available. The Poisson problem generates the solution, $X$, in Line 316 of poisson_global_rom.cpp and it is collected in the generator in Line 323 of poisson_global_rom.cpp. The member function, writeSnapshot on Line 324 of poisson_global_rom.cpp simply writes the solution data in the specified HDF5 file. Make sure that the pointers, generator and options, are deleted after done with sampling. This completes the libROM data collection implementation, which corresponds to the offline phase in the Poisson problem. If you execute the following command:

poisson_global_rom -offline -f 1.0 -id 0


then you should see the HDF5 snapshot output file, i.e., basis0_snapshot.000000. The command line options above include -offline that indicates the offline phase, -f 1.0 sets the frequency variable $\kappa=1.0$ (see the Poisson problem for the description of the frequency variable), and -id 0 labels the snapshot index. The visualization of the solution can be done either with VisIt or GLVis. For example, the VisIt shows the following solution contour for this specific simulation:

poisson_global_rom -offline -f 1.1 -id 1
poisson_global_rom -offline -f 1.2 -id 2


whose solution contour corresponds, respectively, to:

## Tutorial 2

Once the simulation data are collected within libROM basis files, they can be merged to form a reduced basis. This process is called the merge phase. It is implemented in Lines 230--248 of poisson_global_rom.cpp. As in Tutorial 1, the objects, Options and BasisGenerator must be defined (see Lines 223--224 of poisson_global_rom.cpp](https://github.com/LLNL/libROM/blob/master/examples/prom/poisson_global_rom.cpp). The generator iterates over the individual HDF5 snapshot file and loads them all (see Lines 235--238 of poisson_global_rom.cpp. The member function endSamples in Line 239 of poisson_global_rom.cpp computes the reduced basis. Again make sure to delete the pointers, i.e., generator and options.

For exammple, the following command line option runs the merge phase:

poisson_global_rom -merge -ns 3


The command line option, -merge, invokes the merges phase and -ns 3 option indicates that there are three different snapshot files. The merge phase reads the three snapshot files, i.e., basis0_snapshot.000000, basis1_snapshot.000000, and basis2_snapshot.000000, which were generated in Tutorial 1, and forms a reduced basis and stores it in the HDF5 basis file, i.e., basis.000000.

## Tutorial 3

The online phase builds ROM operators, solves the ROM system, and restores the full order states for a new parameter value. This tutorial demonstrates these three different actions for the frequency value, $\kappa = 1.15$.

Lines 334--335 of poisson_global_rom.cpp implements the step of reading a basis file. The BasisReader object reads the basis file, using member function, getSpatialBasis, which returns a Matrix object in libROM. The number of rows and columns of the reduced basis can be obtained through the member functions of the Matrix class, i.e., numRows and numColumns, respectively.

Line 341 of poisson_global_rom.cpp defines a MFEM DenseMatrix that holds the transpose of the reduced basis matrix. This must be understood as the transpose because libROM stores the matrix row-wise. The MFEM matrix is defined to form a reduced system operator, whose process is implemented in Lines 344--355 of poisson_global_rom.cpp. Then the reduced system operator is inverted at Line 356 of poisson_global_rom.cpp.

The reduced right-hand-side is formed by multiplying the reduced basis transpose to the full order model right-hand-side vector, $B$ at Line 350 of poisson_global_rom.cpp.

Line 361 of poisson_global_rom.cpp solves the reduced system of equation.

Line 365 of poisson_global_rom.cpp restores the corresponding full order state by multipling the reduced solution by the reduced basis.

The command line options that executes the online phase described above are

poisson_global_rom -online -f 1.15


where -online option invokes the online phase and -f 1.15 sets the frequency value $\kappa = 1.15$. This particular example ROM accelerates the physics simulation by $7.5$ and achieves the relative error, $6.4e-4$, with respect to the corresponding full order model solution.