/*! \mainpage ML: Multi Level Preconditioning Package

\image html ml-image.jpg
\image latex ml-logo.eps

\section ml_table Table of Contents

<!-- - \ref ml_intro - \ref ml_download - \ref ml_desc - \ref ml_dev -->
- \ref ml_doc
- \ref ml_examples
- \ref ml_minitutorial
- \ref ml_MLP
- \ref ml_mainstruct
- \ref ml_conversion
- \ref ml_amesos
- \ref ml_ifpack
- \ref ml_anasazi
- \ref ml_mlapi_intro
- \ref ml_python
- \ref ml_thyra
- \ref ml_debug 
- \ref ml_changes
- \ref ml_copyright

<!--
\section ml_intro Introduction

ML is a multigrid preconditioning package intended to solve large sparse linear
systems of equations arising from primarily elliptic PDE discretizations. Several
different parallel multigrid schemes are contained within ML including smoothed
aggregation, a version of classical AMG, and a special algebraic multigrid for the
eddy current approximation to Maxwell's equations. This eddy current solver is a
unique capability of ML and utilizes the discrete nullspace of the operator in
building the smoothers and grid hierarchy. Within each of these methods there are
several different algorithms to guide the type of coarsening and the inter-grid
transfers (including the ability to drop weak coupling within the operator during
inter-transfer construction). There are also a number of smoothers including a
local Gauss-Seidel method, a symmetric local Gauss-Seidel method, a polynomial
smoother based on the Chebyshev semi-iterative method, block Gauss-Seidel
smoothers, as well as two-stage distributed relaxation smoothers for Maxwell's
equations. It is also possible to use ML with other packages to supply smoothers.
We have built-in interfaces for using methods from Aztec as smoothers and using
SuperLU as a coarse grid direct solver. Using the Amesos it is possible to access
other direct solvers such as MUMPS for use as a coarse grid solver.

ML can be used as a stand-alone package or to generate preconditioners for a
traditional iterative solver package (e.g. Krylov methods). We have supplied
support for working with the Aztec 2.1 and AztecOO iterative package Aztec.
However, other solvers can be used by supplying a few functions.

ML can also be used as a framework to generate new multigrid methods. Using ML's
built in aggregation routines and Galerkin products, it is possible to focus on
new types of inter-grid transfer operators without having to address the
cumbersome aspects of generating an entirely new parallel algebraic multigrid
code. We have used these flexibility to produce special multilevel methods using
coarse grid finite element functions to serve as inter-grid transfers.

A user-friendly, MATLAB-like interface to ML, called MLAPI, is under development; see
\ref ml_mlapi.

ML has been used within a number of applications at Sandia and a few applications
outside of Sandia. ML is released for external distribution and can be obtained as
part of the Trilinos development environment. 

-->

<!--
\section ml_download Download ML

ML can be downloaded from the web page http://software.sandia.gov/trilinos/downloads.html
-->

<!--
\section ml_desc Project Description

Many important scientific and engineering applications require the use of linear
solvers. The ML iterative solver package grew out of a need for scalable solvers.
Several algebraic multigrid methods are contained within ML. In addition to
standard algebraic multigrid, there is a special eddy current Maxwell solver. This
special solver takes into account the discrete null space associated with these
equations. The eddy current Maxwell solver is a unique capability provided for by
the  ML  library.

Our primary goal has been to provide state-of-the-art iterative methods that
perform well on parallel computers (applications running on over 1000 processors
have been run) and at the same time are easy to use for application engineers. In
addition to providing algebraic multilevel methods to engineers, the ML library is
also used in our research on preconditioners. At present, we are working closely
with a couple of specific applications in further extending our capabilities. We
have used ML in the following ways:
- Parallel: MPI, several different linux clusters, Intel ASC Red Storm, IBM
  SP2, ...
- Data-Neutral Interface: Matrices are accessed via getrow() and matvec()
  functions.

Primary Multilevel Schemes:
- Smoothed Aggregation;
- Edge Element Eddy Current AMG;
- Finite Element Based Two-Level Schemes;
- Refinement Based Multigrid;
- Classical AMG.

Parallel Smoother Methods:
- Processor-based Gauss-Seidel type methods (point and block version,
  symmetric and non-symmetric versions);
- Polynomial-Based Smoothers;
- One step CG smoothing;
- all Aztec preconditioners as smoothers;
- arbitrary number of Krylov solver iterations (through Aztec);
- Two-stage distributed relaxation hybrid for eddy currents.

As mentioned above, a unique feature of ML is its ability to solve the eddy
current Maxwell Equations. This is done by having the user supply the discrete
null space. This null space is used to develop a special smoother (hybrid
distributed relaxation method) and to develop special intergrid transfers. The
inter-grid transfer satisfy a commuting property such that the coarse grid
discretizations satisfy an exact discrete null space relationship. This solver has
been used in both the time and frequency domain. In the frequency domain,
equivalent real forms are used to address complex arithmetic. In this case, a
special block form the eddy current Maxwell method is used to develop the grid
transfers. In addition, a complex form of the Chebyshev smoother is used as a
relaxation method.

ML is designed to be cooperate with other Trilinos project, and in particular with 
the Aztec-2.1/AztecOO linear solver package developed at
Sandia National Laboratories. However, ML can also be run stand-alone or the user
can write their own functions such as an application specific smoother. 
-->

<!--
\section ml_dev Developers
The ML developers are:
- Ray S. Tuminaro
- Jonathan J. Hu
- Marzio G. Sala
- Michael W. Gee
-->

\section ml_doc Where to find documentation

ML is a large package.  The following documents are suggested for ML users:
- "ML 5.0 Smoothed Aggregation User's Guide", Sandia report SAND2006-2649,
  by M.  Gee, J. Hu, M. Sala, C. Siefert and R. Tuminaro.
  This report introduces how to use ML. The guide is focused
  on smoothed aggregation multilevel methods. (However, ML can also be used for
  geometric multilevel methods.). The guide can be downloaded from the
  <a href="http://software.sandia.gov/Trilinos/packages/ml/documentation.html">documentation</a> page.
- The doxygen documentation provides an up-to-date overview of the C++
  functionalities of ML. ML has an Epetra interface, and can be used to define
  black-box preconditioners for Epetra_RowMatrix's. The doxygen documentation
  covers the ML/Epetra interface, but does NOT cover the C source files.
- A developers' guide is available in the ml/doc subdirectory (Sandia
  report number SAND2004-4821).
- The \ref ml_changelog and \ref ml_readme files.

Probably, the best way to understand ML is to use it. Several examples are
provided in the Trilinos/packages/ml/examples subdirectories. Users are suggested
to compile and run these examples. Often, a copy-and-paste approach is good enough
to start with ML. This is particularly true for the ML/Epetra interface.


\section ml_examples Examples source code

Several examples are distributed within ml. You can browse the source file of the
following examples:
- \ref mlguide_c is the simplest ML (serial) example;
- \ref mlguide_par_c is the parallel counterpart of mlguide.c.
- \ref ml_aztec_simple_c gives an example of the ML/Aztec C interface;
- \ref ml_operator_cpp presents the use of the MultiLevelOperator class
(see also section \ref ml_multileveloperator);
- \ref ml_preconditioner_cpp details the use of ML as a
  black-box preconditionerr (see also section \ref ml_minitutorial
  and section \ref ml_multilevelpreconditioner);
- \ref ml_2level_DD_cpp  describes how to define
  domain decomposition preconditioners using ML.  
- \ref ml_viz_cpp  describes how to visualize the aggregates;
- \ref ml_analyze_cpp shows how ML can be used to analyze the performances of a
  the preconditioner on a given linear system;
- \ref ml_read_maxwell_cpp outlines the use of ML to solve the Maxwell equations.


\section ml_minitutorial Quick introduction to the ML/Epetra interface

To take advantage of the ML/Epetra interface, ML must be configured with the
following options:
- \c --enable-epetra
- \c --enable-teuchos

We suggest enabling the Amesos interface (\c --enable-amesos). Amesos is a
Trilinos package that interfaces with various serial and parallel sparse direct
solvers. Morever, it contains a simple serial sparse direct solver (KLU), that is
quite good for small matrices.


New users interested in the ML/Epetra interface should take a look to the
following classes (both in the ML_Epetra namespace):
- ML_Epetra::MultiLevelPreconditioner (defined in file ml_epetra_preconditioner.h)
- ML_Epetra::MultiLevelOperator  (defined in file ml_epetra_operator.h)
- Function ML_Epetra::SetDefaults() can be used to set the default values.

Detailed examples are reported in:
- \ref ml_preconditioner_cpp
- \ref ml_operator_cpp


\section ml_MLP The ML_Epetra::MultiLevelPreconditioner class

This documentation is targeted to the ML_Epetra::MultiLevelPreconditioner 
class. It is very useful to have a list of the available parameters for a
given option. This can be in obtained from the comments of:
- for smoothers: ML_Epetra::MultiLevelPreconditioner::SetSmoothers()
- for the coarse solver: ML_Epetra::MultiLevelPreconditioner::SetCoarse();
- for default values: ML_Epetra::SetDefaults().


\section ml_mainstruct Main Structures of ML

The following structure are used by ML:
- ML_Struct (aliased simply as ML) contains the main information about the
  ML hierarchy;
- ML_Aggregate_Struct (aliased as ML_Aggregate) contains the main information
  about the aggregates (for smoothed aggregates only)
- ML_Operator_Struct (aliased as ML_Operator) defined the ML's internal matrix
  format;
- classes MultiLevelOperator and MultiLevelPreconditioner should be used to
  define AztecOO preconditioners.

 
\section ml_conversion Conversion utilities from/to Epetra matrices.

ML is bases on a particular (and very flexible) matrix format, defined by the
ML_Operator struct. A set of conversion utilities exists to:
- convert an ML_Operator into an Epetra CrsMatrix with ML_Operator2EpetraCrsMatrix()
- convert (wrap) an Epetra_RowMatrix into an ML_Operator with
  EpetraMatrix2MLMatrix(). This is a light-weight
  conversion, as a suitable wrapper is created. This means that data are still
  stored in the original Epetra_RowMatrix. Functions Epetra_ML_comm_wrapper(),
  Epetra_ML_getrow() and Epetra_ML_matvec() are used to perform the getrow, data
  exchange and matrix-vector product.

All the conversion functions are declared in file ml_epetra_utils.h.


\section ml_amesos ML interface to Amesos 

If configured with options \c --enable-amesos \c --enable-epetra 
\c --enable-teuchos,
ML can take advantage of Amesos to solve the coarse problem. 

Details about the ML/Amesos interface are reported in file ml_amesos_wrap.h.

\note ML supports directly SuperLU (serial version) and SuperLU_DIST
(distributed version). These interfaces are deprecated in favor of the Amesos
interface (although still working).



\section ml_ifpack ML interface to IFPACK

If configured with options \c --enable-ifpack \c --enable-epetra 
\c --enable-teuchos,
ML can use IFPACK to define ILU-type smoothers.

Details about the ML/IFPACK interface are reported in file ml_ifpack_wrap.h.



\section ml_anasazi ML interface to Anasazi

If configured with options \c --enable-anasazi \c --enable-epetra 
\c --enable-teuchos,
ML can use Anasazi for eigenvalue computations.

The user can:
- use Anasazi to estimate the maximum eigenvalue of a given level matrix
 (for smoothed aggregation);
- use Anasazi  to compute the low-convergence modes, and filter them;
- use Anasazi to compute the field-of-values of a non-symmetric operator,
  and use this information to improve smoothed aggregation for highly
  non-symmetric systems.

Details about the ML/Anasazi interface are reported in file ml_anasazi.h,
and in the ML_Anasazi namespace.

\note ML also have an interface to ARPACK and PARPACK. 


\section ml_mlapi_intro Overview of MLAPI

An object-oriented layer based on ML, called MLAPI, can be used to
access most of the ML capabilites in a very way. Click \ref ml_mlapi for more
details.


\section ml_python ML for Python Applications

ML is accessible from Python through the PyTrilinos package. Using PyTrilinos,
ML can be used to create black-box preconditioners based on smoothed
aggregation for both serial and parallel runs, using a standard Python
interpreter.  Please refer to the PyTrilinos <a href="http://software.sandia.gov/Trilinos/packages/pytrilinos/overview.html">homepage</a> for more details.


\section ml_thyra ML/Thyra adapters

Adapters are available for using ML with the Thyra solver components.
See <A HREF="../../thyra/doc/html/index.html"> ML/Thyra adapters. </A>

\section ml_debug Debugging Utilities

It is possible to instruct ML_Epetra::MultiLevelPreconditioner to print out the
process ID, so that one can attach to the desired process. One can proceed as
follows:
- define the environmental variable ML_BREAK_FOR_DEBUGGER (example, in BASH, export
 ML_BREAK_FOR_DEBUGGER=1 ), or create a file called \c ML_debug_now in the
 directory of the executable.
- run the parallel code on a terminal (example, mpirun -np 4 ml_example.exe )
- the code will stop in the first call to ComputePreconditioner(). This may occur
 in the construction phase. Few information about the ID number of each process
 will be showed.
- in another terminal, attach to the desired process.
- insert one character to let the code continue, and debug as required. 

(see also the documentation of method
ML_Epetra::MultiLevelPreconditioner::BreakForDebugger()).

If ML is compiled with -DML_MEM_CHECK, the destruction of
ML_Epetra::MultiLevelPreconditioner() will verify that memory has not been
corrupted, and that no memory leak occurs. Note that this option may be
computationally expensive, and it is not recommended for performance evaluations.

\section ml_changes (Incomplete) History of visible changes

Consult the \ref ml_changelog file. The \ref ml_readme file gives some other
information about ML.

\section ml_copyright Copyright

\verbatim
Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
license for use of this work by or on behalf of the U.S. Government.

This library is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as
published by the Free Software Foundation; either version 2.1 of the
License, or (at your option) any later version.

This library is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
USA
\endverbatim

*/

