// this preconditioner first initializes phihat to (IA)phihat = rhshat // (diagonization of L -- A is the matrix version of L) // then smooths with a couple of passes of levelGSRB void VCAMRPoissonOp2::preCond(LevelData<FArrayBox>& a_phi, const LevelData<FArrayBox>& a_rhs) { CH_TIME("VCAMRPoissonOp2::preCond"); // diagonal term of this operator in: // // alpha * a(i) // + beta * sum_over_dir (b(i-1/2*e_dir) + b(i+1/2*e_dir)) / (dx*dx) // // The inverse of this is our initial multiplier. int ncomp = a_phi.nComp(); CH_assert(m_lambda.isDefined()); CH_assert(a_rhs.nComp() == ncomp); CH_assert(m_bCoef->nComp() == ncomp); // Recompute the relaxation coefficient if needed. resetLambda(); // don't need to use a Copier -- plain copy will do DataIterator dit = a_phi.dataIterator(); for (dit.begin(); dit.ok(); ++dit) { // also need to average and sum face-centered bCoefs to cell-centers Box gridBox = a_rhs[dit].box(); // approximate inverse a_phi[dit].copy(a_rhs[dit]); a_phi[dit].mult(m_lambda[dit], gridBox, 0, 0, ncomp); } relax(a_phi, a_rhs, 2); }
// Compute the reciprocal of the diagonal entry of the operator matrix void VCAMRPoissonOp2::computeLambda() { CH_TIME("VCAMRPoissonOp2::computeLambda"); CH_assert(!m_lambda.isDefined()); // Define lambda m_lambda.define(m_aCoef->disjointBoxLayout(),m_aCoef->nComp()); resetLambda(); }
void VCAMRPoissonOp2::levelJacobi(LevelData<FArrayBox>& a_phi, const LevelData<FArrayBox>& a_rhs) { CH_TIME("VCAMRPoissonOp2::levelJacobi"); // Recompute the relaxation coefficient if needed. resetLambda(); LevelData<FArrayBox> resid; create(resid, a_rhs); // Get the residual residual(resid,a_phi,a_rhs,true); // Multiply by the weights DataIterator dit = m_lambda.dataIterator(); for (dit.begin(); dit.ok(); ++dit) { resid[dit].mult(m_lambda[dit]); } // Do the Jacobi relaxation incr(a_phi, resid, 0.5); }
void VCAMRPoissonOp2::looseGSRB(LevelData<FArrayBox>& a_phi, const LevelData<FArrayBox>& a_rhs) { CH_TIME("VCAMRPoissonOp2::looseGSRB"); #if 1 MayDay::Abort("VCAMRPoissonOp2::looseGSRB - Not implemented"); #else // This implementation converges at half the rate of "levelGSRB" in // multigrid solves CH_assert(a_phi.isDefined()); CH_assert(a_rhs.isDefined()); CH_assert(a_phi.ghostVect() >= IntVect::Unit); CH_assert(a_phi.nComp() == a_rhs.nComp()); // Recompute the relaxation coefficient if needed. resetLambda(); const DisjointBoxLayout& dbl = a_phi.disjointBoxLayout(); DataIterator dit = a_phi.dataIterator(); // fill in intersection of ghostcells and a_phi's boxes { CH_TIME("VCAMRPoissonOp2::looseGSRB::homogeneousCFInterp"); homogeneousCFInterp(a_phi); } { CH_TIME("VCAMRPoissonOp2::looseGSRB::exchange"); a_phi.exchange(a_phi.interval(), m_exchangeCopier); } // now step through grids... for (dit.begin(); dit.ok(); ++dit) { // invoke physical BC's where necessary { CH_TIME("VCAMRPoissonOp2::looseGSRB::BCs"); m_bc(a_phi[dit], dbl[dit()], m_domain, m_dx, true); } const Box& region = dbl.get(dit()); const FluxBox& thisBCoef = (*m_bCoef)[dit]; int whichPass = 0; #if CH_SPACEDIM == 1 FORT_GSRBHELMHOLTZVC1D #elif CH_SPACEDIM == 2 FORT_GSRBHELMHOLTZVC2D #elif CH_SPACEDIM == 3 FORT_GSRBHELMHOLTZVC3D #else This_will_not_compile! #endif (CHF_FRA(a_phi[dit]), CHF_CONST_FRA(a_rhs[dit]), CHF_BOX(region), CHF_CONST_REAL(m_dx), CHF_CONST_REAL(m_alpha), CHF_CONST_FRA((*m_aCoef)[dit]), CHF_CONST_REAL(m_beta), #if CH_SPACEDIM >= 1 CHF_CONST_FRA(thisBCoef[0]), #endif #if CH_SPACEDIM >= 2 CHF_CONST_FRA(thisBCoef[1]), #endif #if CH_SPACEDIM >= 3 CHF_CONST_FRA(thisBCoef[2]), #endif #if CH_SPACEDIM >= 4 This_will_not_compile! #endif CHF_CONST_FRA(m_lambda[dit]), CHF_CONST_INT(whichPass)); whichPass = 1; #if CH_SPACEDIM == 1 FORT_GSRBHELMHOLTZVC1D #elif CH_SPACEDIM == 2 FORT_GSRBHELMHOLTZVC2D #elif CH_SPACEDIM == 3 FORT_GSRBHELMHOLTZVC3D #else This_will_not_compile! #endif (CHF_FRA(a_phi[dit]), CHF_CONST_FRA(a_rhs[dit]), CHF_BOX(region), CHF_CONST_REAL(m_dx), CHF_CONST_REAL(m_alpha), CHF_CONST_FRA((*m_aCoef)[dit]), CHF_CONST_REAL(m_beta), #if CH_SPACEDIM >= 1 CHF_CONST_FRA(thisBCoef[0]), #endif #if CH_SPACEDIM >= 2 CHF_CONST_FRA(thisBCoef[1]), #endif #if CH_SPACEDIM >= 3 CHF_CONST_FRA(thisBCoef[2]), #endif #if CH_SPACEDIM >= 4 This_will_not_compile! #endif CHF_CONST_FRA(m_lambda[dit]), CHF_CONST_INT(whichPass)); } // end loop through grids #endif }
/******************************************************************************* * clearLambda - sets all elements of lambda to zero * * INPUTS: double ***transition_matrix - pointer to lambda * int num_haplotypes * int num_snps * * RETURNS: void * * ASSUMES: * * EFFECTS: modifies lambda * * ERROR CONDITIONS: * * COMMENTS: * ******************************************************************************/ void clearLambda(double ***transition_matrix, int num_haplotypes, int num_snps) { resetLambda(transition_matrix, num_haplotypes, num_snps, 0.0); }