diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 000000000..35b1b0675 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,52 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "(gdb) Attach", + "type": "cppdbg", + "request": "attach", + "program": "enter program name, for example ${workspaceFolder}/a.out", + "MIMode": "gdb", + "setupCommands": [ + { + "description": "Enable pretty-printing for gdb", + "text": "-enable-pretty-printing", + "ignoreFailures": true + }, + { + "description": "Set Disassembly Flavor to Intel", + "text": "-gdb-set disassembly-flavor intel", + "ignoreFailures": true + } + ] + }, + { + "name": "(gdb) Launch", + "type": "cppdbg", + "request": "launch", + "program": "enter program name, for example ${workspaceFolder}/a.out", + "args": [], + "stopAtEntry": false, + "cwd": "${fileDirname}", + "environment": [], + "externalConsole": false, + "MIMode": "gdb", + "setupCommands": [ + { + "description": "Enable pretty-printing for gdb", + "text": "-enable-pretty-printing", + "ignoreFailures": true + }, + { + "description": "Set Disassembly Flavor to Intel", + "text": "-gdb-set disassembly-flavor intel", + "ignoreFailures": true + } + ] + } + + ] +} \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 000000000..08d9005bb --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,28 @@ +{ + "tasks": [ + { + "type": "cppbuild", + "label": "C/C++: gcc build active file", + "command": "/usr/bin/gcc", + "args": [ + "-fdiagnostics-color=always", + "-g", + "${file}", + "-o", + "${fileDirname}/${fileBasenameNoExtension}" + ], + "options": { + "cwd": "${fileDirname}" + }, + "problemMatcher": [ + "$gcc" + ], + "group": { + "kind": "build", + "isDefault": true + }, + "detail": "Task generated by Debugger." + } + ], + "version": "2.0.0" +} \ No newline at end of file diff --git a/website/README.md b/website/README.md new file mode 100644 index 000000000..0ade9634b --- /dev/null +++ b/website/README.md @@ -0,0 +1,56 @@ +# EPANET Website + +This is the official website for the EPANET project, built with HTML, CSS, and JavaScript. + +## Structure + +``` +website/ +├── index.html # Homepage +├── documentation.html # API Documentation +├── examples.html # Code Examples +├── css/ +│ └── style.css # Main stylesheet +├── js/ +│ └── main.js # JavaScript functionality +└── img/ + ├── Network.png # Network diagram + ├── DataFlow.png # Data flow diagram + ├── DistributionSystem.png + └── Example2.png +``` + +## Features + +- **Responsive Design**: Works on desktop, tablet, and mobile devices +- **Modern UI**: Clean, professional design with water-themed colors +- **Documentation**: Complete API reference and function categories +- **Examples**: Practical code examples in C +- **Mobile Navigation**: Hamburger menu for mobile devices + +## Viewing the Website + +To view the website locally, you can use any web server. For example: + +```bash +# Using Python +cd website +python -m http.server 8000 + +# Using Node.js +npx serve . + +# Using VS Code +# Open index.html with Live Server extension +``` + +Then open http://localhost:8000 in your browser. + +## About EPANET + +EPANET is an industry-standard program for modeling the hydraulic and water quality behavior of water distribution system pipe networks. It is maintained by the Open Water Analytics (OWA) community. + +For more information, visit: +- [GitHub Repository](https://github.com/OpenWaterAnalytics/EPANET) +- [API Documentation](http://wateranalytics.org/EPANET/) +- [Building Guide](BUILDING.md) \ No newline at end of file diff --git a/website/css/style.css b/website/css/style.css new file mode 100644 index 000000000..33334f90e --- /dev/null +++ b/website/css/style.css @@ -0,0 +1,548 @@ +/* EPANET Website Styles */ + +:root { + --primary-color: #0ea5e9; + --primary-dark: #0284c7; + --secondary-color: #64748b; + --accent-color: #0d9488; + --text-dark: #1e293b; + --text-light: #64748b; + --bg-light: #f8fafc; + --bg-white: #ffffff; + --border-color: #e2e8f0; + --shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06); + --transition: all 0.3s ease; +} + +* { + margin: 0; + padding: 0; + box-sizing: border-box; +} + +body { + font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; + line-height: 1.6; + color: var(--text-dark); + background-color: var(--bg-white); +} + +.container { + width: 100%; + max-width: 1200px; + margin: 0 auto; + padding: 0 20px; +} + +/* Header & Navigation */ +.header { + background: var(--bg-white); + box-shadow: var(--shadow); + position: sticky; + top: 0; + z-index: 100; +} + +.navbar { + padding: 1rem 0; +} + +.navbar .container { + display: flex; + justify-content: space-between; + align-items: center; +} + +.logo { + display: flex; + align-items: center; + gap: 10px; + font-size: 1.5rem; + font-weight: 700; + color: var(--primary-color); +} + +.logo i { + font-size: 1.8rem; +} + +.nav-menu { + display: flex; + list-style: none; + gap: 2rem; +} + +.nav-menu a { + text-decoration: none; + color: var(--text-dark); + font-weight: 500; + transition: var(--transition); + padding: 0.5rem 1rem; + border-radius: 0.5rem; +} + +.nav-menu a:hover, +.nav-menu a.active { + color: var(--primary-color); + background: var(--bg-light); +} + +.hamburger { + display: none; + flex-direction: column; + cursor: pointer; +} + +.bar { + width: 25px; + height: 3px; + background: var(--text-dark); + margin: 3px 0; + transition: var(--transition); + border-radius: 2px; +} + +/* Hero Section */ +.hero { + background: linear-gradient(135deg, var(--primary-color) 0%, var(--primary-dark) 100%); + color: white; + padding: 4rem 0; + min-height: 80vh; + display: flex; + align-items: center; +} + +.hero .container { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 3rem; + align-items: center; +} + +.hero h1 { + font-size: 3.5rem; + font-weight: 700; + margin-bottom: 1rem; +} + +.hero-subtitle { + font-size: 1.25rem; + margin-bottom: 2rem; + opacity: 0.9; +} + +.hero-buttons { + display: flex; + gap: 1rem; +} + +.btn { + padding: 0.75rem 2rem; + border-radius: 0.5rem; + text-decoration: none; + font-weight: 600; + transition: var(--transition); + display: inline-block; + border: none; + cursor: pointer; +} + +.btn-primary { + background: var(--bg-white); + color: var(--primary-color); +} + +.btn-primary:hover { + background: var(--bg-light); + transform: translateY(-2px); + box-shadow: var(--shadow); +} + +.btn-secondary { + background: transparent; + color: var(--bg-white); + border: 2px solid var(--bg-white); +} + +.btn-secondary:hover { + background: var(--bg-white); + color: var(--primary-color); +} + +.btn-outline { + background: transparent; + color: var(--primary-color); + border: 2px solid var(--primary-color); +} + +.btn-outline:hover { + background: var(--primary-color); + color: var(--bg-white); +} + +.hero-image img { + width: 100%; + max-width: 500px; + border-radius: 1rem; + box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1); +} + +/* Features Section */ +.features { + padding: 5rem 0; + background: var(--bg-light); +} + +.features h2 { + text-align: center; + font-size: 2.5rem; + margin-bottom: 3rem; + color: var(--text-dark); +} + +.features-grid { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); + gap: 2rem; +} + +.feature-card { + background: var(--bg-white); + padding: 2rem; + border-radius: 1rem; + text-align: center; + box-shadow: var(--shadow); + transition: var(--transition); +} + +.feature-card:hover { + transform: translateY(-5px); + box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1); +} + +.feature-card i { + font-size: 2.5rem; + color: var(--primary-color); + margin-bottom: 1rem; +} + +.feature-card h3 { + font-size: 1.25rem; + margin-bottom: 1rem; + color: var(--text-dark); +} + +/* About Section */ +.about { + padding: 5rem 0; +} + +.about-content { + max-width: 800px; + margin: 0 auto; + text-align: center; +} + +.about h2 { + font-size: 2.5rem; + margin-bottom: 2rem; + color: var(--text-dark); +} + +.about p { + font-size: 1.1rem; + margin-bottom: 1.5rem; + color: var(--text-light); +} + +/* Quick Start Section */ +.quick-start { + padding: 5rem 0; + background: var(--bg-light); +} + +.quick-start h2 { + text-align: center; + font-size: 2.5rem; + margin-bottom: 2rem; + color: var(--text-dark); +} + +.code-block { + background: #1e293b; + border-radius: 0.75rem; + padding: 2rem; + overflow-x: auto; + margin-bottom: 1.5rem; +} + +.code-block pre { + color: #e2e8f0; + font-family: 'Fira Code', 'Consolas', monospace; + font-size: 0.95rem; + line-height: 1.5; +} + +.code-block code { + font-family: inherit; +} + +.quick-start-text { + text-align: center; + color: var(--text-light); +} + +.quick-start-text a { + color: var(--primary-color); + text-decoration: none; + font-weight: 600; +} + +/* CTA Section */ +.cta { + padding: 4rem 0; + background: linear-gradient(135deg, var(--accent-color) 0%, #0f766e 100%); + color: white; + text-align: center; +} + +.cta h2 { + font-size: 2.5rem; + margin-bottom: 1rem; +} + +.cta p { + font-size: 1.1rem; + margin-bottom: 2rem; + opacity: 0.9; +} + +.cta-buttons { + display: flex; + justify-content: center; + gap: 1rem; +} + +.cta .btn-primary, +.cta .btn-secondary { + background: var(--bg-white); + color: var(--accent-color); +} + +.cta .btn-secondary { + background: transparent; + color: var(--bg-white); + border: 2px solid var(--bg-white); +} + +/* Footer */ +.footer { + background: var(--text-dark); + color: var(--bg-white); + padding: 3rem 0 1.5rem; +} + +.footer-content { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); + gap: 2rem; + margin-bottom: 2rem; +} + +.footer-section h3 { + font-size: 1.25rem; + margin-bottom: 1rem; + color: var(--primary-color); +} + +.footer-section ul { + list-style: none; +} + +.footer-section ul li { + margin-bottom: 0.5rem; +} + +.footer-section a { + color: var(--bg-white); + text-decoration: none; + transition: var(--transition); +} + +.footer-section a:hover { + color: var(--primary-color); +} + +.footer-bottom { + text-align: center; + padding-top: 1.5rem; + border-top: 1px solid var(--border-color); +} + +/* Documentation Page */ +.docs-hero { + background: linear-gradient(135deg, var(--primary-color) 0%, var(--primary-dark) 100%); + color: white; + padding: 3rem 0; + text-align: center; +} + +.docs-hero h1 { + font-size: 2.5rem; + margin-bottom: 1rem; +} + +.docs-content { + padding: 4rem 0; +} + +.docs-grid { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); + gap: 2rem; +} + +.doc-card { + background: var(--bg-white); + padding: 2rem; + border-radius: 1rem; + box-shadow: var(--shadow); + transition: var(--transition); +} + +.doc-card:hover { + transform: translateY(-3px); +} + +.doc-card i { + font-size: 2rem; + color: var(--primary-color); + margin-bottom: 1rem; +} + +.doc-card h3 { + margin-bottom: 1rem; + color: var(--text-dark); +} + +.doc-card ul { + list-style: none; +} + +.doc-card ul li { + margin-bottom: 0.5rem; +} + +.doc-card a { + color: var(--primary-color); + text-decoration: none; +} + +.doc-card a:hover { + text-decoration: underline; +} + +/* Examples Page */ +.examples-hero { + background: linear-gradient(135deg, var(--primary-color) 0%, var(--primary-dark) 100%); + color: white; + padding: 3rem 0; + text-align: center; +} + +.examples-content { + padding: 4rem 0; +} + +.example-card { + background: var(--bg-white); + border-radius: 1rem; + box-shadow: var(--shadow); + margin-bottom: 2rem; + overflow: hidden; +} + +.example-header { + background: var(--primary-color); + color: white; + padding: 1.5rem; +} + +.example-header h3 { + margin: 0; +} + +.example-body { + padding: 1.5rem; +} + +.example-body pre { + background: var(--bg-light); + padding: 1rem; + border-radius: 0.5rem; + overflow-x: auto; + margin: 1rem 0; +} + +/* Responsive Design */ +@media (max-width: 768px) { + .hamburger { + display: flex; + } + + .nav-menu { + position: fixed; + left: -100%; + top: 70px; + flex-direction: column; + background: var(--bg-white); + width: 100%; + text-align: center; + transition: var(--transition); + box-shadow: var(--shadow); + padding: 2rem 0; + gap: 0; + } + + .nav-menu.active { + left: 0; + } + + .hero .container { + grid-template-columns: 1fr; + text-align: center; + } + + .hero h1 { + font-size: 2.5rem; + } + + .hero-buttons { + justify-content: center; + } + + .features h2, + .about h2, + .quick-start h2, + .cta h2 { + font-size: 2rem; + } +} + +/* Animation */ +@keyframes fadeIn { + from { + opacity: 0; + transform: translateY(20px); + } + to { + opacity: 1; + transform: translateY(0); + } +} + +.feature-card, +.doc-card, +.example-card { + animation: fadeIn 0.6s ease-out; +} \ No newline at end of file diff --git a/website/documentation.html b/website/documentation.html new file mode 100644 index 000000000..a68091b4f --- /dev/null +++ b/website/documentation.html @@ -0,0 +1,188 @@ + + +
+ + +Complete guide to using EPANET and its Programmer's Toolkit API
+EN_createproject, EN_deleteproject, EN_open, EN_saveinpfile, EN_close
+EN_solveH, EN_openH, EN_initH, EN_runH, EN_nextH, EN_closeH
+EN_solveQ, EN_openQ, EN_initQ, EN_runQ, EN_nextQ, EN_closeQ
+EN_report, EN_setreport, EN_writeline, EN_geterror
+EN_getoption, EN_setoption, EN_gettimeparam, EN_settimeparam
+EN_addnode, EN_addlink, EN_getnodevalue, EN_setnodevalue
+Learn how to use EPANET with practical code examples and network models
+Run a complete hydraulic simulation with EPANET Toolkit:
+#include
+#include
+
+int main() {
+ EN_Project ph;
+ int errcode;
+
+ // Create a new EPANET project
+ errcode = EN_createproject(&ph);
+ if (errcode != 0) {
+ printf("Error creating project: %d\n", errcode);
+ return 1;
+ }
+
+ // Open an existing network file
+ errcode = EN_open(ph, "Net1.inp", "Net1.rpt", "Net1.out");
+ if (errcode != 0) {
+ printf("Error opening file: %d\n", errcode);
+ EN_deleteproject(ph);
+ return 1;
+ }
+
+ // Run hydraulic analysis
+ errcode = EN_solveH(ph);
+ if (errcode != 0) {
+ printf("Error in hydraulic analysis: %d\n", errcode);
+ }
+
+ // Generate report
+ EN_report(ph);
+
+ // Clean up
+ EN_deleteproject(ph);
+ return 0;
+}
+ Run a water quality simulation with chlorine decay analysis:
+#include
+
+int main() {
+ EN_Project ph;
+
+ // Create and open project
+ EN_createproject(&ph);
+ EN_open(ph, "Net1.inp", "quality.rpt", "quality.out");
+
+ // Run hydraulic analysis first
+ EN_solveH(ph);
+
+ // Run water quality analysis
+ EN_solveQ(ph);
+
+ // Generate report
+ EN_report(ph);
+
+ // Clean up
+ EN_deleteproject(ph);
+ return 0;
+}
+ Access intermediate hydraulic results during simulation:
+#include
+
+int main() {
+ EN_Project ph;
+ long t, tstep;
+ double pressure, flow;
+ int nodeIndex, linkIndex;
+
+ // Create and open project
+ EN_createproject(&ph);
+ EN_open(ph, "Net1.inp", "Net1.rpt", "");
+
+ // Open hydraulic solver
+ EN_openH(ph);
+ EN_initH(ph, EN_SAVE); // Save intermediate results
+
+ // Run extended period simulation
+ do {
+ EN_runH(ph, &t);
+
+ // Get node pressure at current time
+ nodeIndex = 1; // Node 1
+ EN_getnodevalue(ph, nodeIndex, EN_PRESSURE, &pressure);
+
+ // Get link flow at current time
+ linkIndex = 1; // Link 1
+ EN_getlinkvalue(ph, linkIndex, EN_FLOW, &flow);
+
+ printf("Time: %ld, Pressure: %.2f, Flow: %.2f\n", t, pressure, flow);
+
+ EN_nextH(ph, &tstep);
+ } while (tstep > 0);
+
+ EN_closeH(ph);
+ EN_deleteproject(ph);
+ return 0;
+}
+ Modify network elements programmatically:
+#include
+
+int main() {
+ EN_Project ph;
+ int nodeIndex;
+ double newDemand;
+
+ // Create and open project
+ EN_createproject(&ph);
+ EN_open(ph, "Net1.inp", "Net1.rpt", "");
+
+ // Get node index by ID
+ EN_getnodeindex(ph, "11", &nodeIndex);
+
+ // Modify node demand
+ newDemand = 200.0; // GPM
+ EN_setnodevalue(ph, nodeIndex, EN_BASEDEMAND, newDemand);
+
+ // Save modified network
+ EN_saveinpfile(ph, "modified_network.inp");
+
+ // Run analysis on modified network
+ EN_solveH(ph);
+ EN_solveQ(ph);
+ EN_report(ph);
+
+ EN_deleteproject(ph);
+ return 0;
+}
+ Create a water network programmatically without an input file:
+#include
+
+int main() {
+ EN_Project ph;
+ int j1, j2, p1, t1, r1;
+
+ // Create a new project
+ EN_createproject(&ph);
+
+ // Initialize project with units and headloss formula
+ EN_init(ph, "report.rpt", "output.out",
+ EN_GPM, EN_HW); // GPM, Hazen-Williams
+
+ // Add nodes
+ EN_addnode(ph, "J1", EN_JUNCTION, &j1);
+ EN_addnode(ph, "J2", EN_JUNCTION, &j2);
+ EN_addnode(ph, "Tank1", EN_TANK, &t1);
+ EN_addnode(ph, "Reservoir1", EN_RESERVOIR, &r1);
+
+ // Set node properties
+ EN_setjuncdata(ph, j1, 100.0, 100.0, ""); // Elev, Demand
+ EN_setjuncdata(ph, j2, 95.0, 100.0, "");
+
+ // Add links (pipes)
+ EN_addlink(ph, "P1", EN_PIPE, "J1", "J2", &p1);
+
+ // Set link properties
+ EN_setlinkvalue(ph, p1, EN_LENGTH, 1000.0);
+ EN_setlinkvalue(ph, p1, EN_DIAMETER, 12.0);
+ EN_setlinkvalue(ph, p1, EN_ROUGHNESS, 0.1);
+
+ // Run analysis
+ EN_solveH(ph);
+ EN_report(ph);
+
+ EN_deleteproject(ph);
+ return 0;
+}
+ Pre-built example networks are available in the example-networks directory:
These networks demonstrate various features of EPANET including:
+Industry-Standard Software for Modeling Hydraulic and Water Quality Behavior of Water Distribution Systems
+ +
+ Model steady-state and extended period simulations of water flow, pressure, and tank levels.
+Analyze the fate and transport of chemical constituents and trace the source of contamination.
+Programmatic access to EPANET's engine for custom applications in C/C++.
+Model complex water distribution networks with pumps, valves, tanks, and pipes.
+Evaluate system performance under various operating conditions and demand patterns.
+Community-driven development with contributions from researchers and practitioners worldwide.
+EPANET is an industry-standard program for modeling the hydraulic and water quality behavior of water distribution system pipe networks. Originally developed by the U.S. Environmental Protection Agency (USEPA), it is now maintained by the Open Water Analytics (OWA) community.
+The EPANET Programmer's Toolkit is a library of functions (or API) written in C that allows programmers to customize the use of EPANET's solution engine for their own applications.
+ Learn More +// C Example - Simple EPANET Analysis
+#include
+
+int main() {
+ EN_Project ph;
+ EN_createproject(&ph);
+ EN_open(ph, "network.inp", "network.rpt", "network.out");
+ EN_solveH(ph); // Run hydraulic analysis
+ EN_solveQ(ph); // Run water quality analysis
+ EN_report(ph); // Generate report
+ EN_deleteproject(ph);
+ return 0;
+}
+ Use the Toolkit API to integrate EPANET into your applications. See the Documentation for more details.
+Contribute to EPANET development, report issues, or get help from the community.
+ +