/*!

\page ml_multilevelpreconditioner Example of use ML_Epetra::MultiLevelPreconditioner

We now report and comment and example of usage of
ML_Epetra::MultiLevelPreconditioner. The source code can be found in
ml_preconditioner.cpp. 

First, we need to include several header files. Note that the example works for
MPI and non-MPI configurations. However, some coarse solver requires MPI (like for
instance \c AMESOS-Superludist and \c AMESOS-Mumps). \c
Trilinos_Util_CrsMatrixGallery.h is required by this example, and not by ML.

\code
#ifdef HAVE_MPI
#include "mpi.h"
#include "Epetra_MpiComm.h"
#else
#include "Epetra_SerialComm.h"
#endif
#include "Epetra_Map.h"
#include "Epetra_SerialDenseVector.h"
#include "Epetra_Vector.h"
#include "Epetra_CrsMatrix.h"
#include "Epetra_LinearProblem.h"
#include "AztecOO.h"
#include "Trilinos_Util_CrsMatrixGallery.h"
#include "ml_include.h"
#include "ml_epetra_preconditioner.h"
\endcode

The following namespace will be used quite often:
\code
using namespace Teuchos;
using namespace Trilinos_Util;
\endcode

We can now start with the \c main() function.  We create the linear problem using the class
\c Trilinos_Util::CrsMatrixGallery.  Several matrix examples are supported; please refer to the
Trilinos tutorial for more details.  Most of the examples using the \c ML_Epetra::MultiLevelPreconditioner
class are based on Epetra_CrsMatrix. Example
\c ml_EpetraVbr.cpp shows how to define a Epetra_VbrMatrix.

\c laplace_2d is a symmetric matrix; an example of non-symmetric
matrices is \c recirc_2d' (advection-diffusion in a box, with
recirculating flow). The number of nodes must be a square number

\code
int main(int argc, char *argv[])
{

#ifdef EPETRA_MPI
  MPI_Init(&argc,&argv);
  Epetra_MpiComm Comm(MPI_COMM_WORLD);
#else
  Epetra_SerialComm Comm;
#endif

  CrsMatrixGallery Gallery("laplace_2d", Comm);
  int nx = 128;;
  Gallery.Set("problem_size", nx*nx);
\endcode

The following methods of CrsMatrixGallery are used to get
 pointers to internally stored Epetra_RowMatrix and Epetra_LinearProblem. Then, as
 we wish to use AztecOO, we need to construct a solver object for this problem.

\code
  Epetra_RowMatrix * A = Gallery.GetMatrix();
  Epetra_LinearProblem * Problem = Gallery.GetLinearProblem();
  AztecOO solver(*Problem);
\endcode

This is the beginning of the ML part. We proceed as follows:
- we create a parameter list for ML options;
- set default values for classical smoothed aggregation;
- overwrite some parameters.  Please refer to the user's guide for more
  information some of the parameters do not differ from their default value,
  Here the smoother is symmetric Gauss-Seidel.  Example file ml_2level_DD.cpp
  shows how to use AZTEC's preconditioners as smoothers
  and they are here reported for the sake of clarity maximum number of levels. 
  We solve the coarse problem with serial direct solver KLU.

\code
  ParameterList MLList;
  ML_Epetra::SetDefaults("SA",MLList);
  MLList.set("max levels",6);
  MLList.set("increasing or decreasing","decreasing");
  MLList.set("aggregation: type", "Uncoupled");
  MLList.set("aggregation: threshold", 0.0);

  MLList.set("smoother: type","Gauss-Seidel");
  MLList.set("smoother: pre or post", "both");

  MLList.set("coarse: type","Amesos_KLU");
  MLList.set("coarse: maximum size",30);
\endcode

Now, we create the preconditioning object.  We suggest to use `new' and
`delete' because the destructor contains some calls to MPI (as required by
ML and possibly Amesos).  This is an issue only if the destructor is
called **after** MPI_Finalize().
Then, we instruct AztecOO to use this preconditioner and solve
with 500 iterations and 1e-12 tolerance.

\code
  ML_Epetra::MultiLevelPreconditioner * MLPrec = new
     ML_Epetra::MultiLevelPreconditioner(A, MLList, true);

  solver.SetPrecOperator(MLPrec);

  Problem->GetLHS()->PutScalar(0.0);
  Problem->GetRHS()->PutScalar(1.0);

  solver.SetAztecOption(AZ_solver, AZ_cg);
  solver.SetAztecOption(AZ_conv, AZ_noscaled);
  solver.SetAztecOption(AZ_output, 1);

  solver.Iterate(500, 1e-8);

  delete MLPrec;
\endcode

At this point, we can compute the true residual, and quit.
\code
  double residual, diff;
  Gallery.ComputeResidual(residual);
  Gallery.ComputeDiffBetweenStartingAndExactSolutions(diff);

  if( Comm.MyPID()==0) {
    cout << "||b-Ax||_2 = " << residual << endl;
    cout << "||x_exact - x||_2 = " << diff << endl;
  }

#ifdef
  EPETRA_MPI MPI_Finalize() ;
#endif

  return 0 ;
}
\endcode

*/

