PetscErrorCode SNESFASCycleSetupPhase_Full(SNES snes) { SNES next; SNES_FAS *fas = (SNES_FAS*)snes->data; PetscBool isFine; PetscErrorCode ierr; PetscFunctionBegin; /* pre-smooth -- just update using the pre-smoother */ ierr = SNESFASCycleIsFine(snes,&isFine);CHKERRQ(ierr); ierr = SNESFASCycleGetCorrection(snes,&next);CHKERRQ(ierr); fas->full_stage = 0; if (next) {ierr = SNESFASCycleSetupPhase_Full(next);CHKERRQ(ierr);} PetscFunctionReturn(0); }
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); }