/* InitialConditions - Computes the solution at the initial time. Input Parameter: u - uninitialized solution vector (global) appctx - user-defined application context Output Parameter: u - vector with solution at initial time (global) */ PetscErrorCode InitialConditions(Vec u,AppCtx *appctx) { PetscScalar *u_localptr,h = appctx->h; PetscInt i; PetscErrorCode ierr; /* Get a pointer to vector data. - For default PETSc vectors, VecGetArray() returns a pointer to the data array. Otherwise, the routine is implementation dependent. - You MUST call VecRestoreArray() when you no longer need access to the array. - Note that the Fortran interface to VecGetArray() differs from the C version. See the users manual for details. */ ierr = VecGetArray(u,&u_localptr);CHKERRQ(ierr); /* We initialize the solution array by simply writing the solution directly into the array locations. Alternatively, we could use VecSetValues() or VecSetValuesLocal(). */ for (i=0; i<appctx->m; i++) { u_localptr[i] = PetscCosScalar(PETSC_PI*i*6.*h) + 3.*PetscCosScalar(PETSC_PI*i*2.*h); } /* Restore vector */ ierr = VecRestoreArray(u,&u_localptr);CHKERRQ(ierr); /* Print debugging information if desired */ if (appctx->debug) { printf("initial guess vector\n"); ierr = VecView(u,PETSC_VIEWER_STDOUT_SELF);CHKERRQ(ierr); } return 0; }
/* Define the analytic solution for check method easily */ static PetscErrorCode sol_true(PetscReal t, Vec U,AppCtx *ctx) { PetscErrorCode ierr; PetscScalar *u; PetscFunctionBegin; ierr = VecGetArray(U,&u);CHKERRQ(ierr); u[0] = PetscExpScalar(t/ctx->a); u[1] = (ctx->a*PetscCosScalar(ctx->b*t)+ctx->a*ctx->a*ctx->b*PetscSinScalar(ctx->b*t))*PetscExpScalar(t/ctx->a)/(1+ctx->a*ctx->a*ctx->b*ctx->b); ierr = VecRestoreArray(U,&u);CHKERRQ(ierr); PetscFunctionReturn(0); }
PetscErrorCode ComputeRHS(KSP ksp,Vec b,void *ctx) { PetscErrorCode ierr; PetscInt i,j,k,mx,my,mz,xm,ym,zm,xs,ys,zs; PetscScalar Hx,Hy,Hz; PetscScalar ***array; DM da; MatNullSpace nullspace; PetscFunctionBeginUser; ierr = KSPGetDM(ksp,&da);CHKERRQ(ierr); ierr = DMDAGetInfo(da, 0, &mx, &my, &mz, 0,0,0,0,0,0,0,0,0);CHKERRQ(ierr); Hx = 1.0 / (PetscReal)(mx); Hy = 1.0 / (PetscReal)(my); Hz = 1.0 / (PetscReal)(mz); ierr = DMDAGetCorners(da,&xs,&ys,&zs,&xm,&ym,&zm);CHKERRQ(ierr); ierr = DMDAVecGetArray(da, b, &array);CHKERRQ(ierr); for (k=zs; k<zs+zm; k++) { for (j=ys; j<ys+ym; j++) { for (i=xs; i<xs+xm; i++) { array[k][j][i] = 12 * PETSC_PI * PETSC_PI * PetscCosScalar(2*PETSC_PI*(((PetscReal)i+0.5)*Hx)) * PetscCosScalar(2*PETSC_PI*(((PetscReal)j+0.5)*Hy)) * PetscCosScalar(2*PETSC_PI*(((PetscReal)k+0.5)*Hz)) * Hx * Hy * Hz; } } } ierr = DMDAVecRestoreArray(da, b, &array);CHKERRQ(ierr); ierr = VecAssemblyBegin(b);CHKERRQ(ierr); ierr = VecAssemblyEnd(b);CHKERRQ(ierr); /* force right hand side to be consistent for singular matrix */ /* note this is really a hack, normally the model would provide you with a consistent right handside */ ierr = MatNullSpaceCreate(PETSC_COMM_WORLD,PETSC_TRUE,0,0,&nullspace);CHKERRQ(ierr); ierr = MatNullSpaceRemove(nullspace,b);CHKERRQ(ierr); ierr = MatNullSpaceDestroy(&nullspace);CHKERRQ(ierr); PetscFunctionReturn(0); }
PetscErrorCode ComputeRHS(KSP ksp,Vec b,void *ctx) { UserContext *user = (UserContext*)ctx; PetscErrorCode ierr; PetscInt i,j,M,N,xm,ym,xs,ys; PetscScalar Hx,Hy,pi,uu,tt; PetscScalar **array; DM da; PetscFunctionBeginUser; ierr = KSPGetDM(ksp,&da);CHKERRQ(ierr); ierr = DMDAGetInfo(da, 0, &M, &N, 0,0,0,0,0,0,0,0,0,0);CHKERRQ(ierr); uu = user->uu; tt = user->tt; pi = 4*atan(1.0); Hx = 1.0/(PetscReal)(M); Hy = 1.0/(PetscReal)(N); ierr = DMDAGetCorners(da,&xs,&ys,0,&xm,&ym,0);CHKERRQ(ierr); /* Fine grid */ /* printf(" M N: %d %d; xm ym: %d %d; xs ys: %d %d\n",M,N,xm,ym,xs,ys); */ ierr = DMDAVecGetArray(da, b, &array);CHKERRQ(ierr); for (j=ys; j<ys+ym; j++) { for (i=xs; i<xs+xm; i++) { array[j][i] = -PetscCosScalar(uu*pi*((PetscReal)i+0.5)*Hx)*PetscCosScalar(tt*pi*((PetscReal)j+0.5)*Hy)*Hx*Hy; } } ierr = DMDAVecRestoreArray(da, b, &array);CHKERRQ(ierr); ierr = VecAssemblyBegin(b);CHKERRQ(ierr); ierr = VecAssemblyEnd(b);CHKERRQ(ierr); /* force right hand side to be consistent for singular matrix */ /* note this is really a hack, normally the model would provide you with a consistent right handside */ if (user->bcType == NEUMANN) { MatNullSpace nullspace; ierr = MatNullSpaceCreate(PETSC_COMM_WORLD,PETSC_TRUE,0,0,&nullspace);CHKERRQ(ierr); ierr = MatNullSpaceRemove(nullspace,b);CHKERRQ(ierr); ierr = MatNullSpaceDestroy(&nullspace);CHKERRQ(ierr); } PetscFunctionReturn(0); }
static PetscErrorCode RHSFunctionfast(TS ts,PetscReal t,Vec U,Vec F,AppCtx *ctx) { PetscErrorCode ierr; const PetscScalar *u; PetscScalar *f; PetscFunctionBegin; ierr = VecGetArrayRead(U,&u);CHKERRQ(ierr); ierr = VecGetArray(F,&f);CHKERRQ(ierr); f[0] = u[0]*PetscCosScalar(t*ctx->b); ierr = VecRestoreArrayRead(U,&u);CHKERRQ(ierr); ierr = VecRestoreArray(F,&f);CHKERRQ(ierr); PetscFunctionReturn(0); }
static PetscErrorCode FormJacobian2_block(SNES snes,Vec x,Mat *jac,Mat *B,MatStructure *flag,void *dummy) { PetscScalar *xx,A[4]; PetscErrorCode ierr; PetscInt idx[2] = {0,1}; PetscFunctionBegin; /* Get pointer to vector data */ ierr = VecGetArray(x,&xx); CHKERRQ(ierr); /* Compute Jacobian entries and insert into matrix. - Since this is such a small problem, we set all entries for the matrix at once. */ A[0] = 3.0*PetscCosScalar(3.0*xx[0]) + 1.0; A[1] = 0.0; A[2] = 0.0; A[3] = 1.0; ierr = MatSetValues(*jac,2,idx,2,idx,A,INSERT_VALUES); CHKERRQ(ierr); *flag = SAME_NONZERO_PATTERN; /* Restore vector */ ierr = VecRestoreArray(x,&xx); CHKERRQ(ierr); /* Assemble matrix */ ierr = MatAssemblyBegin(*jac,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); ierr = MatAssemblyEnd(*jac,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); PetscFunctionReturn(0); }
PetscErrorCode FAMapRegion2(FA fa,Vec g) { PetscErrorCode ierr; PetscReal R = 1.0,Rscale,Ascale; PetscInt i,k,x,y,m,n; Field **ga; PetscFunctionBeginUser; Rscale = R/(fa->r2-1); Ascale = 2.0*PETSC_PI/fa->p2; ierr = FAGetGlobalCorners(fa,1,&x,&y,&m,&n);CHKERRQ(ierr); ierr = FAGetGlobalArray(fa,g,1,&ga);CHKERRQ(ierr); for (k=y; k<y+n; k++) { for (i=x; i<x+m; i++) { ga[k][i].X = (R + k*Rscale)*PetscCosScalar(i*Ascale - PETSC_PI/2.0); ga[k][i].Y = (R + k*Rscale)*PetscSinScalar(i*Ascale - PETSC_PI/2.0); } } ierr = FARestoreGlobalArray(fa,g,1,&ga);CHKERRQ(ierr); PetscFunctionReturn(0); }
PetscErrorCode InitialConditions(DM da,Vec U) { PetscErrorCode ierr; PetscInt i,xs,xm,Mx; Field *u; PetscReal hx,x; PetscFunctionBegin; ierr = DMDAGetInfo(da,PETSC_IGNORE,&Mx,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE);CHKERRQ(ierr); hx = 1.0/(PetscReal)(Mx-1); /* Get pointers to vector data */ ierr = DMDAVecGetArray(da,U,&u);CHKERRQ(ierr); /* Get local grid boundaries */ ierr = DMDAGetCorners(da,&xs,NULL,NULL,&xm,NULL,NULL);CHKERRQ(ierr); /* Compute function over the locally owned part of the grid */ for (i=xs; i<xs+xm; i++) { x = i*hx; if (x < 1.0) u[i].rho = 0.0; else u[i].rho = 1.0; u[i].c = PetscCosScalar(.5*PETSC_PI*x); } /* Restore vectors */ ierr = DMDAVecRestoreArray(da,U,&u);CHKERRQ(ierr); PetscFunctionReturn(0); }
/* Defines the Jacobian of the ODE passed to the ODE solver. See TSSetIJacobian() for the meaning of a and the Jacobian. */ static PetscErrorCode IJacobian(TS ts,PetscReal t,Vec U,Vec Udot,PetscReal a,Mat A,Mat B,AppCtx *ctx) { PetscErrorCode ierr; PetscInt rowcol[] = {0,1}; PetscScalar *u,*udot,J[2][2]; PetscFunctionBegin; ierr = VecGetArray(U,&u);CHKERRQ(ierr); ierr = VecGetArray(Udot,&udot);CHKERRQ(ierr); J[0][0] = 2.0*ctx->H*a/ctx->omega_s; J[0][1] = -ctx->E*ctx->V*PetscCosScalar(u[1])/ctx->X; J[1][0] = -1.0; J[1][1] = a; ierr = MatSetValues(B,2,rowcol,2,rowcol,&J[0][0],INSERT_VALUES);CHKERRQ(ierr); ierr = VecRestoreArray(U,&u);CHKERRQ(ierr); ierr = VecRestoreArray(Udot,&udot);CHKERRQ(ierr); ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); if (A != B) { ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); } PetscFunctionReturn(0); }
static PetscReal p(PetscReal xi, PetscReal ecc) { PetscReal t=1.0+ecc*PetscCosScalar(xi); return (t*t*t); }
PetscErrorCode FormFunction(SNES snes,Vec X, Vec F,void *appctx) { PetscErrorCode ierr; DM networkdm; UserCtx *User=(UserCtx*)appctx; Vec localX,localF; PetscInt e; PetscInt v,vStart,vEnd,vfrom,vto; const PetscScalar *xarr; PetscScalar *farr; PetscInt offsetfrom,offsetto,offset; DMNetworkComponentGenericDataType *arr; PetscFunctionBegin; ierr = SNESGetDM(snes,&networkdm);CHKERRQ(ierr); ierr = DMGetLocalVector(networkdm,&localX);CHKERRQ(ierr); ierr = DMGetLocalVector(networkdm,&localF);CHKERRQ(ierr); ierr = VecSet(F,0.0);CHKERRQ(ierr); ierr = DMGlobalToLocalBegin(networkdm,X,INSERT_VALUES,localX);CHKERRQ(ierr); ierr = DMGlobalToLocalEnd(networkdm,X,INSERT_VALUES,localX);CHKERRQ(ierr); ierr = DMGlobalToLocalBegin(networkdm,F,INSERT_VALUES,localF);CHKERRQ(ierr); ierr = DMGlobalToLocalEnd(networkdm,F,INSERT_VALUES,localF);CHKERRQ(ierr); ierr = VecGetArrayRead(localX,&xarr);CHKERRQ(ierr); ierr = VecGetArray(localF,&farr);CHKERRQ(ierr); ierr = DMNetworkGetVertexRange(networkdm,&vStart,&vEnd);CHKERRQ(ierr); ierr = DMNetworkGetComponentDataArray(networkdm,&arr);CHKERRQ(ierr); for (v=vStart; v < vEnd; v++) { PetscInt i,j,offsetd,key; PetscScalar Vm; PetscScalar Sbase=User->Sbase; VERTEXDATA bus=NULL; GEN gen; LOAD load; PetscBool ghostvtex; PetscInt numComps; ierr = DMNetworkIsGhostVertex(networkdm,v,&ghostvtex);CHKERRQ(ierr); ierr = DMNetworkGetNumComponents(networkdm,v,&numComps);CHKERRQ(ierr); ierr = DMNetworkGetVariableOffset(networkdm,v,&offset);CHKERRQ(ierr); for (j = 0; j < numComps; j++) { ierr = DMNetworkGetComponentTypeOffset(networkdm,v,j,&key,&offsetd);CHKERRQ(ierr); if (key == 1) { PetscInt nconnedges; const PetscInt *connedges; bus = (VERTEXDATA)(arr+offsetd); /* Handle reference bus constrained dofs */ if (bus->ide == REF_BUS || bus->ide == ISOLATED_BUS) { farr[offset] = xarr[offset] - bus->va*PETSC_PI/180.0; farr[offset+1] = xarr[offset+1] - bus->vm; break; } if (!ghostvtex) { Vm = xarr[offset+1]; /* Shunt injections */ farr[offset] += Vm*Vm*bus->gl/Sbase; if(bus->ide != PV_BUS) farr[offset+1] += -Vm*Vm*bus->bl/Sbase; } ierr = DMNetworkGetSupportingEdges(networkdm,v,&nconnedges,&connedges);CHKERRQ(ierr); for (i=0; i < nconnedges; i++) { EDGEDATA branch; PetscInt keye; PetscScalar Gff,Bff,Gft,Bft,Gtf,Btf,Gtt,Btt; const PetscInt *cone; PetscScalar Vmf,Vmt,thetaf,thetat,thetaft,thetatf; e = connedges[i]; ierr = DMNetworkGetComponentTypeOffset(networkdm,e,0,&keye,&offsetd);CHKERRQ(ierr); branch = (EDGEDATA)(arr+offsetd); if (!branch->status) continue; Gff = branch->yff[0]; Bff = branch->yff[1]; Gft = branch->yft[0]; Bft = branch->yft[1]; Gtf = branch->ytf[0]; Btf = branch->ytf[1]; Gtt = branch->ytt[0]; Btt = branch->ytt[1]; ierr = DMNetworkGetConnectedNodes(networkdm,e,&cone);CHKERRQ(ierr); vfrom = cone[0]; vto = cone[1]; ierr = DMNetworkGetVariableOffset(networkdm,vfrom,&offsetfrom);CHKERRQ(ierr); ierr = DMNetworkGetVariableOffset(networkdm,vto,&offsetto);CHKERRQ(ierr); thetaf = xarr[offsetfrom]; Vmf = xarr[offsetfrom+1]; thetat = xarr[offsetto]; Vmt = xarr[offsetto+1]; thetaft = thetaf - thetat; thetatf = thetat - thetaf; if (vfrom == v) { farr[offsetfrom] += Gff*Vmf*Vmf + Vmf*Vmt*(Gft*PetscCosScalar(thetaft) + Bft*PetscSinScalar(thetaft)); farr[offsetfrom+1] += -Bff*Vmf*Vmf + Vmf*Vmt*(-Bft*PetscCosScalar(thetaft) + Gft*PetscSinScalar(thetaft)); } else { farr[offsetto] += Gtt*Vmt*Vmt + Vmt*Vmf*(Gtf*PetscCosScalar(thetatf) + Btf*PetscSinScalar(thetatf)); farr[offsetto+1] += -Btt*Vmt*Vmt + Vmt*Vmf*(-Btf*PetscCosScalar(thetatf) + Gtf*PetscSinScalar(thetatf)); } } } else if (key == 2) { if (!ghostvtex) { gen = (GEN)(arr+offsetd); if (!gen->status) continue; farr[offset] += -gen->pg/Sbase; farr[offset+1] += -gen->qg/Sbase; } } else if (key == 3) { if (!ghostvtex) { load = (LOAD)(arr+offsetd); farr[offset] += load->pl/Sbase; farr[offset+1] += load->ql/Sbase; } } } if (bus && bus->ide == PV_BUS) { farr[offset+1] = xarr[offset+1] - bus->vm; } } ierr = VecRestoreArrayRead(localX,&xarr);CHKERRQ(ierr); ierr = VecRestoreArray(localF,&farr);CHKERRQ(ierr); ierr = DMRestoreLocalVector(networkdm,&localX);CHKERRQ(ierr); ierr = DMLocalToGlobalBegin(networkdm,localF,ADD_VALUES,F);CHKERRQ(ierr); ierr = DMLocalToGlobalEnd(networkdm,localF,ADD_VALUES,F);CHKERRQ(ierr); ierr = DMRestoreLocalVector(networkdm,&localF);CHKERRQ(ierr); PetscFunctionReturn(0); }
PetscErrorCode FormJacobian(SNES snes,Vec X, Mat J,Mat Jpre,void *appctx) { PetscErrorCode ierr; DM networkdm; UserCtx *User=(UserCtx*)appctx; Vec localX; PetscInt e; PetscInt v,vStart,vEnd,vfrom,vto; const PetscScalar *xarr; PetscInt offsetfrom,offsetto,goffsetfrom,goffsetto; DMNetworkComponentGenericDataType *arr; PetscInt row[2],col[8]; PetscScalar values[8]; PetscFunctionBegin; ierr = MatZeroEntries(J);CHKERRQ(ierr); ierr = SNESGetDM(snes,&networkdm);CHKERRQ(ierr); ierr = DMGetLocalVector(networkdm,&localX);CHKERRQ(ierr); ierr = DMGlobalToLocalBegin(networkdm,X,INSERT_VALUES,localX);CHKERRQ(ierr); ierr = DMGlobalToLocalEnd(networkdm,X,INSERT_VALUES,localX);CHKERRQ(ierr); ierr = VecGetArrayRead(localX,&xarr);CHKERRQ(ierr); ierr = DMNetworkGetVertexRange(networkdm,&vStart,&vEnd);CHKERRQ(ierr); ierr = DMNetworkGetComponentDataArray(networkdm,&arr);CHKERRQ(ierr); for (v=vStart; v < vEnd; v++) { PetscInt i,j,offsetd,key; PetscInt offset,goffset; PetscScalar Vm; PetscScalar Sbase=User->Sbase; VERTEXDATA bus; PetscBool ghostvtex; PetscInt numComps; ierr = DMNetworkIsGhostVertex(networkdm,v,&ghostvtex);CHKERRQ(ierr); ierr = DMNetworkGetNumComponents(networkdm,v,&numComps);CHKERRQ(ierr); for (j = 0; j < numComps; j++) { ierr = DMNetworkGetVariableOffset(networkdm,v,&offset);CHKERRQ(ierr); ierr = DMNetworkGetVariableGlobalOffset(networkdm,v,&goffset);CHKERRQ(ierr); ierr = DMNetworkGetComponentTypeOffset(networkdm,v,j,&key,&offsetd);CHKERRQ(ierr); if (key == 1) { PetscInt nconnedges; const PetscInt *connedges; bus = (VERTEXDATA)(arr+offsetd); if (!ghostvtex) { /* Handle reference bus constrained dofs */ if (bus->ide == REF_BUS || bus->ide == ISOLATED_BUS) { row[0] = goffset; row[1] = goffset+1; col[0] = goffset; col[1] = goffset+1; col[2] = goffset; col[3] = goffset+1; values[0] = 1.0; values[1] = 0.0; values[2] = 0.0; values[3] = 1.0; ierr = MatSetValues(J,2,row,2,col,values,ADD_VALUES);CHKERRQ(ierr); break; } Vm = xarr[offset+1]; /* Shunt injections */ row[0] = goffset; row[1] = goffset+1; col[0] = goffset; col[1] = goffset+1; values[0] = values[1] = values[2] = values[3] = 0.0; if (bus->ide != PV_BUS) { values[1] = 2.0*Vm*bus->gl/Sbase; values[3] = -2.0*Vm*bus->bl/Sbase; } ierr = MatSetValues(J,2,row,2,col,values,ADD_VALUES);CHKERRQ(ierr); } ierr = DMNetworkGetSupportingEdges(networkdm,v,&nconnedges,&connedges);CHKERRQ(ierr); for (i=0; i < nconnedges; i++) { EDGEDATA branch; VERTEXDATA busf,bust; PetscInt offsetfd,offsettd,keyf,keyt; PetscScalar Gff,Bff,Gft,Bft,Gtf,Btf,Gtt,Btt; const PetscInt *cone; PetscScalar Vmf,Vmt,thetaf,thetat,thetaft,thetatf; e = connedges[i]; ierr = DMNetworkGetComponentTypeOffset(networkdm,e,0,&key,&offsetd);CHKERRQ(ierr); branch = (EDGEDATA)(arr+offsetd); if (!branch->status) continue; Gff = branch->yff[0]; Bff = branch->yff[1]; Gft = branch->yft[0]; Bft = branch->yft[1]; Gtf = branch->ytf[0]; Btf = branch->ytf[1]; Gtt = branch->ytt[0]; Btt = branch->ytt[1]; ierr = DMNetworkGetConnectedNodes(networkdm,e,&cone);CHKERRQ(ierr); vfrom = cone[0]; vto = cone[1]; ierr = DMNetworkGetVariableOffset(networkdm,vfrom,&offsetfrom);CHKERRQ(ierr); ierr = DMNetworkGetVariableOffset(networkdm,vto,&offsetto);CHKERRQ(ierr); ierr = DMNetworkGetVariableGlobalOffset(networkdm,vfrom,&goffsetfrom);CHKERRQ(ierr); ierr = DMNetworkGetVariableGlobalOffset(networkdm,vto,&goffsetto);CHKERRQ(ierr); if (goffsetto < 0) goffsetto = -goffsetto - 1; thetaf = xarr[offsetfrom]; Vmf = xarr[offsetfrom+1]; thetat = xarr[offsetto]; Vmt = xarr[offsetto+1]; thetaft = thetaf - thetat; thetatf = thetat - thetaf; ierr = DMNetworkGetComponentTypeOffset(networkdm,vfrom,0,&keyf,&offsetfd);CHKERRQ(ierr); ierr = DMNetworkGetComponentTypeOffset(networkdm,vto,0,&keyt,&offsettd);CHKERRQ(ierr); busf = (VERTEXDATA)(arr+offsetfd); bust = (VERTEXDATA)(arr+offsettd); if (vfrom == v) { if (busf->ide != REF_BUS) { /* farr[offsetfrom] += Gff*Vmf*Vmf + Vmf*Vmt*(Gft*PetscCosScalar(thetaft) + Bft*PetscSinScalar(thetaft)); */ row[0] = goffsetfrom; col[0] = goffsetfrom; col[1] = goffsetfrom+1; col[2] = goffsetto; col[3] = goffsetto+1; values[0] = Vmf*Vmt*(Gft*-PetscSinScalar(thetaft) + Bft*PetscCosScalar(thetaft)); /* df_dthetaf */ values[1] = 2.0*Gff*Vmf + Vmt*(Gft*PetscCosScalar(thetaft) + Bft*PetscSinScalar(thetaft)); /* df_dVmf */ values[2] = Vmf*Vmt*(Gft*PetscSinScalar(thetaft) + Bft*-PetscCosScalar(thetaft)); /* df_dthetat */ values[3] = Vmf*(Gft*PetscCosScalar(thetaft) + Bft*PetscSinScalar(thetaft)); /* df_dVmt */ ierr = MatSetValues(J,1,row,4,col,values,ADD_VALUES);CHKERRQ(ierr); } if (busf->ide != PV_BUS && busf->ide != REF_BUS) { row[0] = goffsetfrom+1; col[0] = goffsetfrom; col[1] = goffsetfrom+1; col[2] = goffsetto; col[3] = goffsetto+1; /* farr[offsetfrom+1] += -Bff*Vmf*Vmf + Vmf*Vmt*(-Bft*PetscCosScalar(thetaft) + Gft*PetscSinScalar(thetaft)); */ values[0] = Vmf*Vmt*(Bft*PetscSinScalar(thetaft) + Gft*PetscCosScalar(thetaft)); values[1] = -2.0*Bff*Vmf + Vmt*(-Bft*PetscCosScalar(thetaft) + Gft*PetscSinScalar(thetaft)); values[2] = Vmf*Vmt*(-Bft*PetscSinScalar(thetaft) + Gft*-PetscCosScalar(thetaft)); values[3] = Vmf*(-Bft*PetscCosScalar(thetaft) + Gft*PetscSinScalar(thetaft)); ierr = MatSetValues(J,1,row,4,col,values,ADD_VALUES);CHKERRQ(ierr); } } else { if (bust->ide != REF_BUS) { row[0] = goffsetto; col[0] = goffsetto; col[1] = goffsetto+1; col[2] = goffsetfrom; col[3] = goffsetfrom+1; /* farr[offsetto] += Gtt*Vmt*Vmt + Vmt*Vmf*(Gtf*PetscCosScalar(thetatf) + Btf*PetscSinScalar(thetatf)); */ values[0] = Vmt*Vmf*(Gtf*-PetscSinScalar(thetatf) + Btf*PetscCosScalar(thetaft)); /* df_dthetat */ values[1] = 2.0*Gtt*Vmt + Vmf*(Gtf*PetscCosScalar(thetatf) + Btf*PetscSinScalar(thetatf)); /* df_dVmt */ values[2] = Vmt*Vmf*(Gtf*PetscSinScalar(thetatf) + Btf*-PetscCosScalar(thetatf)); /* df_dthetaf */ values[3] = Vmt*(Gtf*PetscCosScalar(thetatf) + Btf*PetscSinScalar(thetatf)); /* df_dVmf */ ierr = MatSetValues(J,1,row,4,col,values,ADD_VALUES);CHKERRQ(ierr); } if (bust->ide != PV_BUS && bust->ide != REF_BUS) { row[0] = goffsetto+1; col[0] = goffsetto; col[1] = goffsetto+1; col[2] = goffsetfrom; col[3] = goffsetfrom+1; /* farr[offsetto+1] += -Btt*Vmt*Vmt + Vmt*Vmf*(-Btf*PetscCosScalar(thetatf) + Gtf*PetscSinScalar(thetatf)); */ values[0] = Vmt*Vmf*(Btf*PetscSinScalar(thetatf) + Gtf*PetscCosScalar(thetatf)); values[1] = -2.0*Btt*Vmt + Vmf*(-Btf*PetscCosScalar(thetatf) + Gtf*PetscSinScalar(thetatf)); values[2] = Vmt*Vmf*(-Btf*PetscSinScalar(thetatf) + Gtf*-PetscCosScalar(thetatf)); values[3] = Vmt*(-Btf*PetscCosScalar(thetatf) + Gtf*PetscSinScalar(thetatf)); ierr = MatSetValues(J,1,row,4,col,values,ADD_VALUES);CHKERRQ(ierr); } } } if (!ghostvtex && bus->ide == PV_BUS) { row[0] = goffset+1; col[0] = goffset+1; values[0] = 1.0; ierr = MatSetValues(J,1,row,1,col,values,ADD_VALUES);CHKERRQ(ierr); } } } } ierr = VecRestoreArrayRead(localX,&xarr);CHKERRQ(ierr); ierr = DMRestoreLocalVector(networkdm,&localX);CHKERRQ(ierr); ierr = MatAssemblyBegin(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); PetscFunctionReturn(0); }
PetscErrorCode SetInitialGuess(Vec X,Userctx *user) { PetscErrorCode ierr; Vec Xgen,Xnet; PetscScalar *xgen,*xnet; PetscInt i,idx=0; PetscScalar Vr,Vi,IGr,IGi,Vm,Vm2; PetscScalar Eqp,Edp,delta; PetscScalar Efd,RF,VR; /* Exciter variables */ PetscScalar Id,Iq; /* Generator dq axis currents */ PetscScalar theta,Vd,Vq,SE; PetscFunctionBegin; 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(user->dmpgrid,&Xgen,&Xnet);CHKERRQ(ierr); /* Network subsystem initialization */ ierr = VecCopy(user->V0,Xnet);CHKERRQ(ierr); /* Generator subsystem initialization */ ierr = VecGetArray(Xgen,&xgen);CHKERRQ(ierr); ierr = VecGetArray(Xnet,&xnet);CHKERRQ(ierr); for (i=0; i < ngen; 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 */ Vm = PetscSqrtScalar(Vr*Vr + Vi*Vi); Vm2 = Vm*Vm; IGr = (Vr*PG[i] + Vi*QG[i])/Vm2; IGi = (Vi*PG[i] - Vr*QG[i])/Vm2; delta = atan2(Vi+Xq[i]*IGr,Vr-Xq[i]*IGi); /* Machine angle */ theta = PETSC_PI/2.0 - delta; Id = IGr*PetscCosScalar(theta) - IGi*PetscSinScalar(theta); /* d-axis stator current */ Iq = IGr*PetscSinScalar(theta) + IGi*PetscCosScalar(theta); /* q-axis stator current */ Vd = Vr*PetscCosScalar(theta) - Vi*PetscSinScalar(theta); Vq = Vr*PetscSinScalar(theta) + Vi*PetscCosScalar(theta); Edp = Vd + Rs[i]*Id - Xqp[i]*Iq; /* d-axis transient EMF */ Eqp = Vq + Rs[i]*Iq + Xdp[i]*Id; /* q-axis transient EMF */ TM[i] = PG[i]; /* The generator variables are ordered as [Eqp,Edp,delta,w,Id,Iq] */ xgen[idx] = Eqp; xgen[idx+1] = Edp; xgen[idx+2] = delta; xgen[idx+3] = w_s; idx = idx + 4; xgen[idx] = Id; xgen[idx+1] = Iq; idx = idx + 2; /* Exciter */ Efd = Eqp + (Xd[i] - Xdp[i])*Id; SE = k1[i]*PetscExpScalar(k2[i]*Efd); VR = KE[i]*Efd + SE; RF = KF[i]*Efd/TF[i]; xgen[idx] = Efd; xgen[idx+1] = RF; xgen[idx+2] = VR; Vref[i] = Vm + (VR/KA[i]); idx = idx + 3; } ierr = VecRestoreArray(Xgen,&xgen);CHKERRQ(ierr); ierr = VecRestoreArray(Xnet,&xnet);CHKERRQ(ierr); /* ierr = VecView(Xgen,0);CHKERRQ(ierr); */ ierr = DMCompositeGather(user->dmpgrid,X,INSERT_VALUES,Xgen,Xnet);CHKERRQ(ierr); ierr = DMCompositeRestoreLocalVectors(user->dmpgrid,&Xgen,&Xnet);CHKERRQ(ierr); PetscFunctionReturn(0); }
PetscErrorCode PFReadMatPowerData(PFDATA *pf,char *filename) { FILE *fp; PetscErrorCode ierr; VERTEXDATA Bus; LOAD Load; GEN Gen; EDGEDATA Branch; PetscInt line_counter=0; PetscInt bus_start_line=-1,bus_end_line=-1; /* xx_end_line points to the next line after the record ends */ PetscInt gen_start_line=-1,gen_end_line=-1; PetscInt br_start_line=-1,br_end_line=-1; char line[MAXLINE]; PetscInt loadi=0,geni=0,bri=0,busi=0,i,j; int extbusnum,bustype_i; double Pd,Qd; PetscInt maxbusnum=-1,intbusnum,*busext2intmap,genj,loadj; GEN newgen; LOAD newload; PetscFunctionBegin; fp = fopen(filename,"r"); /* Check for valid file */ if (!fp) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Can't open Matpower data file %s",filename); pf->nload=0; while(fgets(line,MAXLINE,fp)) { if (strstr(line,"mpc.bus")) bus_start_line = line_counter+1; /* Bus data starts from next line */ if (strstr(line,"mpc.gen") && gen_start_line == -1) gen_start_line = line_counter+1; /* Generator data starts from next line */ if (strstr(line,"mpc.branch")) br_start_line = line_counter+1; /* Branch data starts from next line */ if (strstr(line,"];")) { if (bus_start_line != -1 && bus_end_line == -1) bus_end_line = line_counter; if (gen_start_line != -1 && gen_end_line == -1) gen_end_line = line_counter; if (br_start_line != -1 && br_end_line == -1) br_end_line = line_counter; } /* Count the number of pq loads */ if (bus_start_line != -1 && line_counter >= bus_start_line && bus_end_line == -1) { sscanf(line,"%d %d %lf %lf",&extbusnum,&bustype_i,&Pd,&Qd); if (!((Pd == 0.0) && (Qd == 0.0))) pf->nload++; if (extbusnum > maxbusnum) maxbusnum = extbusnum; } line_counter++; } fclose(fp); pf->nbus = bus_end_line - bus_start_line; pf->ngen = gen_end_line - gen_start_line; pf->nbranch = br_end_line - br_start_line; ierr = PetscPrintf(PETSC_COMM_SELF,"nb = %D, ngen = %D, nload = %D, nbranch = %D\n",pf->nbus,pf->ngen,pf->nload,pf->nbranch);CHKERRQ(ierr); ierr = PetscCalloc1(pf->nbus,&pf->bus);CHKERRQ(ierr); ierr = PetscCalloc1(pf->ngen,&pf->gen);CHKERRQ(ierr); ierr = PetscCalloc1(pf->nload,&pf->load);CHKERRQ(ierr); ierr = PetscCalloc1(pf->nbranch,&pf->branch);CHKERRQ(ierr); Bus = pf->bus; Gen = pf->gen; Load = pf->load; Branch = pf->branch; for(i=0; i < pf->nbus; i++) { pf->bus[i].ngen = pf->bus[i].nload = 0; } /* Setting pf->sbase to 100 */ pf->sbase = 100.0; ierr = PetscMalloc1(maxbusnum+1,&busext2intmap);CHKERRQ(ierr); for (i=0; i < maxbusnum+1; i++) busext2intmap[i] = -1; fp = fopen(filename,"r"); /* Reading data */ for (i=0;i<line_counter;i++) { fgets(line,MAXLINE,fp); if ((i >= bus_start_line) && (i < bus_end_line)) { double gl,bl,vm,va,basekV,vmin,vmax; int bus_i,ide,area,zone; /* Bus data */ sscanf(line,"%d %d %lf %lf %lf %lf %d %lf %lf %lf %d %lf %lf", \ &bus_i,&ide,&Pd,&Qd,&gl, \ &bl,&area,&vm,&va,&basekV,&zone,&vmax,&vmin); Bus[busi].bus_i = bus_i; Bus[busi].ide = ide; Bus[busi].area = area; Bus[busi].gl = gl; Bus[busi].bl = bl; Bus[busi].vm = vm; Bus[busi].va = va; Bus[busi].basekV = basekV; Bus[busi].vmin = vmin; Bus[busi].vmax = vmax; Bus[busi].internal_i = busi; busext2intmap[Bus[busi].bus_i] = busi; if (!((Pd == 0.0) && (Qd == 0.0))) { Load[loadi].bus_i = Bus[busi].bus_i; Load[loadi].status = 1; Load[loadi].pl = Pd; Load[loadi].ql = Qd; Load[loadi].area = Bus[busi].area; Load[loadi].internal_i = busi; Bus[busi].lidx[Bus[busi].nload++] = loadi; if (Bus[busi].nload > NLOAD_AT_BUS_MAX) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Exceeded maximum number of loads allowed at bus"); loadi++; } busi++; } /* Read generator data */ if (i >= gen_start_line && i < gen_end_line) { double pg,qg,qt,qb,vs,mbase,pt,pb; int bus_i,status; sscanf(line,"%d %lf %lf %lf %lf %lf %lf %d %lf %lf",&bus_i, \ &pg,&qg,&qt,&qb, \ &vs,&mbase,&status,&pt,&pb); Gen[geni].bus_i = bus_i; Gen[geni].status = status; Gen[geni].pg = pg; Gen[geni].qg = qg; Gen[geni].qt = qt; Gen[geni].qb = qb; Gen[geni].vs = vs; Gen[geni].mbase = mbase; Gen[geni].pt = pt; Gen[geni].pb = pb; intbusnum = busext2intmap[Gen[geni].bus_i]; Gen[geni].internal_i = intbusnum; Bus[intbusnum].gidx[Bus[intbusnum].ngen++] = geni; Bus[intbusnum].vm = Gen[geni].vs; if (Bus[intbusnum].ngen > NGEN_AT_BUS_MAX) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Exceeded maximum number of generators allowed at bus"); geni++; } if (i >= br_start_line && i < br_end_line) { PetscScalar R,X,Bc,B,G,Zm,tap,shift,tap2,tapr,tapi; double r,x,b,rateA,rateB,rateC,tapratio,phaseshift; int fbus,tbus,status; sscanf(line,"%d %d %lf %lf %lf %lf %lf %lf %lf %lf %d",&fbus,&tbus, \ &r,&x,&b,&rateA,&rateB,&rateC, \ &tapratio,&phaseshift,&status); Branch[bri].fbus = fbus; Branch[bri].tbus = tbus; Branch[bri].status = status; Branch[bri].r = r; Branch[bri].x = x; Branch[bri].b = b; Branch[bri].rateA = rateA; Branch[bri].rateB = rateB; Branch[bri].rateC = rateC; Branch[bri].tapratio = tapratio; Branch[bri].phaseshift = phaseshift; if(Branch[bri].tapratio == 0.0) Branch[bri].tapratio = 1.0; Branch[bri].phaseshift *= PETSC_PI/180.0; intbusnum = busext2intmap[Branch[bri].fbus]; Branch[bri].internal_i = intbusnum; intbusnum = busext2intmap[Branch[bri].tbus]; Branch[bri].internal_j = intbusnum; /* Compute self and transfer admittances */ R = Branch[bri].r; X = Branch[bri].x; Bc = Branch[bri].b; Zm = R*R + X*X; G = R/Zm; B = -X/Zm; tap = Branch[bri].tapratio; shift = Branch[bri].phaseshift; tap2 = tap*tap; tapr = tap*PetscCosScalar(shift); tapi = tap*PetscSinScalar(shift); Branch[bri].yff[0] = G/tap2; Branch[bri].yff[1] = (B+Bc/2.0)/tap2; Branch[bri].yft[0] = -(G*tapr - B*tapi)/tap2; Branch[bri].yft[1] = -(B*tapr + G*tapi)/tap2; Branch[bri].ytf[0] = -(G*tapr + B*tapi)/tap2; Branch[bri].ytf[1] = -(B*tapr - G*tapi)/tap2; Branch[bri].ytt[0] = G; Branch[bri].ytt[1] = B+Bc/2.0; bri++; } } fclose(fp); /* Reorder the generator data structure according to bus numbers */ genj=0; loadj=0; ierr = PetscMalloc(pf->ngen*sizeof(struct _p_GEN),&newgen);CHKERRQ(ierr); ierr = PetscMalloc(pf->nload*sizeof(struct _p_LOAD),&newload);CHKERRQ(ierr); for (i = 0; i < pf->nbus; i++) { for (j = 0; j < pf->bus[i].ngen; j++) { ierr = PetscMemcpy(&newgen[genj++],&pf->gen[pf->bus[i].gidx[j]],sizeof(struct _p_GEN)); } for (j = 0; j < pf->bus[i].nload; j++) { ierr = PetscMemcpy(&newload[loadj++],&pf->load[pf->bus[i].lidx[j]],sizeof(struct _p_LOAD)); } } ierr = PetscFree(pf->gen);CHKERRQ(ierr); ierr = PetscFree(pf->load);CHKERRQ(ierr); pf->gen = newgen; pf->load = newload; ierr = PetscFree(busext2intmap);CHKERRQ(ierr); PetscFunctionReturn(0); }
int main(int argc,char **argv) { KSP ksp; DM da; PetscReal norm; PetscErrorCode ierr; PetscInt i,j,k,mx,my,mz,xm,ym,zm,xs,ys,zs; PetscScalar Hx,Hy,Hz; PetscScalar ***array; Vec x,b,r; Mat J; PetscInitialize(&argc,&argv,(char*)0,help); ierr = KSPCreate(PETSC_COMM_WORLD,&ksp);CHKERRQ(ierr); ierr = DMDACreate3d(PETSC_COMM_WORLD,DM_BOUNDARY_NONE,DM_BOUNDARY_NONE,DM_BOUNDARY_NONE,DMDA_STENCIL_STAR,-12,-12,-12,PETSC_DECIDE,PETSC_DECIDE,PETSC_DECIDE,1,1,0,0,0,&da);CHKERRQ(ierr); ierr = DMDASetInterpolationType(da, DMDA_Q0);CHKERRQ(ierr); ierr = KSPSetDM(ksp,da);CHKERRQ(ierr); ierr = KSPSetComputeRHS(ksp,ComputeRHS,NULL);CHKERRQ(ierr); ierr = KSPSetComputeOperators(ksp,ComputeMatrix,NULL);CHKERRQ(ierr); ierr = KSPSetFromOptions(ksp);CHKERRQ(ierr); ierr = KSPSolve(ksp,NULL,NULL);CHKERRQ(ierr); ierr = KSPGetSolution(ksp,&x);CHKERRQ(ierr); ierr = KSPGetRhs(ksp,&b);CHKERRQ(ierr); ierr = KSPGetOperators(ksp,NULL,&J);CHKERRQ(ierr); ierr = VecDuplicate(b,&r);CHKERRQ(ierr); ierr = MatMult(J,x,r);CHKERRQ(ierr); ierr = VecAXPY(r,-1.0,b);CHKERRQ(ierr); ierr = VecNorm(r,NORM_2,&norm);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"Residual norm %g\n",(double)norm);CHKERRQ(ierr); ierr = DMDAGetInfo(da, 0, &mx, &my, &mz, 0,0,0,0,0,0,0,0,0);CHKERRQ(ierr); Hx = 1.0 / (PetscReal)(mx); Hy = 1.0 / (PetscReal)(my); Hz = 1.0 / (PetscReal)(mz); ierr = DMDAGetCorners(da,&xs,&ys,&zs,&xm,&ym,&zm);CHKERRQ(ierr); ierr = DMDAVecGetArray(da, x, &array);CHKERRQ(ierr); for (k=zs; k<zs+zm; k++) { for (j=ys; j<ys+ym; j++) { for (i=xs; i<xs+xm; i++) { array[k][j][i] -= PetscCosScalar(2*PETSC_PI*(((PetscReal)i+0.5)*Hx))* PetscCosScalar(2*PETSC_PI*(((PetscReal)j+0.5)*Hy))* PetscCosScalar(2*PETSC_PI*(((PetscReal)k+0.5)*Hz)); } } } ierr = DMDAVecRestoreArray(da, x, &array);CHKERRQ(ierr); ierr = VecAssemblyBegin(x);CHKERRQ(ierr); ierr = VecAssemblyEnd(x);CHKERRQ(ierr); ierr = VecNorm(x,NORM_INFINITY,&norm);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"Error norm %g\n",(double)norm);CHKERRQ(ierr); ierr = VecNorm(x,NORM_1,&norm);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"Error norm %g\n",(double)(norm/((PetscReal)(mx)*(PetscReal)(my)*(PetscReal)(mz))));CHKERRQ(ierr); ierr = VecNorm(x,NORM_2,&norm);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"Error norm %g\n",(double)(norm/((PetscReal)(mx)*(PetscReal)(my)*(PetscReal)(mz))));CHKERRQ(ierr); ierr = VecDestroy(&r);CHKERRQ(ierr); ierr = KSPDestroy(&ksp);CHKERRQ(ierr); ierr = DMDestroy(&da);CHKERRQ(ierr); 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); }
/* TrueSolution() computes the true solution for the PDE Input Parameter: u - uninitialized solution vector (global) appctx - user-defined application context Output Parameter: u - vector with solution at initial time (global) */ PetscErrorCode TrueSolution(TS ts, PetscReal t, Vec u,AppCtx *appctx) { PetscScalar *s; const PetscScalar *xg; PetscErrorCode ierr; PetscInt i,xs,xn; ierr = DMDAVecGetArray(appctx->da,u,&s);CHKERRQ(ierr); ierr = DMDAVecGetArrayRead(appctx->da,appctx->SEMop.grid,(void*)&xg);CHKERRQ(ierr); ierr = DMDAGetCorners(appctx->da,&xs,NULL,NULL,&xn,NULL,NULL);CHKERRQ(ierr); for (i=xs; i<xs+xn; i++) { s[i]=2.0*appctx->param.mu*PETSC_PI*PetscSinScalar(PETSC_PI*xg[i])*PetscExpReal(-appctx->param.mu*PETSC_PI*PETSC_PI*t)/(2.0+PetscCosScalar(PETSC_PI*xg[i])*PetscExpReal(-appctx->param.mu*PETSC_PI*PETSC_PI*t)); } ierr = DMDAVecRestoreArray(appctx->da,u,&s);CHKERRQ(ierr); ierr = DMDAVecRestoreArrayRead(appctx->da,appctx->SEMop.grid,(void*)&xg);CHKERRQ(ierr); return 0; }
int main(int argc,char **argv) { KSP ksp; DM da; UserContext user; PetscReal norm; const char *bcTypes[2] = {"dirichlet","neumann"}; PetscErrorCode ierr; PetscInt bc; PetscInt i,j,k,mx,my,mz,xm,ym,zm,xs,ys,zs; PetscScalar Hx,Hy,Hz; PetscScalar ***array; Vec x,b,r; Mat J; PetscInitialize(&argc,&argv,(char *)0,help); ierr = KSPCreate(PETSC_COMM_WORLD,&ksp);CHKERRQ(ierr); ierr = DMDACreate3d(PETSC_COMM_WORLD,DMDA_BOUNDARY_NONE,DMDA_BOUNDARY_NONE,DMDA_BOUNDARY_NONE,DMDA_STENCIL_STAR,12,12,12,PETSC_DECIDE,PETSC_DECIDE,PETSC_DECIDE,1,1,0,0,0,&da);CHKERRQ(ierr); ierr = DMDASetInterpolationType(da, DMDA_Q0);CHKERRQ(ierr); ierr = KSPSetDM(ksp,da);CHKERRQ(ierr); ierr = PetscOptionsBegin(PETSC_COMM_WORLD, "", "Options for the inhomogeneous Poisson equation", "DM"); bc = (PetscInt)NEUMANN; ierr = PetscOptionsEList("-bc_type","Type of boundary condition","ex34.c",bcTypes,2,bcTypes[0],&bc,PETSC_NULL);CHKERRQ(ierr); user.bcType = (BCType)bc; ierr = PetscOptionsEnd(); ierr = KSPSetComputeRHS(ksp,ComputeRHS,&user);CHKERRQ(ierr); ierr = KSPSetComputeOperators(ksp,ComputeMatrix,&user);CHKERRQ(ierr); ierr = KSPSetFromOptions(ksp);CHKERRQ(ierr); ierr = KSPSolve(ksp,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); ierr = KSPGetSolution(ksp,&x);CHKERRQ(ierr); ierr = KSPGetRhs(ksp,&b);CHKERRQ(ierr); ierr = KSPGetOperators(ksp,PETSC_NULL,&J,PETSC_NULL);CHKERRQ(ierr); ierr = VecDuplicate(b,&r);CHKERRQ(ierr); ierr = MatMult(J,x,r);CHKERRQ(ierr); ierr = VecAXPY(r,-1.0,b);CHKERRQ(ierr); ierr = VecNorm(r,NORM_2,&norm);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"Residual norm %G\n",norm);CHKERRQ(ierr); ierr = DMDAGetInfo(da, 0, &mx, &my, &mz, 0,0,0,0,0,0,0,0,0);CHKERRQ(ierr); Hx = 1.0 / (PetscReal)(mx); Hy = 1.0 / (PetscReal)(my); Hz = 1.0 / (PetscReal)(mz); ierr = DMDAGetCorners(da,&xs,&ys,&zs,&xm,&ym,&zm);CHKERRQ(ierr); ierr = DMDAVecGetArray(da, x, &array);CHKERRQ(ierr); for (k=zs; k<zs+zm; k++){ for (j=ys; j<ys+ym; j++){ for(i=xs; i<xs+xm; i++){ array[k][j][i] -= PetscCosScalar(2*PETSC_PI*(((PetscReal)i+0.5)*Hx))* PetscCosScalar(2*PETSC_PI*(((PetscReal)j+0.5)*Hy))* PetscCosScalar(2*PETSC_PI*(((PetscReal)k+0.5)*Hz)); } } } ierr = DMDAVecRestoreArray(da, x, &array);CHKERRQ(ierr); ierr = VecAssemblyBegin(x);CHKERRQ(ierr); ierr = VecAssemblyEnd(x);CHKERRQ(ierr); ierr = VecNorm(x,NORM_INFINITY,&norm);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"Error norm %g\n",norm);CHKERRQ(ierr); ierr = VecNorm(x,NORM_1,&norm);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"Error norm %g\n",norm/((PetscReal)(mx)*(PetscReal)(my)*(PetscReal)(mz)));CHKERRQ(ierr); ierr = VecNorm(x,NORM_2,&norm);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"Error norm %g\n",norm/((PetscReal)(mx)*(PetscReal)(my)*(PetscReal)(mz)));CHKERRQ(ierr); ierr = VecDestroy(&r);CHKERRQ(ierr); ierr = KSPDestroy(&ksp);CHKERRQ(ierr); ierr = DMDestroy(&da);CHKERRQ(ierr); ierr = PetscFinalize(); return 0; }