/*! \page ml_multileveloperator Example of use of ML_Epetra::MultiLevelOperator

We now report and comment and example of usage of
ML_Epetra::MultiLevelPreconditioner. The source code can be found in
ml_preconditioner.cpp. 

Trilinos (and hence ML) requires the variable \c HAVE_CONFIG_H to be defined,
either in the Makefile, or in the file itself. We suggest the following:
\code
#ifndef HAVE_CONFIG_H
#define HAVE_CONFIG_H
#endif
\endcode

Then, we need to include several header files. Note that the example works for
MPI and non-MPI configurations. However, some coarse solver requires MPI (like for
instance \c AMESOS-Superludist and \c AMESOS-Mumps). \c
Trilinos_Util_CrsMatrixGallery.h is required by this example, and not by ML.

\code
#include "ml_include.h"
#ifdef HAVE_MPI
#include "mpi.h"
#include "Epetra_MpiComm.h"
#else
#include "Epetra_SerialComm.h"
#endif
#include "Epetra_Map.h"
#include "Epetra_IntVector.h"
#include "Epetra_SerialDenseVector.h"
#include "Epetra_Vector.h"
#include "Epetra_CrsMatrix.h"
#include "Epetra_VbrMatrix.h"
#include "Epetra_LinearProblem.h"
#include "Epetra_Time.h"
#include "AztecOO.h"
#include "ml_epetra_preconditioner.h"
#include "Trilinos_Util_CommandLineParser.h"
#include "Trilinos_Util_CrsMatrixGallery.h"
#include "ml_epetra_utils.h"
#include "ml_epetra_operator.h"
\endcode

\c HAVE_ML_TRIUTILS, and the header files are required by the example, and not
by the ML source. Class Trilinos_Util::CrsMatrixGallery is used to create an
example matrix. This Epetra_CrsMatrix is then converted to an ML_Operator
(heavy-weight conversion).

\note ML accepts Epetra_RowMatrix's; please refer to \ref
ml_preconditioner_cpp.

\code
using namespace ML_Epetra;
using namespace Teuchos;
using namespace Trilinos_Util;

int main(int argc, char *argv[])
{
  
#ifdef EPETRA_MPI
  MPI_Init(&argc,&argv);
  Epetra_MpiComm Comm(MPI_COMM_WORLD);
#else
  Epetra_SerialComm Comm;
#endif
  
  Epetra_Time Time(Comm);
\endcode
We parse the command line, to create the example matrix, get a pointer to this
matrix.
\code
  CommandLineParser CLP(argc,argv);
  CrsMatrixGallery Gallery("", Comm);

  // default values for problem type and size
  if( CLP.Has("-problem_type") == false ) CLP.Add("-problem_type", "laplace_2d" ); 
  if( CLP.Has("-problem_size") == false ) CLP.Add("-problem_size", "100" ); 

  // initialize MatrixGallery object with options specified in the shell
  Gallery.Set(CLP);
  
  // get pointer to the linear system matrix
  Epetra_CrsMatrix * A = Gallery.GetMatrix();

  // get a pointer to the map
  const Epetra_Map * Map = Gallery.GetMap();

  // get a pointer to the linear system problem
  Epetra_LinearProblem * Problem = Gallery.GetLinearProblem();
  
  // Construct a solver object for this problem
  AztecOO solver(*Problem);
\endcode

This is the beginning of the ML part. We need to create an ML_handle, convert
the input matrix into ML_Operator format, create an ML_Aggregate structure
(that will hold the data about the aggregates).

\code
  int nLevels = 10;
  int maxMgLevels = 6;
  ML_Set_PrintLevel(10);
  ML *ml_handle;
  
  ML_Create(&ml_handle, maxMgLevels);

  // convert to epetra matrix, put finest matrix into
  // position maxMgLevels - 1 of the hierarchy
  EpetraMatrix2MLMatrix(ml_handle, maxMgLevels-1, A);
  
  // create an Aggregate object; this will contain information
  // about the aggregation process for each level
  ML_Aggregate *agg_object;
  ML_Aggregate_Create(&agg_object);
\endcode
At this point we select out aggregation scheme (Uncoupled in this case), and
we build the hierarchy.
\code
  ML_Aggregate_Set_CoarsenScheme_Uncoupled(agg_object);
  nLevels = ML_Gen_MGHierarchy_UsingAggregation(ml_handle, maxMgLevels-1,
						ML_DECREASING, agg_object);
\encode

Now, we define the ID of the coarsest level and set up the smoothers. We
suppose to deal with a symmetric problem. We also set a simple coarse solver
-- symmetric Gauss-Seidel.

\code
  int coarsestLevel = maxMgLevels - nLevels;
  
  int nits = 1;
  for(int level = maxMgLevels-1; level > coarsestLevel; level--)
    ML_Gen_Smoother_Cheby(ml_handle, level, ML_BOTH, 30., 3);

  ML_Gen_Smoother_SymGaussSeidel(ml_handle, coarsestLevel, ML_BOTH, 
				 nits, ML_DEFAULT);
 
  // generate the solver
  ML_Gen_Solver(ml_handle, ML_MGV, maxMgLevels-1, coarsestLevel);
 
  // create an Epetra_Operator based on the previously created
  // hierarchy
  MultiLevelOperator MLPrec(ml_handle, Comm, *Map, *Map);
\endcode

This is the end of the ML settings. We just need to instruct AztecOO about the
existence of \c MLPrec.

\code
  solver.SetPrecOperator(&MLPrec);

  solver.SetAztecOption(AZ_solver, AZ_cg_condnum);
  solver.SetAztecOption(AZ_output, 16);

  // solve with AztecOO
  solver.Iterate(500, 1e-5);

#ifdef EPETRA_MPI
  MPI_Finalize() ;
#endif

  return 0 ;
  
}
\endcode

To execute this example,/from the command line, you may try something like that:
\code
$ mpirun -np 4 ./ml_operator.exe -problem_type=laplace_3d 
          -problem_size=1000
\endcode
For more options for Trilinos_Util::CrsMatrixGallery, consult the
Trilinos 4.0 tutorial.

*/

