void SGSSmoother( VT &sol, const MT &M, VT &def ) // backward Gauss-Seidel // result in sol_vec; def_vec: correct defect before call, after call destroyed { typename VT::Iterator viter(def); typename VT::RevIterator vReviter(def); typename VT::VectorEntry row, col; typename MT::MatrixEntry me; register double sum, diag; int row_index; /* symmetric Gauss-Seidel */ while(viter(row)) { typename MT::Iterator miter(M,row); row_index = row.GetIndex(); sum = def[row]; miter(me); diag = M[me]; while(miter(me)) { col = me.dest(); if( col.GetIndex() < row_index ) sum -= M[me] * def[col]; } def[row] = sum / diag; } viter.reset(); while(viter(row)) def[row] *= M.DiagValue(row); while(vReviter(row)) { typename MT::Iterator miter(M,row); row_index = row.GetIndex(); sum = def[row]; miter(me); diag = M[me]; while(miter(me)) { col = me.dest(); if( col.GetIndex() > row_index ) sum -= M[me] * def[col]; } def[row] = sum / diag; } sol += def; // update solution return; }
void JacobiSmoother( VT &sol, const MT &M, const VT &def ) // result in sol_vec; def_vec: correct defect before call, after call destroyed { typename VT::Iterator viter(sol); typename VT::VectorEntry ve; while(viter(ve)) sol[ve] += def[ve] / M.DiagValue(ve); return; }
void JacobiSmoothFG( VT &sol, const MT &M, const VT &def ) // changes only the fine unknowns // result in sol_vec; def_vec: correct defect before call, after call destroyed { typename VT::Iterator viter(sol); typename VT::VectorEntry ve; #ifdef USE_UG_DS while(viter(ve)) if( sol.IsFG(ve) ) sol[ve] = def[ve] / M.DiagValue(ve); else sol[ve] = 0; // init other components #else while(viter(ve)) if( sol.IsFG(ve) ) sol[ve] += def[ve] / M.DiagValue(ve); #endif return; }
void dampedJacobiSmoother( VT &sol, const MT &M, const VT &def ) // result in sol_vec; def_vec: correct defect before call, after call destroyed { static const double omega = 2.0/3.0; typename VT::Iterator viter(sol); typename VT::VectorEntry ve; while(viter(ve)) sol[ve] += omega * def[ve] / M.DiagValue(ve); return; }