Actual source code: water.c
petsc-3.10.5 2019-03-28
1: static char help[] = "This example demonstrates the use of DMNetwork interface for solving a steady-state water network model.\n\
2: The water network equations follow those used for the package EPANET\n\
3: The data file format used is from the EPANET package (https://www.epa.gov/water-research/epanet).\n\
4: Run this program: mpiexec -n <n> ./water\n\\n";
6: /* T
7: Concepts: DMNetwork
8: Concepts: PETSc SNES solver
9: */
11: #include "water.h"
12: #include <petscdmnetwork.h>
14: int main(int argc,char ** argv)
15: {
16: PetscErrorCode ierr;
17: char waterdata_file[PETSC_MAX_PATH_LEN]="sample1.inp";
18: WATERDATA *waterdata;
19: AppCtx_Water appctx;
20: PetscLogStage stage1,stage2;
21: PetscMPIInt crank;
22: DM networkdm;
23: PetscInt *edgelist = NULL;
24: PetscInt nv,ne,i;
25: const PetscInt *vtx,*edges;
26: Vec X,F;
27: SNES snes;
28: PetscInt ngvtx=PETSC_DETERMINE,ngedge=PETSC_DETERMINE;
29: SNESConvergedReason reason;
31: PetscInitialize(&argc,&argv,"wateroptions",help);
32: MPI_Comm_rank(PETSC_COMM_WORLD,&crank);
34: /* Create an empty network object */
35: DMNetworkCreate(PETSC_COMM_WORLD,&networkdm);
37: /* Register the components in the network */
38: DMNetworkRegisterComponent(networkdm,"edgestruct",sizeof(struct _p_EDGE_Water),&appctx.compkey_edge);
39: DMNetworkRegisterComponent(networkdm,"busstruct",sizeof(struct _p_VERTEX_Water),&appctx.compkey_vtx);
41: PetscLogStageRegister("Read Data",&stage1);
42: PetscLogStagePush(stage1);
43: PetscNew(&waterdata);
45: /* READ THE DATA */
46: if (!crank) {
47: /* READ DATA. Only rank 0 reads the data */
48: PetscOptionsGetString(NULL,NULL,"-waterdata",waterdata_file,PETSC_MAX_PATH_LEN-1,NULL);
49: WaterReadData(waterdata,waterdata_file);
51: PetscCalloc1(2*waterdata->nedge,&edgelist);
52: GetListofEdges_Water(waterdata,edgelist);
53: }
54: PetscLogStagePop();
56: PetscLogStageRegister("Create network",&stage2);
57: PetscLogStagePush(stage2);
59: /* Set numbers of nodes and edges */
60: DMNetworkSetSizes(networkdm,1,0,&waterdata->nvertex,&waterdata->nedge,&ngvtx,&ngedge);
61: if (!crank) {
62: PetscPrintf(PETSC_COMM_SELF,"water nvertices %D, nedges %D\n",waterdata->nvertex,waterdata->nedge);
63: }
65: /* Add edge connectivity */
66: DMNetworkSetEdgeList(networkdm,&edgelist,NULL);
68: /* Set up the network layout */
69: DMNetworkLayoutSetUp(networkdm);
71: if (!crank) {
72: PetscFree(edgelist);
73: }
75: /* ADD VARIABLES AND COMPONENTS FOR THE NETWORK */
76: DMNetworkGetSubnetworkInfo(networkdm,0,&nv,&ne,&vtx,&edges);
78: for (i = 0; i < ne; i++) {
79: DMNetworkAddComponent(networkdm,edges[i],appctx.compkey_edge,&waterdata->edge[i]);
80: }
82: for (i = 0; i < nv; i++) {
83: DMNetworkAddComponent(networkdm,vtx[i],appctx.compkey_vtx,&waterdata->vertex[i]);
84: /* Add number of variables */
85: DMNetworkAddNumVariables(networkdm,vtx[i],1);
86: }
88: /* Set up DM for use */
89: DMSetUp(networkdm);
91: if (!crank) {
92: PetscFree(waterdata->vertex);
93: PetscFree(waterdata->edge);
94: }
95: PetscFree(waterdata);
97: /* Distribute networkdm to multiple processes */
98: DMNetworkDistribute(&networkdm,0);
100: PetscLogStagePop();
102: DMCreateGlobalVector(networkdm,&X);
103: VecDuplicate(X,&F);
105: /* HOOK UP SOLVER */
106: SNESCreate(PETSC_COMM_WORLD,&snes);
107: SNESSetDM(snes,networkdm);
108: SNESSetOptionsPrefix(snes,"water_");
109: SNESSetFunction(snes,F,WaterFormFunction,NULL);
110: SNESSetFromOptions(snes);
112: WaterSetInitialGuess(networkdm,X);
113: /* VecView(X,PETSC_VIEWER_STDOUT_WORLD); */
115: SNESSolve(snes,NULL,X);
116: SNESGetConvergedReason(snes,&reason);
117: if (reason < 0) {
118: SETERRQ(PETSC_COMM_SELF,0,"No solution found for the water network");
119: }
120: /* VecView(X,PETSC_VIEWER_STDOUT_WORLD); */
122: VecDestroy(&X);
123: VecDestroy(&F);
124: SNESDestroy(&snes);
125: DMDestroy(&networkdm);
126: PetscFinalize();
127: return ierr;
128: }
130: /*TEST
132: build:
133: depends: waterreaddata.c waterfunctions.c
134: requires: !complex double define(PETSC_HAVE_ATTRIBUTEALIGNED)
136: test:
137: args: -water_snes_converged_reason -options_left no
138: localrunfiles: wateroptions sample1.inp
139: output_file: output/water.out
140: requires: double !complex define(PETSC_HAVE_ATTRIBUTEALIGNED)
142: test:
143: suffix: 2
144: nsize: 3
145: args: -water_snes_converged_reason -options_left no
146: localrunfiles: wateroptions sample1.inp
147: output_file: output/water.out
148: requires: double !complex define(PETSC_HAVE_ATTRIBUTEALIGNED)
150: TEST*/