/*! 
\page mlguide_c mlguide.c 
\include mlguide.c
*/

/*!
\page mlguide_par_c mlguide_par.c
\include mlguide_par.c
*/

/*!
\page ml_aztec_simple_c ml_aztec_simple.c
\include ml_aztec_simple.c
*/

/*!
\page ml_operator_cpp ml_operator.cpp
\include ml_operator.cpp
*/

/*!
\page ml_preconditioner_cpp ml_preconditioner.cpp
\include ml_preconditioner.cpp
*/

/*!
\page ml_2level_DD_cpp ml_2level_DD.cpp
\include ml_2level_DD.cpp
*/

/*!
\page ml_viz_cpp ml_viz.cpp
\include ml_viz.cpp
*/

/*!
\page ml_analyze_cpp ml_analyze.cpp
\include ml_analyze.cpp
*/

/*!
\page ml_read_maxwell_cpp ml_read_maxwell.cpp
\include ml_read_maxwell.cpp
*/

/*!
\page ml_changelog ChangeLog
\include ChangeLog-ML
*/

/*!
\page ml_readme README
\include README-ML
*/

/*!
\page ml_blackboard_cpp BlackBoard.cpp
\include Blackboard.cpp
*/

/*!
\page ml_powermethod PowerMethod.cpp
\include PowerMethod.cpp
*/

