Actual source code: water.c
petsc-3.14.6 2021-03-30
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: #if defined(PETSC_USE_LOG)
21: PetscLogStage stage1,stage2;
22: #endif
23: PetscMPIInt crank;
24: DM networkdm;
25: PetscInt *edgelist = NULL;
26: PetscInt nv,ne,i;
27: const PetscInt *vtx,*edges;
28: Vec X,F;
29: SNES snes;
30: SNESConvergedReason reason;
32: PetscInitialize(&argc,&argv,"wateroptions",help);if (ierr) return ierr;
33: MPI_Comm_rank(PETSC_COMM_WORLD,&crank);
35: /* Create an empty network object */
36: DMNetworkCreate(PETSC_COMM_WORLD,&networkdm);
38: /* Register the components in the network */
39: DMNetworkRegisterComponent(networkdm,"edgestruct",sizeof(struct _p_EDGE_Water),&appctx.compkey_edge);
40: DMNetworkRegisterComponent(networkdm,"busstruct",sizeof(struct _p_VERTEX_Water),&appctx.compkey_vtx);
42: PetscLogStageRegister("Read Data",&stage1);
43: PetscLogStagePush(stage1);
44: PetscNew(&waterdata);
46: /* READ THE DATA */
47: if (!crank) {
48: /* READ DATA. Only rank 0 reads the data */
49: PetscOptionsGetString(NULL,NULL,"-waterdata",waterdata_file,sizeof(waterdata_file),NULL);
50: WaterReadData(waterdata,waterdata_file);
52: PetscCalloc1(2*waterdata->nedge,&edgelist);
53: GetListofEdges_Water(waterdata,edgelist);
54: }
55: PetscLogStagePop();
57: PetscLogStageRegister("Create network",&stage2);
58: PetscLogStagePush(stage2);
60: /* Set numbers of nodes and edges */
61: DMNetworkSetSizes(networkdm,1,&waterdata->nvertex,&waterdata->nedge,0,NULL);
62: if (!crank) {
63: PetscPrintf(PETSC_COMM_SELF,"water nvertices %D, nedges %D\n",waterdata->nvertex,waterdata->nedge);
64: }
66: /* Add edge connectivity */
67: DMNetworkSetEdgeList(networkdm,&edgelist,NULL);
69: /* Set up the network layout */
70: DMNetworkLayoutSetUp(networkdm);
72: if (!crank) {
73: PetscFree(edgelist);
74: }
76: /* ADD VARIABLES AND COMPONENTS FOR THE NETWORK */
77: DMNetworkGetSubnetworkInfo(networkdm,0,&nv,&ne,&vtx,&edges);
79: for (i = 0; i < ne; i++) {
80: DMNetworkAddComponent(networkdm,edges[i],appctx.compkey_edge,&waterdata->edge[i]);
81: }
83: for (i = 0; i < nv; i++) {
84: DMNetworkAddComponent(networkdm,vtx[i],appctx.compkey_vtx,&waterdata->vertex[i]);
85: /* Add number of variables */
86: DMNetworkAddNumVariables(networkdm,vtx[i],1);
87: }
89: /* Set up DM for use */
90: DMSetUp(networkdm);
92: if (!crank) {
93: PetscFree(waterdata->vertex);
94: PetscFree(waterdata->edge);
95: }
96: PetscFree(waterdata);
98: /* Distribute networkdm to multiple processes */
99: DMNetworkDistribute(&networkdm,0);
101: PetscLogStagePop();
103: DMCreateGlobalVector(networkdm,&X);
104: VecDuplicate(X,&F);
106: /* HOOK UP SOLVER */
107: SNESCreate(PETSC_COMM_WORLD,&snes);
108: SNESSetDM(snes,networkdm);
109: SNESSetOptionsPrefix(snes,"water_");
110: SNESSetFunction(snes,F,WaterFormFunction,NULL);
111: SNESSetFromOptions(snes);
113: WaterSetInitialGuess(networkdm,X);
114: /* VecView(X,PETSC_VIEWER_STDOUT_WORLD); */
116: SNESSolve(snes,NULL,X);
117: SNESGetConvergedReason(snes,&reason);
118: if (reason < 0) SETERRQ(PETSC_COMM_SELF,0,"No solution found for the water network");
119: /* VecView(X,PETSC_VIEWER_STDOUT_WORLD); */
121: VecDestroy(&X);
122: VecDestroy(&F);
123: SNESDestroy(&snes);
124: DMDestroy(&networkdm);
125: PetscFinalize();
126: return ierr;
127: }
129: /*TEST
131: build:
132: depends: waterreaddata.c waterfunctions.c
133: requires: !complex double define(PETSC_HAVE_ATTRIBUTEALIGNED)
135: test:
136: args: -water_snes_converged_reason -options_left no
137: localrunfiles: wateroptions sample1.inp
138: output_file: output/water.out
139: requires: double !complex define(PETSC_HAVE_ATTRIBUTEALIGNED)
141: test:
142: suffix: 2
143: nsize: 3
144: args: -water_snes_converged_reason -options_left no
145: localrunfiles: wateroptions sample1.inp
146: output_file: output/water.out
147: requires: double !complex define(PETSC_HAVE_ATTRIBUTEALIGNED)
149: TEST*/