PetscErrorCode SNESFASCycle_Full(SNES snes, Vec X) { PetscErrorCode ierr; Vec F,B; SNES_FAS *fas = (SNES_FAS*)snes->data; PetscBool isFine; SNES next; PetscFunctionBegin; F = snes->vec_func; B = snes->vec_rhs; ierr = SNESFASCycleIsFine(snes,&isFine);CHKERRQ(ierr); ierr = SNESFASCycleGetCorrection(snes,&next);CHKERRQ(ierr); if (isFine) { ierr = SNESFASCycleSetupPhase_Full(snes);CHKERRQ(ierr); } if (fas->full_stage == 0) { /* downsweep */ if (next) { if (fas->level != 1) next->max_its += 1; if (fas->full_downsweep||isFine) {ierr = SNESFASDownSmooth_Private(snes,B,X,F,&snes->norm);CHKERRQ(ierr);} ierr = SNESFASCoarseCorrection(snes,X,F,X);CHKERRQ(ierr); ierr = SNESFASUpSmooth_Private(snes,B,X,F,&snes->norm);CHKERRQ(ierr); if (fas->level != 1) next->max_its -= 1; } else { /* The smoother on the coarse level is the coarse solver */ ierr = SNESFASDownSmooth_Private(snes,B,X,F,&snes->norm);CHKERRQ(ierr); } fas->full_stage = 1; } else if (fas->full_stage == 1) { if (snes->iter == 0) {ierr = SNESFASDownSmooth_Private(snes,B,X,F,&snes->norm);CHKERRQ(ierr);} if (next) { ierr = SNESFASCoarseCorrection(snes,X,F,X);CHKERRQ(ierr); ierr = SNESFASUpSmooth_Private(snes,B,X,F,&snes->norm);CHKERRQ(ierr); } } /* final v-cycle */ if (isFine) { if (next) { ierr = SNESFASCoarseCorrection(snes,X,F,X);CHKERRQ(ierr); ierr = SNESFASUpSmooth_Private(snes,B,X,F,&snes->norm);CHKERRQ(ierr); } } PetscFunctionReturn(0); }
PetscErrorCode SNESFASCycle_Kaskade(SNES snes, Vec X) { PetscErrorCode ierr; Vec F,B; SNES next; PetscFunctionBegin; F = snes->vec_func; B = snes->vec_rhs; ierr = SNESFASCycleGetCorrection(snes,&next);CHKERRQ(ierr); if (next) { ierr = SNESFASCoarseCorrection(snes,X,F,X);CHKERRQ(ierr); ierr = SNESFASUpSmooth_Private(snes,B,X,F,&snes->norm);CHKERRQ(ierr); } else { ierr = SNESFASDownSmooth_Private(snes,B,X,F,&snes->norm);CHKERRQ(ierr); } PetscFunctionReturn(0); }
/* Defines the FAS cycle as: fine problem: F(x) = 0 coarse problem: F^c(x) = b^c b^c = F^c(I^c_fx^f - I^c_fF(x)) correction: x = x + I(x^c - Rx) */ PetscErrorCode SNESFASCycle_Multiplicative(SNES snes, Vec X) { PetscErrorCode ierr; Vec F,B; SNES_FAS *fas = (SNES_FAS *)snes->data; PetscFunctionBegin; F = snes->vec_func; B = snes->vec_rhs; /* pre-smooth -- just update using the pre-smoother */ ierr = SNESFASDownSmooth_Private(snes, B, X, F, &snes->norm);CHKERRQ(ierr); if (fas->level != 0) { ierr = SNESFASCoarseCorrection(snes, X, F, X);CHKERRQ(ierr); ierr = SNESFASUpSmooth_Private(snes, B, X, F, &snes->norm);CHKERRQ(ierr); } PetscFunctionReturn(0); }