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 Scale( VT &v, double scale ) { // typename is a new C++ keyword! typename VT::Iterator viter(v); typename VT::VectorEntry ve; short ncmp = v.GetSparseVectorPtr()->Get_n(); short *comp = v.GetSparseVectorPtr()->Get_comp(); double *vptr; while(viter(ve)) { vptr = v.GetValuePtr(ve); for(short i = 0; i < ncmp; i++) vptr[comp[i]] *= scale; } }
void VecMinusMatVec( VT &d, const VT &f, const MT &M, const VT &u ) { typename VT::Iterator viter(d); typename VT::VectorEntry row; typename MT::MatrixEntry col; double *dptr, *fptr, *uptr, *mptr; const FAMGSparseVector *svu = u.GetSparseVectorPtr(); const FAMGSparseVector *svf = f.GetSparseVectorPtr(); const FAMGSparseVector *svd = d.GetSparseVectorPtr(); const FAMGSparseBlock *sb = M.GetSparseBlockPtr(); const FAMGSparseBlock *sbd = M.GetDiagSparseBlockPtr(); FAMGSparseVector svsum_d, svsum_o; svsum_d.Product(sbd,svu); svsum_o.Product(sb,svu); double *sum_d = new double[svsum_d.Get_maxcomp()+1]; double *sum_o = new double[svsum_o.Get_maxcomp()+1]; while(viter(row)) { typename MT::Iterator miter(M,row); dptr = d.GetValuePtr(row); fptr = f.GetValuePtr(row); // diagonal miter(col); uptr = u.GetValuePtr(col.dest()); mptr = M.GetValuePtr(col); SparseBlockVSet(&svsum_d,sum_d,0.0); SparseBlockVSet(&svsum_o,sum_o,0.0); SparseBlockMVAddProduct(&svsum_d,sbd,svu,sum_d,mptr,uptr,1.0); while(miter(col)) { uptr = u.GetValuePtr(col.dest()); mptr = M.GetValuePtr(col); SparseBlockMVAddProduct(&svsum_o,sb,svu,sum_o,mptr,uptr,1.0); } SparseBlockVSub(svd,svf,&svsum_o,dptr,fptr,sum_o); SparseBlockVSub(svd,svd,&svsum_d,dptr,dptr,sum_d); } delete sum_d; delete sum_o; }
void AddScaledValue( VT &dest, double scale, const VT &source ) { // not really tesyed // typename is a new C++ keyword! typename VT::Iterator viter(dest); typename VT::VectorEntry ve; short ncmp_d = dest.GetSparseVectorPtr()->Get_n(); short ncmp_s = source.GetSparseVectorPtr()->Get_n(); short *comp_d = dest.GetSparseVectorPtr()->Get_comp(); short *comp_s = source.GetSparseVectorPtr()->Get_comp(); short ncmp; double *vptr_d, *vptr_s; ncmp = Min(ncmp_d,ncmp_s); while(viter(ve)) { vptr_d = dest.GetValuePtr(ve); vptr_s = source.GetValuePtr(ve); for(short i = 0; i < ncmp; i++) vptr_d[comp_d[i]] += scale*vptr_s[comp_s[i]]; } }
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; }