本文整理汇总了C++中PetscObjectComm函数的典型用法代码示例。如果您正苦于以下问题:C++ PetscObjectComm函数的具体用法?C++ PetscObjectComm怎么用?C++ PetscObjectComm使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。
在下文中一共展示了PetscObjectComm函数的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: DMGlobalToLocalBegin
/*@
DMGlobalToLocalSolve - Solve for the global vector that is mapped to a given local vector by DMGlobalToLocalBegin()/DMGlobalToLocalEnd() with mode
= INSERT_VALUES. It is assumed that the sum of all the local vector sizes is greater than or equal to the global vector size, so the solution is
a least-squares solution. It is also assumed that DMLocalToGlobalBegin()/DMLocalToGlobalEnd() with mode = ADD_VALUES is the adjoint of the
global-to-local map, so that the least-squares solution may be found by the normal equations.
collective
Input Parameters:
+ dm - The DM object
. x - The local vector
- y - The global vector: the input value of globalVec is used as an initial guess
Output Parameters:
. y - The least-squares solution
Level: advanced
Note: If the DM is of type DMPLEX, then y is the solution of L' * D * L * y = L' * D * x, where D is a diagonal mask that is 1 for every point in
the union of the closures of the local cells and 0 otherwise. This difference is only relevant if there are anchor points that are not in the
closure of any local cell (see DMPlexGetAnchors()/DMPlexSetAnchors()).
.seealso: DMGlobalToLocalBegin(), DMGlobalToLocalEnd(), DMLocalToGlobalBegin(), DMLocalToGlobalEnd(), DMPlexGetAnchors(), DMPlexSetAnchors()
@*/
PetscErrorCode DMGlobalToLocalSolve(DM dm, Vec x, Vec y)
{
Mat CtC;
PetscInt n, N, cStart, cEnd, c;
PetscBool isPlex;
KSP ksp;
PC pc;
Vec global, mask=NULL;
projectConstraintsCtx ctx;
PetscErrorCode ierr;
PetscFunctionBegin;
ierr = PetscObjectTypeCompare((PetscObject)dm,DMPLEX,&isPlex);CHKERRQ(ierr);
if (isPlex) {
/* mark points in the closure */
ierr = DMGetLocalVector(dm,&mask);CHKERRQ(ierr);
ierr = VecSet(mask,0.0);CHKERRQ(ierr);
ierr = DMPlexGetHeightStratum(dm,0,&cStart,&cEnd);CHKERRQ(ierr);
if (cEnd > cStart) {
PetscScalar *ones;
PetscInt numValues, i;
ierr = DMPlexVecGetClosure(dm,NULL,mask,cStart,&numValues,NULL);CHKERRQ(ierr);
ierr = PetscMalloc1(numValues,&ones);CHKERRQ(ierr);
for (i = 0; i < numValues; i++) {
ones[i] = 1.;
}
for (c = cStart; c < cEnd; c++) {
ierr = DMPlexVecSetClosure(dm,NULL,mask,c,ones,INSERT_VALUES);CHKERRQ(ierr);
}
ierr = PetscFree(ones);CHKERRQ(ierr);
}
}
ctx.dm = dm;
ctx.mask = mask;
ierr = VecGetSize(y,&N);CHKERRQ(ierr);
ierr = VecGetLocalSize(y,&n);CHKERRQ(ierr);
ierr = MatCreate(PetscObjectComm((PetscObject)dm),&CtC);CHKERRQ(ierr);
ierr = MatSetSizes(CtC,n,n,N,N);CHKERRQ(ierr);
ierr = MatSetType(CtC,MATSHELL);CHKERRQ(ierr);
ierr = MatSetUp(CtC);CHKERRQ(ierr);
ierr = MatShellSetContext(CtC,&ctx);CHKERRQ(ierr);
ierr = MatShellSetOperation(CtC,MATOP_MULT,(void(*)(void))MatMult_GlobalToLocalNormal);CHKERRQ(ierr);
ierr = KSPCreate(PetscObjectComm((PetscObject)dm),&ksp);CHKERRQ(ierr);
ierr = KSPSetOperators(ksp,CtC,CtC);CHKERRQ(ierr);
ierr = KSPSetType(ksp,KSPCG);CHKERRQ(ierr);
ierr = KSPGetPC(ksp,&pc);CHKERRQ(ierr);
ierr = PCSetType(pc,PCNONE);CHKERRQ(ierr);
ierr = KSPSetInitialGuessNonzero(ksp,PETSC_TRUE);CHKERRQ(ierr);
ierr = KSPSetUp(ksp);CHKERRQ(ierr);
ierr = DMGetGlobalVector(dm,&global);CHKERRQ(ierr);
ierr = VecSet(global,0.);CHKERRQ(ierr);
if (mask) {ierr = VecPointwiseMult(x,mask,x);CHKERRQ(ierr);}
ierr = DMLocalToGlobalBegin(dm,x,ADD_VALUES,global);CHKERRQ(ierr);
ierr = DMLocalToGlobalEnd(dm,x,ADD_VALUES,global);CHKERRQ(ierr);
ierr = KSPSetFromOptions(ksp);CHKERRQ(ierr);
ierr = KSPSolve(ksp,global,y);CHKERRQ(ierr);
ierr = DMRestoreGlobalVector(dm,&global);CHKERRQ(ierr);
/* clean up */
if (isPlex) {
ierr = DMRestoreLocalVector(dm,&mask);CHKERRQ(ierr);
}
ierr = KSPDestroy(&ksp);CHKERRQ(ierr);
ierr = MatDestroy(&CtC);CHKERRQ(ierr);
PetscFunctionReturn(0);
}
示例2: SNESSetFromOptions_FAS
PetscErrorCode SNESSetFromOptions_FAS(PetscOptionItems *PetscOptionsObject,SNES snes)
{
SNES_FAS *fas = (SNES_FAS*) snes->data;
PetscInt levels = 1;
PetscBool flg = PETSC_FALSE, upflg = PETSC_FALSE, downflg = PETSC_FALSE, monflg = PETSC_FALSE, galerkinflg = PETSC_FALSE,continuationflg = PETSC_FALSE;
PetscErrorCode ierr;
SNESFASType fastype;
const char *optionsprefix;
SNESLineSearch linesearch;
PetscInt m, n_up, n_down;
SNES next;
PetscBool isFine;
PetscFunctionBegin;
ierr = SNESFASCycleIsFine(snes, &isFine);CHKERRQ(ierr);
ierr = PetscOptionsHead(PetscOptionsObject,"SNESFAS Options-----------------------------------");CHKERRQ(ierr);
/* number of levels -- only process most options on the finest level */
if (isFine) {
ierr = PetscOptionsInt("-snes_fas_levels", "Number of Levels", "SNESFASSetLevels", levels, &levels, &flg);CHKERRQ(ierr);
if (!flg && snes->dm) {
ierr = DMGetRefineLevel(snes->dm,&levels);CHKERRQ(ierr);
levels++;
fas->usedmfornumberoflevels = PETSC_TRUE;
}
ierr = SNESFASSetLevels(snes, levels, NULL);CHKERRQ(ierr);
fastype = fas->fastype;
ierr = PetscOptionsEnum("-snes_fas_type","FAS correction type","SNESFASSetType",SNESFASTypes,(PetscEnum)fastype,(PetscEnum*)&fastype,&flg);CHKERRQ(ierr);
if (flg) {
ierr = SNESFASSetType(snes, fastype);CHKERRQ(ierr);
}
ierr = SNESGetOptionsPrefix(snes, &optionsprefix);CHKERRQ(ierr);
ierr = PetscOptionsInt("-snes_fas_cycles","Number of cycles","SNESFASSetCycles",fas->n_cycles,&m,&flg);CHKERRQ(ierr);
if (flg) {
ierr = SNESFASSetCycles(snes, m);CHKERRQ(ierr);
}
ierr = PetscOptionsBool("-snes_fas_continuation","Corrected grid-sequence continuation","SNESFASSetContinuation",fas->continuation,&continuationflg,&flg);CHKERRQ(ierr);
if (flg) {
ierr = SNESFASSetContinuation(snes,continuationflg);CHKERRQ(ierr);
}
ierr = PetscOptionsBool("-snes_fas_galerkin", "Form coarse problems with Galerkin","SNESFASSetGalerkin",fas->galerkin,&galerkinflg,&flg);CHKERRQ(ierr);
if (flg) {
ierr = SNESFASSetGalerkin(snes, galerkinflg);CHKERRQ(ierr);
}
if (fas->fastype == SNES_FAS_FULL) {
ierr = PetscOptionsBool("-snes_fas_full_downsweep","Smooth on the initial upsweep for full FAS cycles","SNESFASFullSetDownSweep",fas->full_downsweep,&fas->full_downsweep,&flg);CHKERRQ(ierr);
if (flg) {SNESFASFullSetDownSweep(snes,fas->full_downsweep);CHKERRQ(ierr);}
}
ierr = PetscOptionsInt("-snes_fas_smoothup","Number of post-smoothing steps","SNESFASSetNumberSmoothUp",fas->max_up_it,&n_up,&upflg);CHKERRQ(ierr);
ierr = PetscOptionsInt("-snes_fas_smoothdown","Number of pre-smoothing steps","SNESFASSetNumberSmoothDown",fas->max_down_it,&n_down,&downflg);CHKERRQ(ierr);
{
PetscViewer viewer;
PetscViewerFormat format;
ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->prefix,
"-snes_fas_monitor",&viewer,&format,&monflg);CHKERRQ(ierr);
if (monflg) {
PetscViewerAndFormat *vf;
ierr = PetscViewerAndFormatCreate(viewer,format,&vf);CHKERRQ(ierr);
ierr = PetscObjectDereference((PetscObject)viewer);CHKERRQ(ierr);
ierr = SNESFASSetMonitor(snes,vf,PETSC_TRUE);CHKERRQ(ierr);
}
}
flg = PETSC_FALSE;
monflg = PETSC_TRUE;
ierr = PetscOptionsBool("-snes_fas_log","Log times for each FAS level","SNESFASSetLog",monflg,&monflg,&flg);CHKERRQ(ierr);
if (flg) {ierr = SNESFASSetLog(snes,monflg);CHKERRQ(ierr);}
}
ierr = PetscOptionsTail();CHKERRQ(ierr);
/* setup from the determined types if there is no pointwise procedure or smoother defined */
if (upflg) {
ierr = SNESFASSetNumberSmoothUp(snes,n_up);CHKERRQ(ierr);
}
if (downflg) {
ierr = SNESFASSetNumberSmoothDown(snes,n_down);CHKERRQ(ierr);
}
/* set up the default line search for coarse grid corrections */
if (fas->fastype == SNES_FAS_ADDITIVE) {
if (!snes->linesearch) {
ierr = SNESGetLineSearch(snes, &linesearch);CHKERRQ(ierr);
ierr = SNESLineSearchSetType(linesearch, SNESLINESEARCHL2);CHKERRQ(ierr);
}
}
ierr = SNESFASCycleGetCorrection(snes, &next);CHKERRQ(ierr);
/* recursive option setting for the smoothers */
if (next) {ierr = SNESSetFromOptions(next);CHKERRQ(ierr);}
PetscFunctionReturn(0);
}
示例3: SNESLineSearchApply_BT
static PetscErrorCode SNESLineSearchApply_BT(SNESLineSearch linesearch)
{
PetscBool changed_y,changed_w;
PetscErrorCode ierr;
Vec X,F,Y,W,G;
SNES snes;
PetscReal fnorm, xnorm, ynorm, gnorm;
PetscReal lambda,lambdatemp,lambdaprev,minlambda,maxstep,initslope,alpha,stol;
PetscReal t1,t2,a,b,d;
PetscReal f;
PetscReal g,gprev;
PetscBool domainerror;
PetscViewer monitor;
PetscInt max_its,count;
SNESLineSearch_BT *bt;
Mat jac;
PetscErrorCode (*objective)(SNES,Vec,PetscReal*,void*);
PetscFunctionBegin;
ierr = SNESLineSearchGetVecs(linesearch, &X, &F, &Y, &W, &G);CHKERRQ(ierr);
ierr = SNESLineSearchGetNorms(linesearch, &xnorm, &fnorm, &ynorm);CHKERRQ(ierr);
ierr = SNESLineSearchGetLambda(linesearch, &lambda);CHKERRQ(ierr);
ierr = SNESLineSearchGetSNES(linesearch, &snes);CHKERRQ(ierr);
ierr = SNESLineSearchGetMonitor(linesearch, &monitor);CHKERRQ(ierr);
ierr = SNESLineSearchGetTolerances(linesearch,&minlambda,&maxstep,NULL,NULL,NULL,&max_its);CHKERRQ(ierr);
ierr = SNESGetTolerances(snes,NULL,NULL,&stol,NULL,NULL);CHKERRQ(ierr);
ierr = SNESGetObjective(snes,&objective,NULL);CHKERRQ(ierr);
bt = (SNESLineSearch_BT*)linesearch->data;
alpha = bt->alpha;
ierr = SNESGetJacobian(snes, &jac, NULL, NULL, NULL);CHKERRQ(ierr);
if (!jac && !objective) SETERRQ(PetscObjectComm((PetscObject)linesearch), PETSC_ERR_USER, "SNESLineSearchBT requires a Jacobian matrix");
/* precheck */
ierr = SNESLineSearchPreCheck(linesearch,X,Y,&changed_y);CHKERRQ(ierr);
ierr = SNESLineSearchSetSuccess(linesearch, PETSC_TRUE);CHKERRQ(ierr);
ierr = VecNormBegin(Y, NORM_2, &ynorm);CHKERRQ(ierr);
ierr = VecNormBegin(X, NORM_2, &xnorm);CHKERRQ(ierr);
ierr = VecNormEnd(Y, NORM_2, &ynorm);CHKERRQ(ierr);
ierr = VecNormEnd(X, NORM_2, &xnorm);CHKERRQ(ierr);
if (ynorm == 0.0) {
if (monitor) {
ierr = PetscViewerASCIIAddTab(monitor,((PetscObject)linesearch)->tablevel);CHKERRQ(ierr);
ierr = PetscViewerASCIIPrintf(monitor," Line search: Initial direction and size is 0\n");CHKERRQ(ierr);
ierr = PetscViewerASCIISubtractTab(monitor,((PetscObject)linesearch)->tablevel);CHKERRQ(ierr);
}
ierr = VecCopy(X,W);CHKERRQ(ierr);
ierr = VecCopy(F,G);CHKERRQ(ierr);
ierr = SNESLineSearchSetSuccess(linesearch, PETSC_FALSE);CHKERRQ(ierr);
PetscFunctionReturn(0);
}
if (ynorm > maxstep) { /* Step too big, so scale back */
if (monitor) {
ierr = PetscViewerASCIIAddTab(monitor,((PetscObject)linesearch)->tablevel);CHKERRQ(ierr);
ierr = PetscViewerASCIIPrintf(monitor," Line search: Scaling step by %14.12e old ynorm %14.12e\n", (double)(maxstep/ynorm),(double)ynorm);CHKERRQ(ierr);
ierr = PetscViewerASCIISubtractTab(monitor,((PetscObject)linesearch)->tablevel);CHKERRQ(ierr);
}
ierr = VecScale(Y,maxstep/(ynorm));CHKERRQ(ierr);
ynorm = maxstep;
}
/* if the SNES has an objective set, use that instead of the function value */
if (objective) {
ierr = SNESComputeObjective(snes,X,&f);CHKERRQ(ierr);
} else {
f = fnorm*fnorm;
}
/* compute the initial slope */
if (objective) {
/* slope comes from the function (assumed to be the gradient of the objective */
ierr = VecDotRealPart(Y,F,&initslope);CHKERRQ(ierr);
} else {
/* slope comes from the normal equations */
ierr = MatMult(jac,Y,W);CHKERRQ(ierr);
ierr = VecDotRealPart(F,W,&initslope);CHKERRQ(ierr);
if (initslope > 0.0) initslope = -initslope;
if (initslope == 0.0) initslope = -1.0;
}
ierr = VecWAXPY(W,-lambda,Y,X);CHKERRQ(ierr);
if (linesearch->ops->viproject) {
ierr = (*linesearch->ops->viproject)(snes, W);CHKERRQ(ierr);
}
if (snes->nfuncs >= snes->max_funcs) {
ierr = PetscInfo(snes,"Exceeded maximum function evaluations, while checking full step length!\n");CHKERRQ(ierr);
snes->reason = SNES_DIVERGED_FUNCTION_COUNT;
ierr = SNESLineSearchSetSuccess(linesearch, PETSC_FALSE);CHKERRQ(ierr);
PetscFunctionReturn(0);
}
if (objective) {
ierr = SNESComputeObjective(snes,W,&g);CHKERRQ(ierr);
} else {
ierr = (*linesearch->ops->snesfunc)(snes,W,G);CHKERRQ(ierr);
ierr = SNESGetFunctionDomainError(snes, &domainerror);CHKERRQ(ierr);
//.........这里部分代码省略.........
示例4: SNESSolve_NCG
PetscErrorCode SNESSolve_NCG(SNES snes)
{
SNES_NCG *ncg = (SNES_NCG*)snes->data;
Vec X,dX,lX,F,dXold;
PetscReal fnorm, ynorm, xnorm, beta = 0.0;
PetscScalar dXdotdX, dXolddotdXold, dXdotdXold, lXdotdX, lXdotdXold;
PetscInt maxits, i;
PetscErrorCode ierr;
SNESLineSearchReason lsresult = SNES_LINESEARCH_SUCCEEDED;
SNESLineSearch linesearch;
SNESConvergedReason reason;
PetscFunctionBegin;
if (snes->xl || snes->xu || snes->ops->computevariablebounds) {
SETERRQ1(PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_WRONGSTATE, "SNES solver %s does not support bounds", ((PetscObject)snes)->type_name);
}
ierr = PetscCitationsRegister(SNESCitation,&SNEScite);CHKERRQ(ierr);
snes->reason = SNES_CONVERGED_ITERATING;
maxits = snes->max_its; /* maximum number of iterations */
X = snes->vec_sol; /* X^n */
dXold = snes->work[0]; /* The previous iterate of X */
dX = snes->work[1]; /* the preconditioned direction */
lX = snes->vec_sol_update; /* the conjugate direction */
F = snes->vec_func; /* residual vector */
ierr = SNESGetLineSearch(snes, &linesearch);CHKERRQ(ierr);
ierr = PetscObjectSAWsTakeAccess((PetscObject)snes);CHKERRQ(ierr);
snes->iter = 0;
snes->norm = 0.;
ierr = PetscObjectSAWsGrantAccess((PetscObject)snes);CHKERRQ(ierr);
/* compute the initial function and preconditioned update dX */
if (snes->pc && snes->functype == SNES_FUNCTION_PRECONDITIONED) {
ierr = SNESApplyNPC(snes,X,NULL,dX);CHKERRQ(ierr);
ierr = SNESGetConvergedReason(snes->pc,&reason);CHKERRQ(ierr);
if (reason < 0 && reason != SNES_DIVERGED_MAX_IT) {
snes->reason = SNES_DIVERGED_INNER;
PetscFunctionReturn(0);
}
ierr = VecCopy(dX,F);CHKERRQ(ierr);
ierr = VecNorm(F,NORM_2,&fnorm);CHKERRQ(ierr);
} else {
if (!snes->vec_func_init_set) {
ierr = SNESComputeFunction(snes,X,F);CHKERRQ(ierr);
} else snes->vec_func_init_set = PETSC_FALSE;
/* convergence test */
ierr = VecNorm(F,NORM_2,&fnorm);CHKERRQ(ierr);
SNESCheckFunctionNorm(snes,fnorm);
ierr = VecCopy(F,dX);CHKERRQ(ierr);
}
if (snes->pc) {
if (snes->functype == SNES_FUNCTION_UNPRECONDITIONED) {
ierr = SNESApplyNPC(snes,X,F,dX);CHKERRQ(ierr);
ierr = SNESGetConvergedReason(snes->pc,&reason);CHKERRQ(ierr);
if (reason < 0 && reason != SNES_DIVERGED_MAX_IT) {
snes->reason = SNES_DIVERGED_INNER;
PetscFunctionReturn(0);
}
}
}
ierr = VecCopy(dX,lX);CHKERRQ(ierr);
ierr = VecDot(dX, dX, &dXdotdX);CHKERRQ(ierr);
ierr = PetscObjectSAWsTakeAccess((PetscObject)snes);CHKERRQ(ierr);
snes->norm = fnorm;
ierr = PetscObjectSAWsGrantAccess((PetscObject)snes);CHKERRQ(ierr);
ierr = SNESLogConvergenceHistory(snes,fnorm,0);CHKERRQ(ierr);
ierr = SNESMonitor(snes,0,fnorm);CHKERRQ(ierr);
/* test convergence */
ierr = (*snes->ops->converged)(snes,0,0.0,0.0,fnorm,&snes->reason,snes->cnvP);CHKERRQ(ierr);
if (snes->reason) PetscFunctionReturn(0);
/* Call general purpose update function */
if (snes->ops->update) {
ierr = (*snes->ops->update)(snes, snes->iter);CHKERRQ(ierr);
}
/* first update -- just use the (preconditioned) residual direction for the initial conjugate direction */
for (i = 1; i < maxits + 1; i++) {
/* some update types require the old update direction or conjugate direction */
if (ncg->type != SNES_NCG_FR) {
ierr = VecCopy(dX, dXold);CHKERRQ(ierr);
}
ierr = SNESLineSearchApply(linesearch,X,F,&fnorm,lX);CHKERRQ(ierr);
ierr = SNESLineSearchGetReason(linesearch, &lsresult);CHKERRQ(ierr);
ierr = SNESLineSearchGetNorms(linesearch, &xnorm, &fnorm, &ynorm);CHKERRQ(ierr);
if (lsresult) {
if (++snes->numFailures >= snes->maxFailures) {
snes->reason = SNES_DIVERGED_LINE_SEARCH;
PetscFunctionReturn(0);
}
//.........这里部分代码省略.........
示例5: KSPSolve_LSQR
static PetscErrorCode KSPSolve_LSQR(KSP ksp)
{
PetscErrorCode ierr;
PetscInt i,size1,size2;
PetscScalar rho,rhobar,phi,phibar,theta,c,s,tmp,tau;
PetscReal beta,alpha,rnorm;
Vec X,B,V,V1,U,U1,TMP,W,W2,SE,Z = NULL;
Mat Amat,Pmat;
MatStructure pflag;
KSP_LSQR *lsqr = (KSP_LSQR*)ksp->data;
PetscBool diagonalscale,nopreconditioner;
PetscFunctionBegin;
ierr = PCGetDiagonalScale(ksp->pc,&diagonalscale);CHKERRQ(ierr);
if (diagonalscale) SETERRQ1(PetscObjectComm((PetscObject)ksp),PETSC_ERR_SUP,"Krylov method %s does not support diagonal scaling",((PetscObject)ksp)->type_name);
ierr = PCGetOperators(ksp->pc,&Amat,&Pmat,&pflag);CHKERRQ(ierr);
ierr = PetscObjectTypeCompare((PetscObject)ksp->pc,PCNONE,&nopreconditioner);CHKERRQ(ierr);
/* nopreconditioner =PETSC_FALSE; */
/* Calculate norm of right hand side */
ierr = VecNorm(ksp->vec_rhs,NORM_2,&lsqr->rhs_norm);CHKERRQ(ierr);
/* mark norm of matrix with negative number to indicate it has not yet been computed */
lsqr->anorm = -1.0;
/* vectors of length m, where system size is mxn */
B = ksp->vec_rhs;
U = lsqr->vwork_m[0];
U1 = lsqr->vwork_m[1];
/* vectors of length n */
X = ksp->vec_sol;
W = lsqr->vwork_n[0];
V = lsqr->vwork_n[1];
V1 = lsqr->vwork_n[2];
W2 = lsqr->vwork_n[3];
if (!nopreconditioner) Z = lsqr->vwork_n[4];
/* standard error vector */
SE = lsqr->se;
if (SE) {
ierr = VecGetSize(SE,&size1);CHKERRQ(ierr);
ierr = VecGetSize(X,&size2);CHKERRQ(ierr);
if (size1 != size2) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Standard error vector (size %d) does not match solution vector (size %d)",size1,size2);
ierr = VecSet(SE,0.0);CHKERRQ(ierr);
}
/* Compute initial residual, temporarily use work vector u */
if (!ksp->guess_zero) {
ierr = KSP_MatMult(ksp,Amat,X,U);CHKERRQ(ierr); /* u <- b - Ax */
ierr = VecAYPX(U,-1.0,B);CHKERRQ(ierr);
} else {
ierr = VecCopy(B,U);CHKERRQ(ierr); /* u <- b (x is 0) */
}
/* Test for nothing to do */
ierr = VecNorm(U,NORM_2,&rnorm);CHKERRQ(ierr);
ierr = PetscObjectSAWsTakeAccess((PetscObject)ksp);CHKERRQ(ierr);
ksp->its = 0;
ksp->rnorm = rnorm;
ierr = PetscObjectSAWsGrantAccess((PetscObject)ksp);CHKERRQ(ierr);
ierr = KSPLogResidualHistory(ksp,rnorm);CHKERRQ(ierr);
ierr = KSPMonitor(ksp,0,rnorm);CHKERRQ(ierr);
ierr = (*ksp->converged)(ksp,0,rnorm,&ksp->reason,ksp->cnvP);CHKERRQ(ierr);
if (ksp->reason) PetscFunctionReturn(0);
beta = rnorm;
ierr = VecScale(U,1.0/beta);CHKERRQ(ierr);
ierr = KSP_MatMultTranspose(ksp,Amat,U,V);CHKERRQ(ierr);
if (nopreconditioner) {
ierr = VecNorm(V,NORM_2,&alpha);CHKERRQ(ierr);
} else {
ierr = PCApply(ksp->pc,V,Z);CHKERRQ(ierr);
ierr = VecDotRealPart(V,Z,&alpha);CHKERRQ(ierr);
if (alpha <= 0.0) {
ksp->reason = KSP_DIVERGED_BREAKDOWN;
PetscFunctionReturn(0);
}
alpha = PetscSqrtReal(alpha);
ierr = VecScale(Z,1.0/alpha);CHKERRQ(ierr);
}
ierr = VecScale(V,1.0/alpha);CHKERRQ(ierr);
if (nopreconditioner) {
ierr = VecCopy(V,W);CHKERRQ(ierr);
} else {
ierr = VecCopy(Z,W);CHKERRQ(ierr);
}
lsqr->arnorm = alpha * beta;
phibar = beta;
rhobar = alpha;
i = 0;
do {
if (nopreconditioner) {
ierr = KSP_MatMult(ksp,Amat,V,U1);CHKERRQ(ierr);
} else {
ierr = KSP_MatMult(ksp,Amat,Z,U1);CHKERRQ(ierr);
}
//.........这里部分代码省略.........
示例6: SNESSolve_Test
PetscErrorCode SNESSolve_Test(SNES snes)
{
Mat A = snes->jacobian,B;
Vec x = snes->vec_sol,f = snes->vec_func,f1 = snes->vec_sol_update;
PetscErrorCode ierr;
PetscInt i;
PetscReal nrm,gnorm;
SNES_Test *neP = (SNES_Test*)snes->data;
PetscErrorCode (*objective)(SNES,Vec,PetscReal*,void*);
void *ctx;
PetscReal fnorm,f1norm,dnorm;
PetscFunctionBegin;
if (A != snes->jacobian_pre) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Cannot test with alternative preconditioner");
ierr = PetscPrintf(PetscObjectComm((PetscObject)snes),"Testing hand-coded Jacobian, if the ratio is\n");CHKERRQ(ierr);
ierr = PetscPrintf(PetscObjectComm((PetscObject)snes),"O(1.e-8), the hand-coded Jacobian is probably correct.\n");CHKERRQ(ierr);
if (!neP->complete_print) {
ierr = PetscPrintf(PetscObjectComm((PetscObject)snes),"Run with -snes_test_display to show difference\n");CHKERRQ(ierr);
ierr = PetscPrintf(PetscObjectComm((PetscObject)snes),"of hand-coded and finite difference Jacobian.\n");CHKERRQ(ierr);
}
for (i=0; i<3; i++) {
void *functx;
static const char *const loc[] = {"user-defined state","constant state -1.0","constant state 1.0"};
PetscInt m,n,M,N;
if (i == 1) {
ierr = VecSet(x,-1.0);CHKERRQ(ierr);
} else if (i == 2) {
ierr = VecSet(x,1.0);CHKERRQ(ierr);
}
/* evaluate the function at this point because SNESComputeJacobianDefaultColor() assumes that the function has been evaluated and put into snes->vec_func */
ierr = SNESComputeFunction(snes,x,f);CHKERRQ(ierr);
if (snes->domainerror) {
ierr = PetscPrintf(PetscObjectComm((PetscObject)snes),"Domain error at %s\n",loc[i]);CHKERRQ(ierr);
snes->domainerror = PETSC_FALSE;
continue;
}
/* compute both versions of Jacobian */
ierr = SNESComputeJacobian(snes,x,A,A);CHKERRQ(ierr);
ierr = MatCreate(PetscObjectComm((PetscObject)A),&B);CHKERRQ(ierr);
ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
ierr = MatGetLocalSize(A,&m,&n);CHKERRQ(ierr);
ierr = MatSetSizes(B,m,n,M,N);CHKERRQ(ierr);
ierr = MatSetType(B,((PetscObject)A)->type_name);CHKERRQ(ierr);
ierr = MatSetUp(B);CHKERRQ(ierr);
ierr = MatSetOption(B,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr);
ierr = SNESGetFunction(snes,NULL,NULL,&functx);CHKERRQ(ierr);
ierr = SNESComputeJacobianDefault(snes,x,B,B,functx);CHKERRQ(ierr);
if (neP->complete_print) {
MPI_Comm comm;
PetscViewer viewer;
ierr = PetscPrintf(PetscObjectComm((PetscObject)snes),"Finite difference Jacobian (%s)\n",loc[i]);CHKERRQ(ierr);
ierr = PetscObjectGetComm((PetscObject)B,&comm);CHKERRQ(ierr);
ierr = PetscViewerASCIIGetStdout(comm,&viewer);CHKERRQ(ierr);
ierr = MatView(B,viewer);CHKERRQ(ierr);
}
/* compare */
ierr = MatAYPX(B,-1.0,A,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr);
ierr = MatNorm(B,NORM_FROBENIUS,&nrm);CHKERRQ(ierr);
ierr = MatNorm(A,NORM_FROBENIUS,&gnorm);CHKERRQ(ierr);
if (neP->complete_print) {
MPI_Comm comm;
PetscViewer viewer;
ierr = PetscPrintf(PetscObjectComm((PetscObject)snes),"Hand-coded Jacobian (%s)\n",loc[i]);CHKERRQ(ierr);
ierr = PetscObjectGetComm((PetscObject)B,&comm);CHKERRQ(ierr);
ierr = PetscViewerASCIIGetStdout(comm,&viewer);CHKERRQ(ierr);
ierr = MatView(A,viewer);CHKERRQ(ierr);
ierr = PetscPrintf(PetscObjectComm((PetscObject)snes),"Hand-coded minus finite-difference Jacobian (%s)\n",loc[i]);CHKERRQ(ierr);
ierr = MatView(B,viewer);CHKERRQ(ierr);
}
if (!gnorm) gnorm = 1; /* just in case */
ierr = PetscPrintf(PetscObjectComm((PetscObject)snes),"Norm of matrix ratio %g, difference %g (%s)\n",(double)(nrm/gnorm),(double)nrm,loc[i]);CHKERRQ(ierr);
ierr = SNESGetObjective(snes,&objective,&ctx);CHKERRQ(ierr);
if (objective) {
ierr = SNESComputeFunction(snes,x,f);CHKERRQ(ierr);
ierr = VecNorm(f,NORM_2,&fnorm);CHKERRQ(ierr);
if (neP->complete_print) {
PetscViewer viewer;
ierr = PetscPrintf(PetscObjectComm((PetscObject)snes),"Hand-coded Function (%s)\n",loc[i]);CHKERRQ(ierr);
ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)snes),&viewer);CHKERRQ(ierr);
ierr = VecView(f,viewer);CHKERRQ(ierr);
}
ierr = SNESObjectiveComputeFunctionDefaultFD(snes,x,f1,NULL);CHKERRQ(ierr);
ierr = VecNorm(f1,NORM_2,&f1norm);CHKERRQ(ierr);
if (neP->complete_print) {
PetscViewer viewer;
ierr = PetscPrintf(PetscObjectComm((PetscObject)snes),"Finite-difference Function (%s)\n",loc[i]);CHKERRQ(ierr);
ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)snes),&viewer);CHKERRQ(ierr);
ierr = VecView(f1,viewer);CHKERRQ(ierr);
}
/* compare the two */
ierr = VecAXPY(f,-1.0,f1);CHKERRQ(ierr);
ierr = VecNorm(f,NORM_2,&dnorm);CHKERRQ(ierr);
//.........这里部分代码省略.........
示例7: SNESSolve
/*@C
SNESUpdateCheckJacobian - Checks each Jacobian computed by the nonlinear solver comparing the users function with a finite difference computation.
Options Database:
+ -snes_check_jacobian - use this every time SNESSolve() is called
- -snes_check_jacobian_view - Display difference between Jacobian approximated by finite-differencing and the hand-coded Jacobian
Output:
+ difference - ||J - Jd||, the norm of the difference of the hand-coded Jacobian J and the approximate Jacobian Jd obtained by finite-differencing
the residual,
- ratio - ||J - Jd||/||J||, the ratio of the norms of the above difference and the hand-coded Jacobian.
Notes:
Frobenius norm is used in the above throughout. This check is carried out every SNES iteration.
Level: intermediate
.seealso: SNESTEST, SNESCreate(), SNES, SNESSetType(), SNESNEWTONLS, SNESNEWTONTR, SNESSolve()
@*/
PetscErrorCode SNESUpdateCheckJacobian(SNES snes,PetscInt it)
{
Mat A = snes->jacobian,B;
Vec x = snes->vec_sol,f = snes->vec_func,f1 = snes->vec_sol_update;
PetscErrorCode ierr;
PetscReal nrm,gnorm;
PetscErrorCode (*objective)(SNES,Vec,PetscReal*,void*);
void *ctx;
PetscReal fnorm,f1norm,dnorm;
PetscInt m,n,M,N;
PetscBool complete_print = PETSC_FALSE;
void *functx;
PetscViewer viewer = PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)snes));
PetscFunctionBegin;
ierr = PetscOptionsHasName(((PetscObject)snes)->prefix,"-snes_check_jacobian_view",&complete_print);CHKERRQ(ierr);
if (A != snes->jacobian_pre) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Cannot check Jacobian with alternative preconditioner");
ierr = PetscViewerASCIIAddTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr);
ierr = PetscViewerASCIIPrintf(viewer," Testing hand-coded Jacobian, if the ratio is O(1.e-8), the hand-coded Jacobian is probably correct.\n");CHKERRQ(ierr);
if (!complete_print) {
ierr = PetscViewerASCIIPrintf(viewer," Run with -snes_check_jacobian_view [viewer][:filename][:format] to show difference of hand-coded and finite difference Jacobian.\n");CHKERRQ(ierr);
}
/* compute both versions of Jacobian */
ierr = SNESComputeJacobian(snes,x,A,A);CHKERRQ(ierr);
ierr = MatCreate(PetscObjectComm((PetscObject)A),&B);CHKERRQ(ierr);
ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
ierr = MatGetLocalSize(A,&m,&n);CHKERRQ(ierr);
ierr = MatSetSizes(B,m,n,M,N);CHKERRQ(ierr);
ierr = MatSetType(B,((PetscObject)A)->type_name);CHKERRQ(ierr);
ierr = MatSetUp(B);CHKERRQ(ierr);
ierr = MatSetOption(B,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr);
ierr = SNESGetFunction(snes,NULL,NULL,&functx);CHKERRQ(ierr);
ierr = SNESComputeJacobianDefault(snes,x,B,B,functx);CHKERRQ(ierr);
if (complete_print) {
ierr = PetscViewerASCIIPrintf(viewer," Finite difference Jacobian\n");CHKERRQ(ierr);
ierr = MatViewFromOptions(B,(PetscObject)snes,"-snes_check_jacobian_view");CHKERRQ(ierr);
}
/* compare */
ierr = MatAYPX(B,-1.0,A,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr);
ierr = MatNorm(B,NORM_FROBENIUS,&nrm);CHKERRQ(ierr);
ierr = MatNorm(A,NORM_FROBENIUS,&gnorm);CHKERRQ(ierr);
if (complete_print) {
ierr = PetscViewerASCIIPrintf(viewer," Hand-coded Jacobian\n");CHKERRQ(ierr);
ierr = MatViewFromOptions(A,(PetscObject)snes,"-snes_check_jacobian_view");CHKERRQ(ierr);
ierr = PetscViewerASCIIPrintf(viewer," Hand-coded minus finite difference Jacobian\n");CHKERRQ(ierr);
ierr = MatViewFromOptions(B,(PetscObject)snes,"-snes_check_jacobian_view");CHKERRQ(ierr);
}
if (!gnorm) gnorm = 1; /* just in case */
ierr = PetscViewerASCIIPrintf(viewer," %g = ||J - Jfd||/||J|| %g = ||J - Jfd||\n",(double)(nrm/gnorm),(double)nrm);CHKERRQ(ierr);
ierr = SNESGetObjective(snes,&objective,&ctx);CHKERRQ(ierr);
if (objective) {
ierr = SNESComputeFunction(snes,x,f);CHKERRQ(ierr);
ierr = VecNorm(f,NORM_2,&fnorm);CHKERRQ(ierr);
if (complete_print) {
ierr = PetscViewerASCIIPrintf(viewer," Hand-coded Objective Function \n");CHKERRQ(ierr);
ierr = VecView(f,viewer);CHKERRQ(ierr);
}
ierr = SNESObjectiveComputeFunctionDefaultFD(snes,x,f1,NULL);CHKERRQ(ierr);
ierr = VecNorm(f1,NORM_2,&f1norm);CHKERRQ(ierr);
if (complete_print) {
ierr = PetscViewerASCIIPrintf(viewer," Finite-Difference Objective Function\n");CHKERRQ(ierr);
ierr = VecView(f1,viewer);CHKERRQ(ierr);
}
/* compare the two */
ierr = VecAXPY(f,-1.0,f1);CHKERRQ(ierr);
ierr = VecNorm(f,NORM_2,&dnorm);CHKERRQ(ierr);
if (!fnorm) fnorm = 1.;
ierr = PetscViewerASCIIPrintf(viewer," %g = Norm of objective function ratio %g = difference\n",dnorm/fnorm,dnorm);CHKERRQ(ierr);
if (complete_print) {
ierr = PetscViewerASCIIPrintf(viewer," Difference\n");CHKERRQ(ierr);
ierr = VecView(f,viewer);CHKERRQ(ierr);
}
}
ierr = PetscViewerASCIISubtractTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr);
//.........这里部分代码省略.........
示例8: MatSetUpMultiply_MPISBAIJ_2comm
//.........这里部分代码省略.........
for (j=0; j<B->ilen[i]; j++) {
PetscInt data,gid1 = aj[B->i[i]+j] + 1;
ierr = PetscTableFind(gid1_lid1,gid1,&data);CHKERRQ(ierr);
if (!data) {
/* one based table */
ierr = PetscTableAdd(gid1_lid1,gid1,++ec,INSERT_VALUES);CHKERRQ(ierr);
}
}
}
/* form array of columns we need */
ierr = PetscMalloc1(ec,&garray);CHKERRQ(ierr);
ierr = PetscTableGetHeadPosition(gid1_lid1,&tpos);CHKERRQ(ierr);
while (tpos) {
ierr = PetscTableGetNext(gid1_lid1,&tpos,&gid,&lid);CHKERRQ(ierr);
gid--; lid--;
garray[lid] = gid;
}
ierr = PetscSortInt(ec,garray);CHKERRQ(ierr);
ierr = PetscTableRemoveAll(gid1_lid1);CHKERRQ(ierr);
for (i=0; i<ec; i++) {
ierr = PetscTableAdd(gid1_lid1,garray[i]+1,i+1,INSERT_VALUES);CHKERRQ(ierr);
}
/* compact out the extra columns in B */
for (i=0; i<B->mbs; i++) {
for (j=0; j<B->ilen[i]; j++) {
PetscInt gid1 = aj[B->i[i] + j] + 1;
ierr = PetscTableFind(gid1_lid1,gid1,&lid);CHKERRQ(ierr);
lid--;
aj[B->i[i]+j] = lid;
}
}
B->nbs = ec;
baij->B->cmap->n = baij->B->cmap->N = ec*mat->rmap->bs;
ierr = PetscLayoutSetUp((baij->B->cmap));CHKERRQ(ierr);
ierr = PetscTableDestroy(&gid1_lid1);CHKERRQ(ierr);
#else
/* For the first stab we make an array as long as the number of columns */
/* mark those columns that are in baij->B */
ierr = PetscCalloc1(Nbs,&indices);CHKERRQ(ierr);
for (i=0; i<B->mbs; i++) {
for (j=0; j<B->ilen[i]; j++) {
if (!indices[aj[B->i[i] + j]]) ec++;
indices[aj[B->i[i] + j]] = 1;
}
}
/* form array of columns we need */
ierr = PetscMalloc1(ec,&garray);CHKERRQ(ierr);
ec = 0;
for (i=0; i<Nbs; i++) {
if (indices[i]) {
garray[ec++] = i;
}
}
/* make indices now point into garray */
for (i=0; i<ec; i++) indices[garray[i]] = i;
/* compact out the extra columns in B */
for (i=0; i<B->mbs; i++) {
for (j=0; j<B->ilen[i]; j++) {
aj[B->i[i] + j] = indices[aj[B->i[i] + j]];
}
}
B->nbs = ec;
baij->B->cmap->n = ec*mat->rmap->bs;
ierr = PetscFree(indices);CHKERRQ(ierr);
#endif
/* create local vector that is used to scatter into */
ierr = VecCreateSeq(PETSC_COMM_SELF,ec*bs,&baij->lvec);CHKERRQ(ierr);
/* create two temporary index sets for building scatter-gather */
ierr = ISCreateBlock(PETSC_COMM_SELF,bs,ec,garray,PETSC_COPY_VALUES,&from);CHKERRQ(ierr);
ierr = PetscMalloc1(ec,&stmp);CHKERRQ(ierr);
for (i=0; i<ec; i++) stmp[i] = i;
ierr = ISCreateBlock(PETSC_COMM_SELF,bs,ec,stmp,PETSC_OWN_POINTER,&to);CHKERRQ(ierr);
/* create temporary global vector to generate scatter context */
ierr = VecCreateMPIWithArray(PetscObjectComm((PetscObject)mat),1,mat->cmap->n,mat->cmap->N,NULL,&gvec);CHKERRQ(ierr);
ierr = VecScatterCreateWithData(gvec,from,baij->lvec,to,&baij->Mvctx);CHKERRQ(ierr);
ierr = VecDestroy(&gvec);CHKERRQ(ierr);
ierr = PetscLogObjectParent((PetscObject)mat,(PetscObject)baij->Mvctx);CHKERRQ(ierr);
ierr = PetscLogObjectParent((PetscObject)mat,(PetscObject)baij->lvec);CHKERRQ(ierr);
ierr = PetscLogObjectParent((PetscObject)mat,(PetscObject)from);CHKERRQ(ierr);
ierr = PetscLogObjectParent((PetscObject)mat,(PetscObject)to);CHKERRQ(ierr);
baij->garray = garray;
ierr = PetscLogObjectMemory((PetscObject)mat,(ec+1)*sizeof(PetscInt));CHKERRQ(ierr);
ierr = ISDestroy(&from);CHKERRQ(ierr);
ierr = ISDestroy(&to);CHKERRQ(ierr);
PetscFunctionReturn(0);
}
示例9: MatSetUpMultiply_MPISBAIJ
PetscErrorCode MatSetUpMultiply_MPISBAIJ(Mat mat)
{
Mat_MPISBAIJ *sbaij = (Mat_MPISBAIJ*)mat->data;
Mat_SeqBAIJ *B = (Mat_SeqBAIJ*)(sbaij->B->data);
PetscErrorCode ierr;
PetscInt Nbs = sbaij->Nbs,i,j,*indices,*aj = B->j,ec = 0,*garray,*sgarray;
PetscInt bs = mat->rmap->bs,*stmp,mbs=sbaij->mbs, vec_size,nt;
IS from,to;
Vec gvec;
PetscMPIInt rank =sbaij->rank,lsize,size=sbaij->size;
PetscInt *owners=sbaij->rangebs,*ec_owner,k;
const PetscInt *sowners;
PetscScalar *ptr;
PetscFunctionBegin;
ierr = VecScatterDestroy(&sbaij->sMvctx);CHKERRQ(ierr);
/* For the first stab we make an array as long as the number of columns */
/* mark those columns that are in sbaij->B */
ierr = PetscCalloc1(Nbs,&indices);CHKERRQ(ierr);
for (i=0; i<mbs; i++) {
for (j=0; j<B->ilen[i]; j++) {
if (!indices[aj[B->i[i] + j]]) ec++;
indices[aj[B->i[i] + j]] = 1;
}
}
/* form arrays of columns we need */
ierr = PetscMalloc1(ec,&garray);CHKERRQ(ierr);
ierr = PetscMalloc2(2*ec,&sgarray,ec,&ec_owner);CHKERRQ(ierr);
ec = 0;
for (j=0; j<size; j++) {
for (i=owners[j]; i<owners[j+1]; i++) {
if (indices[i]) {
garray[ec] = i;
ec_owner[ec] = j;
ec++;
}
}
}
/* make indices now point into garray */
for (i=0; i<ec; i++) indices[garray[i]] = i;
/* compact out the extra columns in B */
for (i=0; i<mbs; i++) {
for (j=0; j<B->ilen[i]; j++) aj[B->i[i] + j] = indices[aj[B->i[i] + j]];
}
B->nbs = ec;
sbaij->B->cmap->n = sbaij->B->cmap->N = ec*mat->rmap->bs;
ierr = PetscLayoutSetUp((sbaij->B->cmap));CHKERRQ(ierr);
ierr = PetscFree(indices);CHKERRQ(ierr);
/* create local vector that is used to scatter into */
ierr = VecCreateSeq(PETSC_COMM_SELF,ec*bs,&sbaij->lvec);CHKERRQ(ierr);
/* create two temporary index sets for building scatter-gather */
ierr = PetscMalloc1(2*ec,&stmp);CHKERRQ(ierr);
ierr = ISCreateBlock(PETSC_COMM_SELF,bs,ec,garray,PETSC_COPY_VALUES,&from);CHKERRQ(ierr);
for (i=0; i<ec; i++) stmp[i] = i;
ierr = ISCreateBlock(PETSC_COMM_SELF,bs,ec,stmp,PETSC_COPY_VALUES,&to);CHKERRQ(ierr);
/* generate the scatter context
-- Mvctx and lvec are not used by MatMult_MPISBAIJ(), but usefule for some applications */
ierr = VecCreateMPIWithArray(PetscObjectComm((PetscObject)mat),1,mat->cmap->n,mat->cmap->N,NULL,&gvec);CHKERRQ(ierr);
ierr = VecScatterCreateWithData(gvec,from,sbaij->lvec,to,&sbaij->Mvctx);CHKERRQ(ierr);
ierr = VecDestroy(&gvec);CHKERRQ(ierr);
sbaij->garray = garray;
ierr = PetscLogObjectParent((PetscObject)mat,(PetscObject)sbaij->Mvctx);CHKERRQ(ierr);
ierr = PetscLogObjectParent((PetscObject)mat,(PetscObject)sbaij->lvec);CHKERRQ(ierr);
ierr = PetscLogObjectParent((PetscObject)mat,(PetscObject)from);CHKERRQ(ierr);
ierr = PetscLogObjectParent((PetscObject)mat,(PetscObject)to);CHKERRQ(ierr);
ierr = ISDestroy(&from);CHKERRQ(ierr);
ierr = ISDestroy(&to);CHKERRQ(ierr);
/* create parallel vector that is used by SBAIJ matrix to scatter from/into */
lsize = (mbs + ec)*bs;
ierr = VecCreateMPI(PetscObjectComm((PetscObject)mat),lsize,PETSC_DETERMINE,&sbaij->slvec0);CHKERRQ(ierr);
ierr = VecDuplicate(sbaij->slvec0,&sbaij->slvec1);CHKERRQ(ierr);
ierr = VecGetSize(sbaij->slvec0,&vec_size);CHKERRQ(ierr);
ierr = VecGetOwnershipRanges(sbaij->slvec0,&sowners);CHKERRQ(ierr);
/* x index in the IS sfrom */
for (i=0; i<ec; i++) {
j = ec_owner[i];
sgarray[i] = garray[i] + (sowners[j]/bs - owners[j]);
}
/* b index in the IS sfrom */
k = sowners[rank]/bs + mbs;
for (i=ec,j=0; i< 2*ec; i++,j++) sgarray[i] = k + j;
ierr = ISCreateBlock(PETSC_COMM_SELF,bs,2*ec,sgarray,PETSC_COPY_VALUES,&from);CHKERRQ(ierr);
/* x index in the IS sto */
//.........这里部分代码省略.........
示例10: output
/*@C
KSPView - Prints the KSP data structure.
Collective on KSP
Input Parameters:
+ ksp - the Krylov space context
- viewer - visualization context
Options Database Keys:
. -ksp_view - print the ksp data structure at the end of a KSPSolve call
Note:
The available visualization contexts include
+ PETSC_VIEWER_STDOUT_SELF - standard output (default)
- PETSC_VIEWER_STDOUT_WORLD - synchronized standard
output where only the first processor opens
the file. All other processors send their
data to the first processor to print.
The user can open an alternative visualization context with
PetscViewerASCIIOpen() - output to a specified file.
Level: beginner
.keywords: KSP, view
.seealso: PCView(), PetscViewerASCIIOpen()
@*/
PetscErrorCode KSPView(KSP ksp,PetscViewer viewer)
{
PetscErrorCode ierr;
PetscBool iascii,isbinary,isdraw;
#if defined(PETSC_HAVE_AMS)
PetscBool isams;
#endif
PetscFunctionBegin;
PetscValidHeaderSpecific(ksp,KSP_CLASSID,1);
if (!viewer) viewer = PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)ksp));
PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
PetscCheckSameComm(ksp,1,viewer,2);
ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr);
ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr);
#if defined(PETSC_HAVE_AMS)
ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERAMS,&isams);CHKERRQ(ierr);
#endif
if (iascii) {
ierr = PetscObjectPrintClassNamePrefixType((PetscObject)ksp,viewer);CHKERRQ(ierr);
if (ksp->ops->view) {
ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
ierr = (*ksp->ops->view)(ksp,viewer);CHKERRQ(ierr);
ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
}
if (ksp->guess_zero) {
ierr = PetscViewerASCIIPrintf(viewer," maximum iterations=%D, initial guess is zero\n",ksp->max_it);CHKERRQ(ierr);
} else {
ierr = PetscViewerASCIIPrintf(viewer," maximum iterations=%D\n", ksp->max_it);CHKERRQ(ierr);
}
if (ksp->guess_knoll) {ierr = PetscViewerASCIIPrintf(viewer," using preconditioner applied to right hand side for initial guess\n");CHKERRQ(ierr);}
ierr = PetscViewerASCIIPrintf(viewer," tolerances: relative=%G, absolute=%G, divergence=%G\n",ksp->rtol,ksp->abstol,ksp->divtol);CHKERRQ(ierr);
if (ksp->pc_side == PC_RIGHT) {
ierr = PetscViewerASCIIPrintf(viewer," right preconditioning\n");CHKERRQ(ierr);
} else if (ksp->pc_side == PC_SYMMETRIC) {
ierr = PetscViewerASCIIPrintf(viewer," symmetric preconditioning\n");CHKERRQ(ierr);
} else {
ierr = PetscViewerASCIIPrintf(viewer," left preconditioning\n");CHKERRQ(ierr);
}
if (ksp->guess) {ierr = PetscViewerASCIIPrintf(viewer," using Fischers initial guess method %D with size %D\n",ksp->guess->method,ksp->guess->maxl);CHKERRQ(ierr);}
if (ksp->dscale) {ierr = PetscViewerASCIIPrintf(viewer," diagonally scaled system\n");CHKERRQ(ierr);}
if (ksp->nullsp) {ierr = PetscViewerASCIIPrintf(viewer," has attached null space\n");CHKERRQ(ierr);}
if (!ksp->guess_zero) {ierr = PetscViewerASCIIPrintf(viewer," using nonzero initial guess\n");CHKERRQ(ierr);}
ierr = PetscViewerASCIIPrintf(viewer," using %s norm type for convergence test\n",KSPNormTypes[ksp->normtype]);CHKERRQ(ierr);
} else if (isbinary) {
PetscInt classid = KSP_FILE_CLASSID;
MPI_Comm comm;
PetscMPIInt rank;
char type[256];
ierr = PetscObjectGetComm((PetscObject)ksp,&comm);CHKERRQ(ierr);
ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
if (!rank) {
ierr = PetscViewerBinaryWrite(viewer,&classid,1,PETSC_INT,PETSC_FALSE);CHKERRQ(ierr);
ierr = PetscStrncpy(type,((PetscObject)ksp)->type_name,256);CHKERRQ(ierr);
ierr = PetscViewerBinaryWrite(viewer,type,256,PETSC_CHAR,PETSC_FALSE);CHKERRQ(ierr);
}
if (ksp->ops->view) {
ierr = (*ksp->ops->view)(ksp,viewer);CHKERRQ(ierr);
}
} else if (isdraw) {
PetscDraw draw;
char str[36];
PetscReal x,y,bottom,h;
PetscBool flg;
ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr);
ierr = PetscDrawGetCurrentPoint(draw,&x,&y);CHKERRQ(ierr);
ierr = PetscObjectTypeCompare((PetscObject)ksp,KSPPREONLY,&flg);CHKERRQ(ierr);
//.........这里部分代码省略.........
示例11: MatNullSpaceCreate
/*@
MatNullSpaceCreateRigidBody - create rigid body modes from coordinates
Collective on Vec
Input Argument:
. coords - block of coordinates of each node, must have block size set
Output Argument:
. sp - the null space
Level: advanced
.seealso: MatNullSpaceCreate()
@*/
PetscErrorCode MatNullSpaceCreateRigidBody(Vec coords,MatNullSpace *sp)
{
PetscErrorCode ierr;
const PetscScalar *x;
PetscScalar *v[6],dots[3];
Vec vec[6];
PetscInt n,N,dim,nmodes,i,j;
PetscFunctionBegin;
ierr = VecGetBlockSize(coords,&dim);CHKERRQ(ierr);
ierr = VecGetLocalSize(coords,&n);CHKERRQ(ierr);
ierr = VecGetSize(coords,&N);CHKERRQ(ierr);
n /= dim;
N /= dim;
switch (dim) {
case 1:
ierr = MatNullSpaceCreate(PetscObjectComm((PetscObject)coords),PETSC_TRUE,0,NULL,sp);CHKERRQ(ierr);
break;
case 2:
case 3:
nmodes = (dim == 2) ? 3 : 6;
ierr = VecCreate(PetscObjectComm((PetscObject)coords),&vec[0]);CHKERRQ(ierr);
ierr = VecSetSizes(vec[0],dim*n,dim*N);CHKERRQ(ierr);
ierr = VecSetBlockSize(vec[0],dim);CHKERRQ(ierr);
ierr = VecSetUp(vec[0]);CHKERRQ(ierr);
for (i=1; i<nmodes; i++) {ierr = VecDuplicate(vec[0],&vec[i]);CHKERRQ(ierr);}
for (i=0; i<nmodes; i++) {ierr = VecGetArray(vec[i],&v[i]);CHKERRQ(ierr);}
ierr = VecGetArrayRead(coords,&x);CHKERRQ(ierr);
for (i=0; i<n; i++) {
if (dim == 2) {
v[0][i*2+0] = 1./N;
v[0][i*2+1] = 0.;
v[1][i*2+0] = 0.;
v[1][i*2+1] = 1./N;
/* Rotations */
v[2][i*2+0] = -x[i*2+1];
v[2][i*2+1] = x[i*2+0];
} else {
v[0][i*3+0] = 1./N;
v[0][i*3+1] = 0.;
v[0][i*3+2] = 0.;
v[1][i*3+0] = 0.;
v[1][i*3+1] = 1./N;
v[1][i*3+2] = 0.;
v[2][i*3+0] = 0.;
v[2][i*3+1] = 0.;
v[2][i*3+2] = 1./N;
v[3][i*3+0] = x[i*3+1];
v[3][i*3+1] = -x[i*3+0];
v[3][i*3+2] = 0.;
v[4][i*3+0] = 0.;
v[4][i*3+1] = -x[i*3+2];
v[4][i*3+2] = x[i*3+1];
v[5][i*3+0] = x[i*3+2];
v[5][i*3+1] = 0.;
v[5][i*3+2] = -x[i*3+0];
}
}
for (i=0; i<nmodes; i++) {ierr = VecRestoreArray(vec[i],&v[i]);CHKERRQ(ierr);}
ierr = VecRestoreArrayRead(coords,&x);CHKERRQ(ierr);
for (i=dim; i<nmodes; i++) {
/* Orthonormalize vec[i] against vec[0:dim] */
ierr = VecMDot(vec[i],i,vec,dots);CHKERRQ(ierr);
for (j=0; j<i; j++) dots[j] *= -1.;
ierr = VecMAXPY(vec[i],i,dots,vec);CHKERRQ(ierr);
ierr = VecNormalize(vec[i],NULL);CHKERRQ(ierr);
}
ierr = MatNullSpaceCreate(PetscObjectComm((PetscObject)coords),PETSC_FALSE,nmodes,vec,sp);CHKERRQ(ierr);
for (i=0; i<nmodes; i++) {ierr = VecDestroy(&vec[i]);CHKERRQ(ierr);}
}
PetscFunctionReturn(0);
}
示例12: PetscViewerFileSetName_ASCII
PetscErrorCode PetscViewerFileSetName_ASCII(PetscViewer viewer,const char name[])
{
PetscErrorCode ierr;
size_t len;
char fname[PETSC_MAX_PATH_LEN],*gz;
PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
PetscBool isstderr,isstdout;
PetscMPIInt rank;
PetscFunctionBegin;
ierr = PetscViewerFileClose_ASCII(viewer);CHKERRQ(ierr);
if (!name) PetscFunctionReturn(0);
ierr = PetscStrallocpy(name,&vascii->filename);CHKERRQ(ierr);
/* Is this file to be compressed */
vascii->storecompressed = PETSC_FALSE;
ierr = PetscStrstr(vascii->filename,".gz",&gz);CHKERRQ(ierr);
if (gz) {
ierr = PetscStrlen(gz,&len);CHKERRQ(ierr);
if (len == 3) {
*gz = 0;
vascii->storecompressed = PETSC_TRUE;
}
}
ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);CHKERRQ(ierr);
if (!rank) {
ierr = PetscStrcmp(name,"stderr",&isstderr);CHKERRQ(ierr);
ierr = PetscStrcmp(name,"stdout",&isstdout);CHKERRQ(ierr);
/* empty filename means stdout */
if (name[0] == 0) isstdout = PETSC_TRUE;
if (isstderr) vascii->fd = PETSC_STDERR;
else if (isstdout) vascii->fd = PETSC_STDOUT;
else {
ierr = PetscFixFilename(name,fname);CHKERRQ(ierr);
switch (vascii->mode) {
case FILE_MODE_READ:
vascii->fd = fopen(fname,"r");
break;
case FILE_MODE_WRITE:
vascii->fd = fopen(fname,"w");
break;
case FILE_MODE_APPEND:
vascii->fd = fopen(fname,"a");
break;
case FILE_MODE_UPDATE:
vascii->fd = fopen(fname,"r+");
if (!vascii->fd) vascii->fd = fopen(fname,"w+");
break;
case FILE_MODE_APPEND_UPDATE:
/* I really want a file which is opened at the end for updating,
not a+, which opens at the beginning, but makes writes at the end.
*/
vascii->fd = fopen(fname,"r+");
if (!vascii->fd) vascii->fd = fopen(fname,"w+");
else {
ierr = fseek(vascii->fd, 0, SEEK_END);CHKERRQ(ierr);
}
break;
default:
SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG, "Invalid file mode %d", vascii->mode);
}
if (!vascii->fd) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open PetscViewer file: %s",fname);
}
}
#if defined(PETSC_USE_LOG)
PetscLogObjectState((PetscObject)viewer,"File: %s",name);
#endif
PetscFunctionReturn(0);
}
示例13: KSPAGMRESRoddec
PetscErrorCode KSPAGMRESRoddec(KSP ksp, PetscInt nvec)
{
KSP_AGMRES *agmres = (KSP_AGMRES*) ksp->data;
MPI_Comm comm;
PetscScalar *Qloc = agmres->Qloc;
PetscScalar *sgn = agmres->sgn;
PetscScalar *tloc = agmres->tloc;
PetscErrorCode ierr;
PetscReal *wbufptr = agmres->wbufptr;
PetscMPIInt rank = agmres->rank;
PetscMPIInt First = agmres->First;
PetscMPIInt Last = agmres->Last;
PetscBLASInt nloc,pas,len;
PetscInt d, i, j, k;
PetscInt pos,tag;
PetscReal c, s, rho, Ajj, val, tt, old;
PetscScalar *col;
MPI_Status status;
PetscBLASInt N = MAXKSPSIZE + 1;
PetscFunctionBegin;
ierr = PetscObjectGetComm((PetscObject)ksp,&comm);CHKERRQ(ierr);
tag = 0x666;
ierr = PetscLogEventBegin(KSP_AGMRESRoddec,ksp,0,0,0);CHKERRQ(ierr);
ierr = PetscMemzero(agmres->Rloc, N*N*sizeof(PetscScalar));CHKERRQ(ierr);
/* check input arguments */
if (nvec < 1) SETERRQ(PetscObjectComm((PetscObject)ksp),PETSC_ERR_ARG_OUTOFRANGE, "The number of input vectors shoud be positive");
ierr = VecGetLocalSize(VEC_V(0), &nloc);CHKERRQ(ierr);
if (nvec > nloc) SETERRQ(PetscObjectComm((PetscObject)ksp), PETSC_ERR_ARG_WRONG, "In QR factorization, the number of local rows should be greater or equal to the number of columns");
pas = 1;
k = 0;
/* Copy the vectors of the basis */
for (j = 0; j < nvec; j++) {
ierr = VecGetArray(VEC_V(j), &col);CHKERRQ(ierr);
PetscStackCallBLAS("BLAScopy",BLAScopy_(&nloc, col, &pas, &Qloc[j*nloc], &pas));
ierr = VecRestoreArray(VEC_V(j), &col);CHKERRQ(ierr);
}
/* Each process performs a local QR on its own block */
for (j = 0; j < nvec; j++) {
len = nloc - j;
Ajj = Qloc[j*nloc+j];
rho = -PetscSign(Ajj) * BLASnrm2_(&len, &(Qloc[j*nloc+j]), &pas);
if (rho == 0.0) tloc[j] = 0.0;
else {
tloc[j] = (Ajj - rho) / rho;
len = len - 1;
val = 1.0 / (Ajj - rho);
PetscStackCallBLAS("BLASscal",BLASscal_(&len, &val, &(Qloc[j*nloc+j+1]), &pas));
Qloc[j*nloc+j] = 1.0;
len = len + 1;
for (k = j + 1; k < nvec; k++) {
PetscStackCallBLAS("BLASdot",tt = tloc[j] * BLASdot_(&len, &(Qloc[j*nloc+j]), &pas, &(Qloc[k*nloc+j]), &pas));
PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&len, &tt, &(Qloc[j*nloc+j]), &pas, &(Qloc[k*nloc+j]), &pas));
}
Qloc[j*nloc+j] = rho;
}
}
/*annihilate undesirable Rloc, diagonal by diagonal*/
for (d = 0; d < nvec; d++) {
len = nvec - d;
if (rank == First) {
PetscStackCallBLAS("BLAScopy",BLAScopy_(&len, &(Qloc[d*nloc+d]), &nloc, &(wbufptr[d]), &pas));
ierr = MPI_Send(&(wbufptr[d]), len, MPIU_SCALAR, rank + 1, tag, comm);CHKERRQ(ierr);
} else {
ierr = MPI_Recv(&(wbufptr[d]), len, MPIU_SCALAR, rank - 1, tag, comm, &status);CHKERRQ(ierr);
/*Elimination of Rloc(1,d)*/
c = wbufptr[d];
s = Qloc[d*nloc];
ierr = KSPAGMRESRoddecGivens(&c, &s, &rho, 1);
/*Apply Givens Rotation*/
for (k = d; k < nvec; k++) {
old = wbufptr[k];
wbufptr[k] = c * old - s * Qloc[k*nloc];
Qloc[k*nloc] = s * old + c * Qloc[k*nloc];
}
Qloc[d*nloc] = rho;
if (rank != Last) {
ierr = MPI_Send(& (wbufptr[d]), len, MPIU_SCALAR, rank + 1, tag, comm);CHKERRQ(ierr);
}
/* zero-out the d-th diagonal of Rloc ...*/
for (j = d + 1; j < nvec; j++) {
/* elimination of Rloc[i][j]*/
i = j - d;
c = Qloc[j*nloc+i-1];
s = Qloc[j*nloc+i];
ierr = KSPAGMRESRoddecGivens(&c, &s, &rho, 1);CHKERRQ(ierr);
for (k = j; k < nvec; k++) {
old = Qloc[k*nloc+i-1];
Qloc[k*nloc+i-1] = c * old - s * Qloc[k*nloc+i];
Qloc[k*nloc+i] = s * old + c * Qloc[k*nloc+i];
}
Qloc[j*nloc+i] = rho;
}
if (rank == Last) {
PetscStackCallBLAS("BLAScopy",BLAScopy_(&len, &(wbufptr[d]), &pas, RLOC(d,d), &N));
for (k = d + 1; k < nvec; k++) *RLOC(k,d) = 0.0;
}
}
}
//.........这里部分代码省略.........
示例14: MatGetMultiProcBlock_MPIAIJ
PetscErrorCode MatGetMultiProcBlock_MPIAIJ(Mat mat, MPI_Comm subComm, MatReuse scall,Mat *subMat)
{
PetscErrorCode ierr;
Mat_MPIAIJ *aij = (Mat_MPIAIJ*)mat->data;
Mat_SeqAIJ *aijB = (Mat_SeqAIJ*)aij->B->data;
PetscMPIInt commRank,subCommSize,subCommRank;
PetscMPIInt *commRankMap,subRank,rank,commsize;
PetscInt *garrayCMap,col,i,j,*nnz,newRow,newCol;
PetscFunctionBegin;
ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&commsize);CHKERRQ(ierr);
ierr = MPI_Comm_size(subComm,&subCommSize);CHKERRQ(ierr);
/* create subMat object with the relavent layout */
if (scall == MAT_INITIAL_MATRIX) {
ierr = MatCreate(subComm,subMat);CHKERRQ(ierr);
ierr = MatSetType(*subMat,MATMPIAIJ);CHKERRQ(ierr);
ierr = MatSetSizes(*subMat,mat->rmap->n,mat->cmap->n,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr);
ierr = MatSetBlockSizesFromMats(*subMat,mat,mat);CHKERRQ(ierr);
/* need to setup rmap and cmap before Preallocation */
ierr = PetscLayoutSetUp((*subMat)->rmap);CHKERRQ(ierr);
ierr = PetscLayoutSetUp((*subMat)->cmap);CHKERRQ(ierr);
}
/* create a map of comm_rank from subComm to comm - should commRankMap and garrayCMap be kept for reused? */
ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)mat),&commRank);CHKERRQ(ierr);
ierr = MPI_Comm_rank(subComm,&subCommRank);CHKERRQ(ierr);
ierr = PetscMalloc1(subCommSize,&commRankMap);CHKERRQ(ierr);
ierr = MPI_Allgather(&commRank,1,MPI_INT,commRankMap,1,MPI_INT,subComm);CHKERRQ(ierr);
/* Traverse garray and identify column indices [of offdiag mat] that
should be discarded. For the ones not discarded, store the newCol+1
value in garrayCMap */
ierr = PetscCalloc1(aij->B->cmap->n,&garrayCMap);CHKERRQ(ierr);
for (i=0; i<aij->B->cmap->n; i++) {
col = aij->garray[i];
for (subRank=0; subRank<subCommSize; subRank++) {
rank = commRankMap[subRank];
if ((col >= mat->cmap->range[rank]) && (col < mat->cmap->range[rank+1])) {
garrayCMap[i] = (*subMat)->cmap->range[subRank] + col - mat->cmap->range[rank]+1;
break;
}
}
}
if (scall == MAT_INITIAL_MATRIX) {
/* Now compute preallocation for the offdiag mat */
ierr = PetscCalloc1(aij->B->rmap->n,&nnz);CHKERRQ(ierr);
for (i=0; i<aij->B->rmap->n; i++) {
for (j=aijB->i[i]; j<aijB->i[i+1]; j++) {
if (garrayCMap[aijB->j[j]]) nnz[i]++;
}
}
ierr = MatMPIAIJSetPreallocation(*(subMat),0,NULL,0,nnz);CHKERRQ(ierr);
/* reuse diag block with the new submat */
ierr = MatDestroy(&((Mat_MPIAIJ*)((*subMat)->data))->A);CHKERRQ(ierr);
((Mat_MPIAIJ*)((*subMat)->data))->A = aij->A;
ierr = PetscObjectReference((PetscObject)aij->A);CHKERRQ(ierr);
} else if (((Mat_MPIAIJ*)(*subMat)->data)->A != aij->A) {
PetscObject obj = (PetscObject)((Mat_MPIAIJ*)((*subMat)->data))->A;
ierr = PetscObjectReference((PetscObject)obj);CHKERRQ(ierr);
((Mat_MPIAIJ*)((*subMat)->data))->A = aij->A;
ierr = PetscObjectReference((PetscObject)aij->A);CHKERRQ(ierr);
}
/* Now traverse aij->B and insert values into subMat */
for (i=0; i<aij->B->rmap->n; i++) {
newRow = (*subMat)->rmap->range[subCommRank] + i;
for (j=aijB->i[i]; j<aijB->i[i+1]; j++) {
newCol = garrayCMap[aijB->j[j]];
if (newCol) {
newCol--; /* remove the increment */
ierr = MatSetValues(*subMat,1,&newRow,1,&newCol,(aijB->a+j),INSERT_VALUES);CHKERRQ(ierr);
}
}
}
/* assemble the submat */
ierr = MatAssemblyBegin(*subMat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
ierr = MatAssemblyEnd(*subMat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
/* deallocate temporary data */
ierr = PetscFree(commRankMap);CHKERRQ(ierr);
ierr = PetscFree(garrayCMap);CHKERRQ(ierr);
if (scall == MAT_INITIAL_MATRIX) {
ierr = PetscFree(nnz);CHKERRQ(ierr);
}
PetscFunctionReturn(0);
}
示例15: F
/*
MatMult_MFFD - Default matrix-free form for Jacobian-vector product, y = F'(u)*a:
y ~= (F(u + ha) - F(u))/h,
where F = nonlinear function, as set by SNESSetFunction()
u = current iterate
h = difference interval
*/
PetscErrorCode MatMult_MFFD(Mat mat,Vec a,Vec y)
{
MatMFFD ctx = (MatMFFD)mat->data;
PetscScalar h;
Vec w,U,F;
PetscErrorCode ierr;
PetscBool zeroa;
PetscFunctionBegin;
if (!ctx->current_u) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"MatMFFDSetBase() has not been called, this is often caused by forgetting to call \n\t\tMatAssemblyBegin/End on the first Mat in the SNES compute function");
/* We log matrix-free matrix-vector products separately, so that we can
separate the performance monitoring from the cases that use conventional
storage. We may eventually modify event logging to associate events
with particular objects, hence alleviating the more general problem. */
ierr = PetscLogEventBegin(MATMFFD_Mult,a,y,0,0);CHKERRQ(ierr);
w = ctx->w;
U = ctx->current_u;
F = ctx->current_f;
/*
Compute differencing parameter
*/
if (!ctx->ops->compute) {
ierr = MatMFFDSetType(mat,MATMFFD_WP);CHKERRQ(ierr);
ierr = MatSetFromOptions(mat);CHKERRQ(ierr);
}
ierr = (*ctx->ops->compute)(ctx,U,a,&h,&zeroa);CHKERRQ(ierr);
if (zeroa) {
ierr = VecSet(y,0.0);CHKERRQ(ierr);
PetscFunctionReturn(0);
}
if (PetscIsInfOrNanScalar(h)) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Computed Nan differencing parameter h");
if (ctx->checkh) {
ierr = (*ctx->checkh)(ctx->checkhctx,U,a,&h);CHKERRQ(ierr);
}
/* keep a record of the current differencing parameter h */
ctx->currenth = h;
#if defined(PETSC_USE_COMPLEX)
ierr = PetscInfo2(mat,"Current differencing parameter: %G + %G i\n",PetscRealPart(h),PetscImaginaryPart(h));CHKERRQ(ierr);
#else
ierr = PetscInfo1(mat,"Current differencing parameter: %15.12e\n",h);CHKERRQ(ierr);
#endif
if (ctx->historyh && ctx->ncurrenth < ctx->maxcurrenth) {
ctx->historyh[ctx->ncurrenth] = h;
}
ctx->ncurrenth++;
/* w = u + ha */
if (ctx->drscale) {
ierr = VecPointwiseMult(ctx->drscale,a,U);CHKERRQ(ierr);
ierr = VecAYPX(U,h,w);CHKERRQ(ierr);
} else {
ierr = VecWAXPY(w,h,a,U);CHKERRQ(ierr);
}
/* compute func(U) as base for differencing; only needed first time in and not when provided by user */
if (ctx->ncurrenth == 1 && ctx->current_f_allocated) {
ierr = (*ctx->func)(ctx->funcctx,U,F);CHKERRQ(ierr);
}
ierr = (*ctx->func)(ctx->funcctx,w,y);CHKERRQ(ierr);
ierr = VecAXPY(y,-1.0,F);CHKERRQ(ierr);
ierr = VecScale(y,1.0/h);CHKERRQ(ierr);
if ((ctx->vshift != 0.0) || (ctx->vscale != 1.0)) {
ierr = VecAXPBY(y,ctx->vshift,ctx->vscale,a);CHKERRQ(ierr);
}
if (ctx->dlscale) {
ierr = VecPointwiseMult(y,ctx->dlscale,y);CHKERRQ(ierr);
}
if (ctx->dshift) {
ierr = VecPointwiseMult(ctx->dshift,a,U);CHKERRQ(ierr);
ierr = VecAXPY(y,1.0,U);CHKERRQ(ierr);
}
if (ctx->sp) {ierr = MatNullSpaceRemove(ctx->sp,y);CHKERRQ(ierr);}
ierr = PetscLogEventEnd(MATMFFD_Mult,a,y,0,0);CHKERRQ(ierr);
PetscFunctionReturn(0);
}