1a7b5fb5fSBarry Smith #include <../src/snes/impls/fas/fasimpls.h> /*I "petscsnes.h" I*/ 2ab8d36c9SPeter Brune 3ab8d36c9SPeter Brune 4ab8d36c9SPeter Brune /* -------------- functions called on the fine level -------------- */ 5ab8d36c9SPeter Brune 6ab8d36c9SPeter Brune /*@ 7ab8d36c9SPeter Brune SNESFASSetType - Sets the update and correction type used for FAS. 8ab8d36c9SPeter Brune 9ab8d36c9SPeter Brune Logically Collective 10ab8d36c9SPeter Brune 11ab8d36c9SPeter Brune Input Parameters: 12583a1250SSatish Balay + snes - FAS context 1334d65b3cSPeter Brune - fastype - SNES_FAS_ADDITIVE, SNES_FAS_MULTIPLICATIVE, SNES_FAS_FULL, or SNES_FAS_KASKADE 14583a1250SSatish Balay 15583a1250SSatish Balay Level: intermediate 16ab8d36c9SPeter Brune 17ab8d36c9SPeter Brune .seealso: PCMGSetType() 18ab8d36c9SPeter Brune @*/ 19ab8d36c9SPeter Brune PetscErrorCode SNESFASSetType(SNES snes,SNESFASType fastype) 20ab8d36c9SPeter Brune { 21f833ba53SLisandro Dalcin SNES_FAS *fas; 22ab8d36c9SPeter Brune PetscErrorCode ierr; 2322d28d08SBarry Smith 24ab8d36c9SPeter Brune PetscFunctionBegin; 25f833ba53SLisandro Dalcin PetscValidHeaderSpecificType(snes,SNES_CLASSID,1,SNESFAS); 26ab8d36c9SPeter Brune PetscValidLogicalCollectiveEnum(snes,fastype,2); 27f833ba53SLisandro Dalcin fas = (SNES_FAS*)snes->data; 28ab8d36c9SPeter Brune fas->fastype = fastype; 2922d28d08SBarry Smith if (fas->next) { 3022d28d08SBarry Smith ierr = SNESFASSetType(fas->next, fastype);CHKERRQ(ierr); 3122d28d08SBarry Smith } 32ab8d36c9SPeter Brune PetscFunctionReturn(0); 33ab8d36c9SPeter Brune } 34ab8d36c9SPeter Brune 35ab8d36c9SPeter Brune 36ab8d36c9SPeter Brune /*@ 37ab8d36c9SPeter Brune SNESFASGetType - Sets the update and correction type used for FAS. 38ab8d36c9SPeter Brune 39ab8d36c9SPeter Brune Logically Collective 40ab8d36c9SPeter Brune 41ab8d36c9SPeter Brune Input Parameters: 42ab8d36c9SPeter Brune . snes - FAS context 43ab8d36c9SPeter Brune 44ab8d36c9SPeter Brune Output Parameters: 45ab8d36c9SPeter Brune . fastype - SNES_FAS_ADDITIVE or SNES_FAS_MULTIPLICATIVE 46ab8d36c9SPeter Brune 47583a1250SSatish Balay Level: intermediate 48583a1250SSatish Balay 49ab8d36c9SPeter Brune .seealso: PCMGSetType() 50ab8d36c9SPeter Brune @*/ 51ab8d36c9SPeter Brune PetscErrorCode SNESFASGetType(SNES snes,SNESFASType *fastype) 52ab8d36c9SPeter Brune { 53f833ba53SLisandro Dalcin SNES_FAS *fas; 54ab8d36c9SPeter Brune 55ab8d36c9SPeter Brune PetscFunctionBegin; 56f833ba53SLisandro Dalcin PetscValidHeaderSpecificType(snes,SNES_CLASSID,1,SNESFAS); 57ab8d36c9SPeter Brune PetscValidPointer(fastype, 2); 58f833ba53SLisandro Dalcin fas = (SNES_FAS*)snes->data; 59ab8d36c9SPeter Brune *fastype = fas->fastype; 60ab8d36c9SPeter Brune PetscFunctionReturn(0); 61ab8d36c9SPeter Brune } 62ab8d36c9SPeter Brune 63ab8d36c9SPeter Brune /*@C 64ab8d36c9SPeter Brune SNESFASSetLevels - Sets the number of levels to use with FAS. 65ab8d36c9SPeter Brune Must be called before any other FAS routine. 66ab8d36c9SPeter Brune 67ab8d36c9SPeter Brune Input Parameters: 68ab8d36c9SPeter Brune + snes - the snes context 69ab8d36c9SPeter Brune . levels - the number of levels 70ab8d36c9SPeter Brune - comms - optional communicators for each level; this is to allow solving the coarser 712bf68e3eSBarry Smith problems on smaller sets of processors. 72ab8d36c9SPeter Brune 73ab8d36c9SPeter Brune Level: intermediate 74ab8d36c9SPeter Brune 75ab8d36c9SPeter Brune Notes: 76ab8d36c9SPeter Brune If the number of levels is one then the multigrid uses the -fas_levels prefix 77ab8d36c9SPeter Brune for setting the level options rather than the -fas_coarse prefix. 78ab8d36c9SPeter Brune 79ab8d36c9SPeter Brune .seealso: SNESFASGetLevels() 80ab8d36c9SPeter Brune @*/ 8122d28d08SBarry Smith PetscErrorCode SNESFASSetLevels(SNES snes, PetscInt levels, MPI_Comm *comms) 8222d28d08SBarry Smith { 83ab8d36c9SPeter Brune PetscErrorCode ierr; 84ab8d36c9SPeter Brune PetscInt i; 85ab8d36c9SPeter Brune const char *optionsprefix; 86ab8d36c9SPeter Brune char tprefix[128]; 87f833ba53SLisandro Dalcin SNES_FAS *fas; 88ab8d36c9SPeter Brune SNES prevsnes; 89ab8d36c9SPeter Brune MPI_Comm comm; 9022d28d08SBarry Smith 91ab8d36c9SPeter Brune PetscFunctionBegin; 92f833ba53SLisandro Dalcin PetscValidHeaderSpecificType(snes,SNES_CLASSID,1,SNESFAS); 93f833ba53SLisandro Dalcin fas = (SNES_FAS*)snes->data; 94ce94432eSBarry Smith ierr = PetscObjectGetComm((PetscObject)snes,&comm);CHKERRQ(ierr); 95ab8d36c9SPeter Brune if (levels == fas->levels) { 9622d28d08SBarry Smith if (!comms) PetscFunctionReturn(0); 97ab8d36c9SPeter Brune } 98ab8d36c9SPeter Brune /* user has changed the number of levels; reset */ 99f833ba53SLisandro Dalcin ierr = (*snes->ops->reset)(snes);CHKERRQ(ierr); 100ab8d36c9SPeter Brune /* destroy any coarser levels if necessary */ 101f833ba53SLisandro Dalcin ierr = SNESDestroy(&fas->next);CHKERRQ(ierr); 1020298fd71SBarry Smith fas->next = NULL; 1030298fd71SBarry Smith fas->previous = NULL; 104ab8d36c9SPeter Brune prevsnes = snes; 105ab8d36c9SPeter Brune /* setup the finest level */ 106ab8d36c9SPeter Brune ierr = SNESGetOptionsPrefix(snes, &optionsprefix);CHKERRQ(ierr); 107ab83eea4SMatthew G. Knepley ierr = PetscObjectComposedDataSetInt((PetscObject) snes, PetscMGLevelId, levels-1);CHKERRQ(ierr); 108ab8d36c9SPeter Brune for (i = levels - 1; i >= 0; i--) { 109ab8d36c9SPeter Brune if (comms) comm = comms[i]; 110ab8d36c9SPeter Brune fas->level = i; 111ab8d36c9SPeter Brune fas->levels = levels; 112ab8d36c9SPeter Brune fas->fine = snes; 1130298fd71SBarry Smith fas->next = NULL; 114ab8d36c9SPeter Brune if (i > 0) { 115ab8d36c9SPeter Brune ierr = SNESCreate(comm, &fas->next);CHKERRQ(ierr); 116e964f0dbSPeter Brune ierr = SNESGetOptionsPrefix(fas->fine, &optionsprefix);CHKERRQ(ierr); 117f833ba53SLisandro Dalcin ierr = PetscSNPrintf(tprefix,sizeof(tprefix),"fas_levels_%d_cycle_",(int)fas->level);CHKERRQ(ierr); 118ab8d36c9SPeter Brune ierr = SNESAppendOptionsPrefix(fas->next,optionsprefix);CHKERRQ(ierr); 119e964f0dbSPeter Brune ierr = SNESAppendOptionsPrefix(fas->next,tprefix);CHKERRQ(ierr); 120ab8d36c9SPeter Brune ierr = SNESSetType(fas->next, SNESFAS);CHKERRQ(ierr); 121ab8d36c9SPeter Brune ierr = SNESSetTolerances(fas->next, fas->next->abstol, fas->next->rtol, fas->next->stol, fas->n_cycles, fas->next->max_funcs);CHKERRQ(ierr); 122ab8d36c9SPeter Brune ierr = PetscObjectIncrementTabLevel((PetscObject)fas->next, (PetscObject)snes, levels - i);CHKERRQ(ierr); 123ab83eea4SMatthew G. Knepley ierr = PetscObjectComposedDataSetInt((PetscObject) fas->next, PetscMGLevelId, i-1);CHKERRQ(ierr); 1241aa26658SKarl Rupp 125ab8d36c9SPeter Brune ((SNES_FAS*)fas->next->data)->previous = prevsnes; 1261aa26658SKarl Rupp 127ab8d36c9SPeter Brune prevsnes = fas->next; 128ab8d36c9SPeter Brune fas = (SNES_FAS*)prevsnes->data; 129ab8d36c9SPeter Brune } 130ab8d36c9SPeter Brune } 131ab8d36c9SPeter Brune PetscFunctionReturn(0); 132ab8d36c9SPeter Brune } 133ab8d36c9SPeter Brune 134ab8d36c9SPeter Brune 135ab8d36c9SPeter Brune /*@ 136ab8d36c9SPeter Brune SNESFASGetLevels - Gets the number of levels in a FAS, including fine and coarse grids 137ab8d36c9SPeter Brune 138ab8d36c9SPeter Brune Input Parameter: 139ab8d36c9SPeter Brune . snes - the nonlinear solver context 140ab8d36c9SPeter Brune 141ab8d36c9SPeter Brune Output parameter: 142ab8d36c9SPeter Brune . levels - the number of levels 143ab8d36c9SPeter Brune 144ab8d36c9SPeter Brune Level: advanced 145ab8d36c9SPeter Brune 146ab8d36c9SPeter Brune .seealso: SNESFASSetLevels(), PCMGGetLevels() 147ab8d36c9SPeter Brune @*/ 14822d28d08SBarry Smith PetscErrorCode SNESFASGetLevels(SNES snes, PetscInt *levels) 14922d28d08SBarry Smith { 150f833ba53SLisandro Dalcin SNES_FAS *fas; 1515fd66863SKarl Rupp 152ab8d36c9SPeter Brune PetscFunctionBegin; 153f833ba53SLisandro Dalcin PetscValidHeaderSpecificType(snes,SNES_CLASSID,1,SNESFAS); 154f833ba53SLisandro Dalcin PetscValidIntPointer(levels,3); 155f833ba53SLisandro Dalcin fas = (SNES_FAS*)snes->data; 156ab8d36c9SPeter Brune *levels = fas->levels; 157ab8d36c9SPeter Brune PetscFunctionReturn(0); 158ab8d36c9SPeter Brune } 159ab8d36c9SPeter Brune 160ab8d36c9SPeter Brune 161ab8d36c9SPeter Brune /*@ 162ab8d36c9SPeter Brune SNESFASGetCycleSNES - Gets the SNES corresponding to a particular 163ab8d36c9SPeter Brune level of the FAS hierarchy. 164ab8d36c9SPeter Brune 165ab8d36c9SPeter Brune Input Parameters: 166ab8d36c9SPeter Brune + snes - the multigrid context 167ab8d36c9SPeter Brune level - the level to get 168ab8d36c9SPeter Brune - lsnes - whether to use the nonlinear smoother or not 169ab8d36c9SPeter Brune 170ab8d36c9SPeter Brune Level: advanced 171ab8d36c9SPeter Brune 172ab8d36c9SPeter Brune .seealso: SNESFASSetLevels(), SNESFASGetLevels() 173ab8d36c9SPeter Brune @*/ 17422d28d08SBarry Smith PetscErrorCode SNESFASGetCycleSNES(SNES snes,PetscInt level,SNES *lsnes) 17522d28d08SBarry Smith { 176f833ba53SLisandro Dalcin SNES_FAS *fas; 177ab8d36c9SPeter Brune PetscInt i; 178ab8d36c9SPeter Brune 179ab8d36c9SPeter Brune PetscFunctionBegin; 180f833ba53SLisandro Dalcin PetscValidHeaderSpecificType(snes,SNES_CLASSID,1,SNESFAS); 181f833ba53SLisandro Dalcin PetscValidPointer(lsnes,3); 182f833ba53SLisandro Dalcin fas = (SNES_FAS*)snes->data; 183ce94432eSBarry Smith if (level > fas->levels-1) SETERRQ2(PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_OUTOFRANGE,"Requested level %D from SNESFAS containing %D levels",level,fas->levels); 184ce94432eSBarry Smith if (fas->level != fas->levels - 1) SETERRQ2(PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_OUTOFRANGE,"SNESFASGetCycleSNES may only be called on the finest-level SNES.",level,fas->level); 185ab8d36c9SPeter Brune 186ab8d36c9SPeter Brune *lsnes = snes; 187ab8d36c9SPeter Brune for (i = fas->level; i > level; i--) { 188ab8d36c9SPeter Brune *lsnes = fas->next; 189ab8d36c9SPeter Brune fas = (SNES_FAS*)(*lsnes)->data; 190ab8d36c9SPeter Brune } 191ce94432eSBarry Smith if (fas->level != level) SETERRQ(PetscObjectComm((PetscObject)snes),PETSC_ERR_PLIB,"SNESFAS level hierarchy corrupt"); 192ab8d36c9SPeter Brune PetscFunctionReturn(0); 193ab8d36c9SPeter Brune } 194ab8d36c9SPeter Brune 195ab8d36c9SPeter Brune /*@ 196ab8d36c9SPeter Brune SNESFASSetNumberSmoothUp - Sets the number of post-smoothing steps to 197ab8d36c9SPeter Brune use on all levels. 198ab8d36c9SPeter Brune 199ab8d36c9SPeter Brune Logically Collective on SNES 200ab8d36c9SPeter Brune 201ab8d36c9SPeter Brune Input Parameters: 202ab8d36c9SPeter Brune + snes - the multigrid context 203ab8d36c9SPeter Brune - n - the number of smoothing steps 204ab8d36c9SPeter Brune 205ab8d36c9SPeter Brune Options Database Key: 206ab8d36c9SPeter Brune . -snes_fas_smoothup <n> - Sets number of pre-smoothing steps 207ab8d36c9SPeter Brune 208ab8d36c9SPeter Brune Level: advanced 209ab8d36c9SPeter Brune 210ab8d36c9SPeter Brune .seealso: SNESFASSetNumberSmoothDown() 211ab8d36c9SPeter Brune @*/ 21222d28d08SBarry Smith PetscErrorCode SNESFASSetNumberSmoothUp(SNES snes, PetscInt n) 21322d28d08SBarry Smith { 214f833ba53SLisandro Dalcin SNES_FAS *fas; 21522d28d08SBarry Smith PetscErrorCode ierr; 21622d28d08SBarry Smith 217ab8d36c9SPeter Brune PetscFunctionBegin; 218f833ba53SLisandro Dalcin PetscValidHeaderSpecificType(snes,SNES_CLASSID,1,SNESFAS); 219f833ba53SLisandro Dalcin fas = (SNES_FAS*)snes->data; 220ab8d36c9SPeter Brune fas->max_up_it = n; 221656ede7eSPeter Brune if (!fas->smoothu && fas->level != 0) { 22222d28d08SBarry Smith ierr = SNESFASCycleCreateSmoother_Private(snes, &fas->smoothu);CHKERRQ(ierr); 223ab8d36c9SPeter Brune } 22422d28d08SBarry Smith if (fas->smoothu) { 22522d28d08SBarry Smith ierr = SNESSetTolerances(fas->smoothu, fas->smoothu->abstol, fas->smoothu->rtol, fas->smoothu->stol, n, fas->smoothu->max_funcs);CHKERRQ(ierr); 22622d28d08SBarry Smith } 227ab8d36c9SPeter Brune if (fas->next) { 228ab8d36c9SPeter Brune ierr = SNESFASSetNumberSmoothUp(fas->next, n);CHKERRQ(ierr); 229ab8d36c9SPeter Brune } 230ab8d36c9SPeter Brune PetscFunctionReturn(0); 231ab8d36c9SPeter Brune } 232ab8d36c9SPeter Brune 233ab8d36c9SPeter Brune /*@ 234ab8d36c9SPeter Brune SNESFASSetNumberSmoothDown - Sets the number of pre-smoothing steps to 235ab8d36c9SPeter Brune use on all levels. 236ab8d36c9SPeter Brune 237ab8d36c9SPeter Brune Logically Collective on SNES 238ab8d36c9SPeter Brune 239ab8d36c9SPeter Brune Input Parameters: 240ab8d36c9SPeter Brune + snes - the multigrid context 241ab8d36c9SPeter Brune - n - the number of smoothing steps 242ab8d36c9SPeter Brune 243ab8d36c9SPeter Brune Options Database Key: 244ab8d36c9SPeter Brune . -snes_fas_smoothdown <n> - Sets number of pre-smoothing steps 245ab8d36c9SPeter Brune 246ab8d36c9SPeter Brune Level: advanced 247ab8d36c9SPeter Brune 248ab8d36c9SPeter Brune .seealso: SNESFASSetNumberSmoothUp() 249ab8d36c9SPeter Brune @*/ 25022d28d08SBarry Smith PetscErrorCode SNESFASSetNumberSmoothDown(SNES snes, PetscInt n) 25122d28d08SBarry Smith { 252f833ba53SLisandro Dalcin SNES_FAS *fas; 253f833ba53SLisandro Dalcin PetscErrorCode ierr; 25422d28d08SBarry Smith 255ab8d36c9SPeter Brune PetscFunctionBegin; 256f833ba53SLisandro Dalcin PetscValidHeaderSpecificType(snes,SNES_CLASSID,1,SNESFAS); 257f833ba53SLisandro Dalcin fas = (SNES_FAS*)snes->data; 258ab8d36c9SPeter Brune if (!fas->smoothd) { 25922d28d08SBarry Smith ierr = SNESFASCycleCreateSmoother_Private(snes, &fas->smoothd);CHKERRQ(ierr); 260ab8d36c9SPeter Brune } 261ab8d36c9SPeter Brune ierr = SNESSetTolerances(fas->smoothd, fas->smoothd->abstol, fas->smoothd->rtol, fas->smoothd->stol, n, fas->smoothd->max_funcs);CHKERRQ(ierr); 2621aa26658SKarl Rupp 263ab8d36c9SPeter Brune fas->max_down_it = n; 264ab8d36c9SPeter Brune if (fas->next) { 265ab8d36c9SPeter Brune ierr = SNESFASSetNumberSmoothDown(fas->next, n);CHKERRQ(ierr); 266ab8d36c9SPeter Brune } 267ab8d36c9SPeter Brune PetscFunctionReturn(0); 268ab8d36c9SPeter Brune } 269ab8d36c9SPeter Brune 270ab8d36c9SPeter Brune 27187f44e3fSPeter Brune /*@ 27287f44e3fSPeter Brune SNESFASSetContinuation - Sets the FAS cycle to default to exact Newton solves on the upsweep 27387f44e3fSPeter Brune 27487f44e3fSPeter Brune Logically Collective on SNES 27587f44e3fSPeter Brune 27687f44e3fSPeter Brune Input Parameters: 27787f44e3fSPeter Brune + snes - the multigrid context 27887f44e3fSPeter Brune - n - the number of smoothing steps 27987f44e3fSPeter Brune 28087f44e3fSPeter Brune Options Database Key: 28187f44e3fSPeter Brune . -snes_fas_continuation - sets continuation to true 28287f44e3fSPeter Brune 28387f44e3fSPeter Brune Level: advanced 28487f44e3fSPeter Brune 28595452b02SPatrick Sanan Notes: 28695452b02SPatrick Sanan This sets the prefix on the upsweep smoothers to -fas_continuation 28787f44e3fSPeter Brune 28887f44e3fSPeter Brune .seealso: SNESFAS 28987f44e3fSPeter Brune @*/ 29087f44e3fSPeter Brune PetscErrorCode SNESFASSetContinuation(SNES snes,PetscBool continuation) 29187f44e3fSPeter Brune { 29287f44e3fSPeter Brune const char *optionsprefix; 29387f44e3fSPeter Brune char tprefix[128]; 294f833ba53SLisandro Dalcin SNES_FAS *fas; 295f833ba53SLisandro Dalcin PetscErrorCode ierr; 29687f44e3fSPeter Brune 29787f44e3fSPeter Brune PetscFunctionBegin; 298f833ba53SLisandro Dalcin PetscValidHeaderSpecificType(snes,SNES_CLASSID,1,SNESFAS); 299f833ba53SLisandro Dalcin fas = (SNES_FAS*)snes->data; 30087f44e3fSPeter Brune ierr = SNESGetOptionsPrefix(fas->fine, &optionsprefix);CHKERRQ(ierr); 30187f44e3fSPeter Brune if (!fas->smoothu) { 30287f44e3fSPeter Brune ierr = SNESFASCycleCreateSmoother_Private(snes, &fas->smoothu);CHKERRQ(ierr); 30387f44e3fSPeter Brune } 304f833ba53SLisandro Dalcin ierr = PetscStrncpy(tprefix,"fas_levels_continuation_",sizeof(tprefix));CHKERRQ(ierr); 30587f44e3fSPeter Brune ierr = SNESSetOptionsPrefix(fas->smoothu, optionsprefix);CHKERRQ(ierr); 30687f44e3fSPeter Brune ierr = SNESAppendOptionsPrefix(fas->smoothu, tprefix);CHKERRQ(ierr); 30787f44e3fSPeter Brune ierr = SNESSetType(fas->smoothu,SNESNEWTONLS);CHKERRQ(ierr); 30887f44e3fSPeter Brune ierr = SNESSetTolerances(fas->smoothu,fas->fine->abstol,fas->fine->rtol,fas->fine->stol,50,100);CHKERRQ(ierr); 30987f44e3fSPeter Brune fas->continuation = continuation; 31087f44e3fSPeter Brune if (fas->next) { 31187f44e3fSPeter Brune ierr = SNESFASSetContinuation(fas->next,continuation);CHKERRQ(ierr); 31287f44e3fSPeter Brune } 31387f44e3fSPeter Brune PetscFunctionReturn(0); 31487f44e3fSPeter Brune } 31587f44e3fSPeter Brune 31687f44e3fSPeter Brune 317ab8d36c9SPeter Brune /*@ 318ab8d36c9SPeter Brune SNESFASSetCycles - Sets the number of FAS multigrid cycles to use each time a grid is visited. Use SNESFASSetCyclesOnLevel() for more 319ab8d36c9SPeter Brune complicated cycling. 320ab8d36c9SPeter Brune 321ab8d36c9SPeter Brune Logically Collective on SNES 322ab8d36c9SPeter Brune 323ab8d36c9SPeter Brune Input Parameters: 324ab8d36c9SPeter Brune + snes - the multigrid context 325ab8d36c9SPeter Brune - cycles - the number of cycles -- 1 for V-cycle, 2 for W-cycle 326ab8d36c9SPeter Brune 327ab8d36c9SPeter Brune Options Database Key: 328e1bc860dSBarry Smith . -snes_fas_cycles 1 or 2 329ab8d36c9SPeter Brune 330ab8d36c9SPeter Brune Level: advanced 331ab8d36c9SPeter Brune 332ab8d36c9SPeter Brune .seealso: SNESFASSetCyclesOnLevel() 333ab8d36c9SPeter Brune @*/ 33422d28d08SBarry Smith PetscErrorCode SNESFASSetCycles(SNES snes, PetscInt cycles) 33522d28d08SBarry Smith { 336f833ba53SLisandro Dalcin SNES_FAS *fas; 337ab8d36c9SPeter Brune PetscErrorCode ierr; 338ab8d36c9SPeter Brune PetscBool isFine; 33922d28d08SBarry Smith 340ab8d36c9SPeter Brune PetscFunctionBegin; 341f833ba53SLisandro Dalcin PetscValidHeaderSpecificType(snes,SNES_CLASSID,1,SNESFAS); 34222d28d08SBarry Smith ierr = SNESFASCycleIsFine(snes, &isFine);CHKERRQ(ierr); 343f833ba53SLisandro Dalcin fas = (SNES_FAS*)snes->data; 344ab8d36c9SPeter Brune fas->n_cycles = cycles; 3451aa26658SKarl Rupp if (!isFine) { 346ab8d36c9SPeter Brune ierr = SNESSetTolerances(snes, snes->abstol, snes->rtol, snes->stol, cycles, snes->max_funcs);CHKERRQ(ierr); 3471aa26658SKarl Rupp } 348ab8d36c9SPeter Brune if (fas->next) { 349ab8d36c9SPeter Brune ierr = SNESFASSetCycles(fas->next, cycles);CHKERRQ(ierr); 350ab8d36c9SPeter Brune } 351ab8d36c9SPeter Brune PetscFunctionReturn(0); 352ab8d36c9SPeter Brune } 353ab8d36c9SPeter Brune 354c8c899caSPeter Brune 355c8c899caSPeter Brune /*@ 356c8c899caSPeter Brune SNESFASSetMonitor - Sets the method-specific cycle monitoring 357c8c899caSPeter Brune 358c8c899caSPeter Brune Logically Collective on SNES 359c8c899caSPeter Brune 360c8c899caSPeter Brune Input Parameters: 361c8c899caSPeter Brune + snes - the FAS context 362d142ab34SLawrence Mitchell . vf - viewer and format structure (may be NULL if flg is FALSE) 363c8c899caSPeter Brune - flg - monitor or not 364c8c899caSPeter Brune 365c8c899caSPeter Brune Level: advanced 366c8c899caSPeter Brune 367c8c899caSPeter Brune .seealso: SNESFASSetCyclesOnLevel() 368c8c899caSPeter Brune @*/ 369d142ab34SLawrence Mitchell PetscErrorCode SNESFASSetMonitor(SNES snes, PetscViewerAndFormat *vf, PetscBool flg) 37022d28d08SBarry Smith { 371f833ba53SLisandro Dalcin SNES_FAS *fas; 372c8c899caSPeter Brune PetscErrorCode ierr; 373c8c899caSPeter Brune PetscBool isFine; 374f833ba53SLisandro Dalcin PetscInt i, levels; 375c8c899caSPeter Brune SNES levelsnes; 37622d28d08SBarry Smith 377c8c899caSPeter Brune PetscFunctionBegin; 378f833ba53SLisandro Dalcin PetscValidHeaderSpecificType(snes,SNES_CLASSID,1,SNESFAS); 379c8c899caSPeter Brune ierr = SNESFASCycleIsFine(snes, &isFine);CHKERRQ(ierr); 380f833ba53SLisandro Dalcin fas = (SNES_FAS*)snes->data; 381f833ba53SLisandro Dalcin levels = fas->levels; 382c8c899caSPeter Brune if (isFine) { 383c8c899caSPeter Brune for (i = 0; i < levels; i++) { 38422d28d08SBarry Smith ierr = SNESFASGetCycleSNES(snes, i, &levelsnes);CHKERRQ(ierr); 385c8c899caSPeter Brune fas = (SNES_FAS*)levelsnes->data; 386c8c899caSPeter Brune if (flg) { 387c8c899caSPeter Brune /* set the monitors for the upsmoother and downsmoother */ 388c8c899caSPeter Brune ierr = SNESMonitorCancel(levelsnes);CHKERRQ(ierr); 389d142ab34SLawrence Mitchell /* Only register destroy on finest level */ 390d142ab34SLawrence Mitchell ierr = SNESMonitorSet(levelsnes,(PetscErrorCode (*)(SNES,PetscInt,PetscReal,void*))SNESMonitorDefault,vf,(!i ? (PetscErrorCode (*)(void**))PetscViewerAndFormatDestroy : NULL));CHKERRQ(ierr); 3911aa26658SKarl Rupp } else if (i != fas->levels - 1) { 392c8c899caSPeter Brune /* unset the monitors on the coarse levels */ 393c8c899caSPeter Brune ierr = SNESMonitorCancel(levelsnes);CHKERRQ(ierr); 394c8c899caSPeter Brune } 395c8c899caSPeter Brune } 396c8c899caSPeter Brune } 397c8c899caSPeter Brune PetscFunctionReturn(0); 398c8c899caSPeter Brune } 399c8c899caSPeter Brune 4000dd27c6cSPeter Brune /*@ 4010dd27c6cSPeter Brune SNESFASSetLog - Sets or unsets time logging for various FAS stages on all levels 4020dd27c6cSPeter Brune 4030dd27c6cSPeter Brune Logically Collective on SNES 4040dd27c6cSPeter Brune 4050dd27c6cSPeter Brune Input Parameters: 4060dd27c6cSPeter Brune + snes - the FAS context 4070dd27c6cSPeter Brune - flg - monitor or not 4080dd27c6cSPeter Brune 4090dd27c6cSPeter Brune Level: advanced 4100dd27c6cSPeter Brune 4110dd27c6cSPeter Brune .seealso: SNESFASSetMonitor() 4120dd27c6cSPeter Brune @*/ 4130dd27c6cSPeter Brune PetscErrorCode SNESFASSetLog(SNES snes, PetscBool flg) 4140dd27c6cSPeter Brune { 415f833ba53SLisandro Dalcin SNES_FAS *fas; 4160dd27c6cSPeter Brune PetscErrorCode ierr; 4170dd27c6cSPeter Brune PetscBool isFine; 418f833ba53SLisandro Dalcin PetscInt i, levels; 4190dd27c6cSPeter Brune SNES levelsnes; 4200dd27c6cSPeter Brune char eventname[128]; 4210dd27c6cSPeter Brune 4220dd27c6cSPeter Brune PetscFunctionBegin; 423f833ba53SLisandro Dalcin PetscValidHeaderSpecificType(snes,SNES_CLASSID,1,SNESFAS); 4240dd27c6cSPeter Brune ierr = SNESFASCycleIsFine(snes, &isFine);CHKERRQ(ierr); 425f833ba53SLisandro Dalcin fas = (SNES_FAS*)snes->data; 426f833ba53SLisandro Dalcin levels = fas->levels; 4270dd27c6cSPeter Brune if (isFine) { 4280dd27c6cSPeter Brune for (i = 0; i < levels; i++) { 4290dd27c6cSPeter Brune ierr = SNESFASGetCycleSNES(snes, i, &levelsnes);CHKERRQ(ierr); 4300dd27c6cSPeter Brune fas = (SNES_FAS*)levelsnes->data; 4310dd27c6cSPeter Brune if (flg) { 432f833ba53SLisandro Dalcin ierr = PetscSNPrintf(eventname,sizeof(eventname),"FASSetup %d",(int)i);CHKERRQ(ierr); 4330dd27c6cSPeter Brune ierr = PetscLogEventRegister(eventname,((PetscObject)snes)->classid,&fas->eventsmoothsetup);CHKERRQ(ierr); 434f833ba53SLisandro Dalcin ierr = PetscSNPrintf(eventname,sizeof(eventname),"FASSmooth %d",(int)i);CHKERRQ(ierr); 4350dd27c6cSPeter Brune ierr = PetscLogEventRegister(eventname,((PetscObject)snes)->classid,&fas->eventsmoothsolve);CHKERRQ(ierr); 436f833ba53SLisandro Dalcin ierr = PetscSNPrintf(eventname,sizeof(eventname),"FASResid %d",(int)i);CHKERRQ(ierr); 4370dd27c6cSPeter Brune ierr = PetscLogEventRegister(eventname,((PetscObject)snes)->classid,&fas->eventresidual);CHKERRQ(ierr); 438f833ba53SLisandro Dalcin ierr = PetscSNPrintf(eventname,sizeof(eventname),"FASInterp %d",(int)i);CHKERRQ(ierr); 4390dd27c6cSPeter Brune ierr = PetscLogEventRegister(eventname,((PetscObject)snes)->classid,&fas->eventinterprestrict);CHKERRQ(ierr); 4400dd27c6cSPeter Brune } else { 4410298fd71SBarry Smith fas->eventsmoothsetup = 0; 4420298fd71SBarry Smith fas->eventsmoothsolve = 0; 4430298fd71SBarry Smith fas->eventresidual = 0; 4440298fd71SBarry Smith fas->eventinterprestrict = 0; 4450dd27c6cSPeter Brune } 4460dd27c6cSPeter Brune } 4470dd27c6cSPeter Brune } 4480dd27c6cSPeter Brune PetscFunctionReturn(0); 4490dd27c6cSPeter Brune } 4500dd27c6cSPeter Brune 451ab8d36c9SPeter Brune /* 452ab8d36c9SPeter Brune Creates the default smoother type. 453ab8d36c9SPeter Brune 45404d7464bSBarry Smith This is SNESNRICHARDSON on each fine level and SNESNEWTONLS on the coarse level. 455ab8d36c9SPeter Brune 456ab8d36c9SPeter Brune */ 45722d28d08SBarry Smith PetscErrorCode SNESFASCycleCreateSmoother_Private(SNES snes, SNES *smooth) 45822d28d08SBarry Smith { 459ab8d36c9SPeter Brune SNES_FAS *fas; 460ab8d36c9SPeter Brune const char *optionsprefix; 461ab8d36c9SPeter Brune char tprefix[128]; 462ab8d36c9SPeter Brune PetscErrorCode ierr; 463ab8d36c9SPeter Brune SNES nsmooth; 46422d28d08SBarry Smith 465ab8d36c9SPeter Brune PetscFunctionBegin; 466f833ba53SLisandro Dalcin PetscValidHeaderSpecificType(snes,SNES_CLASSID,1,SNESFAS); 467f833ba53SLisandro Dalcin PetscValidPointer(smooth,3); 468ab8d36c9SPeter Brune fas = (SNES_FAS*)snes->data; 469ab8d36c9SPeter Brune ierr = SNESGetOptionsPrefix(fas->fine, &optionsprefix);CHKERRQ(ierr); 470ab8d36c9SPeter Brune /* create the default smoother */ 471ce94432eSBarry Smith ierr = SNESCreate(PetscObjectComm((PetscObject)snes), &nsmooth);CHKERRQ(ierr); 472ab8d36c9SPeter Brune if (fas->level == 0) { 473f833ba53SLisandro Dalcin ierr = PetscStrncpy(tprefix,"fas_coarse_",sizeof(tprefix));CHKERRQ(ierr); 474ab8d36c9SPeter Brune ierr = SNESAppendOptionsPrefix(nsmooth, optionsprefix);CHKERRQ(ierr); 475ab8d36c9SPeter Brune ierr = SNESAppendOptionsPrefix(nsmooth, tprefix);CHKERRQ(ierr); 47604d7464bSBarry Smith ierr = SNESSetType(nsmooth, SNESNEWTONLS);CHKERRQ(ierr); 477e70c42e5SPeter Brune ierr = SNESSetTolerances(nsmooth, nsmooth->abstol, nsmooth->rtol, nsmooth->stol, nsmooth->max_its, nsmooth->max_funcs);CHKERRQ(ierr); 478ab8d36c9SPeter Brune } else { 479f833ba53SLisandro Dalcin ierr = PetscSNPrintf(tprefix,sizeof(tprefix),"fas_levels_%d_",(int)fas->level);CHKERRQ(ierr); 480ab8d36c9SPeter Brune ierr = SNESAppendOptionsPrefix(nsmooth, optionsprefix);CHKERRQ(ierr); 481ab8d36c9SPeter Brune ierr = SNESAppendOptionsPrefix(nsmooth, tprefix);CHKERRQ(ierr); 482ab8d36c9SPeter Brune ierr = SNESSetType(nsmooth, SNESNRICHARDSON);CHKERRQ(ierr); 483e70c42e5SPeter Brune ierr = SNESSetTolerances(nsmooth, 0.0, 0.0, 0.0, fas->max_down_it, nsmooth->max_funcs);CHKERRQ(ierr); 484ab8d36c9SPeter Brune } 485ab8d36c9SPeter Brune ierr = PetscObjectIncrementTabLevel((PetscObject)nsmooth, (PetscObject)snes, 1);CHKERRQ(ierr); 4863bb1ff40SBarry Smith ierr = PetscLogObjectParent((PetscObject)snes,(PetscObject)nsmooth);CHKERRQ(ierr); 487f89ba88eSPeter Brune ierr = PetscObjectCopyFortranFunctionPointers((PetscObject)snes, (PetscObject)nsmooth);CHKERRQ(ierr); 488ab83eea4SMatthew G. Knepley ierr = PetscObjectComposedDataSetInt((PetscObject) nsmooth, PetscMGLevelId, fas->level);CHKERRQ(ierr); 489ab8d36c9SPeter Brune *smooth = nsmooth; 490ab8d36c9SPeter Brune PetscFunctionReturn(0); 491ab8d36c9SPeter Brune } 492ab8d36c9SPeter Brune 493ab8d36c9SPeter Brune /* ------------- Functions called on a particular level ----------------- */ 494ab8d36c9SPeter Brune 495ab8d36c9SPeter Brune /*@ 496ab8d36c9SPeter Brune SNESFASCycleSetCycles - Sets the number of cycles on a particular level. 497ab8d36c9SPeter Brune 498ab8d36c9SPeter Brune Logically Collective on SNES 499ab8d36c9SPeter Brune 500ab8d36c9SPeter Brune Input Parameters: 501ab8d36c9SPeter Brune + snes - the multigrid context 502ab8d36c9SPeter Brune . level - the level to set the number of cycles on 503ab8d36c9SPeter Brune - cycles - the number of cycles -- 1 for V-cycle, 2 for W-cycle 504ab8d36c9SPeter Brune 505ab8d36c9SPeter Brune Level: advanced 506ab8d36c9SPeter Brune 507ab8d36c9SPeter Brune .seealso: SNESFASSetCycles() 508ab8d36c9SPeter Brune @*/ 50922d28d08SBarry Smith PetscErrorCode SNESFASCycleSetCycles(SNES snes, PetscInt cycles) 51022d28d08SBarry Smith { 511f833ba53SLisandro Dalcin SNES_FAS *fas; 512ab8d36c9SPeter Brune PetscErrorCode ierr; 51322d28d08SBarry Smith 514ab8d36c9SPeter Brune PetscFunctionBegin; 515f833ba53SLisandro Dalcin PetscValidHeaderSpecificType(snes,SNES_CLASSID,1,SNESFAS); 516f833ba53SLisandro Dalcin fas = (SNES_FAS*)snes->data; 517ab8d36c9SPeter Brune fas->n_cycles = cycles; 518ab8d36c9SPeter Brune ierr = SNESSetTolerances(snes, snes->abstol, snes->rtol, snes->stol, cycles, snes->max_funcs);CHKERRQ(ierr); 519ab8d36c9SPeter Brune PetscFunctionReturn(0); 520ab8d36c9SPeter Brune } 521ab8d36c9SPeter Brune 522ab8d36c9SPeter Brune 523ab8d36c9SPeter Brune /*@ 524ab8d36c9SPeter Brune SNESFASCycleGetSmoother - Gets the smoother on a particular cycle level. 525ab8d36c9SPeter Brune 526ab8d36c9SPeter Brune Logically Collective on SNES 527ab8d36c9SPeter Brune 528ab8d36c9SPeter Brune Input Parameters: 529ab8d36c9SPeter Brune . snes - the multigrid context 530ab8d36c9SPeter Brune 531ab8d36c9SPeter Brune Output Parameters: 532ab8d36c9SPeter Brune . smooth - the smoother 533ab8d36c9SPeter Brune 534ab8d36c9SPeter Brune Level: advanced 535ab8d36c9SPeter Brune 536ab8d36c9SPeter Brune .seealso: SNESFASCycleGetSmootherUp(), SNESFASCycleGetSmootherDown() 537ab8d36c9SPeter Brune @*/ 538ab8d36c9SPeter Brune PetscErrorCode SNESFASCycleGetSmoother(SNES snes, SNES *smooth) 539ab8d36c9SPeter Brune { 540ab8d36c9SPeter Brune SNES_FAS *fas; 5415fd66863SKarl Rupp 542ab8d36c9SPeter Brune PetscFunctionBegin; 543f833ba53SLisandro Dalcin PetscValidHeaderSpecificType(snes,SNES_CLASSID,1,SNESFAS); 544f833ba53SLisandro Dalcin PetscValidPointer(smooth,2); 545ab8d36c9SPeter Brune fas = (SNES_FAS*)snes->data; 546ab8d36c9SPeter Brune *smooth = fas->smoothd; 547ab8d36c9SPeter Brune PetscFunctionReturn(0); 548ab8d36c9SPeter Brune } 549ab8d36c9SPeter Brune /*@ 550ab8d36c9SPeter Brune SNESFASCycleGetSmootherUp - Gets the up smoother on a particular cycle level. 551ab8d36c9SPeter Brune 552ab8d36c9SPeter Brune Logically Collective on SNES 553ab8d36c9SPeter Brune 554ab8d36c9SPeter Brune Input Parameters: 555ab8d36c9SPeter Brune . snes - the multigrid context 556ab8d36c9SPeter Brune 557ab8d36c9SPeter Brune Output Parameters: 558ab8d36c9SPeter Brune . smoothu - the smoother 559ab8d36c9SPeter Brune 560ab8d36c9SPeter Brune Notes: 561ab8d36c9SPeter Brune Returns the downsmoother if no up smoother is available. This enables transparent 562ab8d36c9SPeter Brune default behavior in the process of the solve. 563ab8d36c9SPeter Brune 564ab8d36c9SPeter Brune Level: advanced 565ab8d36c9SPeter Brune 566ab8d36c9SPeter Brune .seealso: SNESFASCycleGetSmoother(), SNESFASCycleGetSmootherDown() 567ab8d36c9SPeter Brune @*/ 568ab8d36c9SPeter Brune PetscErrorCode SNESFASCycleGetSmootherUp(SNES snes, SNES *smoothu) 569ab8d36c9SPeter Brune { 570ab8d36c9SPeter Brune SNES_FAS *fas; 5715fd66863SKarl Rupp 572ab8d36c9SPeter Brune PetscFunctionBegin; 573f833ba53SLisandro Dalcin PetscValidHeaderSpecificType(snes,SNES_CLASSID,1,SNESFAS); 574f833ba53SLisandro Dalcin PetscValidPointer(smoothu,2); 575ab8d36c9SPeter Brune fas = (SNES_FAS*)snes->data; 5761aa26658SKarl Rupp if (!fas->smoothu) *smoothu = fas->smoothd; 5771aa26658SKarl Rupp else *smoothu = fas->smoothu; 578ab8d36c9SPeter Brune PetscFunctionReturn(0); 579ab8d36c9SPeter Brune } 580ab8d36c9SPeter Brune 581ab8d36c9SPeter Brune /*@ 582ab8d36c9SPeter Brune SNESFASCycleGetSmootherDown - Gets the down smoother on a particular cycle level. 583ab8d36c9SPeter Brune 584ab8d36c9SPeter Brune Logically Collective on SNES 585ab8d36c9SPeter Brune 586ab8d36c9SPeter Brune Input Parameters: 587ab8d36c9SPeter Brune . snes - the multigrid context 588ab8d36c9SPeter Brune 589ab8d36c9SPeter Brune Output Parameters: 590ab8d36c9SPeter Brune . smoothd - the smoother 591ab8d36c9SPeter Brune 592ab8d36c9SPeter Brune Level: advanced 593ab8d36c9SPeter Brune 594ab8d36c9SPeter Brune .seealso: SNESFASCycleGetSmootherUp(), SNESFASCycleGetSmoother() 595ab8d36c9SPeter Brune @*/ 596ab8d36c9SPeter Brune PetscErrorCode SNESFASCycleGetSmootherDown(SNES snes, SNES *smoothd) 597ab8d36c9SPeter Brune { 598ab8d36c9SPeter Brune SNES_FAS *fas; 5995fd66863SKarl Rupp 600ab8d36c9SPeter Brune PetscFunctionBegin; 601f833ba53SLisandro Dalcin PetscValidHeaderSpecificType(snes,SNES_CLASSID,1,SNESFAS); 602f833ba53SLisandro Dalcin PetscValidPointer(smoothd,2); 603ab8d36c9SPeter Brune fas = (SNES_FAS*)snes->data; 604ab8d36c9SPeter Brune *smoothd = fas->smoothd; 605ab8d36c9SPeter Brune PetscFunctionReturn(0); 606ab8d36c9SPeter Brune } 607ab8d36c9SPeter Brune 608ab8d36c9SPeter Brune 609ab8d36c9SPeter Brune /*@ 610ab8d36c9SPeter Brune SNESFASCycleGetCorrection - Gets the coarse correction FAS context for this level 611ab8d36c9SPeter Brune 612ab8d36c9SPeter Brune Logically Collective on SNES 613ab8d36c9SPeter Brune 614ab8d36c9SPeter Brune Input Parameters: 615ab8d36c9SPeter Brune . snes - the multigrid context 616ab8d36c9SPeter Brune 617ab8d36c9SPeter Brune Output Parameters: 618ab8d36c9SPeter Brune . correction - the coarse correction on this level 619ab8d36c9SPeter Brune 620ab8d36c9SPeter Brune Notes: 6210298fd71SBarry Smith Returns NULL on the coarsest level. 622ab8d36c9SPeter Brune 623ab8d36c9SPeter Brune Level: advanced 624ab8d36c9SPeter Brune 625ab8d36c9SPeter Brune .seealso: SNESFASCycleGetSmootherUp(), SNESFASCycleGetSmoother() 626ab8d36c9SPeter Brune @*/ 627ab8d36c9SPeter Brune PetscErrorCode SNESFASCycleGetCorrection(SNES snes, SNES *correction) 628ab8d36c9SPeter Brune { 629ab8d36c9SPeter Brune SNES_FAS *fas; 6305fd66863SKarl Rupp 631ab8d36c9SPeter Brune PetscFunctionBegin; 632f833ba53SLisandro Dalcin PetscValidHeaderSpecificType(snes,SNES_CLASSID,1,SNESFAS); 633f833ba53SLisandro Dalcin PetscValidPointer(correction,2); 634ab8d36c9SPeter Brune fas = (SNES_FAS*)snes->data; 635ab8d36c9SPeter Brune *correction = fas->next; 636ab8d36c9SPeter Brune PetscFunctionReturn(0); 637ab8d36c9SPeter Brune } 638ab8d36c9SPeter Brune 639ab8d36c9SPeter Brune /*@ 640ab8d36c9SPeter Brune SNESFASCycleGetInterpolation - Gets the interpolation on this level 641ab8d36c9SPeter Brune 642ab8d36c9SPeter Brune Logically Collective on SNES 643ab8d36c9SPeter Brune 644ab8d36c9SPeter Brune Input Parameters: 645ab8d36c9SPeter Brune . snes - the multigrid context 646ab8d36c9SPeter Brune 647ab8d36c9SPeter Brune Output Parameters: 648ab8d36c9SPeter Brune . mat - the interpolation operator on this level 649ab8d36c9SPeter Brune 650ab8d36c9SPeter Brune Level: developer 651ab8d36c9SPeter Brune 652ab8d36c9SPeter Brune .seealso: SNESFASCycleGetSmootherUp(), SNESFASCycleGetSmoother() 653ab8d36c9SPeter Brune @*/ 654ab8d36c9SPeter Brune PetscErrorCode SNESFASCycleGetInterpolation(SNES snes, Mat *mat) 655ab8d36c9SPeter Brune { 656ab8d36c9SPeter Brune SNES_FAS *fas; 6575fd66863SKarl Rupp 658ab8d36c9SPeter Brune PetscFunctionBegin; 659f833ba53SLisandro Dalcin PetscValidHeaderSpecificType(snes,SNES_CLASSID,1,SNESFAS); 660f833ba53SLisandro Dalcin PetscValidPointer(mat,2); 661ab8d36c9SPeter Brune fas = (SNES_FAS*)snes->data; 662ab8d36c9SPeter Brune *mat = fas->interpolate; 663ab8d36c9SPeter Brune PetscFunctionReturn(0); 664ab8d36c9SPeter Brune } 665ab8d36c9SPeter Brune 666ab8d36c9SPeter Brune 667ab8d36c9SPeter Brune /*@ 668ab8d36c9SPeter Brune SNESFASCycleGetRestriction - Gets the restriction on this level 669ab8d36c9SPeter Brune 670ab8d36c9SPeter Brune Logically Collective on SNES 671ab8d36c9SPeter Brune 672ab8d36c9SPeter Brune Input Parameters: 673ab8d36c9SPeter Brune . snes - the multigrid context 674ab8d36c9SPeter Brune 675ab8d36c9SPeter Brune Output Parameters: 676ab8d36c9SPeter Brune . mat - the restriction operator on this level 677ab8d36c9SPeter Brune 678ab8d36c9SPeter Brune Level: developer 679ab8d36c9SPeter Brune 680ab8d36c9SPeter Brune .seealso: SNESFASGetRestriction(), SNESFASCycleGetInterpolation() 681ab8d36c9SPeter Brune @*/ 682ab8d36c9SPeter Brune PetscErrorCode SNESFASCycleGetRestriction(SNES snes, Mat *mat) 683ab8d36c9SPeter Brune { 684ab8d36c9SPeter Brune SNES_FAS *fas; 6855fd66863SKarl Rupp 686ab8d36c9SPeter Brune PetscFunctionBegin; 687f833ba53SLisandro Dalcin PetscValidHeaderSpecificType(snes,SNES_CLASSID,1,SNESFAS); 688f833ba53SLisandro Dalcin PetscValidPointer(mat,2); 689ab8d36c9SPeter Brune fas = (SNES_FAS*)snes->data; 690ab8d36c9SPeter Brune *mat = fas->restrct; 691ab8d36c9SPeter Brune PetscFunctionReturn(0); 692ab8d36c9SPeter Brune } 693ab8d36c9SPeter Brune 694ab8d36c9SPeter Brune 695ab8d36c9SPeter Brune /*@ 696ab8d36c9SPeter Brune SNESFASCycleGetInjection - Gets the injection on this level 697ab8d36c9SPeter Brune 698ab8d36c9SPeter Brune Logically Collective on SNES 699ab8d36c9SPeter Brune 700ab8d36c9SPeter Brune Input Parameters: 701ab8d36c9SPeter Brune . snes - the multigrid context 702ab8d36c9SPeter Brune 703ab8d36c9SPeter Brune Output Parameters: 704ab8d36c9SPeter Brune . mat - the restriction operator on this level 705ab8d36c9SPeter Brune 706ab8d36c9SPeter Brune Level: developer 707ab8d36c9SPeter Brune 708ab8d36c9SPeter Brune .seealso: SNESFASGetInjection(), SNESFASCycleGetRestriction() 709ab8d36c9SPeter Brune @*/ 710ab8d36c9SPeter Brune PetscErrorCode SNESFASCycleGetInjection(SNES snes, Mat *mat) 711ab8d36c9SPeter Brune { 712ab8d36c9SPeter Brune SNES_FAS *fas; 7135fd66863SKarl Rupp 714ab8d36c9SPeter Brune PetscFunctionBegin; 715f833ba53SLisandro Dalcin PetscValidHeaderSpecificType(snes,SNES_CLASSID,1,SNESFAS); 716f833ba53SLisandro Dalcin PetscValidPointer(mat,2); 717ab8d36c9SPeter Brune fas = (SNES_FAS*)snes->data; 718ab8d36c9SPeter Brune *mat = fas->inject; 719ab8d36c9SPeter Brune PetscFunctionReturn(0); 720ab8d36c9SPeter Brune } 721ab8d36c9SPeter Brune 722ab8d36c9SPeter Brune /*@ 723ab8d36c9SPeter Brune SNESFASCycleGetRScale - Gets the injection on this level 724ab8d36c9SPeter Brune 725ab8d36c9SPeter Brune Logically Collective on SNES 726ab8d36c9SPeter Brune 727ab8d36c9SPeter Brune Input Parameters: 728ab8d36c9SPeter Brune . snes - the multigrid context 729ab8d36c9SPeter Brune 730ab8d36c9SPeter Brune Output Parameters: 731ab8d36c9SPeter Brune . mat - the restriction operator on this level 732ab8d36c9SPeter Brune 733ab8d36c9SPeter Brune Level: developer 734ab8d36c9SPeter Brune 735ab8d36c9SPeter Brune .seealso: SNESFASCycleGetRestriction(), SNESFASGetRScale() 736ab8d36c9SPeter Brune @*/ 737ab8d36c9SPeter Brune PetscErrorCode SNESFASCycleGetRScale(SNES snes, Vec *vec) 738ab8d36c9SPeter Brune { 739ab8d36c9SPeter Brune SNES_FAS *fas; 7405fd66863SKarl Rupp 741ab8d36c9SPeter Brune PetscFunctionBegin; 742f833ba53SLisandro Dalcin PetscValidHeaderSpecificType(snes,SNES_CLASSID,1,SNESFAS); 743f833ba53SLisandro Dalcin PetscValidPointer(vec,2); 744ab8d36c9SPeter Brune fas = (SNES_FAS*)snes->data; 745ab8d36c9SPeter Brune *vec = fas->rscale; 746ab8d36c9SPeter Brune PetscFunctionReturn(0); 747ab8d36c9SPeter Brune } 748ab8d36c9SPeter Brune 749ab8d36c9SPeter Brune /*@ 750ab8d36c9SPeter Brune SNESFASCycleIsFine - Determines if a given cycle is the fine level. 751ab8d36c9SPeter Brune 752ab8d36c9SPeter Brune Logically Collective on SNES 753ab8d36c9SPeter Brune 754ab8d36c9SPeter Brune Input Parameters: 755ab8d36c9SPeter Brune . snes - the FAS context 756ab8d36c9SPeter Brune 757ab8d36c9SPeter Brune Output Parameters: 758ab8d36c9SPeter Brune . flg - indicates if this is the fine level or not 759ab8d36c9SPeter Brune 760ab8d36c9SPeter Brune Level: advanced 761ab8d36c9SPeter Brune 762ab8d36c9SPeter Brune .seealso: SNESFASSetLevels() 763ab8d36c9SPeter Brune @*/ 764ab8d36c9SPeter Brune PetscErrorCode SNESFASCycleIsFine(SNES snes, PetscBool *flg) 765ab8d36c9SPeter Brune { 766ab8d36c9SPeter Brune SNES_FAS *fas; 7675fd66863SKarl Rupp 768ab8d36c9SPeter Brune PetscFunctionBegin; 769f833ba53SLisandro Dalcin PetscValidHeaderSpecificType(snes,SNES_CLASSID,1,SNESFAS); 770*534a8f05SLisandro Dalcin PetscValidBoolPointer(flg,2); 771ab8d36c9SPeter Brune fas = (SNES_FAS*)snes->data; 7721aa26658SKarl Rupp if (fas->level == fas->levels - 1) *flg = PETSC_TRUE; 7731aa26658SKarl Rupp else *flg = PETSC_FALSE; 774ab8d36c9SPeter Brune PetscFunctionReturn(0); 775ab8d36c9SPeter Brune } 776ab8d36c9SPeter Brune 777ab8d36c9SPeter Brune /* ---------- functions called on the finest level that return level-specific information ---------- */ 778ab8d36c9SPeter Brune 779ab8d36c9SPeter Brune /*@ 780ab8d36c9SPeter Brune SNESFASSetInterpolation - Sets the function to be used to calculate the 781ab8d36c9SPeter Brune interpolation from l-1 to the lth level 782ab8d36c9SPeter Brune 783ab8d36c9SPeter Brune Input Parameters: 784ab8d36c9SPeter Brune + snes - the multigrid context 785ab8d36c9SPeter Brune . mat - the interpolation operator 786ab8d36c9SPeter Brune - level - the level (0 is coarsest) to supply [do not supply 0] 787ab8d36c9SPeter Brune 788ab8d36c9SPeter Brune Level: advanced 789ab8d36c9SPeter Brune 790ab8d36c9SPeter Brune Notes: 791ab8d36c9SPeter Brune Usually this is the same matrix used also to set the restriction 792ab8d36c9SPeter Brune for the same level. 793ab8d36c9SPeter Brune 794ab8d36c9SPeter Brune One can pass in the interpolation matrix or its transpose; PETSc figures 795ab8d36c9SPeter Brune out from the matrix size which one it is. 796ab8d36c9SPeter Brune 797ab8d36c9SPeter Brune .seealso: SNESFASSetInjection(), SNESFASSetRestriction(), SNESFASSetRScale() 798ab8d36c9SPeter Brune @*/ 7990adebc6cSBarry Smith PetscErrorCode SNESFASSetInterpolation(SNES snes, PetscInt level, Mat mat) 8000adebc6cSBarry Smith { 80122d28d08SBarry Smith SNES_FAS *fas; 802ab8d36c9SPeter Brune PetscErrorCode ierr; 803ab8d36c9SPeter Brune SNES levelsnes; 80422d28d08SBarry Smith 805ab8d36c9SPeter Brune PetscFunctionBegin; 806f833ba53SLisandro Dalcin PetscValidHeaderSpecificType(snes,SNES_CLASSID,1,SNESFAS); 807f833ba53SLisandro Dalcin if (mat) PetscValidHeaderSpecific(mat,MAT_CLASSID,3); 808ab8d36c9SPeter Brune ierr = SNESFASGetCycleSNES(snes, level, &levelsnes);CHKERRQ(ierr); 809ab8d36c9SPeter Brune fas = (SNES_FAS*)levelsnes->data; 810ab8d36c9SPeter Brune ierr = PetscObjectReference((PetscObject)mat);CHKERRQ(ierr); 811ab8d36c9SPeter Brune ierr = MatDestroy(&fas->interpolate);CHKERRQ(ierr); 812ab8d36c9SPeter Brune fas->interpolate = mat; 813ab8d36c9SPeter Brune PetscFunctionReturn(0); 814ab8d36c9SPeter Brune } 815ab8d36c9SPeter Brune 816ab8d36c9SPeter Brune /*@ 817ab8d36c9SPeter Brune SNESFASGetInterpolation - Gets the matrix used to calculate the 818ab8d36c9SPeter Brune interpolation from l-1 to the lth level 819ab8d36c9SPeter Brune 820ab8d36c9SPeter Brune Input Parameters: 821ab8d36c9SPeter Brune + snes - the multigrid context 822ab8d36c9SPeter Brune - level - the level (0 is coarsest) to supply [do not supply 0] 823ab8d36c9SPeter Brune 824ab8d36c9SPeter Brune Output Parameters: 825ab8d36c9SPeter Brune . mat - the interpolation operator 826ab8d36c9SPeter Brune 827ab8d36c9SPeter Brune Level: advanced 828ab8d36c9SPeter Brune 829ab8d36c9SPeter Brune .seealso: SNESFASSetInterpolation(), SNESFASGetInjection(), SNESFASGetRestriction(), SNESFASGetRScale() 830ab8d36c9SPeter Brune @*/ 83122d28d08SBarry Smith PetscErrorCode SNESFASGetInterpolation(SNES snes, PetscInt level, Mat *mat) 83222d28d08SBarry Smith { 83322d28d08SBarry Smith SNES_FAS *fas; 834ab8d36c9SPeter Brune PetscErrorCode ierr; 835ab8d36c9SPeter Brune SNES levelsnes; 83622d28d08SBarry Smith 837ab8d36c9SPeter Brune PetscFunctionBegin; 838f833ba53SLisandro Dalcin PetscValidHeaderSpecificType(snes,SNES_CLASSID,1,SNESFAS); 839f833ba53SLisandro Dalcin PetscValidPointer(mat,3); 840ab8d36c9SPeter Brune ierr = SNESFASGetCycleSNES(snes, level, &levelsnes);CHKERRQ(ierr); 841ab8d36c9SPeter Brune fas = (SNES_FAS*)levelsnes->data; 842ab8d36c9SPeter Brune *mat = fas->interpolate; 843ab8d36c9SPeter Brune PetscFunctionReturn(0); 844ab8d36c9SPeter Brune } 845ab8d36c9SPeter Brune 846ab8d36c9SPeter Brune /*@ 847ab8d36c9SPeter Brune SNESFASSetRestriction - Sets the function to be used to restrict the defect 848ab8d36c9SPeter Brune from level l to l-1. 849ab8d36c9SPeter Brune 850ab8d36c9SPeter Brune Input Parameters: 851ab8d36c9SPeter Brune + snes - the multigrid context 852ab8d36c9SPeter Brune . mat - the restriction matrix 853ab8d36c9SPeter Brune - level - the level (0 is coarsest) to supply [Do not supply 0] 854ab8d36c9SPeter Brune 855ab8d36c9SPeter Brune Level: advanced 856ab8d36c9SPeter Brune 857ab8d36c9SPeter Brune Notes: 858ab8d36c9SPeter Brune Usually this is the same matrix used also to set the interpolation 859ab8d36c9SPeter Brune for the same level. 860ab8d36c9SPeter Brune 861ab8d36c9SPeter Brune One can pass in the interpolation matrix or its transpose; PETSc figures 862ab8d36c9SPeter Brune out from the matrix size which one it is. 863ab8d36c9SPeter Brune 864ab8d36c9SPeter Brune If you do not set this, the transpose of the Mat set with SNESFASSetInterpolation() 865ab8d36c9SPeter Brune is used. 866ab8d36c9SPeter Brune 867ab8d36c9SPeter Brune .seealso: SNESFASSetInterpolation(), SNESFASSetInjection() 868ab8d36c9SPeter Brune @*/ 86922d28d08SBarry Smith PetscErrorCode SNESFASSetRestriction(SNES snes, PetscInt level, Mat mat) 87022d28d08SBarry Smith { 87122d28d08SBarry Smith SNES_FAS *fas; 872ab8d36c9SPeter Brune PetscErrorCode ierr; 873ab8d36c9SPeter Brune SNES levelsnes; 87422d28d08SBarry Smith 875ab8d36c9SPeter Brune PetscFunctionBegin; 876f833ba53SLisandro Dalcin PetscValidHeaderSpecificType(snes,SNES_CLASSID,1,SNESFAS); 877f833ba53SLisandro Dalcin if (mat) PetscValidHeaderSpecific(mat,MAT_CLASSID,3); 878ab8d36c9SPeter Brune ierr = SNESFASGetCycleSNES(snes, level, &levelsnes);CHKERRQ(ierr); 879ab8d36c9SPeter Brune fas = (SNES_FAS*)levelsnes->data; 880ab8d36c9SPeter Brune ierr = PetscObjectReference((PetscObject)mat);CHKERRQ(ierr); 881ab8d36c9SPeter Brune ierr = MatDestroy(&fas->restrct);CHKERRQ(ierr); 882ab8d36c9SPeter Brune fas->restrct = mat; 883ab8d36c9SPeter Brune PetscFunctionReturn(0); 884ab8d36c9SPeter Brune } 885ab8d36c9SPeter Brune 886ab8d36c9SPeter Brune /*@ 887ab8d36c9SPeter Brune SNESFASGetRestriction - Gets the matrix used to calculate the 888ab8d36c9SPeter Brune restriction from l to the l-1th level 889ab8d36c9SPeter Brune 890ab8d36c9SPeter Brune Input Parameters: 891ab8d36c9SPeter Brune + snes - the multigrid context 892ab8d36c9SPeter Brune - level - the level (0 is coarsest) to supply [do not supply 0] 893ab8d36c9SPeter Brune 894ab8d36c9SPeter Brune Output Parameters: 895ab8d36c9SPeter Brune . mat - the interpolation operator 896ab8d36c9SPeter Brune 897ab8d36c9SPeter Brune Level: advanced 898ab8d36c9SPeter Brune 899ab8d36c9SPeter Brune .seealso: SNESFASSetRestriction(), SNESFASGetInjection(), SNESFASGetInterpolation(), SNESFASGetRScale() 900ab8d36c9SPeter Brune @*/ 90122d28d08SBarry Smith PetscErrorCode SNESFASGetRestriction(SNES snes, PetscInt level, Mat *mat) 90222d28d08SBarry Smith { 90322d28d08SBarry Smith SNES_FAS *fas; 904ab8d36c9SPeter Brune PetscErrorCode ierr; 905ab8d36c9SPeter Brune SNES levelsnes; 90622d28d08SBarry Smith 907ab8d36c9SPeter Brune PetscFunctionBegin; 908f833ba53SLisandro Dalcin PetscValidHeaderSpecificType(snes,SNES_CLASSID,1,SNESFAS); 909f833ba53SLisandro Dalcin PetscValidPointer(mat,3); 910ab8d36c9SPeter Brune ierr = SNESFASGetCycleSNES(snes, level, &levelsnes);CHKERRQ(ierr); 911ab8d36c9SPeter Brune fas = (SNES_FAS*)levelsnes->data; 912ab8d36c9SPeter Brune *mat = fas->restrct; 913ab8d36c9SPeter Brune PetscFunctionReturn(0); 914ab8d36c9SPeter Brune } 915ab8d36c9SPeter Brune 916ab8d36c9SPeter Brune 917ab8d36c9SPeter Brune /*@ 918ab8d36c9SPeter Brune SNESFASSetInjection - Sets the function to be used to inject the solution 919ab8d36c9SPeter Brune from level l to l-1. 920ab8d36c9SPeter Brune 921ab8d36c9SPeter Brune Input Parameters: 922ab8d36c9SPeter Brune + snes - the multigrid context 923ab8d36c9SPeter Brune . mat - the restriction matrix 924ab8d36c9SPeter Brune - level - the level (0 is coarsest) to supply [Do not supply 0] 925ab8d36c9SPeter Brune 926ab8d36c9SPeter Brune Level: advanced 927ab8d36c9SPeter Brune 928ab8d36c9SPeter Brune Notes: 929ab8d36c9SPeter Brune If you do not set this, the restriction and rscale is used to 930ab8d36c9SPeter Brune project the solution instead. 931ab8d36c9SPeter Brune 932ab8d36c9SPeter Brune .seealso: SNESFASSetInterpolation(), SNESFASSetRestriction() 933ab8d36c9SPeter Brune @*/ 93422d28d08SBarry Smith PetscErrorCode SNESFASSetInjection(SNES snes, PetscInt level, Mat mat) 93522d28d08SBarry Smith { 93622d28d08SBarry Smith SNES_FAS *fas; 937ab8d36c9SPeter Brune PetscErrorCode ierr; 938ab8d36c9SPeter Brune SNES levelsnes; 93922d28d08SBarry Smith 940ab8d36c9SPeter Brune PetscFunctionBegin; 941f833ba53SLisandro Dalcin PetscValidHeaderSpecificType(snes,SNES_CLASSID,1,SNESFAS); 942f833ba53SLisandro Dalcin if (mat) PetscValidHeaderSpecific(mat,MAT_CLASSID,3); 943ab8d36c9SPeter Brune ierr = SNESFASGetCycleSNES(snes, level, &levelsnes);CHKERRQ(ierr); 944ab8d36c9SPeter Brune fas = (SNES_FAS*)levelsnes->data; 945ab8d36c9SPeter Brune ierr = PetscObjectReference((PetscObject)mat);CHKERRQ(ierr); 946ab8d36c9SPeter Brune ierr = MatDestroy(&fas->inject);CHKERRQ(ierr); 9471aa26658SKarl Rupp 948ab8d36c9SPeter Brune fas->inject = mat; 949ab8d36c9SPeter Brune PetscFunctionReturn(0); 950ab8d36c9SPeter Brune } 951ab8d36c9SPeter Brune 952ab8d36c9SPeter Brune 953ab8d36c9SPeter Brune /*@ 954ab8d36c9SPeter Brune SNESFASGetInjection - Gets the matrix used to calculate the 955ab8d36c9SPeter Brune injection from l-1 to the lth level 956ab8d36c9SPeter Brune 957ab8d36c9SPeter Brune Input Parameters: 958ab8d36c9SPeter Brune + snes - the multigrid context 959ab8d36c9SPeter Brune - level - the level (0 is coarsest) to supply [do not supply 0] 960ab8d36c9SPeter Brune 961ab8d36c9SPeter Brune Output Parameters: 962ab8d36c9SPeter Brune . mat - the injection operator 963ab8d36c9SPeter Brune 964ab8d36c9SPeter Brune Level: advanced 965ab8d36c9SPeter Brune 966ab8d36c9SPeter Brune .seealso: SNESFASSetInjection(), SNESFASGetRestriction(), SNESFASGetInterpolation(), SNESFASGetRScale() 967ab8d36c9SPeter Brune @*/ 96822d28d08SBarry Smith PetscErrorCode SNESFASGetInjection(SNES snes, PetscInt level, Mat *mat) 96922d28d08SBarry Smith { 97022d28d08SBarry Smith SNES_FAS *fas; 971ab8d36c9SPeter Brune PetscErrorCode ierr; 972ab8d36c9SPeter Brune SNES levelsnes; 97322d28d08SBarry Smith 974ab8d36c9SPeter Brune PetscFunctionBegin; 975f833ba53SLisandro Dalcin PetscValidHeaderSpecificType(snes,SNES_CLASSID,1,SNESFAS); 976f833ba53SLisandro Dalcin PetscValidPointer(mat,3); 977ab8d36c9SPeter Brune ierr = SNESFASGetCycleSNES(snes, level, &levelsnes);CHKERRQ(ierr); 978ab8d36c9SPeter Brune fas = (SNES_FAS*)levelsnes->data; 979ab8d36c9SPeter Brune *mat = fas->inject; 980ab8d36c9SPeter Brune PetscFunctionReturn(0); 981ab8d36c9SPeter Brune } 982ab8d36c9SPeter Brune 983ab8d36c9SPeter Brune /*@ 984ab8d36c9SPeter Brune SNESFASSetRScale - Sets the scaling factor of the restriction 985ab8d36c9SPeter Brune operator from level l to l-1. 986ab8d36c9SPeter Brune 987ab8d36c9SPeter Brune Input Parameters: 988ab8d36c9SPeter Brune + snes - the multigrid context 989ab8d36c9SPeter Brune . rscale - the restriction scaling 990ab8d36c9SPeter Brune - level - the level (0 is coarsest) to supply [Do not supply 0] 991ab8d36c9SPeter Brune 992ab8d36c9SPeter Brune Level: advanced 993ab8d36c9SPeter Brune 994ab8d36c9SPeter Brune Notes: 995ab8d36c9SPeter Brune This is only used in the case that the injection is not set. 996ab8d36c9SPeter Brune 997ab8d36c9SPeter Brune .seealso: SNESFASSetInjection(), SNESFASSetRestriction() 998ab8d36c9SPeter Brune @*/ 99922d28d08SBarry Smith PetscErrorCode SNESFASSetRScale(SNES snes, PetscInt level, Vec rscale) 100022d28d08SBarry Smith { 1001ab8d36c9SPeter Brune SNES_FAS *fas; 1002ab8d36c9SPeter Brune PetscErrorCode ierr; 1003ab8d36c9SPeter Brune SNES levelsnes; 100422d28d08SBarry Smith 1005ab8d36c9SPeter Brune PetscFunctionBegin; 1006f833ba53SLisandro Dalcin PetscValidHeaderSpecificType(snes,SNES_CLASSID,1,SNESFAS); 1007f833ba53SLisandro Dalcin if (rscale) PetscValidHeaderSpecific(rscale,VEC_CLASSID,3); 1008ab8d36c9SPeter Brune ierr = SNESFASGetCycleSNES(snes, level, &levelsnes);CHKERRQ(ierr); 1009ab8d36c9SPeter Brune fas = (SNES_FAS*)levelsnes->data; 1010ab8d36c9SPeter Brune ierr = PetscObjectReference((PetscObject)rscale);CHKERRQ(ierr); 1011ab8d36c9SPeter Brune ierr = VecDestroy(&fas->rscale);CHKERRQ(ierr); 1012ab8d36c9SPeter Brune fas->rscale = rscale; 1013ab8d36c9SPeter Brune PetscFunctionReturn(0); 1014ab8d36c9SPeter Brune } 1015ab8d36c9SPeter Brune 1016ab8d36c9SPeter Brune /*@ 1017ab8d36c9SPeter Brune SNESFASGetSmoother - Gets the default smoother on a level. 1018ab8d36c9SPeter Brune 1019ab8d36c9SPeter Brune Input Parameters: 1020ab8d36c9SPeter Brune + snes - the multigrid context 1021ab8d36c9SPeter Brune - level - the level (0 is coarsest) to supply 1022ab8d36c9SPeter Brune 1023ab8d36c9SPeter Brune Output Parameters: 1024ab8d36c9SPeter Brune smooth - the smoother 1025ab8d36c9SPeter Brune 1026ab8d36c9SPeter Brune Level: advanced 1027ab8d36c9SPeter Brune 1028ab8d36c9SPeter Brune .seealso: SNESFASSetInjection(), SNESFASSetRestriction() 1029ab8d36c9SPeter Brune @*/ 103022d28d08SBarry Smith PetscErrorCode SNESFASGetSmoother(SNES snes, PetscInt level, SNES *smooth) 103122d28d08SBarry Smith { 1032ab8d36c9SPeter Brune SNES_FAS *fas; 1033ab8d36c9SPeter Brune PetscErrorCode ierr; 1034ab8d36c9SPeter Brune SNES levelsnes; 103522d28d08SBarry Smith 1036ab8d36c9SPeter Brune PetscFunctionBegin; 1037f833ba53SLisandro Dalcin PetscValidHeaderSpecificType(snes,SNES_CLASSID,1,SNESFAS); 1038f833ba53SLisandro Dalcin PetscValidPointer(smooth,3); 1039ab8d36c9SPeter Brune ierr = SNESFASGetCycleSNES(snes, level, &levelsnes);CHKERRQ(ierr); 1040ab8d36c9SPeter Brune fas = (SNES_FAS*)levelsnes->data; 1041ab8d36c9SPeter Brune if (!fas->smoothd) { 10423de4d1dbSPeter Brune ierr = SNESFASCycleCreateSmoother_Private(levelsnes, &fas->smoothd);CHKERRQ(ierr); 1043ab8d36c9SPeter Brune } 1044ab8d36c9SPeter Brune *smooth = fas->smoothd; 1045ab8d36c9SPeter Brune PetscFunctionReturn(0); 1046ab8d36c9SPeter Brune } 1047ab8d36c9SPeter Brune 1048ab8d36c9SPeter Brune /*@ 1049ab8d36c9SPeter Brune SNESFASGetSmootherDown - Gets the downsmoother on a level. 1050ab8d36c9SPeter Brune 1051ab8d36c9SPeter Brune Input Parameters: 1052ab8d36c9SPeter Brune + snes - the multigrid context 1053ab8d36c9SPeter Brune - level - the level (0 is coarsest) to supply 1054ab8d36c9SPeter Brune 1055ab8d36c9SPeter Brune Output Parameters: 1056ab8d36c9SPeter Brune smooth - the smoother 1057ab8d36c9SPeter Brune 1058ab8d36c9SPeter Brune Level: advanced 1059ab8d36c9SPeter Brune 1060ab8d36c9SPeter Brune .seealso: SNESFASSetInjection(), SNESFASSetRestriction() 1061ab8d36c9SPeter Brune @*/ 106222d28d08SBarry Smith PetscErrorCode SNESFASGetSmootherDown(SNES snes, PetscInt level, SNES *smooth) 106322d28d08SBarry Smith { 1064ab8d36c9SPeter Brune SNES_FAS *fas; 1065ab8d36c9SPeter Brune PetscErrorCode ierr; 1066ab8d36c9SPeter Brune SNES levelsnes; 106722d28d08SBarry Smith 1068ab8d36c9SPeter Brune PetscFunctionBegin; 1069f833ba53SLisandro Dalcin PetscValidHeaderSpecificType(snes,SNES_CLASSID,1,SNESFAS); 1070f833ba53SLisandro Dalcin PetscValidPointer(smooth,3); 1071ab8d36c9SPeter Brune ierr = SNESFASGetCycleSNES(snes, level, &levelsnes);CHKERRQ(ierr); 1072ab8d36c9SPeter Brune fas = (SNES_FAS*)levelsnes->data; 1073ab8d36c9SPeter Brune /* if the user chooses to differentiate smoothers, create them both at this point */ 1074ab8d36c9SPeter Brune if (!fas->smoothd) { 10753de4d1dbSPeter Brune ierr = SNESFASCycleCreateSmoother_Private(levelsnes, &fas->smoothd);CHKERRQ(ierr); 1076ab8d36c9SPeter Brune } 1077ab8d36c9SPeter Brune if (!fas->smoothu) { 10783de4d1dbSPeter Brune ierr = SNESFASCycleCreateSmoother_Private(levelsnes, &fas->smoothu);CHKERRQ(ierr); 1079ab8d36c9SPeter Brune } 1080ab8d36c9SPeter Brune *smooth = fas->smoothd; 1081ab8d36c9SPeter Brune PetscFunctionReturn(0); 1082ab8d36c9SPeter Brune } 1083ab8d36c9SPeter Brune 1084ab8d36c9SPeter Brune /*@ 1085ab8d36c9SPeter Brune SNESFASGetSmootherUp - Gets the upsmoother on a level. 1086ab8d36c9SPeter Brune 1087ab8d36c9SPeter Brune Input Parameters: 1088ab8d36c9SPeter Brune + snes - the multigrid context 1089ab8d36c9SPeter Brune - level - the level (0 is coarsest) 1090ab8d36c9SPeter Brune 1091ab8d36c9SPeter Brune Output Parameters: 1092ab8d36c9SPeter Brune smooth - the smoother 1093ab8d36c9SPeter Brune 1094ab8d36c9SPeter Brune Level: advanced 1095ab8d36c9SPeter Brune 1096ab8d36c9SPeter Brune .seealso: SNESFASSetInjection(), SNESFASSetRestriction() 1097ab8d36c9SPeter Brune @*/ 109822d28d08SBarry Smith PetscErrorCode SNESFASGetSmootherUp(SNES snes, PetscInt level, SNES *smooth) 109922d28d08SBarry Smith { 1100ab8d36c9SPeter Brune SNES_FAS *fas; 1101ab8d36c9SPeter Brune PetscErrorCode ierr; 1102ab8d36c9SPeter Brune SNES levelsnes; 110322d28d08SBarry Smith 1104ab8d36c9SPeter Brune PetscFunctionBegin; 1105f833ba53SLisandro Dalcin PetscValidHeaderSpecificType(snes,SNES_CLASSID,1,SNESFAS); 1106f833ba53SLisandro Dalcin PetscValidPointer(smooth,3); 1107ab8d36c9SPeter Brune ierr = SNESFASGetCycleSNES(snes, level, &levelsnes);CHKERRQ(ierr); 1108ab8d36c9SPeter Brune fas = (SNES_FAS*)levelsnes->data; 1109ab8d36c9SPeter Brune /* if the user chooses to differentiate smoothers, create them both at this point */ 1110ab8d36c9SPeter Brune if (!fas->smoothd) { 11113de4d1dbSPeter Brune ierr = SNESFASCycleCreateSmoother_Private(levelsnes, &fas->smoothd);CHKERRQ(ierr); 1112ab8d36c9SPeter Brune } 1113ab8d36c9SPeter Brune if (!fas->smoothu) { 11143de4d1dbSPeter Brune ierr = SNESFASCycleCreateSmoother_Private(levelsnes, &fas->smoothu);CHKERRQ(ierr); 1115ab8d36c9SPeter Brune } 1116ab8d36c9SPeter Brune *smooth = fas->smoothu; 1117ab8d36c9SPeter Brune PetscFunctionReturn(0); 1118ab8d36c9SPeter Brune } 1119d6ad1212SPeter Brune 1120d6ad1212SPeter Brune /*@ 1121d6ad1212SPeter Brune SNESFASGetCoarseSolve - Gets the coarsest solver. 1122d6ad1212SPeter Brune 1123d6ad1212SPeter Brune Input Parameters: 1124a3a80b83SMatthew G. Knepley . snes - the multigrid context 1125d6ad1212SPeter Brune 1126d6ad1212SPeter Brune Output Parameters: 1127a3a80b83SMatthew G. Knepley . coarse - the coarse-level solver 1128d6ad1212SPeter Brune 1129d6ad1212SPeter Brune Level: advanced 1130d6ad1212SPeter Brune 1131d6ad1212SPeter Brune .seealso: SNESFASSetInjection(), SNESFASSetRestriction() 1132d6ad1212SPeter Brune @*/ 1133a3a80b83SMatthew G. Knepley PetscErrorCode SNESFASGetCoarseSolve(SNES snes, SNES *coarse) 113422d28d08SBarry Smith { 1135d6ad1212SPeter Brune SNES_FAS *fas; 1136d6ad1212SPeter Brune PetscErrorCode ierr; 1137d6ad1212SPeter Brune SNES levelsnes; 113822d28d08SBarry Smith 1139d6ad1212SPeter Brune PetscFunctionBegin; 1140f833ba53SLisandro Dalcin PetscValidHeaderSpecificType(snes,SNES_CLASSID,1,SNESFAS); 1141f833ba53SLisandro Dalcin PetscValidPointer(coarse,3); 1142d6ad1212SPeter Brune ierr = SNESFASGetCycleSNES(snes, 0, &levelsnes);CHKERRQ(ierr); 1143d6ad1212SPeter Brune fas = (SNES_FAS*)levelsnes->data; 1144d6ad1212SPeter Brune /* if the user chooses to differentiate smoothers, create them both at this point */ 1145d6ad1212SPeter Brune if (!fas->smoothd) { 11463de4d1dbSPeter Brune ierr = SNESFASCycleCreateSmoother_Private(levelsnes, &fas->smoothd);CHKERRQ(ierr); 1147d6ad1212SPeter Brune } 1148a3a80b83SMatthew G. Knepley *coarse = fas->smoothd; 1149d6ad1212SPeter Brune PetscFunctionReturn(0); 1150d6ad1212SPeter Brune } 1151928e959bSPeter Brune 1152928e959bSPeter Brune /*@ 1153928e959bSPeter Brune SNESFASFullSetDownSweep - Smooth during the initial downsweep for SNESFAS 1154928e959bSPeter Brune 1155928e959bSPeter Brune Logically Collective on SNES 1156928e959bSPeter Brune 1157928e959bSPeter Brune Input Parameters: 1158928e959bSPeter Brune + snes - the multigrid context 1159928e959bSPeter Brune - swp - whether to downsweep or not 1160928e959bSPeter Brune 1161928e959bSPeter Brune Options Database Key: 1162928e959bSPeter Brune . -snes_fas_full_downsweep - Sets number of pre-smoothing steps 1163928e959bSPeter Brune 1164928e959bSPeter Brune Level: advanced 1165928e959bSPeter Brune 1166928e959bSPeter Brune .seealso: SNESFASSetNumberSmoothUp() 1167928e959bSPeter Brune @*/ 1168928e959bSPeter Brune PetscErrorCode SNESFASFullSetDownSweep(SNES snes,PetscBool swp) 1169928e959bSPeter Brune { 1170f833ba53SLisandro Dalcin SNES_FAS *fas; 1171f833ba53SLisandro Dalcin PetscErrorCode ierr; 1172928e959bSPeter Brune 1173928e959bSPeter Brune PetscFunctionBegin; 1174f833ba53SLisandro Dalcin PetscValidHeaderSpecificType(snes,SNES_CLASSID,1,SNESFAS); 1175f833ba53SLisandro Dalcin fas = (SNES_FAS*)snes->data; 1176928e959bSPeter Brune fas->full_downsweep = swp; 1177928e959bSPeter Brune if (fas->next) { 1178928e959bSPeter Brune ierr = SNESFASFullSetDownSweep(fas->next,swp);CHKERRQ(ierr); 1179928e959bSPeter Brune } 1180928e959bSPeter Brune PetscFunctionReturn(0); 1181928e959bSPeter Brune } 1182