ESYS13
Revision_
|
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 */