### SWMM Build and Install with CMake (Bash) Source: https://context7.com/usepa/stormwater-management-model/llms.txt Instructions for compiling and installing the SWMM solver library and associated tools using CMake. This process allows for cross-platform development and customization through various CMake options. The guide covers configuration, building, testing, installation, and provides examples for linking the library and enabling OpenMP. ```bash # Create build directory mkdir build cd build # Configure with CMake (basic configuration) cmake .. # Configure with options cmake -DCMAKE_BUILD_TYPE=Release \ -DBUILD_TESTS=ON \ -DCMAKE_INSTALL_PREFIX=/usr/local \ .. # Build the project cmake --build . --config Release # Run tests (if BUILD_TESTS=ON) ctest --output-on-failure # Install binaries and libraries cmake --install . # Generated outputs: # - lib/libswmm5.so (or swmm5.dll on Windows) - Main solver library # - lib/libswmm-output.so - Output file reader library # - bin/runswmm - Command-line executable # - include/swmm5.h - Solver API header # - include/swmm_output.h - Output API header # Create distribution package cpack # Example: Link against SWMM in your own project gcc -o myapp myapp.c -I/usr/local/include -L/usr/local/lib -lswmm5 -lm # Example: Compile with OpenMP support for parallel processing cmake -DCMAKE_C_FLAGS="-fopenmp" .. cmake --build . ``` -------------------------------- ### Access SWMM System Properties and Run Simulation using C Source: https://context7.com/usepa/stormwater-management-model/llms.txt This snippet demonstrates retrieving simulation-wide settings and time information, and running a SWMM simulation. It requires 'swmm5.h' and 'stdio.h'. The code opens SWMM input/report/output files, retrieves configuration details (start date, time steps, flow units), decodes the start date, prints SWMM version, starts the simulation, steps through it while monitoring elapsed time, ends the simulation, generates a report, and closes the files. ```c #include "swmm5.h" #include int main() { int error; double elapsedTime; error = swmm_open("example.inp", "example.rpt", "example.out"); if (error) return error; // Get system properties before starting double startDate = swmm_getValue(swmm_STARTDATE, 0); double routeStep = swmm_getValue(swmm_ROUTESTEP, 0); double reportStep = swmm_getValue(swmm_REPORTSTEP, 0); int flowUnits = (int)swmm_getValue(swmm_FLOWUNITS, 0); // Decode the start date int year, month, day, hour, minute, second, dayOfWeek; swmm_decodeDate(startDate, &year, &month, &day, &hour, &minute, &second, &dayOfWeek); printf("Simulation Configuration:\n"); printf(" Start Date: %04d-%02d-%02d %02d:%02d:%02d\n", year, month, day, hour, minute, second); printf(" Routing Time Step: %.0f seconds\n", routeStep); printf(" Report Time Step: %.0f seconds\n", reportStep); const char *flowUnitStr[] = {"CFS", "GPM", "MGD", "CMS", "LPS", "MLD"}; printf(" Flow Units: %s\n", flowUnitStr[flowUnits]); // Get version information int version = swmm_getVersion(); int major = version / 10000; int minor = (version - 10000 * major) / 1000; int release = version - 10000 * major - 1000 * minor; printf(" SWMM Version: %d.%d.%d\n", major, minor, release); error = swmm_start(1); if (error) { swmm_close(); return error; } // Monitor elapsed time during simulation int steps = 0; do { error = swmm_step(&elapsedTime); steps++; if (steps % 1000 == 0) { double currentDate = swmm_getValue(swmm_CURRENTDATE, 0); swmm_decodeDate(currentDate, &year, &month, &day, &hour, &minute, &second, &dayOfWeek); printf("Progress: %04d-%02d-%02d %02d:%02d (%.1f hours elapsed)\n", year, month, day, hour, minute, elapsedTime / 3600.0); } } while (elapsedTime > 0 && !error); swmm_end(); swmm_report(); swmm_close(); return 0; } ``` -------------------------------- ### System Libraries and CPack Installer Configuration Source: https://github.com/usepa/stormwater-management-model/blob/develop/CMakeLists.txt Configures the installation of OpenMP runtime libraries and includes the 'InstallRequiredSystemLibraries' module. It also sets up CPack for generating an installer package, specifying 'ZIP' as the generator and 'US_EPA' as the vendor. ```cmake # Create install rules for vcruntime.dll, msvcp.dll, vcomp.dll etc. set(CMAKE_INSTALL_OPENMP_LIBRARIES TRUE) include(InstallRequiredSystemLibraries) # Configure CPack driven installer package set(CPACK_GENERATOR "ZIP") set(CPACK_PACKAGE_VENDOR "US_EPA") set(CPACK_ARCHIVE_FILE_NAME "swmm") include(CPack) ``` -------------------------------- ### CMake: Install SWMM Library and Headers Source: https://github.com/usepa/stormwater-management-model/blob/develop/src/solver/CMakeLists.txt This CMake code defines the installation rules for the `swmm5` library and its associated header files. It specifies the destinations for runtime, library, archive, and framework files, as well as the installation path for public headers. ```cmake install(TARGETS swmm5 EXPORT swmm5Targets RUNTIME DESTINATION "${TOOL_DIST}" LIBRARY DESTINATION "${TOOL_DIST}" ARCHIVE DESTINATION "${LIBRARY_DIST}" FRAMEWORK DESTINATION "${TOOL_DIST}" ) # Create target import scripts so other cmake projects can use swmm libraries install( EXPORT swmm5Targets DESTINATION "${CONFIG_DIST}" FILE swmm5-config.cmake ) install( FILES ${SWMM_PUBLIC_HEADERS} DESTINATION "${INCLUDE_DIST}" ) ``` -------------------------------- ### SWMM Control Rule - Arithmetic Expressions Example Source: https://github.com/usepa/stormwater-management-model/blob/develop/doc/New SWMM 5.2 Features.md Illustrates the use of arithmetic expressions within SWMM control rule conditions. Named variables are combined using mathematical operators and functions to define complex conditions. ```swmm [RULES] VARIABLE Q1 = LINK 1 FLOW VARIABLE Q2 = LINK 2 FLOW VARIABLE Q3 = Link 3 FLOW EXPRESSION Net_Inflow = (Q1 + Q2)/2 - Q3 RULE 1 IF Net_Inflow > 0.1 THEN ORIFICE 3 SETTING = 1 ELSE ORIFICE 3 SETTING = 0.5 ``` -------------------------------- ### SWMM Control Rule - Named Variables Example Source: https://github.com/usepa/stormwater-management-model/blob/develop/doc/New SWMM 5.2 Features.md Demonstrates the use of named variables in SWMM control rules to create aliases for object attributes. This simplifies rule definitions, especially when referencing the same attributes multiple times. ```swmm [RULES] VARIABLE Dabc = NODE abc DEPTH VARIABLE Defg = NODE efg DEPTH VARIABLE P45 = PUMP 45 STATUS RULE 1 IF Dabc > Defg AND P45 = OFF THEN PUMP 45 STATUS = ON RULE 2 IF Dabc < 1 THEN PUMP 45 STATUS = OFF ``` -------------------------------- ### SWMM Solver Subdirectory and Testing Setup Source: https://github.com/usepa/stormwater-management-model/blob/develop/CMakeLists.txt Includes subdirectories for 'outfile', 'solver', and 'run' components of the SWMM project. If 'BUILD_TESTS' is enabled, it also enables testing and includes the 'tests' subdirectory. ```cmake # Add project subdirectories add_subdirectory(src/outfile) add_subdirectory(src/solver) add_subdirectory(src/run) if(BUILD_TESTS) enable_testing() add_subdirectory(tests) endif() ``` -------------------------------- ### Build SWMM runswmm Executable with CMake Source: https://github.com/usepa/stormwater-management-model/blob/develop/src/run/CMakeLists.txt This CMake code defines the build process for the 'runswmm' executable. It adds the main C source file, specifies public include directories, links against the 'swmm5' library, and defines installation rules. A post-build custom command is included to copy the generated executable to a specific location within the build directory for testing purposes. ```cmake add_executable(runswmm main.c ) target_include_directories(runswmm PUBLIC include ) target_link_libraries(runswmm LINK_PUBLIC swmm5 ) install(TARGETS runswmm DESTINATION "${TOOL_DIST}" ) # copy runswmm to build tree for testing add_custom_command(TARGET runswmm POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy $ ${CMAKE_BINARY_DIR}/bin/$/$ ) ``` -------------------------------- ### CMake: Link Libraries and Include Directories Source: https://github.com/usepa/stormwater-management-model/blob/develop/src/solver/CMakeLists.txt This CMake snippet configures the linking of libraries and the inclusion of directories for the `swmm5` target. It links against the math library (`m`) on non-MSVC systems, OpenMP, and specifies public include directories for build and installation. ```cmake target_link_libraries(swmm5 PUBLIC $<$>>:m> $<$:OpenMP::OpenMP_C> ) target_include_directories(swmm5 PUBLIC $ $ ) ``` -------------------------------- ### Configure SWMM Output Library Build with CMake Source: https://github.com/usepa/stormwater-management-model/blob/develop/src/outfile/CMakeLists.txt This CMake script defines the build process for the swmm-output shared library. It specifies source files, public header directories, and includes mechanisms for generating export headers and installing the library and its components. ```cmake # configure file groups set(SWMM_OUT_PUBLIC_HEADERS include/swmm_output.h include/swmm_output_enums.h include/swmm_output_export.h ) # the binary output file API add_library(swmm-output SHARED swmm_output.c errormanager.c ) target_include_directories(swmm-output PUBLIC $ $ ) include(GenerateExportHeader) generate_export_header(swmm-output BASE_NAME swmm_output EXPORT_MACRO_NAME EXPORT_OUT_API EXPORT_FILE_NAME swmm_output_export.h STATIC_DEFINE SHARED_EXPORTS_BUILT_AS_STATIC ) file(COPY ${CMAKE_CURRENT_BINARY_DIR}/swmm_output_export.h DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}/include ) install(TARGETS swmm-output EXPORT swmm-outputTargets RUNTIME DESTINATION "${TOOL_DIST}" LIBRARY DESTINATION "${TOOL_DIST}" ARCHIVE DESTINATION "${LIBRARY_DIST}" FRAMEWORK DESTINATION "${TOOL_DIST}" ) install( EXPORT swmm-outputTargets DESTINATION "${CONFIG_DIST}" FILE swmm-output-config.cmake ) install( FILES ${SWMM_OUT_PUBLIC_HEADERS} DESTINATION "${INCLUDE_DIST}" ) # copy epanet-output to build tree for testing if(BUILD_TESTS) add_custom_command(TARGET swmm-output POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy $ ${CMAKE_BINARY_DIR}/bin/$/$ ) endif() ``` -------------------------------- ### Step-by-Step SWMM Simulation Control (C) Source: https://context7.com/usepa/stormwater-management-model/llms.txt Provides fine-grained control over SWMM simulation execution, allowing for real-time monitoring and modification of parameters. This approach involves opening the project, starting the simulation, stepping through time, querying node/link values, setting link parameters (like pump settings), and finally ending and closing the simulation. ```c #include "swmm5.h" #include int main() { int error; double elapsedTime; int stepCount = 0; // Open the SWMM project and read input data error = swmm_open("example.inp", "example.rpt", "example.out"); if (error) { printf("Error opening SWMM project\n"); return error; } // Start the simulation (1 = save results to binary output file) error = swmm_start(1); if (error) { printf("Error starting simulation\n"); swmm_close(); return error; } // Step through the simulation one routing time step at a time do { error = swmm_step(&elapsedTime); if (error) break; stepCount++; // Query current conditions at node 0 double nodeDepth = swmm_getValue(swmm_NODE_DEPTH, 0); double nodeFlow = swmm_getValue(swmm_NODE_INFLOW, 0); // Monitor and adjust pump settings based on conditions if (nodeDepth > 5.0) { // Turn on pump 0 if depth exceeds 5 feet swmm_setValue(swmm_LINK_SETTING, 0, 1.0); } else if (nodeDepth < 2.0) { // Turn off pump 0 if depth drops below 2 feet swmm_setValue(swmm_LINK_SETTING, 0, 0.0); } // Log status every 100 steps if (stepCount % 100 == 0) { printf("Step %d: Time=%.2f hrs, Depth=%.2f ft, Flow=%.2f CFS\n", stepCount, elapsedTime / 3600.0, nodeDepth, nodeFlow); } } while (elapsedTime > 0 && !error); // End the simulation and clean up swmm_end(); swmm_report(); swmm_close(); printf("Simulation completed after %d time steps\n", stepCount); return error; } ``` -------------------------------- ### Read SWMM Binary Output Files using C Source: https://context7.com/usepa/stormwater-management-model/llms.txt This C code demonstrates how to initialize the SWMM output library, open a binary output file, and extract various simulation results including metadata, time series data for nodes and links, and specific element attributes at a given time. It requires the 'swmm_output.h' header and associated library. The output includes version information, project size, flow units, simulation times, element names, time series statistics (max/avg depth, max/min flow), and detailed node results at a specific time index. ```c #include "swmm_output.h" #include #include int main() { SMO_Handle handle; int error; // Initialize and open output file error = SMO_init(&handle); if (error) { printf("Failed to initialize handle\n"); return error; } error = SMO_open(handle, "example.out"); if (error) { printf("Failed to open output file\n"); return error; } // Get file metadata int version; SMO_getVersion(handle, &version); printf("Output file version: %d\n", version); // Get project size information int *projectSize; int length; SMO_getProjectSize(handle, &projectSize, &length); printf("Project has %d subcatchments, %d nodes, %d links, %d pollutants\n", projectSize[0], projectSize[1], projectSize[2], projectSize[3]); // Get flow units int flowUnits; SMO_getFlowUnits(handle, &flowUnits); const char *unitStr[] = {"CFS", "GPM", "MGD", "CMS", "LPS", "MLD"}; printf("Flow units: %s\n", unitStr[flowUnits]); // Get simulation timing double startDate; int reportStep, numPeriods; SMO_getStartDate(handle, &startDate); SMO_getTimes(handle, SMO_reportStep, &reportStep); SMO_getTimes(handle, SMO_numPeriods, &numPeriods); printf("Report step: %d seconds, Number of periods: %d\n", reportStep, numPeriods); // Get element name char *nodeName; int nameSize; int nodeIndex = 5; SMO_getElementName(handle, SMO_node, nodeIndex, &nodeName, &nameSize); printf("Node %d name: %s\n", nodeIndex, nodeName); SMO_free((void**)&nodeName); // Extract time series for node depth float *depthSeries; int seriesLength; error = SMO_getNodeSeries(handle, nodeIndex, SMO_invert_depth, 0, numPeriods-1, &depthSeries, &seriesLength); if (!error) { printf("\nDepth time series for node %d:\n", nodeIndex); // Calculate statistics float maxDepth = 0.0; float sumDepth = 0.0; for (int i = 0; i < seriesLength; i++) { if (depthSeries[i] > maxDepth) maxDepth = depthSeries[i]; sumDepth += depthSeries[i]; } float avgDepth = sumDepth / seriesLength; printf(" Maximum depth: %.2f ft\n", maxDepth); printf(" Average depth: %.2f ft\n", avgDepth); printf(" Number of data points: %d\n", seriesLength); // Print first 10 values printf(" First 10 values: "); for (int i = 0; i < 10 && i < seriesLength; i++) { printf("%.2f ", depthSeries[i]); } printf("\n"); SMO_free((void**)&depthSeries); } // Get results for all nodes at a specific time int timeIndex = 100; float *nodeResults; int resultLength; error = SMO_getNodeResult(handle, timeIndex, nodeIndex, &nodeResults, &resultLength); if (!error) { printf("\nAll attributes for node %d at time index %d:\n", nodeIndex, timeIndex); printf(" Depth: %.2f\n", nodeResults[0]); printf(" Head: %.2f\n", nodeResults[1]); printf(" Volume: %.2f\n", nodeResults[2]); printf(" Lateral Inflow: %.2f\n", nodeResults[3]); printf(" Total Inflow: %.2f\n", nodeResults[4]); printf(" Flooding: %.2f\n", nodeResults[5]); SMO_free((void**)&nodeResults); } // Extract link flow time series int linkIndex = 3; float *flowSeries; error = SMO_getLinkSeries(handle, linkIndex, SMO_flow_rate_link, 0, numPeriods-1, &flowSeries, &seriesLength); if (!error) { printf("\nFlow statistics for link %d:\n", linkIndex); float maxFlow = 0.0; float minFlow = flowSeries[0]; for (int i = 0; i < seriesLength; i++) { if (flowSeries[i] > maxFlow) maxFlow = flowSeries[i]; if (flowSeries[i] < minFlow) minFlow = flowSeries[i]; } printf(" Maximum flow: %.2f %s\n", maxFlow, unitStr[flowUnits]); printf(" Minimum flow: %.2f %s\n", minFlow, unitStr[flowUnits]); SMO_free((void**)&flowSeries); } // Close and clean up SMO_close(&handle); SMO_free((void**)&projectSize); printf("\nOutput file analysis complete\n"); return 0; } ``` -------------------------------- ### Configure test_output Executable Build with CMake Source: https://github.com/usepa/stormwater-management-model/blob/develop/tests/outfile/CMakeLists.txt This snippet defines the build process for the 'test_output' executable using CMake. It lists the source file (test_output.cpp), specifies public include directories for the output module, links against Boost libraries and the 'swmm-output' library, and sets the runtime output directory for the executable. ```cmake add_executable(test_output test_output.cpp ) target_include_directories(test_output PUBLIC ../../outfile/include ) target_link_libraries(test_output ${Boost_LIBRARIES} swmm-output ) set_target_properties(test_output PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) ``` -------------------------------- ### Run SWMM Simulations via Command Line (Bash) Source: https://context7.com/usepa/stormwater-management-model/llms.txt This section illustrates how to execute SWMM simulations directly from the command line using the standalone executable 'runswmm'. It covers basic simulation execution by specifying input, report, and output files. It also shows how to run a simulation without saving binary output and how to display version and help information using command-line flags. ```bash # Basic simulation with all files specified runswmm input.inp report.rpt output.out # Simulation without saving binary output runswmm model.inp results.rpt # Display version information runswmm --version # Output: 5.2.4 # Display help information runswmm --help # Output: # STORMWATER MANAGEMENT MODEL (SWMM) HELP # # COMMANDS: # --help (-h) SWMM Help # --version (-v) Build Version # # RUNNING A SIMULATION: ``` -------------------------------- ### Include Boost Library (CMake) Source: https://github.com/usepa/stormwater-management-model/blob/develop/tests/CMakeLists.txt This snippet includes the Boost library configuration, likely needed for compiling the SWMM solver or its tests. It assumes a `boost.cmake` file exists in the `extern` subdirectory. ```cmake include(../extern/boost.cmake) ``` -------------------------------- ### CMake: Custom Command to Copy Library for Testing Source: https://github.com/usepa/stormwater-management-model/blob/develop/src/solver/CMakeLists.txt This CMake snippet adds a custom command to the `swmm5` target that executes after the build. It uses `cmake -E copy` to copy the built library to a specific location within the binary directory for testing purposes. ```cmake # copy swmm5 to build tree for testing add_custom_command(TARGET swmm5 POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy $ ${CMAKE_BINARY_DIR}/bin/$/$ ) ``` -------------------------------- ### CMake Minimum Version and Build Directory Check Source: https://github.com/usepa/stormwater-management-model/blob/develop/CMakeLists.txt Ensures the CMake version is sufficient and prevents in-source builds by checking if the binary directory is the same as the source directory. It will raise a fatal error if the condition is met. ```cmake cmake_minimum_required (VERSION 3.13) if("${CMAKE_BINARY_DIR}" STREQUAL "${CMAKE_SOURCE_DIR}") message(FATAL_ERROR "In-source builds are disabled.") endif() ``` -------------------------------- ### SWMM Input File STORAGE Section for New Shapes Source: https://github.com/usepa/stormwater-management-model/blob/develop/doc/New SWMM 5.2 Features.md Defines how to specify conical and pyramidal storage units in the SWMM input file's STORAGE section. It includes parameters for node, elevation, depths, shape type, base dimensions, side slope, evaporation, and infiltration. ```ini [STORAGE] node elev maxDepth initDepth CONICAL L W Z 0 fEvap (infil) node elev maxDepth initDepth PYRAMIDAL L W Z 0 fEvap (infil) ``` -------------------------------- ### Add Test Case (CMake) Source: https://github.com/usepa/stormwater-management-model/blob/develop/tests/CMakeLists.txt Registers a test named 'test_output' to be run by CTest. The test executes the 'test_output' program located in the previously defined test binary directory and sets its working directory to the test data folder. ```cmake add_test( NAME test_output COMMAND "${TEST_BIN_DIRECTORY}/test_output" WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/outfile/data ) ``` -------------------------------- ### Build Configuration Options for SWMM Solver Source: https://github.com/usepa/stormwater-management-model/blob/develop/CMakeLists.txt Sets build options for the SWMM solver, including 'BUILD_TESTS' which requires Boost and 'BUILD_DEF' for a library with a def file interface. These options are initially set to OFF. ```cmake # Define build options option(BUILD_TESTS "Builds component tests (requires Boost)" OFF) option(BUILD_DEF "Builds library with def file interface" OFF) ``` -------------------------------- ### CMake: Build SWMM Shared Library Source: https://github.com/usepa/stormwater-management-model/blob/develop/src/solver/CMakeLists.txt This CMake snippet demonstrates conditional building of the `swmm5` shared library. If `BUILD_DEF` is true, it includes a DEF file for backward compatibility; otherwise, it builds the library with just the source files. ```cmake if(BUILD_DEF) # Build library with def file interface for backward compatibility set_source_files_properties(${PROJECT_SOURCE_DIR}/bindings/swmm5.def PROPERTIES_HEADER_FILE_ONLY TRUE ) add_library(swmm5 SHARED ${SWMM_SOURCES} ${PROJECT_SOURCE_DIR}/bindings/swmm5.def ) else() add_library(swmm5 SHARED ${SWMM_SOURCES} ) endif() ``` -------------------------------- ### Define Inlet Structures (SWMM INLETS) Source: https://github.com/usepa/stormwater-management-model/blob/develop/doc/New SWMM 5.2 Features.md Defines the geometry and type of various inlet structures for use in SWMM projects. Supports GRATE, CURB, SLOTTED, and CUSTOM inlet types with specific parameters for each. Grate types include P_BAR-50, CURVED_VANE, TILT_BAR-45, RETICULINE, and GENERIC, among others. GENERIC grates require additional open area and splash over velocity parameters. ```swmm ; A 2-ft x 2-ft parallel bar grate InletType1 GRATE 2 2 P-BAR-30 ; A combination inlet InletType2 GRATE 2 2 CURVED_VANE InletType2 CURB 4 0.5 HORIZONTAL ; A custom inlet using Curve1 as its capture curve InletType3 CUSTOM Curve1 ``` -------------------------------- ### CMake: Configure OpenMP Dependency Source: https://github.com/usepa/stormwater-management-model/blob/develop/src/solver/CMakeLists.txt This snippet configures the CMake build system to find and use the OpenMP library. It sets the prefix path for OpenMP on Apple systems and then uses `find_package` to locate OpenMP components, requiring the C component. ```cmake if(APPLE) set( CMAKE_PREFIX_PATH ../../deps/openmp-16.0.0-Darwin/ ) endif() find_package( OpenMP COMPONENTS C REQUIRED ) ``` -------------------------------- ### SWMM Multi-Step Striding Simulation (C) Source: https://context7.com/usepa/stormwater-management-model/llms.txt Demonstrates how to advance a SWMM simulation by multiple time steps at once using the `swmm_stride` function. This is useful for faster execution when fine-grained control at every time step is not required. It includes error handling, retrieving simulation parameters like routing and report steps, and periodic status checks. ```c #include "swmm5.h" #include int main() { int error; double elapsedTime; int totalSteps = 0; error = swmm_open("example.inp", "example.rpt", "example.out"); if (error) return error; error = swmm_start(1); if (error) { swmm_close(); return error; } // Get the routing time step double routeStep = swmm_getValue(swmm_ROUTESTEP, 0); double reportStep = swmm_getValue(swmm_REPORTSTEP, 0); // Calculate stride: advance by 10 routing steps at once int strideSteps = 10; printf("Advancing simulation %d steps at a time\n", strideSteps); printf("Routing step: %.0f sec, Report step: %.0f sec\n", routeStep, reportStep); do { // Advance multiple steps with swmm_stride error = swmm_stride(strideSteps, &elapsedTime); if (error) break; totalSteps += strideSteps; // Check system status periodically if (totalSteps % 100 == 0) { // Get critical node status int criticalNode = 5; double depth = swmm_getValue(swmm_NODE_DEPTH, criticalNode); double inflow = swmm_getValue(swmm_NODE_INFLOW, criticalNode); printf("Step %d: Time=%.1f hrs, Node depth=%.2f ft, Inflow=%.2f CFS\n", totalSteps, elapsedTime / 3600.0, depth, inflow); // Take action if needed if (depth > 8.0) { printf("WARNING: Critical depth exceeded at node %d\n", criticalNode); // Could adjust pump settings or other controls here } } } while (elapsedTime > 0 && !error); printf("\nSimulation completed after %d total routing steps\n", totalSteps); swmm_end(); swmm_report(); swmm_close(); return 0; } ``` -------------------------------- ### Assign Inlet Structures to Conduits (SWMM INLET_USAGE) Source: https://github.com/usepa/stormwater-management-model/blob/develop/doc/New SWMM 5.2 Features.md Assigns previously defined inlet structures to specific street conduits and specifies their placement and characteristics. Key parameters include the conduit link, inlet name, receiving node, number of inlets, clogging percentage, maximum intercepted flow, and gutter depression details. Placement can be AUTOMATIC, ON_GRADE, or ON_SAG. Not all parameters are required, with defaults provided for optional values. ```swmm ; Example: Assign InletType1 to Conduit1, flowing to NodeA, with default settings Conduit1 InletType1 NodeA ; Example: Assign InletType2 to Conduit2, flowing to NodeB, with 5% clogging and max flow of 10 cfs Conduit2 InletType2 NodeB 1 5 10 ``` -------------------------------- ### CMake: MSVC Specific Compile and Link Options Source: https://github.com/usepa/stormwater-management-model/blob/develop/src/solver/CMakeLists.txt This CMake code sets compiler and linker options specifically for the MSVC compiler. It enables optimizations like Global Data Optimization (/GL) and fast floating-point model (/fp:fast) for Release configurations, and sets incremental Link-Time Code Generation (/LTCG:incremental). ```cmake target_compile_options(swmm5 PUBLIC $<$: $<$:/GL> $<$:/fp:fast> $<$:/Zi> > ) target_link_options(swmm5 PUBLIC $<$: $<$:/LTCG:incremental> > ) ``` -------------------------------- ### Project Definition and Module Path Configuration Source: https://github.com/usepa/stormwater-management-model/blob/develop/CMakeLists.txt Defines the project name as 'swmm-solver' with version 5.2.4, specifying C and CXX as supported languages. It also appends the local 'cmake' directory to the CMAKE_MODULE_PATH for module searching. ```cmake project(swmm-solver VERSION 5.2.4 LANGUAGES C CXX ) # Append local dir to module search path list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake) ``` -------------------------------- ### Add Subdirectory for Compilation (CMake) Source: https://github.com/usepa/stormwater-management-model/blob/develop/tests/CMakeLists.txt This command adds a subdirectory named 'outfile' to the current build. This is typically used to compile code within that subdirectory as part of the main project build. ```cmake add_subdirectory(outfile) ``` -------------------------------- ### Set Test Executable Directory (CMake) Source: https://github.com/usepa/stormwater-management-model/blob/develop/tests/CMakeLists.txt Defines the directory where test executables will be placed within the build tree. It uses CMake variables to create a configuration-specific subdirectory (e.g., `Debug` or `Release`). ```cmake set(TEST_BIN_DIRECTORY "${CMAKE_BINARY_DIR}/bin/$") ``` -------------------------------- ### CMake: Grouping Source and Header Files Source: https://github.com/usepa/stormwater-management-model/blob/develop/src/solver/CMakeLists.txt This CMake code snippet defines groups for SWMM's public header files and uses `file(GLOB)` to collect all C and header source files within the current directory. These collections are used later for building the library. ```cmake # configure file groups set(SWMM_PUBLIC_HEADERS include/swmm5.h ) file(GLOB SWMM_SOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.c *.h ) ``` -------------------------------- ### SWMM 5.2 C Error Handling and Simulation Diagnostics Source: https://context7.com/usepa/stormwater-management-model/llms.txt Demonstrates robust error checking and diagnostic retrieval during SWMM simulation execution. This includes opening the project, checking input processing warnings, stepping through the simulation with error detection, monitoring for flooding, ending the simulation, retrieving mass balance errors, generating a report, and closing the SWMM model. It highlights the use of `swmm_getError`, `swmm_getWarnings`, `swmm_step`, `swmm_getValue`, `swmm_getMassBalErr`, `swmm_report`, and `swmm_close`. ```c #include "swmm5.h" #include #include void checkError(const char *operation) { char errMsg[256]; int errCode = swmm_getError(errMsg, 256); if (errCode > 0) { printf("Error %d during %s: %s\n", errCode, operation, errMsg); } } int main() { int error; double elapsedTime; // Attempt to open project error = swmm_open("model.inp", "results.rpt", "output.out"); if (error) { checkError("opening project"); return error; } printf("Project opened successfully\n"); // Check warnings after input processing int warnings = swmm_getWarnings(); if (warnings > 0) { printf("WARNING: %d warnings issued during input processing\n", warnings); printf("Check report file for details\ "); } // Start simulation error = swmm_start(1); if (error) { checkError("starting simulation"); swmm_close(); return error; } printf("Simulation started\n"); // Run simulation with error checking int stepCount = 0; int errorCount = 0; do { error = swmm_step(&elapsedTime); if (error) { errorCount++; checkError("stepping simulation"); // Continue or abort based on error severity if (errorCount > 10) { printf("Too many errors, aborting simulation\n"); break; } } stepCount++; // Monitor for unusual conditions if (stepCount % 1000 == 0) { // Check for excessive flooding int nodeCount = swmm_getCount(swmm_NODE); int floodingNodes = 0; for (int i = 0; i < nodeCount; i++) { double overflow = swmm_getValue(swmm_NODE_OVERFLOW, i); if (overflow > 0.01) { floodingNodes++; } } if (floodingNodes > nodeCount * 0.2) { printf("WARNING: %.0f%% of nodes are flooding at time %.1f hrs\n", 100.0 * floodingNodes / nodeCount, elapsedTime / 3600.0); } } } while (elapsedTime > 0 && errorCount < 10); // End simulation and get mass balance error = swmm_end(); if (error) { checkError("ending simulation"); } // Check mass balance errors float runoffErr, flowErr, qualErr; swmm_getMassBalErr(&runoffErr, &flowErr, &qualErr); printf("\nSimulation Summary:\n"); printf(" Total time steps: %d\n", stepCount); printf(" Errors encountered: %d\n", errorCount); printf(" Mass Balance Errors:\n"); printf(" Runoff: %.3f%%\n", runoffErr); printf(" Flow routing: %.3f%%\n", flowErr); printf(" Quality routing: %.3f%%\n", qualErr); // Check if mass balance errors are acceptable if (fabs(runoffErr) > 1.0 || fabs(flowErr) > 1.0) { printf("WARNING: Mass balance errors exceed 1%%\n"); printf("Consider reducing time steps or checking input data\n"); } // Generate report error = swmm_report(); if (error) { checkError("generating report"); } else { printf("Report generated successfully\n"); } // Close and cleanup swmm_close(); return errorCount > 0 ? 1 : 0; } ``` -------------------------------- ### Run Complete SWMM Simulation (C) Source: https://context7.com/usepa/stormwater-management-model/llms.txt Executes an entire SWMM simulation using a single function, internally handling all file I/O and calculations. This method requires input, report, and output file paths as arguments. It returns an error code and can provide mass balance errors upon completion. ```c #include "swmm5.h" #include int main(int argc, char *argv[]) { int error; char errMsg[128]; // Run complete simulation with input file, report file, and binary output file error = swmm_run("example.inp", "example.rpt", "example.out"); if (error) { swmm_getError(errMsg, 128); printf("SWMM Error %d: %s\n", error, errMsg); return error; } // Check for warnings int warnings = swmm_getWarnings(); if (warnings > 0) { printf("Simulation completed with %d warnings\n", warnings); } // Get mass balance errors float runoffErr, flowErr, qualErr; swmm_getMassBalErr(&runoffErr, &flowErr, &qualErr); printf("Mass Balance Errors:\n"); printf(" Runoff: %.2f%%\n", runoffErr); printf(" Flow Routing: %.2f%%\n", flowErr); printf(" Quality Routing: %.2f%%\n", qualErr); return 0; } ``` -------------------------------- ### Pyramidal Storage Unit Surface Area Equation Source: https://github.com/usepa/stormwater-management-model/blob/develop/doc/New SWMM 5.2 Features.md Calculates the surface area of a truncated rectangular pyramid storage unit. It requires parameters for base length (L), base width (W), side slope (Z), and water depth. ```mathematics Area = L*W + (L+W)*Z*Depth + (2*Z*Depth)^2 ``` -------------------------------- ### Conical Storage Unit Surface Area Equation Source: https://github.com/usepa/stormwater-management-model/blob/develop/doc/New SWMM 5.2 Features.md Calculates the surface area of a truncated elliptical cone storage unit. It requires parameters for base major axis length (L), base minor axis width (W), side slope (Z), and water depth. ```mathematics Area = PI * (L*W/4 + W*Z*Depth + (W/L)*(Z*Depth)^2) ``` -------------------------------- ### Extract System-Wide SWMM Results (C) Source: https://context7.com/usepa/stormwater-management-model/llms.txt Uses the SWMM output library (swmm_output.h) to open an output file and extract system-wide time series data for rainfall, runoff, and flooding. It calculates key metrics such as total rainfall, peak intensity, peak runoff rate, total runoff volume, and flooding statistics. Requires the SWMM output library to be linked. ```c #include "swmm_output.h" #include int main() { SMO_Handle handle; int error; SMO_init(&handle); error = SMO_open(handle, "example.out"); if (error) return error; // Get timing information int numPeriods; SMO_getTimes(handle, SMO_numPeriods, &numPeriods); // Extract system-wide rainfall time series float *rainfallSeries; int length; error = SMO_getSystemSeries(handle, SMO_rainfall_system, 0, numPeriods-1, &rainfallSeries, &length); if (!error) { printf("System-Wide Rainfall Analysis:\n"); // Calculate total rainfall depth int reportStep; SMO_getTimes(handle, SMO_reportStep, &reportStep); double totalRainfall = 0.0; double peakIntensity = 0.0; int peakTime = 0; for (int i = 0; i < length; i++) { totalRainfall += rainfallSeries[i] * reportStep / 3600.0; // Convert to depth if (rainfallSeries[i] > peakIntensity) { peakIntensity = rainfallSeries[i]; peakTime = i; } } printf(" Total rainfall: %.2f inches\n", totalRainfall); printf(" Peak intensity: %.2f in/hr at time step %d\n", peakIntensity, peakTime); SMO_free((void**)&rainfallSeries); } // Extract system runoff flow float *runoffSeries; error = SMO_getSystemSeries(handle, SMO_runoff_flow, 0, numPeriods-1, &runoffSeries, &length); if (!error) { double peakRunoff = 0.0; double totalVolume = 0.0; int reportStep; SMO_getTimes(handle, SMO_reportStep, &reportStep); for (int i = 0; i < length; i++) { if (runoffSeries[i] > peakRunoff) peakRunoff = runoffSeries[i]; totalVolume += runoffSeries[i] * reportStep; } printf("\nSystem Runoff:\n"); printf(" Peak runoff rate: %.2f CFS\n", peakRunoff); printf(" Total runoff volume: %.2f cubic feet\n", totalVolume); SMO_free((void**)&runoffSeries); } // Get flood losses float *floodSeries; error = SMO_getSystemSeries(handle, SMO_flood_losses, 0, numPeriods-1, &floodSeries, &length); if (!error) { double totalFlooding = 0.0; int floodingPeriods = 0; for (int i = 0; i < length; i++) { if (floodSeries[i] > 0.01) { floodingPeriods++; totalFlooding += floodSeries[i]; } } printf("\nFlooding Analysis:\n"); printf(" Periods with flooding: %d of %d\n", floodingPeriods, length); printf(" Average flood rate when flooding: %.2f CFS\n", floodingPeriods > 0 ? totalFlooding / floodingPeriods : 0.0); SMO_free((void**)&floodSeries); } SMO_close(&handle); return 0; } ``` -------------------------------- ### Query SWMM Model Object Information using C Source: https://context7.com/usepa/stormwater-management-model/llms.txt This snippet demonstrates how to access SWMM model object counts, names, and indices. It requires including 'swmm5.h' and standard I/O libraries. The function opens a SWMM input file, retrieves counts for subcatchments, nodes, links, and rain gages, lists node details (name, type, elevation, max depth), and looks up a node by its name. ```c #include "swmm5.h" #include #include int main() { int error; error = swmm_open("example.inp", "example.rpt", ""); if (error) return error; // Get counts of different object types int numSubcatch = swmm_getCount(swmm_SUBCATCH); int numNodes = swmm_getCount(swmm_NODE); int numLinks = swmm_getCount(swmm_LINK); int numGages = swmm_getCount(swmm_GAGE); printf("Model Summary:\n"); printf(" Subcatchments: %d\n", numSubcatch); printf(" Nodes: %d\n", numNodes); printf(" Links: %d\n", numLinks); printf(" Rain Gages: %d\n", numGages); // List all node names and types printf("\nNode List:\n"); char nodeName[64]; for (int i = 0; i < numNodes; i++) { swmm_getName(swmm_NODE, i, nodeName, 64); double nodeType = swmm_getValue(swmm_NODE_TYPE, i); double elevation = swmm_getValue(swmm_NODE_ELEV, i); double maxDepth = swmm_getValue(swmm_NODE_MAXDEPTH, i); const char *typeStr; switch ((int)nodeType) { case swmm_JUNCTION: typeStr = "Junction"; break; case swmm_OUTFALL: typeStr = "Outfall"; break; case swmm_STORAGE: typeStr = "Storage"; break; case swmm_DIVIDER: typeStr = "Divider"; break; default: typeStr = "Unknown"; } printf(" %s: %s (Elev=%.2f, MaxDepth=%.2f)\n", nodeName, typeStr, elevation, maxDepth); } // Look up a specific node by name const char *targetNode = "J1"; int nodeIndex = swmm_getIndex(swmm_NODE, targetNode); if (nodeIndex >= 0) { printf("\nNode '%s' found at index %d\n", targetNode, nodeIndex); } else { printf("\nNode '%s' not found\n", targetNode); } swmm_close(); return 0; } ```