void JacobiSmoothFG( VT &sol, const MT &A, 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; const FAMGSparseVector *svsol = sol.GetSparseVectorPtr(); const FAMGSparseVector *svdef = def.GetSparseVectorPtr(); const FAMGSparseBlock *sb = A.GetDiagSparseBlockPtr(); double *solptr, *defptr, *matptr; short nr = sb->Get_nr(); if(nr != sb->Get_nc()) assert(0); if(nr != svsol->Get_n()) assert(0); if(nr != svdef->Get_n()) assert(0); // todo: implement for more general vectors for(short i = 1; i < nr; i++) { if(svsol->Get_comp(i) - svsol->Get_comp(i-1) != 1) assert(0); if(svdef->Get_comp(i) - svdef->Get_comp(i-1) != 1) assert(0); } short sol_off = svsol->Get_comp(0); short def_off = svdef->Get_comp(0); double *decomp = new double[nr*nr]; short *pivotmap = new short[nr]; while(viter(ve)) { if( sol.IsFG(ve) ) { solptr = sol.GetValuePtr(ve)+sol_off; defptr = def.GetValuePtr(ve)+def_off; matptr = A.GetDiagValuePtr(ve); SparseBlockMCopyDense(decomp,sb,matptr); if(LR_Decomp(nr,decomp,pivotmap)) assert(0); if(LR_Solve(nr,decomp,pivotmap,solptr,defptr)) assert(0); } #ifdef USE_UG_DS else { // set coarse components to 0 SparseBlockVSet(svsol,sol.GetValuePtr(ve),0.0); } #endif } delete decomp; delete pivotmap; return; }
void JacobiSmoothFGSimple( VT &sol, const MT &D, 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; const FAMGSparseVector *svsol = sol.GetSparseVectorPtr(); const FAMGSparseVector *svdef = def.GetSparseVectorPtr(); const FAMGSparseBlock *sb = D.GetDiagSparseBlockPtr(); double *solptr, *defptr, *matptr; while(viter(ve)) { if( sol.IsFG(ve) ) { solptr = sol.GetValuePtr(ve); defptr = def.GetValuePtr(ve); matptr = D.GetDiagValuePtr(ve); SparseBlockMVAddProduct(svsol,sb,svdef,solptr,matptr,defptr,1.0); } } return; }