static PetscErrorCode SNESSetUp_QN(SNES snes) { SNES_QN *qn = (SNES_QN*)snes->data; PetscErrorCode ierr; PetscFunctionBegin; ierr = VecDuplicateVecs(snes->vec_sol, qn->m, &qn->U);CHKERRQ(ierr); ierr = VecDuplicateVecs(snes->vec_sol, qn->m, &qn->V);CHKERRQ(ierr); ierr = PetscMalloc3(qn->m, PetscScalar, &qn->alpha, qn->m, PetscScalar, &qn->beta, qn->m, PetscScalar, &qn->dXtdF);CHKERRQ(ierr); if (qn->singlereduction) { ierr = PetscMalloc3(qn->m*qn->m, PetscScalar, &qn->dXdFmat, qn->m, PetscScalar, &qn->dFtdX, qn->m, PetscScalar, &qn->YtdX);CHKERRQ(ierr); } ierr = SNESSetWorkVecs(snes,4);CHKERRQ(ierr); /* set up the line search */ if (qn->scale_type == SNES_QN_SCALE_JACOBIAN) { ierr = SNESSetUpMatrices(snes);CHKERRQ(ierr); } if (snes->pcside == PC_LEFT && snes->functype == SNES_FUNCTION_DEFAULT) {snes->functype = SNES_FUNCTION_UNPRECONDITIONED;} PetscFunctionReturn(0); }
static PetscErrorCode SNESSetUp_KSPONLY(SNES snes) { PetscErrorCode ierr; PetscFunctionBegin; ierr = SNESSetUpMatrices(snes);CHKERRQ(ierr); PetscFunctionReturn(0); }
/*------------------------------------------------------------*/ static PetscErrorCode SNESSetUp_NEWTONTR(SNES snes) { PetscErrorCode ierr; PetscFunctionBegin; ierr = SNESSetWorkVecs(snes,3);CHKERRQ(ierr); ierr = SNESSetUpMatrices(snes);CHKERRQ(ierr); PetscFunctionReturn(0); }
PetscErrorCode SNESSetUp_NEWTONLS(SNES snes) { PetscErrorCode ierr; PetscFunctionBegin; ierr = SNESSetUpMatrices(snes);CHKERRQ(ierr); if (snes->pcside == PC_LEFT && snes->functype == SNES_FUNCTION_DEFAULT) snes->functype = SNES_FUNCTION_PRECONDITIONED; PetscFunctionReturn(0); }
PetscErrorCode SNESSetUp_NEWTONLS(SNES snes) { PetscErrorCode ierr; PetscFunctionBegin; ierr = SNESDefaultGetWork(snes,2);CHKERRQ(ierr); ierr = SNESSetUpMatrices(snes);CHKERRQ(ierr); PetscFunctionReturn(0); }
static PetscErrorCode SNESSetUp_MS(SNES snes) { SNES_MS * ms = (SNES_MS *)snes->data; PetscErrorCode ierr; PetscFunctionBegin; if (!ms->tableau) {ierr = SNESMSSetType(snes,SNESMSDefault);CHKERRQ(ierr);} ierr = SNESDefaultGetWork(snes,3);CHKERRQ(ierr); ierr = SNESSetUpMatrices(snes);CHKERRQ(ierr); PetscFunctionReturn(0); }
EXTERN_C_END #undef __FUNCT__ #define __FUNCT__ "SNESSetUp_NCG" PetscErrorCode SNESSetUp_NCG(SNES snes) { PetscErrorCode ierr; PetscFunctionBegin; ierr = SNESDefaultGetWork(snes,2); CHKERRQ(ierr); ierr = SNESSetUpMatrices(snes); CHKERRQ(ierr); ierr = SNESLineSearchRegisterDynamic(SNESLINESEARCHNCGLINEAR, PETSC_NULL,"SNESLineSearchCreate_NCGLinear", SNESLineSearchCreate_NCGLinear); CHKERRQ(ierr); PetscFunctionReturn(0); }
static PetscErrorCode SNESSetUp_QN(SNES snes) { SNES_QN *qn = (SNES_QN*)snes->data; PetscErrorCode ierr; DM dm; PetscFunctionBegin; if (!snes->vec_sol) { ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); ierr = DMCreateGlobalVector(dm,&snes->vec_sol);CHKERRQ(ierr); } ierr = VecDuplicateVecs(snes->vec_sol, qn->m, &qn->U);CHKERRQ(ierr); if (qn->type != SNES_QN_BROYDEN) ierr = VecDuplicateVecs(snes->vec_sol, qn->m, &qn->V);CHKERRQ(ierr); ierr = PetscMalloc4(qn->m,&qn->alpha,qn->m,&qn->beta,qn->m,&qn->dXtdF,qn->m,&qn->lambda);CHKERRQ(ierr); if (qn->singlereduction) { ierr = PetscMalloc3(qn->m*qn->m,&qn->dXdFmat,qn->m,&qn->dFtdX,qn->m,&qn->YtdX);CHKERRQ(ierr); } ierr = SNESSetWorkVecs(snes,4);CHKERRQ(ierr); /* set method defaults */ if (qn->scale_type == SNES_QN_SCALE_DEFAULT) { if (qn->type == SNES_QN_BADBROYDEN) { qn->scale_type = SNES_QN_SCALE_NONE; } else { qn->scale_type = SNES_QN_SCALE_SHANNO; } } if (qn->restart_type == SNES_QN_RESTART_DEFAULT) { if (qn->type == SNES_QN_LBFGS) { qn->restart_type = SNES_QN_RESTART_POWELL; } else { qn->restart_type = SNES_QN_RESTART_PERIODIC; } } if (qn->scale_type == SNES_QN_SCALE_JACOBIAN) { ierr = SNESSetUpMatrices(snes);CHKERRQ(ierr); } if (snes->pcside == PC_LEFT && snes->functype == SNES_FUNCTION_DEFAULT) {snes->functype = SNES_FUNCTION_UNPRECONDITIONED;} PetscFunctionReturn(0); }
PetscErrorCode SNESLineSearchApply_NCGLinear(SNESLineSearch linesearch) { PetscScalar alpha, ptAp; Vec X, Y, F, W; SNES snes; PetscErrorCode ierr; PetscReal *fnorm, *xnorm, *ynorm; MatStructure flg = DIFFERENT_NONZERO_PATTERN; PetscFunctionBegin; ierr = SNESLineSearchGetSNES(linesearch, &snes);CHKERRQ(ierr); X = linesearch->vec_sol; W = linesearch->vec_sol_new; F = linesearch->vec_func; Y = linesearch->vec_update; fnorm = &linesearch->fnorm; xnorm = &linesearch->xnorm; ynorm = &linesearch->ynorm; if (!snes->jacobian) { ierr = SNESSetUpMatrices(snes);CHKERRQ(ierr); } /* The exact step size for unpreconditioned linear CG is just: alpha = (r, r) / (p, Ap) = (f, f) / (y, Jy) */ ierr = SNESComputeJacobian(snes, X, &snes->jacobian, &snes->jacobian_pre, &flg);CHKERRQ(ierr); ierr = VecDot(F, F, &alpha);CHKERRQ(ierr); ierr = MatMult(snes->jacobian, Y, W);CHKERRQ(ierr); ierr = VecDot(Y, W, &ptAp);CHKERRQ(ierr); alpha = alpha / ptAp; ierr = VecAXPY(X,-alpha,Y);CHKERRQ(ierr); ierr = SNESComputeFunction(snes,X,F);CHKERRQ(ierr); ierr = VecNorm(F,NORM_2,fnorm);CHKERRQ(ierr); ierr = VecNorm(X,NORM_2,xnorm);CHKERRQ(ierr); ierr = VecNorm(Y,NORM_2,ynorm);CHKERRQ(ierr); PetscFunctionReturn(0); }
PetscErrorCode SNESSetUp_VI(SNES snes) { PetscErrorCode ierr; PetscInt i_start[3],i_end[3]; PetscFunctionBegin; ierr = SNESSetWorkVecs(snes,1);CHKERRQ(ierr); ierr = SNESSetUpMatrices(snes);CHKERRQ(ierr); if (!snes->ops->computevariablebounds && snes->dm) { PetscBool flag; ierr = DMHasVariableBounds(snes->dm, &flag);CHKERRQ(ierr); snes->ops->computevariablebounds = SNESVIDMComputeVariableBounds; } if (!snes->usersetbounds) { if (snes->ops->computevariablebounds) { if (!snes->xl) {ierr = VecDuplicate(snes->vec_sol,&snes->xl);CHKERRQ(ierr);} if (!snes->xu) {ierr = VecDuplicate(snes->vec_sol,&snes->xu);CHKERRQ(ierr);} ierr = (*snes->ops->computevariablebounds)(snes,snes->xl,snes->xu);CHKERRQ(ierr); } else if (!snes->xl && !snes->xu) { /* If the lower and upper bound on variables are not set, set it to -Inf and Inf */ ierr = VecDuplicate(snes->vec_sol, &snes->xl);CHKERRQ(ierr); ierr = VecSet(snes->xl,SNES_VI_NINF);CHKERRQ(ierr); ierr = VecDuplicate(snes->vec_sol, &snes->xu);CHKERRQ(ierr); ierr = VecSet(snes->xu,SNES_VI_INF);CHKERRQ(ierr); } else { /* Check if lower bound, upper bound and solution vector distribution across the processors is identical */ ierr = VecGetOwnershipRange(snes->vec_sol,i_start,i_end);CHKERRQ(ierr); ierr = VecGetOwnershipRange(snes->xl,i_start+1,i_end+1);CHKERRQ(ierr); ierr = VecGetOwnershipRange(snes->xu,i_start+2,i_end+2);CHKERRQ(ierr); if ((i_start[0] != i_start[1]) || (i_start[0] != i_start[2]) || (i_end[0] != i_end[1]) || (i_end[0] != i_end[2])) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Distribution of lower bound, upper bound and the solution vector should be identical across all the processors."); } } PetscFunctionReturn(0); }
PetscErrorCode SNESSetUp_NASM(SNES snes) { SNES_NASM *nasm = (SNES_NASM*)snes->data; PetscErrorCode ierr; DM dm,subdm; DM *subdms; PetscInt i; const char *optionsprefix; Vec F; PetscMPIInt size; KSP ksp; PC pc; PetscFunctionBegin; if (!nasm->subsnes) { ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); if (dm) { nasm->usesdm = PETSC_TRUE; ierr = DMCreateDomainDecomposition(dm,&nasm->n,NULL,NULL,NULL,&subdms);CHKERRQ(ierr); if (!subdms) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"DM has no default decomposition defined. Set subsolves manually with SNESNASMSetSubdomains()."); ierr = DMCreateDomainDecompositionScatters(dm,nasm->n,subdms,&nasm->iscatter,&nasm->oscatter,&nasm->gscatter);CHKERRQ(ierr); ierr = SNESGetOptionsPrefix(snes, &optionsprefix);CHKERRQ(ierr); ierr = PetscMalloc(nasm->n*sizeof(SNES),&nasm->subsnes);CHKERRQ(ierr); for (i=0; i<nasm->n; i++) { ierr = SNESCreate(PETSC_COMM_SELF,&nasm->subsnes[i]);CHKERRQ(ierr); ierr = SNESAppendOptionsPrefix(nasm->subsnes[i],optionsprefix);CHKERRQ(ierr); ierr = SNESAppendOptionsPrefix(nasm->subsnes[i],"sub_");CHKERRQ(ierr); ierr = SNESSetDM(nasm->subsnes[i],subdms[i]);CHKERRQ(ierr); ierr = MPI_Comm_size(PetscObjectComm((PetscObject)nasm->subsnes[i]),&size);CHKERRQ(ierr); if (size == 1) { ierr = SNESGetKSP(nasm->subsnes[i],&ksp);CHKERRQ(ierr); ierr = KSPGetPC(ksp,&pc);CHKERRQ(ierr); ierr = KSPSetType(ksp,KSPPREONLY);CHKERRQ(ierr); ierr = PCSetType(pc,PCLU);CHKERRQ(ierr); } ierr = SNESSetFromOptions(nasm->subsnes[i]);CHKERRQ(ierr); ierr = DMDestroy(&subdms[i]);CHKERRQ(ierr); } ierr = PetscFree(subdms);CHKERRQ(ierr); } else SETERRQ(PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_WRONGSTATE,"Cannot construct local problems automatically without a DM!"); } else SETERRQ(PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_WRONGSTATE,"Must set subproblems manually if there is no DM!"); /* allocate the global vectors */ if (!nasm->x) { ierr = PetscMalloc(nasm->n*sizeof(Vec),&nasm->x);CHKERRQ(ierr); ierr = PetscMemzero(nasm->x,nasm->n*sizeof(Vec));CHKERRQ(ierr); } if (!nasm->xl) { ierr = PetscMalloc(nasm->n*sizeof(Vec),&nasm->xl);CHKERRQ(ierr); ierr = PetscMemzero(nasm->xl,nasm->n*sizeof(Vec));CHKERRQ(ierr); } if (!nasm->y) { ierr = PetscMalloc(nasm->n*sizeof(Vec),&nasm->y);CHKERRQ(ierr); ierr = PetscMemzero(nasm->y,nasm->n*sizeof(Vec));CHKERRQ(ierr); } if (!nasm->b) { ierr = PetscMalloc(nasm->n*sizeof(Vec),&nasm->b);CHKERRQ(ierr); ierr = PetscMemzero(nasm->b,nasm->n*sizeof(Vec));CHKERRQ(ierr); } for (i=0; i<nasm->n; i++) { ierr = SNESGetFunction(nasm->subsnes[i],&F,NULL,NULL);CHKERRQ(ierr); if (!nasm->x[i]) {ierr = VecDuplicate(F,&nasm->x[i]);CHKERRQ(ierr);} if (!nasm->y[i]) {ierr = VecDuplicate(F,&nasm->y[i]);CHKERRQ(ierr);} if (!nasm->b[i]) {ierr = VecDuplicate(F,&nasm->b[i]);CHKERRQ(ierr);} if (!nasm->xl[i]) { ierr = SNESGetDM(nasm->subsnes[i],&subdm);CHKERRQ(ierr); ierr = DMCreateLocalVector(subdm,&nasm->xl[i]);CHKERRQ(ierr); } ierr = DMGlobalToLocalHookAdd(subdm,DMGlobalToLocalSubDomainDirichletHook_Private,NULL,nasm->xl[i]);CHKERRQ(ierr); } if (nasm->finaljacobian) { ierr = SNESSetUpMatrices(snes);CHKERRQ(ierr); if (nasm->fjtype == 2) { ierr = VecDuplicate(snes->vec_sol,&nasm->xinit);CHKERRQ(ierr); } for (i=0; i<nasm->n;i++) { ierr = SNESSetUpMatrices(nasm->subsnes[i]);CHKERRQ(ierr); } } PetscFunctionReturn(0); }
PETSC_EXTERN PetscErrorCode SNESComputeNGSDefaultSecant(SNES snes,Vec X,Vec B,void *ctx) { PetscErrorCode ierr; SNES_NGS *gs = (SNES_NGS*)snes->data; PetscInt i,j,k,ncolors; DM dm; PetscBool flg; ISColoring coloring = gs->coloring; MatColoring mc; Vec W,G,F; PetscScalar h=gs->h; IS *coloris; PetscScalar f,g,x,w,d; PetscReal dxt,xt,ft,ft1=0; const PetscInt *idx; PetscInt size,s; PetscReal atol,rtol,stol; PetscInt its; PetscErrorCode (*func)(SNES,Vec,Vec,void*); void *fctx; PetscBool mat = gs->secant_mat,equal,isdone,alldone; PetscScalar *xa,*fa,*wa,*ga; PetscFunctionBegin; if (snes->nwork < 3) { ierr = SNESSetWorkVecs(snes,3);CHKERRQ(ierr); } W = snes->work[0]; G = snes->work[1]; F = snes->work[2]; ierr = VecGetOwnershipRange(X,&s,NULL);CHKERRQ(ierr); ierr = SNESNGSGetTolerances(snes,&atol,&rtol,&stol,&its);CHKERRQ(ierr); ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); ierr = SNESGetFunction(snes,NULL,&func,&fctx);CHKERRQ(ierr); if (!coloring) { /* create the coloring */ ierr = DMHasColoring(dm,&flg);CHKERRQ(ierr); if (flg && !mat) { ierr = DMCreateColoring(dm,IS_COLORING_GLOBAL,&coloring);CHKERRQ(ierr); } else { if (!snes->jacobian) {ierr = SNESSetUpMatrices(snes);CHKERRQ(ierr);} ierr = MatColoringCreate(snes->jacobian,&mc);CHKERRQ(ierr); ierr = MatColoringSetDistance(mc,1);CHKERRQ(ierr); ierr = MatColoringSetFromOptions(mc);CHKERRQ(ierr); ierr = MatColoringApply(mc,&coloring);CHKERRQ(ierr); ierr = MatColoringDestroy(&mc);CHKERRQ(ierr); } gs->coloring = coloring; } ierr = ISColoringGetIS(coloring,&ncolors,&coloris);CHKERRQ(ierr); ierr = VecEqual(X,snes->vec_sol,&equal);CHKERRQ(ierr); if (equal && snes->normschedule == SNES_NORM_ALWAYS) { /* assume that the function is already computed */ ierr = VecCopy(snes->vec_func,F);CHKERRQ(ierr); } else { ierr = PetscLogEventBegin(SNES_NGSFuncEval,snes,X,B,0);CHKERRQ(ierr); ierr = (*func)(snes,X,F,fctx);CHKERRQ(ierr); ierr = PetscLogEventEnd(SNES_NGSFuncEval,snes,X,B,0);CHKERRQ(ierr); if (B) {ierr = VecAXPY(F,-1.0,B);CHKERRQ(ierr);} } ierr = VecGetArray(X,&xa);CHKERRQ(ierr); ierr = VecGetArray(F,&fa);CHKERRQ(ierr); ierr = VecGetArray(G,&ga);CHKERRQ(ierr); ierr = VecGetArray(W,&wa);CHKERRQ(ierr); for (i=0;i<ncolors;i++) { ierr = ISGetIndices(coloris[i],&idx);CHKERRQ(ierr); ierr = ISGetLocalSize(coloris[i],&size);CHKERRQ(ierr); ierr = VecCopy(X,W);CHKERRQ(ierr); for (j=0;j<size;j++) { wa[idx[j]-s] += h; } ierr = PetscLogEventBegin(SNES_NGSFuncEval,snes,X,B,0);CHKERRQ(ierr); ierr = (*func)(snes,W,G,fctx);CHKERRQ(ierr); ierr = PetscLogEventEnd(SNES_NGSFuncEval,snes,X,B,0);CHKERRQ(ierr); if (B) {ierr = VecAXPY(G,-1.0,B);CHKERRQ(ierr);} for (k=0;k<its;k++) { dxt = 0.; xt = 0.; ft = 0.; for (j=0;j<size;j++) { f = fa[idx[j]-s]; x = xa[idx[j]-s]; g = ga[idx[j]-s]; w = wa[idx[j]-s]; if (PetscAbsScalar(g-f) > atol) { /* This is equivalent to d = x - (h*f) / PetscRealPart(g-f) */ d = (x*g-w*f) / PetscRealPart(g-f); } else { d = x; } dxt += PetscRealPart(PetscSqr(d-x)); xt += PetscRealPart(PetscSqr(x)); ft += PetscRealPart(PetscSqr(f)); xa[idx[j]-s] = d; } if (k == 0) ft1 = PetscSqrtReal(ft); if (k<its-1) { isdone = PETSC_FALSE; if (stol*PetscSqrtReal(xt) > PetscSqrtReal(dxt)) isdone = PETSC_TRUE; if (PetscSqrtReal(ft) < atol) isdone = PETSC_TRUE; if (rtol*ft1 > PetscSqrtReal(ft)) isdone = PETSC_TRUE; ierr = MPIU_Allreduce(&isdone,&alldone,1,MPIU_BOOL,MPI_BAND,PetscObjectComm((PetscObject)snes));CHKERRQ(ierr); if (alldone) break; } if (i < ncolors-1 || k < its-1) { ierr = PetscLogEventBegin(SNES_NGSFuncEval,snes,X,B,0);CHKERRQ(ierr); ierr = (*func)(snes,X,F,fctx);CHKERRQ(ierr); ierr = PetscLogEventEnd(SNES_NGSFuncEval,snes,X,B,0);CHKERRQ(ierr); if (B) {ierr = VecAXPY(F,-1.0,B);CHKERRQ(ierr);} } if (k<its-1) { ierr = VecSwap(X,W);CHKERRQ(ierr); ierr = VecSwap(F,G);CHKERRQ(ierr); } } } ierr = VecRestoreArray(X,&xa);CHKERRQ(ierr); ierr = VecRestoreArray(F,&fa);CHKERRQ(ierr); ierr = VecRestoreArray(G,&ga);CHKERRQ(ierr); ierr = VecRestoreArray(W,&wa);CHKERRQ(ierr); ierr = ISColoringRestoreIS(coloring,&coloris);CHKERRQ(ierr); PetscFunctionReturn(0); }