diff --git a/.github/workflows/build-and-test.yml b/.github/workflows/build-and-test.yml index 4414b2820..d51f8e40f 100644 --- a/.github/workflows/build-and-test.yml +++ b/.github/workflows/build-and-test.yml @@ -10,57 +10,39 @@ env: OMP_NUM_THREADS: 1 BUILD_HOME: build TEST_HOME: nrtests + PACKAGE_NAME: vcpkg-export-20220826-200052.1.0.0 + PKG_NAME: vcpkg-export-20220826-200052 jobs: unit_test: name: Build and unit test runs-on: windows-2019 + environment: testing defaults: run: shell: cmd - working-directory: ci-tools/windows steps: - name: Checkout repo uses: actions/checkout@v2 - - name: Checkout submodule - uses: actions/checkout@v2 - with: - repository: michaeltryby/ci-tools - path: ci-tools - - - name: Add tar.exe - if: ${{ runner.os == 'Windows' }} - shell: pwsh + - name: Install boost-test + env: + REMOTE_STORE: "https://nuget.pkg.github.com/michaeltryby/index.json" + USERNAME: michaeltryby run: | - "C:\Program Files\Git\usr\bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 - + nuget sources add -Name github -Source ${{ env.REMOTE_STORE }} -Username ${{ env.USERNAME }} -Password ${{ secrets.ACCESS_TOKEN }} + nuget install ${{env.PKG_NAME}} -Source github - - name: Cache boost - id: cache-boost - uses: actions/cache@v2 - env: - cache_paths: | - C:/ProgramData/chocolatey/lib/boost-* - C:/local/boost_* - pkg_file_hash: ${{ hashFiles('**/windows/packages.config') }} - with: - path: ${{ env.cache_paths }} - key: ${{ runner.os }}-cache-boost-${{ env.pkg_file_hash }} - restore-keys: | - ${{ runner.os }}-cache-boost- - ${{ runner.os }}-cache- - ${{ runner.os }}- - - - name: Install boost - if: steps.cache-boost.outputs.cache-hit != 'true' + - name: Build env: - pkg_cmnd: choco install -y packages.config - run: ${{ env.pkg_cmnd }} + TOOL_CHAIN_PATH: \scripts\buildsystems\vcpkg.cmake + run: | + cmake -B.\build -DBUILD_TESTS=ON -DCMAKE_TOOLCHAIN_FILE=.\${{env.PACKAGE_NAME}}${{env.TOOL_CHAIN_PATH}} . + cmake --build .\build --config DEBUG - - name: Build and unit test - run: make.cmd /t /g "Visual Studio 16 2019" + - name: Unit Test + run: ctest --test-dir .\build -C Debug --output-on-failure reg_test: @@ -98,7 +80,7 @@ jobs: - name: Before reg test env: NRTESTS_URL: https://github.com/USEPA/swmm-nrtestsuite - BENCHMARK_TAG: v2.1.0 + BENCHMARK_TAG: v2.2.0 run: before-nrtest.cmd ${{ env.BENCHMARK_TAG }} - name: Run reg test diff --git a/CMakeLists.txt b/CMakeLists.txt index 4e6e0154f..363c14739 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -17,7 +17,7 @@ endif() project(swmm-solver - VERSION 5.2.1 + VERSION 5.2.2 LANGUAGES C CXX ) diff --git a/Readme.txt b/Readme.txt index f092f1de5..7bbb52e66 100644 --- a/Readme.txt +++ b/Readme.txt @@ -1,8 +1,8 @@ -CONTENTS OF SWMM520_ENGINE.ZIP +CONTENTS OF SWMM522_ENGINE.ZIP ============================== The 'src' folder of this archive contains the C source code for -version 5.2.0 of the Storm Water Management Model's computational +version 5.2.2 of the Storm Water Management Model's computational engine. Consult the included 'Roadmap.txt' file for an overview of the various code modules. The code can be compiled into both a shared object library and a command line executable. Under Windows, the diff --git a/extern/boost.cmake b/extern/boost.cmake index 84d29175a..c512fb559 100644 --- a/extern/boost.cmake +++ b/extern/boost.cmake @@ -2,7 +2,7 @@ # CMakeLists.txt - CMake configuration file for swmm-solver/extern # # Created: March 16, 2020 -# Updated: May 21, 2020 +# Updated: Oct 19, 2022 # # Author: Michael E. Tryby # US EPA - ORD/CESER @@ -17,22 +17,12 @@ else() endif() -# Environment variable "BOOST_ROOT_X_XX_X" points to local install location -if(DEFINED ENV{BOOST_ROOT_1_74_0}) - set(BOOST_ROOT $ENV{BOOST_ROOT_1_74_0}) - -elseif(DEFINED ENV{BOOST_ROOT_1_72_0}) - set(BOOST_ROOT $ENV{BOOST_ROOT_1_72_0}) - -elseif(DEFINED ENV{BOOST_ROOT_1_67_0}) - set(BOOST_ROOT $ENV{BOOST_ROOT_1_67_0}) - -endif() - - -find_package(Boost 1.67.0 +find_package( + Boost COMPONENTS unit_test_framework ) -include_directories (${Boost_INCLUDE_DIRS}) +include_directories( + ${Boost_INCLUDE_DIRS} +) diff --git a/src/solver/consts.h b/src/solver/consts.h index 3cb4cd990..f3deb70ef 100644 --- a/src/solver/consts.h +++ b/src/solver/consts.h @@ -3,7 +3,7 @@ // // Project: EPA SWMM5 // Version: 5.2 -// Date: 06/01/22 (Build 5.2.1) +// Date: 10/18/22 (Build 5.2.2) // Author: L. Rossman // // Various Constants @@ -16,7 +16,7 @@ // General Constants //------------------ -#define VERSION 52001 +#define VERSION 52002 #define MAGICNUMBER 516114522 #define EOFMARK 0x1A // Use 0x04 for UNIX systems #define MAXTITLE 3 // Max. # title lines diff --git a/src/solver/inlet.c b/src/solver/inlet.c index 1ec914c4d..4defe127e 100644 --- a/src/solver/inlet.c +++ b/src/solver/inlet.c @@ -3,7 +3,7 @@ // // Project: EPA SWMM5 // Version: 5.2 -// Date: 06/01/22 (Build 5.2.1) +// Date: 10/08/22 (Build 5.2.2) // Author: L. Rossman // // Street/Channel Inlet Functions @@ -16,6 +16,8 @@ // // Build 5.2.1: // - Substitutes the constant BIG for HUGE. +// Build 5.2.2: +// - Additional statistics added to Street Flow Summary table. //----------------------------------------------------------------------------- #define _CRT_SECURE_NO_DEPRECATE @@ -1030,17 +1032,18 @@ void writeStreetStatsHeader() report_writeLine("*******************"); report_writeLine(""); fprintf(Frpt.file, -"\n ----------------------------------------------------------------------------------------------------------------------" -"\n Peak Maximum Maximum Peak Flow Average Bypass BackFlow" -"\n Flow Spread Depth Inlet Inlet Capture Capture Frequency Frequency"); +"\n ---------------------------------------------------------------------------------------------------------------------------------------" +"\n Peak Avg. Bypass Back Peak Peak" +"\n Peak Maximum Maximum Flow Flow Flow Flow Capture Bypass" +"\n Flow Spread Depth Inlet Inlet Inlet Capture Capture Freq Freq / Inlet Flow"); if (UnitSystem == US) fprintf(Frpt.file, -"\n Street Conduit %3s ft ft Design Location %% %% %% %%", - FlowUnitWords[FlowUnits]); +"\n Street Conduit %3s ft ft Design Location Count Pcnt Pcnt Pcnt Pcnt %3s %3s", + FlowUnitWords[FlowUnits], FlowUnitWords[FlowUnits], FlowUnitWords[FlowUnits]); else fprintf(Frpt.file, -"\n Street Conduit %3s m m Design Location %% %% %% %%", - FlowUnitWords[FlowUnits]); +"\n Street Conduit %3s m m Design Location Pcnt Pcnt Pcnt Pcnt %3s %3s", + FlowUnitWords[FlowUnits], FlowUnitWords[FlowUnits], FlowUnitWords[FlowUnits]); fprintf(Frpt.file, -"\n ----------------------------------------------------------------------------------------------------------------------"); +"\n ---------------------------------------------------------------------------------------------------------------------------------------"); } //============================================================================= @@ -1095,19 +1098,24 @@ void writeStreetStats(int link) fprintf(Frpt.file, " ON-GRADE"); else fprintf(Frpt.file, " ON-SAG "); + fprintf(Frpt.file, " %5d", inlet->numInlets); fp = inlet->stats.flowPeriods / 100.0; if (fp > 0.0) { cp = inlet->stats.capturePeriods / 100.0; - fprintf(Frpt.file, " %9.2f", inlet->stats.peakFlowCapture); + fprintf(Frpt.file, " %7.2f", inlet->stats.peakFlowCapture); if (cp > 0.0) { afc = inlet->stats.avgFlowCapture / cp; bpf = inlet->stats.bypassFreq / cp; } - fprintf(Frpt.file, " %9.2f", afc); - fprintf(Frpt.file, " %9.2f", bpf); - fprintf(Frpt.file, " %9.2f", inlet->stats.backflowPeriods / fp); + fprintf(Frpt.file, " %7.2f", afc); + fprintf(Frpt.file, " %7.2f", bpf); + fprintf(Frpt.file, " %7.2f", inlet->stats.backflowPeriods / fp); + fprintf(Frpt.file, " %7.2f", (maxFlow / Street[t].sides) * UCF(FLOW) * + 0.01 * inlet->stats.peakFlowCapture / inlet->numInlets); + fprintf(Frpt.file, " %7.2f", maxFlow * UCF(FLOW) * 0.01 * + (100.0 - inlet->stats.peakFlowCapture)); } } } diff --git a/src/solver/link.c b/src/solver/link.c index b93cdfbaa..052a030b9 100644 --- a/src/solver/link.c +++ b/src/solver/link.c @@ -3,7 +3,7 @@ // // Project: EPA SWMM5 // Version: 5.2 -// Date: 06/01/22 (Build 5.2.1) +// Date: 10/29/22 (Build 5.2.2) // Author: L. Rossman // M. Tryby (EPA) // @@ -44,6 +44,8 @@ // - Support added for variable speed pumps. // Build 5.2.1 // - Warning no longer issued when conduit elevation drop < MIN_DELTA_Z. +// Build 5.2.2: +// - Warning for conduit elevation drop < MIN_DELTA_Z restored. //----------------------------------------------------------------------------- #define _CRT_SECURE_NO_DEPRECATE @@ -1264,9 +1266,7 @@ double conduit_getSlope(int j) delta = fabs(elev1 - elev2); if ( delta < MIN_DELTA_Z ) { - /* Deprecated as of v.5.2.1 report_writeWarningMsg(WARN04, Link[j].ID); - */ delta = MIN_DELTA_Z; } diff --git a/src/solver/mathexpr.c b/src/solver/mathexpr.c index 2ce4d423d..c39dff7e1 100644 --- a/src/solver/mathexpr.c +++ b/src/solver/mathexpr.c @@ -6,9 +6,9 @@ ** operators. ** AUTHORS: L. Rossman, US EPA - NRMRL ** F. Shang, University of Cincinnati -** VERSION: 5.2.0 -** LAST UPDATE: 11/01/21 -** BUG FIXES: Problems related to '^' operator (L.Rossman, 11/01/21) +** VERSION: 5.2.2 +** LAST UPDATE: 09/02/2022 +** BUG FIXES: Problems related to '^' operator (F. Shang, 09/02/2022) ******************************************************************************/ /* ** Operand codes: @@ -34,12 +34,12 @@ ** 20 = acos ** 21 = atan ** 22 = acot -** 23 = sinh +** 23 = sinh ** 24 = cosh ** 25 = tanh ** 26 = coth ** 27 = log10 -** 28 = step (x<=0 ? 0 : 1) +** 28 = step (x<=0 ? 0 : 1) ** 31 = ^ ******************************************************************************/ #define _CRT_SECURE_NO_DEPRECATE @@ -190,6 +190,7 @@ double getNumber() char c[] = " "; char sNumber[255]; int errflag = 0; + int decimalCount = 0; /* --- get whole number portion of number */ sNumber[0] = '\0'; @@ -205,6 +206,8 @@ double getNumber() { if (S[Pos] == '.') { + decimalCount++; + if (decimalCount > 1) Err = 1; strcat(sNumber, "."); Pos++; while (Pos < Len && isDigit(S[Pos])) @@ -257,7 +260,7 @@ int getOperand() case '-': code = 4; if (Pos < Len-1 && isDigit(S[Pos+1]) && - (CurLex == 0 || CurLex == 1)) + (CurLex <= 6 || CurLex == 31)) { Pos++; Fvalue = -getNumber(); @@ -294,7 +297,7 @@ int getLex() n = getMathFunc(); if ( n == 0 ) n = getVariable(); } - else if ( isDigit(S[Pos]) ) + else if ( S[Pos] == '.' || isDigit(S[Pos]) ) { n = 7; Fvalue = getNumber(); @@ -330,6 +333,7 @@ ExprTree * getSingleOp(int *lex) { int opcode; ExprTree *left; + ExprTree *node; /* --- open parenthesis, so continue to grow the tree */ if ( *lex == 1 ) @@ -374,6 +378,17 @@ ExprTree * getSingleOp(int *lex) } } *lex = getLex(); + + /* --- exponentiation */ + if (*lex == 31) + { + node = newNode(); + node->left = left; + node->opcode = *lex; + *lex = getLex(); + node->right = getSingleOp(lex); + left = node; + } return left; } @@ -398,7 +413,7 @@ ExprTree * getOp(int *lex) else if ( *lex == 3) *lex = getLex(); } left = getSingleOp(lex); - while ( *lex == 5 || *lex == 6 || *lex == 31) + while ( *lex == 5 || *lex == 6) { opcode = *lex; *lex = getLex(); @@ -518,88 +533,88 @@ double mathexpr_eval(MathExpr *expr, double (*getVariableValue) (int)) case 3: r1 = ExprStack[stackindex]; stackindex--; - if (stackindex < 0) break; + if (stackindex < 0) break; r2 = ExprStack[stackindex]; ExprStack[stackindex] = r2 + r1; break; - case 4: - r1 = ExprStack[stackindex]; + case 4: + r1 = ExprStack[stackindex]; stackindex--; - if (stackindex < 0) break; + if (stackindex < 0) break; r2 = ExprStack[stackindex]; ExprStack[stackindex] = r2 - r1; break; - case 5: - r1 = ExprStack[stackindex]; + case 5: + r1 = ExprStack[stackindex]; stackindex--; - if (stackindex < 0) break; + if (stackindex < 0) break; r2 = ExprStack[stackindex]; ExprStack[stackindex] = r2 * r1; break; - case 6: + case 6: r1 = ExprStack[stackindex]; stackindex--; - if (stackindex < 0) break; - r2 = ExprStack[stackindex]; + if (stackindex < 0) break; + r2 = ExprStack[stackindex]; ExprStack[stackindex] = r2 / r1; break; - case 7: + case 7: stackindex++; - if (stackindex >= MAX_STACK_SIZE) break; + if (stackindex >= MAX_STACK_SIZE) break; ExprStack[stackindex] = node->fvalue; break; - case 8: - if (getVariableValue != NULL) - { - r1 = getVariableValue(node->ivar); - } - else r1 = 0.0; + case 8: + if (getVariableValue != NULL) + { + r1 = getVariableValue(node->ivar); + } + else r1 = 0.0; stackindex++; - if (stackindex >= MAX_STACK_SIZE) break; - ExprStack[stackindex] = r1; + if (stackindex >= MAX_STACK_SIZE) break; + ExprStack[stackindex] = r1; break; - case 9: + case 9: ExprStack[stackindex] = -ExprStack[stackindex]; break; - case 10: + case 10: r1 = ExprStack[stackindex]; r2 = cos(r1); ExprStack[stackindex] = r2; break; - case 11: + case 11: r1 = ExprStack[stackindex]; r2 = sin(r1); ExprStack[stackindex] = r2; break; - case 12: + case 12: r1 = ExprStack[stackindex]; r2 = tan(r1); ExprStack[stackindex] = r2; break; - case 13: + case 13: r1 = ExprStack[stackindex]; if (r1 == 0.0) r2 = 0.0; else r2 = 1.0/tan( r1 ); ExprStack[stackindex] = r2; break; - case 14: + case 14: r1 = ExprStack[stackindex]; r2 = fabs( r1 ); ExprStack[stackindex] = r2; break; - case 15: + case 15: r1 = ExprStack[stackindex]; if (r1 < 0.0) r2 = -1.0; else if (r1 > 0.0) r2 = 1.0; @@ -607,93 +622,93 @@ double mathexpr_eval(MathExpr *expr, double (*getVariableValue) (int)) ExprStack[stackindex] = r2; break; - case 16: + case 16: r1 = ExprStack[stackindex]; if (r1 < 0.0) r2 = 0.0; else r2 = sqrt( r1 ); ExprStack[stackindex] = r2; break; - case 17: + case 17: r1 = ExprStack[stackindex]; if (r1 <= 0) r2 = 0.0; else r2 = log(r1); ExprStack[stackindex] = r2; break; - case 18: + case 18: r1 = ExprStack[stackindex]; r2 = exp(r1); ExprStack[stackindex] = r2; break; - case 19: + case 19: r1 = ExprStack[stackindex]; r2 = asin( r1 ); ExprStack[stackindex] = r2; break; - case 20: + case 20: r1 = ExprStack[stackindex]; r2 = acos( r1 ); ExprStack[stackindex] = r2; break; - case 21: + case 21: r1 = ExprStack[stackindex]; r2 = atan( r1 ); ExprStack[stackindex] = r2; break; - case 22: + case 22: r1 = ExprStack[stackindex]; r2 = 1.57079632679489661923 - atan(r1); ExprStack[stackindex] = r2; break; - case 23: + case 23: r1 = ExprStack[stackindex]; r2 = (exp(r1)-exp(-r1))/2.0; ExprStack[stackindex] = r2; break; - case 24: + case 24: r1 = ExprStack[stackindex]; r2 = (exp(r1)+exp(-r1))/2.0; ExprStack[stackindex] = r2; break; - case 25: + case 25: r1 = ExprStack[stackindex]; r2 = (exp(r1)-exp(-r1))/(exp(r1)+exp(-r1)); ExprStack[stackindex] = r2; break; - case 26: + case 26: r1 = ExprStack[stackindex]; r2 = (exp(r1)+exp(-r1))/(exp(r1)-exp(-r1)); ExprStack[stackindex] = r2; break; - case 27: + case 27: r1 = ExprStack[stackindex]; if (r1 == 0.0) r2 = 0.0; else r2 = log10( r1 ); ExprStack[stackindex] = r2; break; - case 28: + case 28: r1 = ExprStack[stackindex]; if (r1 <= 0.0) r2 = 0.0; else r2 = 1.0; ExprStack[stackindex] = r2; break; - case 31: + case 31: r1 = ExprStack[stackindex]; - stackindex--; - if (stackindex < 0) break; - r2 = ExprStack[stackindex]; + stackindex--; + if (stackindex < 0) break; + r2 = ExprStack[stackindex]; if (r2 <= 0.0) r2 = 0.0; else r2 = pow(r2, r1); ExprStack[stackindex] = r2; @@ -741,9 +756,9 @@ MathExpr * mathexpr_create(char *formula, int (*getVar) (char *)) tree = getTree(); if (Bc == 0 && Err == 0) { - traverseTree(tree, &expr); - while (expr) - { + traverseTree(tree, &expr); + while (expr) + { result = expr; expr = expr->prev; } diff --git a/src/solver/node.c b/src/solver/node.c index 2b26ecd82..2c8fa2501 100644 --- a/src/solver/node.c +++ b/src/solver/node.c @@ -3,7 +3,7 @@ // // Project: EPA SWMM5 // Version: 5.2 -// Date: 06/01/22 (Build 5.2.1) +// Date: 10/29/22 (Build 5.2.2) // Author: L. Rossman // // Conveyance system node functions. @@ -34,6 +34,9 @@ // - Warning no longer issued when node full depth is increased to match // crown of highest connecting link. // - a2 term for paraboloid shaped storage units was corrected +// Build 5.2.2: +// - Warning restored for node full depth being increased to crown of highest +// connecting link. //----------------------------------------------------------------------------- #define _CRT_SECURE_NO_DEPRECATE @@ -204,12 +207,11 @@ void node_validate(int j) TDwfInflow* inflow; // --- see if full depth was increased to accommodate conduit crown -/* Deprecated as of v.5.2.1 if ( Node[j].fullDepth > Node[j].oldDepth && Node[j].oldDepth > 0.0 ) { report_writeWarningMsg(WARN02, Node[j].ID); } -*/ + // --- check that initial depth does not exceed max. depth if ( Node[j].initDepth > Node[j].fullDepth + Node[j].surDepth ) report_writeErrorMsg(ERR_NODE_DEPTH, Node[j].ID); diff --git a/src/solver/project.c b/src/solver/project.c index 609b55ce2..a5a20dbd8 100644 --- a/src/solver/project.c +++ b/src/solver/project.c @@ -3,7 +3,7 @@ // // Project: EPA SWMM5 // Version: 5.2 -// Date: 11/01/21 (Build 5.2.0) +// Date: 11/21/22 (Build 5.2.2) // Author: L. Rossman // // Project management functions. @@ -49,6 +49,9 @@ // - Support added for Streets and Inlets. // - Support added for RptFlags.disabled option. // - Object's rptFlag changed to record its index in output file. +// Build 5.2.2: +// - Default number of threads changed from OMP max. number to 1 +// to be consistent with User Manual. //----------------------------------------------------------------------------- #define _CRT_SECURE_NO_DEPRECATE @@ -865,7 +868,7 @@ void setDefaults() HeadTol = 0.0; // Force use of default head tolerance SysFlowTol = 0.05; // System flow tolerance for steady state LatFlowTol = 0.05; // Lateral flow tolerance for steady state - NumThreads = 0; // Number of parallel threads to use + NumThreads = 1; // Number of parallel threads to use NumEvents = 0; // Number of detailed routing events // Deprecated options diff --git a/src/solver/runoff.c b/src/solver/runoff.c index b8f9fb72b..080674fbb 100644 --- a/src/solver/runoff.c +++ b/src/solver/runoff.c @@ -3,7 +3,7 @@ // // Project: EPA SWMM5 // Version: 5.2 -// Date: 11/01/21 (Build 5.2.0) +// Date: 10/17/22 (Build 5.2.2) // Author: L. Rossman // M. Tryby // @@ -27,7 +27,9 @@ // Build 5.1.014: // - Fixed street sweeping bug. // Build 5.2.0: -// - Support added for saving rainfall amounts in previous 48 hours. +// - Support added for saving rainfall amounts in previous 48 hours. +// Build 5.2.2: +// - Fixed possible use of canSweep in runoff_execute() with no assigned value. //----------------------------------------------------------------------------- #define _CRT_SECURE_NO_DEPRECATE @@ -204,12 +206,12 @@ void runoff_execute() // --- see if street sweeping can occur on current date day = datetime_dayOfYear(currentDate); + canSweep = FALSE; if ( SweepStart <= SweepEnd ) { if ( day >= SweepStart && day <= SweepEnd ) canSweep = TRUE; } else if ( day <= SweepEnd || day >= SweepStart ) canSweep = TRUE; - else canSweep = FALSE; // --- get runoff time step (in seconds) runoffStep = runoff_getTimeStep(currentDate); diff --git a/src/solver/stats.c b/src/solver/stats.c index 65100ac09..a22a5c68d 100644 --- a/src/solver/stats.c +++ b/src/solver/stats.c @@ -592,7 +592,7 @@ void stats_updateNodeStats(int j, double tStep, DateTime aDate) k = Node[j].subIndex; StorageStats[k].avgVol += newVolume; StorageStats[k].evapLosses += - Storage[Node[j].subIndex].evapLoss; + Storage[Node[j].subIndex].evapLoss; StorageStats[k].exfilLosses += Storage[Node[j].subIndex].exfilLoss; diff --git a/src/solver/statsrpt.c b/src/solver/statsrpt.c index 3bd799b9f..52cc169eb 100644 --- a/src/solver/statsrpt.c +++ b/src/solver/statsrpt.c @@ -3,7 +3,7 @@ // // Project: EPA SWMM5 // Version: 5.2 -// Date: 06/01/22 (Build 5.2.1) +// Date: 11/19/22 (Build 5.2.2) // Author: L. Rossman // // Report writing functions for summary statistics. @@ -27,6 +27,9 @@ // - Fixes value used for total reporting time. // Build 5.2.1: // - Replaces the "3" in "ft3" and "m3" with ANSI superscript (\xB3). +// Build 5.2.2 +// - Calculation of % Evaporation and % Exfiltration losses for storage +// units was corrected. //----------------------------------------------------------------------------- #define _CRT_SECURE_NO_DEPRECATE @@ -511,7 +514,7 @@ void writeStorageVolumes() { int j, k, days, hrs, mins; double avgVol, maxVol, pctAvgVol, pctMaxVol; - double addedVol, pctEvapLoss, pctSeepLoss; + double pctEvapLoss, pctSeepLoss; if ( Nnodes[STORAGE] > 0 ) { @@ -522,16 +525,16 @@ void writeStorageVolumes() WRITE(""); fprintf(Frpt.file, -"\n --------------------------------------------------------------------------------------------------" -"\n Average Avg Evap Exfil Maximum Max Time of Max Maximum" -"\n Volume Pcnt Pcnt Pcnt Volume Pcnt Occurrence Outflow"); +"\n ------------------------------------------------------------------------------------------------" +"\n Average Avg Evap Exfil Maximum Max Time of Max Maximum" +"\n Volume Pcnt Pcnt Pcnt Volume Pcnt Occurrence Outflow"); if ( UnitSystem == US ) fprintf(Frpt.file, -"\n Storage Unit 1000 ft\xB3 Full Loss Loss 1000 ft\xB3 Full days hr:min "); +"\n Storage Unit 1000 ft\xB3 Full Loss Loss 1000 ft\xB3 Full days hr:min "); else fprintf(Frpt.file, -"\n Storage Unit 1000 m\xB3 Full Loss Loss 1000 m\xB3 Full days hr:min "); +"\n Storage Unit 1000 m\xB3 Full Loss Loss 1000 m\xB3 Full days hr:min "); fprintf(Frpt.file, "%3s", FlowUnitWords[FlowUnits]); fprintf(Frpt.file, -"\n --------------------------------------------------------------------------------------------------"); +"\n ------------------------------------------------------------------------------------------------"); for ( j = 0; j < Nobjects[NODE]; j++ ) { @@ -549,14 +552,13 @@ void writeStorageVolumes() } pctEvapLoss = 0.0; pctSeepLoss = 0.0; - addedVol = NodeInflow[j] + StorageStats[k].initVol; - if ( addedVol > 0.0 ) + if ( NodeInflow[j] > 0.0 ) { - pctEvapLoss = StorageStats[k].evapLosses / addedVol * 100.0; - pctSeepLoss = StorageStats[k].exfilLosses / addedVol * 100.0; + pctEvapLoss = StorageStats[k].evapLosses / NodeInflow[j] * 100.0; + pctSeepLoss = StorageStats[k].exfilLosses / NodeInflow[j] * 100.0; } - fprintf(Frpt.file, "%10.3f %4.0f %4.0f %4.0f %10.3f %4.0f", + fprintf(Frpt.file, "%10.3f %5.1f %5.1f %5.1f %10.3f %5.1f", avgVol*UCF(VOLUME)/1000.0, pctAvgVol, pctEvapLoss, pctSeepLoss, maxVol*UCF(VOLUME)/1000.0, pctMaxVol); diff --git a/src/solver/table.c b/src/solver/table.c index aced49e13..f5917cacb 100644 --- a/src/solver/table.c +++ b/src/solver/table.c @@ -3,7 +3,7 @@ // // Project: EPA SWMM5 // Version: 5.2 -// Date: 11/01/21 (Build 5.2.0) +// Date: 10/17/22 (Build 5.2.2) // Author: L. Rossman // // Table (curve and time series) functions. @@ -28,6 +28,8 @@ // - The table_getInverseArea function was renamed table_getStorageDepth and // was refactored. // - Support added for relative file names. +// Build 5.2.2: +// - Prevent re-reading a time series file from start once end is reached. //----------------------------------------------------------------------------- #define _CRT_SECURE_NO_DEPRECATE @@ -759,6 +761,13 @@ double table_tseriesLookup(TTable *table, double x, char extend) && table->x2 >= x && table->x1 != table->x2 ) return table_interpolate(x, table->x1, table->y1, table->x2, table->y2); + + // --- end of external time series file has been reached + if ( table->file.mode == USE_FILE && feof(table->file.file) ) + { + if (extend == TRUE) return table->y1; + else return 0; + } // --- x lies before current time bracket: // move to start of time series diff --git a/src/solver/text.h b/src/solver/text.h index 70bfc1f50..8448978c4 100644 --- a/src/solver/text.h +++ b/src/solver/text.h @@ -3,7 +3,7 @@ // // Project: EPA SWMM5 // Version: 5.2 -// Date: 06/01/22 (Build 5.2.1) +// Date: 10/18/22 (Build 5.2.2) // Author: L. Rossman // // Text strings @@ -25,7 +25,7 @@ #define FMT03 " There are errors.\n" #define FMT04 " There are warnings.\n" #define FMT08 \ - "\n EPA STORM WATER MANAGEMENT MODEL - VERSION 5.2 (Build 5.2.1)" + "\n EPA STORM WATER MANAGEMENT MODEL - VERSION 5.2 (Build 5.2.2)" #define FMT09 \ "\n ------------------------------------------------------------" #define FMT10 "\n" diff --git a/src/solver/xsect.c b/src/solver/xsect.c index 5ebab53c0..1a53d36e2 100644 --- a/src/solver/xsect.c +++ b/src/solver/xsect.c @@ -3,7 +3,7 @@ // // Project: EPA SWMM5 // Version: 5.2 -// Date: 11/01/21 (Build 5.2.0) +// Date: 10/17/22 (Build 5.2.2) // Author: L. Rossman // M. Tryby (EPA) // @@ -32,6 +32,8 @@ // - Width at full height set to 0 for closed rectangular shape. // Build 5.2.0: // - Support added for Street cross sections. +// Build 5.2.2: +// - Feasibility check added to Mod. Baskethandle & Rect.-Round shapes. //----------------------------------------------------------------------------- #define _CRT_SECURE_NO_DEPRECATE @@ -430,6 +432,7 @@ int xsect_setParams(TXsect *xsect, int type, double p[], double ucf) // --- depth of circular bottom xsect->yBot = xsect->rBot * (1.0 - cos(theta/2.0)); + if (xsect->yBot > xsect->yFull) return FALSE; xsect->ywMax = xsect->yFull; xsect->aFull = xsect->wMax * (xsect->yFull - xsect->yBot) + xsect->aBot; @@ -455,6 +458,7 @@ int xsect_setParams(TXsect *xsect, int type, double p[], double ucf) // --- height of circular arc xsect->yBot = xsect->rBot * (1.0 - cos(theta/2.0)); + if (xsect->yBot > xsect->yFull) return FALSE; xsect->ywMax = xsect->yFull - xsect->yBot; // --- area of circular arc diff --git a/src/solver/xsect.dat b/src/solver/xsect.dat index 10b10ed33..fbecb58ac 100644 --- a/src/solver/xsect.dat +++ b/src/solver/xsect.dat @@ -3,7 +3,7 @@ // // Project: EPA SWMM5 // Version: 5.2 -// Date: 06/01/22 (Build 5.2.1) +// Date: 08/01/22 (Build 5.2.1) // Author: L. Rossman // // Tables of relative geometric properties for rounded cross-sections.