ESYS13  Revision_
Preconditioner.h
Go to the documentation of this file.
00001 
00002 /*******************************************************
00003 *
00004 * Copyright (c) 2003-2012 by University of Queensland
00005 * Earth Systems Science Computational Center (ESSCC)
00006 * http://www.uq.edu.au/esscc
00007 *
00008 * Primary Business: Queensland, Australia
00009 * Licensed under the Open Software License version 3.0
00010 * http://www.opensource.org/licenses/osl-3.0.php
00011 *
00012 *******************************************************/
00013 
00014 
00015 #ifndef INC_PRECS
00016 #define INC_PRECS
00017 
00018 #include "SystemMatrix.h"
00019 #include "performance.h"
00020 #include "BOOMERAMG.h"
00021 #include "MergedSolver.h"
00022 
00023 #define PRECONDITIONER_NO_ERROR 0
00024 #define PRECONDITIONER_MAXITER_REACHED 1
00025 #define PRECONDITIONER_INPUT_ERROR -1
00026 #define PRECONDITIONER_MEMORY_ERROR -9
00027 #define PRECONDITIONER_BREAKDOWN -10
00028 #define PRECONDITIONER_NEGATIVE_NORM_ERROR -11
00029 #define PRECONDITIONER_DIVERGENCE -12
00030 
00031 
00032 #define PASO_AMG_UNDECIDED -1
00033 #define PASO_AMG_IN_F 0
00034 #define PASO_AMG_IN_C 1
00035 
00036 /* GAUSS SEIDEL & Jacobi */
00037 typedef struct Paso_Preconditioner_LocalSmoother {
00038    bool_t Jacobi;
00039    double* diag;
00040    double* buffer;
00041    index_t* pivot;
00042 } Paso_Preconditioner_LocalSmoother;
00043 
00044 typedef struct Paso_Preconditioner_Smoother {
00045    Paso_Preconditioner_LocalSmoother* localSmoother;
00046    bool_t is_local;
00047 } Paso_Preconditioner_Smoother;
00048 
00049 void Paso_Preconditioner_Smoother_free(Paso_Preconditioner_Smoother * in);
00050 void Paso_Preconditioner_LocalSmoother_free(Paso_Preconditioner_LocalSmoother * in);
00051 
00052 
00053 Paso_Preconditioner_Smoother* Paso_Preconditioner_Smoother_alloc(Paso_SystemMatrix * A_p, const bool_t jacobi, const bool_t is_local, const bool_t verbose);
00054 Paso_Preconditioner_LocalSmoother* Paso_Preconditioner_LocalSmoother_alloc(Paso_SparseMatrix * A_p,const bool_t jacobi, const bool_t verbose);
00055 
00056 void Paso_Preconditioner_Smoother_solve(Paso_SystemMatrix* A, Paso_Preconditioner_Smoother * gs, double * x, const double * b, const dim_t sweeps, const bool_t x_is_initial);
00057 void Paso_Preconditioner_LocalSmoother_solve(Paso_SparseMatrix* A, Paso_Preconditioner_LocalSmoother * gs, double * x, const double * b, const dim_t sweeps, const bool_t x_is_initial);
00058 err_t Paso_Preconditioner_Smoother_solve_byTolerance(Paso_SystemMatrix* A, Paso_Preconditioner_Smoother * gs, double * x, const double * b, const double atol, dim_t *sweeps, const bool_t x_is_initial);
00059 
00060 void Paso_Preconditioner_LocalSmoother_Sweep(Paso_SparseMatrix* A, Paso_Preconditioner_LocalSmoother * gs, double * x);
00061 void Paso_Preconditioner_LocalSmoother_Sweep_sequential(Paso_SparseMatrix* A, Paso_Preconditioner_LocalSmoother * gs, double * x);
00062 void Paso_Preconditioner_LocalSmoother_Sweep_tiled(Paso_SparseMatrix* A, Paso_Preconditioner_LocalSmoother * gs, double * x);
00063 void Paso_Preconditioner_LocalSmoother_Sweep_colored(Paso_SparseMatrix* A, Paso_Preconditioner_LocalSmoother * gs, double * x);
00064 
00065 
00066 
00067 /* Local preconditioner */
00068 struct Paso_Preconditioner_AMG {
00069    dim_t level;
00070    Paso_SystemMatrix * A_C;  /* coarse level matrix */
00071    Paso_SystemMatrix * P;   /* prolongation n x n_C*/ 
00072    Paso_SystemMatrix * R;   /* restriction  n_C x n */
00073    
00074    Paso_Preconditioner_Smoother* Smoother;
00075    dim_t post_sweeps;
00076    dim_t pre_sweeps;
00077    dim_t options_smoother;  /* used in direct solver */
00078    bool_t verbose;      /* used in direct solver */
00079    index_t reordering;  /* applied reordering in direct solver */
00080    dim_t refinements;  /* number of refinements in direct solver (typically =0) */
00081    double* r;         /* buffer for residual */
00082    double* x_C;       /* solution of coarse level system */
00083    double* b_C;       /* right hand side of coarse level system */
00084    Paso_MergedSolver* merged_solver; /* used on the coarsest level */
00085    struct Paso_Preconditioner_AMG * AMG_C;
00086 };
00087 typedef struct Paso_Preconditioner_AMG Paso_Preconditioner_AMG;
00088 
00089 void Paso_Preconditioner_AMG_free(Paso_Preconditioner_AMG * in);
00090 Paso_Preconditioner_AMG* Paso_Preconditioner_AMG_alloc(Paso_SystemMatrix * A_p,dim_t level,Paso_Options* options);
00091 void Paso_Preconditioner_AMG_solve(Paso_SystemMatrix* A, Paso_Preconditioner_AMG * amg, double * x, double * b);
00092 void Paso_Preconditioner_AMG_setStrongConnections(Paso_SystemMatrix* A,  dim_t *degree_S, index_t* offset_S, index_t *S, const double theta, const double tau);
00093 void Paso_Preconditioner_AMG_setStrongConnections_Block(Paso_SystemMatrix* A, dim_t *degree_S, index_t* offset_S, index_t *S, const double theta, const double tau);
00094 Paso_SystemMatrix* Paso_Preconditioner_AMG_getProlongation(Paso_SystemMatrix* A_p, const index_t* offset_S, const dim_t* degree_S, const index_t* S, const dim_t n_C, index_t* counter_C, const index_t interpolation_method);
00095 void Paso_Preconditioner_AMG_setClassicProlongation(Paso_SystemMatrix* P, Paso_SystemMatrix* A, const index_t* offset_S, const dim_t* degree_S, const index_t* S,const index_t *counter_C);
00096 void Paso_Preconditioner_AMG_setClassicProlongation_Block(Paso_SystemMatrix* P, Paso_SystemMatrix* A, const index_t* offset_S, const dim_t* degree_S, const index_t* S,const index_t *counter_C);
00097 void Paso_Preconditioner_AMG_setDirectProlongation(Paso_SystemMatrix* P, Paso_SystemMatrix* A, const index_t* offset_S, const dim_t* degree_S, const index_t* S,const index_t *counter_C);
00098 void Paso_Preconditioner_AMG_setDirectProlongation_Block(Paso_SystemMatrix* P, Paso_SystemMatrix* A, const index_t* offset_S, const dim_t* degree_S, const index_t* S,const index_t *counter_C);
00099 double Paso_Preconditioner_AMG_getCoarseLevelSparsity(const Paso_Preconditioner_AMG * in);
00100 dim_t Paso_Preconditioner_AMG_getNumCoarseUnknwons(const Paso_Preconditioner_AMG * in);
00101 index_t Paso_Preconditioner_AMG_getMaxLevel(const Paso_Preconditioner_AMG * in);
00102 void Paso_Preconditioner_AMG_transposeStrongConnections(const dim_t n, const dim_t* degree_S, const index_t* offset_S, const index_t* S, const dim_t nT, dim_t *degree_ST, index_t* offset_ST,index_t* ST);
00103 void Paso_Preconditioner_AMG_CIJPCoarsening(const dim_t n, const dim_t my_n, index_t*split_marker,
00104                         const dim_t* degree_S, const index_t* offset_S, const index_t* S,
00105                         const dim_t* degree_ST, const index_t* offset_ST, const index_t* ST,
00106                         Paso_Connector* col_connector, Paso_Distribution* col_dist);
00107 Paso_SystemMatrix* Paso_Preconditioner_AMG_getRestriction(Paso_SystemMatrix* P);
00108 Paso_SystemMatrix* Paso_Preconditioner_AMG_buildInterpolationOperator(Paso_SystemMatrix* A, Paso_SystemMatrix* P, Paso_SystemMatrix* R);
00109 Paso_SystemMatrix* Paso_Preconditioner_AMG_buildInterpolationOperatorBlock(Paso_SystemMatrix* A, Paso_SystemMatrix* P, Paso_SystemMatrix* R);
00110 Paso_SparseMatrix* Paso_Preconditioner_AMG_mergeSystemMatrix(Paso_SystemMatrix* A);
00111 void Paso_Preconditioner_AMG_mergeSolve(Paso_Preconditioner_AMG* amg);
00112 
00113 /* Local AMG preconditioner */
00114 struct Paso_Preconditioner_LocalAMG {
00115    dim_t level;
00116    Paso_SparseMatrix * A_C;  /* coarse level matrix */
00117    Paso_SparseMatrix * P;   /* prolongation n x n_C*/ 
00118    Paso_SparseMatrix * R;   /* restriction  n_C x n */
00119 
00120    Paso_Preconditioner_LocalSmoother* Smoother;
00121    dim_t post_sweeps;
00122    dim_t pre_sweeps;
00123    index_t reordering;  /* applied reordering in direct solver */
00124    dim_t refinements;  /* number of refinements in direct solver (typically =0) */
00125    double* r;         /* buffer for residual */
00126    double* x_C;       /* solution of coarse level system */
00127    double* b_C;       /* right hand side of coarse level system */
00128    struct Paso_Preconditioner_LocalAMG * AMG_C;
00129 };
00130 typedef struct Paso_Preconditioner_LocalAMG Paso_Preconditioner_LocalAMG;
00131 
00132 void Paso_Preconditioner_LocalAMG_free(Paso_Preconditioner_LocalAMG * in);
00133 Paso_Preconditioner_LocalAMG* Paso_Preconditioner_LocalAMG_alloc(Paso_SparseMatrix * A_p,dim_t level,Paso_Options* options);
00134 void Paso_Preconditioner_LocalAMG_solve(Paso_SparseMatrix* A, Paso_Preconditioner_LocalAMG * amg, double * x, double * b);
00135 
00136 void Paso_Preconditioner_LocalAMG_RungeStuebenSearch(const dim_t n, const index_t* offset, const dim_t* degree, const index_t* S, index_t*split_marker, const bool_t usePanel);
00137 void Paso_Preconditioner_LocalAMG_setStrongConnections_Block(Paso_SparseMatrix* A, dim_t *degree, index_t *S, const double theta, const double tau);
00138 void Paso_Preconditioner_LocalAMG_setStrongConnections(Paso_SparseMatrix* A, dim_t *degree, index_t *S, const double theta, const double tau);
00139 Paso_SparseMatrix* Paso_Preconditioner_LocalAMG_getProlongation(Paso_SparseMatrix* A_p, const index_t* offset_S, const dim_t* degree_S, const index_t* S, const dim_t n_C, const index_t* counter_C, const index_t interpolation_method);
00140 void Paso_Preconditioner_LocalAMG_setDirectProlongation_Block(Paso_SparseMatrix* P_p, const Paso_SparseMatrix* A_p, const index_t *counter_C);
00141 void Paso_Preconditioner_LocalAMG_setDirectProlongation(Paso_SparseMatrix* P_p, const Paso_SparseMatrix* A_p, const index_t *counter_C);
00142 void Paso_Preconditioner_LocalAMG_setClassicProlongation(Paso_SparseMatrix* P_p, Paso_SparseMatrix* A_p, const index_t* offset_S, const dim_t* degree_S, const index_t* S, const index_t *counter_C);
00143 void Paso_Preconditioner_LocalAMG_setClassicProlongation_Block(Paso_SparseMatrix* P_p, Paso_SparseMatrix* A_p, const index_t* offset_S, const dim_t* degree_S, const index_t* S, const index_t *counter_C);
00144 index_t Paso_Preconditioner_LocalAMG_getMaxLevel(const Paso_Preconditioner_LocalAMG * in);
00145 double Paso_Preconditioner_LocalAMG_getCoarseLevelSparsity(const Paso_Preconditioner_LocalAMG * in);
00146 dim_t Paso_Preconditioner_LocalAMG_getNumCoarseUnknwons(const Paso_Preconditioner_LocalAMG * in);
00147 void Paso_Preconditioner_LocalAMG_enforceFFConnectivity(const dim_t n, const index_t* offset_S, const dim_t* degree_S, const index_t* S, index_t*split_marker);
00148 
00149 
00150 struct Paso_Preconditioner_BoomerAMG
00151 {
00152   Paso_BOOMERAMG_Handler* pt;
00153 };
00154 typedef struct Paso_Preconditioner_BoomerAMG Paso_Preconditioner_BoomerAMG;
00155 void Paso_Preconditioner_BoomerAMG_free(Paso_Preconditioner_BoomerAMG * in);
00156 Paso_Preconditioner_BoomerAMG* Paso_Preconditioner_BoomerAMG_alloc(Paso_SystemMatrix * A_p,Paso_Options* options);
00157 void Paso_Preconditioner_BoomerAMG_solve(Paso_SystemMatrix* A, Paso_Preconditioner_BoomerAMG * amg, double * x, double * b);
00158 
00159 
00160 struct Paso_Preconditioner_AMG_Root 
00161 {
00162   bool_t is_local;
00163   Paso_Preconditioner_AMG* amg;
00164   Paso_Preconditioner_LocalAMG* localamg;
00165   Paso_Preconditioner_BoomerAMG* boomeramg;
00166   dim_t sweeps;
00167   Paso_Preconditioner_Smoother* amgsubstitute;
00168 };
00169 typedef struct Paso_Preconditioner_AMG_Root Paso_Preconditioner_AMG_Root;
00170 
00171 Paso_Preconditioner_AMG_Root* Paso_Preconditioner_AMG_Root_alloc(Paso_SystemMatrix *A, Paso_Options* options);
00172 void Paso_Preconditioner_AMG_Root_free(Paso_Preconditioner_AMG_Root * in);
00173 void Paso_Preconditioner_AMG_Root_solve(Paso_SystemMatrix* A, Paso_Preconditioner_AMG_Root * amg, double * x, double * b);
00174 
00175 /*===============================================*/
00176 /* ILU preconditioner */
00177 struct Paso_Solver_ILU {
00178   double* factors;
00179 };
00180 typedef struct Paso_Solver_ILU Paso_Solver_ILU;
00181 
00182 
00183 
00184 /* RILU preconditioner */
00185 struct Paso_Solver_RILU {
00186   dim_t n;
00187   dim_t n_block;
00188   dim_t n_F;
00189   dim_t n_C;
00190   double* inv_A_FF;
00191   index_t* A_FF_pivot;
00192   Paso_SparseMatrix * A_FC;
00193   Paso_SparseMatrix * A_CF;
00194   index_t* rows_in_F;
00195   index_t* rows_in_C;
00196   index_t* mask_F;
00197   index_t* mask_C;
00198   double* x_F;
00199   double* b_F;
00200   double* x_C;
00201   double* b_C;
00202   struct Paso_Solver_RILU * RILU_of_Schur;
00203 };
00204 typedef struct Paso_Solver_RILU Paso_Solver_RILU;
00205 
00206 
00207 
00208 /* general preconditioner interface */
00209 
00210 typedef struct Paso_Preconditioner {
00211   dim_t type;
00212   dim_t sweeps;
00213   /* jacobi preconditioner */
00214   Paso_Preconditioner_Smoother* jacobi;
00215   /* Gauss-Seidel preconditioner */
00216   Paso_Preconditioner_Smoother* gs;  
00217   /* amg preconditioner */
00218   Paso_Preconditioner_AMG_Root *amg;
00219   
00220   /* ilu preconditioner */
00221   Paso_Solver_ILU* ilu;
00222   /* rilu preconditioner */
00223   Paso_Solver_RILU* rilu;
00224   
00225 } Paso_Preconditioner;
00226 
00227 void Paso_Preconditioner_free(Paso_Preconditioner*);
00228 Paso_Preconditioner* Paso_Preconditioner_alloc(Paso_SystemMatrix* A,Paso_Options* options);
00229 void Paso_Preconditioner_solve(Paso_Preconditioner* prec, Paso_SystemMatrix* A,double*,double*);
00230 
00231 
00232 /*******************************************/
00233 void Paso_Solver_ILU_free(Paso_Solver_ILU * in);
00234 Paso_Solver_ILU* Paso_Solver_getILU(Paso_SparseMatrix * A_p,bool_t verbose);
00235 void Paso_Solver_solveILU(Paso_SparseMatrix * A, Paso_Solver_ILU * ilu, double * x, const double * b);
00236 
00237 void Paso_Solver_RILU_free(Paso_Solver_RILU * in);
00238 Paso_Solver_RILU* Paso_Solver_getRILU(Paso_SparseMatrix * A_p,bool_t verbose);
00239 void Paso_Solver_solveRILU(Paso_Solver_RILU * rilu, double * x, double * b);
00240 
00241 void Paso_Solver_updateIncompleteSchurComplement(Paso_SparseMatrix* A_CC, Paso_SparseMatrix *A_CF,double* invA_FF,index_t* A_FF_pivot, Paso_SparseMatrix *A_FC);
00242 
00243 
00244 #endif /* #ifndef INC_PRECS */