void NonlinearSystem::stopSolve() { #ifdef LIBMESH_HAVE_PETSC #if PETSC_VERSION_LESS_THAN(3, 0, 0) #else PetscNonlinearSolver<Real> & solver = static_cast<PetscNonlinearSolver<Real> &>(*sys().nonlinear_solver); SNESSetFunctionDomainError(solver.snes()); #endif #endif // Insert a NaN into the residual vector. As of PETSc-3.6, this // should make PETSc return DIVERGED_NANORINF the next time it does // a reduction. We'll write to the first local dof on every // processor that has any dofs. _transient_sys.rhs->close(); if (_transient_sys.rhs->local_size()) _transient_sys.rhs->set(_transient_sys.rhs->first_local_index(), std::numeric_limits<Real>::quiet_NaN()); _transient_sys.rhs->close(); // Clean up by getting other vectors into a valid state for a // (possible) subsequent solve. There may be more than just // these... if (_Re_time) _Re_time->close(); _Re_non_time->close(); }
PetscErrorCode SNESComputeFunctionDefaultNPC(SNES snes,Vec X,Vec F) { /* This is to be used as an argument to SNESMF -- NOT as a "function" */ SNESConvergedReason reason; PetscErrorCode ierr; PetscFunctionBegin; if (snes->pc) { ierr = SNESApplyNPC(snes,X,NULL,F);CHKERRQ(ierr); ierr = SNESGetConvergedReason(snes->pc,&reason);CHKERRQ(ierr); if (reason < 0 && reason != SNES_DIVERGED_MAX_IT) { ierr = SNESSetFunctionDomainError(snes);CHKERRQ(ierr); } } else { ierr = SNESComputeFunction(snes,X,F);CHKERRQ(ierr); } PetscFunctionReturn(0); }
PetscErrorCode FormFunctionLocal(DMDALocalInfo *info,Field **x,Field **f,void *ptr) { AppCtx *user = (AppCtx*)ptr; PetscErrorCode ierr; PetscInt xints,xinte,yints,yinte,i,j; PetscReal hx,hy,dhx,dhy,hxdhy,hydhx; PetscReal grashof,prandtl,lid; PetscScalar u,uxx,uyy,vx,vy,avx,avy,vxp,vxm,vyp,vym; static PetscInt fail = 0; PetscFunctionBeginUser; if ((fail++ > 7 && user->errorindomainmf) || (fail++ > 36 && user->errorindomain)){ PetscMPIInt rank; ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)user->snes),&rank);CHKERRQ(ierr); if (!rank) { ierr = SNESSetFunctionDomainError(user->snes);CHKERRQ(ierr); } } grashof = user->grashof; prandtl = user->prandtl; lid = user->lidvelocity; /* Define mesh intervals ratios for uniform grid. Note: FD formulae below are normalized by multiplying through by local volume element (i.e. hx*hy) to obtain coefficients O(1) in two dimensions. */ dhx = (PetscReal)(info->mx-1); dhy = (PetscReal)(info->my-1); hx = 1.0/dhx; hy = 1.0/dhy; hxdhy = hx*dhy; hydhx = hy*dhx; xints = info->xs; xinte = info->xs+info->xm; yints = info->ys; yinte = info->ys+info->ym; /* Test whether we are on the bottom edge of the global array */ if (yints == 0) { j = 0; yints = yints + 1; /* bottom edge */ for (i=info->xs; i<info->xs+info->xm; i++) { f[j][i].u = x[j][i].u; f[j][i].v = x[j][i].v; f[j][i].omega = x[j][i].omega + (x[j+1][i].u - x[j][i].u)*dhy; f[j][i].temp = x[j][i].temp-x[j+1][i].temp; } } /* Test whether we are on the top edge of the global array */ if (yinte == info->my) { j = info->my - 1; yinte = yinte - 1; /* top edge */ for (i=info->xs; i<info->xs+info->xm; i++) { f[j][i].u = x[j][i].u - lid; f[j][i].v = x[j][i].v; f[j][i].omega = x[j][i].omega + (x[j][i].u - x[j-1][i].u)*dhy; f[j][i].temp = x[j][i].temp-x[j-1][i].temp; } } /* Test whether we are on the left edge of the global array */ if (xints == 0) { i = 0; xints = xints + 1; /* left edge */ for (j=info->ys; j<info->ys+info->ym; j++) { f[j][i].u = x[j][i].u; f[j][i].v = x[j][i].v; f[j][i].omega = x[j][i].omega - (x[j][i+1].v - x[j][i].v)*dhx; f[j][i].temp = x[j][i].temp; } } /* Test whether we are on the right edge of the global array */ if (xinte == info->mx) { i = info->mx - 1; xinte = xinte - 1; /* right edge */ for (j=info->ys; j<info->ys+info->ym; j++) { f[j][i].u = x[j][i].u; f[j][i].v = x[j][i].v; f[j][i].omega = x[j][i].omega - (x[j][i].v - x[j][i-1].v)*dhx; f[j][i].temp = x[j][i].temp - (PetscReal)(grashof>0); } } /* Compute over the interior points */ for (j=yints; j<yinte; j++) { for (i=xints; i<xinte; i++) { /* convective coefficients for upwinding */ vx = x[j][i].u; avx = PetscAbsScalar(vx); vxp = .5*(vx+avx); vxm = .5*(vx-avx); vy = x[j][i].v; avy = PetscAbsScalar(vy); vyp = .5*(vy+avy); vym = .5*(vy-avy); /* U velocity */ u = x[j][i].u; uxx = (2.0*u - x[j][i-1].u - x[j][i+1].u)*hydhx; uyy = (2.0*u - x[j-1][i].u - x[j+1][i].u)*hxdhy; f[j][i].u = uxx + uyy - .5*(x[j+1][i].omega-x[j-1][i].omega)*hx; /* V velocity */ u = x[j][i].v; uxx = (2.0*u - x[j][i-1].v - x[j][i+1].v)*hydhx; uyy = (2.0*u - x[j-1][i].v - x[j+1][i].v)*hxdhy; f[j][i].v = uxx + uyy + .5*(x[j][i+1].omega-x[j][i-1].omega)*hy; /* Omega */ u = x[j][i].omega; uxx = (2.0*u - x[j][i-1].omega - x[j][i+1].omega)*hydhx; uyy = (2.0*u - x[j-1][i].omega - x[j+1][i].omega)*hxdhy; f[j][i].omega = uxx + uyy + (vxp*(u - x[j][i-1].omega) + vxm*(x[j][i+1].omega - u))*hy + (vyp*(u - x[j-1][i].omega) + vym*(x[j+1][i].omega - u))*hx - .5*grashof*(x[j][i+1].temp - x[j][i-1].temp)*hy; /* Temperature */ u = x[j][i].temp; uxx = (2.0*u - x[j][i-1].temp - x[j][i+1].temp)*hydhx; uyy = (2.0*u - x[j-1][i].temp - x[j+1][i].temp)*hxdhy; f[j][i].temp = uxx + uyy + prandtl*((vxp*(u - x[j][i-1].temp) + vxm*(x[j][i+1].temp - u))*hy + (vyp*(u - x[j-1][i].temp) + vym*(x[j+1][i].temp - u))*hx); } } /* Flop count (multiply-adds are counted as 2 operations) */ ierr = PetscLogFlops(84.0*info->ym*info->xm);CHKERRQ(ierr); PetscFunctionReturn(0); }