xref: /petsc/src/ts/tutorials/network/pipes.c (revision c5853193be7e0cd23913bbf6af39be2e963e2513)
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 */
1942dc13f1SHong Zhang PetscErrorCode WashNetworkDistribute(MPI_Comm comm,Wash wash)
2042dc13f1SHong Zhang {
2142dc13f1SHong Zhang   PetscMPIInt    rank,size,tag=0;
2242dc13f1SHong Zhang   PetscInt       i,e,v,numEdges,numVertices,nedges,*eowners=NULL,estart,eend,*vtype=NULL,nvertices;
2342dc13f1SHong Zhang   PetscInt       *edgelist = wash->edgelist,*nvtx=NULL,*vtxDone=NULL;
2442dc13f1SHong Zhang 
2542dc13f1SHong Zhang   PetscFunctionBegin;
269566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_size(comm,&size));
2742dc13f1SHong Zhang   if (size == 1) PetscFunctionReturn(0);
2842dc13f1SHong Zhang 
299566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(comm,&rank));
3042dc13f1SHong Zhang   numEdges    = wash->nedge;
3142dc13f1SHong Zhang   numVertices = wash->nvertex;
3242dc13f1SHong Zhang 
3342dc13f1SHong Zhang   /* (1) all processes get global and local number of edges */
349566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Bcast(&numEdges,1,MPIU_INT,0,comm));
3542dc13f1SHong Zhang   nedges = numEdges/size; /* local nedges */
36dd400576SPatrick Sanan   if (rank == 0) {
3742dc13f1SHong Zhang     nedges += numEdges - size*(numEdges/size);
3842dc13f1SHong Zhang   }
3942dc13f1SHong Zhang   wash->Nedge = numEdges;
4042dc13f1SHong Zhang   wash->nedge = nedges;
419566063dSJacob Faibussowitsch   /* PetscCall(PetscPrintf(PETSC_COMM_SELF,"[%d] nedges %d, numEdges %d\n",rank,nedges,numEdges)); */
4242dc13f1SHong Zhang 
439566063dSJacob Faibussowitsch   PetscCall(PetscCalloc3(size+1,&eowners,size,&nvtx,numVertices,&vtxDone));
449566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Allgather(&nedges,1,MPIU_INT,eowners+1,1,MPIU_INT,PETSC_COMM_WORLD));
4542dc13f1SHong Zhang   eowners[0] = 0;
4642dc13f1SHong Zhang   for (i=2; i<=size; i++) {
4742dc13f1SHong Zhang     eowners[i] += eowners[i-1];
4842dc13f1SHong Zhang   }
4942dc13f1SHong Zhang 
5042dc13f1SHong Zhang   estart = eowners[rank];
5142dc13f1SHong Zhang   eend   = eowners[rank+1];
529566063dSJacob Faibussowitsch   /* PetscCall(PetscPrintf(PETSC_COMM_SELF,"[%d] own lists row %d - %d\n",rank,estart,eend)); */
5342dc13f1SHong Zhang 
5442dc13f1SHong Zhang   /* (2) distribute row block edgelist to all processors */
55dd400576SPatrick Sanan   if (rank == 0) {
5642dc13f1SHong Zhang     vtype = wash->vtype;
5742dc13f1SHong Zhang     for (i=1; i<size; i++) {
5842dc13f1SHong Zhang       /* proc[0] sends edgelist to proc[i] */
599566063dSJacob Faibussowitsch       PetscCallMPI(MPI_Send(edgelist+2*eowners[i],2*(eowners[i+1]-eowners[i]),MPIU_INT,i,tag,comm));
6042dc13f1SHong Zhang 
6142dc13f1SHong Zhang       /* proc[0] sends vtype to proc[i] */
629566063dSJacob Faibussowitsch       PetscCallMPI(MPI_Send(vtype+2*eowners[i],2*(eowners[i+1]-eowners[i]),MPIU_INT,i,tag,comm));
6342dc13f1SHong Zhang     }
6442dc13f1SHong Zhang   } else {
6542dc13f1SHong Zhang     MPI_Status      status;
669566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(2*(eend-estart),&vtype));
679566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(2*(eend-estart),&edgelist));
6842dc13f1SHong Zhang 
699566063dSJacob Faibussowitsch     PetscCallMPI(MPI_Recv(edgelist,2*(eend-estart),MPIU_INT,0,tag,comm,&status));
709566063dSJacob Faibussowitsch     PetscCallMPI(MPI_Recv(vtype,2*(eend-estart),MPIU_INT,0,tag,comm,&status));
7142dc13f1SHong Zhang   }
7242dc13f1SHong Zhang 
7342dc13f1SHong Zhang   wash->edgelist = edgelist;
7442dc13f1SHong Zhang 
7542dc13f1SHong Zhang   /* (3) all processes get global and local number of vertices, without ghost vertices */
76dd400576SPatrick Sanan   if (rank == 0) {
7742dc13f1SHong Zhang     for (i=0; i<size; i++) {
7842dc13f1SHong Zhang       for (e=eowners[i]; e<eowners[i+1]; e++) {
7942dc13f1SHong Zhang         v = edgelist[2*e];
8042dc13f1SHong Zhang         if (!vtxDone[v]) {
8142dc13f1SHong Zhang           nvtx[i]++; vtxDone[v] = 1;
8242dc13f1SHong Zhang         }
8342dc13f1SHong Zhang         v = edgelist[2*e+1];
8442dc13f1SHong Zhang         if (!vtxDone[v]) {
8542dc13f1SHong Zhang           nvtx[i]++; vtxDone[v] = 1;
8642dc13f1SHong Zhang         }
8742dc13f1SHong Zhang       }
8842dc13f1SHong Zhang     }
8942dc13f1SHong Zhang   }
909566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Bcast(&numVertices,1,MPIU_INT,0,PETSC_COMM_WORLD));
919566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Scatter(nvtx,1,MPIU_INT,&nvertices,1,MPIU_INT,0,PETSC_COMM_WORLD));
929566063dSJacob Faibussowitsch   PetscCall(PetscFree3(eowners,nvtx,vtxDone));
9342dc13f1SHong Zhang 
9442dc13f1SHong Zhang   wash->Nvertex = numVertices;
9542dc13f1SHong Zhang   wash->nvertex = nvertices;
9642dc13f1SHong Zhang   wash->vtype   = vtype;
9742dc13f1SHong Zhang   PetscFunctionReturn(0);
9842dc13f1SHong Zhang }
9942dc13f1SHong Zhang 
10042dc13f1SHong Zhang PetscErrorCode WASHIFunction(TS ts,PetscReal t,Vec X,Vec Xdot,Vec F,void* ctx)
10142dc13f1SHong Zhang {
10242dc13f1SHong Zhang   Wash           wash=(Wash)ctx;
10342dc13f1SHong Zhang   DM             networkdm;
10442dc13f1SHong Zhang   Vec            localX,localXdot,localF, localXold;
10542dc13f1SHong Zhang   const PetscInt *cone;
10642dc13f1SHong Zhang   PetscInt       vfrom,vto,offsetfrom,offsetto,varoffset;
10742dc13f1SHong Zhang   PetscInt       v,vStart,vEnd,e,eStart,eEnd;
10842dc13f1SHong Zhang   PetscInt       nend,type;
10942dc13f1SHong Zhang   PetscBool      ghost;
11042dc13f1SHong Zhang   PetscScalar    *farr,*juncf, *pipef;
11142dc13f1SHong Zhang   PetscReal      dt;
11242dc13f1SHong Zhang   Pipe           pipe;
11342dc13f1SHong Zhang   PipeField      *pipex,*pipexdot,*juncx;
11442dc13f1SHong Zhang   Junction       junction;
11542dc13f1SHong Zhang   DMDALocalInfo  info;
11642dc13f1SHong Zhang   const PetscScalar *xarr,*xdotarr, *xoldarr;
11742dc13f1SHong Zhang 
11842dc13f1SHong Zhang   PetscFunctionBegin;
11942dc13f1SHong Zhang   localX    = wash->localX;
12042dc13f1SHong Zhang   localXdot = wash->localXdot;
12142dc13f1SHong Zhang 
1229566063dSJacob Faibussowitsch   PetscCall(TSGetSolution(ts,&localXold));
1239566063dSJacob Faibussowitsch   PetscCall(TSGetDM(ts,&networkdm));
1249566063dSJacob Faibussowitsch   PetscCall(TSGetTimeStep(ts,&dt));
1259566063dSJacob Faibussowitsch   PetscCall(DMGetLocalVector(networkdm,&localF));
12642dc13f1SHong Zhang 
12742dc13f1SHong Zhang   /* Set F and localF as zero */
1289566063dSJacob Faibussowitsch   PetscCall(VecSet(F,0.0));
1299566063dSJacob Faibussowitsch   PetscCall(VecSet(localF,0.0));
13042dc13f1SHong Zhang 
13142dc13f1SHong Zhang   /* Update ghost values of locaX and locaXdot */
1329566063dSJacob Faibussowitsch   PetscCall(DMGlobalToLocalBegin(networkdm,X,INSERT_VALUES,localX));
1339566063dSJacob Faibussowitsch   PetscCall(DMGlobalToLocalEnd(networkdm,X,INSERT_VALUES,localX));
13442dc13f1SHong Zhang 
1359566063dSJacob Faibussowitsch   PetscCall(DMGlobalToLocalBegin(networkdm,Xdot,INSERT_VALUES,localXdot));
1369566063dSJacob Faibussowitsch   PetscCall(DMGlobalToLocalEnd(networkdm,Xdot,INSERT_VALUES,localXdot));
13742dc13f1SHong Zhang 
1389566063dSJacob Faibussowitsch   PetscCall(VecGetArrayRead(localX,&xarr));
1399566063dSJacob Faibussowitsch   PetscCall(VecGetArrayRead(localXdot,&xdotarr));
1409566063dSJacob Faibussowitsch   PetscCall(VecGetArrayRead(localXold,&xoldarr));
1419566063dSJacob Faibussowitsch   PetscCall(VecGetArray(localF,&farr));
14242dc13f1SHong Zhang 
14342dc13f1SHong Zhang    /* junction->type == JUNCTION:
14442dc13f1SHong Zhang            juncf[0] = -qJ + sum(qin); juncf[1] = qJ - sum(qout)
14542dc13f1SHong Zhang        junction->type == RESERVOIR (upper stream):
14642dc13f1SHong Zhang            juncf[0] = -hJ + H0; juncf[1] = qJ - sum(qout)
14742dc13f1SHong Zhang        junction->type == VALVE (down stream):
14842dc13f1SHong Zhang            juncf[0] =  -qJ + sum(qin); juncf[1] = qJ
14942dc13f1SHong Zhang   */
15042dc13f1SHong Zhang   /* Vertex/junction initialization */
1519566063dSJacob Faibussowitsch   PetscCall(DMNetworkGetVertexRange(networkdm,&vStart,&vEnd));
15242dc13f1SHong Zhang   for (v=vStart; v<vEnd; v++) {
1539566063dSJacob Faibussowitsch     PetscCall(DMNetworkIsGhostVertex(networkdm,v,&ghost));
15442dc13f1SHong Zhang     if (ghost) continue;
15542dc13f1SHong Zhang 
1569566063dSJacob Faibussowitsch     PetscCall(DMNetworkGetComponent(networkdm,v,0,&type,(void**)&junction,NULL));
1579566063dSJacob Faibussowitsch     PetscCall(DMNetworkGetLocalVecOffset(networkdm,v,ALL_COMPONENTS,&varoffset));
15842dc13f1SHong Zhang     juncx      = (PipeField*)(xarr + varoffset);
15942dc13f1SHong Zhang     juncf      = (PetscScalar*)(farr + varoffset);
16042dc13f1SHong Zhang 
16142dc13f1SHong Zhang     juncf[0] = -juncx[0].q;
16242dc13f1SHong Zhang     juncf[1] =  juncx[0].q;
16342dc13f1SHong Zhang 
16442dc13f1SHong Zhang     if (junction->type == RESERVOIR) { /* upstream reservoir */
16542dc13f1SHong Zhang       juncf[0] = juncx[0].h - wash->H0;
16642dc13f1SHong Zhang     }
16742dc13f1SHong Zhang   }
16842dc13f1SHong Zhang 
16942dc13f1SHong Zhang   /* Edge/pipe */
1709566063dSJacob Faibussowitsch   PetscCall(DMNetworkGetEdgeRange(networkdm,&eStart,&eEnd));
17142dc13f1SHong Zhang   for (e=eStart; e<eEnd; e++) {
1729566063dSJacob Faibussowitsch     PetscCall(DMNetworkGetComponent(networkdm,e,0,&type,(void**)&pipe,NULL));
1739566063dSJacob Faibussowitsch     PetscCall(DMNetworkGetLocalVecOffset(networkdm,e,ALL_COMPONENTS,&varoffset));
17442dc13f1SHong Zhang     pipex    = (PipeField*)(xarr + varoffset);
17542dc13f1SHong Zhang     pipexdot = (PipeField*)(xdotarr + varoffset);
17642dc13f1SHong Zhang     pipef    = (PetscScalar*)(farr + varoffset);
17742dc13f1SHong Zhang 
17842dc13f1SHong Zhang     /* Get some data into the pipe structure: note, some of these operations
17942dc13f1SHong Zhang      * might be redundant. Will it consume too much time? */
18042dc13f1SHong Zhang     pipe->dt   = dt;
18142dc13f1SHong Zhang     pipe->xold = (PipeField*)(xoldarr + varoffset);
18242dc13f1SHong Zhang 
18342dc13f1SHong Zhang     /* Evaluate F over this edge/pipe: pipef[1], ...,pipef[2*nend] */
1849566063dSJacob Faibussowitsch     PetscCall(DMDAGetLocalInfo(pipe->da,&info));
1859566063dSJacob Faibussowitsch     PetscCall(PipeIFunctionLocal_Lax(&info,t,pipex,pipexdot,pipef,pipe));
18642dc13f1SHong Zhang 
18742dc13f1SHong Zhang     /* Get boundary values from connected vertices */
1889566063dSJacob Faibussowitsch     PetscCall(DMNetworkGetConnectedVertices(networkdm,e,&cone));
18942dc13f1SHong Zhang     vfrom = cone[0]; /* local ordering */
19042dc13f1SHong Zhang     vto   = cone[1];
1919566063dSJacob Faibussowitsch     PetscCall(DMNetworkGetLocalVecOffset(networkdm,vfrom,ALL_COMPONENTS,&offsetfrom));
1929566063dSJacob Faibussowitsch     PetscCall(DMNetworkGetLocalVecOffset(networkdm,vto,ALL_COMPONENTS,&offsetto));
19342dc13f1SHong Zhang 
19442dc13f1SHong Zhang     /* Evaluate upstream boundary */
1959566063dSJacob Faibussowitsch     PetscCall(DMNetworkGetComponent(networkdm,vfrom,0,&type,(void**)&junction,NULL));
196cad9d221SBarry Smith     PetscCheck(junction->type == JUNCTION || junction->type == RESERVOIR,PETSC_COMM_SELF,PETSC_ERR_SUP,"junction type is not supported");
19742dc13f1SHong Zhang     juncx = (PipeField*)(xarr + offsetfrom);
19842dc13f1SHong Zhang     juncf = (PetscScalar*)(farr + offsetfrom);
19942dc13f1SHong Zhang 
20042dc13f1SHong Zhang     pipef[0] = pipex[0].h - juncx[0].h;
20142dc13f1SHong Zhang     juncf[1] -= pipex[0].q;
20242dc13f1SHong Zhang 
20342dc13f1SHong Zhang     /* Evaluate downstream boundary */
2049566063dSJacob Faibussowitsch     PetscCall(DMNetworkGetComponent(networkdm,vto,0,&type,(void**)&junction,NULL));
205cad9d221SBarry Smith     PetscCheck(junction->type == JUNCTION || junction->type == VALVE,PETSC_COMM_SELF,PETSC_ERR_SUP,"junction type is not supported");
20642dc13f1SHong Zhang     juncx = (PipeField*)(xarr + offsetto);
20742dc13f1SHong Zhang     juncf = (PetscScalar*)(farr + offsetto);
20842dc13f1SHong Zhang     nend  = pipe->nnodes - 1;
20942dc13f1SHong Zhang 
21042dc13f1SHong Zhang     pipef[2*nend + 1] = pipex[nend].h - juncx[0].h;
21142dc13f1SHong Zhang     juncf[0] += pipex[nend].q;
21242dc13f1SHong Zhang   }
21342dc13f1SHong Zhang 
2149566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayRead(localX,&xarr));
2159566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayRead(localXdot,&xdotarr));
2169566063dSJacob Faibussowitsch   PetscCall(VecRestoreArray(localF,&farr));
21742dc13f1SHong Zhang 
2189566063dSJacob Faibussowitsch   PetscCall(DMLocalToGlobalBegin(networkdm,localF,ADD_VALUES,F));
2199566063dSJacob Faibussowitsch   PetscCall(DMLocalToGlobalEnd(networkdm,localF,ADD_VALUES,F));
2209566063dSJacob Faibussowitsch   PetscCall(DMRestoreLocalVector(networkdm,&localF));
22142dc13f1SHong Zhang   /*
2229566063dSJacob Faibussowitsch    PetscCall(PetscPrintf(PETSC_COMM_WORLD("F:\n"));
2239566063dSJacob Faibussowitsch    PetscCall(VecView(F,PETSC_VIEWER_STDOUT_WORLD));
22442dc13f1SHong Zhang    */
22542dc13f1SHong Zhang   PetscFunctionReturn(0);
22642dc13f1SHong Zhang }
22742dc13f1SHong Zhang 
22842dc13f1SHong Zhang PetscErrorCode WASHSetInitialSolution(DM networkdm,Vec X,Wash wash)
22942dc13f1SHong Zhang {
23042dc13f1SHong Zhang   PetscInt       k,nx,vkey,vfrom,vto,offsetfrom,offsetto;
23142dc13f1SHong Zhang   PetscInt       type,varoffset;
23242dc13f1SHong Zhang   PetscInt       e,eStart,eEnd;
23342dc13f1SHong Zhang   Vec            localX;
23442dc13f1SHong Zhang   PetscScalar    *xarr;
23542dc13f1SHong Zhang   Pipe           pipe;
23642dc13f1SHong Zhang   Junction       junction;
23742dc13f1SHong Zhang   const PetscInt *cone;
23842dc13f1SHong Zhang   const PetscScalar *xarray;
23942dc13f1SHong Zhang 
24042dc13f1SHong Zhang   PetscFunctionBegin;
2419566063dSJacob Faibussowitsch   PetscCall(VecSet(X,0.0));
2429566063dSJacob Faibussowitsch   PetscCall(DMGetLocalVector(networkdm,&localX));
2439566063dSJacob Faibussowitsch   PetscCall(VecGetArray(localX,&xarr));
24442dc13f1SHong Zhang 
24542dc13f1SHong Zhang   /* Edge */
2469566063dSJacob Faibussowitsch   PetscCall(DMNetworkGetEdgeRange(networkdm,&eStart,&eEnd));
24742dc13f1SHong Zhang   for (e=eStart; e<eEnd; e++) {
2489566063dSJacob Faibussowitsch     PetscCall(DMNetworkGetLocalVecOffset(networkdm,e,ALL_COMPONENTS,&varoffset));
2499566063dSJacob Faibussowitsch     PetscCall(DMNetworkGetComponent(networkdm,e,0,&type,(void**)&pipe,NULL));
25042dc13f1SHong Zhang 
25142dc13f1SHong Zhang     /* set initial values for this pipe */
2529566063dSJacob Faibussowitsch     PetscCall(PipeComputeSteadyState(pipe,wash->Q0,wash->H0));
2539566063dSJacob Faibussowitsch     PetscCall(VecGetSize(pipe->x,&nx));
25442dc13f1SHong Zhang 
2559566063dSJacob Faibussowitsch     PetscCall(VecGetArrayRead(pipe->x,&xarray));
25642dc13f1SHong Zhang     /* copy pipe->x to xarray */
25742dc13f1SHong Zhang     for (k=0; k<nx; k++) {
25842dc13f1SHong Zhang       (xarr+varoffset)[k] = xarray[k];
25942dc13f1SHong Zhang     }
26042dc13f1SHong Zhang 
26142dc13f1SHong Zhang     /* set boundary values into vfrom and vto */
2629566063dSJacob Faibussowitsch     PetscCall(DMNetworkGetConnectedVertices(networkdm,e,&cone));
26342dc13f1SHong Zhang     vfrom = cone[0]; /* local ordering */
26442dc13f1SHong Zhang     vto   = cone[1];
2659566063dSJacob Faibussowitsch     PetscCall(DMNetworkGetLocalVecOffset(networkdm,vfrom,ALL_COMPONENTS,&offsetfrom));
2669566063dSJacob Faibussowitsch     PetscCall(DMNetworkGetLocalVecOffset(networkdm,vto,ALL_COMPONENTS,&offsetto));
26742dc13f1SHong Zhang 
26842dc13f1SHong Zhang     /* if vform is a head vertex: */
2699566063dSJacob Faibussowitsch     PetscCall(DMNetworkGetComponent(networkdm,vfrom,0,&vkey,(void**)&junction,NULL));
27042dc13f1SHong Zhang     if (junction->type == RESERVOIR) {
27142dc13f1SHong Zhang       (xarr+offsetfrom)[1] = wash->H0; /* 1st H */
27242dc13f1SHong Zhang     }
27342dc13f1SHong Zhang 
27442dc13f1SHong Zhang     /* if vto is an end vertex: */
2759566063dSJacob Faibussowitsch     PetscCall(DMNetworkGetComponent(networkdm,vto,0,&vkey,(void**)&junction,NULL));
27642dc13f1SHong Zhang     if (junction->type == VALVE) {
27742dc13f1SHong Zhang       (xarr+offsetto)[0] = wash->QL; /* last Q */
27842dc13f1SHong Zhang     }
2799566063dSJacob Faibussowitsch     PetscCall(VecRestoreArrayRead(pipe->x,&xarray));
28042dc13f1SHong Zhang   }
28142dc13f1SHong Zhang 
2829566063dSJacob Faibussowitsch   PetscCall(VecRestoreArray(localX,&xarr));
2839566063dSJacob Faibussowitsch   PetscCall(DMLocalToGlobalBegin(networkdm,localX,ADD_VALUES,X));
2849566063dSJacob Faibussowitsch   PetscCall(DMLocalToGlobalEnd(networkdm,localX,ADD_VALUES,X));
2859566063dSJacob Faibussowitsch   PetscCall(DMRestoreLocalVector(networkdm,&localX));
28642dc13f1SHong Zhang 
28742dc13f1SHong Zhang #if 0
28842dc13f1SHong Zhang   PetscInt N;
2899566063dSJacob Faibussowitsch   PetscCall(VecGetSize(X,&N));
2909566063dSJacob Faibussowitsch   PetscCall(PetscPrintf(PETSC_COMM_WORLD,"initial solution %d:\n",N));
2919566063dSJacob Faibussowitsch   PetscCall(VecView(X,PETSC_VIEWER_STDOUT_WORLD));
29242dc13f1SHong Zhang #endif
29342dc13f1SHong Zhang   PetscFunctionReturn(0);
29442dc13f1SHong Zhang }
29542dc13f1SHong Zhang 
29642dc13f1SHong Zhang PetscErrorCode TSDMNetworkMonitor(TS ts, PetscInt step, PetscReal t, Vec x, void *context)
29742dc13f1SHong Zhang {
29842dc13f1SHong Zhang   DMNetworkMonitor   monitor;
29942dc13f1SHong Zhang 
30042dc13f1SHong Zhang   PetscFunctionBegin;
30142dc13f1SHong Zhang   monitor = (DMNetworkMonitor)context;
3029566063dSJacob Faibussowitsch   PetscCall(DMNetworkMonitorView(monitor,x));
30342dc13f1SHong Zhang   PetscFunctionReturn(0);
30442dc13f1SHong Zhang }
30542dc13f1SHong Zhang 
30642dc13f1SHong Zhang PetscErrorCode PipesView(DM networkdm,PetscInt KeyPipe,Vec X)
30742dc13f1SHong Zhang {
30842dc13f1SHong Zhang   PetscInt       i,numkeys=1,*blocksize,*numselectedvariable,**selectedvariables,n;
30942dc13f1SHong Zhang   IS             isfrom_q,isfrom_h,isfrom;
31042dc13f1SHong Zhang   Vec            Xto;
31142dc13f1SHong Zhang   VecScatter     ctx;
31242dc13f1SHong Zhang   MPI_Comm       comm;
31342dc13f1SHong Zhang 
31442dc13f1SHong Zhang   PetscFunctionBegin;
3159566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetComm((PetscObject)networkdm,&comm));
31642dc13f1SHong Zhang 
31742dc13f1SHong Zhang   /* 1. Create isfrom_q for q-variable of pipes */
3189566063dSJacob Faibussowitsch   PetscCall(PetscMalloc3(numkeys,&blocksize,numkeys,&numselectedvariable,numkeys,&selectedvariables));
31942dc13f1SHong Zhang   for (i=0; i<numkeys; i++) {
32042dc13f1SHong Zhang     blocksize[i]           = 2;
32142dc13f1SHong Zhang     numselectedvariable[i] = 1;
3229566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(numselectedvariable[i],&selectedvariables[i]));
32342dc13f1SHong Zhang     selectedvariables[i][0] = 0; /* q-variable */
32442dc13f1SHong Zhang   }
3259566063dSJacob Faibussowitsch   PetscCall(DMNetworkCreateIS(networkdm,numkeys,&KeyPipe,blocksize,numselectedvariable,selectedvariables,&isfrom_q));
32642dc13f1SHong Zhang 
32742dc13f1SHong Zhang   /* 2. Create Xto and isto */
3289566063dSJacob Faibussowitsch   PetscCall(ISGetLocalSize(isfrom_q, &n));
3299566063dSJacob Faibussowitsch   PetscCall(VecCreate(comm,&Xto));
3309566063dSJacob Faibussowitsch   PetscCall(VecSetSizes(Xto,n,PETSC_DECIDE));
3319566063dSJacob Faibussowitsch   PetscCall(VecSetFromOptions(Xto));
3329566063dSJacob Faibussowitsch   PetscCall(VecSet(Xto,0.0));
33342dc13f1SHong Zhang 
33442dc13f1SHong Zhang   /* 3. Create scatter */
3359566063dSJacob Faibussowitsch   PetscCall(VecScatterCreate(X,isfrom_q,Xto,NULL,&ctx));
33642dc13f1SHong Zhang 
33742dc13f1SHong Zhang   /* 4. Scatter to Xq */
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_q));
34242dc13f1SHong Zhang 
3439566063dSJacob Faibussowitsch   PetscCall(PetscPrintf(PETSC_COMM_WORLD,"Xq:\n"));
3449566063dSJacob Faibussowitsch   PetscCall(VecView(Xto,PETSC_VIEWER_STDOUT_WORLD));
34542dc13f1SHong Zhang 
34642dc13f1SHong Zhang   /* 5. Create isfrom_h for h-variable of pipes; Create scatter; Scatter to Xh */
34742dc13f1SHong Zhang   for (i=0; i<numkeys; i++) {
34842dc13f1SHong Zhang     selectedvariables[i][0] = 1; /* h-variable */
34942dc13f1SHong Zhang   }
3509566063dSJacob Faibussowitsch   PetscCall(DMNetworkCreateIS(networkdm,numkeys,&KeyPipe,blocksize,numselectedvariable,selectedvariables,&isfrom_h));
35142dc13f1SHong Zhang 
3529566063dSJacob Faibussowitsch   PetscCall(VecScatterCreate(X,isfrom_h,Xto,NULL,&ctx));
3539566063dSJacob Faibussowitsch   PetscCall(VecScatterBegin(ctx,X,Xto,INSERT_VALUES,SCATTER_FORWARD));
3549566063dSJacob Faibussowitsch   PetscCall(VecScatterEnd(ctx,X,Xto,INSERT_VALUES,SCATTER_FORWARD));
3559566063dSJacob Faibussowitsch   PetscCall(VecScatterDestroy(&ctx));
3569566063dSJacob Faibussowitsch   PetscCall(ISDestroy(&isfrom_h));
35742dc13f1SHong Zhang 
3589566063dSJacob Faibussowitsch   PetscCall(PetscPrintf(PETSC_COMM_WORLD,"Xh:\n"));
3599566063dSJacob Faibussowitsch   PetscCall(VecView(Xto,PETSC_VIEWER_STDOUT_WORLD));
3609566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&Xto));
36142dc13f1SHong Zhang 
36242dc13f1SHong Zhang   /* 6. Create isfrom for all pipe variables; Create scatter; Scatter to Xpipes */
36342dc13f1SHong Zhang   for (i=0; i<numkeys; i++) {
36442dc13f1SHong Zhang     blocksize[i] = -1; /* select all the variables of the i-th component */
36542dc13f1SHong Zhang   }
3669566063dSJacob Faibussowitsch   PetscCall(DMNetworkCreateIS(networkdm,numkeys,&KeyPipe,blocksize,NULL,NULL,&isfrom));
3679566063dSJacob Faibussowitsch   PetscCall(ISDestroy(&isfrom));
3689566063dSJacob Faibussowitsch   PetscCall(DMNetworkCreateIS(networkdm,numkeys,&KeyPipe,NULL,NULL,NULL,&isfrom));
36942dc13f1SHong Zhang 
3709566063dSJacob Faibussowitsch   PetscCall(ISGetLocalSize(isfrom, &n));
3719566063dSJacob Faibussowitsch   PetscCall(VecCreate(comm,&Xto));
3729566063dSJacob Faibussowitsch   PetscCall(VecSetSizes(Xto,n,PETSC_DECIDE));
3739566063dSJacob Faibussowitsch   PetscCall(VecSetFromOptions(Xto));
3749566063dSJacob Faibussowitsch   PetscCall(VecSet(Xto,0.0));
37542dc13f1SHong Zhang 
3769566063dSJacob Faibussowitsch   PetscCall(VecScatterCreate(X,isfrom,Xto,NULL,&ctx));
3779566063dSJacob Faibussowitsch   PetscCall(VecScatterBegin(ctx,X,Xto,INSERT_VALUES,SCATTER_FORWARD));
3789566063dSJacob Faibussowitsch   PetscCall(VecScatterEnd(ctx,X,Xto,INSERT_VALUES,SCATTER_FORWARD));
3799566063dSJacob Faibussowitsch   PetscCall(VecScatterDestroy(&ctx));
3809566063dSJacob Faibussowitsch   PetscCall(ISDestroy(&isfrom));
38142dc13f1SHong Zhang 
3829566063dSJacob Faibussowitsch   PetscCall(PetscPrintf(PETSC_COMM_WORLD,"Xpipes:\n"));
3839566063dSJacob Faibussowitsch   PetscCall(VecView(Xto,PETSC_VIEWER_STDOUT_WORLD));
38442dc13f1SHong Zhang 
38542dc13f1SHong Zhang   /* 7. Free spaces */
38642dc13f1SHong Zhang   for (i=0; i<numkeys; i++) {
3879566063dSJacob Faibussowitsch     PetscCall(PetscFree(selectedvariables[i]));
38842dc13f1SHong Zhang   }
3899566063dSJacob Faibussowitsch   PetscCall(PetscFree3(blocksize,numselectedvariable,selectedvariables));
3909566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&Xto));
39142dc13f1SHong Zhang   PetscFunctionReturn(0);
39242dc13f1SHong Zhang }
39342dc13f1SHong Zhang 
39442dc13f1SHong Zhang PetscErrorCode ISJunctionsView(DM networkdm,PetscInt KeyJunc)
39542dc13f1SHong Zhang {
39642dc13f1SHong Zhang   PetscInt       numkeys=1;
39742dc13f1SHong Zhang   IS             isfrom;
39842dc13f1SHong Zhang   MPI_Comm       comm;
39942dc13f1SHong Zhang   PetscMPIInt    rank;
40042dc13f1SHong Zhang 
40142dc13f1SHong Zhang   PetscFunctionBegin;
4029566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetComm((PetscObject)networkdm,&comm));
4039566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(comm,&rank));
40442dc13f1SHong Zhang 
40542dc13f1SHong Zhang   /* Create a global isfrom for all junction variables */
4069566063dSJacob Faibussowitsch   PetscCall(DMNetworkCreateIS(networkdm,numkeys,&KeyJunc,NULL,NULL,NULL,&isfrom));
4079566063dSJacob Faibussowitsch   PetscCall(PetscPrintf(PETSC_COMM_WORLD,"ISJunctions:\n"));
4089566063dSJacob Faibussowitsch   PetscCall(ISView(isfrom,PETSC_VIEWER_STDOUT_WORLD));
4099566063dSJacob Faibussowitsch   PetscCall(ISDestroy(&isfrom));
41042dc13f1SHong Zhang 
41142dc13f1SHong Zhang   /* Create a local isfrom for all junction variables */
4129566063dSJacob Faibussowitsch   PetscCall(DMNetworkCreateLocalIS(networkdm,numkeys,&KeyJunc,NULL,NULL,NULL,&isfrom));
413*c5853193SPierre Jolivet   if (rank == 0) {
4149566063dSJacob Faibussowitsch     PetscCall(PetscPrintf(PETSC_COMM_SELF,"[%d] ISLocalJunctions:\n",rank));
4159566063dSJacob Faibussowitsch     PetscCall(ISView(isfrom,PETSC_VIEWER_STDOUT_SELF));
41642dc13f1SHong Zhang   }
4179566063dSJacob Faibussowitsch   PetscCall(ISDestroy(&isfrom));
41842dc13f1SHong Zhang   PetscFunctionReturn(0);
41942dc13f1SHong Zhang }
42042dc13f1SHong Zhang 
42142dc13f1SHong Zhang PetscErrorCode WashNetworkCleanUp(Wash wash)
42242dc13f1SHong Zhang {
42342dc13f1SHong Zhang   PetscMPIInt    rank;
42442dc13f1SHong Zhang 
42542dc13f1SHong Zhang   PetscFunctionBegin;
4269566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(wash->comm,&rank));
4279566063dSJacob Faibussowitsch   PetscCall(PetscFree(wash->edgelist));
4289566063dSJacob Faibussowitsch   PetscCall(PetscFree(wash->vtype));
429dd400576SPatrick Sanan   if (rank == 0) {
4309566063dSJacob Faibussowitsch     PetscCall(PetscFree2(wash->junction,wash->pipe));
43142dc13f1SHong Zhang   }
43242dc13f1SHong Zhang   PetscFunctionReturn(0);
43342dc13f1SHong Zhang }
43442dc13f1SHong Zhang 
43542dc13f1SHong Zhang PetscErrorCode WashNetworkCreate(MPI_Comm comm,PetscInt pipesCase,Wash *wash_ptr)
43642dc13f1SHong Zhang {
43742dc13f1SHong Zhang   PetscInt       npipes;
43842dc13f1SHong Zhang   PetscMPIInt    rank;
43942dc13f1SHong Zhang   Wash           wash=NULL;
44042dc13f1SHong Zhang   PetscInt       i,numVertices,numEdges,*vtype;
44142dc13f1SHong Zhang   PetscInt       *edgelist;
44242dc13f1SHong Zhang   Junction       junctions=NULL;
44342dc13f1SHong Zhang   Pipe           pipes=NULL;
44442dc13f1SHong Zhang   PetscBool      washdist=PETSC_TRUE;
44542dc13f1SHong Zhang 
44642dc13f1SHong Zhang   PetscFunctionBegin;
4479566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(comm,&rank));
44842dc13f1SHong Zhang 
4499566063dSJacob Faibussowitsch   PetscCall(PetscCalloc1(1,&wash));
45042dc13f1SHong Zhang   wash->comm = comm;
45142dc13f1SHong Zhang   *wash_ptr  = wash;
45242dc13f1SHong Zhang   wash->Q0   = 0.477432; /* RESERVOIR */
45342dc13f1SHong Zhang   wash->H0   = 150.0;
45442dc13f1SHong Zhang   wash->HL   = 143.488;  /* VALVE */
45542dc13f1SHong Zhang   wash->QL   = 0.0;
45642dc13f1SHong Zhang   wash->nnodes_loc = 0;
45742dc13f1SHong Zhang 
45842dc13f1SHong Zhang   numVertices = 0;
45942dc13f1SHong Zhang   numEdges    = 0;
46042dc13f1SHong Zhang   edgelist    = NULL;
46142dc13f1SHong Zhang 
46242dc13f1SHong Zhang   /* proc[0] creates a sequential wash and edgelist */
46363a3b9bcSJacob Faibussowitsch   PetscCall(PetscPrintf(PETSC_COMM_WORLD,"Setup pipesCase %" PetscInt_FMT "\n",pipesCase));
46442dc13f1SHong Zhang 
46542dc13f1SHong Zhang   /* Set global number of pipes, edges, and junctions */
46642dc13f1SHong Zhang   /*-------------------------------------------------*/
46742dc13f1SHong Zhang   switch (pipesCase) {
46842dc13f1SHong Zhang   case 0:
46942dc13f1SHong Zhang     /* pipeCase 0: */
47042dc13f1SHong Zhang     /* =================================================
47142dc13f1SHong Zhang     (RESERVOIR) v0 --E0--> v1--E1--> v2 --E2-->v3 (VALVE)
47242dc13f1SHong Zhang     ====================================================  */
47342dc13f1SHong Zhang     npipes = 3;
4749566063dSJacob Faibussowitsch     PetscCall(PetscOptionsGetInt(NULL,NULL, "-npipes", &npipes, NULL));
47542dc13f1SHong Zhang     wash->nedge   = npipes;
47642dc13f1SHong Zhang     wash->nvertex = npipes + 1;
47742dc13f1SHong Zhang 
47842dc13f1SHong Zhang     /* Set local edges and vertices -- proc[0] sets entire network, then distributes */
47942dc13f1SHong Zhang     numVertices = 0;
48042dc13f1SHong Zhang     numEdges    = 0;
48142dc13f1SHong Zhang     edgelist    = NULL;
482dd400576SPatrick Sanan     if (rank == 0) {
48342dc13f1SHong Zhang       numVertices = wash->nvertex;
48442dc13f1SHong Zhang       numEdges    = wash->nedge;
48542dc13f1SHong Zhang 
4869566063dSJacob Faibussowitsch       PetscCall(PetscCalloc1(2*numEdges,&edgelist));
48742dc13f1SHong Zhang       for (i=0; i<numEdges; i++) {
48842dc13f1SHong Zhang         edgelist[2*i] = i; edgelist[2*i+1] = i+1;
48942dc13f1SHong Zhang       }
49042dc13f1SHong Zhang 
49142dc13f1SHong Zhang       /* Add network components */
49242dc13f1SHong Zhang       /*------------------------*/
4939566063dSJacob Faibussowitsch       PetscCall(PetscCalloc2(numVertices,&junctions,numEdges,&pipes));
49442dc13f1SHong Zhang 
49542dc13f1SHong Zhang       /* vertex */
49642dc13f1SHong Zhang       for (i=0; i<numVertices; i++) {
49742dc13f1SHong Zhang         junctions[i].id = i;
49842dc13f1SHong Zhang         junctions[i].type = JUNCTION;
49942dc13f1SHong Zhang       }
50042dc13f1SHong Zhang 
50142dc13f1SHong Zhang       junctions[0].type             = RESERVOIR;
50242dc13f1SHong Zhang       junctions[numVertices-1].type = VALVE;
50342dc13f1SHong Zhang     }
50442dc13f1SHong Zhang     break;
50542dc13f1SHong Zhang   case 1:
50642dc13f1SHong Zhang     /* pipeCase 1: */
50742dc13f1SHong Zhang     /* ==========================
50842dc13f1SHong Zhang                 v2 (VALVE)
50942dc13f1SHong Zhang                 ^
51042dc13f1SHong Zhang                 |
51142dc13f1SHong Zhang                E2
51242dc13f1SHong Zhang                 |
51342dc13f1SHong Zhang     v0 --E0--> v3--E1--> v1
51442dc13f1SHong Zhang   (RESERVOIR)            (RESERVOIR)
51542dc13f1SHong Zhang     =============================  */
51642dc13f1SHong Zhang     npipes = 3;
51742dc13f1SHong Zhang     wash->nedge   = npipes;
51842dc13f1SHong Zhang     wash->nvertex = npipes + 1;
51942dc13f1SHong Zhang 
52042dc13f1SHong Zhang     /* Set local edges and vertices -- proc[0] sets entire network, then distributes */
521dd400576SPatrick Sanan     if (rank == 0) {
52242dc13f1SHong Zhang       numVertices = wash->nvertex;
52342dc13f1SHong Zhang       numEdges    = wash->nedge;
52442dc13f1SHong Zhang 
5259566063dSJacob Faibussowitsch       PetscCall(PetscCalloc1(2*numEdges,&edgelist));
52642dc13f1SHong Zhang       edgelist[0] = 0; edgelist[1] = 3;  /* edge[0] */
52742dc13f1SHong Zhang       edgelist[2] = 3; edgelist[3] = 1;  /* edge[1] */
52842dc13f1SHong Zhang       edgelist[4] = 3; edgelist[5] = 2;  /* edge[2] */
52942dc13f1SHong Zhang 
53042dc13f1SHong Zhang       /* Add network components */
53142dc13f1SHong Zhang       /*------------------------*/
5329566063dSJacob Faibussowitsch       PetscCall(PetscCalloc2(numVertices,&junctions,numEdges,&pipes));
53342dc13f1SHong Zhang       /* vertex */
53442dc13f1SHong Zhang       for (i=0; i<numVertices; i++) {
53542dc13f1SHong Zhang         junctions[i].id   = i;
53642dc13f1SHong Zhang         junctions[i].type = JUNCTION;
53742dc13f1SHong Zhang       }
53842dc13f1SHong Zhang 
53942dc13f1SHong Zhang       junctions[0].type = RESERVOIR;
54042dc13f1SHong Zhang       junctions[1].type = VALVE;
54142dc13f1SHong Zhang       junctions[2].type = VALVE;
54242dc13f1SHong Zhang     }
54342dc13f1SHong Zhang     break;
54442dc13f1SHong Zhang   case 2:
54542dc13f1SHong Zhang     /* pipeCase 2: */
54642dc13f1SHong Zhang     /* ==========================
54742dc13f1SHong Zhang     (RESERVOIR)  v2--> E2
54842dc13f1SHong Zhang                        |
54942dc13f1SHong Zhang             v0 --E0--> v3--E1--> v1
55042dc13f1SHong Zhang     (RESERVOIR)               (VALVE)
55142dc13f1SHong Zhang     =============================  */
55242dc13f1SHong Zhang 
55342dc13f1SHong Zhang     /* Set application parameters -- to be used in function evalutions */
55442dc13f1SHong Zhang     npipes = 3;
55542dc13f1SHong Zhang     wash->nedge   = npipes;
55642dc13f1SHong Zhang     wash->nvertex = npipes + 1;
55742dc13f1SHong Zhang 
55842dc13f1SHong Zhang     /* Set local edges and vertices -- proc[0] sets entire network, then distributes */
559dd400576SPatrick Sanan     if (rank == 0) {
56042dc13f1SHong Zhang       numVertices = wash->nvertex;
56142dc13f1SHong Zhang       numEdges    = wash->nedge;
56242dc13f1SHong Zhang 
5639566063dSJacob Faibussowitsch       PetscCall(PetscCalloc1(2*numEdges,&edgelist));
56442dc13f1SHong Zhang       edgelist[0] = 0; edgelist[1] = 3;  /* edge[0] */
56542dc13f1SHong Zhang       edgelist[2] = 3; edgelist[3] = 1;  /* edge[1] */
56642dc13f1SHong Zhang       edgelist[4] = 2; edgelist[5] = 3;  /* edge[2] */
56742dc13f1SHong Zhang 
56842dc13f1SHong Zhang       /* Add network components */
56942dc13f1SHong Zhang       /*------------------------*/
5709566063dSJacob Faibussowitsch       PetscCall(PetscCalloc2(numVertices,&junctions,numEdges,&pipes));
57142dc13f1SHong Zhang       /* vertex */
57242dc13f1SHong Zhang       for (i=0; i<numVertices; i++) {
57342dc13f1SHong Zhang         junctions[i].id = i;
57442dc13f1SHong Zhang         junctions[i].type = JUNCTION;
57542dc13f1SHong Zhang       }
57642dc13f1SHong Zhang 
57742dc13f1SHong Zhang       junctions[0].type = RESERVOIR;
57842dc13f1SHong Zhang       junctions[1].type = VALVE;
57942dc13f1SHong Zhang       junctions[2].type = RESERVOIR;
58042dc13f1SHong Zhang     }
58142dc13f1SHong Zhang     break;
58242dc13f1SHong Zhang   default:
58342dc13f1SHong Zhang     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"not done yet");
58442dc13f1SHong Zhang   }
58542dc13f1SHong Zhang 
58642dc13f1SHong Zhang   /* set edge global id */
58742dc13f1SHong Zhang   for (i=0; i<numEdges; i++) pipes[i].id = i;
58842dc13f1SHong Zhang 
589dd400576SPatrick Sanan   if (rank == 0) { /* set vtype for proc[0] */
59042dc13f1SHong Zhang     PetscInt v;
5919566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(2*numEdges,&vtype));
59242dc13f1SHong Zhang     for (i=0; i<2*numEdges; i++) {
59342dc13f1SHong Zhang       v        = edgelist[i];
59442dc13f1SHong Zhang       vtype[i] = junctions[v].type;
59542dc13f1SHong Zhang     }
59642dc13f1SHong Zhang     wash->vtype = vtype;
59742dc13f1SHong Zhang   }
59842dc13f1SHong Zhang 
59942dc13f1SHong Zhang   *wash_ptr      = wash;
60042dc13f1SHong Zhang   wash->nedge    = numEdges;
60142dc13f1SHong Zhang   wash->nvertex  = numVertices;
60242dc13f1SHong Zhang   wash->edgelist = edgelist;
60342dc13f1SHong Zhang   wash->junction = junctions;
60442dc13f1SHong Zhang   wash->pipe     = pipes;
60542dc13f1SHong Zhang 
60642dc13f1SHong Zhang   /* Distribute edgelist to other processors */
6079566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetBool(NULL,NULL,"-wash_distribute",&washdist,NULL));
60842dc13f1SHong Zhang   if (washdist) {
60942dc13f1SHong Zhang     /*
6109566063dSJacob Faibussowitsch      PetscCall(PetscPrintf(PETSC_COMM_WORLD," Distribute sequential wash ...\n"));
61142dc13f1SHong Zhang      */
6129566063dSJacob Faibussowitsch     PetscCall(WashNetworkDistribute(comm,wash));
61342dc13f1SHong Zhang   }
61442dc13f1SHong Zhang   PetscFunctionReturn(0);
61542dc13f1SHong Zhang }
61642dc13f1SHong Zhang 
61742dc13f1SHong Zhang /* ------------------------------------------------------- */
61842dc13f1SHong Zhang int main(int argc,char ** argv)
61942dc13f1SHong Zhang {
62042dc13f1SHong Zhang   Wash              wash;
62142dc13f1SHong Zhang   Junction          junctions,junction;
62242dc13f1SHong Zhang   Pipe              pipe,pipes;
623f11a936eSBarry Smith   PetscInt          KeyPipe,KeyJunction,*edgelist = NULL,*vtype = NULL;
624f11a936eSBarry Smith   PetscInt          i,e,v,eStart,eEnd,vStart,vEnd,key,vkey,type;
625f11a936eSBarry Smith   PetscInt          steps=1,nedges,nnodes=6;
62642dc13f1SHong Zhang   const PetscInt    *cone;
62742dc13f1SHong Zhang   DM                networkdm;
62842dc13f1SHong Zhang   PetscMPIInt       size,rank;
62942dc13f1SHong Zhang   PetscReal         ftime;
63042dc13f1SHong Zhang   Vec               X;
63142dc13f1SHong Zhang   TS                ts;
63242dc13f1SHong Zhang   TSConvergedReason reason;
63342dc13f1SHong Zhang   PetscBool         viewpipes,viewjuncs,monipipes=PETSC_FALSE,userJac=PETSC_TRUE,viewdm=PETSC_FALSE,viewX=PETSC_FALSE;
63442dc13f1SHong Zhang   PetscInt          pipesCase=0;
63542dc13f1SHong Zhang   DMNetworkMonitor  monitor;
63642dc13f1SHong Zhang   MPI_Comm          comm;
63742dc13f1SHong Zhang 
6389566063dSJacob Faibussowitsch   PetscCall(PetscInitialize(&argc,&argv,"pOption",help));
63942dc13f1SHong Zhang 
64042dc13f1SHong Zhang   /* Read runtime options */
6419566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetInt(NULL,NULL, "-case", &pipesCase, NULL));
6429566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetBool(NULL,NULL,"-user_Jac",&userJac,NULL));
6439566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetBool(NULL,NULL,"-pipe_monitor",&monipipes,NULL));
6449566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetBool(NULL,NULL,"-viewdm",&viewdm,NULL));
6459566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetBool(NULL,NULL,"-viewX",&viewX,NULL));
6469566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetInt(NULL,NULL, "-npipenodes", &nnodes, NULL));
64742dc13f1SHong Zhang 
64842dc13f1SHong Zhang   /* Create networkdm */
64942dc13f1SHong Zhang   /*------------------*/
6509566063dSJacob Faibussowitsch   PetscCall(DMNetworkCreate(PETSC_COMM_WORLD,&networkdm));
6519566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetComm((PetscObject)networkdm,&comm));
6529566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(comm,&rank));
6539566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_size(comm,&size));
65442dc13f1SHong Zhang 
65542dc13f1SHong Zhang   if (size == 1 && monipipes) {
6569566063dSJacob Faibussowitsch     PetscCall(DMNetworkMonitorCreate(networkdm,&monitor));
65742dc13f1SHong Zhang   }
65842dc13f1SHong Zhang 
65942dc13f1SHong Zhang   /* Register the components in the network */
6609566063dSJacob Faibussowitsch   PetscCall(DMNetworkRegisterComponent(networkdm,"junctionstruct",sizeof(struct _p_Junction),&KeyJunction));
6619566063dSJacob Faibussowitsch   PetscCall(DMNetworkRegisterComponent(networkdm,"pipestruct",sizeof(struct _p_Pipe),&KeyPipe));
66242dc13f1SHong Zhang 
66342dc13f1SHong Zhang   /* Create a distributed wash network (user-specific) */
6649566063dSJacob Faibussowitsch   PetscCall(WashNetworkCreate(comm,pipesCase,&wash));
66542dc13f1SHong Zhang   nedges      = wash->nedge;
66642dc13f1SHong Zhang   edgelist    = wash->edgelist;
66742dc13f1SHong Zhang   vtype       = wash->vtype;
66842dc13f1SHong Zhang   junctions   = wash->junction;
66942dc13f1SHong Zhang   pipes       = wash->pipe;
67042dc13f1SHong Zhang 
67142dc13f1SHong Zhang   /* Set up the network layout */
6729566063dSJacob Faibussowitsch   PetscCall(DMNetworkSetNumSubNetworks(networkdm,PETSC_DECIDE,1));
6739566063dSJacob Faibussowitsch   PetscCall(DMNetworkAddSubnetwork(networkdm,NULL,nedges,edgelist,NULL));
67442dc13f1SHong Zhang 
6759566063dSJacob Faibussowitsch   PetscCall(DMNetworkLayoutSetUp(networkdm));
67642dc13f1SHong Zhang 
6779566063dSJacob Faibussowitsch   PetscCall(DMNetworkGetEdgeRange(networkdm,&eStart,&eEnd));
6789566063dSJacob Faibussowitsch   PetscCall(DMNetworkGetVertexRange(networkdm,&vStart,&vEnd));
6799566063dSJacob Faibussowitsch   /* PetscCall(PetscPrintf(PETSC_COMM_SELF,"[%d] eStart/End: %d - %d; vStart/End: %d - %d\n",rank,eStart,eEnd,vStart,vEnd)); */
68042dc13f1SHong Zhang 
68142dc13f1SHong Zhang   if (rank) { /* junctions[] and pipes[] for proc[0] are allocated in WashNetworkCreate() */
68242dc13f1SHong Zhang     /* vEnd - vStart = nvertices + number of ghost vertices! */
6839566063dSJacob Faibussowitsch     PetscCall(PetscCalloc2(vEnd - vStart,&junctions,nedges,&pipes));
68442dc13f1SHong Zhang   }
68542dc13f1SHong Zhang 
68642dc13f1SHong Zhang   /* Add Pipe component and number of variables to all local edges */
68742dc13f1SHong Zhang   for (e = eStart; e < eEnd; e++) {
68842dc13f1SHong Zhang     pipes[e-eStart].nnodes = nnodes;
6899566063dSJacob Faibussowitsch     PetscCall(DMNetworkAddComponent(networkdm,e,KeyPipe,&pipes[e-eStart],2*pipes[e-eStart].nnodes));
69042dc13f1SHong Zhang 
69142dc13f1SHong Zhang     if (size == 1 && monipipes) { /* Add monitor -- show Q_{pipes[e-eStart].id}? */
69242dc13f1SHong Zhang       pipes[e-eStart].length = 600.0;
6939566063dSJacob 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));
6949566063dSJacob 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));
69542dc13f1SHong Zhang     }
69642dc13f1SHong Zhang   }
69742dc13f1SHong Zhang 
698eac198afSGetnet   /* Add Junction component and number of variables to all local vertices */
69942dc13f1SHong Zhang   for (v = vStart; v < vEnd; v++) {
7009566063dSJacob Faibussowitsch     PetscCall(DMNetworkAddComponent(networkdm,v,KeyJunction,&junctions[v-vStart],2));
70142dc13f1SHong Zhang   }
70242dc13f1SHong Zhang 
70342dc13f1SHong Zhang   if (size > 1) {  /* must be called before DMSetUp()???. Other partitioners do not work yet??? -- cause crash in proc[0]! */
70442dc13f1SHong Zhang     DM               plexdm;
70542dc13f1SHong Zhang     PetscPartitioner part;
7069566063dSJacob Faibussowitsch     PetscCall(DMNetworkGetPlex(networkdm,&plexdm));
7079566063dSJacob Faibussowitsch     PetscCall(DMPlexGetPartitioner(plexdm, &part));
7089566063dSJacob Faibussowitsch     PetscCall(PetscPartitionerSetType(part,PETSCPARTITIONERSIMPLE));
7099566063dSJacob Faibussowitsch     PetscCall(PetscOptionsSetValue(NULL,"-dm_plex_csr_alg","mat")); /* for parmetis */
71042dc13f1SHong Zhang   }
71142dc13f1SHong Zhang 
71242dc13f1SHong Zhang   /* Set up DM for use */
7139566063dSJacob Faibussowitsch   PetscCall(DMSetUp(networkdm));
71442dc13f1SHong Zhang   if (viewdm) {
7159566063dSJacob Faibussowitsch     PetscCall(PetscPrintf(PETSC_COMM_WORLD,"\nOriginal networkdm, DMView:\n"));
7169566063dSJacob Faibussowitsch     PetscCall(DMView(networkdm,PETSC_VIEWER_STDOUT_WORLD));
71742dc13f1SHong Zhang   }
71842dc13f1SHong Zhang 
71942dc13f1SHong Zhang   /* Set user physical parameters to the components */
72042dc13f1SHong Zhang   for (e = eStart; e < eEnd; e++) {
7219566063dSJacob Faibussowitsch     PetscCall(DMNetworkGetConnectedVertices(networkdm,e,&cone));
72242dc13f1SHong Zhang     /* vfrom */
7239566063dSJacob Faibussowitsch     PetscCall(DMNetworkGetComponent(networkdm,cone[0],0,&vkey,(void**)&junction,NULL));
72442dc13f1SHong Zhang     junction->type = (VertexType)vtype[2*e];
72542dc13f1SHong Zhang 
72642dc13f1SHong Zhang     /* vto */
7279566063dSJacob Faibussowitsch     PetscCall(DMNetworkGetComponent(networkdm,cone[1],0,&vkey,(void**)&junction,NULL));
72842dc13f1SHong Zhang     junction->type = (VertexType)vtype[2*e+1];
72942dc13f1SHong Zhang   }
73042dc13f1SHong Zhang 
7319566063dSJacob Faibussowitsch   PetscCall(WashNetworkCleanUp(wash));
73242dc13f1SHong Zhang 
73342dc13f1SHong Zhang   /* Network partitioning and distribution of data */
7349566063dSJacob Faibussowitsch   PetscCall(DMNetworkDistribute(&networkdm,0));
73542dc13f1SHong Zhang   if (viewdm) {
7369566063dSJacob Faibussowitsch     PetscCall(PetscPrintf(PETSC_COMM_WORLD,"\nAfter DMNetworkDistribute, DMView:\n"));
7379566063dSJacob Faibussowitsch     PetscCall(DMView(networkdm,PETSC_VIEWER_STDOUT_WORLD));
73842dc13f1SHong Zhang   }
73942dc13f1SHong Zhang 
74042dc13f1SHong Zhang   /* create vectors */
7419566063dSJacob Faibussowitsch   PetscCall(DMCreateGlobalVector(networkdm,&X));
7429566063dSJacob Faibussowitsch   PetscCall(DMCreateLocalVector(networkdm,&wash->localX));
7439566063dSJacob Faibussowitsch   PetscCall(DMCreateLocalVector(networkdm,&wash->localXdot));
74442dc13f1SHong Zhang 
74542dc13f1SHong Zhang   /* PipeSetUp -- each process only sets its own pipes */
74642dc13f1SHong Zhang   /*---------------------------------------------------*/
7479566063dSJacob Faibussowitsch   PetscCall(DMNetworkGetVertexRange(networkdm,&vStart,&vEnd));
74842dc13f1SHong Zhang 
74942dc13f1SHong Zhang   userJac = PETSC_TRUE;
7509566063dSJacob Faibussowitsch   PetscCall(DMNetworkHasJacobian(networkdm,userJac,userJac));
7519566063dSJacob Faibussowitsch   PetscCall(DMNetworkGetEdgeRange(networkdm,&eStart,&eEnd));
75242dc13f1SHong Zhang   for (e=eStart; e<eEnd; e++) { /* each edge has only one component, pipe */
7539566063dSJacob Faibussowitsch     PetscCall(DMNetworkGetComponent(networkdm,e,0,&type,(void**)&pipe,NULL));
75442dc13f1SHong Zhang 
75542dc13f1SHong Zhang     wash->nnodes_loc += pipe->nnodes; /* local total number of nodes, will be used by PipesView() */
7569566063dSJacob Faibussowitsch     PetscCall(PipeSetParameters(pipe,
75742dc13f1SHong Zhang                               600.0,   /* length   */
75842dc13f1SHong Zhang                               0.5,     /* diameter */
75942dc13f1SHong Zhang                               1200.0,  /* a        */
760b122ec5aSJacob Faibussowitsch                               0.018)); /* friction */
7619566063dSJacob Faibussowitsch     PetscCall(PipeSetUp(pipe));
76242dc13f1SHong Zhang 
76342dc13f1SHong Zhang     if (userJac) {
76442dc13f1SHong Zhang       /* Create Jacobian matrix structures for a Pipe */
76542dc13f1SHong Zhang       Mat            *J;
7669566063dSJacob Faibussowitsch       PetscCall(PipeCreateJacobian(pipe,NULL,&J));
7679566063dSJacob Faibussowitsch       PetscCall(DMNetworkEdgeSetMatrix(networkdm,e,J));
76842dc13f1SHong Zhang     }
76942dc13f1SHong Zhang   }
77042dc13f1SHong Zhang 
77142dc13f1SHong Zhang   if (userJac) {
7729566063dSJacob Faibussowitsch     PetscCall(DMNetworkGetVertexRange(networkdm,&vStart,&vEnd));
77342dc13f1SHong Zhang     for (v=vStart; v<vEnd; v++) {
77442dc13f1SHong Zhang       Mat            *J;
7759566063dSJacob Faibussowitsch       PetscCall(JunctionCreateJacobian(networkdm,v,NULL,&J));
7769566063dSJacob Faibussowitsch       PetscCall(DMNetworkVertexSetMatrix(networkdm,v,J));
77742dc13f1SHong Zhang 
7789566063dSJacob Faibussowitsch       PetscCall(DMNetworkGetComponent(networkdm,v,0,&vkey,(void**)&junction,NULL));
77942dc13f1SHong Zhang       junction->jacobian = J;
78042dc13f1SHong Zhang     }
78142dc13f1SHong Zhang   }
78242dc13f1SHong Zhang 
78342dc13f1SHong Zhang   /* Setup solver                                           */
78442dc13f1SHong Zhang   /*--------------------------------------------------------*/
7859566063dSJacob Faibussowitsch   PetscCall(TSCreate(PETSC_COMM_WORLD,&ts));
78642dc13f1SHong Zhang 
7879566063dSJacob Faibussowitsch   PetscCall(TSSetDM(ts,(DM)networkdm));
7889566063dSJacob Faibussowitsch   PetscCall(TSSetIFunction(ts,NULL,WASHIFunction,wash));
78942dc13f1SHong Zhang 
7909566063dSJacob Faibussowitsch   PetscCall(TSSetMaxSteps(ts,steps));
7919566063dSJacob Faibussowitsch   PetscCall(TSSetExactFinalTime(ts,TS_EXACTFINALTIME_STEPOVER));
7929566063dSJacob Faibussowitsch   PetscCall(TSSetTimeStep(ts,0.1));
7939566063dSJacob Faibussowitsch   PetscCall(TSSetType(ts,TSBEULER));
7949566063dSJacob Faibussowitsch   if (size == 1 && monipipes) PetscCall(TSMonitorSet(ts, TSDMNetworkMonitor, monitor, NULL));
7959566063dSJacob Faibussowitsch   PetscCall(TSSetFromOptions(ts));
79642dc13f1SHong Zhang 
7979566063dSJacob Faibussowitsch   PetscCall(WASHSetInitialSolution(networkdm,X,wash));
79842dc13f1SHong Zhang 
7999566063dSJacob Faibussowitsch   PetscCall(TSSolve(ts,X));
80042dc13f1SHong Zhang 
8019566063dSJacob Faibussowitsch   PetscCall(TSGetSolveTime(ts,&ftime));
8029566063dSJacob Faibussowitsch   PetscCall(TSGetStepNumber(ts,&steps));
8039566063dSJacob Faibussowitsch   PetscCall(TSGetConvergedReason(ts,&reason));
80463a3b9bcSJacob Faibussowitsch   PetscCall(PetscPrintf(PETSC_COMM_WORLD,"%s at time %g after %" PetscInt_FMT " steps\n",TSConvergedReasons[reason],(double)ftime,steps));
80542dc13f1SHong Zhang   if (viewX) {
8069566063dSJacob Faibussowitsch     PetscCall(VecView(X,PETSC_VIEWER_STDOUT_WORLD));
80742dc13f1SHong Zhang   }
80842dc13f1SHong Zhang 
80942dc13f1SHong Zhang   viewpipes = PETSC_FALSE;
8109566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetBool(NULL,NULL, "-Jac_view", &viewpipes,NULL));
81142dc13f1SHong Zhang   if (viewpipes) {
81242dc13f1SHong Zhang     SNES snes;
81342dc13f1SHong Zhang     Mat  Jac;
8149566063dSJacob Faibussowitsch     PetscCall(TSGetSNES(ts,&snes));
8159566063dSJacob Faibussowitsch     PetscCall(SNESGetJacobian(snes,&Jac,NULL,NULL,NULL));
8169566063dSJacob Faibussowitsch     PetscCall(MatView(Jac,PETSC_VIEWER_DRAW_WORLD));
81742dc13f1SHong Zhang   }
81842dc13f1SHong Zhang 
81942dc13f1SHong Zhang   /* View solutions */
82042dc13f1SHong Zhang   /* -------------- */
82142dc13f1SHong Zhang   viewpipes = PETSC_FALSE;
8229566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetBool(NULL,NULL, "-pipe_view", &viewpipes,NULL));
82342dc13f1SHong Zhang   if (viewpipes) {
8249566063dSJacob Faibussowitsch     PetscCall(PipesView(networkdm,KeyPipe,X));
82542dc13f1SHong Zhang   }
82642dc13f1SHong Zhang 
82742dc13f1SHong Zhang   /* Test IS */
82842dc13f1SHong Zhang   viewjuncs = PETSC_FALSE;
8299566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetBool(NULL,NULL, "-isjunc_view", &viewjuncs,NULL));
83042dc13f1SHong Zhang   if (viewjuncs) {
8319566063dSJacob Faibussowitsch     PetscCall(ISJunctionsView(networkdm,KeyJunction));
83242dc13f1SHong Zhang   }
83342dc13f1SHong Zhang 
83442dc13f1SHong Zhang   /* Free spaces */
83542dc13f1SHong Zhang   /* ----------- */
8369566063dSJacob Faibussowitsch   PetscCall(TSDestroy(&ts));
8379566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&X));
8389566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&wash->localX));
8399566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&wash->localXdot));
84042dc13f1SHong Zhang 
84142dc13f1SHong Zhang   /* Destroy objects from each pipe that are created in PipeSetUp() */
8429566063dSJacob Faibussowitsch   PetscCall(DMNetworkGetEdgeRange(networkdm,&eStart, &eEnd));
84342dc13f1SHong Zhang   for (i = eStart; i < eEnd; i++) {
8449566063dSJacob Faibussowitsch     PetscCall(DMNetworkGetComponent(networkdm,i,0,&key,(void**)&pipe,NULL));
8459566063dSJacob Faibussowitsch     PetscCall(PipeDestroy(&pipe));
84642dc13f1SHong Zhang   }
84742dc13f1SHong Zhang   if (userJac) {
84842dc13f1SHong Zhang     for (v=vStart; v<vEnd; v++) {
8499566063dSJacob Faibussowitsch       PetscCall(DMNetworkGetComponent(networkdm,v,0,&vkey,(void**)&junction,NULL));
8509566063dSJacob Faibussowitsch       PetscCall(JunctionDestroyJacobian(networkdm,v,junction));
85142dc13f1SHong Zhang     }
85242dc13f1SHong Zhang   }
85342dc13f1SHong Zhang 
85442dc13f1SHong Zhang   if (size == 1 && monipipes) {
8559566063dSJacob Faibussowitsch     PetscCall(DMNetworkMonitorDestroy(&monitor));
85642dc13f1SHong Zhang   }
8579566063dSJacob Faibussowitsch   PetscCall(DMDestroy(&networkdm));
8589566063dSJacob Faibussowitsch   PetscCall(PetscFree(wash));
85942dc13f1SHong Zhang 
86042dc13f1SHong Zhang   if (rank) {
8619566063dSJacob Faibussowitsch     PetscCall(PetscFree2(junctions,pipes));
86242dc13f1SHong Zhang   }
8639566063dSJacob Faibussowitsch   PetscCall(PetscFinalize());
864b122ec5aSJacob Faibussowitsch   return 0;
86542dc13f1SHong Zhang }
86642dc13f1SHong Zhang 
86742dc13f1SHong Zhang /*TEST
86842dc13f1SHong Zhang 
86942dc13f1SHong Zhang    build:
87042dc13f1SHong Zhang      depends: pipeInterface.c pipeImpls.c
87142dc13f1SHong Zhang      requires: mumps
87242dc13f1SHong Zhang 
87342dc13f1SHong Zhang    test:
87442dc13f1SHong Zhang       args: -ts_monitor -case 1 -ts_max_steps 1 -pc_factor_mat_solver_type mumps -options_left no -viewX
87542dc13f1SHong Zhang       localrunfiles: pOption
87642dc13f1SHong Zhang       output_file: output/pipes_1.out
87742dc13f1SHong Zhang 
87842dc13f1SHong Zhang    test:
87942dc13f1SHong Zhang       suffix: 2
88042dc13f1SHong Zhang       nsize: 2
88142dc13f1SHong Zhang       args: -ts_monitor -case 1 -ts_max_steps 1 -pc_factor_mat_solver_type mumps -petscpartitioner_type simple -options_left no -viewX
88242dc13f1SHong Zhang       localrunfiles: pOption
88342dc13f1SHong Zhang       output_file: output/pipes_2.out
88442dc13f1SHong Zhang 
88542dc13f1SHong Zhang    test:
88642dc13f1SHong Zhang       suffix: 3
88742dc13f1SHong Zhang       nsize: 2
88842dc13f1SHong Zhang       args: -ts_monitor -case 0 -ts_max_steps 1 -pc_factor_mat_solver_type mumps -petscpartitioner_type simple -options_left no -viewX
88942dc13f1SHong Zhang       localrunfiles: pOption
89042dc13f1SHong Zhang       output_file: output/pipes_3.out
89142dc13f1SHong Zhang 
89242dc13f1SHong Zhang    test:
89342dc13f1SHong Zhang       suffix: 4
89442dc13f1SHong Zhang       args: -ts_monitor -case 2 -ts_max_steps 1 -pc_factor_mat_solver_type mumps -options_left no -viewX
89542dc13f1SHong Zhang       localrunfiles: pOption
89642dc13f1SHong Zhang       output_file: output/pipes_4.out
89742dc13f1SHong Zhang 
89842dc13f1SHong Zhang    test:
89942dc13f1SHong Zhang       suffix: 5
90042dc13f1SHong Zhang       nsize: 3
90142dc13f1SHong Zhang       args: -ts_monitor -case 2 -ts_max_steps 10 -pc_factor_mat_solver_type mumps -petscpartitioner_type simple -options_left no -viewX
90242dc13f1SHong Zhang       localrunfiles: pOption
90342dc13f1SHong Zhang       output_file: output/pipes_5.out
90442dc13f1SHong Zhang 
90542dc13f1SHong Zhang    test:
90642dc13f1SHong Zhang       suffix: 6
90742dc13f1SHong Zhang       nsize: 2
90842dc13f1SHong 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
90942dc13f1SHong Zhang       localrunfiles: pOption
91042dc13f1SHong Zhang       output_file: output/pipes_6.out
91142dc13f1SHong Zhang 
91242dc13f1SHong Zhang    test:
91342dc13f1SHong Zhang       suffix: 7
91442dc13f1SHong Zhang       nsize: 2
91542dc13f1SHong 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
91642dc13f1SHong Zhang       localrunfiles: pOption
91742dc13f1SHong Zhang       output_file: output/pipes_7.out
91842dc13f1SHong Zhang 
91942dc13f1SHong Zhang    test:
92042dc13f1SHong Zhang       suffix: 8
92142dc13f1SHong Zhang       nsize: 2
92242dc13f1SHong Zhang       requires: parmetis
92342dc13f1SHong 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
92442dc13f1SHong Zhang       localrunfiles: pOption
92542dc13f1SHong Zhang       output_file: output/pipes_8.out
92642dc13f1SHong Zhang 
92742dc13f1SHong Zhang    test:
92842dc13f1SHong Zhang       suffix: 9
92942dc13f1SHong Zhang       nsize: 2
93042dc13f1SHong 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
93142dc13f1SHong Zhang       localrunfiles: pOption
93242dc13f1SHong Zhang       output_file: output/pipes_9.out
93342dc13f1SHong Zhang 
93442dc13f1SHong Zhang    test:
93542dc13f1SHong Zhang       suffix: 10
93642dc13f1SHong Zhang       nsize: 2
93742dc13f1SHong 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
93842dc13f1SHong Zhang       localrunfiles: pOption
93942dc13f1SHong Zhang       output_file: output/pipes_10.out
94042dc13f1SHong Zhang 
94142dc13f1SHong Zhang TEST*/
942