xref: /petsc/src/ts/tutorials/network/pipes.c (revision 48a46eb9bd028bec07ec0f396b1a3abb43f14558)
142dc13f1SHong Zhang static char help[] = "This example demonstrates DMNetwork. It is used for testing parallel generation of dmnetwork, then redistribute. \n\\n";
242dc13f1SHong Zhang /*
342dc13f1SHong Zhang   Example: mpiexec -n <np> ./pipes -ts_max_steps 10
442dc13f1SHong Zhang */
542dc13f1SHong Zhang 
642dc13f1SHong Zhang #include "wash.h"
742dc13f1SHong Zhang 
842dc13f1SHong Zhang /*
942dc13f1SHong Zhang   WashNetworkDistribute - proc[0] distributes sequential wash object
1042dc13f1SHong Zhang    Input Parameters:
1142dc13f1SHong Zhang .  comm - MPI communicator
1242dc13f1SHong Zhang .  wash - wash context with all network data in proc[0]
1342dc13f1SHong Zhang 
1442dc13f1SHong Zhang    Output Parameter:
1542dc13f1SHong Zhang .  wash - wash context with nedge, nvertex and edgelist distributed
1642dc13f1SHong Zhang 
1742dc13f1SHong Zhang    Note: The routine is used for testing parallel generation of dmnetwork, then redistribute.
1842dc13f1SHong Zhang */
199371c9d4SSatish Balay PetscErrorCode WashNetworkDistribute(MPI_Comm comm, Wash wash) {
2042dc13f1SHong Zhang   PetscMPIInt rank, size, tag = 0;
2142dc13f1SHong Zhang   PetscInt    i, e, v, numEdges, numVertices, nedges, *eowners = NULL, estart, eend, *vtype = NULL, nvertices;
2242dc13f1SHong Zhang   PetscInt   *edgelist = wash->edgelist, *nvtx = NULL, *vtxDone = NULL;
2342dc13f1SHong Zhang 
2442dc13f1SHong Zhang   PetscFunctionBegin;
259566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_size(comm, &size));
2642dc13f1SHong Zhang   if (size == 1) PetscFunctionReturn(0);
2742dc13f1SHong Zhang 
289566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(comm, &rank));
2942dc13f1SHong Zhang   numEdges    = wash->nedge;
3042dc13f1SHong Zhang   numVertices = wash->nvertex;
3142dc13f1SHong Zhang 
3242dc13f1SHong Zhang   /* (1) all processes get global and local number of edges */
339566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Bcast(&numEdges, 1, MPIU_INT, 0, comm));
3442dc13f1SHong Zhang   nedges = numEdges / size; /* local nedges */
359371c9d4SSatish Balay   if (rank == 0) { nedges += numEdges - size * (numEdges / size); }
3642dc13f1SHong Zhang   wash->Nedge = numEdges;
3742dc13f1SHong Zhang   wash->nedge = nedges;
389566063dSJacob Faibussowitsch   /* PetscCall(PetscPrintf(PETSC_COMM_SELF,"[%d] nedges %d, numEdges %d\n",rank,nedges,numEdges)); */
3942dc13f1SHong Zhang 
409566063dSJacob Faibussowitsch   PetscCall(PetscCalloc3(size + 1, &eowners, size, &nvtx, numVertices, &vtxDone));
419566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Allgather(&nedges, 1, MPIU_INT, eowners + 1, 1, MPIU_INT, PETSC_COMM_WORLD));
4242dc13f1SHong Zhang   eowners[0] = 0;
439371c9d4SSatish Balay   for (i = 2; i <= size; i++) { eowners[i] += eowners[i - 1]; }
4442dc13f1SHong Zhang 
4542dc13f1SHong Zhang   estart = eowners[rank];
4642dc13f1SHong Zhang   eend   = eowners[rank + 1];
479566063dSJacob Faibussowitsch   /* PetscCall(PetscPrintf(PETSC_COMM_SELF,"[%d] own lists row %d - %d\n",rank,estart,eend)); */
4842dc13f1SHong Zhang 
4942dc13f1SHong Zhang   /* (2) distribute row block edgelist to all processors */
50dd400576SPatrick Sanan   if (rank == 0) {
5142dc13f1SHong Zhang     vtype = wash->vtype;
5242dc13f1SHong Zhang     for (i = 1; i < size; i++) {
5342dc13f1SHong Zhang       /* proc[0] sends edgelist to proc[i] */
549566063dSJacob Faibussowitsch       PetscCallMPI(MPI_Send(edgelist + 2 * eowners[i], 2 * (eowners[i + 1] - eowners[i]), MPIU_INT, i, tag, comm));
5542dc13f1SHong Zhang 
5642dc13f1SHong Zhang       /* proc[0] sends vtype to proc[i] */
579566063dSJacob Faibussowitsch       PetscCallMPI(MPI_Send(vtype + 2 * eowners[i], 2 * (eowners[i + 1] - eowners[i]), MPIU_INT, i, tag, comm));
5842dc13f1SHong Zhang     }
5942dc13f1SHong Zhang   } else {
6042dc13f1SHong Zhang     MPI_Status status;
619566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(2 * (eend - estart), &vtype));
629566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(2 * (eend - estart), &edgelist));
6342dc13f1SHong Zhang 
649566063dSJacob Faibussowitsch     PetscCallMPI(MPI_Recv(edgelist, 2 * (eend - estart), MPIU_INT, 0, tag, comm, &status));
659566063dSJacob Faibussowitsch     PetscCallMPI(MPI_Recv(vtype, 2 * (eend - estart), MPIU_INT, 0, tag, comm, &status));
6642dc13f1SHong Zhang   }
6742dc13f1SHong Zhang 
6842dc13f1SHong Zhang   wash->edgelist = edgelist;
6942dc13f1SHong Zhang 
7042dc13f1SHong Zhang   /* (3) all processes get global and local number of vertices, without ghost vertices */
71dd400576SPatrick Sanan   if (rank == 0) {
7242dc13f1SHong Zhang     for (i = 0; i < size; i++) {
7342dc13f1SHong Zhang       for (e = eowners[i]; e < eowners[i + 1]; e++) {
7442dc13f1SHong Zhang         v = edgelist[2 * e];
7542dc13f1SHong Zhang         if (!vtxDone[v]) {
769371c9d4SSatish Balay           nvtx[i]++;
779371c9d4SSatish Balay           vtxDone[v] = 1;
7842dc13f1SHong Zhang         }
7942dc13f1SHong Zhang         v = edgelist[2 * e + 1];
8042dc13f1SHong Zhang         if (!vtxDone[v]) {
819371c9d4SSatish Balay           nvtx[i]++;
829371c9d4SSatish Balay           vtxDone[v] = 1;
8342dc13f1SHong Zhang         }
8442dc13f1SHong Zhang       }
8542dc13f1SHong Zhang     }
8642dc13f1SHong Zhang   }
879566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Bcast(&numVertices, 1, MPIU_INT, 0, PETSC_COMM_WORLD));
889566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Scatter(nvtx, 1, MPIU_INT, &nvertices, 1, MPIU_INT, 0, PETSC_COMM_WORLD));
899566063dSJacob Faibussowitsch   PetscCall(PetscFree3(eowners, nvtx, vtxDone));
9042dc13f1SHong Zhang 
9142dc13f1SHong Zhang   wash->Nvertex = numVertices;
9242dc13f1SHong Zhang   wash->nvertex = nvertices;
9342dc13f1SHong Zhang   wash->vtype   = vtype;
9442dc13f1SHong Zhang   PetscFunctionReturn(0);
9542dc13f1SHong Zhang }
9642dc13f1SHong Zhang 
979371c9d4SSatish Balay PetscErrorCode WASHIFunction(TS ts, PetscReal t, Vec X, Vec Xdot, Vec F, void *ctx) {
9842dc13f1SHong Zhang   Wash               wash = (Wash)ctx;
9942dc13f1SHong Zhang   DM                 networkdm;
10042dc13f1SHong Zhang   Vec                localX, localXdot, localF, localXold;
10142dc13f1SHong Zhang   const PetscInt    *cone;
10242dc13f1SHong Zhang   PetscInt           vfrom, vto, offsetfrom, offsetto, varoffset;
10342dc13f1SHong Zhang   PetscInt           v, vStart, vEnd, e, eStart, eEnd;
10442dc13f1SHong Zhang   PetscInt           nend, type;
10542dc13f1SHong Zhang   PetscBool          ghost;
10642dc13f1SHong Zhang   PetscScalar       *farr, *juncf, *pipef;
10742dc13f1SHong Zhang   PetscReal          dt;
10842dc13f1SHong Zhang   Pipe               pipe;
10942dc13f1SHong Zhang   PipeField         *pipex, *pipexdot, *juncx;
11042dc13f1SHong Zhang   Junction           junction;
11142dc13f1SHong Zhang   DMDALocalInfo      info;
11242dc13f1SHong Zhang   const PetscScalar *xarr, *xdotarr, *xoldarr;
11342dc13f1SHong Zhang 
11442dc13f1SHong Zhang   PetscFunctionBegin;
11542dc13f1SHong Zhang   localX    = wash->localX;
11642dc13f1SHong Zhang   localXdot = wash->localXdot;
11742dc13f1SHong Zhang 
1189566063dSJacob Faibussowitsch   PetscCall(TSGetSolution(ts, &localXold));
1199566063dSJacob Faibussowitsch   PetscCall(TSGetDM(ts, &networkdm));
1209566063dSJacob Faibussowitsch   PetscCall(TSGetTimeStep(ts, &dt));
1219566063dSJacob Faibussowitsch   PetscCall(DMGetLocalVector(networkdm, &localF));
12242dc13f1SHong Zhang 
12342dc13f1SHong Zhang   /* Set F and localF as zero */
1249566063dSJacob Faibussowitsch   PetscCall(VecSet(F, 0.0));
1259566063dSJacob Faibussowitsch   PetscCall(VecSet(localF, 0.0));
12642dc13f1SHong Zhang 
12742dc13f1SHong Zhang   /* Update ghost values of locaX and locaXdot */
1289566063dSJacob Faibussowitsch   PetscCall(DMGlobalToLocalBegin(networkdm, X, INSERT_VALUES, localX));
1299566063dSJacob Faibussowitsch   PetscCall(DMGlobalToLocalEnd(networkdm, X, INSERT_VALUES, localX));
13042dc13f1SHong Zhang 
1319566063dSJacob Faibussowitsch   PetscCall(DMGlobalToLocalBegin(networkdm, Xdot, INSERT_VALUES, localXdot));
1329566063dSJacob Faibussowitsch   PetscCall(DMGlobalToLocalEnd(networkdm, Xdot, INSERT_VALUES, localXdot));
13342dc13f1SHong Zhang 
1349566063dSJacob Faibussowitsch   PetscCall(VecGetArrayRead(localX, &xarr));
1359566063dSJacob Faibussowitsch   PetscCall(VecGetArrayRead(localXdot, &xdotarr));
1369566063dSJacob Faibussowitsch   PetscCall(VecGetArrayRead(localXold, &xoldarr));
1379566063dSJacob Faibussowitsch   PetscCall(VecGetArray(localF, &farr));
13842dc13f1SHong Zhang 
13942dc13f1SHong Zhang   /* junction->type == JUNCTION:
14042dc13f1SHong Zhang            juncf[0] = -qJ + sum(qin); juncf[1] = qJ - sum(qout)
14142dc13f1SHong Zhang        junction->type == RESERVOIR (upper stream):
14242dc13f1SHong Zhang            juncf[0] = -hJ + H0; juncf[1] = qJ - sum(qout)
14342dc13f1SHong Zhang        junction->type == VALVE (down stream):
14442dc13f1SHong Zhang            juncf[0] =  -qJ + sum(qin); juncf[1] = qJ
14542dc13f1SHong Zhang   */
14642dc13f1SHong Zhang   /* Vertex/junction initialization */
1479566063dSJacob Faibussowitsch   PetscCall(DMNetworkGetVertexRange(networkdm, &vStart, &vEnd));
14842dc13f1SHong Zhang   for (v = vStart; v < vEnd; v++) {
1499566063dSJacob Faibussowitsch     PetscCall(DMNetworkIsGhostVertex(networkdm, v, &ghost));
15042dc13f1SHong Zhang     if (ghost) continue;
15142dc13f1SHong Zhang 
1529566063dSJacob Faibussowitsch     PetscCall(DMNetworkGetComponent(networkdm, v, 0, &type, (void **)&junction, NULL));
1539566063dSJacob Faibussowitsch     PetscCall(DMNetworkGetLocalVecOffset(networkdm, v, ALL_COMPONENTS, &varoffset));
15442dc13f1SHong Zhang     juncx = (PipeField *)(xarr + varoffset);
15542dc13f1SHong Zhang     juncf = (PetscScalar *)(farr + varoffset);
15642dc13f1SHong Zhang 
15742dc13f1SHong Zhang     juncf[0] = -juncx[0].q;
15842dc13f1SHong Zhang     juncf[1] = juncx[0].q;
15942dc13f1SHong Zhang 
16042dc13f1SHong Zhang     if (junction->type == RESERVOIR) { /* upstream reservoir */
16142dc13f1SHong Zhang       juncf[0] = juncx[0].h - wash->H0;
16242dc13f1SHong Zhang     }
16342dc13f1SHong Zhang   }
16442dc13f1SHong Zhang 
16542dc13f1SHong Zhang   /* Edge/pipe */
1669566063dSJacob Faibussowitsch   PetscCall(DMNetworkGetEdgeRange(networkdm, &eStart, &eEnd));
16742dc13f1SHong Zhang   for (e = eStart; e < eEnd; e++) {
1689566063dSJacob Faibussowitsch     PetscCall(DMNetworkGetComponent(networkdm, e, 0, &type, (void **)&pipe, NULL));
1699566063dSJacob Faibussowitsch     PetscCall(DMNetworkGetLocalVecOffset(networkdm, e, ALL_COMPONENTS, &varoffset));
17042dc13f1SHong Zhang     pipex    = (PipeField *)(xarr + varoffset);
17142dc13f1SHong Zhang     pipexdot = (PipeField *)(xdotarr + varoffset);
17242dc13f1SHong Zhang     pipef    = (PetscScalar *)(farr + varoffset);
17342dc13f1SHong Zhang 
17442dc13f1SHong Zhang     /* Get some data into the pipe structure: note, some of these operations
17542dc13f1SHong Zhang      * might be redundant. Will it consume too much time? */
17642dc13f1SHong Zhang     pipe->dt   = dt;
17742dc13f1SHong Zhang     pipe->xold = (PipeField *)(xoldarr + varoffset);
17842dc13f1SHong Zhang 
17942dc13f1SHong Zhang     /* Evaluate F over this edge/pipe: pipef[1], ...,pipef[2*nend] */
1809566063dSJacob Faibussowitsch     PetscCall(DMDAGetLocalInfo(pipe->da, &info));
1819566063dSJacob Faibussowitsch     PetscCall(PipeIFunctionLocal_Lax(&info, t, pipex, pipexdot, pipef, pipe));
18242dc13f1SHong Zhang 
18342dc13f1SHong Zhang     /* Get boundary values from connected vertices */
1849566063dSJacob Faibussowitsch     PetscCall(DMNetworkGetConnectedVertices(networkdm, e, &cone));
18542dc13f1SHong Zhang     vfrom = cone[0]; /* local ordering */
18642dc13f1SHong Zhang     vto   = cone[1];
1879566063dSJacob Faibussowitsch     PetscCall(DMNetworkGetLocalVecOffset(networkdm, vfrom, ALL_COMPONENTS, &offsetfrom));
1889566063dSJacob Faibussowitsch     PetscCall(DMNetworkGetLocalVecOffset(networkdm, vto, ALL_COMPONENTS, &offsetto));
18942dc13f1SHong Zhang 
19042dc13f1SHong Zhang     /* Evaluate upstream boundary */
1919566063dSJacob Faibussowitsch     PetscCall(DMNetworkGetComponent(networkdm, vfrom, 0, &type, (void **)&junction, NULL));
192cad9d221SBarry Smith     PetscCheck(junction->type == JUNCTION || junction->type == RESERVOIR, PETSC_COMM_SELF, PETSC_ERR_SUP, "junction type is not supported");
19342dc13f1SHong Zhang     juncx = (PipeField *)(xarr + offsetfrom);
19442dc13f1SHong Zhang     juncf = (PetscScalar *)(farr + offsetfrom);
19542dc13f1SHong Zhang 
19642dc13f1SHong Zhang     pipef[0] = pipex[0].h - juncx[0].h;
19742dc13f1SHong Zhang     juncf[1] -= pipex[0].q;
19842dc13f1SHong Zhang 
19942dc13f1SHong Zhang     /* Evaluate downstream boundary */
2009566063dSJacob Faibussowitsch     PetscCall(DMNetworkGetComponent(networkdm, vto, 0, &type, (void **)&junction, NULL));
201cad9d221SBarry Smith     PetscCheck(junction->type == JUNCTION || junction->type == VALVE, PETSC_COMM_SELF, PETSC_ERR_SUP, "junction type is not supported");
20242dc13f1SHong Zhang     juncx = (PipeField *)(xarr + offsetto);
20342dc13f1SHong Zhang     juncf = (PetscScalar *)(farr + offsetto);
20442dc13f1SHong Zhang     nend  = pipe->nnodes - 1;
20542dc13f1SHong Zhang 
20642dc13f1SHong Zhang     pipef[2 * nend + 1] = pipex[nend].h - juncx[0].h;
20742dc13f1SHong Zhang     juncf[0] += pipex[nend].q;
20842dc13f1SHong Zhang   }
20942dc13f1SHong Zhang 
2109566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayRead(localX, &xarr));
2119566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayRead(localXdot, &xdotarr));
2129566063dSJacob Faibussowitsch   PetscCall(VecRestoreArray(localF, &farr));
21342dc13f1SHong Zhang 
2149566063dSJacob Faibussowitsch   PetscCall(DMLocalToGlobalBegin(networkdm, localF, ADD_VALUES, F));
2159566063dSJacob Faibussowitsch   PetscCall(DMLocalToGlobalEnd(networkdm, localF, ADD_VALUES, F));
2169566063dSJacob Faibussowitsch   PetscCall(DMRestoreLocalVector(networkdm, &localF));
21742dc13f1SHong Zhang   /*
2189566063dSJacob Faibussowitsch    PetscCall(PetscPrintf(PETSC_COMM_WORLD("F:\n"));
2199566063dSJacob Faibussowitsch    PetscCall(VecView(F,PETSC_VIEWER_STDOUT_WORLD));
22042dc13f1SHong Zhang    */
22142dc13f1SHong Zhang   PetscFunctionReturn(0);
22242dc13f1SHong Zhang }
22342dc13f1SHong Zhang 
2249371c9d4SSatish Balay PetscErrorCode WASHSetInitialSolution(DM networkdm, Vec X, Wash wash) {
22542dc13f1SHong Zhang   PetscInt           k, nx, vkey, vfrom, vto, offsetfrom, offsetto;
22642dc13f1SHong Zhang   PetscInt           type, varoffset;
22742dc13f1SHong Zhang   PetscInt           e, eStart, eEnd;
22842dc13f1SHong Zhang   Vec                localX;
22942dc13f1SHong Zhang   PetscScalar       *xarr;
23042dc13f1SHong Zhang   Pipe               pipe;
23142dc13f1SHong Zhang   Junction           junction;
23242dc13f1SHong Zhang   const PetscInt    *cone;
23342dc13f1SHong Zhang   const PetscScalar *xarray;
23442dc13f1SHong Zhang 
23542dc13f1SHong Zhang   PetscFunctionBegin;
2369566063dSJacob Faibussowitsch   PetscCall(VecSet(X, 0.0));
2379566063dSJacob Faibussowitsch   PetscCall(DMGetLocalVector(networkdm, &localX));
2389566063dSJacob Faibussowitsch   PetscCall(VecGetArray(localX, &xarr));
23942dc13f1SHong Zhang 
24042dc13f1SHong Zhang   /* Edge */
2419566063dSJacob Faibussowitsch   PetscCall(DMNetworkGetEdgeRange(networkdm, &eStart, &eEnd));
24242dc13f1SHong Zhang   for (e = eStart; e < eEnd; e++) {
2439566063dSJacob Faibussowitsch     PetscCall(DMNetworkGetLocalVecOffset(networkdm, e, ALL_COMPONENTS, &varoffset));
2449566063dSJacob Faibussowitsch     PetscCall(DMNetworkGetComponent(networkdm, e, 0, &type, (void **)&pipe, NULL));
24542dc13f1SHong Zhang 
24642dc13f1SHong Zhang     /* set initial values for this pipe */
2479566063dSJacob Faibussowitsch     PetscCall(PipeComputeSteadyState(pipe, wash->Q0, wash->H0));
2489566063dSJacob Faibussowitsch     PetscCall(VecGetSize(pipe->x, &nx));
24942dc13f1SHong Zhang 
2509566063dSJacob Faibussowitsch     PetscCall(VecGetArrayRead(pipe->x, &xarray));
25142dc13f1SHong Zhang     /* copy pipe->x to xarray */
2529371c9d4SSatish Balay     for (k = 0; k < nx; k++) { (xarr + varoffset)[k] = xarray[k]; }
25342dc13f1SHong Zhang 
25442dc13f1SHong Zhang     /* set boundary values into vfrom and vto */
2559566063dSJacob Faibussowitsch     PetscCall(DMNetworkGetConnectedVertices(networkdm, e, &cone));
25642dc13f1SHong Zhang     vfrom = cone[0]; /* local ordering */
25742dc13f1SHong Zhang     vto   = cone[1];
2589566063dSJacob Faibussowitsch     PetscCall(DMNetworkGetLocalVecOffset(networkdm, vfrom, ALL_COMPONENTS, &offsetfrom));
2599566063dSJacob Faibussowitsch     PetscCall(DMNetworkGetLocalVecOffset(networkdm, vto, ALL_COMPONENTS, &offsetto));
26042dc13f1SHong Zhang 
26142dc13f1SHong Zhang     /* if vform is a head vertex: */
2629566063dSJacob Faibussowitsch     PetscCall(DMNetworkGetComponent(networkdm, vfrom, 0, &vkey, (void **)&junction, NULL));
2639371c9d4SSatish Balay     if (junction->type == RESERVOIR) { (xarr + offsetfrom)[1] = wash->H0; /* 1st H */ }
26442dc13f1SHong Zhang 
26542dc13f1SHong Zhang     /* if vto is an end vertex: */
2669566063dSJacob Faibussowitsch     PetscCall(DMNetworkGetComponent(networkdm, vto, 0, &vkey, (void **)&junction, NULL));
2679371c9d4SSatish Balay     if (junction->type == VALVE) { (xarr + offsetto)[0] = wash->QL; /* last Q */ }
2689566063dSJacob Faibussowitsch     PetscCall(VecRestoreArrayRead(pipe->x, &xarray));
26942dc13f1SHong Zhang   }
27042dc13f1SHong Zhang 
2719566063dSJacob Faibussowitsch   PetscCall(VecRestoreArray(localX, &xarr));
2729566063dSJacob Faibussowitsch   PetscCall(DMLocalToGlobalBegin(networkdm, localX, ADD_VALUES, X));
2739566063dSJacob Faibussowitsch   PetscCall(DMLocalToGlobalEnd(networkdm, localX, ADD_VALUES, X));
2749566063dSJacob Faibussowitsch   PetscCall(DMRestoreLocalVector(networkdm, &localX));
27542dc13f1SHong Zhang 
27642dc13f1SHong Zhang #if 0
27742dc13f1SHong Zhang   PetscInt N;
2789566063dSJacob Faibussowitsch   PetscCall(VecGetSize(X,&N));
2799566063dSJacob Faibussowitsch   PetscCall(PetscPrintf(PETSC_COMM_WORLD,"initial solution %d:\n",N));
2809566063dSJacob Faibussowitsch   PetscCall(VecView(X,PETSC_VIEWER_STDOUT_WORLD));
28142dc13f1SHong Zhang #endif
28242dc13f1SHong Zhang   PetscFunctionReturn(0);
28342dc13f1SHong Zhang }
28442dc13f1SHong Zhang 
2859371c9d4SSatish Balay PetscErrorCode TSDMNetworkMonitor(TS ts, PetscInt step, PetscReal t, Vec x, void *context) {
28642dc13f1SHong Zhang   DMNetworkMonitor monitor;
28742dc13f1SHong Zhang 
28842dc13f1SHong Zhang   PetscFunctionBegin;
28942dc13f1SHong Zhang   monitor = (DMNetworkMonitor)context;
2909566063dSJacob Faibussowitsch   PetscCall(DMNetworkMonitorView(monitor, x));
29142dc13f1SHong Zhang   PetscFunctionReturn(0);
29242dc13f1SHong Zhang }
29342dc13f1SHong Zhang 
2949371c9d4SSatish Balay PetscErrorCode PipesView(DM networkdm, PetscInt KeyPipe, Vec X) {
29542dc13f1SHong Zhang   PetscInt   i, numkeys = 1, *blocksize, *numselectedvariable, **selectedvariables, n;
29642dc13f1SHong Zhang   IS         isfrom_q, isfrom_h, isfrom;
29742dc13f1SHong Zhang   Vec        Xto;
29842dc13f1SHong Zhang   VecScatter ctx;
29942dc13f1SHong Zhang   MPI_Comm   comm;
30042dc13f1SHong Zhang 
30142dc13f1SHong Zhang   PetscFunctionBegin;
3029566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetComm((PetscObject)networkdm, &comm));
30342dc13f1SHong Zhang 
30442dc13f1SHong Zhang   /* 1. Create isfrom_q for q-variable of pipes */
3059566063dSJacob Faibussowitsch   PetscCall(PetscMalloc3(numkeys, &blocksize, numkeys, &numselectedvariable, numkeys, &selectedvariables));
30642dc13f1SHong Zhang   for (i = 0; i < numkeys; i++) {
30742dc13f1SHong Zhang     blocksize[i]           = 2;
30842dc13f1SHong Zhang     numselectedvariable[i] = 1;
3099566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(numselectedvariable[i], &selectedvariables[i]));
31042dc13f1SHong Zhang     selectedvariables[i][0] = 0; /* q-variable */
31142dc13f1SHong Zhang   }
3129566063dSJacob Faibussowitsch   PetscCall(DMNetworkCreateIS(networkdm, numkeys, &KeyPipe, blocksize, numselectedvariable, selectedvariables, &isfrom_q));
31342dc13f1SHong Zhang 
31442dc13f1SHong Zhang   /* 2. Create Xto and isto */
3159566063dSJacob Faibussowitsch   PetscCall(ISGetLocalSize(isfrom_q, &n));
3169566063dSJacob Faibussowitsch   PetscCall(VecCreate(comm, &Xto));
3179566063dSJacob Faibussowitsch   PetscCall(VecSetSizes(Xto, n, PETSC_DECIDE));
3189566063dSJacob Faibussowitsch   PetscCall(VecSetFromOptions(Xto));
3199566063dSJacob Faibussowitsch   PetscCall(VecSet(Xto, 0.0));
32042dc13f1SHong Zhang 
32142dc13f1SHong Zhang   /* 3. Create scatter */
3229566063dSJacob Faibussowitsch   PetscCall(VecScatterCreate(X, isfrom_q, Xto, NULL, &ctx));
32342dc13f1SHong Zhang 
32442dc13f1SHong Zhang   /* 4. Scatter to Xq */
3259566063dSJacob Faibussowitsch   PetscCall(VecScatterBegin(ctx, X, Xto, INSERT_VALUES, SCATTER_FORWARD));
3269566063dSJacob Faibussowitsch   PetscCall(VecScatterEnd(ctx, X, Xto, INSERT_VALUES, SCATTER_FORWARD));
3279566063dSJacob Faibussowitsch   PetscCall(VecScatterDestroy(&ctx));
3289566063dSJacob Faibussowitsch   PetscCall(ISDestroy(&isfrom_q));
32942dc13f1SHong Zhang 
3309566063dSJacob Faibussowitsch   PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Xq:\n"));
3319566063dSJacob Faibussowitsch   PetscCall(VecView(Xto, PETSC_VIEWER_STDOUT_WORLD));
33242dc13f1SHong Zhang 
33342dc13f1SHong Zhang   /* 5. Create isfrom_h for h-variable of pipes; Create scatter; Scatter to Xh */
3349371c9d4SSatish Balay   for (i = 0; i < numkeys; i++) { selectedvariables[i][0] = 1; /* h-variable */ }
3359566063dSJacob Faibussowitsch   PetscCall(DMNetworkCreateIS(networkdm, numkeys, &KeyPipe, blocksize, numselectedvariable, selectedvariables, &isfrom_h));
33642dc13f1SHong Zhang 
3379566063dSJacob Faibussowitsch   PetscCall(VecScatterCreate(X, isfrom_h, Xto, NULL, &ctx));
3389566063dSJacob Faibussowitsch   PetscCall(VecScatterBegin(ctx, X, Xto, INSERT_VALUES, SCATTER_FORWARD));
3399566063dSJacob Faibussowitsch   PetscCall(VecScatterEnd(ctx, X, Xto, INSERT_VALUES, SCATTER_FORWARD));
3409566063dSJacob Faibussowitsch   PetscCall(VecScatterDestroy(&ctx));
3419566063dSJacob Faibussowitsch   PetscCall(ISDestroy(&isfrom_h));
34242dc13f1SHong Zhang 
3439566063dSJacob Faibussowitsch   PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Xh:\n"));
3449566063dSJacob Faibussowitsch   PetscCall(VecView(Xto, PETSC_VIEWER_STDOUT_WORLD));
3459566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&Xto));
34642dc13f1SHong Zhang 
34742dc13f1SHong Zhang   /* 6. Create isfrom for all pipe variables; Create scatter; Scatter to Xpipes */
3489371c9d4SSatish Balay   for (i = 0; i < numkeys; i++) { blocksize[i] = -1; /* select all the variables of the i-th component */ }
3499566063dSJacob Faibussowitsch   PetscCall(DMNetworkCreateIS(networkdm, numkeys, &KeyPipe, blocksize, NULL, NULL, &isfrom));
3509566063dSJacob Faibussowitsch   PetscCall(ISDestroy(&isfrom));
3519566063dSJacob Faibussowitsch   PetscCall(DMNetworkCreateIS(networkdm, numkeys, &KeyPipe, NULL, NULL, NULL, &isfrom));
35242dc13f1SHong Zhang 
3539566063dSJacob Faibussowitsch   PetscCall(ISGetLocalSize(isfrom, &n));
3549566063dSJacob Faibussowitsch   PetscCall(VecCreate(comm, &Xto));
3559566063dSJacob Faibussowitsch   PetscCall(VecSetSizes(Xto, n, PETSC_DECIDE));
3569566063dSJacob Faibussowitsch   PetscCall(VecSetFromOptions(Xto));
3579566063dSJacob Faibussowitsch   PetscCall(VecSet(Xto, 0.0));
35842dc13f1SHong Zhang 
3599566063dSJacob Faibussowitsch   PetscCall(VecScatterCreate(X, isfrom, Xto, NULL, &ctx));
3609566063dSJacob Faibussowitsch   PetscCall(VecScatterBegin(ctx, X, Xto, INSERT_VALUES, SCATTER_FORWARD));
3619566063dSJacob Faibussowitsch   PetscCall(VecScatterEnd(ctx, X, Xto, INSERT_VALUES, SCATTER_FORWARD));
3629566063dSJacob Faibussowitsch   PetscCall(VecScatterDestroy(&ctx));
3639566063dSJacob Faibussowitsch   PetscCall(ISDestroy(&isfrom));
36442dc13f1SHong Zhang 
3659566063dSJacob Faibussowitsch   PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Xpipes:\n"));
3669566063dSJacob Faibussowitsch   PetscCall(VecView(Xto, PETSC_VIEWER_STDOUT_WORLD));
36742dc13f1SHong Zhang 
36842dc13f1SHong Zhang   /* 7. Free spaces */
369*48a46eb9SPierre Jolivet   for (i = 0; i < numkeys; i++) PetscCall(PetscFree(selectedvariables[i]));
3709566063dSJacob Faibussowitsch   PetscCall(PetscFree3(blocksize, numselectedvariable, selectedvariables));
3719566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&Xto));
37242dc13f1SHong Zhang   PetscFunctionReturn(0);
37342dc13f1SHong Zhang }
37442dc13f1SHong Zhang 
3759371c9d4SSatish Balay PetscErrorCode ISJunctionsView(DM networkdm, PetscInt KeyJunc) {
37642dc13f1SHong Zhang   PetscInt    numkeys = 1;
37742dc13f1SHong Zhang   IS          isfrom;
37842dc13f1SHong Zhang   MPI_Comm    comm;
37942dc13f1SHong Zhang   PetscMPIInt rank;
38042dc13f1SHong Zhang 
38142dc13f1SHong Zhang   PetscFunctionBegin;
3829566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetComm((PetscObject)networkdm, &comm));
3839566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(comm, &rank));
38442dc13f1SHong Zhang 
38542dc13f1SHong Zhang   /* Create a global isfrom for all junction variables */
3869566063dSJacob Faibussowitsch   PetscCall(DMNetworkCreateIS(networkdm, numkeys, &KeyJunc, NULL, NULL, NULL, &isfrom));
3879566063dSJacob Faibussowitsch   PetscCall(PetscPrintf(PETSC_COMM_WORLD, "ISJunctions:\n"));
3889566063dSJacob Faibussowitsch   PetscCall(ISView(isfrom, PETSC_VIEWER_STDOUT_WORLD));
3899566063dSJacob Faibussowitsch   PetscCall(ISDestroy(&isfrom));
39042dc13f1SHong Zhang 
39142dc13f1SHong Zhang   /* Create a local isfrom for all junction variables */
3929566063dSJacob Faibussowitsch   PetscCall(DMNetworkCreateLocalIS(networkdm, numkeys, &KeyJunc, NULL, NULL, NULL, &isfrom));
393c5853193SPierre Jolivet   if (rank == 0) {
3949566063dSJacob Faibussowitsch     PetscCall(PetscPrintf(PETSC_COMM_SELF, "[%d] ISLocalJunctions:\n", rank));
3959566063dSJacob Faibussowitsch     PetscCall(ISView(isfrom, PETSC_VIEWER_STDOUT_SELF));
39642dc13f1SHong Zhang   }
3979566063dSJacob Faibussowitsch   PetscCall(ISDestroy(&isfrom));
39842dc13f1SHong Zhang   PetscFunctionReturn(0);
39942dc13f1SHong Zhang }
40042dc13f1SHong Zhang 
4019371c9d4SSatish Balay PetscErrorCode WashNetworkCleanUp(Wash wash) {
40242dc13f1SHong Zhang   PetscMPIInt rank;
40342dc13f1SHong Zhang 
40442dc13f1SHong Zhang   PetscFunctionBegin;
4059566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(wash->comm, &rank));
4069566063dSJacob Faibussowitsch   PetscCall(PetscFree(wash->edgelist));
4079566063dSJacob Faibussowitsch   PetscCall(PetscFree(wash->vtype));
408*48a46eb9SPierre Jolivet   if (rank == 0) PetscCall(PetscFree2(wash->junction, wash->pipe));
40942dc13f1SHong Zhang   PetscFunctionReturn(0);
41042dc13f1SHong Zhang }
41142dc13f1SHong Zhang 
4129371c9d4SSatish Balay PetscErrorCode WashNetworkCreate(MPI_Comm comm, PetscInt pipesCase, Wash *wash_ptr) {
41342dc13f1SHong Zhang   PetscInt    npipes;
41442dc13f1SHong Zhang   PetscMPIInt rank;
41542dc13f1SHong Zhang   Wash        wash = NULL;
41642dc13f1SHong Zhang   PetscInt    i, numVertices, numEdges, *vtype;
41742dc13f1SHong Zhang   PetscInt   *edgelist;
41842dc13f1SHong Zhang   Junction    junctions = NULL;
41942dc13f1SHong Zhang   Pipe        pipes     = NULL;
42042dc13f1SHong Zhang   PetscBool   washdist  = PETSC_TRUE;
42142dc13f1SHong Zhang 
42242dc13f1SHong Zhang   PetscFunctionBegin;
4239566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(comm, &rank));
42442dc13f1SHong Zhang 
4259566063dSJacob Faibussowitsch   PetscCall(PetscCalloc1(1, &wash));
42642dc13f1SHong Zhang   wash->comm       = comm;
42742dc13f1SHong Zhang   *wash_ptr        = wash;
42842dc13f1SHong Zhang   wash->Q0         = 0.477432; /* RESERVOIR */
42942dc13f1SHong Zhang   wash->H0         = 150.0;
43042dc13f1SHong Zhang   wash->HL         = 143.488; /* VALVE */
43142dc13f1SHong Zhang   wash->QL         = 0.0;
43242dc13f1SHong Zhang   wash->nnodes_loc = 0;
43342dc13f1SHong Zhang 
43442dc13f1SHong Zhang   numVertices = 0;
43542dc13f1SHong Zhang   numEdges    = 0;
43642dc13f1SHong Zhang   edgelist    = NULL;
43742dc13f1SHong Zhang 
43842dc13f1SHong Zhang   /* proc[0] creates a sequential wash and edgelist */
43963a3b9bcSJacob Faibussowitsch   PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Setup pipesCase %" PetscInt_FMT "\n", pipesCase));
44042dc13f1SHong Zhang 
44142dc13f1SHong Zhang   /* Set global number of pipes, edges, and junctions */
44242dc13f1SHong Zhang   /*-------------------------------------------------*/
44342dc13f1SHong Zhang   switch (pipesCase) {
44442dc13f1SHong Zhang   case 0:
44542dc13f1SHong Zhang     /* pipeCase 0: */
44642dc13f1SHong Zhang     /* =================================================
44742dc13f1SHong Zhang     (RESERVOIR) v0 --E0--> v1--E1--> v2 --E2-->v3 (VALVE)
44842dc13f1SHong Zhang     ====================================================  */
44942dc13f1SHong Zhang     npipes = 3;
4509566063dSJacob Faibussowitsch     PetscCall(PetscOptionsGetInt(NULL, NULL, "-npipes", &npipes, NULL));
45142dc13f1SHong Zhang     wash->nedge   = npipes;
45242dc13f1SHong Zhang     wash->nvertex = npipes + 1;
45342dc13f1SHong Zhang 
45442dc13f1SHong Zhang     /* Set local edges and vertices -- proc[0] sets entire network, then distributes */
45542dc13f1SHong Zhang     numVertices = 0;
45642dc13f1SHong Zhang     numEdges    = 0;
45742dc13f1SHong Zhang     edgelist    = NULL;
458dd400576SPatrick Sanan     if (rank == 0) {
45942dc13f1SHong Zhang       numVertices = wash->nvertex;
46042dc13f1SHong Zhang       numEdges    = wash->nedge;
46142dc13f1SHong Zhang 
4629566063dSJacob Faibussowitsch       PetscCall(PetscCalloc1(2 * numEdges, &edgelist));
46342dc13f1SHong Zhang       for (i = 0; i < numEdges; i++) {
4649371c9d4SSatish Balay         edgelist[2 * i]     = i;
4659371c9d4SSatish Balay         edgelist[2 * i + 1] = i + 1;
46642dc13f1SHong Zhang       }
46742dc13f1SHong Zhang 
46842dc13f1SHong Zhang       /* Add network components */
46942dc13f1SHong Zhang       /*------------------------*/
4709566063dSJacob Faibussowitsch       PetscCall(PetscCalloc2(numVertices, &junctions, numEdges, &pipes));
47142dc13f1SHong Zhang 
47242dc13f1SHong Zhang       /* vertex */
47342dc13f1SHong Zhang       for (i = 0; i < numVertices; i++) {
47442dc13f1SHong Zhang         junctions[i].id   = i;
47542dc13f1SHong Zhang         junctions[i].type = JUNCTION;
47642dc13f1SHong Zhang       }
47742dc13f1SHong Zhang 
47842dc13f1SHong Zhang       junctions[0].type               = RESERVOIR;
47942dc13f1SHong Zhang       junctions[numVertices - 1].type = VALVE;
48042dc13f1SHong Zhang     }
48142dc13f1SHong Zhang     break;
48242dc13f1SHong Zhang   case 1:
48342dc13f1SHong Zhang     /* pipeCase 1: */
48442dc13f1SHong Zhang     /* ==========================
48542dc13f1SHong Zhang                 v2 (VALVE)
48642dc13f1SHong Zhang                 ^
48742dc13f1SHong Zhang                 |
48842dc13f1SHong Zhang                E2
48942dc13f1SHong Zhang                 |
49042dc13f1SHong Zhang     v0 --E0--> v3--E1--> v1
49142dc13f1SHong Zhang   (RESERVOIR)            (RESERVOIR)
49242dc13f1SHong Zhang     =============================  */
49342dc13f1SHong Zhang     npipes        = 3;
49442dc13f1SHong Zhang     wash->nedge   = npipes;
49542dc13f1SHong Zhang     wash->nvertex = npipes + 1;
49642dc13f1SHong Zhang 
49742dc13f1SHong Zhang     /* Set local edges and vertices -- proc[0] sets entire network, then distributes */
498dd400576SPatrick Sanan     if (rank == 0) {
49942dc13f1SHong Zhang       numVertices = wash->nvertex;
50042dc13f1SHong Zhang       numEdges    = wash->nedge;
50142dc13f1SHong Zhang 
5029566063dSJacob Faibussowitsch       PetscCall(PetscCalloc1(2 * numEdges, &edgelist));
5039371c9d4SSatish Balay       edgelist[0] = 0;
5049371c9d4SSatish Balay       edgelist[1] = 3; /* edge[0] */
5059371c9d4SSatish Balay       edgelist[2] = 3;
5069371c9d4SSatish Balay       edgelist[3] = 1; /* edge[1] */
5079371c9d4SSatish Balay       edgelist[4] = 3;
5089371c9d4SSatish Balay       edgelist[5] = 2; /* edge[2] */
50942dc13f1SHong Zhang 
51042dc13f1SHong Zhang       /* Add network components */
51142dc13f1SHong Zhang       /*------------------------*/
5129566063dSJacob Faibussowitsch       PetscCall(PetscCalloc2(numVertices, &junctions, numEdges, &pipes));
51342dc13f1SHong Zhang       /* vertex */
51442dc13f1SHong Zhang       for (i = 0; i < numVertices; i++) {
51542dc13f1SHong Zhang         junctions[i].id   = i;
51642dc13f1SHong Zhang         junctions[i].type = JUNCTION;
51742dc13f1SHong Zhang       }
51842dc13f1SHong Zhang 
51942dc13f1SHong Zhang       junctions[0].type = RESERVOIR;
52042dc13f1SHong Zhang       junctions[1].type = VALVE;
52142dc13f1SHong Zhang       junctions[2].type = VALVE;
52242dc13f1SHong Zhang     }
52342dc13f1SHong Zhang     break;
52442dc13f1SHong Zhang   case 2:
52542dc13f1SHong Zhang     /* pipeCase 2: */
52642dc13f1SHong Zhang     /* ==========================
52742dc13f1SHong Zhang     (RESERVOIR)  v2--> E2
52842dc13f1SHong Zhang                        |
52942dc13f1SHong Zhang             v0 --E0--> v3--E1--> v1
53042dc13f1SHong Zhang     (RESERVOIR)               (VALVE)
53142dc13f1SHong Zhang     =============================  */
53242dc13f1SHong Zhang 
53342dc13f1SHong Zhang     /* Set application parameters -- to be used in function evalutions */
53442dc13f1SHong Zhang     npipes        = 3;
53542dc13f1SHong Zhang     wash->nedge   = npipes;
53642dc13f1SHong Zhang     wash->nvertex = npipes + 1;
53742dc13f1SHong Zhang 
53842dc13f1SHong Zhang     /* Set local edges and vertices -- proc[0] sets entire network, then distributes */
539dd400576SPatrick Sanan     if (rank == 0) {
54042dc13f1SHong Zhang       numVertices = wash->nvertex;
54142dc13f1SHong Zhang       numEdges    = wash->nedge;
54242dc13f1SHong Zhang 
5439566063dSJacob Faibussowitsch       PetscCall(PetscCalloc1(2 * numEdges, &edgelist));
5449371c9d4SSatish Balay       edgelist[0] = 0;
5459371c9d4SSatish Balay       edgelist[1] = 3; /* edge[0] */
5469371c9d4SSatish Balay       edgelist[2] = 3;
5479371c9d4SSatish Balay       edgelist[3] = 1; /* edge[1] */
5489371c9d4SSatish Balay       edgelist[4] = 2;
5499371c9d4SSatish Balay       edgelist[5] = 3; /* edge[2] */
55042dc13f1SHong Zhang 
55142dc13f1SHong Zhang       /* Add network components */
55242dc13f1SHong Zhang       /*------------------------*/
5539566063dSJacob Faibussowitsch       PetscCall(PetscCalloc2(numVertices, &junctions, numEdges, &pipes));
55442dc13f1SHong Zhang       /* vertex */
55542dc13f1SHong Zhang       for (i = 0; i < numVertices; i++) {
55642dc13f1SHong Zhang         junctions[i].id   = i;
55742dc13f1SHong Zhang         junctions[i].type = JUNCTION;
55842dc13f1SHong Zhang       }
55942dc13f1SHong Zhang 
56042dc13f1SHong Zhang       junctions[0].type = RESERVOIR;
56142dc13f1SHong Zhang       junctions[1].type = VALVE;
56242dc13f1SHong Zhang       junctions[2].type = RESERVOIR;
56342dc13f1SHong Zhang     }
56442dc13f1SHong Zhang     break;
5659371c9d4SSatish Balay   default: SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "not done yet");
56642dc13f1SHong Zhang   }
56742dc13f1SHong Zhang 
56842dc13f1SHong Zhang   /* set edge global id */
56942dc13f1SHong Zhang   for (i = 0; i < numEdges; i++) pipes[i].id = i;
57042dc13f1SHong Zhang 
571dd400576SPatrick Sanan   if (rank == 0) { /* set vtype for proc[0] */
57242dc13f1SHong Zhang     PetscInt v;
5739566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(2 * numEdges, &vtype));
57442dc13f1SHong Zhang     for (i = 0; i < 2 * numEdges; i++) {
57542dc13f1SHong Zhang       v        = edgelist[i];
57642dc13f1SHong Zhang       vtype[i] = junctions[v].type;
57742dc13f1SHong Zhang     }
57842dc13f1SHong Zhang     wash->vtype = vtype;
57942dc13f1SHong Zhang   }
58042dc13f1SHong Zhang 
58142dc13f1SHong Zhang   *wash_ptr      = wash;
58242dc13f1SHong Zhang   wash->nedge    = numEdges;
58342dc13f1SHong Zhang   wash->nvertex  = numVertices;
58442dc13f1SHong Zhang   wash->edgelist = edgelist;
58542dc13f1SHong Zhang   wash->junction = junctions;
58642dc13f1SHong Zhang   wash->pipe     = pipes;
58742dc13f1SHong Zhang 
58842dc13f1SHong Zhang   /* Distribute edgelist to other processors */
5899566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetBool(NULL, NULL, "-wash_distribute", &washdist, NULL));
59042dc13f1SHong Zhang   if (washdist) {
59142dc13f1SHong Zhang     /*
5929566063dSJacob Faibussowitsch      PetscCall(PetscPrintf(PETSC_COMM_WORLD," Distribute sequential wash ...\n"));
59342dc13f1SHong Zhang      */
5949566063dSJacob Faibussowitsch     PetscCall(WashNetworkDistribute(comm, wash));
59542dc13f1SHong Zhang   }
59642dc13f1SHong Zhang   PetscFunctionReturn(0);
59742dc13f1SHong Zhang }
59842dc13f1SHong Zhang 
59942dc13f1SHong Zhang /* ------------------------------------------------------- */
6009371c9d4SSatish Balay int main(int argc, char **argv) {
60142dc13f1SHong Zhang   Wash              wash;
60242dc13f1SHong Zhang   Junction          junctions, junction;
60342dc13f1SHong Zhang   Pipe              pipe, pipes;
604f11a936eSBarry Smith   PetscInt          KeyPipe, KeyJunction, *edgelist = NULL, *vtype = NULL;
605f11a936eSBarry Smith   PetscInt          i, e, v, eStart, eEnd, vStart, vEnd, key, vkey, type;
606f11a936eSBarry Smith   PetscInt          steps = 1, nedges, nnodes = 6;
60742dc13f1SHong Zhang   const PetscInt   *cone;
60842dc13f1SHong Zhang   DM                networkdm;
60942dc13f1SHong Zhang   PetscMPIInt       size, rank;
61042dc13f1SHong Zhang   PetscReal         ftime;
61142dc13f1SHong Zhang   Vec               X;
61242dc13f1SHong Zhang   TS                ts;
61342dc13f1SHong Zhang   TSConvergedReason reason;
61442dc13f1SHong Zhang   PetscBool         viewpipes, viewjuncs, monipipes = PETSC_FALSE, userJac = PETSC_TRUE, viewdm = PETSC_FALSE, viewX = PETSC_FALSE;
61542dc13f1SHong Zhang   PetscInt          pipesCase = 0;
61642dc13f1SHong Zhang   DMNetworkMonitor  monitor;
61742dc13f1SHong Zhang   MPI_Comm          comm;
61842dc13f1SHong Zhang 
619327415f7SBarry Smith   PetscFunctionBeginUser;
6209566063dSJacob Faibussowitsch   PetscCall(PetscInitialize(&argc, &argv, "pOption", help));
62142dc13f1SHong Zhang 
62242dc13f1SHong Zhang   /* Read runtime options */
6239566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetInt(NULL, NULL, "-case", &pipesCase, NULL));
6249566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetBool(NULL, NULL, "-user_Jac", &userJac, NULL));
6259566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetBool(NULL, NULL, "-pipe_monitor", &monipipes, NULL));
6269566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetBool(NULL, NULL, "-viewdm", &viewdm, NULL));
6279566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetBool(NULL, NULL, "-viewX", &viewX, NULL));
6289566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetInt(NULL, NULL, "-npipenodes", &nnodes, NULL));
62942dc13f1SHong Zhang 
63042dc13f1SHong Zhang   /* Create networkdm */
63142dc13f1SHong Zhang   /*------------------*/
6329566063dSJacob Faibussowitsch   PetscCall(DMNetworkCreate(PETSC_COMM_WORLD, &networkdm));
6339566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetComm((PetscObject)networkdm, &comm));
6349566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(comm, &rank));
6359566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_size(comm, &size));
63642dc13f1SHong Zhang 
637*48a46eb9SPierre Jolivet   if (size == 1 && monipipes) PetscCall(DMNetworkMonitorCreate(networkdm, &monitor));
63842dc13f1SHong Zhang 
63942dc13f1SHong Zhang   /* Register the components in the network */
6409566063dSJacob Faibussowitsch   PetscCall(DMNetworkRegisterComponent(networkdm, "junctionstruct", sizeof(struct _p_Junction), &KeyJunction));
6419566063dSJacob Faibussowitsch   PetscCall(DMNetworkRegisterComponent(networkdm, "pipestruct", sizeof(struct _p_Pipe), &KeyPipe));
64242dc13f1SHong Zhang 
64342dc13f1SHong Zhang   /* Create a distributed wash network (user-specific) */
6449566063dSJacob Faibussowitsch   PetscCall(WashNetworkCreate(comm, pipesCase, &wash));
64542dc13f1SHong Zhang   nedges    = wash->nedge;
64642dc13f1SHong Zhang   edgelist  = wash->edgelist;
64742dc13f1SHong Zhang   vtype     = wash->vtype;
64842dc13f1SHong Zhang   junctions = wash->junction;
64942dc13f1SHong Zhang   pipes     = wash->pipe;
65042dc13f1SHong Zhang 
65142dc13f1SHong Zhang   /* Set up the network layout */
6529566063dSJacob Faibussowitsch   PetscCall(DMNetworkSetNumSubNetworks(networkdm, PETSC_DECIDE, 1));
6539566063dSJacob Faibussowitsch   PetscCall(DMNetworkAddSubnetwork(networkdm, NULL, nedges, edgelist, NULL));
65442dc13f1SHong Zhang 
6559566063dSJacob Faibussowitsch   PetscCall(DMNetworkLayoutSetUp(networkdm));
65642dc13f1SHong Zhang 
6579566063dSJacob Faibussowitsch   PetscCall(DMNetworkGetEdgeRange(networkdm, &eStart, &eEnd));
6589566063dSJacob Faibussowitsch   PetscCall(DMNetworkGetVertexRange(networkdm, &vStart, &vEnd));
6599566063dSJacob Faibussowitsch   /* PetscCall(PetscPrintf(PETSC_COMM_SELF,"[%d] eStart/End: %d - %d; vStart/End: %d - %d\n",rank,eStart,eEnd,vStart,vEnd)); */
66042dc13f1SHong Zhang 
66142dc13f1SHong Zhang   if (rank) { /* junctions[] and pipes[] for proc[0] are allocated in WashNetworkCreate() */
66242dc13f1SHong Zhang     /* vEnd - vStart = nvertices + number of ghost vertices! */
6639566063dSJacob Faibussowitsch     PetscCall(PetscCalloc2(vEnd - vStart, &junctions, nedges, &pipes));
66442dc13f1SHong Zhang   }
66542dc13f1SHong Zhang 
66642dc13f1SHong Zhang   /* Add Pipe component and number of variables to all local edges */
66742dc13f1SHong Zhang   for (e = eStart; e < eEnd; e++) {
66842dc13f1SHong Zhang     pipes[e - eStart].nnodes = nnodes;
6699566063dSJacob Faibussowitsch     PetscCall(DMNetworkAddComponent(networkdm, e, KeyPipe, &pipes[e - eStart], 2 * pipes[e - eStart].nnodes));
67042dc13f1SHong Zhang 
67142dc13f1SHong Zhang     if (size == 1 && monipipes) { /* Add monitor -- show Q_{pipes[e-eStart].id}? */
67242dc13f1SHong Zhang       pipes[e - eStart].length = 600.0;
6739566063dSJacob Faibussowitsch       PetscCall(DMNetworkMonitorAdd(monitor, "Pipe Q", e, pipes[e - eStart].nnodes, 0, 2, 0.0, pipes[e - eStart].length, -0.8, 0.8, PETSC_TRUE));
6749566063dSJacob Faibussowitsch       PetscCall(DMNetworkMonitorAdd(monitor, "Pipe H", e, pipes[e - eStart].nnodes, 1, 2, 0.0, pipes[e - eStart].length, -400.0, 800.0, PETSC_TRUE));
67542dc13f1SHong Zhang     }
67642dc13f1SHong Zhang   }
67742dc13f1SHong Zhang 
678eac198afSGetnet   /* Add Junction component and number of variables to all local vertices */
679*48a46eb9SPierre Jolivet   for (v = vStart; v < vEnd; v++) PetscCall(DMNetworkAddComponent(networkdm, v, KeyJunction, &junctions[v - vStart], 2));
68042dc13f1SHong Zhang 
68142dc13f1SHong Zhang   if (size > 1) { /* must be called before DMSetUp()???. Other partitioners do not work yet??? -- cause crash in proc[0]! */
68242dc13f1SHong Zhang     DM               plexdm;
68342dc13f1SHong Zhang     PetscPartitioner part;
6849566063dSJacob Faibussowitsch     PetscCall(DMNetworkGetPlex(networkdm, &plexdm));
6859566063dSJacob Faibussowitsch     PetscCall(DMPlexGetPartitioner(plexdm, &part));
6869566063dSJacob Faibussowitsch     PetscCall(PetscPartitionerSetType(part, PETSCPARTITIONERSIMPLE));
6879566063dSJacob Faibussowitsch     PetscCall(PetscOptionsSetValue(NULL, "-dm_plex_csr_alg", "mat")); /* for parmetis */
68842dc13f1SHong Zhang   }
68942dc13f1SHong Zhang 
69042dc13f1SHong Zhang   /* Set up DM for use */
6919566063dSJacob Faibussowitsch   PetscCall(DMSetUp(networkdm));
69242dc13f1SHong Zhang   if (viewdm) {
6939566063dSJacob Faibussowitsch     PetscCall(PetscPrintf(PETSC_COMM_WORLD, "\nOriginal networkdm, DMView:\n"));
6949566063dSJacob Faibussowitsch     PetscCall(DMView(networkdm, PETSC_VIEWER_STDOUT_WORLD));
69542dc13f1SHong Zhang   }
69642dc13f1SHong Zhang 
69742dc13f1SHong Zhang   /* Set user physical parameters to the components */
69842dc13f1SHong Zhang   for (e = eStart; e < eEnd; e++) {
6999566063dSJacob Faibussowitsch     PetscCall(DMNetworkGetConnectedVertices(networkdm, e, &cone));
70042dc13f1SHong Zhang     /* vfrom */
7019566063dSJacob Faibussowitsch     PetscCall(DMNetworkGetComponent(networkdm, cone[0], 0, &vkey, (void **)&junction, NULL));
70242dc13f1SHong Zhang     junction->type = (VertexType)vtype[2 * e];
70342dc13f1SHong Zhang 
70442dc13f1SHong Zhang     /* vto */
7059566063dSJacob Faibussowitsch     PetscCall(DMNetworkGetComponent(networkdm, cone[1], 0, &vkey, (void **)&junction, NULL));
70642dc13f1SHong Zhang     junction->type = (VertexType)vtype[2 * e + 1];
70742dc13f1SHong Zhang   }
70842dc13f1SHong Zhang 
7099566063dSJacob Faibussowitsch   PetscCall(WashNetworkCleanUp(wash));
71042dc13f1SHong Zhang 
71142dc13f1SHong Zhang   /* Network partitioning and distribution of data */
7129566063dSJacob Faibussowitsch   PetscCall(DMNetworkDistribute(&networkdm, 0));
71342dc13f1SHong Zhang   if (viewdm) {
7149566063dSJacob Faibussowitsch     PetscCall(PetscPrintf(PETSC_COMM_WORLD, "\nAfter DMNetworkDistribute, DMView:\n"));
7159566063dSJacob Faibussowitsch     PetscCall(DMView(networkdm, PETSC_VIEWER_STDOUT_WORLD));
71642dc13f1SHong Zhang   }
71742dc13f1SHong Zhang 
71842dc13f1SHong Zhang   /* create vectors */
7199566063dSJacob Faibussowitsch   PetscCall(DMCreateGlobalVector(networkdm, &X));
7209566063dSJacob Faibussowitsch   PetscCall(DMCreateLocalVector(networkdm, &wash->localX));
7219566063dSJacob Faibussowitsch   PetscCall(DMCreateLocalVector(networkdm, &wash->localXdot));
72242dc13f1SHong Zhang 
72342dc13f1SHong Zhang   /* PipeSetUp -- each process only sets its own pipes */
72442dc13f1SHong Zhang   /*---------------------------------------------------*/
7259566063dSJacob Faibussowitsch   PetscCall(DMNetworkGetVertexRange(networkdm, &vStart, &vEnd));
72642dc13f1SHong Zhang 
72742dc13f1SHong Zhang   userJac = PETSC_TRUE;
7289566063dSJacob Faibussowitsch   PetscCall(DMNetworkHasJacobian(networkdm, userJac, userJac));
7299566063dSJacob Faibussowitsch   PetscCall(DMNetworkGetEdgeRange(networkdm, &eStart, &eEnd));
73042dc13f1SHong Zhang   for (e = eStart; e < eEnd; e++) { /* each edge has only one component, pipe */
7319566063dSJacob Faibussowitsch     PetscCall(DMNetworkGetComponent(networkdm, e, 0, &type, (void **)&pipe, NULL));
73242dc13f1SHong Zhang 
73342dc13f1SHong Zhang     wash->nnodes_loc += pipe->nnodes;        /* local total number of nodes, will be used by PipesView() */
7349371c9d4SSatish Balay     PetscCall(PipeSetParameters(pipe, 600.0, /* length   */
73542dc13f1SHong Zhang                                 0.5,         /* diameter */
73642dc13f1SHong Zhang                                 1200.0,      /* a        */
737b122ec5aSJacob Faibussowitsch                                 0.018));     /* friction */
7389566063dSJacob Faibussowitsch     PetscCall(PipeSetUp(pipe));
73942dc13f1SHong Zhang 
74042dc13f1SHong Zhang     if (userJac) {
74142dc13f1SHong Zhang       /* Create Jacobian matrix structures for a Pipe */
74242dc13f1SHong Zhang       Mat *J;
7439566063dSJacob Faibussowitsch       PetscCall(PipeCreateJacobian(pipe, NULL, &J));
7449566063dSJacob Faibussowitsch       PetscCall(DMNetworkEdgeSetMatrix(networkdm, e, J));
74542dc13f1SHong Zhang     }
74642dc13f1SHong Zhang   }
74742dc13f1SHong Zhang 
74842dc13f1SHong Zhang   if (userJac) {
7499566063dSJacob Faibussowitsch     PetscCall(DMNetworkGetVertexRange(networkdm, &vStart, &vEnd));
75042dc13f1SHong Zhang     for (v = vStart; v < vEnd; v++) {
75142dc13f1SHong Zhang       Mat *J;
7529566063dSJacob Faibussowitsch       PetscCall(JunctionCreateJacobian(networkdm, v, NULL, &J));
7539566063dSJacob Faibussowitsch       PetscCall(DMNetworkVertexSetMatrix(networkdm, v, J));
75442dc13f1SHong Zhang 
7559566063dSJacob Faibussowitsch       PetscCall(DMNetworkGetComponent(networkdm, v, 0, &vkey, (void **)&junction, NULL));
75642dc13f1SHong Zhang       junction->jacobian = J;
75742dc13f1SHong Zhang     }
75842dc13f1SHong Zhang   }
75942dc13f1SHong Zhang 
76042dc13f1SHong Zhang   /* Setup solver                                           */
76142dc13f1SHong Zhang   /*--------------------------------------------------------*/
7629566063dSJacob Faibussowitsch   PetscCall(TSCreate(PETSC_COMM_WORLD, &ts));
76342dc13f1SHong Zhang 
7649566063dSJacob Faibussowitsch   PetscCall(TSSetDM(ts, (DM)networkdm));
7659566063dSJacob Faibussowitsch   PetscCall(TSSetIFunction(ts, NULL, WASHIFunction, wash));
76642dc13f1SHong Zhang 
7679566063dSJacob Faibussowitsch   PetscCall(TSSetMaxSteps(ts, steps));
7689566063dSJacob Faibussowitsch   PetscCall(TSSetExactFinalTime(ts, TS_EXACTFINALTIME_STEPOVER));
7699566063dSJacob Faibussowitsch   PetscCall(TSSetTimeStep(ts, 0.1));
7709566063dSJacob Faibussowitsch   PetscCall(TSSetType(ts, TSBEULER));
7719566063dSJacob Faibussowitsch   if (size == 1 && monipipes) PetscCall(TSMonitorSet(ts, TSDMNetworkMonitor, monitor, NULL));
7729566063dSJacob Faibussowitsch   PetscCall(TSSetFromOptions(ts));
77342dc13f1SHong Zhang 
7749566063dSJacob Faibussowitsch   PetscCall(WASHSetInitialSolution(networkdm, X, wash));
77542dc13f1SHong Zhang 
7769566063dSJacob Faibussowitsch   PetscCall(TSSolve(ts, X));
77742dc13f1SHong Zhang 
7789566063dSJacob Faibussowitsch   PetscCall(TSGetSolveTime(ts, &ftime));
7799566063dSJacob Faibussowitsch   PetscCall(TSGetStepNumber(ts, &steps));
7809566063dSJacob Faibussowitsch   PetscCall(TSGetConvergedReason(ts, &reason));
78163a3b9bcSJacob Faibussowitsch   PetscCall(PetscPrintf(PETSC_COMM_WORLD, "%s at time %g after %" PetscInt_FMT " steps\n", TSConvergedReasons[reason], (double)ftime, steps));
7821baa6e33SBarry Smith   if (viewX) PetscCall(VecView(X, PETSC_VIEWER_STDOUT_WORLD));
78342dc13f1SHong Zhang 
78442dc13f1SHong Zhang   viewpipes = PETSC_FALSE;
7859566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetBool(NULL, NULL, "-Jac_view", &viewpipes, NULL));
78642dc13f1SHong Zhang   if (viewpipes) {
78742dc13f1SHong Zhang     SNES snes;
78842dc13f1SHong Zhang     Mat  Jac;
7899566063dSJacob Faibussowitsch     PetscCall(TSGetSNES(ts, &snes));
7909566063dSJacob Faibussowitsch     PetscCall(SNESGetJacobian(snes, &Jac, NULL, NULL, NULL));
7919566063dSJacob Faibussowitsch     PetscCall(MatView(Jac, PETSC_VIEWER_DRAW_WORLD));
79242dc13f1SHong Zhang   }
79342dc13f1SHong Zhang 
79442dc13f1SHong Zhang   /* View solutions */
79542dc13f1SHong Zhang   /* -------------- */
79642dc13f1SHong Zhang   viewpipes = PETSC_FALSE;
7979566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetBool(NULL, NULL, "-pipe_view", &viewpipes, NULL));
7981baa6e33SBarry Smith   if (viewpipes) PetscCall(PipesView(networkdm, KeyPipe, X));
79942dc13f1SHong Zhang 
80042dc13f1SHong Zhang   /* Test IS */
80142dc13f1SHong Zhang   viewjuncs = PETSC_FALSE;
8029566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetBool(NULL, NULL, "-isjunc_view", &viewjuncs, NULL));
8031baa6e33SBarry Smith   if (viewjuncs) PetscCall(ISJunctionsView(networkdm, KeyJunction));
80442dc13f1SHong Zhang 
80542dc13f1SHong Zhang   /* Free spaces */
80642dc13f1SHong Zhang   /* ----------- */
8079566063dSJacob Faibussowitsch   PetscCall(TSDestroy(&ts));
8089566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&X));
8099566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&wash->localX));
8109566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&wash->localXdot));
81142dc13f1SHong Zhang 
81242dc13f1SHong Zhang   /* Destroy objects from each pipe that are created in PipeSetUp() */
8139566063dSJacob Faibussowitsch   PetscCall(DMNetworkGetEdgeRange(networkdm, &eStart, &eEnd));
81442dc13f1SHong Zhang   for (i = eStart; i < eEnd; i++) {
8159566063dSJacob Faibussowitsch     PetscCall(DMNetworkGetComponent(networkdm, i, 0, &key, (void **)&pipe, NULL));
8169566063dSJacob Faibussowitsch     PetscCall(PipeDestroy(&pipe));
81742dc13f1SHong Zhang   }
81842dc13f1SHong Zhang   if (userJac) {
81942dc13f1SHong Zhang     for (v = vStart; v < vEnd; v++) {
8209566063dSJacob Faibussowitsch       PetscCall(DMNetworkGetComponent(networkdm, v, 0, &vkey, (void **)&junction, NULL));
8219566063dSJacob Faibussowitsch       PetscCall(JunctionDestroyJacobian(networkdm, v, junction));
82242dc13f1SHong Zhang     }
82342dc13f1SHong Zhang   }
82442dc13f1SHong Zhang 
825*48a46eb9SPierre Jolivet   if (size == 1 && monipipes) PetscCall(DMNetworkMonitorDestroy(&monitor));
8269566063dSJacob Faibussowitsch   PetscCall(DMDestroy(&networkdm));
8279566063dSJacob Faibussowitsch   PetscCall(PetscFree(wash));
82842dc13f1SHong Zhang 
8291baa6e33SBarry Smith   if (rank) PetscCall(PetscFree2(junctions, pipes));
8309566063dSJacob Faibussowitsch   PetscCall(PetscFinalize());
831b122ec5aSJacob Faibussowitsch   return 0;
83242dc13f1SHong Zhang }
83342dc13f1SHong Zhang 
83442dc13f1SHong Zhang /*TEST
83542dc13f1SHong Zhang 
83642dc13f1SHong Zhang    build:
83742dc13f1SHong Zhang      depends: pipeInterface.c pipeImpls.c
83842dc13f1SHong Zhang      requires: mumps
83942dc13f1SHong Zhang 
84042dc13f1SHong Zhang    test:
84142dc13f1SHong Zhang       args: -ts_monitor -case 1 -ts_max_steps 1 -pc_factor_mat_solver_type mumps -options_left no -viewX
84242dc13f1SHong Zhang       localrunfiles: pOption
84342dc13f1SHong Zhang       output_file: output/pipes_1.out
84442dc13f1SHong Zhang 
84542dc13f1SHong Zhang    test:
84642dc13f1SHong Zhang       suffix: 2
84742dc13f1SHong Zhang       nsize: 2
84842dc13f1SHong Zhang       args: -ts_monitor -case 1 -ts_max_steps 1 -pc_factor_mat_solver_type mumps -petscpartitioner_type simple -options_left no -viewX
84942dc13f1SHong Zhang       localrunfiles: pOption
85042dc13f1SHong Zhang       output_file: output/pipes_2.out
85142dc13f1SHong Zhang 
85242dc13f1SHong Zhang    test:
85342dc13f1SHong Zhang       suffix: 3
85442dc13f1SHong Zhang       nsize: 2
85542dc13f1SHong Zhang       args: -ts_monitor -case 0 -ts_max_steps 1 -pc_factor_mat_solver_type mumps -petscpartitioner_type simple -options_left no -viewX
85642dc13f1SHong Zhang       localrunfiles: pOption
85742dc13f1SHong Zhang       output_file: output/pipes_3.out
85842dc13f1SHong Zhang 
85942dc13f1SHong Zhang    test:
86042dc13f1SHong Zhang       suffix: 4
86142dc13f1SHong Zhang       args: -ts_monitor -case 2 -ts_max_steps 1 -pc_factor_mat_solver_type mumps -options_left no -viewX
86242dc13f1SHong Zhang       localrunfiles: pOption
86342dc13f1SHong Zhang       output_file: output/pipes_4.out
86442dc13f1SHong Zhang 
86542dc13f1SHong Zhang    test:
86642dc13f1SHong Zhang       suffix: 5
86742dc13f1SHong Zhang       nsize: 3
86842dc13f1SHong Zhang       args: -ts_monitor -case 2 -ts_max_steps 10 -pc_factor_mat_solver_type mumps -petscpartitioner_type simple -options_left no -viewX
86942dc13f1SHong Zhang       localrunfiles: pOption
87042dc13f1SHong Zhang       output_file: output/pipes_5.out
87142dc13f1SHong Zhang 
87242dc13f1SHong Zhang    test:
87342dc13f1SHong Zhang       suffix: 6
87442dc13f1SHong Zhang       nsize: 2
87542dc13f1SHong Zhang       args: -ts_monitor -case 1 -ts_max_steps 1 -pc_factor_mat_solver_type mumps -petscpartitioner_type simple -options_left no -wash_distribute 0 -viewX
87642dc13f1SHong Zhang       localrunfiles: pOption
87742dc13f1SHong Zhang       output_file: output/pipes_6.out
87842dc13f1SHong Zhang 
87942dc13f1SHong Zhang    test:
88042dc13f1SHong Zhang       suffix: 7
88142dc13f1SHong Zhang       nsize: 2
88242dc13f1SHong Zhang       args: -ts_monitor -case 2 -ts_max_steps 1 -pc_factor_mat_solver_type mumps -petscpartitioner_type simple -options_left no -wash_distribute 0 -viewX
88342dc13f1SHong Zhang       localrunfiles: pOption
88442dc13f1SHong Zhang       output_file: output/pipes_7.out
88542dc13f1SHong Zhang 
88642dc13f1SHong Zhang    test:
88742dc13f1SHong Zhang       suffix: 8
88842dc13f1SHong Zhang       nsize: 2
88942dc13f1SHong Zhang       requires: parmetis
89042dc13f1SHong Zhang       args: -ts_monitor -case 2 -ts_max_steps 1 -pc_factor_mat_solver_type mumps -petscpartitioner_type parmetis -options_left no -wash_distribute 1
89142dc13f1SHong Zhang       localrunfiles: pOption
89242dc13f1SHong Zhang       output_file: output/pipes_8.out
89342dc13f1SHong Zhang 
89442dc13f1SHong Zhang    test:
89542dc13f1SHong Zhang       suffix: 9
89642dc13f1SHong Zhang       nsize: 2
89742dc13f1SHong Zhang       args: -case 0 -ts_max_steps 1 -pc_factor_mat_solver_type mumps -petscpartitioner_type simple -options_left no -wash_distribute 0 -pipe_view
89842dc13f1SHong Zhang       localrunfiles: pOption
89942dc13f1SHong Zhang       output_file: output/pipes_9.out
90042dc13f1SHong Zhang 
90142dc13f1SHong Zhang    test:
90242dc13f1SHong Zhang       suffix: 10
90342dc13f1SHong Zhang       nsize: 2
90442dc13f1SHong Zhang       args: -case 0 -ts_max_steps 1 -pc_factor_mat_solver_type mumps -petscpartitioner_type simple -options_left no -wash_distribute 0 -isjunc_view
90542dc13f1SHong Zhang       localrunfiles: pOption
90642dc13f1SHong Zhang       output_file: output/pipes_10.out
90742dc13f1SHong Zhang 
90842dc13f1SHong Zhang TEST*/
909