xref: /petsc/src/ts/tutorials/network/pipes.c (revision b122ec5aa1bd4469eb4e0673542fb7de3f411254)
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;
265f80ce2aSJacob Faibussowitsch   CHKERRMPI(MPI_Comm_size(comm,&size));
2742dc13f1SHong Zhang   if (size == 1) PetscFunctionReturn(0);
2842dc13f1SHong Zhang 
295f80ce2aSJacob Faibussowitsch   CHKERRMPI(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 */
345f80ce2aSJacob Faibussowitsch   CHKERRMPI(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;
415f80ce2aSJacob Faibussowitsch   /* CHKERRQ(PetscPrintf(PETSC_COMM_SELF,"[%d] nedges %d, numEdges %d\n",rank,nedges,numEdges)); */
4242dc13f1SHong Zhang 
435f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscCalloc3(size+1,&eowners,size,&nvtx,numVertices,&vtxDone));
445f80ce2aSJacob Faibussowitsch   CHKERRMPI(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];
525f80ce2aSJacob Faibussowitsch   /* CHKERRQ(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] */
595f80ce2aSJacob Faibussowitsch       CHKERRMPI(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] */
625f80ce2aSJacob Faibussowitsch       CHKERRMPI(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;
665f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscMalloc1(2*(eend-estart),&vtype));
675f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscMalloc1(2*(eend-estart),&edgelist));
6842dc13f1SHong Zhang 
695f80ce2aSJacob Faibussowitsch     CHKERRMPI(MPI_Recv(edgelist,2*(eend-estart),MPIU_INT,0,tag,comm,&status));
705f80ce2aSJacob Faibussowitsch     CHKERRMPI(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   }
905f80ce2aSJacob Faibussowitsch   CHKERRMPI(MPI_Bcast(&numVertices,1,MPIU_INT,0,PETSC_COMM_WORLD));
915f80ce2aSJacob Faibussowitsch   CHKERRMPI(MPI_Scatter(nvtx,1,MPIU_INT,&nvertices,1,MPIU_INT,0,PETSC_COMM_WORLD));
925f80ce2aSJacob Faibussowitsch   CHKERRQ(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 
1225f80ce2aSJacob Faibussowitsch   CHKERRQ(TSGetSolution(ts,&localXold));
1235f80ce2aSJacob Faibussowitsch   CHKERRQ(TSGetDM(ts,&networkdm));
1245f80ce2aSJacob Faibussowitsch   CHKERRQ(TSGetTimeStep(ts,&dt));
1255f80ce2aSJacob Faibussowitsch   CHKERRQ(DMGetLocalVector(networkdm,&localF));
12642dc13f1SHong Zhang 
12742dc13f1SHong Zhang   /* Set F and localF as zero */
1285f80ce2aSJacob Faibussowitsch   CHKERRQ(VecSet(F,0.0));
1295f80ce2aSJacob Faibussowitsch   CHKERRQ(VecSet(localF,0.0));
13042dc13f1SHong Zhang 
13142dc13f1SHong Zhang   /* Update ghost values of locaX and locaXdot */
1325f80ce2aSJacob Faibussowitsch   CHKERRQ(DMGlobalToLocalBegin(networkdm,X,INSERT_VALUES,localX));
1335f80ce2aSJacob Faibussowitsch   CHKERRQ(DMGlobalToLocalEnd(networkdm,X,INSERT_VALUES,localX));
13442dc13f1SHong Zhang 
1355f80ce2aSJacob Faibussowitsch   CHKERRQ(DMGlobalToLocalBegin(networkdm,Xdot,INSERT_VALUES,localXdot));
1365f80ce2aSJacob Faibussowitsch   CHKERRQ(DMGlobalToLocalEnd(networkdm,Xdot,INSERT_VALUES,localXdot));
13742dc13f1SHong Zhang 
1385f80ce2aSJacob Faibussowitsch   CHKERRQ(VecGetArrayRead(localX,&xarr));
1395f80ce2aSJacob Faibussowitsch   CHKERRQ(VecGetArrayRead(localXdot,&xdotarr));
1405f80ce2aSJacob Faibussowitsch   CHKERRQ(VecGetArrayRead(localXold,&xoldarr));
1415f80ce2aSJacob Faibussowitsch   CHKERRQ(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 */
1515f80ce2aSJacob Faibussowitsch   CHKERRQ(DMNetworkGetVertexRange(networkdm,&vStart,&vEnd));
15242dc13f1SHong Zhang   for (v=vStart; v<vEnd; v++) {
1535f80ce2aSJacob Faibussowitsch     CHKERRQ(DMNetworkIsGhostVertex(networkdm,v,&ghost));
15442dc13f1SHong Zhang     if (ghost) continue;
15542dc13f1SHong Zhang 
1565f80ce2aSJacob Faibussowitsch     CHKERRQ(DMNetworkGetComponent(networkdm,v,0,&type,(void**)&junction,NULL));
1575f80ce2aSJacob Faibussowitsch     CHKERRQ(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 */
1705f80ce2aSJacob Faibussowitsch   CHKERRQ(DMNetworkGetEdgeRange(networkdm,&eStart,&eEnd));
17142dc13f1SHong Zhang   for (e=eStart; e<eEnd; e++) {
1725f80ce2aSJacob Faibussowitsch     CHKERRQ(DMNetworkGetComponent(networkdm,e,0,&type,(void**)&pipe,NULL));
1735f80ce2aSJacob Faibussowitsch     CHKERRQ(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] */
1845f80ce2aSJacob Faibussowitsch     CHKERRQ(DMDAGetLocalInfo(pipe->da,&info));
1855f80ce2aSJacob Faibussowitsch     CHKERRQ(PipeIFunctionLocal_Lax(&info,t,pipex,pipexdot,pipef,pipe));
18642dc13f1SHong Zhang 
18742dc13f1SHong Zhang     /* Get boundary values from connected vertices */
1885f80ce2aSJacob Faibussowitsch     CHKERRQ(DMNetworkGetConnectedVertices(networkdm,e,&cone));
18942dc13f1SHong Zhang     vfrom = cone[0]; /* local ordering */
19042dc13f1SHong Zhang     vto   = cone[1];
1915f80ce2aSJacob Faibussowitsch     CHKERRQ(DMNetworkGetLocalVecOffset(networkdm,vfrom,ALL_COMPONENTS,&offsetfrom));
1925f80ce2aSJacob Faibussowitsch     CHKERRQ(DMNetworkGetLocalVecOffset(networkdm,vto,ALL_COMPONENTS,&offsetto));
19342dc13f1SHong Zhang 
19442dc13f1SHong Zhang     /* Evaluate upstream boundary */
1955f80ce2aSJacob Faibussowitsch     CHKERRQ(DMNetworkGetComponent(networkdm,vfrom,0,&type,(void**)&junction,NULL));
1962c71b3e2SJacob Faibussowitsch     PetscCheckFalse(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 */
2045f80ce2aSJacob Faibussowitsch     CHKERRQ(DMNetworkGetComponent(networkdm,vto,0,&type,(void**)&junction,NULL));
2052c71b3e2SJacob Faibussowitsch     PetscCheckFalse(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 
2145f80ce2aSJacob Faibussowitsch   CHKERRQ(VecRestoreArrayRead(localX,&xarr));
2155f80ce2aSJacob Faibussowitsch   CHKERRQ(VecRestoreArrayRead(localXdot,&xdotarr));
2165f80ce2aSJacob Faibussowitsch   CHKERRQ(VecRestoreArray(localF,&farr));
21742dc13f1SHong Zhang 
2185f80ce2aSJacob Faibussowitsch   CHKERRQ(DMLocalToGlobalBegin(networkdm,localF,ADD_VALUES,F));
2195f80ce2aSJacob Faibussowitsch   CHKERRQ(DMLocalToGlobalEnd(networkdm,localF,ADD_VALUES,F));
2205f80ce2aSJacob Faibussowitsch   CHKERRQ(DMRestoreLocalVector(networkdm,&localF));
22142dc13f1SHong Zhang   /*
2225f80ce2aSJacob Faibussowitsch    CHKERRQ(PetscPrintf(PETSC_COMM_WORLD("F:\n"));
2235f80ce2aSJacob Faibussowitsch    CHKERRQ(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;
2415f80ce2aSJacob Faibussowitsch   CHKERRQ(VecSet(X,0.0));
2425f80ce2aSJacob Faibussowitsch   CHKERRQ(DMGetLocalVector(networkdm,&localX));
2435f80ce2aSJacob Faibussowitsch   CHKERRQ(VecGetArray(localX,&xarr));
24442dc13f1SHong Zhang 
24542dc13f1SHong Zhang   /* Edge */
2465f80ce2aSJacob Faibussowitsch   CHKERRQ(DMNetworkGetEdgeRange(networkdm,&eStart,&eEnd));
24742dc13f1SHong Zhang   for (e=eStart; e<eEnd; e++) {
2485f80ce2aSJacob Faibussowitsch     CHKERRQ(DMNetworkGetLocalVecOffset(networkdm,e,ALL_COMPONENTS,&varoffset));
2495f80ce2aSJacob Faibussowitsch     CHKERRQ(DMNetworkGetComponent(networkdm,e,0,&type,(void**)&pipe,NULL));
25042dc13f1SHong Zhang 
25142dc13f1SHong Zhang     /* set initial values for this pipe */
2525f80ce2aSJacob Faibussowitsch     CHKERRQ(PipeComputeSteadyState(pipe,wash->Q0,wash->H0));
2535f80ce2aSJacob Faibussowitsch     CHKERRQ(VecGetSize(pipe->x,&nx));
25442dc13f1SHong Zhang 
2555f80ce2aSJacob Faibussowitsch     CHKERRQ(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 */
2625f80ce2aSJacob Faibussowitsch     CHKERRQ(DMNetworkGetConnectedVertices(networkdm,e,&cone));
26342dc13f1SHong Zhang     vfrom = cone[0]; /* local ordering */
26442dc13f1SHong Zhang     vto   = cone[1];
2655f80ce2aSJacob Faibussowitsch     CHKERRQ(DMNetworkGetLocalVecOffset(networkdm,vfrom,ALL_COMPONENTS,&offsetfrom));
2665f80ce2aSJacob Faibussowitsch     CHKERRQ(DMNetworkGetLocalVecOffset(networkdm,vto,ALL_COMPONENTS,&offsetto));
26742dc13f1SHong Zhang 
26842dc13f1SHong Zhang     /* if vform is a head vertex: */
2695f80ce2aSJacob Faibussowitsch     CHKERRQ(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: */
2755f80ce2aSJacob Faibussowitsch     CHKERRQ(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     }
2795f80ce2aSJacob Faibussowitsch     CHKERRQ(VecRestoreArrayRead(pipe->x,&xarray));
28042dc13f1SHong Zhang   }
28142dc13f1SHong Zhang 
2825f80ce2aSJacob Faibussowitsch   CHKERRQ(VecRestoreArray(localX,&xarr));
2835f80ce2aSJacob Faibussowitsch   CHKERRQ(DMLocalToGlobalBegin(networkdm,localX,ADD_VALUES,X));
2845f80ce2aSJacob Faibussowitsch   CHKERRQ(DMLocalToGlobalEnd(networkdm,localX,ADD_VALUES,X));
2855f80ce2aSJacob Faibussowitsch   CHKERRQ(DMRestoreLocalVector(networkdm,&localX));
28642dc13f1SHong Zhang 
28742dc13f1SHong Zhang #if 0
28842dc13f1SHong Zhang   PetscInt N;
2895f80ce2aSJacob Faibussowitsch   CHKERRQ(VecGetSize(X,&N));
2905f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscPrintf(PETSC_COMM_WORLD,"initial solution %d:\n",N));
2915f80ce2aSJacob Faibussowitsch   CHKERRQ(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;
3025f80ce2aSJacob Faibussowitsch   CHKERRQ(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;
3155f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscObjectGetComm((PetscObject)networkdm,&comm));
31642dc13f1SHong Zhang 
31742dc13f1SHong Zhang   /* 1. Create isfrom_q for q-variable of pipes */
3185f80ce2aSJacob Faibussowitsch   CHKERRQ(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;
3225f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscMalloc1(numselectedvariable[i],&selectedvariables[i]));
32342dc13f1SHong Zhang     selectedvariables[i][0] = 0; /* q-variable */
32442dc13f1SHong Zhang   }
3255f80ce2aSJacob Faibussowitsch   CHKERRQ(DMNetworkCreateIS(networkdm,numkeys,&KeyPipe,blocksize,numselectedvariable,selectedvariables,&isfrom_q));
32642dc13f1SHong Zhang 
32742dc13f1SHong Zhang   /* 2. Create Xto and isto */
3285f80ce2aSJacob Faibussowitsch   CHKERRQ(ISGetLocalSize(isfrom_q, &n));
3295f80ce2aSJacob Faibussowitsch   CHKERRQ(VecCreate(comm,&Xto));
3305f80ce2aSJacob Faibussowitsch   CHKERRQ(VecSetSizes(Xto,n,PETSC_DECIDE));
3315f80ce2aSJacob Faibussowitsch   CHKERRQ(VecSetFromOptions(Xto));
3325f80ce2aSJacob Faibussowitsch   CHKERRQ(VecSet(Xto,0.0));
33342dc13f1SHong Zhang 
33442dc13f1SHong Zhang   /* 3. Create scatter */
3355f80ce2aSJacob Faibussowitsch   CHKERRQ(VecScatterCreate(X,isfrom_q,Xto,NULL,&ctx));
33642dc13f1SHong Zhang 
33742dc13f1SHong Zhang   /* 4. Scatter to Xq */
3385f80ce2aSJacob Faibussowitsch   CHKERRQ(VecScatterBegin(ctx,X,Xto,INSERT_VALUES,SCATTER_FORWARD));
3395f80ce2aSJacob Faibussowitsch   CHKERRQ(VecScatterEnd(ctx,X,Xto,INSERT_VALUES,SCATTER_FORWARD));
3405f80ce2aSJacob Faibussowitsch   CHKERRQ(VecScatterDestroy(&ctx));
3415f80ce2aSJacob Faibussowitsch   CHKERRQ(ISDestroy(&isfrom_q));
34242dc13f1SHong Zhang 
3435f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscPrintf(PETSC_COMM_WORLD,"Xq:\n"));
3445f80ce2aSJacob Faibussowitsch   CHKERRQ(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   }
3505f80ce2aSJacob Faibussowitsch   CHKERRQ(DMNetworkCreateIS(networkdm,numkeys,&KeyPipe,blocksize,numselectedvariable,selectedvariables,&isfrom_h));
35142dc13f1SHong Zhang 
3525f80ce2aSJacob Faibussowitsch   CHKERRQ(VecScatterCreate(X,isfrom_h,Xto,NULL,&ctx));
3535f80ce2aSJacob Faibussowitsch   CHKERRQ(VecScatterBegin(ctx,X,Xto,INSERT_VALUES,SCATTER_FORWARD));
3545f80ce2aSJacob Faibussowitsch   CHKERRQ(VecScatterEnd(ctx,X,Xto,INSERT_VALUES,SCATTER_FORWARD));
3555f80ce2aSJacob Faibussowitsch   CHKERRQ(VecScatterDestroy(&ctx));
3565f80ce2aSJacob Faibussowitsch   CHKERRQ(ISDestroy(&isfrom_h));
35742dc13f1SHong Zhang 
3585f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscPrintf(PETSC_COMM_WORLD,"Xh:\n"));
3595f80ce2aSJacob Faibussowitsch   CHKERRQ(VecView(Xto,PETSC_VIEWER_STDOUT_WORLD));
3605f80ce2aSJacob Faibussowitsch   CHKERRQ(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   }
3665f80ce2aSJacob Faibussowitsch   CHKERRQ(DMNetworkCreateIS(networkdm,numkeys,&KeyPipe,blocksize,NULL,NULL,&isfrom));
3675f80ce2aSJacob Faibussowitsch   CHKERRQ(ISDestroy(&isfrom));
3685f80ce2aSJacob Faibussowitsch   CHKERRQ(DMNetworkCreateIS(networkdm,numkeys,&KeyPipe,NULL,NULL,NULL,&isfrom));
36942dc13f1SHong Zhang 
3705f80ce2aSJacob Faibussowitsch   CHKERRQ(ISGetLocalSize(isfrom, &n));
3715f80ce2aSJacob Faibussowitsch   CHKERRQ(VecCreate(comm,&Xto));
3725f80ce2aSJacob Faibussowitsch   CHKERRQ(VecSetSizes(Xto,n,PETSC_DECIDE));
3735f80ce2aSJacob Faibussowitsch   CHKERRQ(VecSetFromOptions(Xto));
3745f80ce2aSJacob Faibussowitsch   CHKERRQ(VecSet(Xto,0.0));
37542dc13f1SHong Zhang 
3765f80ce2aSJacob Faibussowitsch   CHKERRQ(VecScatterCreate(X,isfrom,Xto,NULL,&ctx));
3775f80ce2aSJacob Faibussowitsch   CHKERRQ(VecScatterBegin(ctx,X,Xto,INSERT_VALUES,SCATTER_FORWARD));
3785f80ce2aSJacob Faibussowitsch   CHKERRQ(VecScatterEnd(ctx,X,Xto,INSERT_VALUES,SCATTER_FORWARD));
3795f80ce2aSJacob Faibussowitsch   CHKERRQ(VecScatterDestroy(&ctx));
3805f80ce2aSJacob Faibussowitsch   CHKERRQ(ISDestroy(&isfrom));
38142dc13f1SHong Zhang 
3825f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscPrintf(PETSC_COMM_WORLD,"Xpipes:\n"));
3835f80ce2aSJacob Faibussowitsch   CHKERRQ(VecView(Xto,PETSC_VIEWER_STDOUT_WORLD));
38442dc13f1SHong Zhang 
38542dc13f1SHong Zhang   /* 7. Free spaces */
38642dc13f1SHong Zhang   for (i=0; i<numkeys; i++) {
3875f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscFree(selectedvariables[i]));
38842dc13f1SHong Zhang   }
3895f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscFree3(blocksize,numselectedvariable,selectedvariables));
3905f80ce2aSJacob Faibussowitsch   CHKERRQ(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;
4025f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscObjectGetComm((PetscObject)networkdm,&comm));
4035f80ce2aSJacob Faibussowitsch   CHKERRMPI(MPI_Comm_rank(comm,&rank));
40442dc13f1SHong Zhang 
40542dc13f1SHong Zhang   /* Create a global isfrom for all junction variables */
4065f80ce2aSJacob Faibussowitsch   CHKERRQ(DMNetworkCreateIS(networkdm,numkeys,&KeyJunc,NULL,NULL,NULL,&isfrom));
4075f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscPrintf(PETSC_COMM_WORLD,"ISJunctions:\n"));
4085f80ce2aSJacob Faibussowitsch   CHKERRQ(ISView(isfrom,PETSC_VIEWER_STDOUT_WORLD));
4095f80ce2aSJacob Faibussowitsch   CHKERRQ(ISDestroy(&isfrom));
41042dc13f1SHong Zhang 
41142dc13f1SHong Zhang   /* Create a local isfrom for all junction variables */
4125f80ce2aSJacob Faibussowitsch   CHKERRQ(DMNetworkCreateLocalIS(networkdm,numkeys,&KeyJunc,NULL,NULL,NULL,&isfrom));
41342dc13f1SHong Zhang   if (!rank) {
4145f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscPrintf(PETSC_COMM_SELF,"[%d] ISLocalJunctions:\n",rank));
4155f80ce2aSJacob Faibussowitsch     CHKERRQ(ISView(isfrom,PETSC_VIEWER_STDOUT_SELF));
41642dc13f1SHong Zhang   }
4175f80ce2aSJacob Faibussowitsch   CHKERRQ(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;
4265f80ce2aSJacob Faibussowitsch   CHKERRMPI(MPI_Comm_rank(wash->comm,&rank));
4275f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscFree(wash->edgelist));
4285f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscFree(wash->vtype));
429dd400576SPatrick Sanan   if (rank == 0) {
4305f80ce2aSJacob Faibussowitsch     CHKERRQ(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;
4475f80ce2aSJacob Faibussowitsch   CHKERRMPI(MPI_Comm_rank(comm,&rank));
44842dc13f1SHong Zhang 
4495f80ce2aSJacob Faibussowitsch   CHKERRQ(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 */
4635f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscPrintf(PETSC_COMM_WORLD,"Setup pipesCase %D\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;
4745f80ce2aSJacob Faibussowitsch     CHKERRQ(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 
4865f80ce2aSJacob Faibussowitsch       CHKERRQ(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       /*------------------------*/
4935f80ce2aSJacob Faibussowitsch       CHKERRQ(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 
5255f80ce2aSJacob Faibussowitsch       CHKERRQ(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       /*------------------------*/
5325f80ce2aSJacob Faibussowitsch       CHKERRQ(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 
5635f80ce2aSJacob Faibussowitsch       CHKERRQ(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       /*------------------------*/
5705f80ce2aSJacob Faibussowitsch       CHKERRQ(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;
5915f80ce2aSJacob Faibussowitsch     CHKERRQ(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 */
6075f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsGetBool(NULL,NULL,"-wash_distribute",&washdist,NULL));
60842dc13f1SHong Zhang   if (washdist) {
60942dc13f1SHong Zhang     /*
6105f80ce2aSJacob Faibussowitsch      CHKERRQ(PetscPrintf(PETSC_COMM_WORLD," Distribute sequential wash ...\n"));
61142dc13f1SHong Zhang      */
6125f80ce2aSJacob Faibussowitsch     CHKERRQ(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 
638*b122ec5aSJacob Faibussowitsch   CHKERRQ(PetscInitialize(&argc,&argv,"pOption",help));
63942dc13f1SHong Zhang 
64042dc13f1SHong Zhang   /* Read runtime options */
6415f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsGetInt(NULL,NULL, "-case", &pipesCase, NULL));
6425f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsGetBool(NULL,NULL,"-user_Jac",&userJac,NULL));
6435f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsGetBool(NULL,NULL,"-pipe_monitor",&monipipes,NULL));
6445f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsGetBool(NULL,NULL,"-viewdm",&viewdm,NULL));
6455f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsGetBool(NULL,NULL,"-viewX",&viewX,NULL));
6465f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsGetInt(NULL,NULL, "-npipenodes", &nnodes, NULL));
64742dc13f1SHong Zhang 
64842dc13f1SHong Zhang   /* Create networkdm */
64942dc13f1SHong Zhang   /*------------------*/
6505f80ce2aSJacob Faibussowitsch   CHKERRQ(DMNetworkCreate(PETSC_COMM_WORLD,&networkdm));
6515f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscObjectGetComm((PetscObject)networkdm,&comm));
6525f80ce2aSJacob Faibussowitsch   CHKERRMPI(MPI_Comm_rank(comm,&rank));
6535f80ce2aSJacob Faibussowitsch   CHKERRMPI(MPI_Comm_size(comm,&size));
65442dc13f1SHong Zhang 
65542dc13f1SHong Zhang   if (size == 1 && monipipes) {
6565f80ce2aSJacob Faibussowitsch     CHKERRQ(DMNetworkMonitorCreate(networkdm,&monitor));
65742dc13f1SHong Zhang   }
65842dc13f1SHong Zhang 
65942dc13f1SHong Zhang   /* Register the components in the network */
6605f80ce2aSJacob Faibussowitsch   CHKERRQ(DMNetworkRegisterComponent(networkdm,"junctionstruct",sizeof(struct _p_Junction),&KeyJunction));
6615f80ce2aSJacob Faibussowitsch   CHKERRQ(DMNetworkRegisterComponent(networkdm,"pipestruct",sizeof(struct _p_Pipe),&KeyPipe));
66242dc13f1SHong Zhang 
66342dc13f1SHong Zhang   /* Create a distributed wash network (user-specific) */
6645f80ce2aSJacob Faibussowitsch   CHKERRQ(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 */
6725f80ce2aSJacob Faibussowitsch   CHKERRQ(DMNetworkSetNumSubNetworks(networkdm,PETSC_DECIDE,1));
6735f80ce2aSJacob Faibussowitsch   CHKERRQ(DMNetworkAddSubnetwork(networkdm,NULL,nedges,edgelist,NULL));
67442dc13f1SHong Zhang 
6755f80ce2aSJacob Faibussowitsch   CHKERRQ(DMNetworkLayoutSetUp(networkdm));
67642dc13f1SHong Zhang 
6775f80ce2aSJacob Faibussowitsch   CHKERRQ(DMNetworkGetEdgeRange(networkdm,&eStart,&eEnd));
6785f80ce2aSJacob Faibussowitsch   CHKERRQ(DMNetworkGetVertexRange(networkdm,&vStart,&vEnd));
6795f80ce2aSJacob Faibussowitsch   /* CHKERRQ(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! */
6835f80ce2aSJacob Faibussowitsch     CHKERRQ(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;
6895f80ce2aSJacob Faibussowitsch     CHKERRQ(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;
6935f80ce2aSJacob Faibussowitsch       CHKERRQ(DMNetworkMonitorAdd(monitor, "Pipe Q", e, pipes[e-eStart].nnodes, 0, 2, 0.0,pipes[e-eStart].length, -0.8, 0.8, PETSC_TRUE));
6945f80ce2aSJacob Faibussowitsch       CHKERRQ(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++) {
7005f80ce2aSJacob Faibussowitsch     CHKERRQ(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;
7065f80ce2aSJacob Faibussowitsch     CHKERRQ(DMNetworkGetPlex(networkdm,&plexdm));
7075f80ce2aSJacob Faibussowitsch     CHKERRQ(DMPlexGetPartitioner(plexdm, &part));
7085f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscPartitionerSetType(part,PETSCPARTITIONERSIMPLE));
7095f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscOptionsSetValue(NULL,"-dm_plex_csr_alg","mat")); /* for parmetis */
71042dc13f1SHong Zhang   }
71142dc13f1SHong Zhang 
71242dc13f1SHong Zhang   /* Set up DM for use */
7135f80ce2aSJacob Faibussowitsch   CHKERRQ(DMSetUp(networkdm));
71442dc13f1SHong Zhang   if (viewdm) {
7155f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscPrintf(PETSC_COMM_WORLD,"\nOriginal networkdm, DMView:\n"));
7165f80ce2aSJacob Faibussowitsch     CHKERRQ(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++) {
7215f80ce2aSJacob Faibussowitsch     CHKERRQ(DMNetworkGetConnectedVertices(networkdm,e,&cone));
72242dc13f1SHong Zhang     /* vfrom */
7235f80ce2aSJacob Faibussowitsch     CHKERRQ(DMNetworkGetComponent(networkdm,cone[0],0,&vkey,(void**)&junction,NULL));
72442dc13f1SHong Zhang     junction->type = (VertexType)vtype[2*e];
72542dc13f1SHong Zhang 
72642dc13f1SHong Zhang     /* vto */
7275f80ce2aSJacob Faibussowitsch     CHKERRQ(DMNetworkGetComponent(networkdm,cone[1],0,&vkey,(void**)&junction,NULL));
72842dc13f1SHong Zhang     junction->type = (VertexType)vtype[2*e+1];
72942dc13f1SHong Zhang   }
73042dc13f1SHong Zhang 
7315f80ce2aSJacob Faibussowitsch   CHKERRQ(WashNetworkCleanUp(wash));
73242dc13f1SHong Zhang 
73342dc13f1SHong Zhang   /* Network partitioning and distribution of data */
7345f80ce2aSJacob Faibussowitsch   CHKERRQ(DMNetworkDistribute(&networkdm,0));
73542dc13f1SHong Zhang   if (viewdm) {
736*b122ec5aSJacob Faibussowitsch     CHKERRQ(PetscPrintf(PETSC_COMM_WORLD,"\nAfter DMNetworkDistribute, DMView:\n"));
7375f80ce2aSJacob Faibussowitsch     CHKERRQ(DMView(networkdm,PETSC_VIEWER_STDOUT_WORLD));
73842dc13f1SHong Zhang   }
73942dc13f1SHong Zhang 
74042dc13f1SHong Zhang   /* create vectors */
7415f80ce2aSJacob Faibussowitsch   CHKERRQ(DMCreateGlobalVector(networkdm,&X));
7425f80ce2aSJacob Faibussowitsch   CHKERRQ(DMCreateLocalVector(networkdm,&wash->localX));
7435f80ce2aSJacob Faibussowitsch   CHKERRQ(DMCreateLocalVector(networkdm,&wash->localXdot));
74442dc13f1SHong Zhang 
74542dc13f1SHong Zhang   /* PipeSetUp -- each process only sets its own pipes */
74642dc13f1SHong Zhang   /*---------------------------------------------------*/
7475f80ce2aSJacob Faibussowitsch   CHKERRQ(DMNetworkGetVertexRange(networkdm,&vStart,&vEnd));
74842dc13f1SHong Zhang 
74942dc13f1SHong Zhang   userJac = PETSC_TRUE;
7505f80ce2aSJacob Faibussowitsch   CHKERRQ(DMNetworkHasJacobian(networkdm,userJac,userJac));
7515f80ce2aSJacob Faibussowitsch   CHKERRQ(DMNetworkGetEdgeRange(networkdm,&eStart,&eEnd));
75242dc13f1SHong Zhang   for (e=eStart; e<eEnd; e++) { /* each edge has only one component, pipe */
7535f80ce2aSJacob Faibussowitsch     CHKERRQ(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() */
756*b122ec5aSJacob Faibussowitsch     CHKERRQ(PipeSetParameters(pipe,
75742dc13f1SHong Zhang                               600.0,   /* length   */
75842dc13f1SHong Zhang                               0.5,     /* diameter */
75942dc13f1SHong Zhang                               1200.0,  /* a        */
760*b122ec5aSJacob Faibussowitsch                               0.018)); /* friction */
7615f80ce2aSJacob Faibussowitsch     CHKERRQ(PipeSetUp(pipe));
76242dc13f1SHong Zhang 
76342dc13f1SHong Zhang     if (userJac) {
76442dc13f1SHong Zhang       /* Create Jacobian matrix structures for a Pipe */
76542dc13f1SHong Zhang       Mat            *J;
7665f80ce2aSJacob Faibussowitsch       CHKERRQ(PipeCreateJacobian(pipe,NULL,&J));
7675f80ce2aSJacob Faibussowitsch       CHKERRQ(DMNetworkEdgeSetMatrix(networkdm,e,J));
76842dc13f1SHong Zhang     }
76942dc13f1SHong Zhang   }
77042dc13f1SHong Zhang 
77142dc13f1SHong Zhang   if (userJac) {
7725f80ce2aSJacob Faibussowitsch     CHKERRQ(DMNetworkGetVertexRange(networkdm,&vStart,&vEnd));
77342dc13f1SHong Zhang     for (v=vStart; v<vEnd; v++) {
77442dc13f1SHong Zhang       Mat            *J;
7755f80ce2aSJacob Faibussowitsch       CHKERRQ(JunctionCreateJacobian(networkdm,v,NULL,&J));
7765f80ce2aSJacob Faibussowitsch       CHKERRQ(DMNetworkVertexSetMatrix(networkdm,v,J));
77742dc13f1SHong Zhang 
7785f80ce2aSJacob Faibussowitsch       CHKERRQ(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   /*--------------------------------------------------------*/
7855f80ce2aSJacob Faibussowitsch   CHKERRQ(TSCreate(PETSC_COMM_WORLD,&ts));
78642dc13f1SHong Zhang 
7875f80ce2aSJacob Faibussowitsch   CHKERRQ(TSSetDM(ts,(DM)networkdm));
7885f80ce2aSJacob Faibussowitsch   CHKERRQ(TSSetIFunction(ts,NULL,WASHIFunction,wash));
78942dc13f1SHong Zhang 
7905f80ce2aSJacob Faibussowitsch   CHKERRQ(TSSetMaxSteps(ts,steps));
7915f80ce2aSJacob Faibussowitsch   CHKERRQ(TSSetExactFinalTime(ts,TS_EXACTFINALTIME_STEPOVER));
7925f80ce2aSJacob Faibussowitsch   CHKERRQ(TSSetTimeStep(ts,0.1));
7935f80ce2aSJacob Faibussowitsch   CHKERRQ(TSSetType(ts,TSBEULER));
794*b122ec5aSJacob Faibussowitsch   if (size == 1 && monipipes) CHKERRQ(TSMonitorSet(ts, TSDMNetworkMonitor, monitor, NULL));
7955f80ce2aSJacob Faibussowitsch   CHKERRQ(TSSetFromOptions(ts));
79642dc13f1SHong Zhang 
7975f80ce2aSJacob Faibussowitsch   CHKERRQ(WASHSetInitialSolution(networkdm,X,wash));
79842dc13f1SHong Zhang 
7995f80ce2aSJacob Faibussowitsch   CHKERRQ(TSSolve(ts,X));
80042dc13f1SHong Zhang 
8015f80ce2aSJacob Faibussowitsch   CHKERRQ(TSGetSolveTime(ts,&ftime));
8025f80ce2aSJacob Faibussowitsch   CHKERRQ(TSGetStepNumber(ts,&steps));
8035f80ce2aSJacob Faibussowitsch   CHKERRQ(TSGetConvergedReason(ts,&reason));
8045f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscPrintf(PETSC_COMM_WORLD,"%s at time %g after %D steps\n",TSConvergedReasons[reason],(double)ftime,steps));
80542dc13f1SHong Zhang   if (viewX) {
8065f80ce2aSJacob Faibussowitsch     CHKERRQ(VecView(X,PETSC_VIEWER_STDOUT_WORLD));
80742dc13f1SHong Zhang   }
80842dc13f1SHong Zhang 
80942dc13f1SHong Zhang   viewpipes = PETSC_FALSE;
8105f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsGetBool(NULL,NULL, "-Jac_view", &viewpipes,NULL));
81142dc13f1SHong Zhang   if (viewpipes) {
81242dc13f1SHong Zhang     SNES snes;
81342dc13f1SHong Zhang     Mat  Jac;
8145f80ce2aSJacob Faibussowitsch     CHKERRQ(TSGetSNES(ts,&snes));
8155f80ce2aSJacob Faibussowitsch     CHKERRQ(SNESGetJacobian(snes,&Jac,NULL,NULL,NULL));
8165f80ce2aSJacob Faibussowitsch     CHKERRQ(MatView(Jac,PETSC_VIEWER_DRAW_WORLD));
81742dc13f1SHong Zhang   }
81842dc13f1SHong Zhang 
81942dc13f1SHong Zhang   /* View solutions */
82042dc13f1SHong Zhang   /* -------------- */
82142dc13f1SHong Zhang   viewpipes = PETSC_FALSE;
8225f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsGetBool(NULL,NULL, "-pipe_view", &viewpipes,NULL));
82342dc13f1SHong Zhang   if (viewpipes) {
8245f80ce2aSJacob Faibussowitsch     CHKERRQ(PipesView(networkdm,KeyPipe,X));
82542dc13f1SHong Zhang   }
82642dc13f1SHong Zhang 
82742dc13f1SHong Zhang   /* Test IS */
82842dc13f1SHong Zhang   viewjuncs = PETSC_FALSE;
8295f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsGetBool(NULL,NULL, "-isjunc_view", &viewjuncs,NULL));
83042dc13f1SHong Zhang   if (viewjuncs) {
8315f80ce2aSJacob Faibussowitsch     CHKERRQ(ISJunctionsView(networkdm,KeyJunction));
83242dc13f1SHong Zhang   }
83342dc13f1SHong Zhang 
83442dc13f1SHong Zhang   /* Free spaces */
83542dc13f1SHong Zhang   /* ----------- */
8365f80ce2aSJacob Faibussowitsch   CHKERRQ(TSDestroy(&ts));
8375f80ce2aSJacob Faibussowitsch   CHKERRQ(VecDestroy(&X));
8385f80ce2aSJacob Faibussowitsch   CHKERRQ(VecDestroy(&wash->localX));
8395f80ce2aSJacob Faibussowitsch   CHKERRQ(VecDestroy(&wash->localXdot));
84042dc13f1SHong Zhang 
84142dc13f1SHong Zhang   /* Destroy objects from each pipe that are created in PipeSetUp() */
8425f80ce2aSJacob Faibussowitsch   CHKERRQ(DMNetworkGetEdgeRange(networkdm,&eStart, &eEnd));
84342dc13f1SHong Zhang   for (i = eStart; i < eEnd; i++) {
8445f80ce2aSJacob Faibussowitsch     CHKERRQ(DMNetworkGetComponent(networkdm,i,0,&key,(void**)&pipe,NULL));
8455f80ce2aSJacob Faibussowitsch     CHKERRQ(PipeDestroy(&pipe));
84642dc13f1SHong Zhang   }
84742dc13f1SHong Zhang   if (userJac) {
84842dc13f1SHong Zhang     for (v=vStart; v<vEnd; v++) {
8495f80ce2aSJacob Faibussowitsch       CHKERRQ(DMNetworkGetComponent(networkdm,v,0,&vkey,(void**)&junction,NULL));
8505f80ce2aSJacob Faibussowitsch       CHKERRQ(JunctionDestroyJacobian(networkdm,v,junction));
85142dc13f1SHong Zhang     }
85242dc13f1SHong Zhang   }
85342dc13f1SHong Zhang 
85442dc13f1SHong Zhang   if (size == 1 && monipipes) {
8555f80ce2aSJacob Faibussowitsch     CHKERRQ(DMNetworkMonitorDestroy(&monitor));
85642dc13f1SHong Zhang   }
8575f80ce2aSJacob Faibussowitsch   CHKERRQ(DMDestroy(&networkdm));
8585f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscFree(wash));
85942dc13f1SHong Zhang 
86042dc13f1SHong Zhang   if (rank) {
8615f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscFree2(junctions,pipes));
86242dc13f1SHong Zhang   }
863*b122ec5aSJacob Faibussowitsch   CHKERRQ(PetscFinalize());
864*b122ec5aSJacob 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