PetscErrorCode VecCompare(Vec a,Vec b) { PetscInt locmin[2],locmax[2]; PetscReal min[2],max[2]; Vec ref; PetscErrorCode ierr; PetscFunctionBeginUser; ierr = VecMin(a,&locmin[0],&min[0]);CHKERRQ(ierr); ierr = VecMax(a,&locmax[0],&max[0]);CHKERRQ(ierr); ierr = VecMin(b,&locmin[1],&min[1]);CHKERRQ(ierr); ierr = VecMax(b,&locmax[1],&max[1]);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"VecCompare\n");CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD," min(a) = %+1.2e [loc %D]\n",(double)min[0],locmin[0]);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD," max(a) = %+1.2e [loc %D]\n",(double)max[0],locmax[0]);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD," min(b) = %+1.2e [loc %D]\n",(double)min[1],locmin[1]);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD," max(b) = %+1.2e [loc %D]\n",(double)max[1],locmax[1]);CHKERRQ(ierr); ierr = VecDuplicate(a,&ref);CHKERRQ(ierr); ierr = VecCopy(a,ref);CHKERRQ(ierr); ierr = VecAXPY(ref,-1.0,b);CHKERRQ(ierr); ierr = VecMin(ref,&locmin[0],&min[0]);CHKERRQ(ierr); if (PetscAbsReal(min[0]) > 1.0e-10) { ierr = PetscPrintf(PETSC_COMM_WORLD," ERROR: min(a-b) > 1.0e-10\n");CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD," min(a-b) = %+1.10e\n",(double)PetscAbsReal(min[0]));CHKERRQ(ierr); } else { ierr = PetscPrintf(PETSC_COMM_WORLD," min(a-b) < 1.0e-10\n");CHKERRQ(ierr); } ierr = VecDestroy(&ref);CHKERRQ(ierr); PetscFunctionReturn(0); }
_Use_decl_annotations_ BIH* BIH::CreateFromTriangles(const StaticGeometryVertex* vertices, uint32_t numVertices, const uint32_t* indices, uint32_t numIndices) { UNREFERENCED_PARAMETER(numVertices); uint32_t numTriangles = numIndices / 3; assert(numTriangles > 0); CompileTriangle* triangles = new CompileTriangle(vertices[indices[0]], vertices[indices[1]], vertices[indices[2]], indices[0], indices[1], indices[2], vertices[indices[0]].MaterialId); XMFLOAT3 min = triangles->Min; XMFLOAT3 max = triangles->Max; for (uint32_t i = 1; i < numTriangles; ++i) { CompileTriangle* t = new CompileTriangle(vertices[indices[i * 3]], vertices[indices[i * 3 + 1]], vertices[indices[i * 3 + 2]], indices[i * 3], indices[i * 3 + 1], indices[i * 3 + 2], vertices[indices[i * 3]].MaterialId); t->Next = triangles; triangles = t; min = VecMin(min, t->Min); max = VecMax(max, t->Max); } BIH* bih = new BIH; bih->_bounds = AABB(min, max); bih->_root = bih->ProcessTriangles(&triangles, numTriangles, bih->_bounds); return bih; }
_Use_decl_annotations_ void KdTreeCompiler2::BuildVisibleIndexList(const XMMATRIX& cameraWorld, const XMMATRIX& projection, uint32_t* indices, uint32_t maxIndices, uint32_t* numIndices, uint32_t* materials, uint32_t maxMaterials, uint32_t* numMaterials) { *numIndices = 0; *numMaterials = 0; // TODO: Remove dependency on BoundingFrustum. Since all we // need is the 4 corners, we can derive those directly from view & projection BoundingFrustum frustum; BoundingFrustum::CreateFromMatrix(frustum, projection); frustum.Transform(frustum, cameraWorld); XMFLOAT3 corners[8]; frustum.GetCorners(corners); XMFLOAT3 min = corners[0]; XMFLOAT3 max = corners[0]; for (uint32_t i = 1; i < 8; ++i) { min = VecMin(min, corners[i]); max = VecMax(max, corners[i]); } XMFLOAT3 position; XMStoreFloat3(&position, cameraWorld.r[3]); AppendVisibleIndices(&position.x, &min.x, &max.x, _root, indices, maxIndices, numIndices, materials, maxMaterials, numMaterials); }
PetscErrorCode ReactingFlowPostCheck(SNESLineSearch linesearch, Vec X, Vec Y, Vec W, PetscBool *changed_y, PetscBool *changed_w, void *vctx) { PetscInt i,j,l,Mx,My,xs,ys,xm,ym; PetscErrorCode ierr; Field **x; SNES snes; DM da; PetscScalar min; PetscFunctionBeginUser; *changed_w = PETSC_FALSE; ierr = VecMin(X,NULL,&min);CHKERRQ(ierr); if (min >= 0.) PetscFunctionReturn(0); *changed_w = PETSC_TRUE; ierr = SNESLineSearchGetSNES(linesearch, &snes);CHKERRQ(ierr); ierr = SNESGetDM(snes,&da);CHKERRQ(ierr); ierr = DMDAGetInfo(da,PETSC_IGNORE,&Mx,&My,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE, PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE); ierr = DMDAVecGetArray(da,W,&x);CHKERRQ(ierr); ierr = DMDAGetCorners(da,&xs,&ys,NULL,&xm,&ym,NULL);CHKERRQ(ierr); for (j=ys; j<ys+ym; j++) { for (i=xs; i<xs+xm; i++) { for (l = 0; l < N_SPECIES; l++) { if (x[j][i].sp[l] < 0.) x[j][i].sp[l] = 0.; } } } ierr = DMDAVecRestoreArray(da,W,&x);CHKERRQ(ierr); PetscFunctionReturn(0); }
static PetscErrorCode VecMin_Nest_Recursive(Vec x,PetscInt *cnt,PetscInt *p,PetscReal *min) { Vec_Nest *bx = (Vec_Nest*)x->data; PetscInt i,nr,L,_entry_loc; PetscBool isnest; PetscReal _entry_val; PetscErrorCode ierr; PetscFunctionBegin; ierr = PetscObjectTypeCompare((PetscObject)x,VECNEST,&isnest);CHKERRQ(ierr); if (!isnest) { /* Not nest */ ierr = VecMin(x,&_entry_loc,&_entry_val);CHKERRQ(ierr); if (_entry_val < *min) { *min = _entry_val; *p = _entry_loc + *cnt; } ierr = VecGetSize(x,&L);CHKERRQ(ierr); *cnt = *cnt + L; PetscFunctionReturn(0); } /* Otherwise we have a nest */ bx = (Vec_Nest*)x->data; nr = bx->nb; /* now descend recursively */ for (i=0; i<nr; i++) { ierr = VecMin_Nest_Recursive(bx->v[i],cnt,p,min);CHKERRQ(ierr); } PetscFunctionReturn(0); }
inline double PetscVector::min () const { this->_restore_array(); int index=0, ierr=0; PetscReal min=0.; ierr = VecMin (_vec, &index, &min); CHKERRABORT(MPI_COMM_WORLD,ierr); // this return value is correct: VecMin returns a PetscReal return static_cast<double>(min); }
realtype N_VMin_Petsc(N_Vector x) { Vec *xv = NV_PVEC_PTC(x); PetscReal minval; PetscInt i; VecMin(*xv, &i, &minval); return minval; }
void MonodomainProblem<ELEMENT_DIM, SPACE_DIM>::WriteInfo(double time) { if (PetscTools::AmMaster()) { std::cout << "Solved to time " << time << "\n" << std::flush; } double v_max, v_min; VecMax( this->mSolution, PETSC_NULL, &v_max ); VecMin( this->mSolution, PETSC_NULL, &v_min ); if (PetscTools::AmMaster()) { std::cout << " V = " << "[" <<v_min << ", " << v_max << "]" << "\n" << std::flush; } }
PetscErrorCode MyTSMonitor(TS ts,PetscInt step,PetscReal ptime,Vec v,void *ptr) { PetscErrorCode ierr; PetscReal norm,vmax,vmin; MPI_Comm comm; MonitorCtx *user = (MonitorCtx*)ptr; PetscFunctionBegin; ierr = VecNorm(v,NORM_1,&norm);CHKERRQ(ierr); ierr = VecMax(v,PETSC_NULL,&vmax);CHKERRQ(ierr); ierr = VecMin(v,PETSC_NULL,&vmin);CHKERRQ(ierr); ierr = PetscObjectGetComm((PetscObject)ts,&comm);CHKERRQ(ierr); ierr = PetscPrintf(comm,"timestep %D: time %G, solution norm %G, max %G, min %G\n",step,ptime,norm,vmax,vmin);CHKERRQ(ierr); if (user->drawcontours){ ierr = VecView(v,PETSC_VIEWER_DRAW_WORLD);CHKERRQ(ierr); } PetscFunctionReturn(0); }
PetscErrorCode VecMin_MultiVec(Vec x, PetscInt* p, PetscScalar* val) { #if !defined(NDEBUG) TBOX_ASSERT(x); #endif Vec_MultiVec* mx = static_cast<Vec_MultiVec*>(x->data); #if !defined(NDEBUG) TBOX_ASSERT(mx); #endif PetscErrorCode ierr; *p = -1; *val = PETSC_MAX_REAL; for (PetscInt k = 0; k < mx->n; ++k) { PetscInt component_p; PetscScalar component_val; ierr = VecMin(mx->array[k], &component_p, &component_val); CHKERRQ(ierr); *val = std::min(*val, component_val); } PetscFunctionReturn(0); } // VecMin_MultiVec
-n <length> : vector length\n\n"; #include <petscvec.h> int main(int argc,char **argv) { PetscErrorCode ierr; PetscInt n = 5,idx; PetscReal value; Vec x; PetscScalar one = 1.0; ierr = PetscInitialize(&argc,&argv,(char*)0,help);if (ierr) return ierr; ierr = PetscOptionsGetInt(NULL,NULL,"-n",&n,NULL);CHKERRQ(ierr); /* create vector */ ierr = VecCreate(PETSC_COMM_WORLD,&x);CHKERRQ(ierr); ierr = VecSetSizes(x,PETSC_DECIDE,n);CHKERRQ(ierr); ierr = VecSetFromOptions(x);CHKERRQ(ierr); ierr = VecSet(x,one);CHKERRQ(ierr); ierr = VecSetValue(x,0,0.0,INSERT_VALUES);CHKERRQ(ierr); ierr = VecSetValue(x,n-1,2.0,INSERT_VALUES);CHKERRQ(ierr); ierr = VecAssemblyBegin(x);CHKERRQ(ierr); ierr = VecAssemblyEnd(x);CHKERRQ(ierr); ierr = VecView(x,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); ierr = VecMax(x,&idx,&value);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"Maximum value %g index %D\n",(double)value,idx);CHKERRQ(ierr); ierr = VecMin(x,&idx,&value);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"Minimum value %g index %D\n",(double)value,idx);CHKERRQ(ierr); ierr = VecDestroy(&x);CHKERRQ(ierr); ierr = PetscFinalize(); return ierr; }
PetscErrorCode BSSCR_DRIVER_flex( KSP ksp, Mat stokes_A, Vec stokes_x, Vec stokes_b, Mat approxS, KSP ksp_K, MatStokesBlockScaling BA, PetscTruth sym, KSP_BSSCR * bsscrp_self ) { char name[PETSC_MAX_PATH_LEN]; char ubefore[100]; char uafter[100]; char pbefore[100]; char pafter[100]; PetscTruth flg, flg2, truth, useAcceleratingSmoothingMG, useFancySmoothingMG; PetscTruth usePreviousGuess, useNormInfStoppingConditions, useNormInfMonitor, found, extractMats; Mat K,G,D,C; Vec u,p,f,h; Mat S; Vec h_hat,t,t2,q,v; KSP ksp_inner; KSP ksp_S; KSP ksp_cleaner; KSPType ksp_inner_type; PetscTruth has_cnst_nullspace; PC pc_S, pc_MG, pcInner; PetscInt monitor_index,max_it,min_it; Vec nsp_vec = PETSC_NULL; PetscReal scr_rtol; PetscReal inner_rtol; PetscReal vSolver_rtol; PetscScalar uNormInf, pNormInf; PetscScalar uNorm, pNorm, rNorm, fNorm; PetscInt uSize, pSize; PetscInt lmin,lmax; PetscInt iterations; PetscReal min,max; PetscReal p_sum; MGContext mgCtx; PC shellPC; double t0, t1; double mgSetupTime, scrSolveTime, a11SingleSolveTime, solutionAnalysisTime; Index nx,ny,nz; PetscInt j,start,end; static int been_here = 0; /* Ha Ha Ha !! */ /* get sub matrix / vector objects */ MatNestGetSubMat( stokes_A, 0,0, &K ); MatNestGetSubMat( stokes_A, 0,1, &G ); MatNestGetSubMat( stokes_A, 1,0, &D ); MatNestGetSubMat( stokes_A, 1,1, &C ); VecNestGetSubVec( stokes_x, 0, &u ); VecNestGetSubVec( stokes_x, 1, &p ); VecNestGetSubVec( stokes_b, 0, &f ); VecNestGetSubVec( stokes_b, 1, &h ); /* PetscPrintf( PETSC_COMM_WORLD, "\t Adress of stokes_x is %p\n", stokes_x); */ /* VecNorm( u, NORM_2, &uNorm ); */ /* PetscPrintf( PETSC_COMM_WORLD, "\t u Norm is %.6e in %s: address is %p\n",uNorm,__func__,u); */ /* VecNorm( p, NORM_2, &pNorm ); */ /* PetscPrintf( PETSC_COMM_WORLD, "\t p Norm is %.6e in %s: addres is %p\n",pNorm,__func__,p); */ /* Create Schur complement matrix */ //MatCreateSchurFromBlock( stokes_A, 0.0, "MatSchur_A11", &S ); MatCreateSchurComplement(K,K,G,D,C, &S); /* configure inner solver */ if (ksp_K!=PETSC_NULL) { MatSchurComplementSetKSP( S, ksp_K ); MatSchurComplementGetKSP( S, &ksp_inner ); } else { abort(); MatSchurComplementGetKSP( S, &ksp_inner ); KSPSetType( ksp_inner, "cg" ); } KSPGetPC( ksp_inner, &pcInner ); /* If we're using multigrid, replace the preconditioner here so we get the same options prefix. */ if(bsscrp_self->mg) { mgSetupTime=setupMG( bsscrp_self, ksp_inner, pcInner, K, &mgCtx ); } /* SETFROMOPTIONS MIGHT F**K MG UP */ KSPSetOptionsPrefix( ksp_inner, "A11_" ); KSPSetFromOptions( ksp_inner ); useNormInfStoppingConditions = PETSC_FALSE; PetscOptionsGetTruth( PETSC_NULL ,"-A11_use_norm_inf_stopping_condition", &useNormInfStoppingConditions, &found ); if(useNormInfStoppingConditions) BSSCR_KSPSetNormInfConvergenceTest( ksp_inner ); useNormInfMonitor = PETSC_FALSE; PetscOptionsGetTruth( PETSC_NULL, "-A11_ksp_norm_inf_monitor", &useNormInfMonitor, &found ); if(useNormInfMonitor) KSPMonitorSet( ksp_inner, BSSCR_KSPNormInfMonitor, PETSC_NULL, PETSC_NULL ); useNormInfMonitor = PETSC_FALSE; PetscOptionsGetTruth( PETSC_NULL, "-A11_ksp_norm_inf_to_norm_2_monitor", &useNormInfMonitor, &found ); if(useNormInfMonitor) KSPMonitorSet( ksp_inner, BSSCR_KSPNormInfToNorm2Monitor, PETSC_NULL, PETSC_NULL ); /* create right hand side */ /* h_hat = G'*inv(K)*f - h */ MatGetVecs(K,PETSC_NULL,&t); MatGetVecs( S, PETSC_NULL, &h_hat ); KSPSetOptionsPrefix( ksp_inner, "A11_" ); KSPSetFromOptions( ksp_inner ); KSPSolve(ksp_inner,f,t);/* t=f/K */ //bsscr_writeVec( t, "ts", "Writing t vector"); MatMult(D,t,h_hat);/* G'*t */ VecAXPY(h_hat, -1.0, h);/* h_hat = h_hat - h */ Stg_VecDestroy(&t); //bsscr_writeVec( h_hat, "h_hat", "Writing h_hat Vector in Solver"); //MatSchurApplyReductionToVecFromBlock( S, stokes_b, h_hat ); /* create solver for S p = h_hat */ KSPCreate( PETSC_COMM_WORLD, &ksp_S ); KSPSetOptionsPrefix( ksp_S, "scr_"); Stg_KSPSetOperators( ksp_S, S,S, SAME_NONZERO_PATTERN ); KSPSetType( ksp_S, "cg" ); /* Build preconditioner for S */ KSPGetPC( ksp_S, &pc_S ); BSSCR_BSSCR_StokesCreatePCSchur2( K,G,D,C,approxS,pc_S,sym, bsscrp_self ); KSPSetFromOptions(ksp_S); /* Set specific monitor test */ KSPGetTolerances( ksp_S, PETSC_NULL, PETSC_NULL, PETSC_NULL, &max_it ); //BSSCR_KSPLogSetMonitor( ksp_S, max_it, &monitor_index ); /* Pressure / Velocity Solve */ scrSolveTime = MPI_Wtime(); PetscPrintf( PETSC_COMM_WORLD, "\t* Pressure / Velocity Solve \n"); usePreviousGuess = PETSC_FALSE; if(been_here) PetscOptionsGetTruth( PETSC_NULL, "-scr_use_previous_guess", &usePreviousGuess, &found ); if(usePreviousGuess) { /* Note this should actually look at checkpoint information */ KSPSetInitialGuessNonzero( ksp_S, PETSC_TRUE ); } else { KSPSetInitialGuessNonzero( ksp_S, PETSC_FALSE ); } //KSPSetRelativeRhsConvergenceTest( ksp_S ); useNormInfStoppingConditions = PETSC_FALSE; PetscOptionsGetTruth( PETSC_NULL ,"-scr_use_norm_inf_stopping_condition", &useNormInfStoppingConditions, &found ); if(useNormInfStoppingConditions) BSSCR_KSPSetNormInfConvergenceTest(ksp_S); useNormInfMonitor = PETSC_FALSE; PetscOptionsGetTruth( PETSC_NULL, "-scr_ksp_norm_inf_monitor", &useNormInfMonitor, &found ); if(useNormInfMonitor) KSPMonitorSet( ksp_S, BSSCR_KSPNormInfToNorm2Monitor, PETSC_NULL, PETSC_NULL ); PetscPrintf( PETSC_COMM_WORLD, "\t* KSPSolve( ksp_S, h_hat, p )\n"); /* if h_hat needs to be fixed up ..take out any nullspace vectors here */ /* we want to check that there is no "noise" in the null-space in the h vector */ /* this causes problems when we are trying to solve a Jacobian system when the Residual is almost converged */ if(bsscrp_self->check_pressureNS){ bsscrp_self->buildPNS(ksp);/* build and set nullspace vectors on bsscr - which is on ksp (function pointer is set in KSPSetUp_BSSCR */ } PetscScalar norm, a, a1, a2, hnorm, pnorm, gnorm; MatNorm(G,NORM_INFINITY,&gnorm); VecNorm(h_hat, NORM_2, &hnorm); hnorm=hnorm/gnorm; if((hnorm < 1e-6) && (hnorm > 1e-20)){ VecScale(h_hat,1.0/hnorm); } /* test to see if v or t are in nullspace of G and orthogonalize wrt h_hat if needed */ KSPRemovePressureNullspace_BSSCR(ksp, h_hat); /***************************************/ /* set convergence test to use min_it */ found = PETSC_FALSE; min_it = 0; PetscOptionsGetInt( PETSC_NULL,"-scr_ksp_set_min_it_converge", &min_it, &found); if(found && min_it > 0){ BSSCR_KSPSetConvergenceMinIts(ksp_S, min_it, bsscrp_self); } KSPSolve( ksp_S, h_hat, p ); sprintf(pafter,"psafter_%d",been_here); bsscr_writeVec( p, pafter, "Writing p Vector in Solver"); /***************************************/ if((hnorm < 1e-6) && (hnorm > 1e-20)){ VecScale(h_hat,hnorm); VecScale(p,hnorm); } KSPRemovePressureNullspace_BSSCR(ksp, p); scrSolveTime = MPI_Wtime() - scrSolveTime; PetscPrintf( PETSC_COMM_WORLD, "\n\t* KSPSolve( ksp_S, h_hat, p ) Solve Finished in time: %lf seconds\n\n", scrSolveTime); /* Resolve with this pressure to obtain solution for u */ /* obtain solution for u */ VecDuplicate( u, &t ); MatMult( G, p, t); VecAYPX( t, -1.0, f ); /* t <- -t + f */ MatSchurComplementGetKSP( S, &ksp_inner ); a11SingleSolveTime = MPI_Wtime(); /* ---------------------------------- Final V Solve */ if(usePreviousGuess) KSPSetInitialGuessNonzero( ksp_inner, PETSC_TRUE ); KSPSetOptionsPrefix( ksp_inner, "backsolveA11_" ); KSPSetFromOptions( ksp_inner ); KSPSolve( ksp_inner, t, u ); /* Solve, then restore default tolerance and initial guess */ a11SingleSolveTime = MPI_Wtime() - a11SingleSolveTime; /* ------------------ Final V Solve */ PetscPrintf( PETSC_COMM_WORLD, "\n\nSCR Solver Summary:\n\n"); if(bsscrp_self->mg) PetscPrintf( PETSC_COMM_WORLD, " Multigrid setup: = %.4g secs \n", mgSetupTime); KSPGetIterationNumber( ksp_S, &iterations); PetscPrintf( PETSC_COMM_WORLD, " Pressure Solve: = %.4g secs / %d its\n", scrSolveTime, iterations); KSPGetIterationNumber( ksp_inner, &iterations); PetscPrintf( PETSC_COMM_WORLD, " Final V Solve: = %.4g secs / %d its\n\n", a11SingleSolveTime, iterations); /* Analysis of solution: This can be somewhat time consuming as it requires allocation / de-allocation, computing vector norms etc. So we make it optional.. This should be put into a proper KSP monitor now? */ flg = PETSC_TRUE; PetscOptionsGetTruth( PETSC_NULL, "-scr_ksp_solution_summary", &flg, &found ); if(flg) { solutionAnalysisTime = MPI_Wtime(); VecGetSize( u, &uSize ); VecGetSize( p, &pSize ); VecDuplicate( u, &t2 ); MatMult( K, u, t2); VecAYPX( t2, -1.0, t ); /* t2 <- -t2 + t ... should be the formal residual vector */ VecNorm( t2, NORM_2, &rNorm ); VecNorm( f, NORM_2, &fNorm ); PetscPrintf( PETSC_COMM_WORLD, " |f - K u - G p|/|f| = %.6e\n", rNorm/fNorm ); VecDuplicate( p, &q ); MatMult( D, u, q ); VecNorm( u, NORM_2, &uNorm ); VecNorm( q, NORM_2, &rNorm ); PetscPrintf( PETSC_COMM_WORLD, " |G^T u|_2/|u|_2 = %.6e\n", sqrt( (double) uSize / (double) pSize ) * rNorm / uNorm); VecNorm( q, NORM_INFINITY, &rNorm ); PetscPrintf( PETSC_COMM_WORLD, " |G^T u|_infty/|u|_2 = %.6e\n", sqrt( (double) uSize ) * rNorm / uNorm); VecNorm( u, NORM_INFINITY, &uNormInf ); VecNorm( u, NORM_2, &uNorm ); VecGetSize( u, &uSize ); VecNorm( p, NORM_INFINITY, &pNormInf ); VecNorm( p, NORM_2, &pNorm ); PetscPrintf( PETSC_COMM_WORLD, " |u|_{\\infty} = %.6e , u_rms = %.6e\n", uNormInf, uNorm / sqrt( (double) uSize ) ); PetscPrintf( PETSC_COMM_WORLD, " |p|_{\\infty} = %.6e , p_rms = %.6e\n", pNormInf, pNorm / sqrt( (double) pSize ) ); VecMax( u, &lmax, &max ); VecMin( u, &lmin, &min ); PetscPrintf( PETSC_COMM_WORLD, " min/max(u) = %.6e [%d] / %.6e [%d]\n",min,lmin,max,lmax); VecMax( p, &lmax, &max ); VecMin( p, &lmin, &min ); PetscPrintf( PETSC_COMM_WORLD, " min/max(p) = %.6e [%d] / %.6e [%d]\n",min,lmin,max,lmax); VecSum( p, &p_sum ); PetscPrintf( PETSC_COMM_WORLD, " \\sum_i p_i = %.6e \n", p_sum ); solutionAnalysisTime = MPI_Wtime() - solutionAnalysisTime; PetscPrintf( PETSC_COMM_WORLD, "\n Time for this analysis = %.4g secs\n\n",solutionAnalysisTime); Stg_VecDestroy(&t2 ); Stg_VecDestroy(&q ); } if(bsscrp_self->mg) { //MG_inner_solver_pcmg_shutdown( pcInner ); } Stg_VecDestroy(&t ); // KSPLogDestroyMonitor( ksp_S ); Stg_KSPDestroy(&ksp_S ); //Stg_KSPDestroy(&ksp_inner ); Stg_VecDestroy(&h_hat ); Stg_MatDestroy(&S ); /* Destroy nullspace vector if it exists. */ if(nsp_vec) Stg_VecDestroy(&nsp_vec); //been_here = 1; been_here++; PetscFunctionReturn(0); }
void PetscVector::min( double& min, int& index ) { int ierr = VecMin( pv, &index, &min ); assert( ierr == 0 ); }
PetscErrorCode test_view( void ) { Vec X, a,b; Vec c,d,e,f; Vec tmp_buf[2]; IS tmp_is[2]; PetscInt index; PetscReal val; PetscInt list[]={0,1,2}; PetscScalar vals[]={0.720032,0.061794,0.0100223}; PetscErrorCode ierr; PetscBool explcit = PETSC_FALSE; PetscFunctionBegin; PetscPrintf( PETSC_COMM_WORLD, "\n\n============== %s ==============\n", PETSC_FUNCTION_NAME ); ierr = VecCreate( PETSC_COMM_WORLD, &c );CHKERRQ(ierr); ierr = VecSetSizes( c, PETSC_DECIDE, 3 );CHKERRQ(ierr); ierr = VecSetFromOptions( c );CHKERRQ(ierr); ierr = VecDuplicate( c, &d );CHKERRQ(ierr); ierr = VecDuplicate( c, &e );CHKERRQ(ierr); ierr = VecDuplicate( c, &f );CHKERRQ(ierr); ierr = VecSet( c, 1.0 );CHKERRQ(ierr); ierr = VecSet( d, 2.0 );CHKERRQ(ierr); ierr = VecSet( e, 3.0 );CHKERRQ(ierr); ierr = VecSetValues(f,3,list,vals,INSERT_VALUES);CHKERRQ(ierr); ierr = VecAssemblyBegin(f);CHKERRQ(ierr); ierr = VecAssemblyEnd(f);CHKERRQ(ierr); ierr = VecScale( f, 10.0 );CHKERRQ(ierr); tmp_buf[0] = e; tmp_buf[1] = f; ierr = PetscOptionsGetBool(0,"-explicit_is",&explcit,0);CHKERRQ(ierr); ierr = GetISs(tmp_buf,tmp_is);CHKERRQ(ierr); ierr = VecCreateNest(PETSC_COMM_WORLD,2,explcit?tmp_is:PETSC_NULL,tmp_buf,&b);CHKERRQ(ierr); ierr = VecDestroy(&e);CHKERRQ(ierr); ierr = VecDestroy(&f);CHKERRQ(ierr); ierr = ISDestroy(&tmp_is[0]);CHKERRQ(ierr); ierr = ISDestroy(&tmp_is[1]);CHKERRQ(ierr); tmp_buf[0] = c; tmp_buf[1] = d; ierr = VecCreateNest(PETSC_COMM_WORLD,2,PETSC_NULL,tmp_buf,&a);CHKERRQ(ierr); ierr = VecDestroy(&c);CHKERRQ(ierr); ierr = VecDestroy(&d);CHKERRQ(ierr); tmp_buf[0] = a; tmp_buf[1] = b; ierr = VecCreateNest(PETSC_COMM_WORLD,2,PETSC_NULL,tmp_buf,&X);CHKERRQ(ierr); ierr = VecDestroy(&a);CHKERRQ(ierr); ierr = VecAssemblyBegin(X);CHKERRQ(ierr); ierr = VecAssemblyEnd(X);CHKERRQ(ierr); ierr = VecMax( b, &index, &val );CHKERRQ(ierr); PetscPrintf( PETSC_COMM_WORLD, "(max-b) = %f : index = %d \n", val, index ); ierr = VecMin( b, &index, &val );CHKERRQ(ierr); PetscPrintf( PETSC_COMM_WORLD, "(min-b) = %f : index = %d \n", val, index ); ierr = VecDestroy(&b);CHKERRQ(ierr); ierr = VecMax( X, &index, &val );CHKERRQ(ierr); PetscPrintf( PETSC_COMM_WORLD, "(max-X) = %f : index = %d \n", val, index ); ierr = VecMin( X, &index, &val );CHKERRQ(ierr); PetscPrintf( PETSC_COMM_WORLD, "(min-X) = %f : index = %d \n", val, index ); ierr = VecView( X, PETSC_VIEWER_STDOUT_WORLD );CHKERRQ(ierr); ierr = VecDestroy(&X);CHKERRQ(ierr); PetscFunctionReturn(0); }
void _Stokes_SLE_PenaltySolver_Solve( void* solver,void* stokesSLE ) { Stokes_SLE_PenaltySolver* self = (Stokes_SLE_PenaltySolver*)solver; Stokes_SLE* sle = (Stokes_SLE*)stokesSLE; /* Create shortcuts to stuff needed on sle */ Mat kMatrix = sle->kStiffMat->matrix; Mat gradMat = sle->gStiffMat->matrix; Mat divMat = NULL; Mat C_Mat = sle->cStiffMat->matrix; Vec uVec = sle->uSolnVec->vector; Vec pVec = sle->pSolnVec->vector; Vec fVec = sle->fForceVec->vector; Vec hVec = sle->hForceVec->vector; Vec hTempVec; Vec fTempVec; Vec penalty; Mat GTrans, kHat; KSP ksp_v; double negOne=-1.0; double one=1.0; Mat C_InvMat; Vec diagC; PC pc; int rank; MPI_Comm_rank( MPI_COMM_WORLD, &rank ); Journal_DPrintf( self->debug, "In %s():\n", __func__ ); VecDuplicate( hVec, &hTempVec ); VecDuplicate( fVec, &fTempVec ); VecDuplicate( pVec, &diagC ); if( sle->dStiffMat == NULL ) { Journal_DPrintf( self->debug, "Div matrix == NULL : Problem is assumed to be symmetric. ie Div = GTrans \n"); #if( PETSC_VERSION_MAJOR <= 2 ) MatTranspose( gradMat, >rans ); #else MatTranspose( gradMat, MAT_INITIAL_MATRIX, >rans ); #endif divMat = GTrans; } else { MatType type; PetscInt size[2]; MatGetType( sle->dStiffMat->matrix, &type ); MatGetLocalSize( sle->dStiffMat->matrix, size + 0, size + 1 ); /* make a copy we can play with */ MatCreate( sle->comm, >rans ); MatSetSizes( GTrans, size[0], size[1], PETSC_DECIDE, PETSC_DECIDE ); MatSetType( GTrans, type ); #if (((PETSC_VERSION_MAJOR==3) && (PETSC_VERSION_MINOR>=3)) || (PETSC_VERSION_MAJOR>3) ) MatSetUp(GTrans); #endif MatCopy( sle->dStiffMat->matrix, GTrans, DIFFERENT_NONZERO_PATTERN ); divMat = GTrans; } Stokes_SLE_PenaltySolver_MakePenalty( self, sle, &penalty ); /* Create CInv */ MatGetDiagonal( C_Mat, diagC ); VecReciprocal( diagC ); VecPointwiseMult( diagC, penalty, diagC ); { /* Print the maximum and minimum penalties in my system. */ PetscInt idx; PetscReal min, max; VecMin( diagC, &idx, &min ); VecMax( diagC, &idx, &max ); if( rank == 0 ) { printf( "PENALTY RANGE:\n" ); printf( " MIN: %e\n", min ); printf( " MAX: %e\n", max ); } } MatDiagonalSet( C_Mat, diagC, INSERT_VALUES ); C_InvMat = C_Mat; /* Use pointer CInv since C has been inverted */ /* Build RHS : rhs = f - GCInv h */ MatMult( C_InvMat, hVec, hTempVec ); /* hTempVec = C_InvMat * hVec */ VecScale( hTempVec, -1.0 ); MatMult( gradMat, hTempVec, fTempVec ); #if 0 VecPointwiseMult( fTempVec, penalty, fTempVec ); { /* Print the maximum and minimum penalties in my system. */ PetscInt idx; PetscReal min, max; VecMin( fTempVec, &idx, &min ); VecMax( fTempVec, &idx, &max ); printf( "PENALTY RANGE:\n" ); printf( " MIN: %e\n", min ); printf( " MAX: %e\n", max ); } #endif VecAXPY( fTempVec, 1.0, fVec ); /*MatMultAdd( gradMat, hTempVec, fVec, fTempVec );*/ /* Build G CInv GTrans */ /* MatTranspose( gradMat, >rans ); */ /* since CInv is diagonal we can just scale mat entries by the diag vector */ MatDiagonalScale( divMat, diagC, PETSC_NULL ); /* Div = CInve Div */ MatMatMult( gradMat, divMat, MAT_INITIAL_MATRIX, PETSC_DEFAULT, &kHat ); /*MatDiagonalScale( kHat, penalty, PETSC_NULL );*/ MatScale( kHat, -1.0 ); MatAXPY( kMatrix, 1.0, kHat, SAME_NONZERO_PATTERN ); /* Setup solver context and make sure that it uses a direct solver */ KSPCreate( sle->comm, &ksp_v ); Stg_KSPSetOperators( ksp_v, kMatrix, kMatrix, DIFFERENT_NONZERO_PATTERN ); KSPSetType( ksp_v, KSPPREONLY ); KSPGetPC( ksp_v, &pc ); PCSetType( pc, PCLU ); KSPSetFromOptions( ksp_v ); KSPSolve( ksp_v, fTempVec, uVec ); /* Recover p */ if( sle->dStiffMat == NULL ) { /* since Div was modified when C is diagonal, re build the transpose */ if( GTrans != PETSC_NULL ) Stg_MatDestroy(>rans ); #if( PETSC_VERSION_MAJOR <= 2 ) MatTranspose( gradMat, >rans ); #else MatTranspose( gradMat, MAT_INITIAL_MATRIX, >rans ); #endif divMat = GTrans; } else { /* never modified Div_null so set divMat to point back to it */ divMat = sle->dStiffMat->matrix; } MatMult( divMat, uVec, hTempVec ); /* hTemp = Div v */ VecAYPX( hTempVec, negOne, hVec ); /* hTemp = H - hTemp : hTemp = H - Div v */ MatMult( C_InvMat, hTempVec, pVec ); /* p = CInv hTemp : p = CInv ( H - Div v ) */ Stg_MatDestroy(&kHat ); if( fTempVec != PETSC_NULL ) Stg_VecDestroy(&fTempVec ); if( hTempVec != PETSC_NULL ) Stg_VecDestroy(&hTempVec ); if( diagC != PETSC_NULL ) Stg_VecDestroy(&diagC ); if( ksp_v != PETSC_NULL ) Stg_KSPDestroy(&ksp_v ); if( GTrans != PETSC_NULL ) Stg_MatDestroy(>rans ); }
void bsscr_summary(KSP_BSSCR * bsscrp_self, KSP ksp_S, KSP ksp_inner, Mat K,Mat K2,Mat D,Mat G,Mat C,Vec u,Vec p,Vec f,Vec h,Vec t, double penaltyNumber,PetscTruth KisJustK,double mgSetupTime,double scrSolveTime,double a11SingleSolveTime){ PetscTruth flg, found; PetscInt uSize, pSize, lmax, lmin, iterations; PetscReal rNorm, fNorm, uNorm, uNormInf, pNorm, pNormInf, p_sum, min, max; Vec q, qq, t2, t3; double solutionAnalysisTime; PetscPrintf( PETSC_COMM_WORLD, "\n\nSCR Solver Summary:\n\n"); if(bsscrp_self->mg) PetscPrintf( PETSC_COMM_WORLD, " Multigrid setup: = %.4g secs \n", mgSetupTime); KSPGetIterationNumber( ksp_S, &iterations); bsscrp_self->solver->stats.pressure_its = iterations; PetscPrintf( PETSC_COMM_WORLD, " Pressure Solve: = %.4g secs / %d its\n", scrSolveTime, iterations); KSPGetIterationNumber( ksp_inner, &iterations); bsscrp_self->solver->stats.velocity_backsolve_its = iterations; PetscPrintf( PETSC_COMM_WORLD, " Final V Solve: = %.4g secs / %d its\n\n", a11SingleSolveTime, iterations); /***************************************************************************************************************/ flg = PETSC_FALSE; /* Off by default */ PetscOptionsGetTruth( PETSC_NULL, "-scr_ksp_solution_summary", &flg, &found ); if(flg) { PetscScalar KuNorm; solutionAnalysisTime = MPI_Wtime(); VecGetSize( u, &uSize ); VecGetSize( p, &pSize ); VecDuplicate( u, &t2 ); VecDuplicate( u, &t3 ); MatMult( K, u, t3); VecNorm( t3, NORM_2, &KuNorm ); double angle, kdot; if(penaltyNumber > 1e-10){/* should change this to ifK2built maybe */ MatMult( K2, u, t2); VecNorm( t2, NORM_2, &rNorm ); VecDot(t2,t3,&kdot); angle = (kdot/(rNorm*KuNorm)); PetscPrintf( PETSC_COMM_WORLD, " <K u, K2 u>/(|K u| |K2 u|) = %.6e\n", angle); } VecNorm( t, NORM_2, &rNorm ); /* t = f- G p should be the formal residual vector, calculated on line 267 in auglag-driver-DGTGD.c */ VecDot(t3,t,&kdot); angle = (kdot/(rNorm*KuNorm)); PetscPrintf( PETSC_COMM_WORLD, " <K u, (f-G p)>/(|K u| |f- G p|) = %.6e\n\n", angle); MatMult( K, u, t2); VecNorm(t2, NORM_2, &KuNorm); VecAYPX( t2, -1.0, t ); /* t2 <- -t2 + t : t = f- G p should be the formal residual vector, calculated on line 267 in auglag-driver-DGTGD.c*/ VecNorm( t2, NORM_2, &rNorm ); VecNorm( f, NORM_2, &fNorm ); if(KisJustK){ PetscPrintf( PETSC_COMM_WORLD,"Velocity back-solve with original K matrix\n"); PetscPrintf( PETSC_COMM_WORLD,"Solved K u = G p -f\n"); PetscPrintf( PETSC_COMM_WORLD,"Residual with original K matrix\n"); PetscPrintf( PETSC_COMM_WORLD, " |f - K u - G p| = %.12e\n", rNorm); PetscPrintf( PETSC_COMM_WORLD, " |f - K u - G p|/|f| = %.12e\n", rNorm/fNorm); if(penaltyNumber > 1e-10){/* means the restore_K flag was used */ //if(K2 && f2){ MatAXPY(K,penaltyNumber,K2,DIFFERENT_NONZERO_PATTERN);/* Computes K = penaltyNumber*K2 + K */ //VecAXPY(f,penaltyNumber,f2); /* f = penaltyNumber*f2 + f */ KisJustK=PETSC_FALSE; MatMult( K, u, t2); MatMult( G, p, t); VecAYPX( t, -1.0, f ); /* t <- -t + f */ VecAYPX( t2, -1.0, t ); /* t2 <- -t2 + t */ VecNorm( t2, NORM_2, &rNorm ); PetscPrintf( PETSC_COMM_WORLD,"Residual with K+K2 matrix and f rhs vector\n"); PetscPrintf( PETSC_COMM_WORLD, " |(f) - (K + K2) u - G p| = %.12e\n", rNorm); //} } } else{ PetscPrintf( PETSC_COMM_WORLD,"Velocity back-solve with K+K2 matrix\n"); PetscPrintf( PETSC_COMM_WORLD,"Solved (K + K2) u = G p - (f)\n"); PetscPrintf( PETSC_COMM_WORLD,"Residual with K+K2 matrix and f rhs vector\n"); PetscPrintf( PETSC_COMM_WORLD, " |(f) - (K + K2) u - G p| = %.12e\n", rNorm); PetscReal KK2Norm,KK2Normf; MatNorm(K,NORM_1,&KK2Norm); MatNorm(K,NORM_FROBENIUS,&KK2Normf); penaltyNumber = -penaltyNumber; MatAXPY(K,penaltyNumber,K2,DIFFERENT_NONZERO_PATTERN);/* Computes K = penaltyNumber*K2 + K */ //VecAXPY(f,penaltyNumber,f2); /* f = penaltyNumber*f2 + f */ KisJustK=PETSC_FALSE; MatMult( K, u, t2); /* t2 = K*u */ MatMult( G, p, t); /* t = G*p */ VecAYPX( t, -1.0, f ); /* t <- f - t ; t = f - G*p */ VecAYPX( t2, -1.0, t ); /* t2 <- t - t2; t2 = f - G*p - K*u */ VecNorm( t2, NORM_2, &rNorm ); PetscPrintf( PETSC_COMM_WORLD,"Residual with original K matrix\n"); PetscPrintf( PETSC_COMM_WORLD, " |f - K u - G p| = %.12e\n", rNorm); PetscPrintf( PETSC_COMM_WORLD, " |f - K u - G p|/|f| = %.12e\n", rNorm/fNorm); PetscReal KNorm, K2Norm; MatNorm(K,NORM_1,&KNorm); MatNorm(K2,NORM_1,&K2Norm); PetscPrintf( PETSC_COMM_WORLD,"K and K2 norm_1 %.12e %.12e ratio %.12e\n",KNorm,K2Norm,K2Norm/KNorm); MatNorm(K,NORM_INFINITY,&KNorm); MatNorm(K2,NORM_INFINITY,&K2Norm); PetscPrintf( PETSC_COMM_WORLD,"K and K2 norm_inf %.12e %.12e ratio %.12e\n",KNorm,K2Norm,K2Norm/KNorm); MatNorm(K,NORM_FROBENIUS,&KNorm); MatNorm(K2,NORM_FROBENIUS,&K2Norm); PetscPrintf( PETSC_COMM_WORLD,"K and K2 norm_frob %.12e %.12e ratio %.12e\n",KNorm,K2Norm,K2Norm/KNorm); PetscPrintf( PETSC_COMM_WORLD,"K+r*K2 norm_1 %.12e\n",KK2Norm); PetscPrintf( PETSC_COMM_WORLD,"K+r*K2 norm_frob %.12e\n",KK2Normf); penaltyNumber = -penaltyNumber; MatAXPY(K,penaltyNumber,K2,DIFFERENT_NONZERO_PATTERN);/* Computes K = penaltyNumber*K2 + K */ } PetscPrintf( PETSC_COMM_WORLD,"\n"); PetscPrintf( PETSC_COMM_WORLD, " |K u| = %.12e\n", KuNorm); if(penaltyNumber > 1e-10){ MatMult( K2, u, t2); VecNorm( t2, NORM_2, &rNorm ); PetscPrintf( PETSC_COMM_WORLD, " |K2 u| = %.12e\n", rNorm); PetscPrintf( PETSC_COMM_WORLD,"\n"); } VecDuplicate( p, &q ); MatMult( D, u, q ); /* q = G'*u = D*u */ VecNorm( u, NORM_2, &uNorm ); VecNorm( q, NORM_2, &rNorm ); PetscPrintf( PETSC_COMM_WORLD, " |G^T u|_2 = %.6e\n", rNorm ); PetscPrintf( PETSC_COMM_WORLD, " |G^T u|_2/|u|_2 = %.6e\n", sqrt( (double) uSize / (double) pSize ) * rNorm / uNorm); VecDuplicate( p, &qq ); MatMultTranspose( G, u, qq ); VecNorm( qq, NORM_2, &rNorm ); PetscPrintf( PETSC_COMM_WORLD, " |G^T u|/|u| = %.8e\n", rNorm/uNorm ); /* to compare directly with Uzawa */ VecNorm( q, NORM_INFINITY, &rNorm ); PetscPrintf( PETSC_COMM_WORLD, " |G^T u|_infty/|u|_2 = %.6e\n", sqrt( (double) uSize ) * rNorm / uNorm); /* create G'*u+C*p-h to check on this constraint */ /* already have q = D*u */ VecZeroEntries(qq); if(C){ MatMult( C, p, qq ); } VecAYPX( q, 1.0, qq ); /* q = q+qq; G'*u + C*p*/ VecAXPY( q, -1.0, h ); /* q = q-h; G'*u + C*p - h */ VecNorm( q, NORM_2, &rNorm ); PetscPrintf( PETSC_COMM_WORLD, " |G^T u + C p - h| = %.8e :constraint\n", rNorm ); VecNorm( u, NORM_INFINITY, &uNormInf ); VecNorm( u, NORM_2, &uNorm ); VecGetSize( u, &uSize ); VecNorm( p, NORM_INFINITY, &pNormInf ); VecNorm( p, NORM_2, &pNorm ); PetscPrintf( PETSC_COMM_WORLD, " |u|_{\\infty} = %.6e , u_rms = %.6e\n", uNormInf, uNorm / sqrt( (double) uSize ) ); PetscPrintf( PETSC_COMM_WORLD, " |p|_{\\infty} = %.6e , p_rms = %.6e\n", pNormInf, pNorm / sqrt( (double) pSize ) ); VecMax( u, &lmax, &max ); VecMin( u, &lmin, &min ); PetscPrintf( PETSC_COMM_WORLD, " min/max(u) = %.6e [%d] / %.6e [%d]\n",min,lmin,max,lmax); bsscrp_self->solver->stats.vmin = min; bsscrp_self->solver->stats.vmax = max; VecMax( p, &lmax, &max ); VecMin( p, &lmin, &min ); PetscPrintf( PETSC_COMM_WORLD, " min/max(p) = %.6e [%d] / %.6e [%d]\n",min,lmin,max,lmax); bsscrp_self->solver->stats.pmin = min; bsscrp_self->solver->stats.pmax = max; VecSum( p, &p_sum ); PetscPrintf( PETSC_COMM_WORLD, " \\sum_i p_i = %.6e \n", p_sum ); bsscrp_self->solver->stats.p_sum=p_sum; solutionAnalysisTime = MPI_Wtime() - solutionAnalysisTime; PetscPrintf( PETSC_COMM_WORLD, "\n Time for this analysis = %.4g secs\n\n",solutionAnalysisTime); Stg_VecDestroy(&t2 ); Stg_VecDestroy(&t3 ); Stg_VecDestroy(&q ); Stg_VecDestroy(&qq ); } }
int Brusselator(int argc,char **argv,PetscInt cycle) { TS ts; /* nonlinear solver */ Vec X; /* solution, residual vectors */ Mat J; /* Jacobian matrix */ PetscInt steps,maxsteps,mx; PetscErrorCode ierr; DM da; PetscReal ftime,hx,dt,xmax,xmin; struct _User user; /* user-defined work context */ TSConvergedReason reason; PetscInitialize(&argc,&argv,(char*)0,help); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Create distributed array (DMDA) to manage parallel grid and vectors - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = DMDACreate1d(PETSC_COMM_WORLD,DM_BOUNDARY_NONE,-11,2,2,NULL,&da);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Extract global vectors from DMDA; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = DMCreateGlobalVector(da,&X);CHKERRQ(ierr); /* Initialize user application context */ ierr = PetscOptionsBegin(PETSC_COMM_WORLD,NULL,"Advection-reaction options",""); { user.A = 1; user.B = 3; user.alpha = 0.1; user.uleft = 1; user.uright = 1; user.vleft = 3; user.vright = 3; ierr = PetscOptionsReal("-A","Reaction rate","",user.A,&user.A,NULL);CHKERRQ(ierr); ierr = PetscOptionsReal("-B","Reaction rate","",user.B,&user.B,NULL);CHKERRQ(ierr); ierr = PetscOptionsReal("-alpha","Diffusion coefficient","",user.alpha,&user.alpha,NULL);CHKERRQ(ierr); ierr = PetscOptionsReal("-uleft","Dirichlet boundary condition","",user.uleft,&user.uleft,NULL);CHKERRQ(ierr); ierr = PetscOptionsReal("-uright","Dirichlet boundary condition","",user.uright,&user.uright,NULL);CHKERRQ(ierr); ierr = PetscOptionsReal("-vleft","Dirichlet boundary condition","",user.vleft,&user.vleft,NULL);CHKERRQ(ierr); ierr = PetscOptionsReal("-vright","Dirichlet boundary condition","",user.vright,&user.vright,NULL);CHKERRQ(ierr); } ierr = PetscOptionsEnd();CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Create timestepping solver context - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = TSCreate(PETSC_COMM_WORLD,&ts);CHKERRQ(ierr); ierr = TSSetDM(ts,da);CHKERRQ(ierr); ierr = TSSetType(ts,TSARKIMEX);CHKERRQ(ierr); ierr = TSSetRHSFunction(ts,NULL,FormRHSFunction,&user);CHKERRQ(ierr); ierr = TSSetIFunction(ts,NULL,FormIFunction,&user);CHKERRQ(ierr); ierr = DMSetMatType(da,MATAIJ);CHKERRQ(ierr); ierr = DMCreateMatrix(da,&J);CHKERRQ(ierr); ierr = TSSetIJacobian(ts,J,J,FormIJacobian,&user);CHKERRQ(ierr); ftime = 1.0; maxsteps = 10000; ierr = TSSetDuration(ts,maxsteps,ftime);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Set initial conditions - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = FormInitialSolution(ts,X,&user);CHKERRQ(ierr); ierr = TSSetSolution(ts,X);CHKERRQ(ierr); ierr = VecGetSize(X,&mx);CHKERRQ(ierr); hx = 1.0/(PetscReal)(mx/2-1); dt = 0.4 * PetscSqr(hx) / user.alpha; /* Diffusive stability limit */ dt *= PetscPowRealInt(0.2,cycle); /* Shrink the time step in convergence study. */ ierr = TSSetInitialTimeStep(ts,0.0,dt);CHKERRQ(ierr); ierr = TSSetTolerances(ts,1e-3*PetscPowRealInt(0.5,cycle),NULL,1e-3*PetscPowRealInt(0.5,cycle),NULL);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Set runtime options - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = TSSetFromOptions(ts);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Solve nonlinear system - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = TSSolve(ts,X);CHKERRQ(ierr); ierr = TSGetSolveTime(ts,&ftime);CHKERRQ(ierr); ierr = TSGetTimeStepNumber(ts,&steps);CHKERRQ(ierr); ierr = TSGetConvergedReason(ts,&reason);CHKERRQ(ierr); ierr = VecMin(X,NULL,&xmin);CHKERRQ(ierr); ierr = VecMax(X,NULL,&xmax);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"%s at time %g after % 3D steps. Range [%6.4f,%6.4f]\n",TSConvergedReasons[reason],(double)ftime,steps,(double)xmin,(double)xmax);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Free work space. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = MatDestroy(&J);CHKERRQ(ierr); ierr = VecDestroy(&X);CHKERRQ(ierr); ierr = TSDestroy(&ts);CHKERRQ(ierr); ierr = DMDestroy(&da);CHKERRQ(ierr); ierr = PetscFinalize(); return 0; }
int main(int argc,char *argv[]) { //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% //VARIABLE DEFINITION //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% float cp,S,sigma,gamma,pp,Topt; float q,Ab,Aw,Agf,grad_T,fi,mm,nn,Pmax,EVPmax; float Ec,Es,deltat,t_integracion,t_modelacion; float Lini,Lfin,deltaL; int niter,niterL,nzc; Vector zc_vector; int zczc,ii; float Ac,L,zc; float aclouds,awhite,ablack,Ts,d; float t,xx,As; float k1,k2,k3,k4; int j; float Tc,Tlb,Tlw,Tanual,I,a,EVP,E; float P; float k1c,k2c,k3c,k4c; float k1w,k2w,k3w,k4w; float k1b,k2b,k3b,k4b; float Bw,Bb; int it; Vector time,temperature,white_temperature, black_temperature,white_area,black_area,clouds_area,evap,prec; Matrix resultados; FILE *fl; char fname[1000]; float k1p1,k1p2,k1p3,k1p4,k1p5; //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% //PARAMETERS //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% cp = 3.e13; //erg*cm-2*K-1 S = 2.89e13; //erg*cm-2*año-1 sigma = 1789.; //erg*cm-2*año-1*K-4 gamma = 0.3; //año-1 pp = 1.; //adimensional Topt = 295.5; //K q = 20.; //K Ab = 0.25; //adimensinal Aw = 0.75; //adimensinal Agf = 0.50; //adimensinal grad_T = (-0.0065); //K*m-1, Trenberth 95, p.10 fi = 0.1; mm = 0.35; nn = 0.1; Pmax = pow((1./mm),(1/nn)); //=36251 [mm/año], cuando ac=1.0 EVPmax = Pmax; //EVPmax = 1511.; //[mm/año] corresponde a Ts=26 grados centÃgrados //Pmax = EVPmax; //[mm/año] //ac_crit = mm*Pmax^nn; //&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& //experimento otro: cambiando estos parámetros Ec=1.; //emisividad de las nubes Es=1.; //emisividad de la superficie //&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& deltat = 0.01; //[años] tamaño de paso temporal para dTsdt y dadt t_integracion = 1; //[año] cada cuanto se guardan valores de las variables t_modelacion = 10000; //[años] perÃodo de modelación por cada L niter = t_integracion/deltat; //# de iteraciones en los RK4 /* Lini = 1.992; Lfin = 4.004; deltaL = 0.004; */ Lini = 1.000; Lfin = 1.000; deltaL = 0.004; niterL = (Lfin-Lini)/deltaL; ////zc_vector = [1000.,2000.,3000.,4000.,5000.,6000.,7000.,8000.] zc_vector=VecAlloc(1); VecSet(zc_vector,0,6000.); nzc=1; //&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& //LOOP IN HEIGHTS //&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& FILE *ft=fopen("hdw-legacy.dat","w"); for(zczc=0;zczc<=nzc-1;zczc++){ zc=VecGet(zc_vector,zczc); //Ac=1.-fi*(zc/1000.); Ac=0.6; resultados=MatAlloc(niterL+1,19); //&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& //LOOP IN SOLAR FORCING //&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& for(ii=0;ii<=niterL;ii++){ L = deltaL*ii+Lini; printf("%d de %d, L = %.4lf\n",ii,niterL,L); //valores iniciales aclouds = 0.01 ;//adimensional, 0 para reproducir modelo original, 0.01 para iniciar con area de nubes awhite = 0.01 ;//adimensional ablack = 0.01 ;//adimensional Ts=295.5 ;//temperatura en la superficie, valor inicial para rk4 d = t_modelacion ;//numero de años en el eje de las abscisas - iteraciones de t - dimension de los vectores de resultados //printf("Tam:%d\n",(int)(d+1)/2); time=VecAlloc((d+1)/2); temperature=VecAlloc((d+1)/2); white_temperature=VecAlloc((d+1)/2); black_temperature=VecAlloc((d+1)/2); white_area=VecAlloc((d+1)/2); black_area=VecAlloc((d+1)/2); clouds_area=VecAlloc((d+1)/2); evap=VecAlloc((d+1)/2); prec=VecAlloc((d+1)/2); it=0; //&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& //LOOP IN MODELLING TIME //&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& for(t=0;t<=t_modelacion;t+=t_integracion){ //if(it>5000){ if(it>-1){ fprintf(ft,"%e %e %e %e %e\n", t,Ts,aclouds,awhite,ablack); } xx = pp - awhite - ablack; As = xx*Agf + ablack*Ab + awhite*Aw; //&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& //TIME INTEGRATION //&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& for(j=1;j<=niter;j++){ //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% //TEMPERATURE //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% k1=(1/cp)*(S*L*((1-Ac)*aclouds+(1-aclouds))*(1-As)+sigma*Ec*aclouds*gsl_pow_int((Ts+grad_T*zc),4)-sigma*Es*gsl_pow_int(Ts,4)); k2=(1/cp)*(S*L*((1-Ac)*aclouds+(1-aclouds))*(1-As)+sigma*Ec*aclouds*gsl_pow_int(((Ts+k1/2)+grad_T*zc),4)-sigma*Es*gsl_pow_int((Ts+k1/2),4)); k3=(1/cp)*(S*L*((1-Ac)*aclouds+(1-aclouds))*(1-As)+sigma*Ec*aclouds*gsl_pow_int(((Ts+k2/2)+grad_T*zc),4)-sigma*Es*gsl_pow_int((Ts+k2/2),4)); k4=(1/cp)*(S*L*((1-Ac)*aclouds+(1-aclouds))*(1-As)+sigma*Ec*aclouds*gsl_pow_int(((Ts+k3)+grad_T*zc),4)-sigma*Es*gsl_pow_int((Ts+k3),4)); Ts = Ts+deltat*(k1/6+k2/3+k3/3+k4/6); //CLOUD TEMPERATURE Tc=Ts+zc*grad_T; Tlb=q*(As-Ab)+Ts; Tlw=q*(As-Aw)+Ts; //EVAPORATION if(Ts>277){ Tanual = Ts - 273. ;//(°C) I = 12.*pow((Tanual/5.),1.5); a = (6.7e-7)*gsl_pow_int(I,3) - (7.7e-5)*PowInt(I,2) + (1.8e-2)*I + 0.49; EVP = 12.*16*pow((10.*(Ts - 273.)/I),a); E = Min(1.,EVP/EVPmax); }else{ E = 0.; } //PRECIPITATION P = (1./Pmax)*pow((aclouds/mm),(1./nn)); //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% //CLOUD COVERING //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% k1c=(1-aclouds)*E-aclouds*P; k2c=(1-(aclouds+k1c/2))*E-(aclouds+k1c/2)*P; k3c=(1-(aclouds+k2c/2))*E-(aclouds+k2c/2)*P; k4c=(1-(aclouds+k3c))*E-(aclouds+k3c)*P; aclouds=aclouds+deltat*(k1c/6+k2c/3+k3c/3+k4c/6); //REPRODUCTIVE FITNESS //WHITE DAISIES if((Tlw>278)&&(Tlw<313)) Bw=1-0.003265*PowInt((Topt-Tlw),2); else Bw=0; //BLACK DAISIES if((Tlb>278)&&(Tlb<313)) Bb=1-0.003265*PowInt((Topt-Tlb),2); else Bb=0; //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% //WHITE AREA //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% k1w=awhite*(xx*Bw-gamma); k2w=(awhite+k1w/2)*(xx*Bw-gamma); k3w=(awhite+k2w/2)*(xx*Bw-gamma); k4w=(awhite+k3w)*(xx*Bw-gamma); awhite=awhite+deltat*(k1w/6+k2w/3+k3w/3+k4w/6); //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% //BLACK AREA //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% k1b=ablack*(xx*Bb-gamma); k2b=(ablack+k1b/2)*(xx*Bb-gamma); k3b=(ablack+k2b/2)*(xx*Bb-gamma); k4b=(ablack+k3b)*(xx*Bb-gamma); ablack=ablack+deltat*(k1b/6+k2b/3+k3b/3+k4b/6); xx = pp - awhite - ablack; As = xx*Agf + ablack*Ab + awhite*Aw; }//end for time integration if(it>5000){ VecSet(time,it-5001,t); VecSet(temperature,it-5001,Ts-273); VecSet(white_temperature,it-5001,Tlw-273); VecSet(black_temperature,it-5001,Tlb-273); VecSet(white_area,it-5001,awhite); VecSet(black_area,it-5001,ablack); VecSet(clouds_area,it-5001,aclouds); VecSet(evap,it-5001,E*(1-aclouds)); VecSet(prec,it-5001,P*aclouds); } it++; }//end for modelling time t if(VERBOSE){ fprintf(stdout,"Valor %s = %.6e\n",VARS[0],L); fprintf(stdout,"Valor %s = %.6e\n",VARS[1],VecMin(temperature)) ;//Ts fprintf(stdout,"Valor %s = %.6e\n",VARS[2],VecMean(temperature)) ;//Ts fprintf(stdout,"Valor %s = %.6e\n",VARS[3],VecMax(temperature)) ;//Ts fprintf(stdout,"Valor %s = %.6e\n",VARS[4],VecMin(white_area)) ;//aw fprintf(stdout,"Valor %s = %.6e\n",VARS[5],VecMean(white_area)) ;//aw fprintf(stdout,"Valor %s = %.6e\n",VARS[6],VecMax(white_area)) ;//aw fprintf(stdout,"Valor %s = %.6e\n",VARS[7],VecMin(black_area)) ;//ab fprintf(stdout,"Valor %s = %.6e\n",VARS[8],VecMean(black_area)) ;//ab fprintf(stdout,"Valor %s = %.6e\n",VARS[9],VecMax(black_area)) ;//ab fprintf(stdout,"Valor %s = %.6e\n",VARS[10],VecMin(clouds_area)) ;//ac fprintf(stdout,"Valor %s = %.6e\n",VARS[11],VecMean(clouds_area)) ;//ac fprintf(stdout,"Valor %s = %.6e\n",VARS[12],VecMax(clouds_area)) ;//ac fprintf(stdout,"Valor %s = %.6e\n",VARS[13],VecMin(evap)) ;//E fprintf(stdout,"Valor %s = %.6e\n",VARS[14],VecMean(evap)) ;//E fprintf(stdout,"Valor %s = %.6e\n",VARS[15],VecMax(evap)) ;//E fprintf(stdout,"Valor %s = %.6e\n",VARS[16],VecMin(prec)) ;//P fprintf(stdout,"Valor %s = %.6e\n",VARS[17],VecMean(prec)) ;//P fprintf(stdout,"Valor %s = %.6e\n",VARS[18],VecMax(prec)) ;//P } //&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& //RESULTADOS //&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& MatSet(resultados,ii,0,L); MatSet(resultados,ii,1,VecMin(temperature)) ;//Ts MatSet(resultados,ii,2,VecMean(temperature)) ;//Ts MatSet(resultados,ii,3,VecMax(temperature)) ;//Ts MatSet(resultados,ii,4,VecMin(white_area)) ;//aw MatSet(resultados,ii,5,VecMean(white_area)) ;//aw MatSet(resultados,ii,6,VecMax(white_area)) ;//aw MatSet(resultados,ii,7,VecMin(black_area)) ;//ab MatSet(resultados,ii,8,VecMean(black_area)) ;//ab MatSet(resultados,ii,9,VecMax(black_area)) ;//ab MatSet(resultados,ii,10,VecMin(clouds_area)) ;//ac MatSet(resultados,ii,11,VecMean(clouds_area)) ;//ac MatSet(resultados,ii,12,VecMax(clouds_area)) ;//ac MatSet(resultados,ii,13,VecMin(evap)) ;//E MatSet(resultados,ii,14,VecMean(evap)) ;//E MatSet(resultados,ii,15,VecMax(evap)) ;//E MatSet(resultados,ii,16,VecMin(prec)) ;//P MatSet(resultados,ii,17,VecMean(prec)) ;//P MatSet(resultados,ii,18,VecMax(prec)) ;//P VecFree(time); VecFree(temperature); VecFree(white_temperature); VecFree(black_temperature); VecFree(white_area); VecFree(black_area); VecFree(clouds_area); VecFree(evap); VecFree(prec); }//end for ii sprintf(fname,"DAWHYC2_EXP2_L0416_%.2f_%d_activa.txt",Ac,(int)zc/1000); fl=fopen(fname,"w"); fprintf(fl,"zc= %.0lf\n",zc); fprintf(fl,"Ac= %.2lf\n",Ac); for(j=0;j<NVARS;j++) fprintf(fl,"%10s ",VARS[j]); MatrixFprintf(fl,resultados,"%10.4f "); fclose(fl); MatFree(resultados); }//end for heights fclose(ft); }//end program
PetscErrorCode port_lsd_bfbt(void) { Mat A; Vec x,b; KSP ksp_A; PC pc_A; IS isu,isp; PetscErrorCode ierr; PetscFunctionBeginUser; ierr = LoadTestMatrices(&A,&x,&b,&isu,&isp);CHKERRQ(ierr); ierr = KSPCreate(PETSC_COMM_WORLD,&ksp_A);CHKERRQ(ierr); ierr = KSPSetOptionsPrefix(ksp_A,"fc_");CHKERRQ(ierr); ierr = KSPSetOperators(ksp_A,A,A);CHKERRQ(ierr); ierr = KSPGetPC(ksp_A,&pc_A);CHKERRQ(ierr); ierr = PCSetType(pc_A,PCFIELDSPLIT);CHKERRQ(ierr); ierr = PCFieldSplitSetBlockSize(pc_A,2);CHKERRQ(ierr); ierr = PCFieldSplitSetIS(pc_A,"velocity",isu);CHKERRQ(ierr); ierr = PCFieldSplitSetIS(pc_A,"pressure",isp);CHKERRQ(ierr); ierr = KSPSetFromOptions(ksp_A);CHKERRQ(ierr); ierr = KSPSolve(ksp_A,b,x);CHKERRQ(ierr); /* Pull u,p out of x */ { PetscInt loc; PetscReal max,norm; PetscScalar sum; Vec uvec,pvec; VecScatter uscat,pscat; Mat A11,A22; /* grab matrices and create the compatable u,p vectors */ ierr = MatGetSubMatrix(A,isu,isu,MAT_INITIAL_MATRIX,&A11);CHKERRQ(ierr); ierr = MatGetSubMatrix(A,isp,isp,MAT_INITIAL_MATRIX,&A22);CHKERRQ(ierr); ierr = MatCreateVecs(A11,&uvec,NULL);CHKERRQ(ierr); ierr = MatCreateVecs(A22,&pvec,NULL);CHKERRQ(ierr); /* perform the scatter from x -> (u,p) */ ierr = VecScatterCreate(x,isu,uvec,NULL,&uscat);CHKERRQ(ierr); ierr = VecScatterBegin(uscat,x,uvec,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); ierr = VecScatterEnd(uscat,x,uvec,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); ierr = VecScatterCreate(x,isp,pvec,NULL,&pscat);CHKERRQ(ierr); ierr = VecScatterBegin(pscat,x,pvec,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); ierr = VecScatterEnd(pscat,x,pvec,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); PetscPrintf(PETSC_COMM_WORLD,"-- vector vector values --\n"); ierr = VecMin(uvec,&loc,&max);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD," Min(u) = %1.6f [loc=%D]\n",(double)max,loc);CHKERRQ(ierr); ierr = VecMax(uvec,&loc,&max);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD," Max(u) = %1.6f [loc=%D]\n",(double)max,loc);CHKERRQ(ierr); ierr = VecNorm(uvec,NORM_2,&norm);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD," Norm(u) = %1.6f \n",(double)norm);CHKERRQ(ierr); ierr = VecSum(uvec,&sum);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD," Sum(u) = %1.6f \n",(double)PetscRealPart(sum));CHKERRQ(ierr); PetscPrintf(PETSC_COMM_WORLD,"-- pressure vector values --\n"); ierr = VecMin(pvec,&loc,&max);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD," Min(p) = %1.6f [loc=%D]\n",(double)max,loc);CHKERRQ(ierr); ierr = VecMax(pvec,&loc,&max);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD," Max(p) = %1.6f [loc=%D]\n",(double)max,loc);CHKERRQ(ierr); ierr = VecNorm(pvec,NORM_2,&norm);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD," Norm(p) = %1.6f \n",(double)norm);CHKERRQ(ierr); ierr = VecSum(pvec,&sum);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD," Sum(p) = %1.6f \n",(double)PetscRealPart(sum));CHKERRQ(ierr); PetscPrintf(PETSC_COMM_WORLD,"-- Full vector values --\n"); ierr = VecMin(x,&loc,&max);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD," Min(u,p) = %1.6f [loc=%D]\n",(double)max,loc);CHKERRQ(ierr); ierr = VecMax(x,&loc,&max);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD," Max(u,p) = %1.6f [loc=%D]\n",(double)max,loc);CHKERRQ(ierr); ierr = VecNorm(x,NORM_2,&norm);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD," Norm(u,p) = %1.6f \n",(double)norm);CHKERRQ(ierr); ierr = VecSum(x,&sum);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD," Sum(u,p) = %1.6f \n",(double)PetscRealPart(sum));CHKERRQ(ierr); ierr = VecScatterDestroy(&uscat);CHKERRQ(ierr); ierr = VecScatterDestroy(&pscat);CHKERRQ(ierr); ierr = VecDestroy(&uvec);CHKERRQ(ierr); ierr = VecDestroy(&pvec);CHKERRQ(ierr); ierr = MatDestroy(&A11);CHKERRQ(ierr); ierr = MatDestroy(&A22);CHKERRQ(ierr); } ierr = KSPDestroy(&ksp_A);CHKERRQ(ierr); ierr = MatDestroy(&A);CHKERRQ(ierr); ierr = VecDestroy(&x);CHKERRQ(ierr); ierr = VecDestroy(&b);CHKERRQ(ierr); ierr = ISDestroy(&isu);CHKERRQ(ierr); ierr = ISDestroy(&isp);CHKERRQ(ierr); PetscFunctionReturn(0); }
void AABB::Extend(const vec3& v) { m_min = VecMin(m_min, v); m_max = VecMax(m_max, v); }
void Stokes_SLE_PenaltySolver_MakePenalty( Stokes_SLE_PenaltySolver* self, Stokes_SLE* sle, Vec* _penalty ) { Vec fVec = sle->fForceVec->vector, hVec = sle->hForceVec->vector, penalty, lambda; Mat kMat = sle->kStiffMat->matrix; FeMesh *mesh = sle->kStiffMat->rowVariable->feMesh; FeVariable *velField = sle->kStiffMat->rowVariable; SolutionVector* uVec = sle->uSolnVec; FeEquationNumber *eqNum = uVec->eqNum; IArray *inc; PetscScalar *lambdaVals, lambdaMin, *penaltyVals; int numDofs, numLocalElems, nodeCur, numLocalNodes, rank, eq; SolutionVector *solVec = sle->uSolnVec; double *velBackup; Vec vecBackup; int ii, jj, kk; MPI_Comm_rank( MPI_COMM_WORLD, &rank ); numDofs = Mesh_GetDimSize( mesh ); numLocalElems = FeMesh_GetElementLocalSize( mesh ); numLocalNodes = FeMesh_GetNodeLocalSize( mesh ); velBackup = (double*)malloc( numLocalNodes*numDofs*sizeof(double) ); for( ii = 0; ii < numLocalNodes; ii++ ) FeVariable_GetValueAtNode( velField, ii, velBackup + ii*numDofs ); VecDuplicate( hVec, &penalty ); VecGetArray( penalty, &penaltyVals ); VecDuplicate( fVec, &lambda ); MatGetDiagonal( kMat, lambda ); { PetscInt idx; PetscReal min, max; VecMin( lambda, &idx, &min ); VecMax( lambda, &idx, &max ); if( rank == 0 ) { printf( "LAMBDA RANGE:\n" ); printf( " MIN: %e\n", min ); printf( " MAX: %e\n", max ); } } vecBackup = solVec->vector; solVec->vector = lambda; SolutionVector_UpdateSolutionOntoNodes( solVec ); inc = IArray_New(); lambdaVals = (double*)malloc( numDofs*sizeof(double) ); for( ii = 0; ii < numLocalElems; ii++ ) { lambdaMin = DBL_MAX; FeMesh_GetElementNodes( mesh, ii, inc ); for( jj = 0; jj < inc->size; jj++ ) { nodeCur = inc->ptr[jj]; FeVariable_GetValueAtNode( velField, nodeCur, lambdaVals ); for( kk = 0; kk < numDofs; kk++ ) { eq = eqNum->mapNodeDof2Eq[nodeCur][kk]; if( eq == -1 ) continue; /* eq = *(int*)STreeMap_Map( eqNum->ownedMap, &eq ); VecGetValues( lambda, 1, &eq, &lambdaVal ); */ if( lambdaVals[kk] < 0.0 ) printf( "%g\n", lambdaVals[kk] ); if( lambdaVals[kk] < lambdaMin ) lambdaMin = lambdaVals[kk]; } } penaltyVals[ii] = lambdaMin; } if( lambdaVals ) free( lambdaVals ); Stg_Class_Delete( inc ); solVec->vector = vecBackup; for( ii = 0; ii < numLocalNodes; ii++ ) FeVariable_SetValueAtNode( velField, ii, velBackup + ii*numDofs ); if( velBackup ) free( velBackup ); FeVariable_SyncShadowValues( velField ); Stg_VecDestroy(&lambda ); VecRestoreArray( penalty, &penaltyVals ); VecAssemblyBegin( penalty ); VecAssemblyEnd( penalty ); { PetscInt idx; PetscReal min, max; VecMin( penalty, &idx, &min ); VecMax( penalty, &idx, &max ); if( rank == 0 ) { printf( "SEMI-PENALTY RANGE:\n" ); printf( " MIN: %e\n", min ); printf( " MAX: %e\n", max ); } } *_penalty = penalty; }
PetscScalar SingleLongPipe::computeMaxRadius() { PetscScalar maxRadius; VecMin(radii.getVec(), nullptr, &maxRadius); return maxRadius; }
int main(int argc, char ** argv ) { PetscInitialize(&argc,&argv,"options","DENDRO example\n"); ot::RegisterEvents(); ot::DAMG_Initialize(MPI_COMM_WORLD); int size, rank; MPI_Comm_size(MPI_COMM_WORLD,&size); MPI_Comm_rank(MPI_COMM_WORLD,&rank); if (argc<2) { std::cout<<"Usage: mpirun -np <numProcs> "<<argv[0]<<" <filePrefix>"<<std::endl; return(-1); } std::ostringstream fName; fName<<argv[1]<<rank<<"_"<<size<<".pts"; std::vector<double> pts; ot::readPtsFromFile(const_cast<char*>(fName.str().c_str()), pts); Vec sol; ot::DAMG * damg; // This function pointer will be called while setting up the solver on the coarsest grid if not all processes are active on the coarse grid ot::getPrivateMatricesForKSP_Shell = getPrivateMatricesForKSP_Shell_Jac2; solve_neumann( /* input parameters: */ pts, CalcVarCoef, CalcVarRHS, 30, /* upper bound */ /* output parameters */ sol, damg ); // compare solution with the exact one unsigned numMultigridLevels = damg[0]->totalLevels; ot::DA* da=damg[numMultigridLevels-1]->da; PetscScalar *solArray; da->vecGetBuffer(sol,solArray,false,false,true,1); double maxDiff = 0; unsigned maxDepth=da->getMaxDepth()-1; if(da->iAmActive()) { // first loop over those octants which do not contain ghost nodes. for(da->init<ot::DA_FLAGS::INDEPENDENT>(); da->curr() < da->end<ot::DA_FLAGS::INDEPENDENT>(); da->next<ot::DA_FLAGS::INDEPENDENT>()) { Point pt = da->getCurrentOffset(); unsigned levelhere = da->getLevel(da->curr()) - 1; double hxOct = ldexp(1.0,-levelhere); double x = ldexp(pt.x(),-maxDepth ); double y = ldexp(pt.y(),-maxDepth ); double z = ldexp(pt.z(),-maxDepth ); unsigned int indices[8]; da->getNodeIndices(indices); double coord[8][3] = { {0.0,0.0,0.0}, {1.0,0.0,0.0}, {0.0,1.0,0.0}, {1.0,1.0,0.0}, {0.0,0.0,1.0}, {1.0,0.0,1.0}, {0.0,1.0,1.0}, {1.0,1.0,1.0} }; unsigned char hn = da->getHangingNodeIndex(da->curr()); for(int i = 0; i < 8; i++) if (!(hn & (1 << i))) { double xhere, yhere, zhere; xhere = x + coord[i][0]*hxOct; yhere = y + coord[i][1]*hxOct; zhere = z + coord[i][2]*hxOct; double currDiff = fabs ( solArray[indices[i]] - cos(w*M_PI*xhere)*cos(w*M_PI*yhere)*cos(w*M_PI*zhere) ); if (maxDiff < currDiff) maxDiff=currDiff; } } // now loop over those octants which DO contain ghost nodes; now we need to check if the node is ghost, and skip it if it is size_t myFirstNode = da->getIdxElementBegin(); size_t postFirstNode = da->getIdxPostGhostBegin(); for(da->init<ot::DA_FLAGS::DEPENDENT>(); da->curr() < da->end<ot::DA_FLAGS::DEPENDENT>(); da->next<ot::DA_FLAGS::DEPENDENT>()) { Point pt = da->getCurrentOffset(); unsigned levelhere = da->getLevel(da->curr()) - 1; double hxOct = ldexp(1.0,-levelhere); double x = ldexp(pt.x(),-maxDepth ); double y = ldexp(pt.y(),-maxDepth ); double z = ldexp(pt.z(),-maxDepth ); unsigned int indices[8]; da->getNodeIndices(indices); double coord[8][3] = { {0.0,0.0,0.0}, {1.0,0.0,0.0}, {0.0,1.0,0.0}, {1.0,1.0,0.0}, {0.0,0.0,1.0}, {1.0,0.0,1.0}, {0.0,1.0,1.0}, {1.0,1.0,1.0} }; unsigned char hn = da->getHangingNodeIndex(da->curr()); for(int i = 0; i < 8; i++) if ( indices[i]>=myFirstNode && indices[i]<postFirstNode && !(hn & (1 << i)) ) { double xhere, yhere, zhere; xhere = x + coord[i][0]*hxOct; yhere = y + coord[i][1]*hxOct; zhere = z + coord[i][2]*hxOct; double currDiff = fabs ( solArray[indices[i]] - cos(w*M_PI*xhere)*cos(w*M_PI*yhere)*cos(w*M_PI*zhere) ); if (maxDiff < currDiff) maxDiff=currDiff; } } } da->vecRestoreBuffer(sol,solArray,false,false,true,1); double gMaxDiff; par::Mpi_Reduce<double>(&maxDiff, &gMaxDiff, 1, MPI_MAX, 0, MPI_COMM_WORLD); if (!rank) { std::cout<<"Maximum difference: "<<gMaxDiff<<std::endl; } double solmax,solmin; VecMax(sol,NULL,&solmax); VecMin(sol,NULL,&solmin); if (!rank) std::cout<<"solution min: " << solmin << "; solution max: " << solmax << std::endl; // destroy multigrid context; this destroys the solution as well DAMGDestroy(damg); ot::DAMG_Finalize(); PetscFinalize(); return 0; }
PetscErrorCode bsscr_buildK2(KSP ksp){ KSP_BSSCR *bsscr = (KSP_BSSCR *)ksp->data; Mat K,G,M, K2=0; Vec f2=0; PetscReal minD,maxD; //MatStokesBlockScaling BA=bsscr->BA; Stokes_SLE* stokesSLE = (Stokes_SLE*)bsscr->solver->st_sle; StokesBlockKSPInterface* Solver = bsscr->solver; //PetscErrorCode ierr; PetscFunctionBegin; K = stokesSLE->kStiffMat->matrix; G = stokesSLE->gStiffMat->matrix; if(bsscr->K2){ Stg_MatDestroy(&bsscr->K2); bsscr->K2 = PETSC_NULL; } switch (bsscr->k2type) { case (K2_DGMGD): {/* Should only do this one if scaling is turned off. */ Vec D=0; Vec MD = 0; Mat GKG = 0; Mat KG = 0; Mat Mscale = 0; //AugLagStokes_SLE * stokesSLE = (AugLagStokes_SLE*)bsscr->st_sle; if (Solver->mStiffMat){ MatMatMult(K, G, MAT_INITIAL_MATRIX, PETSC_DEFAULT , &KG); MatTransposeMatMult(G, KG, MAT_INITIAL_MATRIX, PETSC_DEFAULT ,&GKG); MatGetVecs( GKG, PETSC_NULL, &MD ); MatGetDiagonal( GKG, MD ); M = Solver->mStiffMat->matrix; MatDuplicate(M, MAT_COPY_VALUES, &Mscale ); MatDiagonalScale(Mscale, NULL, MD ); VecMin(MD, PETSC_NULL, &minD); VecMax(MD, PETSC_NULL, &maxD); VecScale(MD, 1.0/maxD); VecMin(MD, PETSC_NULL, &minD); VecMax(MD, PETSC_NULL, &maxD); bsscr_GMiGt(&K2,K,G,Mscale); /* K2 created */ Stg_VecDestroy(&D); Stg_VecDestroy(&MD); Stg_MatDestroy(&GKG); Stg_MatDestroy(&KG); PetscPrintf( PETSC_COMM_WORLD, "\n\n----- K2_DGMGD ------"); PetscPrintf( PETSC_COMM_WORLD, " min %f, max %f \n\n", minD, maxD); } else{ PetscPrintf( PETSC_COMM_WORLD,"The Augmented Lagrangian Method DGMGD was specified but the SLE has no mStiffMat on it.\n"); PetscPrintf( PETSC_COMM_WORLD,"You need to use the AugLagStokes_SLE class.\n"); } } break; case (K2_GMG): { //AugLagStokes_SLE * stokesSLE = (AugLagStokes_SLE*)bsscr->st_sle; if (Solver->mStiffMat){ M = Solver->mStiffMat->matrix; bsscr_GMiGt(&K2,K,G,M); /* K2 created */ PetscPrintf( PETSC_COMM_WORLD, "\n\n----- K2_GMG ------\n\n"); }else{ PetscPrintf( PETSC_COMM_WORLD,"The Augmented Lagrangian Method GMG was specified but the SLE has no mStiffMat on it.\n"); PetscPrintf( PETSC_COMM_WORLD,"You need to use the AugLagStokes_SLE class.\n"); } } break; case (K2_GG): { bsscr_GGt(&K2,K,G); /* K2 created */ PetscPrintf( PETSC_COMM_WORLD, "\n\n----- K2_GG ------\n\n"); } break; case (K2_SLE): { //AugLagStokes_SLE * stokesSLE = (AugLagStokes_SLE*)bsscr->st_sle; if (Solver->mStiffMat){ K2 = Solver->mStiffMat->matrix; if(Solver->jForceVec){ f2 = Solver->jForceVec->vector; } PetscPrintf( PETSC_COMM_WORLD, "\n\n----- K2_SLE ------\n\n"); }else{ PetscPrintf( PETSC_COMM_WORLD,"The Augmented Lagrangian Method SLE was specified but the Solver has no Matrix on it.\n"); PetscPrintf( PETSC_COMM_WORLD,"You need to set the K2 matrix on the StokesBlockKSPInterface class.\n"); } } break; default: PetscPrintf( PETSC_COMM_WORLD, "\n\n----- NO K2 ------\n\n"); } bsscr->f2 = f2; bsscr->K2 = K2; PetscFunctionReturn(0); }
void _Stokes_SLE_UzawaSolver_Solve( void* solver, void* stokesSLE ) { Stokes_SLE_UzawaSolver* self = (Stokes_SLE_UzawaSolver*)solver; Stokes_SLE* sle = (Stokes_SLE*)stokesSLE; /* Create shortcuts to stuff needed on sle */ Mat K_Mat = sle->kStiffMat->matrix; Mat G_Mat = sle->gStiffMat->matrix; Mat D_Mat = NULL; Mat M_Mat = NULL; Vec uVec = sle->uSolnVec->vector; Vec qVec = sle->pSolnVec->vector; Vec fVec = sle->fForceVec->vector; Vec hVec = sle->hForceVec->vector; /* Create shortcuts to solver related stuff */ Vec qTempVec = self->pTempVec; Vec rVec = self->rVec; Vec sVec = self->sVec; Vec fTempVec = self->fTempVec; Vec vStarVec = self->vStarVec; KSP velSolver = self->velSolver; /* Inner velocity solver */ KSP pcSolver = self->pcSolver; /* Preconditioner */ Iteration_Index maxIterations = self->maxUzawaIterations; Iteration_Index minIterations = self->minUzawaIterations; Iteration_Index iteration_I = 0; Iteration_Index outputInterval = 1; double zdotr_current = 0.0; double zdotr_previous = 1.0; double sdotGTrans_v; double alpha, beta; double absResidual; double relResidual; double* chosenResidual; /* We can opt to use either the absolute or relative residual in termination condition */ double uzawaRhsScale; double divU; double weightedResidual; double weightedVelocityScale; double momentumEquationResidual; Iteration_Index innerLoopIterations; Stream* errorStream = Journal_Register( Error_Type, (Name)Stokes_SLE_UzawaSolver_Type ); PetscInt fVecSize, qTempVecSize, uVecSize, qVecSize; PetscScalar fVecNorm, qTempVecNorm, uVecNorm, rVecNorm, fTempVecNorm, uVecNormInf, qVecNorm, qVecNormInf; double qGlobalProblemScale; double qReciprocalGlobalProblemScale; int init_info_stream_rank; PetscScalar p_sum; /* Bool nullsp_present; */ Bool uzawa_summary; double time,t0,rnorm0; PetscTruth flg; double ksptime; VecGetSize( qTempVec, &qTempVecSize ); qGlobalProblemScale = sqrt( (double) qTempVecSize ); qReciprocalGlobalProblemScale = 1.0 / qGlobalProblemScale; init_info_stream_rank = Stream_GetPrintingRank( self->info ); Stream_SetPrintingRank( self->info, 0 ); /* DEFINITIONS: See accompanying documentation u - the displacement / velocity solution (to which constraints are applied) q - the pressure-like variable which constrains the divergence displacement / velocity (= pressure for incompressible) F - standard FE force vector Fhat - Uzawa RHS = K^{-1} G F - h K - standard FE stiffness matrix Khat - Uzawa transformed stiffness matrix = G^T K^{-1} G G matrix - discrete gradient operator D matrix - discrete divergence operator = G^T for this particular algorithm C matrix - Mass matrix (M) for compressibility LM & DAM */ /* CHOICE OF RESIDUAL: we may opt to converge on the absolute value (self->useAbsoluteTolerance == True ... default) or the relative value of the residual (self->useAbsoluteTolerance == False) (another possibility would be always to improve the residual by a given tolerance) The Moresi & Solomatov (Phys Fluids, 1995) approach is to use the relative tolerance */ VecNorm( fVec, NORM_2, &fVecNorm ); VecGetSize( fVec, &fVecSize ); if ( fVecNorm / sqrt( (double)fVecSize ) <= 1e-99 ) { Journal_Printf( errorStream, "Error in func %s: The momentum force vector \"%s\" is zero. " "The force vector should be non-zero either because of your chosen boundary " "conditions, or because of the element force vector assembly. You have %d " "element force vectors attached.\n", __func__, sle->fForceVec->name, sle->fForceVec->assembleForceVector->hooks->count ); if ( sle->fForceVec->assembleForceVector->hooks->count > 0 ) { Journal_Printf( errorStream, "You used the following force vector assembly terms:\n" ); EntryPoint_PrintConcise( sle->fForceVec->assembleForceVector, errorStream ); /* TODO : need to print the elementForceVector assembly, not the global guy!! */ } Journal_Printf( errorStream, "Please check values for building the force vector.\n" ); Journal_Firewall( 0, errorStream, "Exiting.\n" ); } Journal_DPrintf( self->debug, "In %s:\n", __func__ ); Journal_RPrintfL( self->debug, 2, "Conjugate Gradient Uzawa solver with:\n"); Stream_IndentBranch( StgFEM_Debug ); Journal_RPrintfL( self->debug, 2, "Compressibility %s\n", (sle->cStiffMat)? "on" : "off"); Journal_RPrintfL( self->debug, 2, "Preconditioning %s\n", (pcSolver)? "on" : "off" ); if ( sle->cStiffMat ) { Journal_DPrintfL( self->debug, 2, "(compressibility active)\n" ); M_Mat = sle->cStiffMat->matrix; } else { Journal_DPrintfL( self->debug, 2, "(compressibility inactive)\n" ); } if ( sle->dStiffMat ) { Journal_DPrintfL( self->debug, 2, "(asymmetric geometry: handling D Matrix [incorrectly - will be ignored])\n" ); D_Mat = sle->dStiffMat->matrix; } else { Journal_DPrintfL( self->debug, 2, "(No D -> symmetric geometry: D = Gt)\n" ); } #if DEBUG if ( Stream_IsPrintableLevel( self->debug, 3 ) ) { Journal_DPrintf( self->debug, "Matrices and Vectors to solve are:\n" ); Journal_DPrintf( self->debug, "K Matrix:\n" ); /* No nice way of viewing Matrices, so commented out as incompatible with * new 3D decomp at present --Kathleen Humble 30-04-07 * Matrix_View( sle->kStiffMat->matrix, self->debug ); */ Journal_DPrintf( self->debug, "G Matrix:\n" ); if ( D_Mat ) { Journal_DPrintf( self->debug, "D Matrix:\n" ); } if ( M_Mat ) { Journal_DPrintf( self->debug, "M Matrix:\n" ); } Journal_DPrintf( self->debug, "Z (preconditioner) Matrix:\n" ); Journal_DPrintf( self->debug, "f Vector:\n" ); _SLE_VectorView( fVec, self->debug ); Journal_DPrintf( self->debug, "h Vector:\n" ); _SLE_VectorView( hVec, self->debug ); } #endif /* STEP 1: Estimate the magnitude of the RHS for the transformed problem we compute (usually to lower accuracy than elsewhere) the RHS (Fhat - h) and store the result in qTempVec. LM & DAM */ Journal_DPrintfL( self->debug, 2, "Building Fhat - h.\n" ); PetscOptionsHasName(PETSC_NULL,"-uzawa_printksptimes",&flg); KSPSetTolerances( velSolver, self->tolerance, PETSC_DEFAULT, PETSC_DEFAULT, PETSC_DEFAULT ); if (flg) { ksptime = MPI_Wtime(); } KSPSolve( velSolver, fVec, vStarVec ); if (flg) { ksptime = MPI_Wtime() - ksptime; PetscPrintf( PETSC_COMM_WORLD, "KSP on velSolver took %lf seconds in Building Fhat step\n", ksptime); } KSPGetIterationNumber( velSolver, &innerLoopIterations ); Journal_DPrintfL( self->debug, 2, "Fhat inner solution: Number of iterations: %d\n", innerLoopIterations ); if ( D_Mat ) { MatMult( D_Mat, vStarVec, qTempVec ); } else { MatMultTranspose( G_Mat, vStarVec, qTempVec ); } VecAXPY( qTempVec, -1.0, hVec ); /* WARNING: If D != G^T then the resulting \hat{K} is not likely to be symmetric, positive definite as required by this implementation of the Uzawa iteration. This next piece of code is VERY unlikely to work properly so it's in the sin bin for the time being - LM. if ( D_Mat ) { MatrixMultiply( D_Mat, vStarVec, qTempVec ); } else { MatrixTransposeMultiply( G_Mat, vStarVec, qTempVec ); } LM & DAM */ /* STEP 2: The problem scaling - optionally normalize the uzawa residual by the magnitude of the RHS (use a relative tolerance) For the inner velocity solver, Citcom uses a relative tolerance equal to that used for the Uzawa iteration as a whole LM & DAM */ if (self->useAbsoluteTolerance) { chosenResidual = &absResidual; Journal_PrintfL( self->info, 2, "Absolute residual < %g for Uzawa stopping condition\n", self->tolerance); /* We should calculate the effective relative tolerance and insert that here !! */ KSPSetTolerances( velSolver, 0.1 * self->tolerance, PETSC_DEFAULT, PETSC_DEFAULT, PETSC_DEFAULT ); } else { /* The CITCOM compatible choice */ chosenResidual = &relResidual; Journal_PrintfL( self->info, 2, "Relative residual < %g for Uzawa stopping condition\n", self->tolerance); KSPSetTolerances( velSolver, 0.1 * self->tolerance, PETSC_DEFAULT, PETSC_DEFAULT, PETSC_DEFAULT ); } Journal_DPrintfL( self->debug, 2, "Determining scaling factor for residual:\n" ); VecNorm( qTempVec, NORM_2, &qTempVecNorm ); uzawaRhsScale = ((double)qTempVecNorm) * qReciprocalGlobalProblemScale; Journal_DPrintfL( self->debug, 2, "uzawaRhsScale = %f\n", uzawaRhsScale ); Journal_Firewall( isGoodNumber( uzawaRhsScale ), errorStream, "Error in func '%s' for %s '%s' - uzawaRhsScale has illegal value '%g'.\n", __func__, self->type, self->name, uzawaRhsScale ); /* STEP 3: Calculate initial residual for transformed equation (\hat{F} - h - \hat{K} q_0) Compute the solution to K u_0 = F - G q_0 (u_0 unknown) Then G^T u* = \hat{F} - \hat{K} q_0 u_0 is also the initial velocity solution to which the constraint is applied by the subsequent iteration LM & DAM */ Journal_DPrintfL( self->debug, 2, "Solving for transformed Uzawa RHS.\n" ); VecCopy( fVec, fTempVec ); VecScale( fTempVec, -1.0 ); MatMultAdd( G_Mat, qVec, fTempVec, fTempVec ); VecScale( fTempVec, -1.0 ); KSPSolve( velSolver, fTempVec, uVec ); /* Handling for NON-SYMMETRIC: relegated to sin bin (see comment above) LM & DAM */ if ( D_Mat ) { MatMult( D_Mat, uVec, rVec ); } else { MatMultTranspose( G_Mat, uVec, rVec ); } VecNorm( rVec, NORM_2, &rnorm0 ); VecNorm( uVec, NORM_2, &uVecNorm ); divU = rnorm0 / uVecNorm; Journal_PrintfL( self->info, 2, "Initial l2Norm( Div u ) / l2Norm( u ) = %f \n", divU); Journal_Firewall( isGoodNumber( divU ), errorStream, "Error in func '%s' for %s '%s' - l2Norm( Div u ) has illegal value '%g'.\n", __func__, self->type, self->name, divU ); Journal_DPrintfL( self->debug, 2, "Adding compressibility and prescribed divergence terms.\n" ); if ( M_Mat ) { MatMultAdd( M_Mat, qVec, rVec, rVec ); } VecAXPY( rVec, -1.0, hVec ); /* Check for existence of constant null space */ #if 0 nullsp_present = _check_if_constant_nullsp_present( self, K_Mat,G_Mat,M_Mat, fTempVec,vStarVec,qTempVec,sVec, velSolver ); #endif /* STEP 4: Preconditioned conjugate gradient iteration loop */ Journal_DPrintfL( self->debug, 1, "Beginning main Uzawa conjugate gradient loop:\n" ); iteration_I = 0; /* outer_it, residual, time */ uzawa_summary = self->monitor; time = 0.0; t0 = MPI_Wtime(); // Journal_PrintfL( self->info, 1, " |r0| = %.8e \n", rnorm0 ); do{ /* reset initial time and end time for inner its back to 0 - probs don't need to do this but just in case */ self->outeritsinitialtime = 0; self->outeritsendtime = 0; //BEGINNING OF OUTER ITERATIONS!!!!! /*get wall time for start of outer loop*/ self->outeritsinitialtime = MPI_Wtime(); Journal_DPrintfL( self->debug, 2, "Beginning solve '%u'.\n", iteration_I ); Stream_IndentBranch( StgFEM_Debug ); /* STEP 4.1: Preconditioner Solve: Q_\hat{K} z_1 = r_1 Q_\hat{K} is an approximation to \hat{K} which is simple / trivial / quick to invert LM & DAM */ if ( pcSolver ) { PetscOptionsHasName(PETSC_NULL,"-uzawa_printksptimes",&flg); if (flg) { ksptime = MPI_Wtime(); } KSPSolve( pcSolver, rVec, qTempVec ); if (flg) { ksptime = MPI_Wtime() - ksptime; PetscPrintf( PETSC_COMM_WORLD, "KSP on pcSolver took %lf seconds\n", ksptime); } } else { VecCopy( rVec, qTempVec ); } /* Remove the constant null space, but only if NOT compressible */ #if 0 if( nullsp_present == True ) { _remove_constant_nullsp( qTempVec ); } #endif /* STEP 4.2: Calculate s_I, the pressure search direction z_{I-1} . r_{I-1} \beta = (z_{I-1} . r_{I-1}) / (z_{I-2} . r_{I-2}) \beta = 0 for the first iteration s_I = z_(I-1) + \beta * s_(I-1) LM & DAM */ VecDot( qTempVec, rVec, &zdotr_current ); VecNorm( qTempVec, NORM_2, &qTempVecNorm ); VecNorm( rVec, NORM_2, &rVecNorm ); Journal_DPrintfL( self->debug, 2, "l2Norm (qTempVec) %g; (rVec) %g \n", qTempVecNorm * qReciprocalGlobalProblemScale, rVecNorm * qReciprocalGlobalProblemScale ); if ( iteration_I == 0 ) { VecCopy( qTempVec, sVec ); } else { beta = zdotr_current/zdotr_previous; VecAYPX( sVec, beta, qTempVec ); } /* STEP 4.3: Velocity search direction corresponding to s_I is found by solving K u* = G s_I LM & DAM */ MatMult( G_Mat, sVec, fTempVec ); Journal_DPrintfL( self->debug, 2, "Uzawa inner iteration step\n"); //START OF INNER ITERATIONS!!!! PetscOptionsHasName(PETSC_NULL,"-uzawa_printksptimes",&flg); /*get initial wall time for inner loop*/ self->inneritsinitialtime = MPI_Wtime(); if (flg) { ksptime = MPI_Wtime(); } KSPSolve( velSolver, fTempVec, vStarVec ); if (flg) { ksptime = MPI_Wtime() - ksptime; PetscPrintf( PETSC_COMM_WORLD, "KSP on velSolver took %lf seconds in Uzawa inner iteration step\n", ksptime); } /*get end wall time for inner loop*/ self->inneritsendtime = MPI_Wtime(); /* add time to total time inner its: */ self->totalinneritstime = self->totalinneritstime + (-self->inneritsinitialtime + self->inneritsendtime); /* reset initial time and end time for inner its back to 0 - probs don't need to do this but just in case */ self->inneritsinitialtime = 0; self->inneritsendtime = 0; KSPGetIterationNumber( velSolver, &innerLoopIterations ); /* add the inner loop iterations to the total inner iterations */ self->totalnuminnerits = self->totalnuminnerits + innerLoopIterations; Journal_DPrintfL( self->debug, 2, "Completed Uzawa inner iteration in '%u' iterations \n", innerLoopIterations ); /* STEP 4.4: Calculate the step size ( \alpha = z_{I-1} . r_{I-1} / (s_I . \hat{K} s_I) ) \hat{K} s_I = G^T u* - M s_I (u* from step 4.3) LM & DAM */ if ( D_Mat ) { MatMult( D_Mat, vStarVec, qTempVec ); } else { MatMultTranspose( G_Mat, vStarVec, qTempVec ); } /* Handling for NON-SYMMETRIC: relegated to sin bin (see comment above) if ( D_Mat ) { MatrixMultiply( D_Mat, vStarVec, qTempVec ); } else { MatrixTransposeMultiply( G_Mat, vStarVec, qTempVec ); } LM & DAM */ if ( M_Mat ) { Journal_DPrintfL( self->debug, 2, "Correcting for Compressibility\n" ); VecScale( qTempVec, -1.0 ); MatMultAdd( M_Mat, sVec, qTempVec, qTempVec ); VecScale( qTempVec, -1.0 ); } VecDot( sVec, qTempVec, &sdotGTrans_v ); alpha = zdotr_current/sdotGTrans_v; /* STEP 4.5: Update pressure, velocity and value of residual by \alpha times corresponding search direction LM & DAM */ Journal_DPrintfL( self->debug, 2, "zdotr_current = %g \n", zdotr_current); Journal_DPrintfL( self->debug, 2, "sdotGTrans_v = %g \n", sdotGTrans_v); Journal_DPrintfL( self->debug, 2, "alpha = %g \n", alpha); Journal_Firewall( isGoodNumber( zdotr_current ) && isGoodNumber( sdotGTrans_v ) && isGoodNumber( alpha ), errorStream, "Error in func '%s' for %s '%s' - zdotr_current, sdotGTrans_v or alpha has an illegal value: '%g','%g' or '%g'\n", __func__, self->type, self->name, zdotr_current, sdotGTrans_v, alpha ); VecAXPY( qVec, alpha, sVec ); VecAXPY( uVec, -alpha, vStarVec ); VecAXPY( rVec, -alpha, qTempVec ); /* STEP 4.6: store the value of z_{I-1} . r_{I-1} for the next iteration LM & DAM */ zdotr_previous = zdotr_current; VecNorm( rVec, NORM_2, &rVecNorm ); absResidual = rVecNorm * qReciprocalGlobalProblemScale; relResidual = absResidual / uzawaRhsScale; Stream_UnIndentBranch( StgFEM_Debug ); if( iteration_I % outputInterval == 0 ) { Journal_PrintfL( self->info, 2, "\tLoop = %u, absResidual = %.8e, relResidual = %.8e\n", iteration_I, absResidual, relResidual ); } Journal_Firewall( isGoodNumber( absResidual ), errorStream, "Error in func '%s' for %s '%s' - absResidual has an illegal value: '%g'\n", __func__, self->type, self->name, absResidual ); Journal_Firewall( iteration_I < maxIterations, errorStream, "In func %s: Reached maximum number of iterations %u without converging; absResidual = %.5g, relResidual = %.5g \n", __func__, iteration_I, absResidual, relResidual ); /* TODO: test for small change in 10 iterations and if so restart? */ time = MPI_Wtime()-t0; if (uzawa_summary) { Journal_PrintfL( self->info, 1, " %1.4d uzawa residual norm %12.13e, cpu time %5.5e\n", iteration_I+1,*chosenResidual,time ); } iteration_I++; //END OF OUTER ITERATION LOOP!!! /*get wall time for end of outer loop*/ self->outeritsendtime = MPI_Wtime(); /* add time to total time inner its: */ self->totalouteritstime = self->totalouteritstime + (-self->outeritsinitialtime + self->outeritsendtime); /* reset initial time and end time for inner its back to 0 - probs don't need to do this but just in case */ self->outeritsinitialtime = 0; self->outeritsendtime = 0; /* add the outer loop iterations to the total outer iterations */ self->totalnumouterits++; } while ( (*chosenResidual > self->tolerance) || (iteration_I<minIterations) ); // } while ( *chosenResidual > self->tolerance ); Journal_DPrintfL( self->debug, 1, "Pressure solution converged. Exiting uzawa \n "); /* STEP 5: Check all the relevant residuals and report back */ if (Stream_IsEnable( self->info ) ) { /* This information should be in an info stream */ Journal_PrintfL( self->info, 1, "Summary:\n"); Journal_PrintfL( self->info, 1, " Uzawa its. = %04d , Uzawa residual = %12.13e\n", iteration_I, relResidual ); MatMultTranspose( G_Mat, uVec, rVec ); VecNorm( rVec, NORM_2, &rVecNorm ); VecNorm( uVec, NORM_2, &uVecNorm ); divU = rVecNorm / uVecNorm; Journal_PrintfL( self->info, 1, " |G^T u|/|u| = %.8e\n", divU); /* Residual for the momentum equation Compute r = || F - Ku - Gp || / || F || */ MatMult( G_Mat, qVec, vStarVec ); MatMultAdd( K_Mat, uVec, vStarVec, fTempVec ); VecAYPX( fTempVec, -1.0, fVec ); VecNorm( fTempVec, NORM_2, &fTempVecNorm ); VecNorm( fVec, NORM_2, &fVecNorm ); momentumEquationResidual = fTempVecNorm / fVecNorm; Journal_PrintfL( self->info, 1, " |f - K u - G p|/|f| = %.8e\n", momentumEquationResidual ); Journal_Firewall( isGoodNumber( momentumEquationResidual ), errorStream, "Bad residual for the momentum equation (|| F - Ku - Gp || / || F || = %g):\n" "\tCheck to see if forcing term is zero or nan - \n\t|| F - Ku - Gp || = %g \n\t|| F || = %g.\n", momentumEquationResidual, fTempVecNorm, fVecNorm ); /* "Preconditioned" residual for the momentum equation r_{w} = || Q_{K}(r) || / || Q_{K}(F) fTempVec contains the residual but is overwritten once used vStarVec is used to hold the diagonal preconditioner Q_{K} */ MatGetDiagonal( K_Mat, vStarVec ); VecReciprocal( vStarVec ); VecPointwiseMult( vStarVec, fTempVec, fTempVec ); VecNorm( fTempVec, NORM_2, &weightedResidual ); VecPointwiseMult( vStarVec, fVec, fTempVec ); VecNorm( fTempVec, NORM_2, &weightedVelocityScale ); Journal_PrintfL( self->info, 1, " |f - K u - G p|_w/|f|_w = %.8e\n", weightedResidual / weightedVelocityScale ); /* Report back on the solution - velocity and pressure Note - correction for dof in Vrms ?? */ VecNorm( uVec, NORM_INFINITY, &uVecNormInf ); VecNorm( uVec, NORM_2, &uVecNorm ); VecGetSize( uVec, &uVecSize ); VecNorm( qVec, NORM_INFINITY, &qVecNormInf ); VecNorm( qVec, NORM_2, &qVecNorm ); VecGetSize( qVec, &qVecSize ); Journal_PrintfL( self->info, 1, " |u|_{\\infty} = %.8e , u_rms = %.8e\n", uVecNormInf, uVecNorm / sqrt( (double)uVecSize ) ); Journal_PrintfL( self->info, 1, " |p|_{\\infty} = %.8e , p_rms = %.8e\n", qVecNormInf, qVecNorm / sqrt( (double)qVecSize ) ); { PetscInt lmin,lmax; PetscReal min,max; VecMax( uVec, &lmax, &max ); VecMin( uVec, &lmin, &min ); Journal_PrintfL( self->info, 1, " min/max(u) = %.8e [%d] / %.8e [%d]\n",min,lmin,max,lmax); VecMax( qVec, &lmax, &max ); VecMin( qVec, &lmin, &min ); Journal_PrintfL( self->info, 1, " min/max(p) = %.8e [%d] / %.8e [%d]\n",min,lmin,max,lmax); } VecSum( qVec, &p_sum ); Journal_PrintfL( self->info, 1, " \\sum_i p_i = %.8e \n", p_sum ); } /* journal stream enabled */ #if DEBUG if ( Stream_IsPrintableLevel( self->debug, 3 ) ) { Journal_DPrintf( self->debug, "Velocity solution:\n" ); _SLE_VectorView( uVec, self->debug ); Journal_DPrintf( self->debug, "Pressure solution:\n" ); _SLE_VectorView( qVec, self->debug ); } #endif Stream_UnIndentBranch( StgFEM_Debug ); Stream_SetPrintingRank( self->info, init_info_stream_rank ); /* Now gather up data for printing out to FrequentOutput file: */ /*!!! if non-linear need to divide by number of nonlinear iterations and we do this in SystemLinearEquations */ if((sle->isNonLinear != True)){ self->avgnuminnerits = self->totalnuminnerits/self->totalnumouterits; self->avgnumouterits = self->totalnumouterits; self->avgtimeouterits = (self->totalouteritstime - self->totalinneritstime)/self->totalnumouterits; self->avgtimeinnerits = self->totalinneritstime/self->totalnuminnerits; } }
int main(int argc,char **argv) { Vec x,y,w; /* vectors */ Vec *z; /* array of vectors */ PetscReal norm,v,v1,v2,maxval; PetscInt n = 20,maxind; PetscErrorCode ierr; PetscScalar one = 1.0,two = 2.0,three = 3.0,dots[3],dot; ierr = PetscInitialize(&argc,&argv,(char*)0,help);if (ierr) return ierr; ierr = PetscOptionsGetInt(NULL,NULL,"-n",&n,NULL);CHKERRQ(ierr); /* Create a vector, specifying only its global dimension. When using VecCreate(), VecSetSizes() and VecSetFromOptions(), the vector format (currently parallel, shared, or sequential) is determined at runtime. Also, the parallel partitioning of the vector is determined by PETSc at runtime. Routines for creating particular vector types directly are: VecCreateSeq() - uniprocessor vector VecCreateMPI() - distributed vector, where the user can determine the parallel partitioning VecCreateShared() - parallel vector that uses shared memory (available only on the SGI); otherwise, is the same as VecCreateMPI() With VecCreate(), VecSetSizes() and VecSetFromOptions() the option -vec_type mpi or -vec_type shared causes the particular type of vector to be formed. */ ierr = VecCreate(PETSC_COMM_WORLD,&x);CHKERRQ(ierr); ierr = VecSetSizes(x,PETSC_DECIDE,n);CHKERRQ(ierr); ierr = VecSetFromOptions(x);CHKERRQ(ierr); /* Duplicate some work vectors (of the same format and partitioning as the initial vector). */ ierr = VecDuplicate(x,&y);CHKERRQ(ierr); ierr = VecDuplicate(x,&w);CHKERRQ(ierr); /* Duplicate more work vectors (of the same format and partitioning as the initial vector). Here we duplicate an array of vectors, which is often more convenient than duplicating individual ones. */ ierr = VecDuplicateVecs(x,3,&z);CHKERRQ(ierr); /* Set the vectors to entries to a constant value. */ ierr = VecSet(x,one);CHKERRQ(ierr); ierr = VecSet(y,two);CHKERRQ(ierr); ierr = VecSet(z[0],one);CHKERRQ(ierr); ierr = VecSet(z[1],two);CHKERRQ(ierr); ierr = VecSet(z[2],three);CHKERRQ(ierr); /* Demonstrate various basic vector routines. */ ierr = VecDot(x,y,&dot);CHKERRQ(ierr); ierr = VecMDot(x,3,z,dots);CHKERRQ(ierr); /* Note: If using a complex numbers version of PETSc, then PETSC_USE_COMPLEX is defined in the makefiles; otherwise, (when using real numbers) it is undefined. */ ierr = PetscPrintf(PETSC_COMM_WORLD,"Vector length %D\n",n);CHKERRQ(ierr); ierr = VecMax(x,&maxind,&maxval);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"VecMax %g, VecInd %D\n",(double)maxval,maxind);CHKERRQ(ierr); ierr = VecMin(x,&maxind,&maxval);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"VecMin %g, VecInd %D\n",(double)maxval,maxind);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"All other values should be near zero\n");CHKERRQ(ierr); ierr = VecScale(x,two);CHKERRQ(ierr); ierr = VecNorm(x,NORM_2,&norm);CHKERRQ(ierr); v = norm-2.0*PetscSqrtReal((PetscReal)n); if (v > -PETSC_SMALL && v < PETSC_SMALL) v = 0.0; ierr = PetscPrintf(PETSC_COMM_WORLD,"VecScale %g\n",(double)v);CHKERRQ(ierr); ierr = VecCopy(x,w);CHKERRQ(ierr); ierr = VecNorm(w,NORM_2,&norm);CHKERRQ(ierr); v = norm-2.0*PetscSqrtReal((PetscReal)n); if (v > -PETSC_SMALL && v < PETSC_SMALL) v = 0.0; ierr = PetscPrintf(PETSC_COMM_WORLD,"VecCopy %g\n",(double)v);CHKERRQ(ierr); ierr = VecAXPY(y,three,x);CHKERRQ(ierr); ierr = VecNorm(y,NORM_2,&norm);CHKERRQ(ierr); v = norm-8.0*PetscSqrtReal((PetscReal)n); if (v > -PETSC_SMALL && v < PETSC_SMALL) v = 0.0; ierr = PetscPrintf(PETSC_COMM_WORLD,"VecAXPY %g\n",(double)v);CHKERRQ(ierr); ierr = VecAYPX(y,two,x);CHKERRQ(ierr); ierr = VecNorm(y,NORM_2,&norm);CHKERRQ(ierr); v = norm-18.0*PetscSqrtReal((PetscReal)n); if (v > -PETSC_SMALL && v < PETSC_SMALL) v = 0.0; ierr = PetscPrintf(PETSC_COMM_WORLD,"VecAYPX %g\n",(double)v);CHKERRQ(ierr); ierr = VecSwap(x,y);CHKERRQ(ierr); ierr = VecNorm(y,NORM_2,&norm);CHKERRQ(ierr); v = norm-2.0*PetscSqrtReal((PetscReal)n); if (v > -PETSC_SMALL && v < PETSC_SMALL) v = 0.0; ierr = PetscPrintf(PETSC_COMM_WORLD,"VecSwap %g\n",(double)v);CHKERRQ(ierr); ierr = VecNorm(x,NORM_2,&norm);CHKERRQ(ierr); v = norm-18.0*PetscSqrtReal((PetscReal)n); if (v > -PETSC_SMALL && v < PETSC_SMALL) v = 0.0; ierr = PetscPrintf(PETSC_COMM_WORLD,"VecSwap %g\n",(double)v);CHKERRQ(ierr); ierr = VecWAXPY(w,two,x,y);CHKERRQ(ierr); ierr = VecNorm(w,NORM_2,&norm);CHKERRQ(ierr); v = norm-38.0*PetscSqrtReal((PetscReal)n); if (v > -PETSC_SMALL && v < PETSC_SMALL) v = 0.0; ierr = PetscPrintf(PETSC_COMM_WORLD,"VecWAXPY %g\n",(double)v);CHKERRQ(ierr); ierr = VecPointwiseMult(w,y,x);CHKERRQ(ierr); ierr = VecNorm(w,NORM_2,&norm);CHKERRQ(ierr); v = norm-36.0*PetscSqrtReal((PetscReal)n); if (v > -PETSC_SMALL && v < PETSC_SMALL) v = 0.0; ierr = PetscPrintf(PETSC_COMM_WORLD,"VecPointwiseMult %g\n",(double)v);CHKERRQ(ierr); ierr = VecPointwiseDivide(w,x,y);CHKERRQ(ierr); ierr = VecNorm(w,NORM_2,&norm);CHKERRQ(ierr); v = norm-9.0*PetscSqrtReal((PetscReal)n); if (v > -PETSC_SMALL && v < PETSC_SMALL) v = 0.0; ierr = PetscPrintf(PETSC_COMM_WORLD,"VecPointwiseDivide %g\n",(double)v);CHKERRQ(ierr); dots[0] = one; dots[1] = three; dots[2] = two; ierr = VecSet(x,one);CHKERRQ(ierr); ierr = VecMAXPY(x,3,dots,z);CHKERRQ(ierr); ierr = VecNorm(z[0],NORM_2,&norm);CHKERRQ(ierr); v = norm-PetscSqrtReal((PetscReal)n); if (v > -PETSC_SMALL && v < PETSC_SMALL) v = 0.0; ierr = VecNorm(z[1],NORM_2,&norm);CHKERRQ(ierr); v1 = norm-2.0*PetscSqrtReal((PetscReal)n); if (v1 > -PETSC_SMALL && v1 < PETSC_SMALL) v1 = 0.0; ierr = VecNorm(z[2],NORM_2,&norm);CHKERRQ(ierr); v2 = norm-3.0*PetscSqrtReal((PetscReal)n); if (v2 > -PETSC_SMALL && v2 < PETSC_SMALL) v2 = 0.0; ierr = PetscPrintf(PETSC_COMM_WORLD,"VecMAXPY %g %g %g \n",(double)v,(double)v1,(double)v2);CHKERRQ(ierr); /* Free work space. All PETSc objects should be destroyed when they are no longer needed. */ ierr = VecDestroy(&x);CHKERRQ(ierr); ierr = VecDestroy(&y);CHKERRQ(ierr); ierr = VecDestroy(&w);CHKERRQ(ierr); ierr = VecDestroyVecs(3,&z);CHKERRQ(ierr); ierr = PetscFinalize(); return ierr; }
PetscErrorCode test_axpy_dot_max( void ) { Vec x1,y1, x2,y2; Vec tmp_buf[2]; Vec X, Y; PetscReal real,real2; PetscScalar scalar; PetscInt index; PetscErrorCode ierr; PetscFunctionBegin; PetscPrintf( PETSC_COMM_WORLD, "\n\n============== %s ==============\n", PETSC_FUNCTION_NAME ); gen_test_vector( PETSC_COMM_WORLD, 4, 0, 1, &x1 ); gen_test_vector( PETSC_COMM_WORLD, 5, 10, 2, &x2 ); gen_test_vector( PETSC_COMM_WORLD, 4, 4, 3, &y1 ); gen_test_vector( PETSC_COMM_WORLD, 5, 5, 1, &y2 ); tmp_buf[0] = x1; tmp_buf[1] = x2; ierr = VecCreateNest(PETSC_COMM_WORLD,2,PETSC_NULL,tmp_buf,&X);CHKERRQ(ierr); ierr = VecAssemblyBegin(X);CHKERRQ(ierr); ierr = VecAssemblyEnd(X);CHKERRQ(ierr); ierr = VecDestroy(&x1);CHKERRQ(ierr); ierr = VecDestroy(&x2);CHKERRQ(ierr); tmp_buf[0] = y1; tmp_buf[1] = y2; ierr = VecCreateNest(PETSC_COMM_WORLD,2,PETSC_NULL,tmp_buf,&Y);CHKERRQ(ierr); ierr = VecAssemblyBegin(Y);CHKERRQ(ierr); ierr = VecAssemblyEnd(Y);CHKERRQ(ierr); ierr = VecDestroy(&y1);CHKERRQ(ierr); ierr = VecDestroy(&y2);CHKERRQ(ierr); PetscPrintf( PETSC_COMM_WORLD, "VecAXPY \n"); ierr = VecAXPY( Y, 1.0, X ); /* Y <- a X + Y */ ierr = VecNestGetSubVec( Y, 0, &y1 );CHKERRQ(ierr); ierr = VecNestGetSubVec( Y, 1, &y2 );CHKERRQ(ierr); PetscPrintf( PETSC_COMM_WORLD, "(1) y1 = \n" ); ierr = VecView( y1, PETSC_VIEWER_STDOUT_WORLD );CHKERRQ(ierr); PetscPrintf( PETSC_COMM_WORLD, "(1) y2 = \n" ); ierr = VecView( y2, PETSC_VIEWER_STDOUT_WORLD );CHKERRQ(ierr); ierr = VecDot( X,Y, &scalar );CHKERRQ(ierr); PetscPrintf( PETSC_COMM_WORLD, "X.Y = %lf + %lfi \n", PetscRealPart(scalar), PetscImaginaryPart(scalar) ); ierr = VecDotNorm2( X,Y, &scalar, &real2 );CHKERRQ(ierr); PetscPrintf( PETSC_COMM_WORLD, "X.Y = %lf + %lfi norm2(Y) = %lf\n", PetscRealPart(scalar), PetscImaginaryPart(scalar), real2); ierr = VecAXPY( Y, 1.0, X ); /* Y <- a X + Y */ ierr = VecNestGetSubVec( Y, 0, &y1 );CHKERRQ(ierr); ierr = VecNestGetSubVec( Y, 1, &y2 );CHKERRQ(ierr); PetscPrintf( PETSC_COMM_WORLD, "(2) y1 = \n" ); ierr = VecView( y1, PETSC_VIEWER_STDOUT_WORLD );CHKERRQ(ierr); PetscPrintf( PETSC_COMM_WORLD, "(2) y2 = \n" ); ierr = VecView( y2, PETSC_VIEWER_STDOUT_WORLD );CHKERRQ(ierr); ierr = VecDot( X,Y, &scalar );CHKERRQ(ierr); PetscPrintf( PETSC_COMM_WORLD, "X.Y = %lf + %lfi \n", PetscRealPart(scalar), PetscImaginaryPart(scalar) ); ierr = VecDotNorm2( X,Y, &scalar, &real2 );CHKERRQ(ierr); PetscPrintf( PETSC_COMM_WORLD, "X.Y = %lf + %lfi norm2(Y) = %lf\n", PetscRealPart(scalar), PetscImaginaryPart(scalar), real2); ierr = VecMax( X, &index, &real );CHKERRQ(ierr); PetscPrintf( PETSC_COMM_WORLD, "(max-X) = %f : index = %d \n", real, index ); ierr = VecMin( X, &index, &real );CHKERRQ(ierr); PetscPrintf( PETSC_COMM_WORLD, "(min-X) = %f : index = %d \n", real, index ); ierr = VecDestroy(&X);CHKERRQ(ierr); ierr = VecDestroy(&Y);CHKERRQ(ierr); PetscFunctionReturn(0); }
PetscErrorCode BSSCR_MatStokesMVBlockReportOperatorScales( Mat A, PetscTruth sym ) { Vec rA, rG; PetscInt loc,M,N; PetscReal min, max; Mat K,G,D,C; PetscTruth is_block; /* check A is 2x2 block matrix */ Stg_PetscObjectTypeCompare( (PetscObject)A, "block", &is_block ); if (is_block==PETSC_FALSE) { Stg_SETERRQ( PETSC_ERR_SUP, "Only valid for MatType = block" ); } MatGetSize( A, &M, &N ); if ( (M!=2) || (N!=2) ) { Stg_SETERRQ2( PETSC_ERR_SUP, "Only valid for 2x2 block. Yours has dimension %Dx%D", M,N ); } MatNestGetSubMat( A, 0,0, &K ); MatNestGetSubMat( A, 0,1, &G ); MatNestGetSubMat( A, 1,0, &D ); MatNestGetSubMat( A, 1,1, &C ); MatGetVecs( K, PETSC_NULL, &rA ); VecDuplicate( rA, &rG ); /* Report the row max and mins */ if (K!=PETSC_NULL) { MatGetRowMax( K, rA, PETSC_NULL ); VecMax( rA, &loc, &max ); PetscPrintf( PETSC_COMM_WORLD, "Sup_max(K) = %g \n", max ); MatGetRowMinAbs( K, rA, PETSC_NULL ); VecMin( rA, &loc, &min ); PetscPrintf( PETSC_COMM_WORLD, "Sup_min(K) = %g \n\n", min ); } if( G != PETSC_NULL ) { MatGetRowMax( G, rG, PETSC_NULL ); VecMax( rG, &loc, &max ); PetscPrintf( PETSC_COMM_WORLD, "Sup_max(G) = %g \n", max ); MatGetRowMinAbs( G, rG, PETSC_NULL ); VecMin( rG, &loc, &min ); PetscPrintf( PETSC_COMM_WORLD, "Sup_min(G) = %g \n", min ); } if( D != PETSC_NULL && !sym ) { Vec rD; MatGetVecs( D, PETSC_NULL, &rD ); MatGetRowMax( D, rD, PETSC_NULL ); VecMax( rD, &loc, &max ); PetscPrintf( PETSC_COMM_WORLD, "Sup_max(D) = %g \n", max ); MatGetRowMinAbs( D, rD, PETSC_NULL ); VecMin( rD, &loc, &min ); PetscPrintf( PETSC_COMM_WORLD, "Sup_min(D) = %g \n", min ); Stg_VecDestroy(&rD ); } if( C != PETSC_NULL ) { Vec cG; MatGetVecs( G, &cG, PETSC_NULL ); MatGetRowMax( C, cG, PETSC_NULL ); VecMax( cG, &loc, &max ); PetscPrintf( PETSC_COMM_WORLD, "Sup_max(C) = %g \n", max ); MatGetRowMin( C, cG, PETSC_NULL ); VecMin( cG, &loc, &min ); PetscPrintf( PETSC_COMM_WORLD, "Sup_min(C) = %g \n\n", min ); Stg_VecDestroy(&cG); } Stg_VecDestroy(&rA ); Stg_VecDestroy(&rG ); PetscFunctionReturn(0); }
/* Stokes output: --------------------------------- Operator summary: K G f, h u p --------------------------------- Solution summary: max_u min_u average_u |r_1| |r_2| --------------------------------- Solver summary: name --------------------------------- Petsc build summary: */ PetscErrorCode BSSCR_stokes_output( PetscViewer v, Mat stokes_A, Vec stokes_b, Vec stokes_x, KSP ksp, PetscInt monitor_index ) { Mat K,G,D,C; Vec f,h, u,p; K = G = D = C = PETSC_NULL; f = h = PETSC_NULL; u = p = PETSC_NULL; MatNestGetSubMat( stokes_A, 0,0, &K ); MatNestGetSubMat( stokes_A, 0,1, &G ); MatNestGetSubMat( stokes_A, 1,0, &D ); MatNestGetSubMat( stokes_A, 1,1, &C ); VecNestGetSubVec( stokes_x, 0, &u ); VecNestGetSubVec( stokes_x, 1, &p ); VecNestGetSubVec( stokes_b, 0, &f ); VecNestGetSubVec( stokes_b, 1, &h ); PetscViewerASCIIPrintf( v, "Stokes Output:\n"); PetscViewerASCIIPushTab( v ); /*--------------------------------------------------------------------------------------------*/ PetscViewerASCIIPrintf( v, "--------------------------------------------------\n"); PetscViewerASCIIPrintf( v, "Operator summary:\n"); PetscViewerASCIIPushTab( v ); if (K) { BSSCR_MatInfoLog(v,K, "stokes_A11"); PetscViewerASCIIPrintf( v, "\n"); } if (G) { BSSCR_MatInfoLog(v,G, "stokes_A12"); PetscViewerASCIIPrintf( v, "\n"); } if (D) { BSSCR_MatInfoLog(v,D, "stokes_A21"); PetscViewerASCIIPrintf( v, "\n"); } if (C) { BSSCR_MatInfoLog(v,C, "stokes_A22"); PetscViewerASCIIPrintf( v, "\n"); } if (f) { BSSCR_VecInfoLog(v,f,"stokes_b1"); PetscViewerASCIIPrintf( v, "\n"); } if (h) { BSSCR_VecInfoLog(v,h,"stokes_b2"); PetscViewerASCIIPrintf( v, "\n"); } PetscViewerASCIIPopTab( v ); /*--------------------------------------------------------------------------------------------*/ PetscViewerASCIIPrintf( v, "--------------------------------------------------\n"); PetscViewerASCIIPrintf( v, "Solution summary:\n"); PetscViewerASCIIPushTab( v ); if (u) { BSSCR_VecInfoLog(v,u,"x1"); PetscViewerASCIIPrintf( v, "\n"); } if (p) { BSSCR_VecInfoLog(v,p,"x2"); PetscViewerASCIIPrintf( v, "\n"); } { PetscScalar s,sum; PetscReal r,max,min; PetscInt N, loc; double r1,r2; Vec K_d; PetscInt loc_max, loc_min; VecGetSize( u, &N ); VecMax( u, &loc, &r ); PetscViewerASCIIPrintf( v, "u_max: %1.12e [%d] \n", r, loc ); VecMin( u, &loc, &r ); PetscViewerASCIIPrintf( v, "u_min: %1.12e [%d] \n", r, loc ); VecDot( u,u, &s ); PetscViewerASCIIPrintf( v, "u_rms: %1.12e \n", sqrt( PetscRealPart(s) )/N ); VecDuplicate( u, &K_d ); MatGetDiagonal( K, K_d ); VecMax( K_d, &loc_max, &max ); VecMin( K_d, &loc_min, &min ); PetscViewerASCIIPrintf( v,"Algebraic contrast: max(K_d)=%.3e [%d] , min(K_d)=%.3e [%d] , max(K_d)/min(K_d) = %.8e \n", max,loc_max, min,loc_min, max/min ); MatGetRowMax( K, K_d, PETSC_NULL ); VecMax( K_d, &loc_max, &max ); MatGetRowMin( K, K_d, PETSC_NULL ); VecAbs( K_d ); VecMin( K_d, &loc_min, &min ); PetscViewerASCIIPrintf( v,"Algebraic contrast: max(K)=%.3e [%d] , |min(K)|=%.3e [%d] , max(K)/|min(K)| = %.8e \n", max,loc_max, min,loc_min, max/min ); Stg_VecDestroy(&K_d ); PetscViewerASCIIPrintf( v, "\n"); VecGetSize( p, &N ); VecMax( p, &loc, &r ); PetscViewerASCIIPrintf( v, "p_max: %1.12e [%d] \n", r, loc ); VecMin( p, &loc, &r ); PetscViewerASCIIPrintf( v, "p_min: %1.12e [%d] \n", r, loc ); VecDot( p,p, &s ); PetscViewerASCIIPrintf( v, "p_rms: %1.12e \n", sqrt( PetscRealPart(s) )/N ); VecSum( p, &sum ); PetscViewerASCIIPrintf( v, "sum(p): %1.12e \n", sum ); PetscViewerASCIIPrintf( v, "\n"); r1 = BSSCR_StokesMomentumResidual( K,G,f, u,p ); PetscViewerASCIIPrintf( v, "|r1| = %1.12e <momentum> \n", r1 ); r2 = BSSCR_StokesContinuityResidual( G,C,h, u,p ); PetscViewerASCIIPrintf( v, "|r2| = %1.12e <continuity> \n", r2 ); PetscViewerASCIIPrintf( v, "\n"); } PetscViewerASCIIPopTab( v ); /*--------------------------------------------------------------------------------------------*/ if (ksp) { PetscViewerASCIIPrintf( v, "--------------------------------------------------\n"); PetscViewerASCIIPrintf( v, "Solver summary:\n"); PetscViewerASCIIPushTab( v ); BSSCR_KSPLogSolve( v, monitor_index, ksp ); BSSCR_BSSCR_KSPLogSolveSummary( v, monitor_index, ksp ); PetscViewerASCIIPrintf( v, "\n"); PetscViewerASCIIPopTab( v ); } /*--------------------------------------------------------------------------------------------*/ PetscViewerASCIIPrintf( v, "--------------------------------------------------\n"); PetscViewerASCIIPrintf( v, "Petsc build summary:\n"); PetscViewerASCIIPushTab( v ); BSSCR_GeneratePetscHeader_for_viewer( v ); PetscViewerASCIIPrintf( v, "\n"); PetscViewerASCIIPopTab( v ); /*--------------------------------------------------------------------------------------------*/ PetscViewerASCIIPopTab(v); PetscFunctionReturn(0); }
int main(int argc,char **argv) { TS ts; /* nonlinear solver */ Vec u; /* solution, residual vectors */ Mat J; /* Jacobian matrix */ PetscInt maxsteps = 1000; /* iterations for convergence */ PetscInt nsteps; PetscReal vmin,vmax,norm; PetscErrorCode ierr; DM da; PetscReal ftime,dt; AppCtx user; /* user-defined work context */ JacobianType jacType; PetscInitialize(&argc,&argv,(char*)0,help); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Create distributed array (DMDA) to manage parallel grid and vectors - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = DMDACreate1d(PETSC_COMM_WORLD,DMDA_BOUNDARY_NONE,-11,1,1,NULL,&da); CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Extract global vectors from DMDA; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = DMCreateGlobalVector(da,&u); CHKERRQ(ierr); /* Initialize user application context */ user.c = -30.0; user.boundary = 0; /* 0: Dirichlet BC; 1: Neumann BC */ user.viewJacobian = PETSC_FALSE; ierr = PetscOptionsGetInt(NULL,"-boundary",&user.boundary,NULL); CHKERRQ(ierr); ierr = PetscOptionsHasName(NULL,"-viewJacobian",&user.viewJacobian); CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Create timestepping solver context - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = TSCreate(PETSC_COMM_WORLD,&ts); CHKERRQ(ierr); ierr = TSSetProblemType(ts,TS_NONLINEAR); CHKERRQ(ierr); ierr = TSSetType(ts,TSTHETA); CHKERRQ(ierr); ierr = TSThetaSetTheta(ts,1.0); CHKERRQ(ierr); /* Make the Theta method behave like backward Euler */ ierr = TSSetIFunction(ts,NULL,FormIFunction,&user); CHKERRQ(ierr); ierr = DMSetMatType(da,MATAIJ); CHKERRQ(ierr); ierr = DMCreateMatrix(da,&J); CHKERRQ(ierr); jacType = JACOBIAN_ANALYTIC; /* use user-provide Jacobian */ ierr = TSSetDM(ts,da); CHKERRQ(ierr); /* Use TSGetDM() to access. Setting here allows easy use of geometric multigrid. */ ftime = 1.0; ierr = TSSetDuration(ts,maxsteps,ftime); CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Set initial conditions - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = FormInitialSolution(ts,u,&user); CHKERRQ(ierr); ierr = TSSetSolution(ts,u); CHKERRQ(ierr); dt = .01; ierr = TSSetInitialTimeStep(ts,0.0,dt); CHKERRQ(ierr); /* Use slow fd Jacobian or fast fd Jacobian with colorings. Note: this requirs snes which is not created until TSSetUp()/TSSetFromOptions() is called */ ierr = PetscOptionsBegin(PETSC_COMM_WORLD,NULL,"Options for Jacobian evaluation",NULL); CHKERRQ(ierr); ierr = PetscOptionsEnum("-jac_type","Type of Jacobian","",JacobianTypes,(PetscEnum)jacType,(PetscEnum*)&jacType,0); CHKERRQ(ierr); ierr = PetscOptionsEnd(); CHKERRQ(ierr); if (jacType == JACOBIAN_ANALYTIC) { ierr = TSSetIJacobian(ts,J,J,FormIJacobian,&user); CHKERRQ(ierr); } else if (jacType == JACOBIAN_FD_COLORING) { SNES snes; ierr = TSGetSNES(ts,&snes); CHKERRQ(ierr); ierr = SNESSetJacobian(snes,J,J,SNESComputeJacobianDefaultColor,0); CHKERRQ(ierr); } else if (jacType == JACOBIAN_FD_FULL) { SNES snes; ierr = TSGetSNES(ts,&snes); CHKERRQ(ierr); ierr = SNESSetJacobian(snes,J,J,SNESComputeJacobianDefault,&user); CHKERRQ(ierr); } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Set runtime options - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = TSSetFromOptions(ts); CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Integrate ODE system - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = TSSolve(ts,u); CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Compute diagnostics of the solution - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = VecNorm(u,NORM_1,&norm); CHKERRQ(ierr); ierr = VecMax(u,NULL,&vmax); CHKERRQ(ierr); ierr = VecMin(u,NULL,&vmin); CHKERRQ(ierr); ierr = TSGetTimeStepNumber(ts,&nsteps); CHKERRQ(ierr); ierr = TSGetTime(ts,&ftime); CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"timestep %D: time %G, solution norm %G, max %G, min %G\n",nsteps,ftime,norm,vmax,vmin); CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Free work space. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = MatDestroy(&J); CHKERRQ(ierr); ierr = VecDestroy(&u); CHKERRQ(ierr); ierr = TSDestroy(&ts); CHKERRQ(ierr); ierr = DMDestroy(&da); CHKERRQ(ierr); ierr = PetscFinalize(); PetscFunctionReturn(0); }