15f25b224SDuncan Campbell static char help[] = "This example demonstrates the use of DMNetwork with subnetworks for solving a coupled nonlinear \n\ 2c4762a1bSJed Brown electric power grid and water pipe problem.\n\ 3c4762a1bSJed Brown The available solver options are in the ex1options file \n\ 4c4762a1bSJed Brown and the data files are in the datafiles of subdirectories.\n\ 5c4762a1bSJed Brown Run this program: mpiexec -n <n> ./ex1 \n\\n"; 65f25b224SDuncan Campbell /* 75f25b224SDuncan Campbell Example: 85f25b224SDuncan Campbell mpiexec -n 3 ./ex1 -petscpartitioner_type parmetis -dmnetwork_view draw -dmnetwork_view_distributed draw -dmnetwork_view_rank_range 0,1,2 9*7cd471e7SHong Zhang mpiexec -n <n> ./ex1 -monitorIteration -monitorColor -power_snes_max_it 0 -water_snes_max_it 0 -coupled_snes_max_it 10 -draw_pause 5.0 105f25b224SDuncan Campbell */ 115f25b224SDuncan Campbell 12c4762a1bSJed Brown #include "power/power.h" 13c4762a1bSJed Brown #include "water/water.h" 14c4762a1bSJed Brown 15c4762a1bSJed Brown typedef struct { 16c4762a1bSJed Brown UserCtx_Power appctx_power; 17c4762a1bSJed Brown AppCtx_Water appctx_water; 18c4762a1bSJed Brown PetscInt subsnes_id; /* snes solver id */ 19c4762a1bSJed Brown PetscInt it; /* iteration number */ 20c4762a1bSJed Brown Vec localXold; /* store previous solution, used by FormFunction_Dummy() */ 21*7cd471e7SHong Zhang PetscBool monitorColor; 22c4762a1bSJed Brown } UserCtx; 23c4762a1bSJed Brown 24*7cd471e7SHong Zhang /* 25*7cd471e7SHong Zhang UserMonitor -- called at the end of every SNES iteration via option `-monitorIteration' or `-monitorColor' 26*7cd471e7SHong Zhang */ 27d71ae5a4SJacob Faibussowitsch PetscErrorCode UserMonitor(SNES snes, PetscInt its, PetscReal fnorm, void *appctx) 28d71ae5a4SJacob Faibussowitsch { 29c4762a1bSJed Brown UserCtx *user = (UserCtx *)appctx; 30c4762a1bSJed Brown PetscMPIInt rank; 31c4762a1bSJed Brown MPI_Comm comm; 32*7cd471e7SHong Zhang PetscInt it; 33c4762a1bSJed Brown 34c4762a1bSJed Brown PetscFunctionBegin; 359566063dSJacob Faibussowitsch PetscCall(PetscObjectGetComm((PetscObject)snes, &comm)); 369566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(comm, &rank)); 37*7cd471e7SHong Zhang 38*7cd471e7SHong Zhang PetscCall(SNESGetIterationNumber(snes, &it)); 39dd400576SPatrick Sanan if (rank == 0) { 40*7cd471e7SHong Zhang PetscCall(SNESGetIterationNumber(snes, &it)); 41*7cd471e7SHong Zhang if (user->subsnes_id == 0 || user->subsnes_id == 1) { 42*7cd471e7SHong Zhang PetscCall(PetscPrintf(PETSC_COMM_SELF, " subsnes_id %" PetscInt_FMT ", it %" PetscInt_FMT ", fnorm %g\n", user->subsnes_id, it, (double)fnorm)); 43c4762a1bSJed Brown } else { 44*7cd471e7SHong Zhang PetscCall(PetscPrintf(PETSC_COMM_SELF, " coupled_snes_it %" PetscInt_FMT ", total_snes_it %" PetscInt_FMT ", fnorm %g\n", it, user->it, (double)fnorm)); 45c4762a1bSJed Brown } 46c4762a1bSJed Brown } 47*7cd471e7SHong Zhang 48*7cd471e7SHong Zhang if (user->monitorColor) { 49*7cd471e7SHong Zhang DM networkdm, dmcoords; 50*7cd471e7SHong Zhang Vec F; 51*7cd471e7SHong Zhang PetscInt v, vStart, vEnd, offset, gidx, rstart; 52*7cd471e7SHong Zhang PetscReal *color; 53*7cd471e7SHong Zhang PetscScalar *farr; 54*7cd471e7SHong Zhang PetscBool ghost; 55*7cd471e7SHong Zhang 569566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &networkdm)); 57*7cd471e7SHong Zhang PetscCall(DMGetCoordinateDM(networkdm, &dmcoords)); 58*7cd471e7SHong Zhang 59*7cd471e7SHong Zhang PetscCall(SNESGetFunction(snes, &F, NULL, NULL)); 60*7cd471e7SHong Zhang PetscCall(VecGetOwnershipRange(F, &rstart, NULL)); 61*7cd471e7SHong Zhang 62*7cd471e7SHong Zhang PetscCall(VecGetArray(F, &farr)); 63*7cd471e7SHong Zhang PetscCall(DMNetworkGetVertexRange(dmcoords, &vStart, &vEnd)); 64*7cd471e7SHong Zhang 65*7cd471e7SHong Zhang PetscCall(PetscPrintf(MPI_COMM_WORLD, "\nColorPrint:\n")); 66*7cd471e7SHong Zhang for (v = vStart; v < vEnd; v++) { 67*7cd471e7SHong Zhang PetscCall(DMNetworkIsGhostVertex(networkdm, v, &ghost)); 68*7cd471e7SHong Zhang PetscCall(DMNetworkGetComponent(dmcoords, v, 0, NULL, (void **)&color, NULL)); 69*7cd471e7SHong Zhang PetscCall(DMNetworkGetGlobalVertexIndex(networkdm, v, &gidx)); 70*7cd471e7SHong Zhang if (!ghost) { 71*7cd471e7SHong Zhang PetscCall(DMNetworkGetGlobalVecOffset(networkdm, v, 0, &offset)); 72*7cd471e7SHong Zhang *color = (PetscRealPart(farr[offset - rstart])); 73*7cd471e7SHong Zhang } 74*7cd471e7SHong Zhang PetscCall(PetscSynchronizedPrintf(MPI_COMM_WORLD, "[%d] v %" PetscInt_FMT ": color[%" PetscInt_FMT "] = %g\n", rank, gidx, offset - rstart, *color)); 75*7cd471e7SHong Zhang } 76*7cd471e7SHong Zhang PetscCall(PetscSynchronizedFlush(MPI_COMM_WORLD, NULL)); 77*7cd471e7SHong Zhang PetscCall(VecRestoreArray(F, &farr)); 78*7cd471e7SHong Zhang 79*7cd471e7SHong Zhang PetscCall(PetscViewerPushFormat(PETSC_VIEWER_STDOUT_WORLD, PETSC_VIEWER_ASCII_CSV)); 80*7cd471e7SHong Zhang PetscCall(DMView(networkdm, PETSC_VIEWER_DRAW_WORLD)); 81*7cd471e7SHong Zhang PetscCall(PetscViewerPopFormat(PETSC_VIEWER_STDOUT_WORLD)); 82*7cd471e7SHong Zhang } 833ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 84c4762a1bSJed Brown } 85c4762a1bSJed Brown 86d71ae5a4SJacob Faibussowitsch PetscErrorCode FormJacobian_subPower(SNES snes, Vec X, Mat J, Mat Jpre, void *appctx) 87d71ae5a4SJacob Faibussowitsch { 88c4762a1bSJed Brown DM networkdm; 89c4762a1bSJed Brown Vec localX; 90c4762a1bSJed Brown PetscInt nv, ne, i, j, offset, nvar, row; 91c4762a1bSJed Brown const PetscInt *vtx, *edges; 92c4762a1bSJed Brown PetscBool ghostvtex; 93c4762a1bSJed Brown PetscScalar one = 1.0; 94c4762a1bSJed Brown PetscMPIInt rank; 95c4762a1bSJed Brown MPI_Comm comm; 96c4762a1bSJed Brown 97c4762a1bSJed Brown PetscFunctionBegin; 989566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &networkdm)); 999566063dSJacob Faibussowitsch PetscCall(DMGetLocalVector(networkdm, &localX)); 100c4762a1bSJed Brown 1019566063dSJacob Faibussowitsch PetscCall(PetscObjectGetComm((PetscObject)networkdm, &comm)); 1029566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(comm, &rank)); 103c4762a1bSJed Brown 1049566063dSJacob Faibussowitsch PetscCall(DMGlobalToLocalBegin(networkdm, X, INSERT_VALUES, localX)); 1059566063dSJacob Faibussowitsch PetscCall(DMGlobalToLocalEnd(networkdm, X, INSERT_VALUES, localX)); 106c4762a1bSJed Brown 1079566063dSJacob Faibussowitsch PetscCall(MatZeroEntries(J)); 108c4762a1bSJed Brown 109c4762a1bSJed Brown /* Power subnetwork: copied from power/FormJacobian_Power() */ 1109566063dSJacob Faibussowitsch PetscCall(DMNetworkGetSubnetwork(networkdm, 0, &nv, &ne, &vtx, &edges)); 1119566063dSJacob Faibussowitsch PetscCall(FormJacobian_Power_private(networkdm, localX, J, nv, ne, vtx, edges, appctx)); 112c4762a1bSJed Brown 113c4762a1bSJed Brown /* Water subnetwork: Identity */ 1149566063dSJacob Faibussowitsch PetscCall(DMNetworkGetSubnetwork(networkdm, 1, &nv, &ne, &vtx, &edges)); 115c4762a1bSJed Brown for (i = 0; i < nv; i++) { 1169566063dSJacob Faibussowitsch PetscCall(DMNetworkIsGhostVertex(networkdm, vtx[i], &ghostvtex)); 117c4762a1bSJed Brown if (ghostvtex) continue; 118c4762a1bSJed Brown 1199566063dSJacob Faibussowitsch PetscCall(DMNetworkGetGlobalVecOffset(networkdm, vtx[i], ALL_COMPONENTS, &offset)); 1209566063dSJacob Faibussowitsch PetscCall(DMNetworkGetComponent(networkdm, vtx[i], ALL_COMPONENTS, NULL, NULL, &nvar)); 121c4762a1bSJed Brown for (j = 0; j < nvar; j++) { 122c4762a1bSJed Brown row = offset + j; 1239566063dSJacob Faibussowitsch PetscCall(MatSetValues(J, 1, &row, 1, &row, &one, ADD_VALUES)); 124c4762a1bSJed Brown } 125c4762a1bSJed Brown } 1269566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(J, MAT_FINAL_ASSEMBLY)); 1279566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(J, MAT_FINAL_ASSEMBLY)); 128c4762a1bSJed Brown 1299566063dSJacob Faibussowitsch PetscCall(DMRestoreLocalVector(networkdm, &localX)); 1303ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 131c4762a1bSJed Brown } 132c4762a1bSJed Brown 133c4762a1bSJed Brown /* Dummy equation localF(X) = localX - localXold */ 134d71ae5a4SJacob Faibussowitsch PetscErrorCode FormFunction_Dummy(DM networkdm, Vec localX, Vec localF, PetscInt nv, PetscInt ne, const PetscInt *vtx, const PetscInt *edges, void *appctx) 135d71ae5a4SJacob Faibussowitsch { 136c4762a1bSJed Brown const PetscScalar *xarr, *xoldarr; 137c4762a1bSJed Brown PetscScalar *farr; 138c4762a1bSJed Brown PetscInt i, j, offset, nvar; 139c4762a1bSJed Brown PetscBool ghostvtex; 140c4762a1bSJed Brown UserCtx *user = (UserCtx *)appctx; 141c4762a1bSJed Brown Vec localXold = user->localXold; 142c4762a1bSJed Brown 143c4762a1bSJed Brown PetscFunctionBegin; 1449566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(localX, &xarr)); 1459566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(localXold, &xoldarr)); 1469566063dSJacob Faibussowitsch PetscCall(VecGetArray(localF, &farr)); 147c4762a1bSJed Brown 148c4762a1bSJed Brown for (i = 0; i < nv; i++) { 1499566063dSJacob Faibussowitsch PetscCall(DMNetworkIsGhostVertex(networkdm, vtx[i], &ghostvtex)); 150c4762a1bSJed Brown if (ghostvtex) continue; 151c4762a1bSJed Brown 1529566063dSJacob Faibussowitsch PetscCall(DMNetworkGetLocalVecOffset(networkdm, vtx[i], ALL_COMPONENTS, &offset)); 1539566063dSJacob Faibussowitsch PetscCall(DMNetworkGetComponent(networkdm, vtx[i], ALL_COMPONENTS, NULL, NULL, &nvar)); 154ad540459SPierre Jolivet for (j = 0; j < nvar; j++) farr[offset + j] = xarr[offset + j] - xoldarr[offset + j]; 155c4762a1bSJed Brown } 156c4762a1bSJed Brown 1579566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(localX, &xarr)); 1589566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(localXold, &xoldarr)); 1599566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(localF, &farr)); 1603ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 161c4762a1bSJed Brown } 162c4762a1bSJed Brown 163d71ae5a4SJacob Faibussowitsch PetscErrorCode FormFunction(SNES snes, Vec X, Vec F, void *appctx) 164d71ae5a4SJacob Faibussowitsch { 165c4762a1bSJed Brown DM networkdm; 166c4762a1bSJed Brown Vec localX, localF; 1672bf73ac6SHong Zhang PetscInt nv, ne, v; 168c4762a1bSJed Brown const PetscInt *vtx, *edges; 169c4762a1bSJed Brown PetscMPIInt rank; 170c4762a1bSJed Brown MPI_Comm comm; 171c4762a1bSJed Brown UserCtx *user = (UserCtx *)appctx; 172c4762a1bSJed Brown UserCtx_Power appctx_power = (*user).appctx_power; 1732bf73ac6SHong Zhang AppCtx_Water appctx_water = (*user).appctx_water; 174c4762a1bSJed Brown 175c4762a1bSJed Brown PetscFunctionBegin; 1769566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &networkdm)); 1779566063dSJacob Faibussowitsch PetscCall(PetscObjectGetComm((PetscObject)networkdm, &comm)); 1789566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(comm, &rank)); 179c4762a1bSJed Brown 1809566063dSJacob Faibussowitsch PetscCall(DMGetLocalVector(networkdm, &localX)); 1819566063dSJacob Faibussowitsch PetscCall(DMGetLocalVector(networkdm, &localF)); 1829566063dSJacob Faibussowitsch PetscCall(VecSet(F, 0.0)); 1839566063dSJacob Faibussowitsch PetscCall(VecSet(localF, 0.0)); 184c4762a1bSJed Brown 1859566063dSJacob Faibussowitsch PetscCall(DMGlobalToLocalBegin(networkdm, X, INSERT_VALUES, localX)); 1869566063dSJacob Faibussowitsch PetscCall(DMGlobalToLocalEnd(networkdm, X, INSERT_VALUES, localX)); 187c4762a1bSJed Brown 188c4762a1bSJed Brown /* Form Function for power subnetwork */ 1899566063dSJacob Faibussowitsch PetscCall(DMNetworkGetSubnetwork(networkdm, 0, &nv, &ne, &vtx, &edges)); 190c4762a1bSJed Brown if (user->subsnes_id == 1) { /* snes_water only */ 1919566063dSJacob Faibussowitsch PetscCall(FormFunction_Dummy(networkdm, localX, localF, nv, ne, vtx, edges, user)); 192c4762a1bSJed Brown } else { 1939566063dSJacob Faibussowitsch PetscCall(FormFunction_Power(networkdm, localX, localF, nv, ne, vtx, edges, &appctx_power)); 194c4762a1bSJed Brown } 195c4762a1bSJed Brown 196c4762a1bSJed Brown /* Form Function for water subnetwork */ 1979566063dSJacob Faibussowitsch PetscCall(DMNetworkGetSubnetwork(networkdm, 1, &nv, &ne, &vtx, &edges)); 198c4762a1bSJed Brown if (user->subsnes_id == 0) { /* snes_power only */ 1999566063dSJacob Faibussowitsch PetscCall(FormFunction_Dummy(networkdm, localX, localF, nv, ne, vtx, edges, user)); 200c4762a1bSJed Brown } else { 2019566063dSJacob Faibussowitsch PetscCall(FormFunction_Water(networkdm, localX, localF, nv, ne, vtx, edges, NULL)); 202c4762a1bSJed Brown } 203c4762a1bSJed Brown 2042bf73ac6SHong Zhang /* Illustrate how to access the coupling vertex of the subnetworks without doing anything to F yet */ 2059566063dSJacob Faibussowitsch PetscCall(DMNetworkGetSharedVertices(networkdm, &nv, &vtx)); 2062bf73ac6SHong Zhang for (v = 0; v < nv; v++) { 2072bf73ac6SHong Zhang PetscInt key, ncomp, nvar, nconnedges, k, e, keye, goffset[3]; 208c4762a1bSJed Brown void *component; 2092bf73ac6SHong Zhang const PetscInt *connedges; 210c4762a1bSJed Brown 2119566063dSJacob Faibussowitsch PetscCall(DMNetworkGetComponent(networkdm, vtx[v], ALL_COMPONENTS, NULL, NULL, &nvar)); 2129566063dSJacob Faibussowitsch PetscCall(DMNetworkGetNumComponents(networkdm, vtx[v], &ncomp)); 21363a3b9bcSJacob Faibussowitsch /* printf(" [%d] coupling vertex[%" PetscInt_FMT "]: v %" PetscInt_FMT ", ncomp %" PetscInt_FMT "; nvar %" PetscInt_FMT "\n",rank,v,vtx[v], ncomp,nvar); */ 214c4762a1bSJed Brown 2152bf73ac6SHong Zhang for (k = 0; k < ncomp; k++) { 2169566063dSJacob Faibussowitsch PetscCall(DMNetworkGetComponent(networkdm, vtx[v], k, &key, &component, &nvar)); 2179566063dSJacob Faibussowitsch PetscCall(DMNetworkGetGlobalVecOffset(networkdm, vtx[v], k, &goffset[k])); 218c4762a1bSJed Brown 2192bf73ac6SHong Zhang /* Verify the coupling vertex is a powernet load vertex or a water vertex */ 2202bf73ac6SHong Zhang switch (k) { 221d71ae5a4SJacob Faibussowitsch case 0: 222d71ae5a4SJacob Faibussowitsch PetscCheck(key == appctx_power.compkey_bus && nvar == 2, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "key %" PetscInt_FMT " not a power bus vertex or nvar %" PetscInt_FMT " != 2", key, nvar); 223d71ae5a4SJacob Faibussowitsch break; 224d71ae5a4SJacob Faibussowitsch case 1: 225d71ae5a4SJacob Faibussowitsch PetscCheck(key == appctx_power.compkey_load && nvar == 0 && goffset[1] == goffset[0] + 2, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Not a power load vertex"); 226d71ae5a4SJacob Faibussowitsch break; 227d71ae5a4SJacob Faibussowitsch case 2: 228d71ae5a4SJacob Faibussowitsch PetscCheck(key == appctx_water.compkey_vtx && nvar == 1 && goffset[2] == goffset[1], PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Not a water vertex"); 229d71ae5a4SJacob Faibussowitsch break; 230d71ae5a4SJacob Faibussowitsch default: 231d71ae5a4SJacob Faibussowitsch SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "k %" PetscInt_FMT " is wrong", k); 2322bf73ac6SHong Zhang } 23363a3b9bcSJacob Faibussowitsch /* printf(" [%d] coupling vertex[%" PetscInt_FMT "]: key %" PetscInt_FMT "; nvar %" PetscInt_FMT ", goffset %" PetscInt_FMT "\n",rank,v,key,nvar,goffset[k]); */ 2342bf73ac6SHong Zhang } 235c4762a1bSJed Brown 2362bf73ac6SHong Zhang /* Get its supporting edges */ 2379566063dSJacob Faibussowitsch PetscCall(DMNetworkGetSupportingEdges(networkdm, vtx[v], &nconnedges, &connedges)); 23863a3b9bcSJacob Faibussowitsch /* printf("\n[%d] coupling vertex: nconnedges %" PetscInt_FMT "\n",rank,nconnedges); */ 239c4762a1bSJed Brown for (k = 0; k < nconnedges; k++) { 240c4762a1bSJed Brown e = connedges[k]; 2419566063dSJacob Faibussowitsch PetscCall(DMNetworkGetNumComponents(networkdm, e, &ncomp)); 24263a3b9bcSJacob Faibussowitsch /* printf("\n [%d] connected edge[%" PetscInt_FMT "]=%" PetscInt_FMT " has ncomp %" PetscInt_FMT "\n",rank,k,e,ncomp); */ 2439566063dSJacob Faibussowitsch PetscCall(DMNetworkGetComponent(networkdm, e, 0, &keye, &component, NULL)); 244ad540459SPierre Jolivet if (keye != appctx_water.compkey_edge) PetscCheck(keye == appctx_power.compkey_branch, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Not a power branch"); 245c4762a1bSJed Brown } 246c4762a1bSJed Brown } 247c4762a1bSJed Brown 2489566063dSJacob Faibussowitsch PetscCall(DMRestoreLocalVector(networkdm, &localX)); 249c4762a1bSJed Brown 2509566063dSJacob Faibussowitsch PetscCall(DMLocalToGlobalBegin(networkdm, localF, ADD_VALUES, F)); 2519566063dSJacob Faibussowitsch PetscCall(DMLocalToGlobalEnd(networkdm, localF, ADD_VALUES, F)); 2529566063dSJacob Faibussowitsch PetscCall(DMRestoreLocalVector(networkdm, &localF)); 2532bf73ac6SHong Zhang #if 0 254dd400576SPatrick Sanan if (rank == 0) printf("F:\n"); 2559566063dSJacob Faibussowitsch PetscCall(VecView(F,PETSC_VIEWER_STDOUT_WORLD)); 2562bf73ac6SHong Zhang #endif 2573ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 258c4762a1bSJed Brown } 259c4762a1bSJed Brown 260d71ae5a4SJacob Faibussowitsch PetscErrorCode SetInitialGuess(DM networkdm, Vec X, void *appctx) 261d71ae5a4SJacob Faibussowitsch { 2622bf73ac6SHong Zhang PetscInt nv, ne, i, j, ncomp, offset, key; 263c4762a1bSJed Brown const PetscInt *vtx, *edges; 264c4762a1bSJed Brown UserCtx *user = (UserCtx *)appctx; 265c4762a1bSJed Brown Vec localX = user->localXold; 266c4762a1bSJed Brown UserCtx_Power appctx_power = (*user).appctx_power; 2672bf73ac6SHong Zhang AppCtx_Water appctx_water = (*user).appctx_water; 2682bf73ac6SHong Zhang PetscBool ghost; 2692bf73ac6SHong Zhang PetscScalar *xarr; 2702bf73ac6SHong Zhang VERTEX_Power bus; 2712bf73ac6SHong Zhang VERTEX_Water vertex; 2722bf73ac6SHong Zhang void *component; 2732bf73ac6SHong Zhang GEN gen; 274c4762a1bSJed Brown 275c4762a1bSJed Brown PetscFunctionBegin; 2769566063dSJacob Faibussowitsch PetscCall(VecSet(X, 0.0)); 2779566063dSJacob Faibussowitsch PetscCall(VecSet(localX, 0.0)); 278c4762a1bSJed Brown 279c4762a1bSJed Brown /* Set initial guess for power subnetwork */ 2809566063dSJacob Faibussowitsch PetscCall(DMNetworkGetSubnetwork(networkdm, 0, &nv, &ne, &vtx, &edges)); 2819566063dSJacob Faibussowitsch PetscCall(SetInitialGuess_Power(networkdm, localX, nv, ne, vtx, edges, &appctx_power)); 282c4762a1bSJed Brown 283c4762a1bSJed Brown /* Set initial guess for water subnetwork */ 2849566063dSJacob Faibussowitsch PetscCall(DMNetworkGetSubnetwork(networkdm, 1, &nv, &ne, &vtx, &edges)); 2859566063dSJacob Faibussowitsch PetscCall(SetInitialGuess_Water(networkdm, localX, nv, ne, vtx, edges, NULL)); 286c4762a1bSJed Brown 2872bf73ac6SHong Zhang /* Set initial guess at the coupling vertex */ 2889566063dSJacob Faibussowitsch PetscCall(VecGetArray(localX, &xarr)); 2899566063dSJacob Faibussowitsch PetscCall(DMNetworkGetSharedVertices(networkdm, &nv, &vtx)); 2902bf73ac6SHong Zhang for (i = 0; i < nv; i++) { 2919566063dSJacob Faibussowitsch PetscCall(DMNetworkIsGhostVertex(networkdm, vtx[i], &ghost)); 2922bf73ac6SHong Zhang if (ghost) continue; 2932bf73ac6SHong Zhang 2949566063dSJacob Faibussowitsch PetscCall(DMNetworkGetNumComponents(networkdm, vtx[i], &ncomp)); 2952bf73ac6SHong Zhang for (j = 0; j < ncomp; j++) { 2969566063dSJacob Faibussowitsch PetscCall(DMNetworkGetLocalVecOffset(networkdm, vtx[i], j, &offset)); 2979566063dSJacob Faibussowitsch PetscCall(DMNetworkGetComponent(networkdm, vtx[i], j, &key, (void **)&component, NULL)); 2982bf73ac6SHong Zhang if (key == appctx_power.compkey_bus) { 2992bf73ac6SHong Zhang bus = (VERTEX_Power)(component); 3002bf73ac6SHong Zhang xarr[offset] = bus->va * PETSC_PI / 180.0; 3012bf73ac6SHong Zhang xarr[offset + 1] = bus->vm; 3022bf73ac6SHong Zhang } else if (key == appctx_power.compkey_gen) { 3032bf73ac6SHong Zhang gen = (GEN)(component); 3042bf73ac6SHong Zhang if (!gen->status) continue; 3052bf73ac6SHong Zhang xarr[offset + 1] = gen->vs; 3062bf73ac6SHong Zhang } else if (key == appctx_water.compkey_vtx) { 3072bf73ac6SHong Zhang vertex = (VERTEX_Water)(component); 3082bf73ac6SHong Zhang if (vertex->type == VERTEX_TYPE_JUNCTION) { 3092bf73ac6SHong Zhang xarr[offset] = 100; 3102bf73ac6SHong Zhang } else if (vertex->type == VERTEX_TYPE_RESERVOIR) { 3112bf73ac6SHong Zhang xarr[offset] = vertex->res.head; 3122bf73ac6SHong Zhang } else { 3132bf73ac6SHong Zhang xarr[offset] = vertex->tank.initlvl + vertex->tank.elev; 314c4762a1bSJed Brown } 3152bf73ac6SHong Zhang } 3162bf73ac6SHong Zhang } 3172bf73ac6SHong Zhang } 3189566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(localX, &xarr)); 319c4762a1bSJed Brown 3209566063dSJacob Faibussowitsch PetscCall(DMLocalToGlobalBegin(networkdm, localX, ADD_VALUES, X)); 3219566063dSJacob Faibussowitsch PetscCall(DMLocalToGlobalEnd(networkdm, localX, ADD_VALUES, X)); 3223ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 323c4762a1bSJed Brown } 324c4762a1bSJed Brown 325cc13d412SHong Zhang /* Set coordinates */ 326*7cd471e7SHong Zhang static PetscErrorCode CoordinateVecSetUp(DM dmcoords, Vec coords) 327cc13d412SHong Zhang { 328cc13d412SHong Zhang PetscInt i, gidx, offset, v, nv, Nsubnet; 329cc13d412SHong Zhang const PetscInt *vtx; 330cc13d412SHong Zhang PetscScalar *carray; 331*7cd471e7SHong Zhang PetscReal *color; 332cc13d412SHong Zhang 333cc13d412SHong Zhang PetscFunctionBeginUser; 334cc13d412SHong Zhang PetscCall(VecGetArrayWrite(coords, &carray)); 335*7cd471e7SHong Zhang PetscCall(DMNetworkGetNumSubNetworks(dmcoords, NULL, &Nsubnet)); 336cc13d412SHong Zhang for (i = 0; i < Nsubnet; i++) { 337*7cd471e7SHong Zhang PetscCall(DMNetworkGetSubnetwork(dmcoords, i, &nv, NULL, &vtx, NULL)); 338cc13d412SHong Zhang for (v = 0; v < nv; v++) { 339*7cd471e7SHong Zhang PetscCall(DMNetworkGetGlobalVertexIndex(dmcoords, vtx[v], &gidx)); 340*7cd471e7SHong Zhang PetscCall(DMNetworkGetLocalVecOffset(dmcoords, vtx[v], 0, &offset)); 341*7cd471e7SHong Zhang PetscCall(DMNetworkGetComponent(dmcoords, vtx[v], 0, NULL, (void **)&color, NULL)); 342*7cd471e7SHong Zhang *color = 0.0; 343cc13d412SHong Zhang switch (gidx) { 344cc13d412SHong Zhang case 0: 345cc13d412SHong Zhang carray[offset] = -1.0; 346cc13d412SHong Zhang carray[offset + 1] = -1.0; 347cc13d412SHong Zhang break; 348cc13d412SHong Zhang case 1: 349cc13d412SHong Zhang carray[offset] = -2.0; 350cc13d412SHong Zhang carray[offset + 1] = 2.0; 351cc13d412SHong Zhang break; 352cc13d412SHong Zhang case 2: 353cc13d412SHong Zhang carray[offset] = 0.0; 354cc13d412SHong Zhang carray[offset + 1] = 2.0; 355cc13d412SHong Zhang break; 356cc13d412SHong Zhang case 3: 357cc13d412SHong Zhang carray[offset] = -1.0; 358cc13d412SHong Zhang carray[offset + 1] = 0.0; 359cc13d412SHong Zhang break; 360cc13d412SHong Zhang case 4: 361cc13d412SHong Zhang carray[offset] = 0.0; 362cc13d412SHong Zhang carray[offset + 1] = 0.0; 363cc13d412SHong Zhang break; 364cc13d412SHong Zhang case 5: 365cc13d412SHong Zhang carray[offset] = 0.0; 366cc13d412SHong Zhang carray[offset + 1] = 1.0; 367cc13d412SHong Zhang break; 368cc13d412SHong Zhang case 6: 369cc13d412SHong Zhang carray[offset] = -1.0; 370cc13d412SHong Zhang carray[offset + 1] = 1.0; 371cc13d412SHong Zhang break; 372cc13d412SHong Zhang case 7: 373cc13d412SHong Zhang carray[offset] = -2.0; 374cc13d412SHong Zhang carray[offset + 1] = 1.0; 375cc13d412SHong Zhang break; 376cc13d412SHong Zhang case 8: 377cc13d412SHong Zhang carray[offset] = -2.0; 378cc13d412SHong Zhang carray[offset + 1] = 0.0; 379cc13d412SHong Zhang break; 380cc13d412SHong Zhang case 9: 381cc13d412SHong Zhang carray[offset] = 1.0; 382cc13d412SHong Zhang carray[offset + 1] = 0.0; 383cc13d412SHong Zhang break; 384cc13d412SHong Zhang case 10: 385cc13d412SHong Zhang carray[offset] = 1.0; 386cc13d412SHong Zhang carray[offset + 1] = -1.0; 387cc13d412SHong Zhang break; 388cc13d412SHong Zhang case 11: 389cc13d412SHong Zhang carray[offset] = 2.0; 390cc13d412SHong Zhang carray[offset + 1] = -1.0; 391cc13d412SHong Zhang break; 392cc13d412SHong Zhang case 12: 393cc13d412SHong Zhang carray[offset] = 2.0; 394cc13d412SHong Zhang carray[offset + 1] = 0.0; 395cc13d412SHong Zhang break; 396cc13d412SHong Zhang case 13: 397cc13d412SHong Zhang carray[offset] = 0.0; 398cc13d412SHong Zhang carray[offset + 1] = -1.0; 399cc13d412SHong Zhang break; 400cc13d412SHong Zhang case 14: 401cc13d412SHong Zhang carray[offset] = 2.0; 402cc13d412SHong Zhang carray[offset + 1] = 1.0; 403cc13d412SHong Zhang break; 404cc13d412SHong Zhang default: 405cc13d412SHong Zhang PetscCheck(gidx < 15 && gidx > -1, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "gidx %" PetscInt_FMT "must between 0 and 14", gidx); 406cc13d412SHong Zhang } 407cc13d412SHong Zhang } 408cc13d412SHong Zhang } 409cc13d412SHong Zhang PetscCall(VecRestoreArrayWrite(coords, &carray)); 410cc13d412SHong Zhang PetscFunctionReturn(PETSC_SUCCESS); 411cc13d412SHong Zhang } 412cc13d412SHong Zhang 413cc13d412SHong Zhang static PetscErrorCode CoordinatePrint(DM dm) 414cc13d412SHong Zhang { 415*7cd471e7SHong Zhang DM dmcoords; 416cc13d412SHong Zhang PetscInt cdim, v, off, vglobal, vStart, vEnd; 417cc13d412SHong Zhang const PetscScalar *carray; 418cc13d412SHong Zhang Vec coords; 419cc13d412SHong Zhang MPI_Comm comm; 420cc13d412SHong Zhang PetscMPIInt rank; 421cc13d412SHong Zhang 422cc13d412SHong Zhang PetscFunctionBegin; 423*7cd471e7SHong Zhang /* get info from dm */ 424*7cd471e7SHong Zhang PetscCall(DMGetCoordinateDim(dm, &cdim)); 425cc13d412SHong Zhang PetscCall(DMGetCoordinatesLocal(dm, &coords)); 426cc13d412SHong Zhang 427*7cd471e7SHong Zhang PetscCall(DMGetCoordinateDM(dm, &dmcoords)); 428*7cd471e7SHong Zhang PetscCall(PetscObjectGetComm((PetscObject)dmcoords, &comm)); 429*7cd471e7SHong Zhang PetscCallMPI(MPI_Comm_rank(comm, &rank)); 430cc13d412SHong Zhang 431*7cd471e7SHong Zhang /* print coordinates from dmcoords */ 432cc13d412SHong Zhang PetscCall(PetscPrintf(MPI_COMM_WORLD, "\nCoordinatePrint, cdim %" PetscInt_FMT ":\n", cdim)); 433*7cd471e7SHong Zhang PetscCall(PetscSynchronizedPrintf(MPI_COMM_WORLD, "[%d]\n", rank)); 434*7cd471e7SHong Zhang 435*7cd471e7SHong Zhang PetscCall(DMNetworkGetVertexRange(dmcoords, &vStart, &vEnd)); 436*7cd471e7SHong Zhang PetscCall(VecGetArrayRead(coords, &carray)); 437cc13d412SHong Zhang for (v = vStart; v < vEnd; v++) { 438*7cd471e7SHong Zhang PetscCall(DMNetworkGetLocalVecOffset(dmcoords, v, 0, &off)); 439*7cd471e7SHong Zhang PetscCall(DMNetworkGetGlobalVertexIndex(dmcoords, v, &vglobal)); 440cc13d412SHong Zhang switch (cdim) { 441cc13d412SHong Zhang case 2: 442cc13d412SHong Zhang PetscCall(PetscSynchronizedPrintf(MPI_COMM_WORLD, "Vertex: %" PetscInt_FMT ", x = %f y = %f \n", vglobal, (double)PetscRealPart(carray[off]), (double)PetscRealPart(carray[off + 1]))); 443cc13d412SHong Zhang break; 444cc13d412SHong Zhang default: 445cc13d412SHong Zhang PetscCheck(cdim == 2, MPI_COMM_WORLD, PETSC_ERR_SUP, "Only supports Network embedding dimension of 2, not supplied %" PetscInt_FMT, cdim); 446cc13d412SHong Zhang break; 447cc13d412SHong Zhang } 448cc13d412SHong Zhang } 449cc13d412SHong Zhang PetscCall(PetscSynchronizedFlush(MPI_COMM_WORLD, NULL)); 450cc13d412SHong Zhang PetscCall(VecRestoreArrayRead(coords, &carray)); 451cc13d412SHong Zhang PetscFunctionReturn(PETSC_SUCCESS); 452cc13d412SHong Zhang } 453cc13d412SHong Zhang 454d71ae5a4SJacob Faibussowitsch int main(int argc, char **argv) 455d71ae5a4SJacob Faibussowitsch { 456*7cd471e7SHong Zhang DM networkdm, dmcoords; 457d5c9c0c4SHong Zhang PetscMPIInt rank, size; 4582bf73ac6SHong Zhang PetscInt Nsubnet = 2, numVertices[2], numEdges[2], i, j, nv, ne, it_max = 10; 459cc13d412SHong Zhang PetscInt vStart, vEnd, compkey; 460c4762a1bSJed Brown const PetscInt *vtx, *edges; 461*7cd471e7SHong Zhang PetscReal *color; 462cc13d412SHong Zhang Vec X, F, coords; 463c4762a1bSJed Brown SNES snes, snes_power, snes_water; 464c4762a1bSJed Brown Mat Jac; 465*7cd471e7SHong Zhang PetscBool ghost, viewJ = PETSC_FALSE, viewX = PETSC_FALSE, test = PETSC_FALSE, distribute = PETSC_TRUE, flg, printCoord = PETSC_FALSE, viewCSV = PETSC_FALSE, monitorIt = PETSC_FALSE; 466c4762a1bSJed Brown UserCtx user; 467c4762a1bSJed Brown SNESConvergedReason reason; 4684279555eSSatish Balay #if defined(PETSC_USE_LOG) 4694279555eSSatish Balay PetscLogStage stage[4]; 4704279555eSSatish Balay #endif 471c4762a1bSJed Brown 472c4762a1bSJed Brown /* Power subnetwork */ 473c4762a1bSJed Brown UserCtx_Power *appctx_power = &user.appctx_power; 474c4762a1bSJed Brown char pfdata_file[PETSC_MAX_PATH_LEN] = "power/case9.m"; 475c4762a1bSJed Brown PFDATA *pfdata = NULL; 4762bf73ac6SHong Zhang PetscInt genj, loadj, *edgelist_power = NULL, power_netnum; 477c4762a1bSJed Brown PetscScalar Sbase = 0.0; 478c4762a1bSJed Brown 479c4762a1bSJed Brown /* Water subnetwork */ 480c4762a1bSJed Brown AppCtx_Water *appctx_water = &user.appctx_water; 481c4762a1bSJed Brown WATERDATA *waterdata = NULL; 482c4762a1bSJed Brown char waterdata_file[PETSC_MAX_PATH_LEN] = "water/sample1.inp"; 4832bf73ac6SHong Zhang PetscInt *edgelist_water = NULL, water_netnum; 484c4762a1bSJed Brown 4852bf73ac6SHong Zhang /* Shared vertices between subnetworks */ 4862bf73ac6SHong Zhang PetscInt power_svtx, water_svtx; 487c4762a1bSJed Brown 488327415f7SBarry Smith PetscFunctionBeginUser; 4899566063dSJacob Faibussowitsch PetscCall(PetscInitialize(&argc, &argv, "ex1options", help)); 4909566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(PETSC_COMM_WORLD, &rank)); 4919566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_size(PETSC_COMM_WORLD, &size)); 492c4762a1bSJed Brown 493c4762a1bSJed Brown /* (1) Read Data - Only rank 0 reads the data */ 4949566063dSJacob Faibussowitsch PetscCall(PetscLogStageRegister("Read Data", &stage[0])); 4959566063dSJacob Faibussowitsch PetscCall(PetscLogStagePush(stage[0])); 496c4762a1bSJed Brown 4972bf73ac6SHong Zhang for (i = 0; i < Nsubnet; i++) { 498c4762a1bSJed Brown numVertices[i] = 0; 499c4762a1bSJed Brown numEdges[i] = 0; 500c4762a1bSJed Brown } 501c4762a1bSJed Brown 5022bf73ac6SHong Zhang /* All processes READ THE DATA FOR THE FIRST SUBNETWORK: Electric Power Grid */ 5032bf73ac6SHong Zhang /* Used for shared vertex, because currently the coupling info must be available in all processes!!! */ 5049566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetString(NULL, NULL, "-pfdata", pfdata_file, PETSC_MAX_PATH_LEN - 1, NULL)); 5059566063dSJacob Faibussowitsch PetscCall(PetscNew(&pfdata)); 5069566063dSJacob Faibussowitsch PetscCall(PFReadMatPowerData(pfdata, pfdata_file)); 50748a46eb9SPierre Jolivet if (rank == 0) PetscCall(PetscPrintf(PETSC_COMM_SELF, "Power network: nb = %" PetscInt_FMT ", ngen = %" PetscInt_FMT ", nload = %" PetscInt_FMT ", nbranch = %" PetscInt_FMT "\n", pfdata->nbus, pfdata->ngen, pfdata->nload, pfdata->nbranch)); 508c4762a1bSJed Brown Sbase = pfdata->sbase; 5092bf73ac6SHong Zhang if (rank == 0) { /* proc[0] will create Electric Power Grid */ 510c4762a1bSJed Brown numEdges[0] = pfdata->nbranch; 511c4762a1bSJed Brown numVertices[0] = pfdata->nbus; 512c4762a1bSJed Brown 5139566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(2 * numEdges[0], &edgelist_power)); 5149566063dSJacob Faibussowitsch PetscCall(GetListofEdges_Power(pfdata, edgelist_power)); 515c4762a1bSJed Brown } 516c4762a1bSJed Brown /* Broadcast power Sbase to all processors */ 5179566063dSJacob Faibussowitsch PetscCallMPI(MPI_Bcast(&Sbase, 1, MPIU_SCALAR, 0, PETSC_COMM_WORLD)); 518c4762a1bSJed Brown appctx_power->Sbase = Sbase; 519c4762a1bSJed Brown appctx_power->jac_error = PETSC_FALSE; 520c4762a1bSJed Brown /* If external option activated. Introduce error in jacobian */ 5219566063dSJacob Faibussowitsch PetscCall(PetscOptionsHasName(NULL, NULL, "-jac_error", &appctx_power->jac_error)); 522c4762a1bSJed Brown 5232bf73ac6SHong Zhang /* All processes READ THE DATA FOR THE SECOND SUBNETWORK: Water */ 5242bf73ac6SHong Zhang /* Used for shared vertex, because currently the coupling info must be available in all processes!!! */ 5259566063dSJacob Faibussowitsch PetscCall(PetscNew(&waterdata)); 5269566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetString(NULL, NULL, "-waterdata", waterdata_file, PETSC_MAX_PATH_LEN - 1, NULL)); 5279566063dSJacob Faibussowitsch PetscCall(WaterReadData(waterdata, waterdata_file)); 5282bf73ac6SHong Zhang if (size == 1 || (size > 1 && rank == 1)) { 5299566063dSJacob Faibussowitsch PetscCall(PetscCalloc1(2 * waterdata->nedge, &edgelist_water)); 5309566063dSJacob Faibussowitsch PetscCall(GetListofEdges_Water(waterdata, edgelist_water)); 531c4762a1bSJed Brown numEdges[1] = waterdata->nedge; 532c4762a1bSJed Brown numVertices[1] = waterdata->nvertex; 533c4762a1bSJed Brown } 5343ba16761SJacob Faibussowitsch PetscCall(PetscLogStagePop()); 535c4762a1bSJed Brown 5362bf73ac6SHong Zhang /* (2) Create a network consist of two subnetworks */ 5379566063dSJacob Faibussowitsch PetscCall(PetscLogStageRegister("Net Setup", &stage[1])); 5389566063dSJacob Faibussowitsch PetscCall(PetscLogStagePush(stage[1])); 539c4762a1bSJed Brown 540cc13d412SHong Zhang PetscCall(PetscOptionsGetBool(NULL, NULL, "-viewCSV", &viewCSV, NULL)); 541cc13d412SHong Zhang PetscCall(PetscOptionsGetBool(NULL, NULL, "-printCoord", &printCoord, NULL)); 5429566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetBool(NULL, NULL, "-test", &test, NULL)); 5439566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetBool(NULL, NULL, "-distribute", &distribute, NULL)); 544c4762a1bSJed Brown 545c4762a1bSJed Brown /* Create an empty network object */ 5469566063dSJacob Faibussowitsch PetscCall(DMNetworkCreate(PETSC_COMM_WORLD, &networkdm)); 547c4762a1bSJed Brown 548c4762a1bSJed Brown /* Register the components in the network */ 5499566063dSJacob Faibussowitsch PetscCall(DMNetworkRegisterComponent(networkdm, "branchstruct", sizeof(struct _p_EDGE_Power), &appctx_power->compkey_branch)); 5509566063dSJacob Faibussowitsch PetscCall(DMNetworkRegisterComponent(networkdm, "busstruct", sizeof(struct _p_VERTEX_Power), &appctx_power->compkey_bus)); 5519566063dSJacob Faibussowitsch PetscCall(DMNetworkRegisterComponent(networkdm, "genstruct", sizeof(struct _p_GEN), &appctx_power->compkey_gen)); 5529566063dSJacob Faibussowitsch PetscCall(DMNetworkRegisterComponent(networkdm, "loadstruct", sizeof(struct _p_LOAD), &appctx_power->compkey_load)); 553c4762a1bSJed Brown 5549566063dSJacob Faibussowitsch PetscCall(DMNetworkRegisterComponent(networkdm, "edge_water", sizeof(struct _p_EDGE_Water), &appctx_water->compkey_edge)); 5559566063dSJacob Faibussowitsch PetscCall(DMNetworkRegisterComponent(networkdm, "vertex_water", sizeof(struct _p_VERTEX_Water), &appctx_water->compkey_vtx)); 556cc13d412SHong Zhang 55763a3b9bcSJacob Faibussowitsch PetscCall(PetscSynchronizedPrintf(PETSC_COMM_WORLD, "[%d] Total local nvertices %" PetscInt_FMT " + %" PetscInt_FMT " = %" PetscInt_FMT ", nedges %" PetscInt_FMT " + %" PetscInt_FMT " = %" PetscInt_FMT "\n", rank, numVertices[0], numVertices[1], numVertices[0] + numVertices[1], numEdges[0], numEdges[1], numEdges[0] + numEdges[1])); 5589566063dSJacob Faibussowitsch PetscCall(PetscSynchronizedFlush(PETSC_COMM_WORLD, PETSC_STDOUT)); 559c4762a1bSJed Brown 5609566063dSJacob Faibussowitsch PetscCall(DMNetworkSetNumSubNetworks(networkdm, PETSC_DECIDE, Nsubnet)); 5619566063dSJacob Faibussowitsch PetscCall(DMNetworkAddSubnetwork(networkdm, "power", numEdges[0], edgelist_power, &power_netnum)); 5629566063dSJacob Faibussowitsch PetscCall(DMNetworkAddSubnetwork(networkdm, "water", numEdges[1], edgelist_water, &water_netnum)); 563c4762a1bSJed Brown 5642bf73ac6SHong Zhang /* vertex subnet[0].4 shares with vertex subnet[1].0 */ 5659371c9d4SSatish Balay power_svtx = 4; 5669371c9d4SSatish Balay water_svtx = 0; 5679566063dSJacob Faibussowitsch PetscCall(DMNetworkAddSharedVertices(networkdm, power_netnum, water_netnum, 1, &power_svtx, &water_svtx)); 568c4762a1bSJed Brown 569c4762a1bSJed Brown /* Set up the network layout */ 5709566063dSJacob Faibussowitsch PetscCall(DMNetworkLayoutSetUp(networkdm)); 571c4762a1bSJed Brown 572c4762a1bSJed Brown /* ADD VARIABLES AND COMPONENTS FOR THE POWER SUBNETWORK */ 5739371c9d4SSatish Balay genj = 0; 5749371c9d4SSatish Balay loadj = 0; 5759566063dSJacob Faibussowitsch PetscCall(DMNetworkGetSubnetwork(networkdm, power_netnum, &nv, &ne, &vtx, &edges)); 5762bf73ac6SHong Zhang 57748a46eb9SPierre Jolivet for (i = 0; i < ne; i++) PetscCall(DMNetworkAddComponent(networkdm, edges[i], appctx_power->compkey_branch, &pfdata->branch[i], 0)); 578c4762a1bSJed Brown 579c4762a1bSJed Brown for (i = 0; i < nv; i++) { 5809566063dSJacob Faibussowitsch PetscCall(DMNetworkIsSharedVertex(networkdm, vtx[i], &flg)); 5812bf73ac6SHong Zhang if (flg) continue; 5822bf73ac6SHong Zhang 5839566063dSJacob Faibussowitsch PetscCall(DMNetworkAddComponent(networkdm, vtx[i], appctx_power->compkey_bus, &pfdata->bus[i], 2)); 584c4762a1bSJed Brown if (pfdata->bus[i].ngen) { 58548a46eb9SPierre Jolivet for (j = 0; j < pfdata->bus[i].ngen; j++) PetscCall(DMNetworkAddComponent(networkdm, vtx[i], appctx_power->compkey_gen, &pfdata->gen[genj++], 0)); 586c4762a1bSJed Brown } 587c4762a1bSJed Brown if (pfdata->bus[i].nload) { 58848a46eb9SPierre Jolivet for (j = 0; j < pfdata->bus[i].nload; j++) PetscCall(DMNetworkAddComponent(networkdm, vtx[i], appctx_power->compkey_load, &pfdata->load[loadj++], 0)); 589c4762a1bSJed Brown } 590c4762a1bSJed Brown } 591c4762a1bSJed Brown 592c4762a1bSJed Brown /* ADD VARIABLES AND COMPONENTS FOR THE WATER SUBNETWORK */ 5939566063dSJacob Faibussowitsch PetscCall(DMNetworkGetSubnetwork(networkdm, water_netnum, &nv, &ne, &vtx, &edges)); 59448a46eb9SPierre Jolivet for (i = 0; i < ne; i++) PetscCall(DMNetworkAddComponent(networkdm, edges[i], appctx_water->compkey_edge, &waterdata->edge[i], 0)); 595c4762a1bSJed Brown 596c4762a1bSJed Brown for (i = 0; i < nv; i++) { 5979566063dSJacob Faibussowitsch PetscCall(DMNetworkIsSharedVertex(networkdm, vtx[i], &flg)); 5982bf73ac6SHong Zhang if (flg) continue; 5992bf73ac6SHong Zhang 6009566063dSJacob Faibussowitsch PetscCall(DMNetworkAddComponent(networkdm, vtx[i], appctx_water->compkey_vtx, &waterdata->vertex[i], 1)); 601c4762a1bSJed Brown } 6022bf73ac6SHong Zhang 603eac198afSGetnet /* ADD VARIABLES AND COMPONENTS AT THE SHARED VERTEX: net[0].4 coupls with net[1].0 -- owning and all ghost ranks of the vertex do this */ 6049566063dSJacob Faibussowitsch PetscCall(DMNetworkGetSharedVertices(networkdm, &nv, &vtx)); 6052bf73ac6SHong Zhang for (i = 0; i < nv; i++) { 6062bf73ac6SHong Zhang /* power */ 6079566063dSJacob Faibussowitsch PetscCall(DMNetworkAddComponent(networkdm, vtx[i], appctx_power->compkey_bus, &pfdata->bus[4], 2)); 6082bf73ac6SHong Zhang /* bus[4] is a load, add its component */ 6099566063dSJacob Faibussowitsch PetscCall(DMNetworkAddComponent(networkdm, vtx[i], appctx_power->compkey_load, &pfdata->load[0], 0)); 6102bf73ac6SHong Zhang 6112bf73ac6SHong Zhang /* water */ 6129566063dSJacob Faibussowitsch PetscCall(DMNetworkAddComponent(networkdm, vtx[i], appctx_water->compkey_vtx, &waterdata->vertex[0], 1)); 613c4762a1bSJed Brown } 614c4762a1bSJed Brown 615cc13d412SHong Zhang /* Set coordinates for visualization */ 616cc13d412SHong Zhang PetscCall(DMSetCoordinateDim(networkdm, 2)); 617*7cd471e7SHong Zhang PetscCall(DMGetCoordinateDM(networkdm, &dmcoords)); 618*7cd471e7SHong Zhang PetscCall(DMNetworkGetVertexRange(dmcoords, &vStart, &vEnd)); 619cc13d412SHong Zhang 620*7cd471e7SHong Zhang PetscCall(PetscCalloc1(vEnd - vStart, &color)); 621*7cd471e7SHong Zhang PetscCall(DMNetworkRegisterComponent(dmcoords, "coordinate&color", sizeof(PetscReal), &compkey)); 622*7cd471e7SHong Zhang for (i = vStart; i < vEnd; i++) PetscCall(DMNetworkAddComponent(dmcoords, i, compkey, &color[i - vStart], 2)); 623*7cd471e7SHong Zhang PetscCall(DMNetworkFinalizeComponents(dmcoords)); 624*7cd471e7SHong Zhang 625*7cd471e7SHong Zhang PetscCall(DMCreateLocalVector(dmcoords, &coords)); 626cc13d412SHong Zhang PetscCall(DMSetCoordinatesLocal(networkdm, coords)); /* set/get coords to/from networkdm */ 627*7cd471e7SHong Zhang PetscCall(CoordinateVecSetUp(dmcoords, coords)); 628cc13d412SHong Zhang if (printCoord) PetscCall(CoordinatePrint(networkdm)); 629cc13d412SHong Zhang 630c4762a1bSJed Brown /* Set up DM for use */ 6319566063dSJacob Faibussowitsch PetscCall(DMSetUp(networkdm)); 632c4762a1bSJed Brown 633c4762a1bSJed Brown /* Free user objects */ 6349566063dSJacob Faibussowitsch PetscCall(PetscFree(edgelist_power)); 6359566063dSJacob Faibussowitsch PetscCall(PetscFree(pfdata->bus)); 6369566063dSJacob Faibussowitsch PetscCall(PetscFree(pfdata->gen)); 6379566063dSJacob Faibussowitsch PetscCall(PetscFree(pfdata->branch)); 6389566063dSJacob Faibussowitsch PetscCall(PetscFree(pfdata->load)); 6399566063dSJacob Faibussowitsch PetscCall(PetscFree(pfdata)); 6402bf73ac6SHong Zhang 6419566063dSJacob Faibussowitsch PetscCall(PetscFree(edgelist_water)); 6429566063dSJacob Faibussowitsch PetscCall(PetscFree(waterdata->vertex)); 6439566063dSJacob Faibussowitsch PetscCall(PetscFree(waterdata->edge)); 6449566063dSJacob Faibussowitsch PetscCall(PetscFree(waterdata)); 645c4762a1bSJed Brown 646d5c9c0c4SHong Zhang /* Re-distribute networkdm to multiple processes for better job balance */ 647cc13d412SHong Zhang if (distribute) { 6489566063dSJacob Faibussowitsch PetscCall(DMNetworkDistribute(&networkdm, 0)); 649cc13d412SHong Zhang 650cc13d412SHong Zhang if (printCoord) PetscCall(CoordinatePrint(networkdm)); 651cc13d412SHong Zhang if (viewCSV) { /* CSV View of network with coordinates */ 652cc13d412SHong Zhang PetscCall(PetscViewerPushFormat(PETSC_VIEWER_STDOUT_WORLD, PETSC_VIEWER_ASCII_CSV)); 6539566063dSJacob Faibussowitsch PetscCall(DMView(networkdm, PETSC_VIEWER_STDOUT_WORLD)); 654cc13d412SHong Zhang PetscCall(PetscViewerPopFormat(PETSC_VIEWER_STDOUT_WORLD)); 655c4762a1bSJed Brown } 656d5c9c0c4SHong Zhang } 657cc13d412SHong Zhang PetscCall(VecDestroy(&coords)); 658c4762a1bSJed Brown 6592bf73ac6SHong Zhang /* Test DMNetworkGetSubnetwork() and DMNetworkGetSubnetworkSharedVertices() */ 660c4762a1bSJed Brown if (test) { 6612bf73ac6SHong Zhang PetscInt v, gidx; 6629566063dSJacob Faibussowitsch PetscCallMPI(MPI_Barrier(PETSC_COMM_WORLD)); 6632bf73ac6SHong Zhang for (i = 0; i < Nsubnet; i++) { 6649566063dSJacob Faibussowitsch PetscCall(DMNetworkGetSubnetwork(networkdm, i, &nv, &ne, &vtx, &edges)); 66563a3b9bcSJacob Faibussowitsch PetscCall(PetscPrintf(PETSC_COMM_SELF, "[%d] After distribute, subnet[%" PetscInt_FMT "] ne %" PetscInt_FMT ", nv %" PetscInt_FMT "\n", rank, i, ne, nv)); 6669566063dSJacob Faibussowitsch PetscCallMPI(MPI_Barrier(PETSC_COMM_WORLD)); 667c4762a1bSJed Brown 6682bf73ac6SHong Zhang for (v = 0; v < nv; v++) { 6699566063dSJacob Faibussowitsch PetscCall(DMNetworkIsGhostVertex(networkdm, vtx[v], &ghost)); 6709566063dSJacob Faibussowitsch PetscCall(DMNetworkGetGlobalVertexIndex(networkdm, vtx[v], &gidx)); 67163a3b9bcSJacob Faibussowitsch PetscCall(PetscPrintf(PETSC_COMM_SELF, "[%d] subnet[%" PetscInt_FMT "] v %" PetscInt_FMT " %" PetscInt_FMT "; ghost %d\n", rank, i, vtx[v], gidx, ghost)); 672c4762a1bSJed Brown } 6739566063dSJacob Faibussowitsch PetscCallMPI(MPI_Barrier(PETSC_COMM_WORLD)); 674c4762a1bSJed Brown } 6759566063dSJacob Faibussowitsch PetscCallMPI(MPI_Barrier(PETSC_COMM_WORLD)); 6762bf73ac6SHong Zhang 6779566063dSJacob Faibussowitsch PetscCall(DMNetworkGetSharedVertices(networkdm, &nv, &vtx)); 67863a3b9bcSJacob Faibussowitsch PetscCall(PetscPrintf(PETSC_COMM_SELF, "[%d] After distribute, num of shared vertices nsv = %" PetscInt_FMT "\n", rank, nv)); 6792bf73ac6SHong Zhang for (v = 0; v < nv; v++) { 6809566063dSJacob Faibussowitsch PetscCall(DMNetworkGetGlobalVertexIndex(networkdm, vtx[v], &gidx)); 68163a3b9bcSJacob Faibussowitsch PetscCall(PetscPrintf(PETSC_COMM_SELF, "[%d] sv %" PetscInt_FMT ", gidx=%" PetscInt_FMT "\n", rank, vtx[v], gidx)); 6822bf73ac6SHong Zhang } 6839566063dSJacob Faibussowitsch PetscCallMPI(MPI_Barrier(PETSC_COMM_WORLD)); 684c4762a1bSJed Brown } 685c4762a1bSJed Brown 6862bf73ac6SHong Zhang /* Create solution vector X */ 6879566063dSJacob Faibussowitsch PetscCall(DMCreateGlobalVector(networkdm, &X)); 6889566063dSJacob Faibussowitsch PetscCall(VecDuplicate(X, &F)); 6899566063dSJacob Faibussowitsch PetscCall(DMGetLocalVector(networkdm, &user.localXold)); 6903ba16761SJacob Faibussowitsch PetscCall(PetscLogStagePop()); 691c4762a1bSJed Brown 692c4762a1bSJed Brown /* (3) Setup Solvers */ 6939566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetBool(NULL, NULL, "-viewJ", &viewJ, NULL)); 6949566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetBool(NULL, NULL, "-viewX", &viewX, NULL)); 695c4762a1bSJed Brown 6969566063dSJacob Faibussowitsch PetscCall(PetscLogStageRegister("SNES Setup", &stage[2])); 6979566063dSJacob Faibussowitsch PetscCall(PetscLogStagePush(stage[2])); 698c4762a1bSJed Brown 6999566063dSJacob Faibussowitsch PetscCall(SetInitialGuess(networkdm, X, &user)); 700c4762a1bSJed Brown 701c4762a1bSJed Brown /* Create coupled snes */ 7029566063dSJacob Faibussowitsch PetscCall(PetscPrintf(PETSC_COMM_WORLD, "SNES_coupled setup ......\n")); 7032bf73ac6SHong Zhang user.subsnes_id = Nsubnet; 7049566063dSJacob Faibussowitsch PetscCall(SNESCreate(PETSC_COMM_WORLD, &snes)); 7059566063dSJacob Faibussowitsch PetscCall(SNESSetDM(snes, networkdm)); 7069566063dSJacob Faibussowitsch PetscCall(SNESSetOptionsPrefix(snes, "coupled_")); 7079566063dSJacob Faibussowitsch PetscCall(SNESSetFunction(snes, F, FormFunction, &user)); 708*7cd471e7SHong Zhang /* set maxit=1 which can be changed via option '-coupled_snes_max_it <>', see ex1options */ 709*7cd471e7SHong Zhang PetscCall(SNESSetTolerances(snes, PETSC_DEFAULT, PETSC_DEFAULT, PETSC_DEFAULT, 1, PETSC_DEFAULT)); 7109566063dSJacob Faibussowitsch PetscCall(SNESSetFromOptions(snes)); 711c4762a1bSJed Brown 712c4762a1bSJed Brown if (viewJ) { 713c4762a1bSJed Brown /* View Jac structure */ 7149566063dSJacob Faibussowitsch PetscCall(SNESGetJacobian(snes, &Jac, NULL, NULL, NULL)); 7159566063dSJacob Faibussowitsch PetscCall(MatView(Jac, PETSC_VIEWER_DRAW_WORLD)); 716c4762a1bSJed Brown } 717c4762a1bSJed Brown 718c4762a1bSJed Brown if (viewX) { 7199566063dSJacob Faibussowitsch PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Solution:\n")); 7209566063dSJacob Faibussowitsch PetscCall(VecView(X, PETSC_VIEWER_STDOUT_WORLD)); 721c4762a1bSJed Brown } 722c4762a1bSJed Brown 723c4762a1bSJed Brown if (viewJ) { 724c4762a1bSJed Brown /* View assembled Jac */ 7259566063dSJacob Faibussowitsch PetscCall(MatView(Jac, PETSC_VIEWER_DRAW_WORLD)); 726c4762a1bSJed Brown } 727c4762a1bSJed Brown 728c4762a1bSJed Brown /* Create snes_power */ 7299566063dSJacob Faibussowitsch PetscCall(PetscPrintf(PETSC_COMM_WORLD, "SNES_power setup ......\n")); 730c4762a1bSJed Brown user.subsnes_id = 0; 7319566063dSJacob Faibussowitsch PetscCall(SNESCreate(PETSC_COMM_WORLD, &snes_power)); 7329566063dSJacob Faibussowitsch PetscCall(SNESSetDM(snes_power, networkdm)); 7339566063dSJacob Faibussowitsch PetscCall(SNESSetOptionsPrefix(snes_power, "power_")); 7349566063dSJacob Faibussowitsch PetscCall(SNESSetFunction(snes_power, F, FormFunction, &user)); 735*7cd471e7SHong Zhang /* set maxit=1 which can be changed via option '-power_snes_max_it <>', see ex1options */ 736*7cd471e7SHong Zhang PetscCall(SNESSetTolerances(snes_power, PETSC_DEFAULT, PETSC_DEFAULT, PETSC_DEFAULT, 1, PETSC_DEFAULT)); 737c4762a1bSJed Brown 738c4762a1bSJed Brown /* Use user-provide Jacobian */ 7399566063dSJacob Faibussowitsch PetscCall(DMCreateMatrix(networkdm, &Jac)); 7409566063dSJacob Faibussowitsch PetscCall(SNESSetJacobian(snes_power, Jac, Jac, FormJacobian_subPower, &user)); 7419566063dSJacob Faibussowitsch PetscCall(SNESSetFromOptions(snes_power)); 742c4762a1bSJed Brown 743c4762a1bSJed Brown if (viewX) { 7449566063dSJacob Faibussowitsch PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Power Solution:\n")); 7459566063dSJacob Faibussowitsch PetscCall(VecView(X, PETSC_VIEWER_STDOUT_WORLD)); 746c4762a1bSJed Brown } 747c4762a1bSJed Brown if (viewJ) { 7489566063dSJacob Faibussowitsch PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Power Jac:\n")); 7499566063dSJacob Faibussowitsch PetscCall(SNESGetJacobian(snes_power, &Jac, NULL, NULL, NULL)); 7509566063dSJacob Faibussowitsch PetscCall(MatView(Jac, PETSC_VIEWER_DRAW_WORLD)); 751c4762a1bSJed Brown } 752c4762a1bSJed Brown 753c4762a1bSJed Brown /* Create snes_water */ 7549566063dSJacob Faibussowitsch PetscCall(PetscPrintf(PETSC_COMM_WORLD, "SNES_water setup......\n")); 755c4762a1bSJed Brown 756c4762a1bSJed Brown user.subsnes_id = 1; 7579566063dSJacob Faibussowitsch PetscCall(SNESCreate(PETSC_COMM_WORLD, &snes_water)); 7589566063dSJacob Faibussowitsch PetscCall(SNESSetDM(snes_water, networkdm)); 7599566063dSJacob Faibussowitsch PetscCall(SNESSetOptionsPrefix(snes_water, "water_")); 7609566063dSJacob Faibussowitsch PetscCall(SNESSetFunction(snes_water, F, FormFunction, &user)); 761*7cd471e7SHong Zhang /* set maxit=1 which can be changed via option '-water_snes_max_it <>', see ex1options */ 762*7cd471e7SHong Zhang PetscCall(SNESSetTolerances(snes_water, PETSC_DEFAULT, PETSC_DEFAULT, PETSC_DEFAULT, 1, PETSC_DEFAULT)); 7639566063dSJacob Faibussowitsch PetscCall(SNESSetFromOptions(snes_water)); 764c4762a1bSJed Brown 765c4762a1bSJed Brown if (viewX) { 7669566063dSJacob Faibussowitsch PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Water Solution:\n")); 7679566063dSJacob Faibussowitsch PetscCall(VecView(X, PETSC_VIEWER_STDOUT_WORLD)); 768c4762a1bSJed Brown } 769*7cd471e7SHong Zhang 770*7cd471e7SHong Zhang /* Monitor snes, snes_power and snes_water iterations */ 771*7cd471e7SHong Zhang PetscCall(PetscOptionsGetBool(NULL, NULL, "-monitorIteration", &monitorIt, NULL)); 772*7cd471e7SHong Zhang user.monitorColor = PETSC_FALSE; 773*7cd471e7SHong Zhang PetscCall(PetscOptionsGetBool(NULL, NULL, "-monitorColor", &user.monitorColor, NULL)); 774*7cd471e7SHong Zhang if (user.monitorColor) monitorIt = PETSC_TRUE; /* require installation of pandas and matplotlib */ 775*7cd471e7SHong Zhang if (monitorIt) { 776*7cd471e7SHong Zhang PetscCall(SNESMonitorSet(snes_power, UserMonitor, &user, NULL)); 777*7cd471e7SHong Zhang PetscCall(SNESMonitorSet(snes_water, UserMonitor, &user, NULL)); 778*7cd471e7SHong Zhang PetscCall(SNESMonitorSet(snes, UserMonitor, &user, NULL)); 779*7cd471e7SHong Zhang } 7809566063dSJacob Faibussowitsch PetscCall(PetscLogStagePop()); 781c4762a1bSJed Brown 782*7cd471e7SHong Zhang /* (4) Solve: we must update user.localXold after each call of SNESSolve(). 783*7cd471e7SHong Zhang See "PETSc DMNetwork: A Library for Scalable Network PDE-Based Multiphysics Simulations", 784*7cd471e7SHong Zhang https://dl.acm.org/doi/10.1145/3344587 785*7cd471e7SHong Zhang */ 7869566063dSJacob Faibussowitsch PetscCall(PetscLogStageRegister("SNES Solve", &stage[3])); 7879566063dSJacob Faibussowitsch PetscCall(PetscLogStagePush(stage[3])); 788*7cd471e7SHong Zhang user.it = 0; /* total_snes_it */ 789c4762a1bSJed Brown reason = SNES_DIVERGED_DTOL; 790c4762a1bSJed Brown while (user.it < it_max && (PetscInt)reason < 0) { 791c4762a1bSJed Brown user.subsnes_id = 0; 7929566063dSJacob Faibussowitsch PetscCall(SNESSolve(snes_power, NULL, X)); 793*7cd471e7SHong Zhang PetscCall(DMGlobalToLocalBegin(networkdm, X, INSERT_VALUES, user.localXold)); 794*7cd471e7SHong Zhang PetscCall(DMGlobalToLocalEnd(networkdm, X, INSERT_VALUES, user.localXold)); 795c4762a1bSJed Brown 796c4762a1bSJed Brown user.subsnes_id = 1; 7979566063dSJacob Faibussowitsch PetscCall(SNESSolve(snes_water, NULL, X)); 798*7cd471e7SHong Zhang PetscCall(DMGlobalToLocalBegin(networkdm, X, INSERT_VALUES, user.localXold)); 799*7cd471e7SHong Zhang PetscCall(DMGlobalToLocalEnd(networkdm, X, INSERT_VALUES, user.localXold)); 800*7cd471e7SHong Zhang 8012bf73ac6SHong Zhang user.subsnes_id = Nsubnet; 8029566063dSJacob Faibussowitsch PetscCall(SNESSolve(snes, NULL, X)); 803*7cd471e7SHong Zhang PetscCall(DMGlobalToLocalBegin(networkdm, X, INSERT_VALUES, user.localXold)); 804*7cd471e7SHong Zhang PetscCall(DMGlobalToLocalEnd(networkdm, X, INSERT_VALUES, user.localXold)); 805c4762a1bSJed Brown 8069566063dSJacob Faibussowitsch PetscCall(SNESGetConvergedReason(snes, &reason)); 807c4762a1bSJed Brown user.it++; 808c4762a1bSJed Brown } 80963a3b9bcSJacob Faibussowitsch PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Coupled_SNES converged in %" PetscInt_FMT " iterations\n", user.it)); 810c4762a1bSJed Brown if (viewX) { 8119566063dSJacob Faibussowitsch PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Final Solution:\n")); 8129566063dSJacob Faibussowitsch PetscCall(VecView(X, PETSC_VIEWER_STDOUT_WORLD)); 813c4762a1bSJed Brown } 8149566063dSJacob Faibussowitsch PetscCall(PetscLogStagePop()); 815c4762a1bSJed Brown 816c4762a1bSJed Brown /* Free objects */ 817c4762a1bSJed Brown /* -------------*/ 818*7cd471e7SHong Zhang PetscCall(PetscFree(color)); 8199566063dSJacob Faibussowitsch PetscCall(VecDestroy(&X)); 8209566063dSJacob Faibussowitsch PetscCall(VecDestroy(&F)); 8219566063dSJacob Faibussowitsch PetscCall(DMRestoreLocalVector(networkdm, &user.localXold)); 822c4762a1bSJed Brown 8239566063dSJacob Faibussowitsch PetscCall(SNESDestroy(&snes)); 8249566063dSJacob Faibussowitsch PetscCall(MatDestroy(&Jac)); 8259566063dSJacob Faibussowitsch PetscCall(SNESDestroy(&snes_power)); 8269566063dSJacob Faibussowitsch PetscCall(SNESDestroy(&snes_water)); 827c4762a1bSJed Brown 8289566063dSJacob Faibussowitsch PetscCall(DMDestroy(&networkdm)); 8299566063dSJacob Faibussowitsch PetscCall(PetscFinalize()); 830b122ec5aSJacob Faibussowitsch return 0; 831c4762a1bSJed Brown } 832c4762a1bSJed Brown 833c4762a1bSJed Brown /*TEST 834c4762a1bSJed Brown 835c4762a1bSJed Brown build: 836dfd57a17SPierre Jolivet requires: !complex double defined(PETSC_HAVE_ATTRIBUTEALIGNED) 837c4762a1bSJed Brown depends: power/PFReadData.c power/pffunctions.c water/waterreaddata.c water/waterfunctions.c 838c4762a1bSJed Brown 839c4762a1bSJed Brown test: 840*7cd471e7SHong Zhang args: -options_left no -dmnetwork_view -fp_trap 0 841c4762a1bSJed Brown localrunfiles: ex1options power/case9.m water/sample1.inp 842c4762a1bSJed Brown output_file: output/ex1.out 843c4762a1bSJed Brown 844c4762a1bSJed Brown test: 845c4762a1bSJed Brown suffix: 2 846c4762a1bSJed Brown nsize: 3 847*7cd471e7SHong Zhang args: -options_left no -petscpartitioner_type parmetis -fp_trap 0 848c4762a1bSJed Brown localrunfiles: ex1options power/case9.m water/sample1.inp 849d5c9c0c4SHong Zhang output_file: output/ex1_2.out 8502bf73ac6SHong Zhang requires: parmetis 8512bf73ac6SHong Zhang 852cc13d412SHong Zhang test: 853cc13d412SHong Zhang suffix: 3 854cc13d412SHong Zhang nsize: 3 855*7cd471e7SHong Zhang args: -options_left no -distribute false -fp_trap 0 856cc13d412SHong Zhang localrunfiles: ex1options power/case9.m water/sample1.inp 857cc13d412SHong Zhang output_file: output/ex1_2.out 858d5c9c0c4SHong Zhang 859d5c9c0c4SHong Zhang test: 8602bf73ac6SHong Zhang suffix: 4 8612bf73ac6SHong Zhang nsize: 4 862*7cd471e7SHong Zhang args: -options_left no -petscpartitioner_type simple -dmnetwork_view -dmnetwork_view_distributed -fp_trap 0 863d5c9c0c4SHong Zhang localrunfiles: ex1options power/case9.m water/sample1.inp 8642bf73ac6SHong Zhang output_file: output/ex1_4.out 865c4762a1bSJed Brown 866cc13d412SHong Zhang test: 867cc13d412SHong Zhang suffix: 5 868*7cd471e7SHong Zhang args: -options_left no -viewCSV -fp_trap 0 869cc13d412SHong Zhang localrunfiles: ex1options power/case9.m water/sample1.inp 870cc13d412SHong Zhang output_file: output/ex1_5.out 871cc13d412SHong Zhang 872cc13d412SHong Zhang test: 873cc13d412SHong Zhang suffix: 6 874cc13d412SHong Zhang nsize: 3 875*7cd471e7SHong Zhang args: -options_left no -petscpartitioner_type parmetis -dmnetwork_view_distributed draw:null -fp_trap 0 876cc13d412SHong Zhang localrunfiles: ex1options power/case9.m water/sample1.inp 877cc13d412SHong Zhang output_file: output/ex1_2.out 878cc13d412SHong Zhang requires: parmetis 879cc13d412SHong Zhang 880c4762a1bSJed Brown TEST*/ 881