static PetscErrorCode AddDRDY(PetscReal t,Vec X,Vec *drdy,Userctx *user) { PetscErrorCode ierr; Vec Xgen,Xnet,Dgen,Dnet; PetscScalar *xnet,*dnet,*proj_vec; PetscInt obs_len,i,idx; PetscReal step_num, aux1, aux2; PetscScalar *mat; PetscFunctionBegin; //printf("AddDRDY lambda\n"); //ierr = VecView(*drdy, PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); ierr = DMCompositeGetLocalVectors(user->dmpgrid,&Xgen,&Xnet);CHKERRQ(ierr); ierr = DMCompositeGetLocalVectors(user->dmpgrid,&Dgen,&Dnet);CHKERRQ(ierr); ierr = DMCompositeScatter(user->dmpgrid,X,Xgen,Xnet);CHKERRQ(ierr); ierr = DMCompositeScatter(user->dmpgrid,*drdy,Dgen,Dnet);CHKERRQ(ierr); ierr = VecGetArray(Xnet,&xnet);CHKERRQ(ierr); ierr = VecGetArray(Dnet,&dnet);CHKERRQ(ierr); ierr = VecGetArray(user->proj,&proj_vec);CHKERRQ(ierr); ierr = VecGetSize(user->proj, &obs_len);CHKERRQ(ierr); //!step_num = round((t-user->tdisturb) / user->data_dt); step_num = round((t-user->trestore) / user->data_dt); idx = 2*obs_len* (PetscInt)step_num; ierr = MatDenseGetArray(user->obs,&mat);CHKERRQ(ierr); for(i=0;i<obs_len; i++) { //printf("B^Tnoisecovinv(B x -d):t=%g index=%d proj_len=%d proj[i] = %d \n", t, idx, obs_len, (int)proj_vec[i]); aux1 = (xnet[2*((int)proj_vec[i])] - mat[idx+2*i]) / pow(user->data_stddev[i],2); // obs[2*i, num_obs] dnet[2*((int)proj_vec[i])] += aux1; aux2 = (xnet[2*((int)proj_vec[i])+1] - mat[idx+2*i+1]) / pow(user->data_stddev[i+1],2);// obs[2*i+1, num_obs] dnet[2*((int)proj_vec[i])+1] += aux2; //printf("IC Adjoint: t=%g [%g] [%g]\n", t, aux1, aux2); } ierr = MatDenseRestoreArray(user->obs,&mat);CHKERRQ(ierr); ierr = VecRestoreArray(user->proj,&proj_vec);CHKERRQ(ierr); ierr = VecRestoreArray(Dnet,&dnet);CHKERRQ(ierr); ierr = DMCompositeGather(user->dmpgrid,*drdy,INSERT_VALUES,Dgen,Dnet);CHKERRQ(ierr); ierr = DMCompositeRestoreLocalVectors(user->dmpgrid,&Dgen,&Dnet);CHKERRQ(ierr); ierr = DMCompositeRestoreLocalVectors(user->dmpgrid,&Xgen,&Xnet);CHKERRQ(ierr); //printf("AddDRDY lambda at the end\n"); //ierr = VecView(*drdy, PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); PetscFunctionReturn(0); }
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); }
static PetscErrorCode CostIntegrand(TS ts,PetscReal t,Vec U,Vec R,Userctx *user) { PetscErrorCode ierr; PetscScalar *r; const PetscScalar *u; PetscInt idx; Vec Xgen,Xnet; PetscScalar *xgen; PetscInt i; PetscFunctionBegin; ierr = DMCompositeGetLocalVectors(user->dmpgrid,&Xgen,&Xnet);CHKERRQ(ierr); ierr = DMCompositeScatter(user->dmpgrid,U,Xgen,Xnet);CHKERRQ(ierr); ierr = VecGetArray(Xgen,&xgen);CHKERRQ(ierr); ierr = VecGetArrayRead(U,&u);CHKERRQ(ierr); ierr = VecGetArray(R,&r);CHKERRQ(ierr); r[0] = 0.; idx = 0; for (i=0;i<ngen;i++) { r[0] += PetscPowScalarInt(PetscMax(0.,PetscMax(xgen[idx+3]/(2.*PETSC_PI)-user->freq_u,user->freq_l-xgen[idx+3]/(2.*PETSC_PI))),user->pow); idx += 9; } ierr = VecRestoreArray(R,&r);CHKERRQ(ierr); ierr = VecRestoreArrayRead(U,&u);CHKERRQ(ierr); ierr = DMCompositeRestoreLocalVectors(user->dmpgrid,&Xgen,&Xnet);CHKERRQ(ierr); PetscFunctionReturn(0); }
static PetscErrorCode RHSJacobianP(TS ts,PetscReal t,Vec X,Mat A,void *ctx0) { PetscErrorCode ierr; PetscScalar a; PetscInt row,col; Userctx *ctx=(Userctx*)ctx0; PetscInt idx=0; Vec Xgen,Xnet; PetscScalar *xgen,*xnet; PetscScalar Eqp,Edp; PetscScalar Id,Iq; PetscFunctionBeginUser; /*if (ctx->jacp_flg) { delete me */ ierr = MatZeroEntries(A);CHKERRQ(ierr); //recompute since this changes M[0] = 2*H[0]/w_s; M[1] = 2*H[1]/w_s; M[2] = 2*H[2]/w_s; D[0] = 0.1*M[0]; D[1] = 0.1*M[1]; D[2] = 0.1*M[2]; ierr = DMCompositeGetLocalVectors(ctx->dmpgrid,&Xgen,&Xnet);CHKERRQ(ierr); ierr = DMCompositeScatter(ctx->dmpgrid,X,Xgen,Xnet);CHKERRQ(ierr); /* Generator subsystem initialization */ ierr = VecGetArray(Xgen,&xgen);CHKERRQ(ierr); ierr = VecGetArray(Xnet,&xnet);CHKERRQ(ierr); for (col=0;col<ngen;col++) { Eqp = xgen[idx]; Edp = xgen[idx+1]; Id = xgen[idx+4]; Iq = xgen[idx+5]; TM[col] = PG[col]; a = -1.0 *(TM[col] - Edp*Id - Eqp*Iq - (Xqp[col]-Xdp[col])*Id*Iq)/M[col]/H[col]; row = 9*col+3; // E is in the 4th equation hence +3 idx = idx + 9; //9 equations per generator, hence move to next gen ierr = MatSetValues(A,1,&row,1,&col,&a,INSERT_VALUES);CHKERRQ(ierr); } /* ctx->jacp_flg = PETSC_FALSE; delete me */ ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = VecRestoreArray(Xgen,&xgen);CHKERRQ(ierr); ierr = VecRestoreArray(Xnet,&xnet);CHKERRQ(ierr); ierr = DMCompositeGather(ctx->dmpgrid,X,INSERT_VALUES,Xgen,Xnet);CHKERRQ(ierr); ierr = DMCompositeRestoreLocalVectors(ctx->dmpgrid,&Xgen,&Xnet);CHKERRQ(ierr); //MatView(A,PETSC_VIEWER_STDOUT_SELF); /* }delete me */ PetscFunctionReturn(0); }
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); }
/* Evaluates FU = Gradiant(L(w,u,lambda)) */ PetscErrorCode FormFunction(SNES snes,Vec U,Vec FU,void *dummy) { UserCtx *user = (UserCtx*)dummy; PetscErrorCode ierr; PetscInt xs,xm,i,N; PetscScalar *u,*lambda,*w,*fu,*fw,*flambda,d,h; Vec vw,vu,vlambda,vfw,vfu,vflambda; PetscFunctionBeginUser; ierr = DMCompositeGetLocalVectors(user->packer,&vw,&vu,&vlambda);CHKERRQ(ierr); ierr = DMCompositeGetLocalVectors(user->packer,&vfw,&vfu,&vflambda);CHKERRQ(ierr); ierr = DMCompositeScatter(user->packer,U,vw,vu,vlambda);CHKERRQ(ierr); ierr = DMDAGetCorners(user->da1,&xs,NULL,NULL,&xm,NULL,NULL);CHKERRQ(ierr); ierr = DMDAGetInfo(user->da1,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(user->da1,vu,&u);CHKERRQ(ierr); ierr = DMDAVecGetArray(user->da1,vfu,&fu);CHKERRQ(ierr); ierr = DMDAVecGetArray(user->da1,vlambda,&lambda);CHKERRQ(ierr); ierr = DMDAVecGetArray(user->da1,vflambda,&flambda);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.*d*lambda[0]; } /* derivative of L() w.r.t. u */ for (i=xs; i<xs+xm; i++) { if (i == 0) flambda[0] = h*u[0] + 2.*d*lambda[0] - d*lambda[1]; else if (i == 1) flambda[1] = 2.*h*u[1] + 2.*d*lambda[1] - d*lambda[2]; else if (i == N-1) flambda[N-1] = h*u[N-1] + 2.*d*lambda[N-1] - d*lambda[N-2]; else if (i == N-2) flambda[N-2] = 2.*h*u[N-2] + 2.*d*lambda[N-2] - d*lambda[N-3]; else flambda[i] = 2.*h*u[i] - d*(lambda[i+1] - 2.0*lambda[i] + lambda[i-1]); } /* derivative of L() w.r.t. lambda */ for (i=xs; i<xs+xm; i++) { if (i == 0) fu[0] = 2.0*d*(u[0] - w[0]); else if (i == N-1) fu[N-1] = 2.0*d*u[N-1]; else fu[i] = -(d*(u[i+1] - 2.0*u[i] + u[i-1]) - 2.0*h); } ierr = VecRestoreArray(vw,&w);CHKERRQ(ierr); ierr = VecRestoreArray(vfw,&fw);CHKERRQ(ierr); ierr = DMDAVecRestoreArray(user->da1,vu,&u);CHKERRQ(ierr); ierr = DMDAVecRestoreArray(user->da1,vfu,&fu);CHKERRQ(ierr); ierr = DMDAVecRestoreArray(user->da1,vlambda,&lambda);CHKERRQ(ierr); ierr = DMDAVecRestoreArray(user->da1,vflambda,&flambda);CHKERRQ(ierr); ierr = DMCompositeGather(user->packer,FU,INSERT_VALUES,vfw,vfu,vflambda);CHKERRQ(ierr); ierr = DMCompositeRestoreLocalVectors(user->packer,&vw,&vu,&vlambda);CHKERRQ(ierr); ierr = DMCompositeRestoreLocalVectors(user->packer,&vfw,&vfu,&vflambda);CHKERRQ(ierr); PetscFunctionReturn(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 SetObservation(Userctx* user, PetscReal t, Vec X) { PetscErrorCode ierr; PetscInt idx,obs_len,i; PetscScalar *mat; Vec Xgen,Xnet; PetscScalar *xnet;//, *xgen; const PetscScalar *x; PetscScalar *proj_vec; PetscReal step_num; PetscFunctionBegin; /* observations are generated only after restore */ /* t = t - user->tdisturb;*/ t = t - user->trestore; if(t >= -1e-6*user->dt) { step_num = round(t / user->data_dt); if(fabs(step_num - t/user->data_dt)<= 1e-6*user->dt) { idx = (PetscInt) step_num; ierr = VecGetSize(user->proj, &obs_len);CHKERRQ(ierr); //printf("SetObservation: t=%g index=%d proj_len=%d \n", t, idx, obs_len); idx = idx*2*obs_len; ierr = MatDenseGetArray(user->obs,&mat);CHKERRQ(ierr); ierr = VecGetArrayRead(X,&x);CHKERRQ(ierr); ierr = VecGetArray(user->proj, &proj_vec);CHKERRQ(ierr); ierr = DMCompositeGetLocalVectors(user->dmpgrid,&Xgen,&Xnet);CHKERRQ(ierr); ierr = DMCompositeScatter(user->dmpgrid,X,Xgen,Xnet);CHKERRQ(ierr); ierr = VecGetArray(Xnet,&xnet);CHKERRQ(ierr); //get pointer to xnet and to user->proj for(i=0;i<obs_len; i++) { //printf("proj[%d]=%d\n", i, (int)proj_vec[i]); *(mat+idx+2*i) = xnet[2*((int)proj_vec[i])]; *(mat+idx+2*i+1) = xnet[2*((int)proj_vec[i])+1]; } //printf("%g \n", xnet[0]); ierr = MatDenseRestoreArray(user->obs,&mat);CHKERRQ(ierr); ierr = VecRestoreArrayRead(X,&x);CHKERRQ(ierr); ierr = VecRestoreArray(user->proj,&proj_vec);CHKERRQ(ierr); ierr = VecRestoreArray(Xnet,&xnet);CHKERRQ(ierr); ierr = DMCompositeRestoreLocalVectors(user->dmpgrid,&Xgen,&Xnet);CHKERRQ(ierr); } } PetscFunctionReturn(0); }
PetscErrorCode EvalMisfit(TS ts) { PetscErrorCode ierr; Userctx *user; Vec X; PetscReal t; Vec Xgen,Xnet; PetscScalar *xnet, *proj_vec; PetscInt obs_len,i,idx; PetscReal step_num; PetscScalar *mat; PetscFunctionBegin; ierr = TSGetApplicationContext(ts,&user);CHKERRQ(ierr); ierr = TSGetTime(ts,&t);CHKERRQ(ierr); ierr = TSGetSolution(ts,&X);CHKERRQ(ierr); //!t = t - user->tdisturb; t = t - user->trestore; step_num = round(t / user->data_dt); if(fabs(step_num - t/user->data_dt)<= 1e-6*user->dt) { ierr = VecGetArray(user->proj,&proj_vec);CHKERRQ(ierr); ierr = VecGetSize(user->proj, &obs_len);CHKERRQ(ierr); idx = 2*obs_len*(PetscInt) step_num; ierr = DMCompositeGetLocalVectors(user->dmpgrid,&Xgen,&Xnet);CHKERRQ(ierr); ierr = DMCompositeScatter(user->dmpgrid,X,Xgen,Xnet);CHKERRQ(ierr); ierr = VecGetArray(Xnet,&xnet);CHKERRQ(ierr); ierr = MatDenseGetArray(user->obs,&mat);CHKERRQ(ierr); for(i=0;i<obs_len; i++) { user->misfit += 0.5*pow(xnet[2*((int)proj_vec[i])] - mat[idx+2*i], 2) / pow(user->data_stddev[i], 2); // obs[2*i, num_obs] user->misfit += 0.5*pow(xnet[2*((int)proj_vec[i])+1] - mat[idx+2*i+1],2) / pow(user->data_stddev[i+1], 2);// obs[2*i+1, num_obs] } //printf("evm %g %g idx=%d\n", xnet[0], mat[idx], idx); ierr = MatDenseRestoreArray(user->obs,&mat);CHKERRQ(ierr); ierr = VecRestoreArray(Xnet,&xnet);CHKERRQ(ierr); ierr = DMCompositeRestoreLocalVectors(user->dmpgrid,&Xgen,&Xnet);CHKERRQ(ierr); ierr = VecRestoreArray(user->proj,&proj_vec);CHKERRQ(ierr); } user->stepnum++; 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); }
PetscErrorCode SetSolution(Userctx* user, PetscReal t, Vec X) { PetscErrorCode ierr; PetscScalar *xgen,*xnet,*mat; PetscInt idx, len_xgen, len_xnet; Vec Xgen, Xnet; PetscFunctionBegin; if(user->saveSol) { //printf("SaveSol at t=%g\n", t); ierr = DMCompositeGetLocalVectors(user->dmpgrid,&Xgen,&Xnet);CHKERRQ(ierr); ierr = DMCompositeScatter(user->dmpgrid,X,Xgen,Xnet);CHKERRQ(ierr); ierr = VecGetSize(Xgen, &len_xgen);CHKERRQ(ierr); ierr = VecGetSize(Xnet, &len_xnet);CHKERRQ(ierr); ierr = VecGetArray(Xgen,&xgen);CHKERRQ(ierr); ierr = VecGetArray(Xnet,&xnet);CHKERRQ(ierr); idx = ((PetscInt) round(t / user->dt))*(user->neqs_pgrid+1); ierr = MatDenseGetArray(user->Sol,&mat);CHKERRQ(ierr); mat[idx] = t; ierr = PetscMemcpy(mat+idx+1, xgen,len_xgen*sizeof(PetscScalar));CHKERRQ(ierr); ierr = PetscMemcpy(mat+idx+1+len_xgen,xnet,len_xnet*sizeof(PetscScalar));CHKERRQ(ierr); ierr = MatDenseRestoreArray(user->Sol,&mat);CHKERRQ(ierr); ierr = VecRestoreArray(Xgen,&xgen);CHKERRQ(ierr); ierr = VecRestoreArray(Xnet,&xnet);CHKERRQ(ierr); ierr = DMCompositeRestoreLocalVectors(user->dmpgrid,&Xgen,&Xnet);CHKERRQ(ierr); } PetscFunctionReturn(0); }
static PetscErrorCode FormJacobian_All(SNES snes,Vec X,Mat J,Mat B,void *ctx) { User user = (User)ctx; DM dau,dak; DMDALocalInfo infou,infok; PetscScalar *u,*k; PetscErrorCode ierr; Vec Uloc,Kloc; 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 = FormJacobianLocal_U(user,&infou,u,k,B);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 = FormJacobianLocal_K(user,&infok,u,k,B);CHKERRQ(ierr); ierr = DMDAVecRestoreArray(dau,user->Uloc,&u);CHKERRQ(ierr); ierr = DMDAVecRestoreArray(dak,Kloc,&k);CHKERRQ(ierr); break; case 2: { Mat Buu,Buk,Bku,Bkk; IS *is; ierr = DMCompositeScatter(user->pack,X,Uloc,Kloc);CHKERRQ(ierr); ierr = DMDAVecGetArray(dau,Uloc,&u);CHKERRQ(ierr); ierr = DMDAVecGetArray(dak,Kloc,&k);CHKERRQ(ierr); ierr = DMCompositeGetLocalISs(user->pack,&is);CHKERRQ(ierr); ierr = MatGetLocalSubMatrix(B,is[0],is[0],&Buu);CHKERRQ(ierr); ierr = MatGetLocalSubMatrix(B,is[0],is[1],&Buk);CHKERRQ(ierr); ierr = MatGetLocalSubMatrix(B,is[1],is[0],&Bku);CHKERRQ(ierr); ierr = MatGetLocalSubMatrix(B,is[1],is[1],&Bkk);CHKERRQ(ierr); ierr = FormJacobianLocal_U(user,&infou,u,k,Buu);CHKERRQ(ierr); ierr = FormJacobianLocal_UK(user,&infou,&infok,u,k,Buk);CHKERRQ(ierr); ierr = FormJacobianLocal_KU(user,&infou,&infok,u,k,Bku);CHKERRQ(ierr); ierr = FormJacobianLocal_K(user,&infok,u,k,Bkk);CHKERRQ(ierr); ierr = MatRestoreLocalSubMatrix(B,is[0],is[0],&Buu);CHKERRQ(ierr); ierr = MatRestoreLocalSubMatrix(B,is[0],is[1],&Buk);CHKERRQ(ierr); ierr = MatRestoreLocalSubMatrix(B,is[1],is[0],&Bku);CHKERRQ(ierr); ierr = MatRestoreLocalSubMatrix(B,is[1],is[1],&Bkk);CHKERRQ(ierr); ierr = DMDAVecRestoreArray(dau,Uloc,&u);CHKERRQ(ierr); ierr = DMDAVecRestoreArray(dak,Kloc,&k);CHKERRQ(ierr); ierr = ISDestroy(&is[0]);CHKERRQ(ierr); ierr = ISDestroy(&is[1]);CHKERRQ(ierr); ierr = PetscFree(is);CHKERRQ(ierr); } break; } ierr = DMCompositeRestoreLocalVectors(user->pack,&Uloc,&Kloc);CHKERRQ(ierr); ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd (B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); if (J != B) { ierr = MatAssemblyBegin(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd (J,MAT_FINAL_ASSEMBLY);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); }
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; }
PetscErrorCode ResidualJacobian(SNES snes,Vec X,Mat J,Mat B,void *ctx) { PetscErrorCode ierr; Userctx *user=(Userctx*)ctx; Vec Xgen,Xnet; PetscScalar *xgen,*xnet; PetscInt i,idx=0; PetscScalar Vr,Vi,Vm,Vm2; PetscScalar Eqp,Edp,delta; /* Generator variables */ PetscScalar Efd; /* Exciter variables */ PetscScalar Id,Iq; /* Generator dq axis currents */ PetscScalar Vd,Vq; PetscScalar val[10]; PetscInt row[2],col[10]; PetscInt net_start=user->neqs_gen; PetscScalar Zdq_inv[4],det; PetscScalar dVd_dVr,dVd_dVi,dVq_dVr,dVq_dVi,dVd_ddelta,dVq_ddelta; PetscScalar dIGr_ddelta,dIGi_ddelta,dIGr_dId,dIGr_dIq,dIGi_dId,dIGi_dIq; PetscScalar dSE_dEfd; PetscScalar dVm_dVd,dVm_dVq,dVm_dVr,dVm_dVi; PetscInt ncols; const PetscInt *cols; const PetscScalar *yvals; PetscInt k; PetscScalar PD,QD,Vm0,*v0,Vm4; PetscScalar dPD_dVr,dPD_dVi,dQD_dVr,dQD_dVi; PetscScalar dIDr_dVr,dIDr_dVi,dIDi_dVr,dIDi_dVi; PetscFunctionBegin; ierr = MatZeroEntries(B);CHKERRQ(ierr); ierr = DMCompositeGetLocalVectors(user->dmpgrid,&Xgen,&Xnet);CHKERRQ(ierr); ierr = DMCompositeScatter(user->dmpgrid,X,Xgen,Xnet);CHKERRQ(ierr); ierr = VecGetArray(Xgen,&xgen);CHKERRQ(ierr); ierr = VecGetArray(Xnet,&xnet);CHKERRQ(ierr); /* Generator subsystem */ for (i=0; i < ngen; i++) { Eqp = xgen[idx]; Edp = xgen[idx+1]; delta = xgen[idx+2]; Id = xgen[idx+4]; Iq = xgen[idx+5]; Efd = xgen[idx+6]; /* fgen[idx] = (Eqp + (Xd[i] - Xdp[i])*Id - Efd)/Td0p[i]; */ row[0] = idx; col[0] = idx; col[1] = idx+4; col[2] = idx+6; val[0] = 1/ Td0p[i]; val[1] = (Xd[i] - Xdp[i])/ Td0p[i]; val[2] = -1/Td0p[i]; ierr = MatSetValues(J,1,row,3,col,val,INSERT_VALUES);CHKERRQ(ierr); /* fgen[idx+1] = (Edp - (Xq[i] - Xqp[i])*Iq)/Tq0p[i]; */ row[0] = idx + 1; col[0] = idx + 1; col[1] = idx+5; val[0] = 1/Tq0p[i]; val[1] = -(Xq[i] - Xqp[i])/Tq0p[i]; ierr = MatSetValues(J,1,row,2,col,val,INSERT_VALUES);CHKERRQ(ierr); /* fgen[idx+2] = - w + w_s; */ row[0] = idx + 2; col[0] = idx + 2; col[1] = idx + 3; val[0] = 0; val[1] = -1; ierr = MatSetValues(J,1,row,2,col,val,INSERT_VALUES);CHKERRQ(ierr); /* fgen[idx+3] = (-TM[i] + Edp*Id + Eqp*Iq + (Xqp[i] - Xdp[i])*Id*Iq + D[i]*(w - w_s))/M[i]; */ row[0] = idx + 3; col[0] = idx; col[1] = idx + 1; col[2] = idx + 3; col[3] = idx + 4; col[4] = idx + 5; val[0] = Iq/M[i]; val[1] = Id/M[i]; val[2] = D[i]/M[i]; val[3] = (Edp + (Xqp[i]-Xdp[i])*Iq)/M[i]; val[4] = (Eqp + (Xqp[i] - Xdp[i])*Id)/M[i]; ierr = MatSetValues(J,1,row,5,col,val,INSERT_VALUES);CHKERRQ(ierr); Vr = xnet[2*gbus[i]]; /* Real part of generator terminal voltage */ Vi = xnet[2*gbus[i]+1]; /* Imaginary part of the generator terminal voltage */ ierr = ri2dq(Vr,Vi,delta,&Vd,&Vq);CHKERRQ(ierr); det = Rs[i]*Rs[i] + Xdp[i]*Xqp[i]; Zdq_inv[0] = Rs[i]/det; Zdq_inv[1] = Xqp[i]/det; Zdq_inv[2] = -Xdp[i]/det; Zdq_inv[3] = Rs[i]/det; dVd_dVr = PetscSinScalar(delta); dVd_dVi = -PetscCosScalar(delta); dVq_dVr = PetscCosScalar(delta); dVq_dVi = PetscSinScalar(delta); dVd_ddelta = Vr*PetscCosScalar(delta) + Vi*PetscSinScalar(delta); dVq_ddelta = -Vr*PetscSinScalar(delta) + Vi*PetscCosScalar(delta); /* fgen[idx+4] = Zdq_inv[0]*(-Edp + Vd) + Zdq_inv[1]*(-Eqp + Vq) + Id; */ row[0] = idx+4; col[0] = idx; col[1] = idx+1; col[2] = idx + 2; val[0] = -Zdq_inv[1]; val[1] = -Zdq_inv[0]; val[2] = Zdq_inv[0]*dVd_ddelta + Zdq_inv[1]*dVq_ddelta; col[3] = idx + 4; col[4] = net_start+2*gbus[i]; col[5] = net_start + 2*gbus[i]+1; val[3] = 1; val[4] = Zdq_inv[0]*dVd_dVr + Zdq_inv[1]*dVq_dVr; val[5] = Zdq_inv[0]*dVd_dVi + Zdq_inv[1]*dVq_dVi; ierr = MatSetValues(J,1,row,6,col,val,INSERT_VALUES);CHKERRQ(ierr); /* fgen[idx+5] = Zdq_inv[2]*(-Edp + Vd) + Zdq_inv[3]*(-Eqp + Vq) + Iq; */ row[0] = idx+5; col[0] = idx; col[1] = idx+1; col[2] = idx + 2; val[0] = -Zdq_inv[3]; val[1] = -Zdq_inv[2]; val[2] = Zdq_inv[2]*dVd_ddelta + Zdq_inv[3]*dVq_ddelta; col[3] = idx + 5; col[4] = net_start+2*gbus[i]; col[5] = net_start + 2*gbus[i]+1; val[3] = 1; val[4] = Zdq_inv[2]*dVd_dVr + Zdq_inv[3]*dVq_dVr; val[5] = Zdq_inv[2]*dVd_dVi + Zdq_inv[3]*dVq_dVi; ierr = MatSetValues(J,1,row,6,col,val,INSERT_VALUES);CHKERRQ(ierr); dIGr_ddelta = Id*PetscCosScalar(delta) - Iq*PetscSinScalar(delta); dIGi_ddelta = Id*PetscSinScalar(delta) + Iq*PetscCosScalar(delta); dIGr_dId = PetscSinScalar(delta); dIGr_dIq = PetscCosScalar(delta); dIGi_dId = -PetscCosScalar(delta); dIGi_dIq = PetscSinScalar(delta); /* fnet[2*gbus[i]] -= IGi; */ row[0] = net_start + 2*gbus[i]; col[0] = idx+2; col[1] = idx + 4; col[2] = idx + 5; val[0] = -dIGi_ddelta; val[1] = -dIGi_dId; val[2] = -dIGi_dIq; ierr = MatSetValues(J,1,row,3,col,val,INSERT_VALUES);CHKERRQ(ierr); /* fnet[2*gbus[i]+1] -= IGr; */ row[0] = net_start + 2*gbus[i]+1; col[0] = idx+2; col[1] = idx + 4; col[2] = idx + 5; val[0] = -dIGr_ddelta; val[1] = -dIGr_dId; val[2] = -dIGr_dIq; ierr = MatSetValues(J,1,row,3,col,val,INSERT_VALUES);CHKERRQ(ierr); Vm = PetscSqrtScalar(Vd*Vd + Vq*Vq); Vm2 = Vm*Vm; /* fgen[idx+6] = (KE[i]*Efd + SE - VR)/TE[i]; */ /* SE = k1[i]*PetscExpScalar(k2[i]*Efd); */ dSE_dEfd = k1[i]*k2[i]*PetscExpScalar(k2[i]*Efd); row[0] = idx + 6; col[0] = idx + 6; col[1] = idx + 8; val[0] = (KE[i] + dSE_dEfd)/TE[i]; val[1] = -1/TE[i]; ierr = MatSetValues(J,1,row,2,col,val,INSERT_VALUES);CHKERRQ(ierr); /* Exciter differential equations */ /* fgen[idx+7] = (RF - KF[i]*Efd/TF[i])/TF[i]; */ row[0] = idx + 7; col[0] = idx + 6; col[1] = idx + 7; val[0] = (-KF[i]/TF[i])/TF[i]; val[1] = 1/TF[i]; ierr = MatSetValues(J,1,row,2,col,val,INSERT_VALUES);CHKERRQ(ierr); /* fgen[idx+8] = (VR - KA[i]*RF + KA[i]*KF[i]*Efd/TF[i] - KA[i]*(Vref[i] - Vm))/TA[i]; */ /* Vm = (Vd^2 + Vq^2)^0.5; */ dVm_dVd = Vd/Vm; dVm_dVq = Vq/Vm; dVm_dVr = dVm_dVd*dVd_dVr + dVm_dVq*dVq_dVr; dVm_dVi = dVm_dVd*dVd_dVi + dVm_dVq*dVq_dVi; row[0] = idx + 8; col[0] = idx + 6; col[1] = idx + 7; col[2] = idx + 8; val[0] = (KA[i]*KF[i]/TF[i])/TA[i]; val[1] = -KA[i]/TA[i]; val[2] = 1/TA[i]; col[3] = net_start + 2*gbus[i]; col[4] = net_start + 2*gbus[i]+1; val[3] = KA[i]*dVm_dVr/TA[i]; val[4] = KA[i]*dVm_dVi/TA[i]; ierr = MatSetValues(J,1,row,5,col,val,INSERT_VALUES);CHKERRQ(ierr); idx = idx + 9; } for (i=0; i<nbus; i++) { ierr = MatGetRow(user->Ybus,2*i,&ncols,&cols,&yvals);CHKERRQ(ierr); row[0] = net_start + 2*i; for (k=0; k<ncols; k++) { col[k] = net_start + cols[k]; val[k] = yvals[k]; } ierr = MatSetValues(J,1,row,ncols,col,val,INSERT_VALUES);CHKERRQ(ierr); ierr = MatRestoreRow(user->Ybus,2*i,&ncols,&cols,&yvals);CHKERRQ(ierr); ierr = MatGetRow(user->Ybus,2*i+1,&ncols,&cols,&yvals);CHKERRQ(ierr); row[0] = net_start + 2*i+1; for (k=0; k<ncols; k++) { col[k] = net_start + cols[k]; val[k] = yvals[k]; } ierr = MatSetValues(J,1,row,ncols,col,val,INSERT_VALUES);CHKERRQ(ierr); ierr = MatRestoreRow(user->Ybus,2*i+1,&ncols,&cols,&yvals);CHKERRQ(ierr); } ierr = MatAssemblyBegin(J,MAT_FLUSH_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(J,MAT_FLUSH_ASSEMBLY);CHKERRQ(ierr); ierr = VecGetArray(user->V0,&v0);CHKERRQ(ierr); for (i=0; i < nload; i++) { Vr = xnet[2*lbus[i]]; /* Real part of load bus voltage */ Vi = xnet[2*lbus[i]+1]; /* Imaginary part of the load bus voltage */ Vm = PetscSqrtScalar(Vr*Vr + Vi*Vi); Vm2 = Vm*Vm; Vm4 = Vm2*Vm2; Vm0 = PetscSqrtScalar(v0[2*lbus[i]]*v0[2*lbus[i]] + v0[2*lbus[i]+1]*v0[2*lbus[i]+1]); PD = QD = 0.0; dPD_dVr = dPD_dVi = dQD_dVr = dQD_dVi = 0.0; for (k=0; k < ld_nsegsp[i]; k++) { PD += ld_alphap[k]*PD0[i]*PetscPowScalar((Vm/Vm0),ld_betap[k]); dPD_dVr += ld_alphap[k]*ld_betap[k]*PD0[i]*PetscPowScalar((1/Vm0),ld_betap[k])*Vr*PetscPowScalar(Vm,(ld_betap[k]-2)); dPD_dVi += ld_alphap[k]*ld_betap[k]*PD0[i]*PetscPowScalar((1/Vm0),ld_betap[k])*Vi*PetscPowScalar(Vm,(ld_betap[k]-2)); } for (k=0; k < ld_nsegsq[i]; k++) { QD += ld_alphaq[k]*QD0[i]*PetscPowScalar((Vm/Vm0),ld_betaq[k]); dQD_dVr += ld_alphaq[k]*ld_betaq[k]*QD0[i]*PetscPowScalar((1/Vm0),ld_betaq[k])*Vr*PetscPowScalar(Vm,(ld_betaq[k]-2)); dQD_dVi += ld_alphaq[k]*ld_betaq[k]*QD0[i]*PetscPowScalar((1/Vm0),ld_betaq[k])*Vi*PetscPowScalar(Vm,(ld_betaq[k]-2)); } /* IDr = (PD*Vr + QD*Vi)/Vm2; */ /* IDi = (-QD*Vr + PD*Vi)/Vm2; */ dIDr_dVr = (dPD_dVr*Vr + dQD_dVr*Vi + PD)/Vm2 - ((PD*Vr + QD*Vi)*2*Vr)/Vm4; dIDr_dVi = (dPD_dVi*Vr + dQD_dVi*Vi + QD)/Vm2 - ((PD*Vr + QD*Vi)*2*Vi)/Vm4; dIDi_dVr = (-dQD_dVr*Vr + dPD_dVr*Vi - QD)/Vm2 - ((-QD*Vr + PD*Vi)*2*Vr)/Vm4; dIDi_dVi = (-dQD_dVi*Vr + dPD_dVi*Vi + PD)/Vm2 - ((-QD*Vr + PD*Vi)*2*Vi)/Vm4; /* fnet[2*lbus[i]] += IDi; */ row[0] = net_start + 2*lbus[i]; col[0] = net_start + 2*lbus[i]; col[1] = net_start + 2*lbus[i]+1; val[0] = dIDi_dVr; val[1] = dIDi_dVi; ierr = MatSetValues(J,1,row,2,col,val,ADD_VALUES);CHKERRQ(ierr); /* fnet[2*lbus[i]+1] += IDr; */ row[0] = net_start + 2*lbus[i]+1; col[0] = net_start + 2*lbus[i]; col[1] = net_start + 2*lbus[i]+1; val[0] = dIDr_dVr; val[1] = dIDr_dVi; ierr = MatSetValues(J,1,row,2,col,val,ADD_VALUES);CHKERRQ(ierr); } ierr = VecRestoreArray(user->V0,&v0);CHKERRQ(ierr); ierr = VecRestoreArray(Xgen,&xgen);CHKERRQ(ierr); ierr = VecRestoreArray(Xnet,&xnet);CHKERRQ(ierr); ierr = DMCompositeRestoreLocalVectors(user->dmpgrid,&Xgen,&Xnet);CHKERRQ(ierr); ierr = MatAssemblyBegin(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); PetscFunctionReturn(0); }
PetscErrorCode ResidualFunction(SNES snes,Vec X, Vec F, Userctx *user) { PetscErrorCode ierr; Vec Xgen,Xnet,Fgen,Fnet; PetscScalar *xgen,*xnet,*fgen,*fnet; PetscInt i,idx=0; PetscScalar Vr,Vi,Vm,Vm2; PetscScalar Eqp,Edp,delta,w; /* Generator variables */ PetscScalar Efd,RF,VR; /* Exciter variables */ PetscScalar Id,Iq; /* Generator dq axis currents */ PetscScalar Vd,Vq,SE; PetscScalar IGr,IGi,IDr,IDi; PetscScalar Zdq_inv[4],det; PetscScalar PD,QD,Vm0,*v0; PetscInt k; PetscFunctionBegin; ierr = VecZeroEntries(F);CHKERRQ(ierr); ierr = DMCompositeGetLocalVectors(user->dmpgrid,&Xgen,&Xnet);CHKERRQ(ierr); ierr = DMCompositeGetLocalVectors(user->dmpgrid,&Fgen,&Fnet);CHKERRQ(ierr); ierr = DMCompositeScatter(user->dmpgrid,X,Xgen,Xnet);CHKERRQ(ierr); ierr = DMCompositeScatter(user->dmpgrid,F,Fgen,Fnet);CHKERRQ(ierr); /* Network current balance residual IG + Y*V + IL = 0. Only YV is added here. The generator current injection, IG, and load current injection, ID are added later */ /* Note that the values in Ybus are stored assuming the imaginary current balance equation is ordered first followed by real current balance equation for each bus. Thus imaginary current contribution goes in location 2*i, and real current contribution in 2*i+1 */ ierr = MatMult(user->Ybus,Xnet,Fnet); ierr = VecGetArray(Xgen,&xgen);CHKERRQ(ierr); ierr = VecGetArray(Xnet,&xnet);CHKERRQ(ierr); ierr = VecGetArray(Fgen,&fgen);CHKERRQ(ierr); ierr = VecGetArray(Fnet,&fnet);CHKERRQ(ierr); /* Generator subsystem */ for (i=0; i < ngen; i++) { Eqp = xgen[idx]; Edp = xgen[idx+1]; delta = xgen[idx+2]; w = xgen[idx+3]; Id = xgen[idx+4]; Iq = xgen[idx+5]; Efd = xgen[idx+6]; RF = xgen[idx+7]; VR = xgen[idx+8]; /* Generator differential equations */ fgen[idx] = (Eqp + (Xd[i] - Xdp[i])*Id - Efd)/Td0p[i]; fgen[idx+1] = (Edp - (Xq[i] - Xqp[i])*Iq)/Tq0p[i]; fgen[idx+2] = -w + w_s; fgen[idx+3] = (-TM[i] + Edp*Id + Eqp*Iq + (Xqp[i] - Xdp[i])*Id*Iq + D[i]*(w - w_s))/M[i]; Vr = xnet[2*gbus[i]]; /* Real part of generator terminal voltage */ Vi = xnet[2*gbus[i]+1]; /* Imaginary part of the generator terminal voltage */ ierr = ri2dq(Vr,Vi,delta,&Vd,&Vq);CHKERRQ(ierr); /* Algebraic equations for stator currents */ det = Rs[i]*Rs[i] + Xdp[i]*Xqp[i]; Zdq_inv[0] = Rs[i]/det; Zdq_inv[1] = Xqp[i]/det; Zdq_inv[2] = -Xdp[i]/det; Zdq_inv[3] = Rs[i]/det; fgen[idx+4] = Zdq_inv[0]*(-Edp + Vd) + Zdq_inv[1]*(-Eqp + Vq) + Id; fgen[idx+5] = Zdq_inv[2]*(-Edp + Vd) + Zdq_inv[3]*(-Eqp + Vq) + Iq; /* Add generator current injection to network */ ierr = dq2ri(Id,Iq,delta,&IGr,&IGi);CHKERRQ(ierr); fnet[2*gbus[i]] -= IGi; fnet[2*gbus[i]+1] -= IGr; Vm = PetscSqrtScalar(Vd*Vd + Vq*Vq); Vm2 = Vm*Vm; SE = k1[i]*PetscExpScalar(k2[i]*Efd); /* Exciter differential equations */ fgen[idx+6] = (KE[i]*Efd + SE - VR)/TE[i]; fgen[idx+7] = (RF - KF[i]*Efd/TF[i])/TF[i]; fgen[idx+8] = (VR - KA[i]*RF + KA[i]*KF[i]*Efd/TF[i] - KA[i]*(Vref[i] - Vm))/TA[i]; idx = idx + 9; } ierr = VecGetArray(user->V0,&v0);CHKERRQ(ierr); for (i=0; i < nload; i++) { Vr = xnet[2*lbus[i]]; /* Real part of load bus voltage */ Vi = xnet[2*lbus[i]+1]; /* Imaginary part of the load bus voltage */ Vm = PetscSqrtScalar(Vr*Vr + Vi*Vi); Vm2 = Vm*Vm; Vm0 = PetscSqrtScalar(v0[2*lbus[i]]*v0[2*lbus[i]] + v0[2*lbus[i]+1]*v0[2*lbus[i]+1]); PD = QD = 0.0; for (k=0; k < ld_nsegsp[i]; k++) PD += ld_alphap[k]*PD0[i]*PetscPowScalar((Vm/Vm0),ld_betap[k]); for (k=0; k < ld_nsegsq[i]; k++) QD += ld_alphaq[k]*QD0[i]*PetscPowScalar((Vm/Vm0),ld_betaq[k]); /* Load currents */ IDr = (PD*Vr + QD*Vi)/Vm2; IDi = (-QD*Vr + PD*Vi)/Vm2; fnet[2*lbus[i]] += IDi; fnet[2*lbus[i]+1] += IDr; } ierr = VecRestoreArray(user->V0,&v0);CHKERRQ(ierr); ierr = VecRestoreArray(Xgen,&xgen);CHKERRQ(ierr); ierr = VecRestoreArray(Xnet,&xnet);CHKERRQ(ierr); ierr = VecRestoreArray(Fgen,&fgen);CHKERRQ(ierr); ierr = VecRestoreArray(Fnet,&fnet);CHKERRQ(ierr); ierr = DMCompositeGather(user->dmpgrid,F,INSERT_VALUES,Fgen,Fnet);CHKERRQ(ierr); ierr = DMCompositeRestoreLocalVectors(user->dmpgrid,&Xgen,&Xnet);CHKERRQ(ierr); ierr = DMCompositeRestoreLocalVectors(user->dmpgrid,&Fgen,&Fnet);CHKERRQ(ierr); PetscFunctionReturn(0); }
int main(int argc,char **argv) { PetscErrorCode ierr; PetscInt nredundant1 = 5,nredundant2 = 2,i,*ridx1,*ridx2,*lidx1,*lidx2,nlocal; PetscMPIInt rank; PetscScalar *redundant1,*redundant2; DMComposite packer; Vec global,local1,local2; PF pf; DA da1,da2; PetscViewer sviewer; ierr = PetscInitialize(&argc,&argv,(char*)0,help);CHKERRQ(ierr); ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr); ierr = DMCompositeCreate(PETSC_COMM_WORLD,&packer);CHKERRQ(ierr); ierr = PetscMalloc(nredundant1*sizeof(PetscScalar),&redundant1);CHKERRQ(ierr); ierr = DMCompositeAddArray(packer,0,nredundant1);CHKERRQ(ierr); ierr = DACreate1d(PETSC_COMM_WORLD,DA_NONPERIODIC,8,1,1,PETSC_NULL,&da1);CHKERRQ(ierr); ierr = DACreateLocalVector(da1,&local1);CHKERRQ(ierr); ierr = DMCompositeAddDM(packer,(DM)da1);CHKERRQ(ierr); ierr = PetscMalloc(nredundant2*sizeof(PetscScalar),&redundant2);CHKERRQ(ierr); ierr = DMCompositeAddArray(packer,0,nredundant2);CHKERRQ(ierr); ierr = DACreate1d(PETSC_COMM_WORLD,DA_NONPERIODIC,6,1,1,PETSC_NULL,&da2);CHKERRQ(ierr); ierr = DACreateLocalVector(da2,&local2);CHKERRQ(ierr); ierr = DMCompositeAddDM(packer,(DM)da2);CHKERRQ(ierr); ierr = DMCompositeCreateGlobalVector(packer,&global);CHKERRQ(ierr); ierr = PFCreate(PETSC_COMM_WORLD,1,1,&pf);CHKERRQ(ierr); ierr = PFSetType(pf,PFIDENTITY,PETSC_NULL);CHKERRQ(ierr); ierr = PFApplyVec(pf,PETSC_NULL,global);CHKERRQ(ierr); ierr = PFDestroy(pf);CHKERRQ(ierr); ierr = VecView(global,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); ierr = DMCompositeScatter(packer,global,redundant1,local1,redundant2,local2);CHKERRQ(ierr); ierr = PetscViewerASCIISynchronizedPrintf(PETSC_VIEWER_STDOUT_WORLD,"[%d] My part of redundant1 array\n",rank);CHKERRQ(ierr); ierr = PetscScalarView(nredundant1,redundant1,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); ierr = PetscViewerASCIISynchronizedPrintf(PETSC_VIEWER_STDOUT_WORLD,"[%d] My part of da1 vector\n",rank);CHKERRQ(ierr); ierr = PetscViewerGetSingleton(PETSC_VIEWER_STDOUT_WORLD,&sviewer);CHKERRQ(ierr); ierr = VecView(local1,sviewer);CHKERRQ(ierr); ierr = PetscViewerRestoreSingleton(PETSC_VIEWER_STDOUT_WORLD,&sviewer);CHKERRQ(ierr); ierr = PetscViewerASCIISynchronizedPrintf(PETSC_VIEWER_STDOUT_WORLD,"[%d] My part of redundant2 array\n",rank);CHKERRQ(ierr); ierr = PetscScalarView(nredundant2,redundant2,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); ierr = PetscViewerASCIISynchronizedPrintf(PETSC_VIEWER_STDOUT_WORLD,"[%d] My part of da2 vector\n",rank);CHKERRQ(ierr); ierr = PetscViewerGetSingleton(PETSC_VIEWER_STDOUT_WORLD,&sviewer);CHKERRQ(ierr); ierr = VecView(local2,sviewer);CHKERRQ(ierr); ierr = PetscViewerRestoreSingleton(PETSC_VIEWER_STDOUT_WORLD,&sviewer);CHKERRQ(ierr); for (i=0; i<nredundant1; i++) redundant1[i] = (rank+2)*i; for (i=0; i<nredundant2; i++) redundant2[i] = (rank+10)*i; ierr = DMCompositeGather(packer,global,redundant1,local1,redundant2,local2);CHKERRQ(ierr); ierr = VecView(global,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); /* get the global numbering for each subvector/array element */ ierr = DMCompositeGetGlobalIndices(packer,&ridx1,&lidx1,&ridx2,&lidx2);CHKERRQ(ierr); ierr = PetscViewerASCIISynchronizedPrintf(PETSC_VIEWER_STDOUT_WORLD,"[%d] Global numbering of redundant1 array\n",rank);CHKERRQ(ierr); ierr = PetscIntView(nredundant1,ridx1,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); ierr = PetscViewerASCIISynchronizedPrintf(PETSC_VIEWER_STDOUT_WORLD,"[%d] Global numbering of local1 vector\n",rank);CHKERRQ(ierr); ierr = VecGetSize(local1,&nlocal);CHKERRQ(ierr); ierr = PetscIntView(nlocal,lidx1,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); ierr = PetscViewerASCIISynchronizedPrintf(PETSC_VIEWER_STDOUT_WORLD,"[%d] Global numbering of redundant2 array\n",rank);CHKERRQ(ierr); ierr = PetscIntView(nredundant2,ridx2,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); ierr = PetscViewerASCIISynchronizedPrintf(PETSC_VIEWER_STDOUT_WORLD,"[%d] Global numbering of local2 vector\n",rank);CHKERRQ(ierr); ierr = VecGetSize(local2,&nlocal);CHKERRQ(ierr); ierr = PetscIntView(nlocal,lidx2,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); ierr = PetscFree(ridx1);CHKERRQ(ierr); ierr = PetscFree(lidx1);CHKERRQ(ierr); ierr = PetscFree(ridx2);CHKERRQ(ierr); ierr = PetscFree(lidx2);CHKERRQ(ierr); ierr = DADestroy(da1);CHKERRQ(ierr); ierr = DADestroy(da2);CHKERRQ(ierr); ierr = VecDestroy(local1);CHKERRQ(ierr); ierr = VecDestroy(local2);CHKERRQ(ierr); ierr = VecDestroy(global);CHKERRQ(ierr); ierr = DMCompositeDestroy(packer);CHKERRQ(ierr); ierr = PetscFree(redundant1);CHKERRQ(ierr); ierr = PetscFree(redundant2);CHKERRQ(ierr); ierr = PetscFinalize();CHKERRQ(ierr); return 0; }
int main(int argc,char **argv) { PetscErrorCode ierr; PetscInt nredundant1 = 5,nredundant2 = 2,i; ISLocalToGlobalMapping *ltog; PetscMPIInt rank,size; DM packer; Vec global,local1,local2,redundant1,redundant2; PF pf; DM da1,da2,dmred1,dmred2; PetscScalar *redundant1a,*redundant2a; PetscViewer sviewer; PetscBool gather_add = PETSC_FALSE; ierr = PetscInitialize(&argc,&argv,(char*)0,help);CHKERRQ(ierr); ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr); ierr = MPI_Comm_size(PETSC_COMM_WORLD,&size);CHKERRQ(ierr); ierr = PetscOptionsGetBool(PETSC_NULL,"-gather_add",&gather_add,PETSC_NULL);CHKERRQ(ierr); ierr = DMCompositeCreate(PETSC_COMM_WORLD,&packer);CHKERRQ(ierr); ierr = DMRedundantCreate(PETSC_COMM_WORLD,0,nredundant1,&dmred1);CHKERRQ(ierr); ierr = DMCreateLocalVector(dmred1,&redundant1);CHKERRQ(ierr); ierr = DMCompositeAddDM(packer,dmred1);CHKERRQ(ierr); ierr = DMDACreate1d(PETSC_COMM_WORLD,DMDA_BOUNDARY_NONE,8,1,1,PETSC_NULL,&da1);CHKERRQ(ierr); ierr = DMCreateLocalVector(da1,&local1);CHKERRQ(ierr); ierr = DMCompositeAddDM(packer,da1);CHKERRQ(ierr); ierr = DMRedundantCreate(PETSC_COMM_WORLD,1%size,nredundant2,&dmred2);CHKERRQ(ierr); ierr = DMCreateLocalVector(dmred2,&redundant2);CHKERRQ(ierr); ierr = DMCompositeAddDM(packer,dmred2);CHKERRQ(ierr); ierr = DMDACreate1d(PETSC_COMM_WORLD,DMDA_BOUNDARY_NONE,6,1,1,PETSC_NULL,&da2);CHKERRQ(ierr); ierr = DMCreateLocalVector(da2,&local2);CHKERRQ(ierr); ierr = DMCompositeAddDM(packer,da2);CHKERRQ(ierr); ierr = DMCreateGlobalVector(packer,&global);CHKERRQ(ierr); ierr = PFCreate(PETSC_COMM_WORLD,1,1,&pf);CHKERRQ(ierr); ierr = PFSetType(pf,PFIDENTITY,PETSC_NULL);CHKERRQ(ierr); ierr = PFApplyVec(pf,PETSC_NULL,global);CHKERRQ(ierr); ierr = PFDestroy(&pf);CHKERRQ(ierr); ierr = VecView(global,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); ierr = DMCompositeScatter(packer,global,redundant1,local1,redundant2,local2);CHKERRQ(ierr); ierr = PetscViewerASCIISynchronizedAllow(PETSC_VIEWER_STDOUT_WORLD,PETSC_TRUE);CHKERRQ(ierr); ierr = PetscViewerASCIISynchronizedPrintf(PETSC_VIEWER_STDOUT_WORLD,"[%d] My part of redundant1 vector\n",rank);CHKERRQ(ierr); ierr = PetscViewerGetSingleton(PETSC_VIEWER_STDOUT_WORLD,&sviewer);CHKERRQ(ierr); ierr = VecView(redundant1,sviewer);CHKERRQ(ierr); ierr = PetscViewerRestoreSingleton(PETSC_VIEWER_STDOUT_WORLD,&sviewer);CHKERRQ(ierr); ierr = PetscViewerASCIISynchronizedAllow(PETSC_VIEWER_STDOUT_WORLD,PETSC_TRUE);CHKERRQ(ierr); ierr = PetscViewerASCIISynchronizedPrintf(PETSC_VIEWER_STDOUT_WORLD,"[%d] My part of da1 vector\n",rank);CHKERRQ(ierr); ierr = PetscViewerGetSingleton(PETSC_VIEWER_STDOUT_WORLD,&sviewer);CHKERRQ(ierr); ierr = VecView(local1,sviewer);CHKERRQ(ierr); ierr = PetscViewerRestoreSingleton(PETSC_VIEWER_STDOUT_WORLD,&sviewer);CHKERRQ(ierr); ierr = PetscViewerASCIISynchronizedAllow(PETSC_VIEWER_STDOUT_WORLD,PETSC_TRUE);CHKERRQ(ierr); ierr = PetscViewerASCIISynchronizedPrintf(PETSC_VIEWER_STDOUT_WORLD,"[%d] My part of redundant2 vector\n",rank);CHKERRQ(ierr); ierr = PetscViewerGetSingleton(PETSC_VIEWER_STDOUT_WORLD,&sviewer);CHKERRQ(ierr); ierr = VecView(redundant2,sviewer);CHKERRQ(ierr); ierr = PetscViewerRestoreSingleton(PETSC_VIEWER_STDOUT_WORLD,&sviewer);CHKERRQ(ierr); ierr = PetscViewerASCIISynchronizedAllow(PETSC_VIEWER_STDOUT_WORLD,PETSC_TRUE);CHKERRQ(ierr); ierr = PetscViewerASCIISynchronizedPrintf(PETSC_VIEWER_STDOUT_WORLD,"[%d] My part of da2 vector\n",rank);CHKERRQ(ierr); ierr = PetscViewerGetSingleton(PETSC_VIEWER_STDOUT_WORLD,&sviewer);CHKERRQ(ierr); ierr = VecView(local2,sviewer);CHKERRQ(ierr); ierr = PetscViewerRestoreSingleton(PETSC_VIEWER_STDOUT_WORLD,&sviewer);CHKERRQ(ierr); ierr = VecGetArray(redundant1,&redundant1a);CHKERRQ(ierr); ierr = VecGetArray(redundant2,&redundant2a);CHKERRQ(ierr); for (i=0; i<nredundant1; i++) redundant1a[i] = (rank+2)*i; for (i=0; i<nredundant2; i++) redundant2a[i] = (rank+10)*i; ierr = VecRestoreArray(redundant1,&redundant1a);CHKERRQ(ierr); ierr = VecRestoreArray(redundant2,&redundant2a);CHKERRQ(ierr); ierr = DMCompositeGather(packer,global,gather_add?ADD_VALUES:INSERT_VALUES,redundant1,local1,redundant2,local2);CHKERRQ(ierr); ierr = VecView(global,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); /* get the global numbering for each subvector element */ ierr = DMCompositeGetISLocalToGlobalMappings(packer,<og);CHKERRQ(ierr); ierr = PetscViewerASCIIPrintf(PETSC_VIEWER_STDOUT_WORLD,"Local to global mapping of redundant1 vector\n");CHKERRQ(ierr); ierr = ISLocalToGlobalMappingView(ltog[0],PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); ierr = PetscViewerASCIIPrintf(PETSC_VIEWER_STDOUT_WORLD,"Local to global mapping of local1 vector\n");CHKERRQ(ierr); ierr = ISLocalToGlobalMappingView(ltog[1],PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); ierr = PetscViewerASCIIPrintf(PETSC_VIEWER_STDOUT_WORLD,"Local to global mapping of redundant2 vector\n");CHKERRQ(ierr); ierr = ISLocalToGlobalMappingView(ltog[2],PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); ierr = PetscViewerASCIIPrintf(PETSC_VIEWER_STDOUT_WORLD,"Local to global mapping of local2 vector\n");CHKERRQ(ierr); ierr = ISLocalToGlobalMappingView(ltog[3],PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); for (i=0; i<4; i++) {ierr = ISLocalToGlobalMappingDestroy(<og[i]);CHKERRQ(ierr);} ierr = PetscFree(ltog);CHKERRQ(ierr); ierr = DMDestroy(&da1);CHKERRQ(ierr); ierr = DMDestroy(&dmred1);CHKERRQ(ierr); ierr = DMDestroy(&dmred2);CHKERRQ(ierr); ierr = DMDestroy(&da2);CHKERRQ(ierr); ierr = VecDestroy(&redundant1);CHKERRQ(ierr); ierr = VecDestroy(&redundant2);CHKERRQ(ierr); ierr = VecDestroy(&local1);CHKERRQ(ierr); ierr = VecDestroy(&local2);CHKERRQ(ierr); ierr = VecDestroy(&global);CHKERRQ(ierr); ierr = DMDestroy(&packer);CHKERRQ(ierr); ierr = PetscFinalize(); return 0; }