/*!
\page ml_epetrainterface EpetraInterface.cpp
\include EpetraInterface.cpp
*/

/*!
\page ml_multilevel MultiLevel.cpp
\include MultiLevel.cpp
*/

/*!
\page ml_richardson Richardson.cpp
\include Richardson.cpp
*/

/*!
\page ml_adaptivesa AdaptiveSA.cpp
\include AdaptiveSA.cpp
*/

/*!
\page ml_twolevel TwoLevelDDAdditive.cpp
\include TwoLevelDDAdditive.cpp
*/

/*!
\page ml_mlapi Overview of MLAPI

\section mlapi_tab Table of contents

- \ref mlapi_intro
- \ref mlapi_memory
- \ref mlapi_multivector
- \ref mlapi_prec
- \ref mlapi_epetrainterface


\section mlapi_intro Introduction to MLAPI

The MLAPI are the Application Program Interface of ML. MLAPI defines a
MATLAB-like environment for rapid prototyping of new multilevel
preconditioners, usually of algebraic type. 

All MLAPI objects are defined in the MLAPI namespace. The most important
objects are:
- MLAPI::Space, which defines the data layout;
- MLAPI::Operator, the basic wrapper of ML_Operator and Epetra_RowMatrix objects;
- MLAPI::InverseOperator, which defined smoothers and coarse grid solvers;
- MLAPI::MultiVector, which contains one vector, or a collection of vectors, all 
  sharing the same space.

MLAPI can be used for both serial and parallel computations.



\section mlapi_multivector Use of MultiVector

Class MLAPI::MultiVector contains one or more vectors. The general usage is as
follows:
\code
Space MySpace(128);
MultiVector V;
int NumVectors = 1;
V.Reshape(V, NumVectors);
\endcode
A new vector can be added to the already allocated ones as follows:
\code
V.Add();
\endcode
Equivalently, one vector can be deleted. For example, to delete the second
multivector, one can write
\code
V.Delete(2);
\endcode
meaning that now \c V contains just one vector.


\section mlapi_memory Memory Management

One of the most powerful feature of C and C++
if the capability of allocating memory. Unfortunately, this is also the
area where most bugs are found -- not to mention memory leaks. We have adopted
smart pointers to manage memory.
MLAPI objects should never be allocated using \c new, and therefore never
free them using \c delete. The code will automatically delete memory
when it is no longer referenced by any object. Besides, functions or methods
that need to return MLAPI objects, should always return an instance of the
required object, and not a pointer or a reference.

Let us consider three generic MLAPI objects.
The assignment A = B means the following: all smart pointers contained
by B are copied in A, both A and B point to the
same memory location. However, A and B are not aliases: we can
still write 
\code
B = C
\endcode
meaning that A contains what was contained in
B, and both B and C point to the same memory location. 
Should we need to create a copy of C in B, we will use the
instruction 
\code
B = Duplicate(C)
\endcode
which is instead an expensive operation, as new memory
needs to be allocated, then all elements in C need to be copied in B.



\section mlapi_prec Available Preconditioners

Although MLAPI is design to be a framework for development of new
preconditioners, two classes already defines ready-to-use preconditioners:
- MLAPI::MultiLevelSA is a classical smoothed aggregation preconditioner,
  which roughly behaves like class ML_Epetra::MultiLevel. However, the list
  of supported parameters is remarkably shorter. This class is meant as 
  an example of usage of MLAPI for the definition of smoothed aggregation
  preconditioners;
- MLAPI::MultiLevelAdaptiveSA implements adaptive smoothed aggregation. 
- example \ref ml_twolevel shows how to define a two-level domain
  decomposition preconditioner. This class shows how to define adaptive
  smoothed aggregation preconditioners.

\section mlapi_epetrainterface Interface with Epetra Objects

Any Epetra_RowMatrix derived class can be wrapped as an MLAPI::Operator.
(However, some restrictions apply, please check you Epetra_Map's for more
details.)

An MLAPI::InverseOperator (and therefore preconditioners MLAPI::MultiLevelSA
and MLAPI::MultiLevelAdaptiveSA) can be easily wrapped as an Epetra_Operator
derived class, then used within, for instance, AztecOO. An example is reported
in \ref ml_epetrainterface.
*/

