static PetscErrorCode FormInitial_Coupled(User user,Vec X) { PetscErrorCode ierr; DM dau,dak; DMDALocalInfo infou,infok; Vec Xu,Xk; PetscScalar *u,*k,hx; PetscInt i; PetscFunctionBeginUser; ierr = DMCompositeGetEntries(user->pack,&dau,&dak);CHKERRQ(ierr); ierr = DMCompositeGetAccess(user->pack,X,&Xu,&Xk);CHKERRQ(ierr); ierr = DMDAVecGetArray(dau,Xu,&u);CHKERRQ(ierr); ierr = DMDAVecGetArray(dak,Xk,&k);CHKERRQ(ierr); ierr = DMDAGetLocalInfo(dau,&infou);CHKERRQ(ierr); ierr = DMDAGetLocalInfo(dak,&infok);CHKERRQ(ierr); hx = 1./(infok.mx); for (i=infou.xs; i<infou.xs+infou.xm; i++) u[i] = (PetscScalar)i*hx * (1.-(PetscScalar)i*hx); for (i=infok.xs; i<infok.xs+infok.xm; i++) k[i] = 1.0 + 0.5*PetscSinScalar(2*PETSC_PI*i*hx); ierr = DMDAVecRestoreArray(dau,Xu,&u);CHKERRQ(ierr); ierr = DMDAVecRestoreArray(dak,Xk,&k);CHKERRQ(ierr); ierr = DMCompositeRestoreAccess(user->pack,X,&Xu,&Xk);CHKERRQ(ierr); ierr = DMCompositeScatter(user->pack,X,user->Uloc,user->Kloc);CHKERRQ(ierr); PetscFunctionReturn(0); }
PetscErrorCode ExactSolution(DM packer,Vec U) { PF pf; Vec x,u_global; PetscScalar *w; DM da; PetscErrorCode ierr; PetscInt m; PetscFunctionBeginUser; ierr = DMCompositeGetEntries(packer,&m,&da);CHKERRQ(ierr); ierr = PFCreate(PETSC_COMM_WORLD,1,2,&pf);CHKERRQ(ierr); /* The cast through PETSC_UINTPTR_T is so that compilers will warn about casting to void * from void(*)(void) */ ierr = PFSetType(pf,PFQUICK,(void*)(PETSC_UINTPTR_T)u_solution);CHKERRQ(ierr); ierr = DMGetCoordinates(da,&x);CHKERRQ(ierr); if (!x) { ierr = DMDASetUniformCoordinates(da,0.0,1.0,0.0,1.0,0.0,1.0);CHKERRQ(ierr); ierr = DMGetCoordinates(da,&x);CHKERRQ(ierr); } ierr = DMCompositeGetAccess(packer,U,&w,&u_global,0);CHKERRQ(ierr); if (w) w[0] = .25; ierr = PFApplyVec(pf,x,u_global);CHKERRQ(ierr); ierr = PFDestroy(&pf);CHKERRQ(ierr); ierr = DMCompositeRestoreAccess(packer,U,&w,&u_global,0);CHKERRQ(ierr); PetscFunctionReturn(0); }
/* FormInitialGuessComp - Forms the initial guess for the composite model Unwraps the global solution vector and passes its local pieces into the user functions */ PetscErrorCode FormInitialGuessComp(DMMG dmmg,Vec X) { PetscErrorCode ierr; AppCtx *user = (AppCtx*)dmmg->user; DMComposite dm = (DMComposite)dmmg->dm; Vec X1,X2; Field1 **x1; Field2 **x2; DALocalInfo info1,info2; DA da1,da2; PetscFunctionBegin; ierr = DMCompositeGetEntries(dm,&da1,&da2);CHKERRQ(ierr); /* Access the subvectors in X */ ierr = DMCompositeGetAccess(dm,X,&X1,&X2);CHKERRQ(ierr); /* Access the arrays inside the subvectors of X */ ierr = DAVecGetArray(da1,X1,(void**)&x1);CHKERRQ(ierr); ierr = DAVecGetArray(da2,X2,(void**)&x2);CHKERRQ(ierr); ierr = DAGetLocalInfo(da1,&info1);CHKERRQ(ierr); ierr = DAGetLocalInfo(da2,&info2);CHKERRQ(ierr); /* Evaluate local user provided function */ ierr = FormInitialGuessLocal1(&info1,x1);CHKERRQ(ierr); ierr = FormInitialGuessLocal2(&info2,x2,user);CHKERRQ(ierr); ierr = DAVecRestoreArray(da1,X1,(void**)&x1);CHKERRQ(ierr); ierr = DAVecRestoreArray(da2,X2,(void**)&x2);CHKERRQ(ierr); ierr = DMCompositeRestoreAccess(dm,X,&X1,&X2);CHKERRQ(ierr); PetscFunctionReturn(0); }
PetscErrorCode DiffusiveTerm<2>::calculateExactSolution() { PetscErrorCode ierr; PetscInt i, j, // loop indices m, n, // local number of nodes along each direction mstart, nstart; // starting indices PetscReal x, y, // coordinates of a node velocity, // velocity value at the node diffusion; // value of the diffusive term at the node PetscReal nu = flow->nu, // viscosity dt = parameters->dt, // time-increment alpha = parameters->diffusion.coefficients[1]; // explicit time-scheme coefficient for diffusive terms ierr = VecDuplicate(q, &rnExact); CHKERRQ(ierr); Vec rnExactXGlobal, rnExactYGlobal; ierr = DMCompositeGetAccess(qPack, rnExact, &rnExactXGlobal, &rnExactYGlobal); CHKERRQ(ierr); // exact explicit terms for u-nodes PetscReal **rnExactX; ierr = DMDAVecGetArray(uda, rnExactXGlobal, &rnExactX); ierr = DMDAGetCorners(uda, &mstart, &nstart, NULL, &m, &n, NULL); CHKERRQ(ierr); for (j=nstart; j<nstart+n; j++) { for (i=mstart; i<mstart+m; i++) { x = mesh->x[i+1]; y = 0.5*(mesh->y[j]+mesh->y[j+1]); velocity = sin(PETSC_PI*x)*sin(PETSC_PI*y) + 1.0; diffusion = -2.0*nu*PETSC_PI*PETSC_PI*sin(PETSC_PI*x)*sin(PETSC_PI*y); rnExactX[j][i] = velocity/dt + alpha*diffusion; } } ierr = DMDAVecRestoreArray(uda, rnExactXGlobal, &rnExactX); CHKERRQ(ierr); // exact explicit terms for v-nodes PetscReal **rnExactY; ierr = DMDAVecGetArray(vda, rnExactYGlobal, &rnExactY); ierr = DMDAGetCorners(vda, &mstart, &nstart, NULL, &m, &n, NULL); CHKERRQ(ierr); for (j=nstart; j<nstart+n; j++) { for (i=mstart; i<mstart+m; i++) { x = 0.5*(mesh->x[i]+mesh->x[i+1]); y = mesh->y[j+1]; velocity = sin(PETSC_PI*x)*sin(PETSC_PI*y); diffusion = -2.0*nu*PETSC_PI*PETSC_PI*sin(PETSC_PI*x)*sin(PETSC_PI*y); rnExactY[j][i] = velocity/dt + alpha*diffusion; } } ierr = DMDAVecRestoreArray(vda, rnExactYGlobal, &rnExactY); CHKERRQ(ierr); ierr = DMCompositeRestoreAccess(qPack, rnExact, &rnExactXGlobal, &rnExactYGlobal); CHKERRQ(ierr); return ierr; } // calculateExactSolution
static PetscErrorCode FormFunction_All(SNES snes,Vec X,Vec F,void *ctx) { User user = (User)ctx; DM dau,dak; DMDALocalInfo infou,infok; PetscScalar *u,*k; PetscScalar *fu,*fk; PetscErrorCode ierr; Vec Uloc,Kloc,Fu,Fk; PetscFunctionBeginUser; ierr = DMCompositeGetEntries(user->pack,&dau,&dak);CHKERRQ(ierr); ierr = DMDAGetLocalInfo(dau,&infou);CHKERRQ(ierr); ierr = DMDAGetLocalInfo(dak,&infok);CHKERRQ(ierr); ierr = DMCompositeGetLocalVectors(user->pack,&Uloc,&Kloc);CHKERRQ(ierr); switch (user->ptype) { case 0: ierr = DMGlobalToLocalBegin(dau,X,INSERT_VALUES,Uloc);CHKERRQ(ierr); ierr = DMGlobalToLocalEnd (dau,X,INSERT_VALUES,Uloc);CHKERRQ(ierr); ierr = DMDAVecGetArray(dau,Uloc,&u);CHKERRQ(ierr); ierr = DMDAVecGetArray(dak,user->Kloc,&k);CHKERRQ(ierr); ierr = DMDAVecGetArray(dau,F,&fu);CHKERRQ(ierr); ierr = FormFunctionLocal_U(user,&infou,u,k,fu);CHKERRQ(ierr); ierr = DMDAVecRestoreArray(dau,F,&fu);CHKERRQ(ierr); ierr = DMDAVecRestoreArray(dau,Uloc,&u);CHKERRQ(ierr); ierr = DMDAVecRestoreArray(dak,user->Kloc,&k);CHKERRQ(ierr); break; case 1: ierr = DMGlobalToLocalBegin(dak,X,INSERT_VALUES,Kloc);CHKERRQ(ierr); ierr = DMGlobalToLocalEnd (dak,X,INSERT_VALUES,Kloc);CHKERRQ(ierr); ierr = DMDAVecGetArray(dau,user->Uloc,&u);CHKERRQ(ierr); ierr = DMDAVecGetArray(dak,Kloc,&k);CHKERRQ(ierr); ierr = DMDAVecGetArray(dak,F,&fk);CHKERRQ(ierr); ierr = FormFunctionLocal_K(user,&infok,u,k,fk);CHKERRQ(ierr); ierr = DMDAVecRestoreArray(dak,F,&fk);CHKERRQ(ierr); ierr = DMDAVecRestoreArray(dau,user->Uloc,&u);CHKERRQ(ierr); ierr = DMDAVecRestoreArray(dak,Kloc,&k);CHKERRQ(ierr); break; case 2: ierr = DMCompositeScatter(user->pack,X,Uloc,Kloc);CHKERRQ(ierr); ierr = DMDAVecGetArray(dau,Uloc,&u);CHKERRQ(ierr); ierr = DMDAVecGetArray(dak,Kloc,&k);CHKERRQ(ierr); ierr = DMCompositeGetAccess(user->pack,F,&Fu,&Fk);CHKERRQ(ierr); ierr = DMDAVecGetArray(dau,Fu,&fu);CHKERRQ(ierr); ierr = DMDAVecGetArray(dak,Fk,&fk);CHKERRQ(ierr); ierr = FormFunctionLocal_U(user,&infou,u,k,fu);CHKERRQ(ierr); ierr = FormFunctionLocal_K(user,&infok,u,k,fk);CHKERRQ(ierr); ierr = DMDAVecRestoreArray(dau,Fu,&fu);CHKERRQ(ierr); ierr = DMDAVecRestoreArray(dak,Fk,&fk);CHKERRQ(ierr); ierr = DMCompositeRestoreAccess(user->pack,F,&Fu,&Fk);CHKERRQ(ierr); ierr = DMDAVecRestoreArray(dau,Uloc,&u);CHKERRQ(ierr); ierr = DMDAVecRestoreArray(dak,Kloc,&k);CHKERRQ(ierr); break; } ierr = DMCompositeRestoreLocalVectors(user->pack,&Uloc,&Kloc);CHKERRQ(ierr); PetscFunctionReturn(0); }
PetscErrorCode TcSolver::generateBC2() { PetscErrorCode ierr; PetscInt mstart, nstart, m, n, i, j; PetscReal **qx, **qy; PetscReal **bc22; Vec bc2Global; ierr = VecSet(bc2, 0.0); CHKERRQ(ierr); ierr = DMCompositeGetAccess(lambdaPack, bc2, &bc2Global, NULL); CHKERRQ(ierr); ierr = DMDAVecGetArray(uda, qxLocal, &qx); CHKERRQ(ierr); ierr = DMDAVecGetArray(vda, qyLocal, &qy); CHKERRQ(ierr); ierr = DMDAVecGetArray(pda, bc2Global, &bc22); CHKERRQ(ierr); ierr = DMDAGetCorners(pda, &mstart, &nstart, NULL, &m, &n, NULL); CHKERRQ(ierr); //x-faces for(j=nstart; j<nstart+n; j++) { //-X if(mstart == 0) //if -X is current process { bc22[j][0] -= qx[j][-1]; } //+X if(mstart+m-1 == fluid.nx-1) { bc22[j][fluid.nx-1] += qx[j][fluid.nx-1]; } } //y-faces for(i=mstart; i<mstart+m; i++) { //-Y if(nstart ==0) { bc22[0][i] -= qy[-1][i]; } //+Y if(nstart+n-1 == fluid.ny-1) { bc22[fluid.ny-1][i] += qy[fluid.ny-1][i]; } } ierr = DMDAVecRestoreArray(pda, bc2Global, &bc22); CHKERRQ(ierr); ierr = DMDAVecRestoreArray(uda, qxLocal, &qx); CHKERRQ(ierr); ierr = DMDAVecRestoreArray(vda, qyLocal, &qy); CHKERRQ(ierr); ierr = DMCompositeRestoreAccess(lambdaPack, bc2, &bc2Global, NULL); CHKERRQ(ierr); return 0; }
/* Evaluates FU = Gradiant(L(w,u,lambda)) This local function acts on the ghosted version of U (accessed via DMCompositeGetLocalVectors() and DMCompositeScatter()) BUT the global, nonghosted version of FU (via DMCompositeGetAccess()). */ PetscErrorCode ComputeFunction(SNES snes,Vec U,Vec FU,void *ctx) { PetscErrorCode ierr; PetscInt xs,xm,i,N; ULambda *u_lambda,*fu_lambda; PetscScalar d,h,*w,*fw; Vec vw,vfw,vu_lambda,vfu_lambda; DM packer,red,da; PetscFunctionBeginUser; ierr = VecGetDM(U, &packer);CHKERRQ(ierr); ierr = DMCompositeGetEntries(packer,&red,&da);CHKERRQ(ierr); ierr = DMCompositeGetLocalVectors(packer,&vw,&vu_lambda);CHKERRQ(ierr); ierr = DMCompositeScatter(packer,U,vw,vu_lambda);CHKERRQ(ierr); ierr = DMCompositeGetAccess(packer,FU,&vfw,&vfu_lambda);CHKERRQ(ierr); ierr = DMDAGetCorners(da,&xs,NULL,NULL,&xm,NULL,NULL);CHKERRQ(ierr); ierr = DMDAGetInfo(da,0,&N,0,0,0,0,0,0,0,0,0,0,0);CHKERRQ(ierr); ierr = VecGetArray(vw,&w);CHKERRQ(ierr); ierr = VecGetArray(vfw,&fw);CHKERRQ(ierr); ierr = DMDAVecGetArray(da,vu_lambda,&u_lambda);CHKERRQ(ierr); ierr = DMDAVecGetArray(da,vfu_lambda,&fu_lambda);CHKERRQ(ierr); d = N-1.0; h = 1.0/d; /* derivative of L() w.r.t. w */ if (xs == 0) { /* only first processor computes this */ fw[0] = -2.0*d*u_lambda[0].lambda; } /* derivative of L() w.r.t. u */ for (i=xs; i<xs+xm; i++) { if (i == 0) fu_lambda[0].lambda = h*u_lambda[0].u + 2.*d*u_lambda[0].lambda - d*u_lambda[1].lambda; else if (i == 1) fu_lambda[1].lambda = 2.*h*u_lambda[1].u + 2.*d*u_lambda[1].lambda - d*u_lambda[2].lambda; else if (i == N-1) fu_lambda[N-1].lambda = h*u_lambda[N-1].u + 2.*d*u_lambda[N-1].lambda - d*u_lambda[N-2].lambda; else if (i == N-2) fu_lambda[N-2].lambda = 2.*h*u_lambda[N-2].u + 2.*d*u_lambda[N-2].lambda - d*u_lambda[N-3].lambda; else fu_lambda[i].lambda = 2.*h*u_lambda[i].u - d*(u_lambda[i+1].lambda - 2.0*u_lambda[i].lambda + u_lambda[i-1].lambda); } /* derivative of L() w.r.t. lambda */ for (i=xs; i<xs+xm; i++) { if (i == 0) fu_lambda[0].u = 2.0*d*(u_lambda[0].u - w[0]); else if (i == N-1) fu_lambda[N-1].u = 2.0*d*u_lambda[N-1].u; else fu_lambda[i].u = -(d*(u_lambda[i+1].u - 2.0*u_lambda[i].u + u_lambda[i-1].u) - 2.0*h); } ierr = VecRestoreArray(vw,&w);CHKERRQ(ierr); ierr = VecRestoreArray(vfw,&fw);CHKERRQ(ierr); ierr = DMDAVecRestoreArray(da,vu_lambda,&u_lambda);CHKERRQ(ierr); ierr = DMDAVecRestoreArray(da,vfu_lambda,&fu_lambda);CHKERRQ(ierr); ierr = DMCompositeRestoreLocalVectors(packer,&vw,&vu_lambda);CHKERRQ(ierr); ierr = DMCompositeRestoreAccess(packer,FU,&vfw,&vfu_lambda);CHKERRQ(ierr); ierr = PetscLogFlops(13.0*N);CHKERRQ(ierr); PetscFunctionReturn(0); }
PetscErrorCode Monitor(SNES snes,PetscInt its,PetscReal rnorm,void *dummy) { UserCtx *user = (UserCtx*)dummy; PetscErrorCode ierr; Vec w,u,lambda,U,F; PetscFunctionBeginUser; ierr = SNESGetSolution(snes,&U);CHKERRQ(ierr); ierr = DMCompositeGetAccess(user->packer,U,&w,&u,&lambda);CHKERRQ(ierr); ierr = VecView(u,user->u_viewer);CHKERRQ(ierr); ierr = VecView(lambda,user->lambda_viewer);CHKERRQ(ierr); ierr = DMCompositeRestoreAccess(user->packer,U,&w,&u,&lambda);CHKERRQ(ierr); ierr = SNESGetFunction(snes,&F,0,0);CHKERRQ(ierr); ierr = DMCompositeGetAccess(user->packer,F,&w,&u,&lambda);CHKERRQ(ierr); ierr = VecView(u,user->fu_viewer);CHKERRQ(ierr); ierr = VecView(lambda,user->flambda_viewer);CHKERRQ(ierr); ierr = DMCompositeRestoreAccess(user->packer,F,&w,&u,&lambda);CHKERRQ(ierr); PetscFunctionReturn(0); }
/* FormInitialGuess - Unwraps the global solution vector and passes its local pieces into the user function */ PetscErrorCode FormInitialGuess(DMMG dmmg,Vec X) { DMComposite dm = (DMComposite)dmmg->dm; DALocalInfo info1,info2,info3; DA da1,da2,da3; FluidField *x1; PetscScalar **x2; FuelField **x3; Vec X1,X2,X3; PetscErrorCode ierr; AppCtx *app = (AppCtx*)dmmg->user; PetscFunctionBegin; ierr = DMCompositeGetEntries(dm,&da1,&da2,&da3); CHKERRQ(ierr); ierr = DAGetLocalInfo(da1,&info1); CHKERRQ(ierr); ierr = DAGetLocalInfo(da2,&info2); CHKERRQ(ierr); ierr = DAGetLocalInfo(da3,&info3); CHKERRQ(ierr); /* Access the three subvectors in X */ ierr = DMCompositeGetAccess(dm,X,&X1,&X2,&X3); CHKERRQ(ierr); /* Access the arrays inside the subvectors of X */ ierr = DAVecGetArray(da1,X1,(void**)&x1); CHKERRQ(ierr); ierr = DAVecGetArray(da2,X2,(void**)&x2); CHKERRQ(ierr); ierr = DAVecGetArray(da3,X3,(void**)&x3); CHKERRQ(ierr); /* Evaluate local user provided function */ ierr = FormInitialGuessLocalFluid(app,&info1,x1); CHKERRQ(ierr); ierr = FormInitialGuessLocalThermal(app,&info2,x2); CHKERRQ(ierr); ierr = FormInitialGuessLocalFuel(app,&info3,x3); CHKERRQ(ierr); ierr = DAVecRestoreArray(da1,X1,(void**)&x1); CHKERRQ(ierr); ierr = DAVecRestoreArray(da2,X2,(void**)&x2); CHKERRQ(ierr); ierr = DAVecRestoreArray(da3,X3,(void**)&x3); CHKERRQ(ierr); ierr = DMCompositeRestoreAccess(dm,X,&X1,&X2,&X3); CHKERRQ(ierr); PetscFunctionReturn(0); }
PetscErrorCode DiffusiveTerm<2>::initializeFluxes() { PetscErrorCode ierr; PetscInt i, j, // loop indices m, n, // local number of nodes along each direction mstart, nstart; // starting indices PetscReal x, y; // coordinates of a node Vec qxGlobal, qyGlobal; ierr = DMCompositeGetAccess(qPack, q, &qxGlobal, &qyGlobal); CHKERRQ(ierr); // fluxes in x-direction PetscReal **qx; ierr = DMDAVecGetArray(uda, qxGlobal, &qx); CHKERRQ(ierr); ierr = DMDAGetCorners(uda, &mstart, &nstart, NULL, &m, &n, NULL); CHKERRQ(ierr); PetscReal u; // value of u-velocity for (j=nstart; j<nstart+n; j++) { for (i=mstart; i<mstart+m; i++) { x = mesh->x[i+1]; y = 0.5*(mesh->y[j]+mesh->y[j+1]); u = sin(PETSC_PI*x)*sin(PETSC_PI*y) + 1.0; qx[j][i] = u*mesh->dy[j]; } } ierr = DMDAVecRestoreArray(uda, qxGlobal, &qx); CHKERRQ(ierr); // fluxes in y-direction PetscReal **qy; ierr = DMDAVecGetArray(vda, qyGlobal, &qy); CHKERRQ(ierr); ierr = DMDAGetCorners(vda, &mstart, &nstart, NULL, &m, &n, NULL); CHKERRQ(ierr); PetscReal v; // value of v-velocity for (j=nstart; j<nstart+n; j++) { for (i=mstart; i<mstart+m; i++) { x = 0.5*(mesh->x[i]+mesh->x[i+1]); y = mesh->y[j+1]; v = sin(PETSC_PI*x)*sin(PETSC_PI*y); qy[j][i] = v*mesh->dx[i]; } } ierr = DMDAVecRestoreArray(vda, qyGlobal, &qy); CHKERRQ(ierr); ierr = DMCompositeRestoreAccess(qPack, q, &qxGlobal, &qyGlobal); CHKERRQ(ierr); return ierr; } // initializeFluxes
PetscErrorCode Monitor(SNES snes,PetscInt its,PetscReal rnorm,void *dummy) { UserCtx *user; PetscErrorCode ierr; PetscInt m,N; PetscScalar *w,*dw; Vec u_lambda,U,F,Uexact; DM packer; PetscReal norm; DM da; PetscFunctionBeginUser; ierr = SNESGetDM(snes,&packer);CHKERRQ(ierr); ierr = DMGetApplicationContext(packer,&user);CHKERRQ(ierr); ierr = SNESGetSolution(snes,&U);CHKERRQ(ierr); ierr = DMCompositeGetAccess(packer,U,&w,&u_lambda);CHKERRQ(ierr); ierr = VecView(u_lambda,user->u_lambda_viewer);CHKERRQ(ierr); ierr = DMCompositeRestoreAccess(packer,U,&w,&u_lambda);CHKERRQ(ierr); ierr = SNESGetFunction(snes,&F,0,0);CHKERRQ(ierr); ierr = DMCompositeGetAccess(packer,F,&w,&u_lambda);CHKERRQ(ierr); /* ierr = VecView(u_lambda,user->fu_lambda_viewer); */ ierr = DMCompositeRestoreAccess(packer,U,&w,&u_lambda);CHKERRQ(ierr); ierr = DMCompositeGetEntries(packer,&m,&da);CHKERRQ(ierr); ierr = DMDAGetInfo(da,0,&N,0,0,0,0,0,0,0,0,0,0,0);CHKERRQ(ierr); ierr = VecDuplicate(U,&Uexact);CHKERRQ(ierr); ierr = ExactSolution(packer,Uexact);CHKERRQ(ierr); ierr = VecAXPY(Uexact,-1.0,U);CHKERRQ(ierr); ierr = DMCompositeGetAccess(packer,Uexact,&dw,&u_lambda);CHKERRQ(ierr); ierr = VecStrideNorm(u_lambda,0,NORM_2,&norm);CHKERRQ(ierr); norm = norm/PetscSqrtReal((PetscReal)N-1.); if (dw) ierr = PetscPrintf(PETSC_COMM_WORLD,"Norm of error %g Error at x = 0 %g\n",(double)norm,(double)PetscRealPart(dw[0]));CHKERRQ(ierr); ierr = VecView(u_lambda,user->fu_lambda_viewer);CHKERRQ(ierr); ierr = DMCompositeRestoreAccess(packer,Uexact,&dw,&u_lambda);CHKERRQ(ierr); ierr = VecDestroy(&Uexact);CHKERRQ(ierr); PetscFunctionReturn(0); }
/* FormFunctionComp - Unwraps the input vector and passes its local ghosted pieces into the user function */ PetscErrorCode FormFunctionComp(SNES snes,Vec X,Vec F,void *ctx) { PetscErrorCode ierr; DMMG dmmg = (DMMG)ctx; AppCtx *user = (AppCtx*)dmmg->user; DMComposite dm = (DMComposite)dmmg->dm; DALocalInfo info1,info2; DA da1,da2; Field1 **x1,**f1; Field2 **x2,**f2; Vec X1,X2,F1,F2; PetscFunctionBegin; ierr = DMCompositeGetEntries(dm,&da1,&da2);CHKERRQ(ierr); ierr = DAGetLocalInfo(da1,&info1);CHKERRQ(ierr); ierr = DAGetLocalInfo(da2,&info2);CHKERRQ(ierr); /* Get local vectors to hold ghosted parts of X */ ierr = DMCompositeGetLocalVectors(dm,&X1,&X2);CHKERRQ(ierr); ierr = DMCompositeScatter(dm,X,X1,X2);CHKERRQ(ierr); /* Access the arrays inside the subvectors of X */ ierr = DAVecGetArray(da1,X1,(void**)&x1);CHKERRQ(ierr); ierr = DAVecGetArray(da2,X2,(void**)&x2);CHKERRQ(ierr); /* Access the subvectors in F. These are not ghosted and directly access the memory locations in F */ ierr = DMCompositeGetAccess(dm,F,&F1,&F2);CHKERRQ(ierr); /* Access the arrays inside the subvectors of F */ ierr = DAVecGetArray(da1,F1,(void**)&f1);CHKERRQ(ierr); ierr = DAVecGetArray(da2,F2,(void**)&f2);CHKERRQ(ierr); /* Evaluate local user provided function */ user->x2 = x2; /* used by FormFunctionLocal1() */ ierr = FormFunctionLocal1(&info1,x1,f1,(void**)user);CHKERRQ(ierr); user->x1 = x1; /* used by FormFunctionLocal2() */ ierr = FormFunctionLocal2(&info2,x2,f2,(void**)user);CHKERRQ(ierr); ierr = DAVecRestoreArray(da1,F1,(void**)&f1);CHKERRQ(ierr); ierr = DAVecRestoreArray(da2,F2,(void**)&f2);CHKERRQ(ierr); ierr = DMCompositeRestoreAccess(dm,F,&F1,&F2);CHKERRQ(ierr); ierr = DAVecRestoreArray(da1,X1,(void**)&x1);CHKERRQ(ierr); ierr = DAVecRestoreArray(da2,X2,(void**)&x2);CHKERRQ(ierr); ierr = DMCompositeRestoreLocalVectors(dm,&X1,&X2);CHKERRQ(ierr); PetscFunctionReturn(0); }
/* FormInitialGuessComp - Forms the initial guess for the composite model Unwraps the global solution vector and passes its local pieces into the user functions */ PetscErrorCode FormInitialGuessComp(DMMG dmmg,Vec X) { PetscErrorCode ierr; AppCtx *user = (AppCtx*)dmmg->user; DMMG *dmmg1 = user->dmmg1,*dmmg2=user->dmmg2; DMComposite dm = (DMComposite)dmmg->dm; Vec X1,X2; PetscFunctionBegin; /* Access the subvectors in X */ ierr = DMCompositeGetAccess(dm,X,&X1,&X2);CHKERRQ(ierr); /* Evaluate local user provided function */ ierr = FormInitialGuessLocal1(*dmmg1,X1);CHKERRQ(ierr); ierr = FormInitialGuessLocal2(*dmmg2,X2);CHKERRQ(ierr); ierr = DMCompositeRestoreAccess(dm,X,&X1,&X2);CHKERRQ(ierr); PetscFunctionReturn(0); }
PetscErrorCode save_VTK(const char* path, const char* filename, Vec sol, DM dm, std::array<double, 2> h) { PetscErrorCode ierr; DM dau, dap; DMDALocalInfo infou, infop; Vec solu, solp; Vec locsolu, locsolp; PetscScalar ***psolu, **psolp; ierr = DMCompositeGetEntries(dm, &dau, &dap);CHKERRQ(ierr); ierr = DMDAGetLocalInfo(dau, &infou);CHKERRQ(ierr); ierr = DMDAGetLocalInfo(dap, &infop);CHKERRQ(ierr); ierr = DMCompositeGetAccess(dm,sol,&solu,&solp);CHKERRQ(ierr); ierr = DMGetLocalVector(dau, &locsolu);CHKERRQ(ierr); ierr = DMGetLocalVector(dap, &locsolp);CHKERRQ(ierr); ierr = DMGlobalToLocalBegin(dau, solu, INSERT_VALUES, locsolu);CHKERRQ(ierr); ierr = DMGlobalToLocalEnd(dau, solu, INSERT_VALUES, locsolu);CHKERRQ(ierr); ierr = DMGlobalToLocalBegin(dap, solp, INSERT_VALUES, locsolp);CHKERRQ(ierr); ierr = DMGlobalToLocalEnd(dap, solp, INSERT_VALUES, locsolp);CHKERRQ(ierr); ierr = DMDAVecGetArrayDOF(dau, locsolu, &psolu);CHKERRQ(ierr); ierr = DMDAVecGetArray(dap, locsolp, &psolp);CHKERRQ(ierr); vtkStructuredGrid* pressureDataSet = vtkStructuredGrid::New(); pressureDataSet->SetExtent(infop.gxs, infop.gxs+infop.gxm-1, infop.gys, infop.gys+infop.gym-1, 0, 0); vtkStructuredGrid* velocityDataSet = vtkStructuredGrid::New(); velocityDataSet->SetExtent(infou.gxs, infou.gxs+infou.gxm-1, infou.gys, infou.gys+infou.gym-1, 0, 0); vtkPoints* pressurePoints = vtkPoints::New(); vtkPoints* velocityPoints = vtkPoints::New(); vtkDoubleArray* velocity = vtkDoubleArray::New(); velocity->SetNumberOfComponents(3); velocity->SetName("velocity"); vtkDoubleArray* pressure = vtkDoubleArray::New(); pressure->SetName("pressure"); for (int j=infop.gys; j<infop.gys+infop.gym; j++) for (int i=infop.gxs; i<infop.gxs+infop.gxm; i++) { pressurePoints->InsertNextPoint(2*i*h[0], 2*j*h[1], 0.); pressure->InsertNextValue(psolp[j][i]); } int rank; MPI_Comm_rank(PETSC_COMM_WORLD, &rank); for (int j=infou.gys; j<infou.gys+infou.gym; j++) for (int i=infou.gxs; i<infou.gxs+infou.gxm; i++) { velocityPoints->InsertNextPoint(i*h[0], j*h[1], 0.); velocity->InsertNextTuple3(psolu[j][i][0], psolu[j][i][1], 0.); } pressureDataSet->SetPoints(pressurePoints); pressureDataSet->GetPointData()->SetScalars(pressure); velocityDataSet->SetPoints(velocityPoints); velocityDataSet->GetPointData()->SetScalars(velocity); vtkXMLStructuredGridWriter* pressureDataWriter = vtkXMLStructuredGridWriter::New(); vtkXMLStructuredGridWriter* velocityDataWriter = vtkXMLStructuredGridWriter::New(); std::stringstream op, ov; int size;//, rank; MPI_Comm_size(PETSC_COMM_WORLD, &size); MPI_Comm_rank(PETSC_COMM_WORLD, &rank); int x[size], y[size], z[size]; int sx[size], sy[size], sz[size]; MPI_Gather(&infop.gxs, 1, MPI_INT, x, 1, MPI_INT, 0, PETSC_COMM_WORLD); MPI_Gather(&infop.gxm, 1, MPI_INT, sx, 1, MPI_INT, 0, PETSC_COMM_WORLD); MPI_Gather(&infop.gys, 1, MPI_INT, y, 1, MPI_INT, 0, PETSC_COMM_WORLD); MPI_Gather(&infop.gym, 1, MPI_INT, sy, 1, MPI_INT, 0, PETSC_COMM_WORLD); MPI_Gather(&infop.gzs, 1, MPI_INT, z, 1, MPI_INT, 0, PETSC_COMM_WORLD); MPI_Gather(&infop.gzm, 1, MPI_INT, sz, 1, MPI_INT, 0, PETSC_COMM_WORLD); op << path << "/" << filename << "_pressure_" << rank << ".vts"; pressureDataWriter->SetFileName(op.str().data()); //dataWriter->SetDataModeToAscii(); #if VTK_MAJOR_VERSION <= 5 pressureDataWriter->SetInput(pressureDataSet); #else pressureDataWriter->SetInputData(pressureDataSet); #endif pressureDataWriter->Write(); ov << path << "/" << filename << "_velocity_" << rank << ".vts"; velocityDataWriter->SetFileName(ov.str().data()); //dataWriter->SetDataModeToAscii(); #if VTK_MAJOR_VERSION <= 5 velocityDataWriter->SetInput(velocityDataSet); #else velocityDataWriter->SetInputData(velocityDataSet); #endif velocityDataWriter->Write(); if (rank == 0){ std::stringstream oall; oall << path << "/" << filename << "_pressure.pvts"; ofstream pvts; pvts.open(oall.str().data(), ios::out | ios::trunc); pvts << "<?xml version=\"1.0\"?>" << endl; pvts << "<VTKFile type=\"PStructuredGrid\" version=\"0.1\" byte_order=\"LittleEndian\" compressor=\"vtkZLibDataCompressor\">" << endl; pvts << "<PStructuredGrid WholeExtent=\"0 " << infop.mx-1 << " 0 " << infop.my-1 << " 0 0\" GhostLevel=\"0\">"; pvts << "<PPoints>" << endl; pvts << "<PDataArray type=\"Float32\" Name=\"Points\" NumberOfComponents=\"3\"/>" << endl; pvts << "</PPoints>" << endl; pvts << "<PPointData Scalars=\"pressure\">" << endl; pvts << "<PDataArray type=\"Float64\" Name=\"pressure\"/>" << endl; pvts << "</PPointData>" << endl; pvts << "<PCells>" << endl; pvts << "</PCells>" << endl; // Attention!! ajout d'un point apres source pour aller dans le repertoire .. // changer les arguments d'entree en dir et filename for(int i=0; i<size; i++){ pvts << "<Piece Extent=\"" << x[i] << " " << x[i]+sx[i]-1 ; pvts << " " << y[i] << " " << y[i]+sy[i]-1 << " "; pvts << " 0 0\" Source=\"./" << filename << "_pressure_" << i << ".vts\"/>" << endl; } pvts << "</PStructuredGrid>" << endl; pvts << "</VTKFile>" << endl; pvts.close(); } MPI_Gather(&infou.gxs, 1, MPI_INT, x, 1, MPI_INT, 0, PETSC_COMM_WORLD); MPI_Gather(&infou.gxm, 1, MPI_INT, sx, 1, MPI_INT, 0, PETSC_COMM_WORLD); MPI_Gather(&infou.gys, 1, MPI_INT, y, 1, MPI_INT, 0, PETSC_COMM_WORLD); MPI_Gather(&infou.gym, 1, MPI_INT, sy, 1, MPI_INT, 0, PETSC_COMM_WORLD); MPI_Gather(&infou.gzs, 1, MPI_INT, z, 1, MPI_INT, 0, PETSC_COMM_WORLD); MPI_Gather(&infou.gzm, 1, MPI_INT, sz, 1, MPI_INT, 0, PETSC_COMM_WORLD); if (rank == 0){ std::stringstream oall; oall << path << "/" << filename << "_velocity.pvts"; ofstream pvts; pvts.open(oall.str().data(), ios::out | ios::trunc); pvts << "<?xml version=\"1.0\"?>" << endl; pvts << "<VTKFile type=\"PStructuredGrid\" version=\"0.1\" byte_order=\"LittleEndian\" compressor=\"vtkZLibDataCompressor\">" << endl; pvts << "<PStructuredGrid WholeExtent=\"0 " << infou.mx-1 << " 0 " << infou.my-1 << " 0 0\" GhostLevel=\"0\">"; pvts << "<PPoints>" << endl; pvts << "<PDataArray type=\"Float32\" Name=\"Points\" NumberOfComponents=\"3\"/>" << endl; pvts << "</PPoints>" << endl; pvts << "<PPointData Vectors=\"velocity\">" << endl; pvts << "<PDataArray type=\"Float64\" Name=\"velocity\" NumberOfComponents=\"3\"/>" << endl; pvts << "</PPointData>" << endl; pvts << "<PCells>" << endl; pvts << "</PCells>" << endl; // Attention!! ajout d'un point apres source pour aller dans le repertoire .. // changer les arguments d'entree en dir et filename for(int i=0; i<size; i++){ pvts << "<Piece Extent=\"" << x[i] << " " << x[i]+sx[i]-1; pvts << " " << y[i] << " " << y[i]+sy[i]-1 << " "; pvts << " 0 0\" Source=\"./" << filename << "_velocity_" << i << ".vts\"/>" << endl; } pvts << "</PStructuredGrid>" << endl; pvts << "</VTKFile>" << endl; pvts.close(); } pressurePoints->Delete(); velocityPoints->Delete(); velocity->Delete(); pressure->Delete(); pressureDataSet->Delete(); velocityDataSet->Delete(); pressureDataWriter->Delete(); velocityDataWriter->Delete(); ierr = DMDAVecRestoreArray(dau, locsolu, &psolu);CHKERRQ(ierr); ierr = DMDAVecRestoreArray(dap, locsolp, &psolp);CHKERRQ(ierr); ierr = DMRestoreLocalVector(dau, &locsolu);CHKERRQ(ierr); ierr = DMRestoreLocalVector(dap, &locsolp);CHKERRQ(ierr); ierr = DMCompositeRestoreAccess(dm,sol,&solu,&solp);CHKERRQ(ierr); PetscFunctionReturn(0); }
int main(int argc, char *argv[]) { PetscErrorCode ierr; DM dau,dak,pack; const PetscInt *lxu; PetscInt *lxk,m,sizes; User user; SNES snes; Vec X,F,Xu,Xk,Fu,Fk; Mat B; IS *isg; PetscBool view_draw,pass_dm; PetscInitialize(&argc,&argv,0,help); ierr = DMDACreate1d(PETSC_COMM_WORLD,DM_BOUNDARY_NONE,-10,1,1,NULL,&dau);CHKERRQ(ierr); ierr = DMSetOptionsPrefix(dau,"u_");CHKERRQ(ierr); ierr = DMSetFromOptions(dau);CHKERRQ(ierr); ierr = DMDAGetOwnershipRanges(dau,&lxu,0,0);CHKERRQ(ierr); ierr = DMDAGetInfo(dau,0, &m,0,0, &sizes,0,0, 0,0,0,0,0,0);CHKERRQ(ierr); ierr = PetscMalloc1(sizes,&lxk);CHKERRQ(ierr); ierr = PetscMemcpy(lxk,lxu,sizes*sizeof(*lxk));CHKERRQ(ierr); lxk[0]--; ierr = DMDACreate1d(PETSC_COMM_WORLD,DM_BOUNDARY_NONE,m-1,1,1,lxk,&dak);CHKERRQ(ierr); ierr = DMSetOptionsPrefix(dak,"k_");CHKERRQ(ierr); ierr = DMSetFromOptions(dak);CHKERRQ(ierr); ierr = PetscFree(lxk);CHKERRQ(ierr); ierr = DMCompositeCreate(PETSC_COMM_WORLD,&pack);CHKERRQ(ierr); ierr = DMSetOptionsPrefix(pack,"pack_");CHKERRQ(ierr); ierr = DMCompositeAddDM(pack,dau);CHKERRQ(ierr); ierr = DMCompositeAddDM(pack,dak);CHKERRQ(ierr); ierr = DMDASetFieldName(dau,0,"u");CHKERRQ(ierr); ierr = DMDASetFieldName(dak,0,"k");CHKERRQ(ierr); ierr = DMSetFromOptions(pack);CHKERRQ(ierr); ierr = DMCreateGlobalVector(pack,&X);CHKERRQ(ierr); ierr = VecDuplicate(X,&F);CHKERRQ(ierr); ierr = PetscNew(&user);CHKERRQ(ierr); user->pack = pack; ierr = DMCompositeGetGlobalISs(pack,&isg);CHKERRQ(ierr); ierr = DMCompositeGetLocalVectors(pack,&user->Uloc,&user->Kloc);CHKERRQ(ierr); ierr = DMCompositeScatter(pack,X,user->Uloc,user->Kloc);CHKERRQ(ierr); ierr = PetscOptionsBegin(PETSC_COMM_WORLD,NULL,"Coupled problem options","SNES");CHKERRQ(ierr); { user->ptype = 0; view_draw = PETSC_FALSE; pass_dm = PETSC_TRUE; ierr = PetscOptionsInt("-problem_type","0: solve for u only, 1: solve for k only, 2: solve for both",0,user->ptype,&user->ptype,NULL);CHKERRQ(ierr); ierr = PetscOptionsBool("-view_draw","Draw the final coupled solution regardless of whether only one physics was solved",0,view_draw,&view_draw,NULL);CHKERRQ(ierr); ierr = PetscOptionsBool("-pass_dm","Pass the packed DM to SNES to use when determining splits and forward into splits",0,pass_dm,&pass_dm,NULL);CHKERRQ(ierr); } ierr = PetscOptionsEnd();CHKERRQ(ierr); ierr = FormInitial_Coupled(user,X);CHKERRQ(ierr); ierr = SNESCreate(PETSC_COMM_WORLD,&snes);CHKERRQ(ierr); switch (user->ptype) { case 0: ierr = DMCompositeGetAccess(pack,X,&Xu,0);CHKERRQ(ierr); ierr = DMCompositeGetAccess(pack,F,&Fu,0);CHKERRQ(ierr); ierr = DMCreateMatrix(dau,&B);CHKERRQ(ierr); ierr = SNESSetFunction(snes,Fu,FormFunction_All,user);CHKERRQ(ierr); ierr = SNESSetJacobian(snes,B,B,FormJacobian_All,user);CHKERRQ(ierr); ierr = SNESSetFromOptions(snes);CHKERRQ(ierr); ierr = SNESSetDM(snes,dau);CHKERRQ(ierr); ierr = SNESSolve(snes,NULL,Xu);CHKERRQ(ierr); ierr = DMCompositeRestoreAccess(pack,X,&Xu,0);CHKERRQ(ierr); ierr = DMCompositeRestoreAccess(pack,F,&Fu,0);CHKERRQ(ierr); break; case 1: ierr = DMCompositeGetAccess(pack,X,0,&Xk);CHKERRQ(ierr); ierr = DMCompositeGetAccess(pack,F,0,&Fk);CHKERRQ(ierr); ierr = DMCreateMatrix(dak,&B);CHKERRQ(ierr); ierr = SNESSetFunction(snes,Fk,FormFunction_All,user);CHKERRQ(ierr); ierr = SNESSetJacobian(snes,B,B,FormJacobian_All,user);CHKERRQ(ierr); ierr = SNESSetFromOptions(snes);CHKERRQ(ierr); ierr = SNESSetDM(snes,dak);CHKERRQ(ierr); ierr = SNESSolve(snes,NULL,Xk);CHKERRQ(ierr); ierr = DMCompositeRestoreAccess(pack,X,0,&Xk);CHKERRQ(ierr); ierr = DMCompositeRestoreAccess(pack,F,0,&Fk);CHKERRQ(ierr); break; case 2: ierr = DMCreateMatrix(pack,&B);CHKERRQ(ierr); /* This example does not correctly allocate off-diagonal blocks. These options allows new nonzeros (slow). */ ierr = MatSetOption(B,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr); ierr = MatSetOption(B,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr); ierr = SNESSetFunction(snes,F,FormFunction_All,user);CHKERRQ(ierr); ierr = SNESSetJacobian(snes,B,B,FormJacobian_All,user);CHKERRQ(ierr); ierr = SNESSetFromOptions(snes);CHKERRQ(ierr); if (!pass_dm) { /* Manually provide index sets and names for the splits */ KSP ksp; PC pc; ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); ierr = KSPGetPC(ksp,&pc);CHKERRQ(ierr); ierr = PCFieldSplitSetIS(pc,"u",isg[0]);CHKERRQ(ierr); ierr = PCFieldSplitSetIS(pc,"k",isg[1]);CHKERRQ(ierr); } else { /* The same names come from the options prefix for dau and dak. This option can support geometric multigrid inside * of splits, but it requires using a DM (perhaps your own implementation). */ ierr = SNESSetDM(snes,pack);CHKERRQ(ierr); } ierr = SNESSolve(snes,NULL,X);CHKERRQ(ierr); break; } if (view_draw) {ierr = VecView(X,PETSC_VIEWER_DRAW_WORLD);CHKERRQ(ierr);} if (0) { PetscInt col = 0; PetscBool mult_dup = PETSC_FALSE,view_dup = PETSC_FALSE; Mat D; Vec Y; ierr = PetscOptionsGetInt(0,"-col",&col,0);CHKERRQ(ierr); ierr = PetscOptionsGetBool(0,"-mult_dup",&mult_dup,0);CHKERRQ(ierr); ierr = PetscOptionsGetBool(0,"-view_dup",&view_dup,0);CHKERRQ(ierr); ierr = VecDuplicate(X,&Y);CHKERRQ(ierr); /* ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); */ /* ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); */ ierr = MatConvert(B,MATAIJ,MAT_INITIAL_MATRIX,&D);CHKERRQ(ierr); ierr = VecZeroEntries(X);CHKERRQ(ierr); ierr = VecSetValue(X,col,1.0,INSERT_VALUES);CHKERRQ(ierr); ierr = VecAssemblyBegin(X);CHKERRQ(ierr); ierr = VecAssemblyEnd(X);CHKERRQ(ierr); ierr = MatMult(mult_dup ? D : B,X,Y);CHKERRQ(ierr); ierr = MatView(view_dup ? D : B,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); /* ierr = VecView(X,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); */ ierr = VecView(Y,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); ierr = MatDestroy(&D);CHKERRQ(ierr); ierr = VecDestroy(&Y);CHKERRQ(ierr); } ierr = DMCompositeRestoreLocalVectors(pack,&user->Uloc,&user->Kloc);CHKERRQ(ierr); ierr = PetscFree(user);CHKERRQ(ierr); ierr = ISDestroy(&isg[0]);CHKERRQ(ierr); ierr = ISDestroy(&isg[1]);CHKERRQ(ierr); ierr = PetscFree(isg);CHKERRQ(ierr); ierr = VecDestroy(&X);CHKERRQ(ierr); ierr = VecDestroy(&F);CHKERRQ(ierr); ierr = MatDestroy(&B);CHKERRQ(ierr); ierr = DMDestroy(&dau);CHKERRQ(ierr); ierr = DMDestroy(&dak);CHKERRQ(ierr); ierr = DMDestroy(&pack);CHKERRQ(ierr); ierr = SNESDestroy(&snes);CHKERRQ(ierr); PetscFinalize(); return 0; }
/* Here is my custom preconditioner Capital vectors: X, X1 are global vectors Small vectors: x, x1 are local ghosted vectors Prefixed a: ax1, aY1 are arrays that access the vector values (either local (ax1) or global aY1) */ PetscErrorCode MyPCApply(PC pc,Vec X,Vec Y) { AppCtx *app; PetscErrorCode ierr; Vec X1,X2,X3,x1,x2,Y1,Y2,Y3; DALocalInfo info1,info2,info3; DA da1,da2,da3; PetscInt i,j; FluidField *ax1,*aY1; PetscScalar **ax2,**aY2; PetscFunctionBegin; ierr = PCShellGetContext(pc,(void**)&app); CHKERRQ(ierr); /* obtain information about the three meshes */ ierr = DMCompositeGetEntries(app->pack,&da1,&da2,&da3); CHKERRQ(ierr); ierr = DAGetLocalInfo(da1,&info1); CHKERRQ(ierr); ierr = DAGetLocalInfo(da2,&info2); CHKERRQ(ierr); ierr = DAGetLocalInfo(da3,&info3); CHKERRQ(ierr); /* get ghosted version of fluid and thermal conduction, global for phi and C */ ierr = DMCompositeGetAccess(app->pack,X,&X1,&X2,&X3); CHKERRQ(ierr); ierr = DMCompositeGetLocalVectors(app->pack,&x1,&x2,PETSC_NULL); CHKERRQ(ierr); ierr = DAGlobalToLocalBegin(da1,X1,INSERT_VALUES,x1); CHKERRQ(ierr); ierr = DAGlobalToLocalEnd(da1,X1,INSERT_VALUES,x1); CHKERRQ(ierr); ierr = DAGlobalToLocalBegin(da2,X2,INSERT_VALUES,x2); CHKERRQ(ierr); ierr = DAGlobalToLocalEnd(da2,X2,INSERT_VALUES,x2); CHKERRQ(ierr); /* get global version of result vector */ ierr = DMCompositeGetAccess(app->pack,Y,&Y1,&Y2,&Y3); CHKERRQ(ierr); /* pull out the phi and C values */ ierr = VecStrideGather(X3,0,app->dx,INSERT_VALUES); CHKERRQ(ierr); ierr = VecStrideGather(X3,1,app->c,INSERT_VALUES); CHKERRQ(ierr); /* update C via formula 38; put back into return vector */ ierr = VecAXPY(app->c,0.0,app->dx); CHKERRQ(ierr); ierr = VecScale(app->c,1.0); CHKERRQ(ierr); ierr = VecStrideScatter(app->c,1,Y3,INSERT_VALUES); CHKERRQ(ierr); /* form the right hand side of the phi equation; solve system; put back into return vector */ ierr = VecAXPBY(app->dx,0.0,1.0,app->c); CHKERRQ(ierr); ierr = DMMGSolve(app->fdmmg); CHKERRQ(ierr); ierr = VecStrideScatter(app->dy,0,Y3,INSERT_VALUES); CHKERRQ(ierr); /* access the ghosted x1 and x2 as arrays */ ierr = DAVecGetArray(da1,x1,&ax1); CHKERRQ(ierr); ierr = DAVecGetArray(da2,x2,&ax2); CHKERRQ(ierr); /* access global y1 and y2 as arrays */ ierr = DAVecGetArray(da1,Y1,&aY1); CHKERRQ(ierr); ierr = DAVecGetArray(da2,Y2,&aY2); CHKERRQ(ierr); for (i=info1.xs; i<info1.xs+info1.xm; i++) { aY1[i].prss = ax1[i].prss; aY1[i].ergg = ax1[i].ergg; aY1[i].ergf = ax1[i].ergf; aY1[i].alfg = ax1[i].alfg; aY1[i].velg = ax1[i].velg; aY1[i].velf = ax1[i].velf; } for (j=info2.ys; j<info2.ys+info2.ym; j++) { for (i=info2.xs; i<info2.xs+info2.xm; i++) { aY2[j][i] = ax2[j][i]; } } ierr = DAVecRestoreArray(da1,x1,&ax1); CHKERRQ(ierr); ierr = DAVecRestoreArray(da2,x2,&ax2); CHKERRQ(ierr); ierr = DAVecRestoreArray(da1,Y1,&aY1); CHKERRQ(ierr); ierr = DAVecRestoreArray(da2,Y2,&aY2); CHKERRQ(ierr); ierr = DMCompositeRestoreLocalVectors(app->pack,&x1,&x2,PETSC_NULL); CHKERRQ(ierr); ierr = DMCompositeRestoreAccess(app->pack,X,&X1,&X2,&X3); CHKERRQ(ierr); ierr = DMCompositeRestoreAccess(app->pack,Y,&Y1,&Y2,&Y3); CHKERRQ(ierr); PetscFunctionReturn(0); }
/* FormFunction - Unwraps the input vector and passes its local ghosted pieces into the user function */ PetscErrorCode FormFunction(SNES snes,Vec X,Vec F,void *ctx) { DMMG dmmg = (DMMG)ctx; DMComposite dm = (DMComposite)dmmg->dm; DALocalInfo info1,info2,info3; DA da1,da2,da3; FluidField *x1,*f1; PetscScalar **x2,**f2; FuelField **x3,**f3; Vec X1,X2,X3,F1,F2,F3; PetscErrorCode ierr; PetscInt i,j; AppCtx *app = (AppCtx*)dmmg->user; PetscFunctionBegin; ierr = DMCompositeGetEntries(dm,&da1,&da2,&da3); CHKERRQ(ierr); ierr = DAGetLocalInfo(da1,&info1); CHKERRQ(ierr); ierr = DAGetLocalInfo(da2,&info2); CHKERRQ(ierr); ierr = DAGetLocalInfo(da3,&info3); CHKERRQ(ierr); /* Get local vectors to hold ghosted parts of X; then fill in the ghosted vectors from the unghosted global vector X */ ierr = DMCompositeGetLocalVectors(dm,&X1,&X2,&X3); CHKERRQ(ierr); ierr = DMCompositeScatter(dm,X,X1,X2,X3); CHKERRQ(ierr); /* Access the arrays inside the subvectors of X */ ierr = DAVecGetArray(da1,X1,(void**)&x1); CHKERRQ(ierr); ierr = DAVecGetArray(da2,X2,(void**)&x2); CHKERRQ(ierr); ierr = DAVecGetArray(da3,X3,(void**)&x3); CHKERRQ(ierr); /* Ghost points for periodicity are used to "force" inflow/outflow fluid boundary conditions Note that there is no periodicity; we define periodicity to "cheat" and have ghost spaces to store "exterior to boundary" values */ /* FLUID */ if (info1.gxs == -3) { /* 3 points at left end of line */ for (i=-3; i<0; i++) { x1[i].prss = app->prin; x1[i].ergg = app->ugin; x1[i].ergf = app->ufin; x1[i].alfg = app->agin; x1[i].velg = app->vgin; x1[i].velf = app->vfin; } } if (info1.gxs+info1.gxm == info1.mx+3) { /* 3 points at right end of line */ for (i=info1.mx; i<info1.mx+3; i++) { x1[i].prss = app->prout; x1[i].ergg = app->ugout; x1[i].ergf = app->ufout; x1[i].alfg = app->agout; x1[i].velg = app->vgi; x1[i].velf = app->vfi; } } /* Thermal */ if (info2.gxs == -1) { /* left side of domain */ for (j=info2.gys; j<info2.gys+info2.gym; j++) { x2[j][-1] = app->twi; } } if (info2.gxs+info2.gxm == info2.mx+1) { /* right side of domain */ for (j=info2.gys; j<info2.gys+info2.gym; j++) { x2[j][info2.mx] = app->twi; } } /* FUEL */ if (info3.gxs == -1) { /* left side of domain */ for (j=info3.gys; j<info3.gys+info3.gym; j++) { x3[j][-1].phii = app->phii; x3[j][-1].prei = app->prei; } } if (info3.gxs+info3.gxm == info3.mx+1) { /* right side of domain */ for (j=info3.gys; j<info3.gys+info3.gym; j++) { x3[j][info3.mx].phii = app->phii; x3[j][info3.mx].prei = app->prei; } } if (info3.gys == -1) { /* bottom of domain */ for (i=info3.gxs; i<info3.gxs+info3.gxm; i++) { x3[-1][i].phii = app->phii; x3[-1][i].prei = app->prei; } } if (info3.gys+info3.gym == info3.my+1) { /* top of domain */ for (i=info3.gxs; i<info3.gxs+info3.gxm; i++) { x3[info3.my][i].phii = app->phii; x3[info3.my][i].prei = app->prei; } } /* Access the three subvectors in F: these are not ghosted and directly access the memory locations in F */ ierr = DMCompositeGetAccess(dm,F,&F1,&F2,&F3); CHKERRQ(ierr); /* Access the arrays inside the subvectors of F */ ierr = DAVecGetArray(da1,F1,(void**)&f1); CHKERRQ(ierr); ierr = DAVecGetArray(da2,F2,(void**)&f2); CHKERRQ(ierr); ierr = DAVecGetArray(da3,F3,(void**)&f3); CHKERRQ(ierr); /* Evaluate local user provided function */ ierr = FormFunctionLocalFluid(&info1,x1,f1); CHKERRQ(ierr); ierr = FormFunctionLocalThermal(&info2,x2,f2); CHKERRQ(ierr); ierr = FormFunctionLocalFuel(&info3,x3,f3); CHKERRQ(ierr); ierr = DAVecRestoreArray(da1,X1,(void**)&x1); CHKERRQ(ierr); ierr = DAVecRestoreArray(da2,X2,(void**)&x2); CHKERRQ(ierr); ierr = DAVecRestoreArray(da3,X3,(void**)&x3); CHKERRQ(ierr); ierr = DMCompositeRestoreLocalVectors(dm,&X1,&X2,&X3); CHKERRQ(ierr); ierr = DAVecRestoreArray(da1,F1,(void**)&f1); CHKERRQ(ierr); ierr = DAVecRestoreArray(da2,F2,(void**)&f2); CHKERRQ(ierr); ierr = DAVecRestoreArray(da3,F3,(void**)&f3); CHKERRQ(ierr); ierr = DMCompositeRestoreAccess(dm,F,&F1,&F2,&F3); CHKERRQ(ierr); PetscFunctionReturn(0); }
#include "../src/sys/f90-src/f90impl.h" #include "petscda.h" #if defined(PETSC_HAVE_FORTRAN_CAPS) #define dmcompositegetaccessvpvp_ DMCOMPOSITEGETACCESSVPVP #define dmcompositerestoreaccessvpvp_ DMCOMPOSITERESTOREACCESSVPVP #elif !defined(PETSC_HAVE_FORTRAN_UNDERSCORE) #define dmcompositegetaccessvpvp_ dmcompositegetaccessvpvp #define dmcompositerestoreaccessvpvp_ dmcompositerestoreaccessvpvp #endif EXTERN_C_BEGIN void PETSC_STDCALL dmcompositegetaccessvpvp_(DMComposite *dm,Vec *v,Vec *v1,F90Array1d *p1,Vec *v2,F90Array1d *p2,PetscErrorCode *ierr PETSC_F90_2PTR_PROTO(ptrd1) PETSC_F90_2PTR_PROTO(ptrd2)) { PetscScalar *pp1,*pp2; PetscInt np1,np2; *ierr = DMCompositeGetEntries(*dm,0,&np1,0,&np2); *ierr = DMCompositeGetAccess(*dm,*v,v1,&pp1,v2,&pp2); *ierr = F90Array1dCreate(pp1,PETSC_SCALAR,0,np1-1,p1 PETSC_F90_2PTR_PARAM(ptrd1)); *ierr = F90Array1dCreate(pp2,PETSC_SCALAR,0,np2-1,p2 PETSC_F90_2PTR_PARAM(ptrd2)); } void PETSC_STDCALL dmcompositerestoreaccessvpvp_(DMComposite *dm,Vec *v,Vec *v1,F90Array1d *p1,Vec *v2,F90Array1d *p2,PetscErrorCode *ierr PETSC_F90_2PTR_PROTO(ptrd1) PETSC_F90_2PTR_PROTO(ptrd2)) { *ierr = DMCompositeRestoreAccess(*dm,*v,v1,0,v2,0); *ierr = F90Array1dDestroy(p1,PETSC_SCALAR PETSC_F90_2PTR_PARAM(ptrd1)); *ierr = F90Array1dDestroy(p2,PETSC_SCALAR PETSC_F90_2PTR_PARAM(ptrd2)); } EXTERN_C_END