Repository: pyswmm/Stormwater-Management-Model (language: python)

Issue:
Merge usepa524
merge in bug fixes from upstream USEPA-SWMM 5.2.4
Small AppveyorCI and CMAKE Fixes
- Trying to make the lights green (at least on Appveyor).
Add benchmarks for extran and routing tests
This PR addresses Issue #132. The scripts `gen-config.cmd` and `run-nrtest.cmd` have also been added to the `tools` folder.   
revise version management
This PR is to create a discussion around an approach to address #382

The changes in this PR at the time of its submission restore the EPA version management approach (constant int defined in [consts.h](https://github.com/pyswmm/Stormwater-Management-Model/blob/414a397d40f726672f2458d180f8f8e747b8ae74/src/solver/consts.h#L19)). The EPA versioning is maintained to define the EPA engine upon which the pyswmm-SWMM code is based. When changes are made in EPA code, they (along with the version definition) will be merged into this fork without updating the version defined in the swmm-solver cmake project.

The swmm-solver version that is defined in the [CMakeLists.txt file](https://github.com/pyswmm/Stormwater-Management-Model/blob/414a397d40f726672f2458d180f8f8e747b8ae74/CMakeLists.txt#L25) is repurposed to define the version of the toolkit API. As changes are made to the toolkit api, the swmm-solver version should be incremented accordingly.

The [EPA report file header is restored](https://github.com/pyswmm/Stormwater-Management-Model/blob/develop_version_management/src/solver/report.c#L230) to document the EPA engine version that was used to run the simulation. [A second header line is added to the report file](https://github.com/pyswmm/Stormwater-Management-Model/blob/414a397d40f726672f2458d180f8f8e747b8ae74/src/solver/report.c#L231-L235) to document the pyswmm toolkit version included in the engine used to run the simulation. Restoring the EPA header to the first line of the rpt file has the added benefit of making it compatible with  PCSWMM gui software, where as previously the OWA header would prevent the PCSWMM from parsing the rpt file properly. 

In addition to these changes, I'd like to discuss revising code annotations in the source code. Previously the SWMM model was defined as OWA SWMM. Since the project has migrated away from OWA, I am wondering if we should rebrand the source code accordingly. I propose instances of "OWA" or "Open Water Analytics" in the source code by replaced with "pyswmm". Thoughts?

Since the rpt file header has changed, regression tests will fail until this new engine is used to generate new benchmark files with the updated rpt header.

@bemcdonnell @abhiramm7 @michaeltryby


Discussion / hints:

Some of the settings pulled from a fresh downloaded compiler from EPA's website related to the default Release Configuration... (Looks like it does use fast floating point model...).

#### VC2010-CLE
```
    <ProjectConfiguration Include="Release|Win32">
      <Configuration>Release</Configuration>
      <Platform>Win32</Platform>
    </ProjectConfiguration>

  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
    <ConfigurationType>Application</ConfigurationType>
    <UseDebugLibraries>false</UseDebugLibraries>
    <WholeProgramOptimization>true</WholeProgramOptimization>
    <CharacterSet>MultiByte</CharacterSet>


  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
    <ClCompile>
      <WarningLevel>Level3</WarningLevel>
      <Optimization>MaxSpeed</Optimization>
      <FunctionLevelLinking>true</FunctionLevelLinking>
      <IntrinsicFunctions>true</IntrinsicFunctions>
      <CompileAs>CompileAsC</CompileAs>
      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
      <OpenMPSupport>true</OpenMPSupport>
      <FloatingPointModel>Fast</FloatingPointModel>
      <FloatingPointExceptions>false</FloatingPointExceptions>
    </ClCompile>
```

#### VC2010-DLL

```
    <ProjectConfiguration Include="Release|Win32">
      <Configuration>Release</Configuration>
      <Platform>Win32</Platform>
    </ProjectConfiguration>

  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
    <ClCompile>
      <Optimization>MaxSpeed</Optimization>
      <IntrinsicFunctions>false</IntrinsicFunctions>
      <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
      <WholeProgramOptimization>true</WholeProgramOptimization>
      <ExceptionHandling>
      </ExceptionHandling>
      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
      <StructMemberAlignment>Default</StructMemberAlignment>
      <FloatingPointModel>Fast</FloatingPointModel>
      <FloatingPointExceptions>false</FloatingPointExceptions>
      <DisableLanguageExtensions>false</DisableLanguageExtensions>
      <WarningLevel>Level4</WarningLevel>
      <CompileAs>CompileAsC</CompileAs>
      <OpenMPSupport>true</OpenMPSupport>
      <MultiProcessorCompilation>false</MultiProcessorCompilation>
    </ClCompile>
```
@goanpeca, I've turned off most of the build matrix.  We're in the green for the Benchmark compiler!!!  (There are issues with finding OpenMP). VS2010, (if I understand this correctly), only allowed paid subscribers to use openMP for VS2010.  
@bemcdonnell appveyor is running now with 21/22 tests passing. 
@michaeltryby, it would be really helpful if you could have the testing framework print a few lines of the diff so we can get a quick preview of what is going on with it.  How complicated would it be if the tool would print ~10 lines of a failed RPT diff?
@michaeltryby, maybe make a small injection here: 

https://github.com/michaeltryby/Stormwater-Management-Model/blob/develop/tools/nrtest-swmm/main.py#L79-L89

```python

def report_compare(path_test, path_ref, (comp_args)):
    '''
    Compares results in two report files ignoring contents of header and footer. 
    '''
    with open(path_test ,'r') as ftest, open(path_ref, 'r') as fref:
        for (test_line, ref_line) in it.izip(hdf.parse(ftest, 4, 4)[1], 
                                             hdf.parse(fref, 4, 4)[1]): 
            if test_line != ref_line: 
                print('benchmark-> {}\ntest       ->{}'.format(ref_line.replace('\n',''), test_line.replace('\n','')))
                return False
              
    return True 
```
@bemcdonnell couple of thought ...
1) Running tests on CI is not a substitute for running tests locally. 
2) Developers should run the tests locally to make sure their code works before issuing a PR. 
3) Being a developer comes with a lot of responsibility. One of those is testing code locally.  
4) If you want to retrieve failure information from the CI server, that should be handled in the CI configuration after tests run and a failure is detected. NOT in the `nrtest` comparison routine!  On failure have the server email or cache the failing test artifacts where you can retrieve them. 
5) The developer should be testing locally. Getting information back from the server can be used in situations where there are differences between local and remote testing.  
6) When in doubt you should be testing locally. 
7) The great thing is, its super easy to run `nrtest` locally!
On Appveyor it looks like you are able to associate and retrieve artifacts with a CI build.   
https://help.appveyor.com/discussions/questions/1649-how-to-keep-a-build-artifact-when-tests-fail

The support for savings test artifacts isn't as good on Travis. They only support S3.
https://github.com/travis-ci/artifacts
@bemcdonnell I propose we accept this PR as is and create an issue to configure appveyor to retrieve failed test artifacts. What do you think?   
@bemcdonnell I can also create an issue to update the readme for running `nrtest` found [here](https://github.com/OpenWaterAnalytics/Stormwater-Management-Model/blob/develop/tests/README.md) with step-by-step instructions for Windows. 
@michaeltryby, i wonder why we have one failure...
@bemcdonnell Let's find out!


Fix patch:
diff --git a/CMakeLists.txt b/CMakeLists.txt
index b7ebd6629..10969a2b0 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -22,7 +22,7 @@ endif()
 
 
 project(swmm-solver
-    VERSION 5.2.3
+    VERSION 5.2.4
     LANGUAGES C CXX
 )
 
diff --git a/extern/version.h.in b/extern/version.h.in
index 6fcc6a895..2a0b7e622 100644
--- a/extern/version.h.in
+++ b/extern/version.h.in
@@ -29,6 +29,7 @@
 #define COMPILER_VERSION    "@CMAKE_C_COMPILER_VERSION@"
 #define BUILD_ID            "@BUILD_ID@"
 
+#define TOOLKIT_VERSION          "1.0"
 
 static inline int get_version_legacy() { \
     return VERSION_MAJOR * 10000 + VERSION_MINOR * 1000 + VERSION_PATCH; \
diff --git a/src/solver/consts.h b/src/solver/consts.h
index 3cf490793..394b5e2e8 100644
--- a/src/solver/consts.h
+++ b/src/solver/consts.h
@@ -3,7 +3,7 @@
 //
 //   Project: EPA SWMM5
 //   Version: 5.2
-//   Date:    02/12/23  (Build 5.2.3)
+//   Date:    07/15/23  (Build 5.2.4)
 //   Author:  L. Rossman
 //
 //   Various Constants
@@ -17,7 +17,7 @@
 //------------------
 
 // OWA Version string stored in version.h
-// #define   VERSION            52003
+// #define   VERSION            52004
 #define   MAGICNUMBER        516114522
 #define   EOFMARK            0x1A           // Use 0x04 for UNIX systems
 #define   MAXTITLE           3              // Max. # title lines
diff --git a/src/solver/dwflow.c b/src/solver/dwflow.c
index d6484fe57..25b2b874a 100644
--- a/src/solver/dwflow.c
+++ b/src/solver/dwflow.c
@@ -3,7 +3,7 @@
 //
 //   Project:  EPA SWMM5
 //   Version:  5.2
-//   Date:     08/01/22  (Build 5.2.1)
+//   Date:     06/12/23  (Build 5.2.4)
 //   Author:   L. Rossman
 //             M. Tryby (EPA)
 //             R. Dickinson (CDM)
@@ -26,6 +26,8 @@
 //     (qOld) in call to link_getLossRate. 
 //   Build 5.2.1:
 //   - Implements the new option to skip checking for normal flow limitations.
+//   Build 5.2.4:
+//   - Arguments to function link_getLossRate changed.
 //-----------------------------------------------------------------------------
 #define _CRT_SECURE_NO_DEPRECATE
 
@@ -231,7 +233,7 @@ void  dwflow_findConduitFlow(int j, int steps, double omega, double dt)
     }
 
     // --- 6. term for evap and seepage losses per unit length
-    dq6 = link_getLossRate(j, qLast) * 2.5 * dt * v / link_getLength(j);
+    dq6 = link_getLossRate(j, DW, qLast, dt) * 2.5 * dt * v / link_getLength(j);
 
     // --- combine terms to find new conduit flow
     denom = 1.0 + dq1 + dq5;
diff --git a/src/solver/dynwave.c b/src/solver/dynwave.c
index ac302e849..85968e2a9 100644
--- a/src/solver/dynwave.c
+++ b/src/solver/dynwave.c
@@ -3,7 +3,7 @@
 //
 //   Project:  EPA SWMM5
 //   Version:  5.2
-//   Date:     11/01/21  (Build 5.2.0)
+//   Date:     07/13/23  (Build 5.2.4)
 //   Author:   L. Rossman
 //             M. Tryby (EPA)
 //             R. Dickinson (CDM)
@@ -44,6 +44,9 @@
 //   - Roll back the 5.1.014 change for conduit losses in updateNodeFlows().
 //   Build 5.2.0:
 //   - Support added for reporting most frequent non-converging links.
+//   Build 5.2.4:
+//   - Conduit evap+seepage outflow split evenly between outflow from
+//     conduit's upstream and non-outfall downstream nodes.
 //-----------------------------------------------------------------------------
 #define _CRT_SECURE_NO_DEPRECATE
 
@@ -129,7 +132,7 @@ void dynwave_init()
             " Not enough memory for dynamic wave routing.");
         return;
     }
-
+    
     // --- initialize node surface areas & crown elev.
     for (i = 0; i < Nobjects[NODE]; i++ )
     {
@@ -144,6 +147,7 @@ void dynwave_init()
         j = Link[i].node1;
         z = Node[j].invertElev + Link[i].offset1 + Link[i].xsect.yFull;
         Node[j].crownElev = MAX(Node[j].crownElev, z);
+        
         j = Link[i].node2;
         z = Node[j].invertElev + Link[i].offset2 + Link[i].xsect.yFull;
         Node[j].crownElev = MAX(Node[j].crownElev, z);
@@ -534,29 +538,39 @@ void updateNodeFlows(int i)
     int    n1 = Link[i].node1;
     int    n2 = Link[i].node2;
     double q = Link[i].newFlow;
-    double uniformLossRate = 0.0;
-
-    // --- compute any uniform seepage loss from a conduit
-    if ( Link[i].type == CONDUIT )
-    {
-        k = Link[i].subIndex;
-        uniformLossRate = Conduit[k].evapLossRate + Conduit[k].seepLossRate; 
-        barrels = Conduit[k].barrels;
-        uniformLossRate *= barrels;
-    }
+    double conduitLossRate = 0.0;
 
     // --- update total inflow & outflow at upstream/downstream nodes
     if ( q >= 0.0 )
     {
-        Node[n1].outflow += q + uniformLossRate;
+        Node[n1].outflow += q;
         Node[n2].inflow  += q;
     }
     else
     {
         Node[n1].inflow   -= q;
-        Node[n2].outflow  -= q - uniformLossRate;
+        Node[n2].outflow  -= q;
     }
-
+ 
+    // --- add any uniform evap & seepage loss from conduit link
+    if ( Link[i].type == CONDUIT )
+    {
+        k = Link[i].subIndex;
+        barrels = Conduit[k].barrels;
+        conduitLossRate = (Conduit[k].evapLossRate + Conduit[k].seepLossRate) *
+                          barrels;
+        if (conduitLossRate > 0.0)
+        {
+            // --- outfall nodes do not share evap & seepage losses
+            if (Node[n1].type != OUTFALL && Node[n2].type != OUTFALL)
+                conduitLossRate /= 2.0;
+            if (Node[n1].type != OUTFALL)
+                Node[n1].outflow += conduitLossRate;
+            if (Node[n2].type != OUTFALL)
+                Node[n2].outflow += conduitLossRate;
+        }
+    }
+    
     // --- add surf. area contributions to upstream/downstream nodes
     Xnode[Link[i].node1].newSurfArea += Link[i].surfArea1 * barrels;
     Xnode[Link[i].node2].newSurfArea += Link[i].surfArea2 * barrels;
@@ -585,7 +599,7 @@ int findNodeDepths(double dt)
 //
 {
     int i;
-    double yOld;        // previous node depth (ft)
+    double yOld = 0.0;       // previous node depth (ft)
 
     // --- compute outfall depths based on flow in connecting link
     for ( i = 0; i < Nobjects[LINK]; i++ ) link_setOutfallDepth(i);
@@ -654,12 +668,11 @@ void setNodeDepth(int i, double dt)
     Node[i].overflow = 0.0;
     surfArea = Xnode[i].newSurfArea;
     surfArea = MAX(surfArea, MinSurfArea);
-
+    
     // --- determine average net flow volume into node over the time step
     dQ = Node[i].inflow - Node[i].outflow;
     dV = 0.5 * (Node[i].oldNetInflow + dQ) * dt;
 
-
     // --- determine if node is EXTRAN surcharged
     if (SurchargeMethod == EXTRAN)
     {
diff --git a/src/solver/flowrout.c b/src/solver/flowrout.c
index f296c3fb0..73f5f67d4 100644
--- a/src/solver/flowrout.c
+++ b/src/solver/flowrout.c
@@ -3,7 +3,7 @@
 //
 //   Project:  EPA SWMM5
 //   Version:  5.2
-//   Date:     05/02/22  (Build 5.2.1)
+//   Date:     06/12/23  (Build 5.2.4)
 //   Author:   L. Rossman
 //             M. Tryby (EPA)
 //
@@ -27,6 +27,8 @@
 //   Build 5.2.1:
 //   - For storage routing, after convergence the reported depth is now
 //     based on the last volume found rather than the next trial depth. 
+//   Build 5.2.4:
+//   - Arguments to link_getLossRate changed.
 //-----------------------------------------------------------------------------
 #define _CRT_SECURE_NO_DEPRECATE
 
@@ -767,7 +769,7 @@ int steadyflow_execute(int j, double* qin, double* qout, double tStep)
         else 
         {
             // --- adjust flow for evap and infil losses
-            q -= link_getLossRate(j, q);
+            q -= link_getLossRate(j, SF, q, tStep);
          
             // --- flow can't exceed full flow 
             if ( q > Link[j].qFull )
diff --git a/src/solver/funcs.h b/src/solver/funcs.h
index 21af0d54d..642318ebd 100644
--- a/src/solver/funcs.h
+++ b/src/solver/funcs.h
@@ -3,7 +3,7 @@
 //
 //   Project:  EPA SWMM5
 //   Version:  5.2
-//   Date:     11/01/21 (Build 5.2.0)
+//   Date:     06/12/23 (Build 5.2.4)
 //   Author:   L. Rossman
 //             M. Tryby (EPA)
 //
@@ -29,6 +29,8 @@
 //   - Support added for named variables & math expressions in control rules.
 //   - Support added for tracking a gage's prior n-hour rainfall total.
 //   - Refactored external inflow code.
+//   Build 5.2.4:
+//   - Additional arguments added to function link_getLossRate.
 //-----------------------------------------------------------------------------
 
 #ifndef FUNCS_H
@@ -425,7 +427,7 @@ double  link_getYnorm(int link, double q);
 double  link_getVelocity(int link, double q, double y);
 double  link_getFroude(int link, double v, double y);
 double  link_getPower(int link);
-double  link_getLossRate(int link, double q);
+double  link_getLossRate(int link, int routeModel, double q, double tstep);
 char    link_getFullState(double a1, double a2, double aFull);
 
 void    link_getResults(int link, double wt, float x[]);
diff --git a/src/solver/include/toolkit.h b/src/solver/include/toolkit.h
index 339dbd09a..540fce63a 100644
--- a/src/solver/include/toolkit.h
+++ b/src/solver/include/toolkit.h
@@ -99,6 +99,22 @@ EXPORT_TOOLKIT int swmm_getSimulationAnalysisSetting(SM_SimOption type, int *val
  */
 EXPORT_TOOLKIT int swmm_getSimulationParam(SM_SimSetting type, double *value);
 
+/**
+ @brief Set Simulation Analysis Setting
+ @param type Option code (see @ref SM_SimSetting)
+ @param value Option value
+ @return Error code
+ */
+EXPORT_TOOLKIT int  swmm_setSimulationParam(SM_SimSetting type, double value);
+
+/**
+ @brief Use/override a hotstart file before the simulation starts.
+ @param type The property type code (see @ref SM_HotStart)
+ @param hsfile The file name of the hot start file that the user would like to use.
+ @return Error code
+*/
+EXPORT_TOOLKIT int swmm_hotstart(SM_HotStart type, const char *hsfile);
+
 /**
  @brief Gets Object Count
  @param type Option code (see @ref SM_ObjectType)
diff --git a/src/solver/include/toolkit_enums.h b/src/solver/include/toolkit_enums.h
index 651743b37..89bf2ce14 100644
--- a/src/solver/include/toolkit_enums.h
+++ b/src/solver/include/toolkit_enums.h
@@ -89,9 +89,16 @@ typedef enum {
     SM_QUALERROR     = 10, /**< Quality routing error */
     SM_HEADTOL       = 11, /**< DW routing head tolerance (ft) */
     SM_SYSFLOWTOL    = 12, /**< Tolerance for steady system flow */
-    SM_LATFLOWTOL    = 13  /**< Tolerance for steady nodal inflow */
+    SM_LATFLOWTOL    = 13, /**< Tolerance for steady nodal inflow */
+    SM_THREADS       = 14  /**< Number of Threads for this process */
 } SM_SimSetting;
 
+/// Hot Start File Manager
+typedef enum {
+    SM_HOTSTART_USE  = 0,  /**< Use Hotstart File */
+    SM_HOTSTART_SAVE = 1   /**< Save Hotstart File */
+} SM_HotStart;
+
 /// Node property codes
 typedef enum {
     SM_INVERTEL     = 0,  /**< Invert Elevation */
diff --git a/src/solver/include/toolkit_error.h b/src/solver/include/toolkit_error.h
index 3f58128ec..29ead3b3f 100644
--- a/src/solver/include/toolkit_error.h
+++ b/src/solver/include/toolkit_error.h
@@ -14,6 +14,7 @@ enum  ToolkitErrorType {
     ERR_TKAPI_UNDEFINED_LID      = 2010,
     ERR_TKAPI_MEMORY             = 2011,
     ERR_TKAPI_NO_INLET           = 2012,
+    ERR_TKAPI_SIM_RUNNING        = 2013,
 
     TKMAXERRMSG                  = 3000
 };
diff --git a/src/solver/include/toolkit_errors.txt b/src/solver/include/toolkit_errors.txt
index 4a9dd1f8e..1349f5a4b 100644
--- a/src/solver/include/toolkit_errors.txt
+++ b/src/solver/include/toolkit_errors.txt
@@ -13,3 +13,4 @@ ERR(2009, "\n API Key Error: Invalid Lid Unit Index")
 ERR(2010, "\n API Key Error: Undefined Subcatchment Lid")
 ERR(2011, "\n API Key Error: No memory allocated for return value")
 ERR(2012, "\n API Key Error: Specified link is not assigned an inlet")
+ERR(2013, "\n API Key Error: Simulation Already Started or Running.")
diff --git a/src/solver/inlet.c b/src/solver/inlet.c
index c44ae9fcb..f3aa180a8 100644
--- a/src/solver/inlet.c
+++ b/src/solver/inlet.c
@@ -3,7 +3,7 @@
 //
 //   Project:  EPA SWMM5
 //   Version:  5.2
-//   Date:     10/08/22 (Build 5.2.2)
+//   Date:     07/13/23 (Build 5.2.4)
 //   Author:   L. Rossman
 //
 //   Street/Channel Inlet Functions
@@ -18,6 +18,10 @@
 //   - Substitutes the constant BIG for HUGE.
 //   Build 5.2.2:
 //   - Additional statistics added to Street Flow Summary table.
+//   Build 5.2.4:
+//   - Fixed expression for equivalent gutter slope in getCurbInletCapture.
+//   - Corrected sign in equation for effective head in a curb inlet
+//     with an inclined throat opening in getCurbOrificeFlow.
 //-----------------------------------------------------------------------------
 #define _CRT_SECURE_NO_DEPRECATE
 
@@ -1444,7 +1448,7 @@ double getCurbInletCapture(double Q, double L)
 //  Input:   Q = flow rate seen by inlet (cfs)
 //           L = length of inlet opening (ft)
 //  Output:  returns captured flow rate (cfs)
-//  Purpose: finds the flow captured by an on-sag inlet.
+//  Purpose: finds the flow captured by an on-grade curb opening inlet.
 //
 {
     double Se = Sx,     // equivalent gutter slope
@@ -1460,7 +1464,7 @@ double getCurbInletCapture(double Q, double L)
     {
         Sr = Sw / Sx;
         Eo = getEo(Sr, T-W, W);
-        Se = Sx + Sw * Eo;                                 //HEC-22 Eq(4-24)
+        Se = Sx + (a/W) * Eo;                              //HEC-22 Eq(4-24)
     }
 
     // --- opening length for full capture
@@ -1741,7 +1745,7 @@ double getCurbOrificeFlow(double di, double h, double L, int throatAngle)
     if (throatAngle == HORIZONTAL_THROAT)
         d = di - h / 2.0;
     else if (throatAngle == INCLINED_THROAT)
-        d = di + (h / 2.0) * 0.7071;
+        d = di - (h / 2.0) * 0.7071;
     return 0.67 * h * L * sqrt(2.0 * 32.16 * d);           //HEC-22 Eq(4-31a)
 }
 
diff --git a/src/solver/kinwave.c b/src/solver/kinwave.c
index b137e4ce9..cafa2e346 100644
--- a/src/solver/kinwave.c
+++ b/src/solver/kinwave.c
@@ -3,7 +3,7 @@
 //
 //   Project:  EPA SWMM5
 //   Version:  5.2
-//   Date:     11/01/21  (Build 5.2.0)
+//   Date:     06/12/23  (Build 5.2.4)
 //   Author:   L. Rossman
 //             M. Tryby (EPA)
 //
@@ -15,6 +15,8 @@
 //   - Conduit inflow passed to function that computes conduit losses.
 //   Build 5.1.014:
 //   - Arguments to function link_getLossRate changed.
+//   Build 5.2.4:
+//   - Arguments to function link_getLossRate changed again.
 //-----------------------------------------------------------------------------
 #define _CRT_SECURE_NO_DEPRECATE
 
@@ -100,7 +102,7 @@ int kinwave_execute(int j, double* qinflow, double* qoutflow, double tStep)
     qin = (*qinflow) / Conduit[k].barrels / Qfull;
 
     // --- compute evaporation and infiltration loss rate
-    q3 = link_getLossRate(j, qin*Qfull) / Qfull;
+    q3 = link_getLossRate(j, KW, qin*Qfull, tStep) / Qfull;
 
     // --- normalize previous areas
     a1 = Conduit[k].a1 / Afull;
diff --git a/src/solver/lid.c b/src/solver/lid.c
index a6e82e16c..63de8920e 100644
--- a/src/solver/lid.c
+++ b/src/solver/lid.c
@@ -3,7 +3,7 @@
 //
 //   Project:  EPA SWMM5
 //   Version:  5.2
-//   Date:     02/10/23   (Build 5.2.3)
+//   Date:     07/13/23   (Build 5.2.4)
 //   Author:   L. Rossman
 //
 //   This module handles all data processing involving LID (Low Impact
@@ -70,6 +70,8 @@
 //   - Covered property added to RAIN_BARREL parameters
 //   Build 5.2.3
 //   - Fixed double counting of initial water volume in green roof drain mat.
+//   Build 5.2.4
+//   - Fixed test for invalid data in readDrainData function.
 //-----------------------------------------------------------------------------
 #define _CRT_SECURE_NO_DEPRECATE
 
@@ -786,7 +788,7 @@ int readDrainData(int j, char* toks[], int ntoks)
     for (i = 0; i < 6; i++) x[i] = 0.0;
     for (i = 2; i < 8; i++)
     {
-        if ( (ntoks > i) && (! getDouble(toks[i], &x[i-2]) || x[i-2]) < 0.0 )
+        if ( (ntoks > i) && (! getDouble(toks[i], &x[i-2]) || x[i-2] < 0.0) )
             return error_setInpError(ERR_NUMBER, toks[i]);
     }
 
@@ -1084,6 +1086,7 @@ void validateLidProc(int j)
     // moved clogging factor conversion logic to readStorageData and readPavementData
     // in 14d2e62e9a6baad89f6cd2dc0c55907e1d2289b2 to allow multiple calls to validateLidProc
     // in toolkit.c
+    
     //... for certain LID types, immediate overflow of excess surface water
     //    occurs if either the surface roughness or slope is zero
     LidProcs[j].surface.canOverflow = TRUE;
diff --git a/src/solver/lidproc.c b/src/solver/lidproc.c
index a74fd67f7..d0876fd15 100644
--- a/src/solver/lidproc.c
+++ b/src/solver/lidproc.c
@@ -3,7 +3,7 @@
 //
 //   Project:  EPA SWMM5
 //   Version:  5.2
-//   Date:     11/01/21   (Build 5.2.0)
+//   Date:     07/13/23   (Build 5.2.4)
 //   Author:   L. Rossman
 //
 //   This module computes the hydrologic performance of an LID (Low Impact
@@ -53,6 +53,11 @@
 //   - Fixed failure to account for effect of Impervious Surface Fraction on
 //     pavement permeability for Permeable Pavement LID
 //   - Fixed units conversion for pavement depth in detailed report file.
+//   Build 5.2.4:
+//   - Modified flux limits in biocellFluxRates, pavementFluxRates and
+//     trenchFluxRates.
+//   - Corrected head calculation in getStorageDrainRate when unit has both
+//     a soil and pavement layer.
 //-----------------------------------------------------------------------------
 #define _CRT_SECURE_NO_DEPRECATE
 
@@ -700,61 +705,64 @@ void biocellFluxRates(double x[], double f[])
         SurfaceInfil = MIN(SurfaceInfil, maxRate);
     }
 
-    //... storage & soil layers are full
-    else if ( soilTheta >= soilPorosity && storageDepth >= storageThickness )
+    else
     {
-        //... limiting rate is smaller of soil perc and storage outflow
-        maxRate = StorageExfil + StorageDrain;
-        if ( SoilPerc < maxRate )
+        //... storage & soil layers are full
+        if ( soilTheta >= soilPorosity && storageDepth >= storageThickness )
         {
-            maxRate = SoilPerc;
-            if ( maxRate > StorageExfil ) StorageDrain = maxRate - StorageExfil;
-            else
+            //... limiting rate is smaller of soil perc and storage outflow
+            maxRate = StorageExfil + StorageDrain;
+            if ( SoilPerc < maxRate )
             {
-                StorageExfil = maxRate;
-                StorageDrain = 0.0;
+                maxRate = SoilPerc;
+                if ( maxRate > StorageExfil ) StorageDrain = maxRate - StorageExfil;
+                else
+                {
+                    StorageExfil = maxRate;
+                    StorageDrain = 0.0;
+                }
             }
-        }
-        else SoilPerc = maxRate;
-
-        //... apply limiting rate to surface infil.
-        SurfaceInfil = MIN(SurfaceInfil, maxRate);
-    }
+            else SoilPerc = maxRate;
 
-    //... either layer not full
-    else if ( storageThickness > 0.0 )
-    {
-        //... limit storage exfiltration by available storage volume
-        maxRate = SoilPerc - StorageEvap + storageDepth*storageVoidFrac/Tstep;
-        StorageExfil = MIN(StorageExfil, maxRate);
-        StorageExfil = MAX(StorageExfil, 0.0);
+            //... apply limiting rate to surface infil.
+            SurfaceInfil = MIN(SurfaceInfil, maxRate);
+        }
 
-        //... limit underdrain flow by volume above drain offset
-        if ( StorageDrain > 0.0 )
+        //... either layer not full
+        else
         {
-            maxRate = -StorageExfil - StorageEvap;
-            if ( storageDepth >= storageThickness) maxRate += SoilPerc;
-            if ( theLidProc->drain.offset <= storageDepth )
+            //... limit storage exfiltration by available storage volume
+            maxRate = SoilPerc - StorageEvap + storageDepth*storageVoidFrac/Tstep;
+            StorageExfil = MIN(StorageExfil, maxRate);
+            StorageExfil = MAX(StorageExfil, 0.0);
+
+            //... limit underdrain flow by volume above drain offset
+            if ( StorageDrain > 0.0 )
             {
-                maxRate += (storageDepth - theLidProc->drain.offset) *
-                           storageVoidFrac/Tstep;
+                maxRate = -StorageExfil - StorageEvap;
+                if ( storageDepth >= storageThickness) maxRate += SoilPerc;
+                if ( theLidProc->drain.offset <= storageDepth )
+                {
+                    maxRate += (storageDepth - theLidProc->drain.offset) *
+                               storageVoidFrac/Tstep;
+                }
+                maxRate = MAX(maxRate, 0.0);
+                StorageDrain = MIN(StorageDrain, maxRate);
             }
-            maxRate = MAX(maxRate, 0.0);
-            StorageDrain = MIN(StorageDrain, maxRate);
-        }
-
-        //... limit soil perc by unused storage volume
-        maxRate = StorageExfil + StorageDrain + StorageEvap +
-                  (storageThickness - storageDepth) *
-                  storageVoidFrac/Tstep;
-        SoilPerc = MIN(SoilPerc, maxRate);
+        
+            //... limit soil perc by unused storage volume
+            maxRate = StorageExfil + StorageDrain + StorageEvap +
+                      (storageThickness - storageDepth) *
+                      storageVoidFrac/Tstep;
+            SoilPerc = MIN(SoilPerc, maxRate);
 
-        //... limit surface infil. by unused soil volume
-        maxRate = (soilPorosity - soilTheta) * soilThickness / Tstep +
-                  SoilPerc + SoilEvap;
-        SurfaceInfil = MIN(SurfaceInfil, maxRate);
+            //... limit surface infil. by unused soil volume
+            maxRate = (soilPorosity - soilTheta) * soilThickness / Tstep +
+                      SoilPerc + SoilEvap;
+            SurfaceInfil = MIN(SurfaceInfil, maxRate);
+        }
     }
-
+    
     //... find surface layer outflow rate
     SurfaceOutflow = getSurfaceOutflowRate(surfaceDepth);
 
@@ -849,7 +857,7 @@ void trenchFluxRates(double x[], double f[])
     SurfaceOutflow = getSurfaceOutflowRate(surfaceDepth);
 
     // ... find net fluxes for each layer
-    f[SURF] = SurfaceInflow - SurfaceEvap - StorageInflow - SurfaceOutflow /
+    f[SURF] = (SurfaceInflow - SurfaceEvap - StorageInflow - SurfaceOutflow) /
               theLidProc->surface.voidFrac;;
     f[STOR] = (StorageInflow - StorageEvap - StorageExfil - StorageDrain) /
               theLidProc->storage.voidFrac;
@@ -1012,6 +1020,7 @@ void pavementFluxRates(double x[], double f[])
             StorageExfil = MIN(StorageExfil, SoilPerc);
             StorageDrain = SoilPerc - StorageExfil;
         }
+        PavePerc = MIN(PavePerc, SoilPerc);        
 
         //... limit surface infil. by available pavement volume
         availVolume = (paveThickness - paveDepth) * paveVoidFrac;
@@ -1027,6 +1036,8 @@ void pavementFluxRates(double x[], double f[])
         PavePerc = MIN(PavePerc, SoilPerc);
         SoilPerc = PavePerc;
         SurfaceInfil = MIN(SurfaceInfil,PavePerc); 
+        maxRate = MAX(StorageVolume / Tstep + SoilPerc - StorageEvap, 0.0);
+	    StorageExfil = MIN(StorageExfil, maxRate); 
     }
 
     //... no adjoining layers are full
@@ -1416,7 +1427,11 @@ double  getStorageDrainRate(double storageDepth, double soilTheta,
                 //     depth in layer above it
                 if ( soilTheta >= soilPorosity )
                 {
-                    if ( paveThickness > 0.0 ) head += paveDepth;
+                    if ( paveThickness > 0.0 )
+                    {
+                        head += paveDepth;
+                        if ( paveDepth >= paveThickness ) head += surfaceDepth;
+                    }    
                     else head += surfaceDepth;
                 }
             }
@@ -1424,7 +1439,7 @@ double  getStorageDrainRate(double storageDepth, double soilTheta,
 
         // --- no soil layer so increase head by water level in pavement
         //     layer and possibly surface layer
-        if ( paveThickness > 0.0 )
+        else if ( paveThickness > 0.0 )
         {
             head += paveDepth;
             if ( paveDepth >= paveThickness ) head += surfaceDepth;
diff --git a/src/solver/link.c b/src/solver/link.c
index 052a030b9..c8e035f4c 100644
--- a/src/solver/link.c
+++ b/src/solver/link.c
@@ -3,7 +3,7 @@
 //
 //   Project:  EPA SWMM5
 //   Version:  5.2
-//   Date:     10/29/22   (Build 5.2.2)
+//   Date:     06/12/23   (Build 5.2.4)
 //   Author:   L. Rossman
 //             M. Tryby (EPA)
 //
@@ -46,6 +46,8 @@
 //   - Warning no longer issued when conduit elevation drop < MIN_DELTA_Z.
 //   Build 5.2.2:
 //   - Warning for conduit elevation drop < MIN_DELTA_Z restored.
+//   Build 5.2.4:
+//   - Conduit evap+seepage loss under DW routing limited by conduit volume.
 //-----------------------------------------------------------------------------
 #define _CRT_SECURE_NO_DEPRECATE
 
@@ -99,7 +101,8 @@ static double conduit_getLength(int j);
 static double conduit_getLengthFactor(int j, int k, double roughness);
 static double conduit_getSlope(int j);
 static double conduit_getInflow(int j);
-static double conduit_getLossRate(int j, double q);
+static double conduit_getLossRate(int j, int routeModel, double q,
+              double tstep);
 
 static int    pump_readParams(int j, int k, char* tok[], int ntoks);
 static void   pump_validate(int j, int k);
@@ -887,9 +890,10 @@ double link_getPower(int j)
 
 //=============================================================================
 
-double link_getLossRate(int j, double q)
+double link_getLossRate(int j, int routeModel, double q, double tstep)
 //
 //  Input:   j = link index
+//           routeModel = flow routing model type
 //           q = flow rate (ft3/sec)
 //           tstep = time step (sec)
 //  Output:  returns uniform loss rate in link (ft3/sec)
@@ -897,7 +901,8 @@ double link_getLossRate(int j, double q)
 //           evaporation and seepage.
 //
 {
-    if ( Link[j].type == CONDUIT ) return conduit_getLossRate(j, q);
+    if ( Link[j].type == CONDUIT )
+        return conduit_getLossRate(j, routeModel, q, tstep);
     else return 0.0;
 }
 
@@ -1326,10 +1331,12 @@ double conduit_getInflow(int j)
 
 //=============================================================================
 
-double conduit_getLossRate(int j, double q)
+double conduit_getLossRate(int j, int routeModel, double q, double tstep)
 //
 //  Input:   j = link index
+//           routeModel = type of flow routing model
 //           q = current link flow rate (cfs)
+//           tstep = current routing time step (sec)
 //  Output:  returns rate of evaporation & seepage losses (ft3/sec)
 //  Purpose: computes volumetric rate of water evaporation & seepage
 //           from a conduit (per barrel).
@@ -1338,7 +1345,7 @@ double conduit_getLossRate(int j, double q)
     TXsect *xsect;
     double depth = 0.5 * (Link[j].oldDepth + Link[j].newDepth);
     double length;
-    double topWidth;
+    double width, topWidth;
     double evapLossRate = 0.0,
            seepLossRate = 0.0,
            totalLossRate = 0.0;
@@ -1359,19 +1366,25 @@ double conduit_getLossRate(int j, double q)
         if ( Link[j].seepRate > 0.0 )
         {
             // limit depth to depth at max width
-            if ( depth >= xsect->ywMax ) depth = xsect->ywMax;
+            if (xsect->type == RECT_CLOSED) width = xsect->wMax;
+            else
+            {
+                if ( depth >= xsect->ywMax ) depth = xsect->ywMax;
+                width = xsect_getWofY(xsect, depth);
+            }
 			
             // compute seepage loss rate across length of conduit
-            seepLossRate = Link[j].seepRate * xsect_getWofY(xsect, depth) *
-                           length;
+            seepLossRate = Link[j].seepRate * width * length;
             seepLossRate *= Adjust.hydconFactor;
         }
 
         // --- compute total loss rate
         totalLossRate = evapLossRate + seepLossRate;
 
-        // --- total loss rate cannot exceed flow rate
-        q = ABS(q);
+        // --- limit total loss rate to current volume for DW routing
+        //     or current link flow rate otherwise
+        if (routeModel == DW) q = Link[j].newVolume / tstep;
+        else q = ABS(q);        
         if (totalLossRate > q)
         {
             evapLossRate = evapLossRate * q / totalLossRate;
diff --git a/src/solver/project.c b/src/solver/project.c
index 55a0866c8..7d65c0f9d 100644
--- a/src/solver/project.c
+++ b/src/solver/project.c
@@ -3,7 +3,7 @@
 //
 //   Project:  EPA SWMM5
 //   Version:  5.2
-//   Date:     11/21/22  (Build 5.2.2)
+//   Date:     07/17/23  (Build 5.2.4)
 //   Author:   L. Rossman
 //
 //   Project management functions.
@@ -52,6 +52,10 @@
 //   Build 5.2.2:
 //   - Default number of threads changed from OMP max. number to 1
 //     to be consistent with User Manual.
+//   Build 5.2.4:
+//   - Default Inertial Damping changed from SOME to PARTIAL_DAMPING.
+//   - Default CourantFactor changed from 0 (fixed routing time step)
+//   - to 0.75 (variable time step)
 //-----------------------------------------------------------------------------
 #define _CRT_SECURE_NO_DEPRECATE
 
@@ -850,12 +854,12 @@ void setDefaults()
    SurchargeMethod = EXTRAN;           // Use EXTRAN method for surcharging
    CrownCutoff     = 0.96;             // Fractional pipe crown cutoff 
    AllowPonding    = FALSE;            // No ponding at nodes
-   InertDamping    = SOME;             // Partial inertial damping
+   InertDamping    = PARTIAL_DAMPING;  // Partial inertial damping
    NormalFlowLtd   = BOTH;             // Default normal flow limitation
    ForceMainEqn    = H_W;              // Hazen-Williams eqn. for force mains
    LinkOffsets     = DEPTH_OFFSET;     // Use depth for link offsets
    LengtheningStep = 0;                // No lengthening of conduits
-   CourantFactor   = 0.0;              // No variable time step 
+   CourantFactor   = 0.75;             // Variable time step reduced to 75%
    MinSurfArea     = 0.0;              // Force use of default min. surface area
    MinSlope        = 0.0;              // No user supplied minimum conduit slope
    SkipSteadyState = FALSE;            // Do flow routing in steady state periods 
diff --git a/src/solver/report.c b/src/solver/report.c
index dd1a3c9d4..18c58e11d 100644
--- a/src/solver/report.c
+++ b/src/solver/report.c
@@ -227,9 +227,10 @@ void report_writeLogo()
 //
 // OWA manages model version differently from EPA SWMM. 
 {
+    fprintf(Frpt.file, FMT08);
 	sprintf(Msg, \
-		"\n  OWA STORM WATER MANAGEMENT MODEL - VERSION v%s (OWA %.10s)", 
-        VERSION, BUILD_ID);
+		"\n  PYSWMM TOOLKIT API - VERSION v%s (%.10s)", 
+        TOOLKIT_VERSION, BUILD_ID);
 
     fprintf(Frpt.file, "%s", Msg);
     fprintf(Frpt.file, FMT09);
diff --git a/src/solver/street.c b/src/solver/street.c
index fd05451b7..0c55d9115 100644
--- a/src/solver/street.c
+++ b/src/solver/street.c
@@ -3,11 +3,14 @@
 //
 //   Project:  EPA SWMM5
 //   Version:  5.2
-//   Date:     11/01/21  (Build 5.2.0)
+//   Date:     07/13/23  (Build 5.2.4)
 //   Author:   L. Rossman
 //
 //   Street Cross-Section Functions
 //
+//   Build 5.2.4:
+//   - Fixed incorrect index used to retrieve street backing parameters
+//     in street_readParams.
 //-----------------------------------------------------------------------------
 #define _CRT_SECURE_NO_DEPRECATE
 
@@ -106,8 +109,8 @@ int street_readParams(char* tok[], int ntoks)
     // --- read street backing parameters
     if (ntoks > 8)
     {
-        if (!getDouble(tok[8], &x[8]) || x[k] < 0.0)
-            return error_setInpError(ERR_NUMBER, tok[k]);
+        if (!getDouble(tok[8], &x[8]) || x[8] < 0.0)
+            return error_setInpError(ERR_NUMBER, tok[8]);
         if (x[8] > 0.0)
         {
             if (ntoks < 11) return error_setInpError(ERR_ITEMS, "");
diff --git a/src/solver/surfqual.c b/src/solver/surfqual.c
index 858fcbee5..64593a012 100644
--- a/src/solver/surfqual.c
+++ b/src/solver/surfqual.c
@@ -3,7 +3,7 @@
 //
 //   Project:  EPA SWMM5
 //   Version:  5.2
-//   Date:     11/01/21  (Build 5.2.0)
+//   Date:     07/14/23  (Build 5.2.4)
 //   Author:   L. Rossman
 //
 //   Subcatchment water quality functions.
@@ -16,6 +16,10 @@
 //   - Support for separate accounting of LID drain flows included. 
 //   Build 5.1.014:
 //   - Fixed bug in computing effective BMP removal by LIDs.
+//   Build 5.2.4:
+//   - Set low runoff flow concentrations to zero before computing runoff
+//     mass loads rather than after so that they match wet weather mass
+//     inflows reported for conveyance system nodes. 
 //-----------------------------------------------------------------------------
 #define _CRT_SECURE_NO_DEPRECATE
 
@@ -255,7 +259,7 @@ void  surfqual_getWashoff(int j, double runoff, double tStep)
     {
         // --- convert washoff load to a concentration
         cOut = 0.0;
-        if ( vOut1 > 0.0 ) cOut = OutflowLoad[p] / vOut1;
+        if ( vOut1 > 0.0 && hasOutflow ) cOut = OutflowLoad[p] / vOut1;
 
         // --- assign any difference between pre- and post-LID
         //     subcatchment outflow loads to BMP removal
@@ -281,7 +285,6 @@ void  surfqual_getWashoff(int j, double runoff, double tStep)
         }
         
         // --- save new washoff concentration
-        if ( !hasOutflow ) cOut = 0.0;
         Subcatch[j].newQual[p] = cOut / LperFT3;
         
         // OWA Addition --- update surface buildup loads (in lbs or kg)
diff --git a/src/solver/text.h b/src/solver/text.h
index 353296b8e..4bb46f059 100644
--- a/src/solver/text.h
+++ b/src/solver/text.h
@@ -3,7 +3,7 @@
 //
 //   Project: EPA SWMM5
 //   Version: 5.2
-//   Date:    12/22/22  (Build 5.2.3)
+//   Date:    07/15/23  (Build 5.2.4)
 //   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.3)"
+  "\n  EPA STORM WATER MANAGEMENT MODEL - VERSION 5.2 (Build 5.2.4)"
 #define FMT09 \
   "\n  ------------------------------------------------------------"
 #define FMT10 "\n"
diff --git a/src/solver/toolkit.c b/src/solver/toolkit.c
index 83571a97e..09d088672 100644
--- a/src/solver/toolkit.c
+++ b/src/solver/toolkit.c
@@ -24,6 +24,16 @@
 #include "swmm5.h"
 #include "toolkit.h"
 
+// Protect against lack of compiler support for OpenMP
+#if defined(_OPENMP)
+#include <omp.h>
+int alt_omp_get_max_threads(void)
+{
+    return omp_get_max_threads();
+}
+#else
+  int alt_omp_get_max_threads(void) { return 1;}
+#endif
 
 // Function Declarations for API
 int  massbal_getRoutingTotal(SM_RoutingTotals **routingTot);
@@ -405,6 +415,8 @@ EXPORT_TOOLKIT int  swmm_getSimulationParam(SM_SimSetting type, double *value)
             case SM_SYSFLOWTOL: *value = SysFlowTol; break;
             // Tolerance for steady nodal inflow
             case SM_LATFLOWTOL: *value = LatFlowTol; break;
+            // Number of Threads (if OpenMP enabled)
+            case SM_THREADS: *value = NumThreads; break;
             // Type not available
             default: error_code = ERR_TKAPI_OUTBOUNDS; break;
         }
@@ -412,6 +424,112 @@ EXPORT_TOOLKIT int  swmm_getSimulationParam(SM_SimSetting type, double *value)
     return error_code;
 }
 
+EXPORT_TOOLKIT int  swmm_setSimulationParam(SM_SimSetting type, double value)
+///
+/// Input:   type = SM_SimSetting
+///          Simulation Parameter
+/// Returns: error code
+/// Purpose: Set simulation analysis parameter (limited support)
+{
+    int error_code = 0;
+
+    // Check if Open
+    if(swmm_IsOpenFlag() == FALSE)
+    {
+        error_code = ERR_TKAPI_INPUTNOTOPEN;
+    }
+    // Check if Simulation is Running
+    else if(swmm_IsStartedFlag() == TRUE)
+    {
+        error_code = ERR_TKAPI_SIM_NRUNNING;
+    }
+    else
+    {
+        switch(type)
+        {
+            case SM_THREADS:
+            {
+                // --- adjust number of parallel threads to be used
+                if ( (int)value <= 0 ) NumThreads = 1;
+                else NumThreads = MIN((int)value, alt_omp_get_max_threads());
+                if ( Nobjects[LINK] < 4 * NumThreads ) NumThreads = 1;
+                break;
+            }
+            default: error_code = ERR_TKAPI_OUTBOUNDS; break;
+        }
+    }
+    return error_code;
+}
+
+EXPORT_TOOLKIT int swmm_hotstart(SM_HotStart type, const char *hsfile)
+///
+/// Input:   type = Hotstart option USE/SAVE (SM_HotStart)
+///          hotstart = file ID name (able to overwrite)
+/// Return   API Error
+/// Purpose: Allows selecting a HSF to use or save
+{
+    int error_code = 0;
+    // Check if Open
+    if(swmm_IsOpenFlag() == FALSE)
+    {
+        error_code = ERR_TKAPI_INPUTNOTOPEN;
+    }
+    // Check if Simulation is Started
+    else if (swmm_IsStartedFlag() == TRUE && type == SM_HOTSTART_USE)
+    {
+        error_code = ERR_TKAPI_SIM_RUNNING;
+    }
+    // Check if Simulation is NOT started
+    else if (swmm_IsStartedFlag() == FALSE && type == SM_HOTSTART_SAVE)
+    {
+        error_code = ERR_TKAPI_SIM_NRUNNING;
+    }
+    else
+    {
+        switch(type)
+        {
+            case SM_HOTSTART_USE:
+            {
+                // Fhotstart1 is the file to to be read
+                char fl_name[MAXFNAME];
+                sstrncpy(fl_name, hsfile, MAXFNAME);
+                Fhotstart1.mode = USE_FILE;
+                sstrncpy(Fhotstart1.name, fl_name, MAXFNAME);
+                break;
+            }
+            case SM_HOTSTART_SAVE:
+            {
+                // Storing Existing INP set HSFs
+                TFile tmpHotstart1 = Fhotstart1;
+                TFile tmpHotstart2 = Fhotstart2;
+                int _fl1_info = Fhotstart1.mode;
+                int _fl2_info = Fhotstart2.mode;
+                // Create info for New HSF
+                Fhotstart1.mode = NO_FILE;
+                Fhotstart2.mode = SAVE_FILE;
+                sstrncpy(Fhotstart2.name, hsfile, MAXFNAME);
+                // Saving Data
+                if (hotstart_open())
+                {
+                    hotstart_close();
+                    // Replacing INP set HSFs
+                    Fhotstart2 = tmpHotstart2;
+                    Fhotstart1 = tmpHotstart1;
+                    Fhotstart1.mode = _fl1_info;
+                    Fhotstart2.mode = _fl2_info;
+                }
+                else
+                {
+                    error_code = ERR_HOTSTART_FILE_OPEN;
+                }
+                break;
+            }
+            default: error_code = ERR_TKAPI_OUTBOUNDS; break;
+        }
+    }
+    return error_code;
+}
+
 EXPORT_TOOLKIT int  swmm_countObjects(SM_ObjectType type, int *count)
 ///
 /// Input:   type = object type (Based on SM_ObjectType enum)
diff --git a/src/solver/transect.c b/src/solver/transect.c
index 831ba017f..6ebd25558 100644
--- a/src/solver/transect.c
+++ b/src/solver/transect.c
@@ -3,7 +3,7 @@
 //
 //   Project:  EPA SWMM5
 //   Version:  5.2
-//   Date:     11/01/21   (Build 5.2.0)
+//   Date:     07/13/23   (Build 5.2.4)
 //   Author:   L. Rossman
 //
 //   Geometry processing for irregular cross-section transects.
@@ -12,6 +12,8 @@
 //   ==============
 //   Build 5.2.0:
 //   - Function added to create a transect for a Street cross-section.
+//   Build 5.2.4:
+//   - Corrected street transect points in transect_createStreetTransect.
 //-----------------------------------------------------------------------------
 #define _CRT_SECURE_NO_DEPRECATE
 
@@ -610,8 +612,8 @@ void  transect_createStreetTransect(TStreet* street)
     w2 = street->gutterWidth;
     w3 = street->width;
     w4 = w3 - w2;
-    y3 = street->gutterDepression;
-    y1 = street->curbHeight + y3;
+    y3 = street->gutterDepression + street->slope * w2;
+    y1 = street->curbHeight + street->gutterDepression;
     ymax = street->backSlope * street->backWidth + y1;
     y4 = y3 + street->slope * w4;
     ymax = MAX(ymax, y4);


Test patch:
diff --git a/.github/workflows/build-test.yml b/.github/workflows/build-test.yml
index c224b9e7d..a23d17dc4 100644
--- a/.github/workflows/build-test.yml
+++ b/.github/workflows/build-test.yml
@@ -20,7 +20,7 @@ jobs:
     strategy:
       fail-fast: false
       matrix:
-        os: [windows-2022, ubuntu-20.04, macos-10.15]
+        os: [windows-2022, ubuntu-20.04, macos-12]
         requirements: [requirements-swmm.txt]
         include:
           - os: windows-2022
@@ -58,9 +58,9 @@ jobs:
                 shell: bash
                 working-directory: ./ci-tools/linux
 
-          - os: macos-10.15
+          - os: macos-12
             sys_pkgs: brew install libomp #boost
-            boost_platform_version: 10.15
+            boost_platform_version: 12
             boost_toolsit: clang
             build_unit_test: make.zsh -t -g "Xcode"
             build_reg_test: make.zsh -g "Xcode"
@@ -94,7 +94,7 @@ jobs:
       - name: Clone ci-tools repo
         uses: actions/checkout@v3
         with:
-          repository: OpenWaterAnalytics/ci-tools
+          repository: pyswmm/ci-tools
           ref: master
           path: ci-tools
 
@@ -111,11 +111,11 @@ jobs:
       # install boost on mac and linux
       - name: Install required system packages on mac and linux
         run: ${{ matrix.sys_pkgs }}
-        if: ${{ runner.os == 'macOS' }} 
+        if: ${{ runner.os == 'macOS' }}
 
       # boost takes a while to install on windows, so try to cache
       - name: Install boost
-        # if: ${{runner.os == 'Windows'}} 
+        # if: ${{runner.os == 'Windows'}}
         uses: MarkusJx/install-boost@v2.4.4
         id: install-boost
         with:
@@ -123,7 +123,7 @@ jobs:
             # A list of supported versions can be found here:
             # https://github.com/MarkusJx/prebuilt-boost/blob/main/versions-manifest.json
             boost_version: 1.81.0
-            link: shared 
+            link: shared
             # OPTIONAL: Specify a custon install location
             # boost_install_dir: C:\some_directory
             # OPTIONAL: Specify a platform version
@@ -143,8 +143,8 @@ jobs:
 
       - name: Before reg test
         env:
-          NRTESTS_URL: https://github.com/OpenWaterAnalytics/swmm-nrtestsuite
-          BENCHMARK_TAG: v3.0.1
+          NRTESTS_URL: https://github.com/pyswmm/swmm-nrtestsuite
+          BENCHMARK_TAG: v3.1.0
         run: ./${{ matrix.before_reg_test }} ${{ env.BENCHMARK_TAG }}
 
       - name: Run reg test
diff --git a/tests/outfile/test_output.cpp b/tests/outfile/test_output.cpp
index 1d44400ad..2494bd3c1 100644
--- a/tests/outfile/test_output.cpp
+++ b/tests/outfile/test_output.cpp
@@ -268,6 +268,26 @@ BOOST_FIXTURE_TEST_CASE(test_getSubcatchSeries, Fixture) {
     BOOST_CHECK(check_cdd_float(test_vec, ref_vec, 3));
 }
 
+BOOST_FIXTURE_TEST_CASE(test_getSystemSeries, Fixture) {
+    error = SMO_getSystemSeries(p_handle, SMO_runoff_flow, 0, 10, &array,
+                                  &array_dim);
+    BOOST_REQUIRE(error == 0);
+
+    const int ref_dim            = 10;
+    float     ref_array[ref_dim] = {
+        0.0f, 6.216825f, 13.030855f, 24.252975f, 14.172027f, 4.1949716f,
+		0.322329f, 0.056010f, 0.024938f, 0.012474f};
+
+    std::vector<float> ref_vec;
+    ref_vec.assign(ref_array, ref_array + 10);
+
+    std::vector<float> test_vec;
+    test_vec.assign(array, array + array_dim);
+
+    BOOST_CHECK(check_cdd_float(test_vec, ref_vec, 3));
+}
+
+
 BOOST_FIXTURE_TEST_CASE(test_getSubcatchResult, Fixture) {
     error = SMO_getSubcatchResult(p_handle, 1, 1, &array, &array_dim);
     BOOST_REQUIRE(error == 0);
diff --git a/tests/solver/CMakeLists.txt b/tests/solver/CMakeLists.txt
index 021832fbb..0a1bdfe1a 100644
--- a/tests/solver/CMakeLists.txt
+++ b/tests/solver/CMakeLists.txt
@@ -38,6 +38,7 @@ set(solver_test_srcs
     test_solver.cpp
     test_stats.cpp
     test_inlets_and_drains.cpp
+    test_toolkit_hotstart.cpp
     # ADD NEW TEST SUITES TO EXISTING TOOLKIT TEST MODULE
 )
 
diff --git a/tests/solver/data/hotstart/Simulation1.inp b/tests/solver/data/hotstart/Simulation1.inp
new file mode 100644
index 000000000..3f2639fc3
--- /dev/null
+++ b/tests/solver/data/hotstart/Simulation1.inp
@@ -0,0 +1,217 @@
+[TITLE]
+;;Project Title/Notes
+Example 1
+
+[OPTIONS]
+;;Option             Value
+FLOW_UNITS           CFS
+INFILTRATION         HORTON
+FLOW_ROUTING         DYNWAVE
+LINK_OFFSETS         DEPTH
+MIN_SLOPE            0
+ALLOW_PONDING        NO
+SKIP_STEADY_STATE    NO
+
+START_DATE           01/01/1998
+START_TIME           00:00:00
+REPORT_START_DATE    01/01/1998
+REPORT_START_TIME    00:00:00
+END_DATE             01/02/1998
+END_TIME             12:00:00
+SWEEP_START          1/1
+SWEEP_END            12/31
+DRY_DAYS             5
+REPORT_STEP          01:00:00
+WET_STEP             00:15:00
+DRY_STEP             01:00:00
+ROUTING_STEP         0:01:00
+
+INERTIAL_DAMPING     PARTIAL
+NORMAL_FLOW_LIMITED  BOTH
+FORCE_MAIN_EQUATION  H-W
+VARIABLE_STEP        0.75
+LENGTHENING_STEP     0
+MIN_SURFAREA         0
+MAX_TRIALS           0
+HEAD_TOLERANCE       0
+SYS_FLOW_TOL         5
+LAT_FLOW_TOL         5
+;MINIMUM_STEP        0.5
+THREADS              1
+
+[FILES]
+SAVE HOTSTART INFILE_Simulation1.hsf
+
+[EVAPORATION]
+;;Data Source    Parameters
+;;-------------- ----------------
+CONSTANT         0.0
+DRY_ONLY         NO
+
+[RAINGAGES]
+;;Name           Format    Interval SCF      Source
+;;-------------- --------- ------ ------ ----------
+RG1              INTENSITY 1:00     1.0      TIMESERIES TS1
+
+[SUBCATCHMENTS]
+;;Name           Rain Gage        Outlet           Area     %Imperv  Width    %Slope   CurbLen  SnowPack
+;;-------------- ---------------- ---------------- -------- -------- -------- -------- -------- ----------------
+1                RG1              9                10       50       500      0.01     0
+2                RG1              10               10       50       500      0.01     0
+3                RG1              13               5        50       500      0.01     0
+4                RG1              22               5        50       500      0.01     0
+5                RG1              15               15       50       500      0.01     0
+6                RG1              23               12       10       500      0.01     0
+7                RG1              19               4        10       500      0.01     0
+8                RG1              18               10       10       500      0.01     0
+
+[SUBAREAS]
+;;Subcatchment   N-Imperv   N-Perv     S-Imperv   S-Perv     PctZero    RouteTo    PctRouted
+;;-------------- ---------- ---------- ---------- ---------- ---------- ---------- ----------
+1                0.001      0.10       0.05       0.05       25         OUTLET
+2                0.001      0.10       0.05       0.05       25         OUTLET
+3                0.001      0.10       0.05       0.05       25         OUTLET
+4                0.001      0.10       0.05       0.05       25         OUTLET
+5                0.001      0.10       0.05       0.05       25         OUTLET
+6                0.001      0.10       0.05       0.05       25         OUTLET
+7                0.001      0.10       0.05       0.05       25         OUTLET
+8                0.001      0.10       0.05       0.05       25         OUTLET
+
+[INFILTRATION]
+;;Subcatchment   MaxRate    MinRate    Decay      DryTime    MaxInfil
+;;-------------- ---------- ---------- ---------- ---------- ----------
+1                0.35       0.25       4.14       0.50       0
+2                0.7        0.3        4.14       0.50       0
+3                0.7        0.3        4.14       0.50       0
+4                0.7        0.3        4.14       0.50       0
+5                0.7        0.3        4.14       0.50       0
+6                0.7        0.3        4.14       0.50       0
+7                0.7        0.3        4.14       0.50       0
+8                0.7        0.3        4.14       0.50       0
+
+[JUNCTIONS]
+;;Name           Elevation  MaxDepth   InitDepth  SurDepth   Aponded
+;;-------------- ---------- ---------- ---------- ---------- ----------
+9                1000       3          0          0          0
+10               995        3          0          0          0
+13               995        3          0          0          0
+14               990        3          0          0          0
+15               987        3          0          0          0
+16               985        3          0          0          0
+17               980        3          0          0          0
+19               1010       3          0          0          0
+20               1005       3          0          0          0
+21               990        3          0          0          0
+22               987        3          0          0          0
+23               990        3          0          0          0
+24               984        3          0          0          0
+
+[OUTFALLS]
+;;Name           Elevation  Type       Stage Data       Gated    Route To
+;;-------------- ---------- ---------- ---------------- -------- ----------------
+18               975        FREE                        NO
+
+[CONDUITS]
+;;Name           From Node        To Node          Length     Roughness  InOffset   OutOffset  InitFlow   MaxFlow
+;;-------------- ---------------- ---------------- ---------- ---------- ---------- ---------- ---------- ----------
+1                9                10               400        0.01       0          0          0          0
+4                19               20               200        0.01       0          0          0          0
+5                20               21               200        0.01       0          0          0          0
+6                10               21               400        0.01       0          1          0          0
+7                21               22               300        0.01       1          1          0          0
+8                22               16               300        0.01       0          0          0          0
+10               17               18               400        0.01       0          0          0          0
+11               13               14               400        0.01       0          0          0          0
+12               14               15               400        0.01       0          0          0          0
+13               15               16               400        0.01       0          0          0          0
+14               23               24               400        0.01       0          0          0          0
+15               16               24               100        0.01       0          0          0          0
+16               24               17               400        0.01       0          0          0          0
+
+[XSECTIONS]
+;;Link           Shape        Geom1            Geom2      Geom3      Geom4      Barrels    Culvert
+;;-------------- ------------ ---------------- ---------- ---------- ---------- ---------- ----------
+1                CIRCULAR     1.5              0          0          0          1
+4                CIRCULAR     1                0          0          0          1
+5                CIRCULAR     1                0          0          0          1
+6                CIRCULAR     1                0          0          0          1
+7                CIRCULAR     2                0          0          0          1
+8                CIRCULAR     2                0          0          0          1
+10               CIRCULAR     2                0          0          0          1
+11               CIRCULAR     1.5              0          0          0          1
+12               CIRCULAR     1.5              0          0          0          1
+13               CIRCULAR     1.5              0          0          0          1
+14               CIRCULAR     1                0          0          0          1
+15               CIRCULAR     2                0          0          0          1
+16               CIRCULAR     2                0          0          0          1
+
+[POLLUTANTS]
+;;Name           Units  Crain      Cgw        Crdii      Kdecay     SnowOnly   Co-Pollutant     Co-Frac    Cdwf       Cinit
+;;-------------- ------ ---------- ---------- ---------- ---------- ---------- ---------------- ---------- ---------- ----------
+TSS              MG/L   0.0        0.0        0          0.0        NO         *                0.0        0          0
+Lead             UG/L   0.0        0.0        0          0.0        NO         TSS              0.2        0          0
+
+[LANDUSES]
+;;               Sweeping   Fraction   Last
+;;Name           Interval   Available  Swept
+;;-------------- ---------- ---------- ----------
+Residential
+Undeveloped
+
+[COVERAGES]
+;;Subcatchment   Land Use         Percent
+;;-------------- ---------------- ----------
+1                Residential      100.00
+2                Residential      50.00
+2                Undeveloped      50.00
+3                Residential      100.00
+4                Residential      50.00
+4                Undeveloped      50.00
+5                Residential      100.00
+6                Undeveloped      100.00
+7                Undeveloped      100.00
+8                Undeveloped      100.00
+
+[LOADINGS]
+;;Subcatchment   Pollutant        Buildup
+;;-------------- ---------------- ----------
+
+[BUILDUP]
+;;Land Use       Pollutant        Function   Coeff1     Coeff2     Coeff3     Per Unit
+;;-------------- ---------------- ---------- ---------- ---------- ---------- ----------
+Residential      TSS              SAT        50         0          2          AREA
+Residential      Lead             NONE       0          0          0          AREA
+Undeveloped      TSS              SAT        100        0          3          AREA
+Undeveloped      Lead             NONE       0          0          0          AREA
+
+[WASHOFF]
+;;Land Use       Pollutant        Function   Coeff1     Coeff2     SweepRmvl  BmpRmvl
+;;-------------- ---------------- ---------- ---------- ---------- ---------- ----------
+Residential      TSS              EXP        0.1        1          0          0
+Residential      Lead             EMC        0          0          0          0
+Undeveloped      TSS              EXP        0.1        0.7        0          0
+Undeveloped      Lead             EMC        0          0          0          0
+
+[TIMESERIES]
+;;Name           Date       Time       Value
+;;-------------- ---------- ---------- ----------
+;RAINFALL
+TS1                         0:00       0.0
+TS1                         1:00       0.25
+TS1                         2:00       0.5
+TS1                         3:00       0.8
+TS1                         4:00       0.4
+TS1                         5:00       0.1
+TS1                         6:00       0.0
+TS1                         27:00      0.0
+TS1                         28:00      0.4
+TS1                         29:00      0.2
+TS1                         30:00      0.0
+
+[REPORT]
+;;Reporting Options
+INPUT      NO
+CONTROLS   NO
+SUBCATCHMENTS ALL
+NODES ALL
+LINKS ALL
diff --git a/tests/solver/data/hotstart/Simulation1_use_hot_start.inp b/tests/solver/data/hotstart/Simulation1_use_hot_start.inp
new file mode 100644
index 000000000..d3aba0d0b
--- /dev/null
+++ b/tests/solver/data/hotstart/Simulation1_use_hot_start.inp
@@ -0,0 +1,215 @@
+[TITLE]
+;;Project Title/Notes
+Example 1
+
+[OPTIONS]
+;;Option             Value
+FLOW_UNITS           CFS
+INFILTRATION         HORTON
+FLOW_ROUTING         DYNWAVE
+LINK_OFFSETS         DEPTH
+MIN_SLOPE            0
+ALLOW_PONDING        NO
+SKIP_STEADY_STATE    NO
+
+START_DATE           01/01/1998
+START_TIME           00:00:00
+REPORT_START_DATE    01/01/1998
+REPORT_START_TIME    00:00:00
+END_DATE             01/02/1998
+END_TIME             12:00:00
+SWEEP_START          1/1
+SWEEP_END            12/31
+DRY_DAYS             5
+REPORT_STEP          01:00:00
+WET_STEP             00:15:00
+DRY_STEP             01:00:00
+ROUTING_STEP         0:00:01
+
+INERTIAL_DAMPING     PARTIAL
+NORMAL_FLOW_LIMITED  BOTH
+FORCE_MAIN_EQUATION  H-W
+VARIABLE_STEP        0.75
+LENGTHENING_STEP     0
+MIN_SURFAREA         0
+MAX_TRIALS           0
+HEAD_TOLERANCE       0
+SYS_FLOW_TOL         5
+LAT_FLOW_TOL         5
+;MINIMUM_STEP        0.5
+THREADS              1
+
+
+[EVAPORATION]
+;;Data Source    Parameters
+;;-------------- ----------------
+CONSTANT         0.0
+DRY_ONLY         NO
+
+[RAINGAGES]
+;;Name           Format    Interval SCF      Source
+;;-------------- --------- ------ ------ ----------
+RG1              INTENSITY 1:00     1.0      TIMESERIES TS1
+
+[SUBCATCHMENTS]
+;;Name           Rain Gage        Outlet           Area     %Imperv  Width    %Slope   CurbLen  SnowPack
+;;-------------- ---------------- ---------------- -------- -------- -------- -------- -------- ----------------
+1                RG1              9                10       50       500      0.01     0
+2                RG1              10               10       50       500      0.01     0
+3                RG1              13               5        50       500      0.01     0
+4                RG1              22               5        50       500      0.01     0
+5                RG1              15               15       50       500      0.01     0
+6                RG1              23               12       10       500      0.01     0
+7                RG1              19               4        10       500      0.01     0
+8                RG1              18               10       10       500      0.01     0
+
+[SUBAREAS]
+;;Subcatchment   N-Imperv   N-Perv     S-Imperv   S-Perv     PctZero    RouteTo    PctRouted
+;;-------------- ---------- ---------- ---------- ---------- ---------- ---------- ----------
+1                0.001      0.10       0.05       0.05       25         OUTLET
+2                0.001      0.10       0.05       0.05       25         OUTLET
+3                0.001      0.10       0.05       0.05       25         OUTLET
+4                0.001      0.10       0.05       0.05       25         OUTLET
+5                0.001      0.10       0.05       0.05       25         OUTLET
+6                0.001      0.10       0.05       0.05       25         OUTLET
+7                0.001      0.10       0.05       0.05       25         OUTLET
+8                0.001      0.10       0.05       0.05       25         OUTLET
+
+[INFILTRATION]
+;;Subcatchment   MaxRate    MinRate    Decay      DryTime    MaxInfil
+;;-------------- ---------- ---------- ---------- ---------- ----------
+1                0.35       0.25       4.14       0.50       0
+2                0.7        0.3        4.14       0.50       0
+3                0.7        0.3        4.14       0.50       0
+4                0.7        0.3        4.14       0.50       0
+5                0.7        0.3        4.14       0.50       0
+6                0.7        0.3        4.14       0.50       0
+7                0.7        0.3        4.14       0.50       0
+8                0.7        0.3        4.14       0.50       0
+
+[JUNCTIONS]
+;;Name           Elevation  MaxDepth   InitDepth  SurDepth   Aponded
+;;-------------- ---------- ---------- ---------- ---------- ----------
+9                1000       3          0          0          0
+10               995        3          0          0          0
+13               995        3          0          0          0
+14               990        3          0          0          0
+15               987        3          0          0          0
+16               985        3          0          0          0
+17               980        3          0          0          0
+19               1010       3          0          0          0
+20               1005       3          0          0          0
+21               990        3          0          0          0
+22               987        3          0          0          0
+23               990        3          0          0          0
+24               984        3          0          0          0
+
+[OUTFALLS]
+;;Name           Elevation  Type       Stage Data       Gated    Route To
+;;-------------- ---------- ---------- ---------------- -------- ----------------
+18               975        FREE                        NO
+
+[CONDUITS]
+;;Name           From Node        To Node          Length     Roughness  InOffset   OutOffset  InitFlow   MaxFlow
+;;-------------- ---------------- ---------------- ---------- ---------- ---------- ---------- ---------- ----------
+1                9                10               400        0.01       0          0          0          0
+4                19               20               200        0.01       0          0          0          0
+5                20               21               200        0.01       0          0          0          0
+6                10               21               400        0.01       0          1          0          0
+7                21               22               300        0.01       1          1          0          0
+8                22               16               300        0.01       0          0          0          0
+10               17               18               400        0.01       0          0          0          0
+11               13               14               400        0.01       0          0          0          0
+12               14               15               400        0.01       0          0          0          0
+13               15               16               400        0.01       0          0          0          0
+14               23               24               400        0.01       0          0          0          0
+15               16               24               100        0.01       0          0          0          0
+16               24               17               400        0.01       0          0          0          0
+
+[XSECTIONS]
+;;Link           Shape        Geom1            Geom2      Geom3      Geom4      Barrels    Culvert
+;;-------------- ------------ ---------------- ---------- ---------- ---------- ---------- ----------
+1                CIRCULAR     1.5              0          0          0          1
+4                CIRCULAR     1                0          0          0          1
+5                CIRCULAR     1                0          0          0          1
+6                CIRCULAR     1                0          0          0          1
+7                CIRCULAR     2                0          0          0          1
+8                CIRCULAR     2                0          0          0          1
+10               CIRCULAR     2                0          0          0          1
+11               CIRCULAR     1.5              0          0          0          1
+12               CIRCULAR     1.5              0          0          0          1
+13               CIRCULAR     1.5              0          0          0          1
+14               CIRCULAR     1                0          0          0          1
+15               CIRCULAR     2                0          0          0          1
+16               CIRCULAR     2                0          0          0          1
+
+[POLLUTANTS]
+;;Name           Units  Crain      Cgw        Crdii      Kdecay     SnowOnly   Co-Pollutant     Co-Frac    Cdwf       Cinit
+;;-------------- ------ ---------- ---------- ---------- ---------- ---------- ---------------- ---------- ---------- ----------
+TSS              MG/L   0.0        0.0        0          0.0        NO         *                0.0        0          0
+Lead             UG/L   0.0        0.0        0          0.0        NO         TSS              0.2        0          0
+
+[LANDUSES]
+;;               Sweeping   Fraction   Last
+;;Name           Interval   Available  Swept
+;;-------------- ---------- ---------- ----------
+Residential
+Undeveloped
+
+[COVERAGES]
+;;Subcatchment   Land Use         Percent
+;;-------------- ---------------- ----------
+1                Residential      100.00
+2                Residential      50.00
+2                Undeveloped      50.00
+3                Residential      100.00
+4                Residential      50.00
+4                Undeveloped      50.00
+5                Residential      100.00
+6                Undeveloped      100.00
+7                Undeveloped      100.00
+8                Undeveloped      100.00
+
+[LOADINGS]
+;;Subcatchment   Pollutant        Buildup
+;;-------------- ---------------- ----------
+
+[BUILDUP]
+;;Land Use       Pollutant        Function   Coeff1     Coeff2     Coeff3     Per Unit
+;;-------------- ---------------- ---------- ---------- ---------- ---------- ----------
+Residential      TSS              SAT        50         0          2          AREA
+Residential      Lead             NONE       0          0          0          AREA
+Undeveloped      TSS              SAT        100        0          3          AREA
+Undeveloped      Lead             NONE       0          0          0          AREA
+
+[WASHOFF]
+;;Land Use       Pollutant        Function   Coeff1     Coeff2     SweepRmvl  BmpRmvl
+;;-------------- ---------------- ---------- ---------- ---------- ---------- ----------
+Residential      TSS              EXP        0.1        1          0          0
+Residential      Lead             EMC        0          0          0          0
+Undeveloped      TSS              EXP        0.1        0.7        0          0
+Undeveloped      Lead             EMC        0          0          0          0
+
+[TIMESERIES]
+;;Name           Date       Time       Value
+;;-------------- ---------- ---------- ----------
+;RAINFALL
+TS1                         0:00       0.0
+TS1                         1:00       0.25
+TS1                         2:00       0.5
+TS1                         3:00       0.8
+TS1                         4:00       0.4
+TS1                         5:00       0.1
+TS1                         6:00       0.0
+TS1                         27:00      0.0
+TS1                         28:00      0.4
+TS1                         29:00      0.2
+TS1                         30:00      0.0
+
+[REPORT]
+;;Reporting Options
+INPUT      NO
+CONTROLS   NO
+SUBCATCHMENTS ALL
+NODES ALL
+LINKS ALL
diff --git a/tests/solver/data/hotstart/Simulation2.inp b/tests/solver/data/hotstart/Simulation2.inp
new file mode 100644
index 000000000..f6af08f88
--- /dev/null
+++ b/tests/solver/data/hotstart/Simulation2.inp
@@ -0,0 +1,217 @@
+[TITLE]
+;;Project Title/Notes
+Example 1
+
+[OPTIONS]
+;;Option             Value
+FLOW_UNITS           CFS
+INFILTRATION         HORTON
+FLOW_ROUTING         DYNWAVE
+LINK_OFFSETS         DEPTH
+MIN_SLOPE            0
+ALLOW_PONDING        NO
+SKIP_STEADY_STATE    NO
+
+START_DATE           01/01/1998
+START_TIME           00:00:00
+REPORT_START_DATE    01/01/1998
+REPORT_START_TIME    00:00:00
+END_DATE             01/02/1998
+END_TIME             12:00:00
+SWEEP_START          1/1
+SWEEP_END            12/31
+DRY_DAYS             5
+REPORT_STEP          01:00:00
+WET_STEP             00:15:00
+DRY_STEP             01:00:00
+ROUTING_STEP         0:01:00
+
+INERTIAL_DAMPING     PARTIAL
+NORMAL_FLOW_LIMITED  BOTH
+FORCE_MAIN_EQUATION  H-W
+VARIABLE_STEP        0.75
+LENGTHENING_STEP     0
+MIN_SURFAREA         0
+MAX_TRIALS           0
+HEAD_TOLERANCE       0
+SYS_FLOW_TOL         5
+LAT_FLOW_TOL         5
+;MINIMUM_STEP        0.5
+THREADS              1
+
+[FILES]
+SAVE HOTSTART INFILE_Simulation2.hsf
+
+[EVAPORATION]
+;;Data Source    Parameters
+;;-------------- ----------------
+CONSTANT         0.0
+DRY_ONLY         NO
+
+[RAINGAGES]
+;;Name           Format    Interval SCF      Source
+;;-------------- --------- ------ ------ ----------
+RG1              INTENSITY 1:00     1.0      TIMESERIES TS1
+
+[SUBCATCHMENTS]
+;;Name           Rain Gage        Outlet           Area     %Imperv  Width    %Slope   CurbLen  SnowPack
+;;-------------- ---------------- ---------------- -------- -------- -------- -------- -------- ----------------
+1                RG1              9                10       50       500      0.01     0
+2                RG1              10               10       50       500      0.01     0
+3                RG1              13               5        50       500      0.01     0
+4                RG1              22               5        50       500      0.01     0
+5                RG1              15               15       50       500      0.01     0
+6                RG1              23               12       10       500      0.01     0
+7                RG1              19               4        10       500      0.01     0
+8                RG1              18               10       10       500      0.01     0
+
+[SUBAREAS]
+;;Subcatchment   N-Imperv   N-Perv     S-Imperv   S-Perv     PctZero    RouteTo    PctRouted
+;;-------------- ---------- ---------- ---------- ---------- ---------- ---------- ----------
+1                0.001      0.10       0.05       0.05       25         OUTLET
+2                0.001      0.10       0.05       0.05       25         OUTLET
+3                0.001      0.10       0.05       0.05       25         OUTLET
+4                0.001      0.10       0.05       0.05       25         OUTLET
+5                0.001      0.10       0.05       0.05       25         OUTLET
+6                0.001      0.10       0.05       0.05       25         OUTLET
+7                0.001      0.10       0.05       0.05       25         OUTLET
+8                0.001      0.10       0.05       0.05       25         OUTLET
+
+[INFILTRATION]
+;;Subcatchment   MaxRate    MinRate    Decay      DryTime    MaxInfil
+;;-------------- ---------- ---------- ---------- ---------- ----------
+1                0.35       0.25       4.14       0.50       0
+2                0.7        0.3        4.14       0.50       0
+3                0.7        0.3        4.14       0.50       0
+4                0.7        0.3        4.14       0.50       0
+5                0.7        0.3        4.14       0.50       0
+6                0.7        0.3        4.14       0.50       0
+7                0.7        0.3        4.14       0.50       0
+8                0.7        0.3        4.14       0.50       0
+
+[JUNCTIONS]
+;;Name           Elevation  MaxDepth   InitDepth  SurDepth   Aponded
+;;-------------- ---------- ---------- ---------- ---------- ----------
+9                1000       3          0          0          0
+10               995        3          0          0          0
+13               995        3          0          0          0
+14               990        3          0          0          0
+15               987        3          0          0          0
+16               985        3          0          0          0
+17               980        3          0          0          0
+19               1010       3          0          0          0
+20               1005       3          0          0          0
+21               990        3          0          0          0
+22               987        3          0          0          0
+23               990        3          0          0          0
+24               984        3          0          0          0
+
+[OUTFALLS]
+;;Name           Elevation  Type       Stage Data       Gated    Route To
+;;-------------- ---------- ---------- ---------------- -------- ----------------
+18               975        FREE                        NO
+
+[CONDUITS]
+;;Name           From Node        To Node          Length     Roughness  InOffset   OutOffset  InitFlow   MaxFlow
+;;-------------- ---------------- ---------------- ---------- ---------- ---------- ---------- ---------- ----------
+1                9                10               400        0.01       0          0          0          0
+4                19               20               200        0.01       0          0          0          0
+5                20               21               200        0.01       0          0          0          0
+6                10               21               400        0.01       0          1          0          0
+7                21               22               300        0.01       1          1          0          0
+8                22               16               300        0.01       0          0          0          0
+10               17               18               400        0.01       0          0          0          0
+11               13               14               400        0.01       0          0          0          0
+12               14               15               400        0.01       0          0          0          0
+13               15               16               400        0.01       0          0          0          0
+14               23               24               400        0.01       0          0          0          0
+15               16               24               100        0.01       0          0          0          0
+16               24               17               400        0.01       0          0          0          0
+
+[XSECTIONS]
+;;Link           Shape        Geom1            Geom2      Geom3      Geom4      Barrels    Culvert
+;;-------------- ------------ ---------------- ---------- ---------- ---------- ---------- ----------
+1                CIRCULAR     1.5              0          0          0          1
+4                CIRCULAR     1                0          0          0          1
+5                CIRCULAR     1                0          0          0          1
+6                CIRCULAR     1                0          0          0          1
+7                CIRCULAR     2                0          0          0          1
+8                CIRCULAR     2                0          0          0          1
+10               CIRCULAR     2                0          0          0          1
+11               CIRCULAR     1.5              0          0          0          1
+12               CIRCULAR     1.5              0          0          0          1
+13               CIRCULAR     1.5              0          0          0          1
+14               CIRCULAR     1                0          0          0          1
+15               CIRCULAR     2                0          0          0          1
+16               CIRCULAR     2                0          0          0          1
+
+[POLLUTANTS]
+;;Name           Units  Crain      Cgw        Crdii      Kdecay     SnowOnly   Co-Pollutant     Co-Frac    Cdwf       Cinit
+;;-------------- ------ ---------- ---------- ---------- ---------- ---------- ---------------- ---------- ---------- ----------
+TSS              MG/L   0.0        0.0        0          0.0        NO         *                0.0        0          0
+Lead             UG/L   0.0        0.0        0          0.0        NO         TSS              0.2        0          0
+
+[LANDUSES]
+;;               Sweeping   Fraction   Last
+;;Name           Interval   Available  Swept
+;;-------------- ---------- ---------- ----------
+Residential
+Undeveloped
+
+[COVERAGES]
+;;Subcatchment   Land Use         Percent
+;;-------------- ---------------- ----------
+1                Residential      100.00
+2                Residential      50.00
+2                Undeveloped      50.00
+3                Residential      100.00
+4                Residential      50.00
+4                Undeveloped      50.00
+5                Residential      100.00
+6                Undeveloped      100.00
+7                Undeveloped      100.00
+8                Undeveloped      100.00
+
+[LOADINGS]
+;;Subcatchment   Pollutant        Buildup
+;;-------------- ---------------- ----------
+
+[BUILDUP]
+;;Land Use       Pollutant        Function   Coeff1     Coeff2     Coeff3     Per Unit
+;;-------------- ---------------- ---------- ---------- ---------- ---------- ----------
+Residential      TSS              SAT        50         0          2          AREA
+Residential      Lead             NONE       0          0          0          AREA
+Undeveloped      TSS              SAT        100        0          3          AREA
+Undeveloped      Lead             NONE       0          0          0          AREA
+
+[WASHOFF]
+;;Land Use       Pollutant        Function   Coeff1     Coeff2     SweepRmvl  BmpRmvl
+;;-------------- ---------------- ---------- ---------- ---------- ---------- ----------
+Residential      TSS              EXP        0.1        1          0          0
+Residential      Lead             EMC        0          0          0          0
+Undeveloped      TSS              EXP        0.1        0.7        0          0
+Undeveloped      Lead             EMC        0          0          0          0
+
+[TIMESERIES]
+;;Name           Date       Time       Value
+;;-------------- ---------- ---------- ----------
+;RAINFALL
+TS1                         0:00       0.0
+TS1                         1:00       0.25
+TS1                         2:00       0.5
+TS1                         3:00       0.8
+TS1                         4:00       0.4
+TS1                         5:00       0.1
+TS1                         6:00       0.0
+TS1                         27:00      0.0
+TS1                         28:00      0.4
+TS1                         29:00      0.2
+TS1                         30:00      0.0
+
+[REPORT]
+;;Reporting Options
+INPUT      NO
+CONTROLS   NO
+SUBCATCHMENTS ALL
+NODES ALL
+LINKS ALL
diff --git a/tests/solver/data/hotstart/Simulation3.inp b/tests/solver/data/hotstart/Simulation3.inp
new file mode 100644
index 000000000..f0521e5a0
--- /dev/null
+++ b/tests/solver/data/hotstart/Simulation3.inp
@@ -0,0 +1,217 @@
+[TITLE]
+;;Project Title/Notes
+Example 1
+
+[OPTIONS]
+;;Option             Value
+FLOW_UNITS           CFS
+INFILTRATION         HORTON
+FLOW_ROUTING         DYNWAVE
+LINK_OFFSETS         DEPTH
+MIN_SLOPE            0
+ALLOW_PONDING        NO
+SKIP_STEADY_STATE    NO
+
+START_DATE           01/01/1998
+START_TIME           00:00:00
+REPORT_START_DATE    01/01/1998
+REPORT_START_TIME    00:00:00
+END_DATE             01/02/1998
+END_TIME             12:00:00
+SWEEP_START          1/1
+SWEEP_END            12/31
+DRY_DAYS             5
+REPORT_STEP          01:00:00
+WET_STEP             00:15:00
+DRY_STEP             01:00:00
+ROUTING_STEP         0:00:01
+
+INERTIAL_DAMPING     PARTIAL
+NORMAL_FLOW_LIMITED  BOTH
+FORCE_MAIN_EQUATION  H-W
+VARIABLE_STEP        0.75
+LENGTHENING_STEP     0
+MIN_SURFAREA         0
+MAX_TRIALS           0
+HEAD_TOLERANCE       0
+SYS_FLOW_TOL         5
+LAT_FLOW_TOL         5
+;MINIMUM_STEP        0.5
+THREADS              1
+
+[FILES]
+USE HOTSTART swmm_api_test_during_Simulation1.hsf
+
+[EVAPORATION]
+;;Data Source    Parameters
+;;-------------- ----------------
+CONSTANT         0.0
+DRY_ONLY         NO
+
+[RAINGAGES]
+;;Name           Format    Interval SCF      Source
+;;-------------- --------- ------ ------ ----------
+RG1              INTENSITY 1:00     1.0      TIMESERIES TS1
+
+[SUBCATCHMENTS]
+;;Name           Rain Gage        Outlet           Area     %Imperv  Width    %Slope   CurbLen  SnowPack
+;;-------------- ---------------- ---------------- -------- -------- -------- -------- -------- ----------------
+1                RG1              9                10       50       500      0.01     0
+2                RG1              10               10       50       500      0.01     0
+3                RG1              13               5        50       500      0.01     0
+4                RG1              22               5        50       500      0.01     0
+5                RG1              15               15       50       500      0.01     0
+6                RG1              23               12       10       500      0.01     0
+7                RG1              19               4        10       500      0.01     0
+8                RG1              18               10       10       500      0.01     0
+
+[SUBAREAS]
+;;Subcatchment   N-Imperv   N-Perv     S-Imperv   S-Perv     PctZero    RouteTo    PctRouted
+;;-------------- ---------- ---------- ---------- ---------- ---------- ---------- ----------
+1                0.001      0.10       0.05       0.05       25         OUTLET
+2                0.001      0.10       0.05       0.05       25         OUTLET
+3                0.001      0.10       0.05       0.05       25         OUTLET
+4                0.001      0.10       0.05       0.05       25         OUTLET
+5                0.001      0.10       0.05       0.05       25         OUTLET
+6                0.001      0.10       0.05       0.05       25         OUTLET
+7                0.001      0.10       0.05       0.05       25         OUTLET
+8                0.001      0.10       0.05       0.05       25         OUTLET
+
+[INFILTRATION]
+;;Subcatchment   MaxRate    MinRate    Decay      DryTime    MaxInfil
+;;-------------- ---------- ---------- ---------- ---------- ----------
+1                0.35       0.25       4.14       0.50       0
+2                0.7        0.3        4.14       0.50       0
+3                0.7        0.3        4.14       0.50       0
+4                0.7        0.3        4.14       0.50       0
+5                0.7        0.3        4.14       0.50       0
+6                0.7        0.3        4.14       0.50       0
+7                0.7        0.3        4.14       0.50       0
+8                0.7        0.3        4.14       0.50       0
+
+[JUNCTIONS]
+;;Name           Elevation  MaxDepth   InitDepth  SurDepth   Aponded
+;;-------------- ---------- ---------- ---------- ---------- ----------
+9                1000       3          0          0          0
+10               995        3          0          0          0
+13               995        3          0          0          0
+14               990        3          0          0          0
+15               987        3          0          0          0
+16               985        3          0          0          0
+17               980        3          0          0          0
+19               1010       3          0          0          0
+20               1005       3          0          0          0
+21               990        3          0          0          0
+22               987        3          0          0          0
+23               990        3          0          0          0
+24               984        3          0          0          0
+
+[OUTFALLS]
+;;Name           Elevation  Type       Stage Data       Gated    Route To
+;;-------------- ---------- ---------- ---------------- -------- ----------------
+18               975        FREE                        NO
+
+[CONDUITS]
+;;Name           From Node        To Node          Length     Roughness  InOffset   OutOffset  InitFlow   MaxFlow
+;;-------------- ---------------- ---------------- ---------- ---------- ---------- ---------- ---------- ----------
+1                9                10               400        0.01       0          0          0          0
+4                19               20               200        0.01       0          0          0          0
+5                20               21               200        0.01       0          0          0          0
+6                10               21               400        0.01       0          1          0          0
+7                21               22               300        0.01       1          1          0          0
+8                22               16               300        0.01       0          0          0          0
+10               17               18               400        0.01       0          0          0          0
+11               13               14               400        0.01       0          0          0          0
+12               14               15               400        0.01       0          0          0          0
+13               15               16               400        0.01       0          0          0          0
+14               23               24               400        0.01       0          0          0          0
+15               16               24               100        0.01       0          0          0          0
+16               24               17               400        0.01       0          0          0          0
+
+[XSECTIONS]
+;;Link           Shape        Geom1            Geom2      Geom3      Geom4      Barrels    Culvert
+;;-------------- ------------ ---------------- ---------- ---------- ---------- ---------- ----------
+1                CIRCULAR     1.5              0          0          0          1
+4                CIRCULAR     1                0          0          0          1
+5                CIRCULAR     1                0          0          0          1
+6                CIRCULAR     1                0          0          0          1
+7                CIRCULAR     2                0          0          0          1
+8                CIRCULAR     2                0          0          0          1
+10               CIRCULAR     2                0          0          0          1
+11               CIRCULAR     1.5              0          0          0          1
+12               CIRCULAR     1.5              0          0          0          1
+13               CIRCULAR     1.5              0          0          0          1
+14               CIRCULAR     1                0          0          0          1
+15               CIRCULAR     2                0          0          0          1
+16               CIRCULAR     2                0          0          0          1
+
+[POLLUTANTS]
+;;Name           Units  Crain      Cgw        Crdii      Kdecay     SnowOnly   Co-Pollutant     Co-Frac    Cdwf       Cinit
+;;-------------- ------ ---------- ---------- ---------- ---------- ---------- ---------------- ---------- ---------- ----------
+TSS              MG/L   0.0        0.0        0          0.0        NO         *                0.0        0          0
+Lead             UG/L   0.0        0.0        0          0.0        NO         TSS              0.2        0          0
+
+[LANDUSES]
+;;               Sweeping   Fraction   Last
+;;Name           Interval   Available  Swept
+;;-------------- ---------- ---------- ----------
+Residential
+Undeveloped
+
+[COVERAGES]
+;;Subcatchment   Land Use         Percent
+;;-------------- ---------------- ----------
+1                Residential      100.00
+2                Residential      50.00
+2                Undeveloped      50.00
+3                Residential      100.00
+4                Residential      50.00
+4                Undeveloped      50.00
+5                Residential      100.00
+6                Undeveloped      100.00
+7                Undeveloped      100.00
+8                Undeveloped      100.00
+
+[LOADINGS]
+;;Subcatchment   Pollutant        Buildup
+;;-------------- ---------------- ----------
+
+[BUILDUP]
+;;Land Use       Pollutant        Function   Coeff1     Coeff2     Coeff3     Per Unit
+;;-------------- ---------------- ---------- ---------- ---------- ---------- ----------
+Residential      TSS              SAT        50         0          2          AREA
+Residential      Lead             NONE       0          0          0          AREA
+Undeveloped      TSS              SAT        100        0          3          AREA
+Undeveloped      Lead             NONE       0          0          0          AREA
+
+[WASHOFF]
+;;Land Use       Pollutant        Function   Coeff1     Coeff2     SweepRmvl  BmpRmvl
+;;-------------- ---------------- ---------- ---------- ---------- ---------- ----------
+Residential      TSS              EXP        0.1        1          0          0
+Residential      Lead             EMC        0          0          0          0
+Undeveloped      TSS              EXP        0.1        0.7        0          0
+Undeveloped      Lead             EMC        0          0          0          0
+
+[TIMESERIES]
+;;Name           Date       Time       Value
+;;-------------- ---------- ---------- ----------
+;RAINFALL
+TS1                         0:00       0.0
+TS1                         1:00       0.25
+TS1                         2:00       0.5
+TS1                         3:00       0.8
+TS1                         4:00       0.4
+TS1                         5:00       0.1
+TS1                         6:00       0.0
+TS1                         27:00      0.0
+TS1                         28:00      0.4
+TS1                         29:00      0.2
+TS1                         30:00      0.0
+
+[REPORT]
+;;Reporting Options
+INPUT      NO
+CONTROLS   NO
+SUBCATCHMENTS ALL
+NODES ALL
+LINKS ALL
diff --git a/tests/solver/data/hotstart/use_hot_start_test.hsf b/tests/solver/data/hotstart/use_hot_start_test.hsf
new file mode 100644
index 000000000..d57d38ed5
Binary files /dev/null and b/tests/solver/data/hotstart/use_hot_start_test.hsf differ
diff --git a/tests/solver/test_solver.hpp b/tests/solver/test_solver.hpp
index e45e477b4..6af24963c 100644
--- a/tests/solver/test_solver.hpp
+++ b/tests/solver/test_solver.hpp
@@ -44,6 +44,15 @@ struct FixtureOpenClose{
     }
 };
 
+struct FixtureBeforeStart_TKAPI{
+    FixtureBeforeStart_TKAPI() {
+        swmm_open(DATA_PATH_INP, DATA_PATH_RPT, DATA_PATH_OUT);
+    }
+    ~FixtureBeforeStart_TKAPI() {
+        swmm_close();
+    }
+};
+
 struct FixtureBeforeStep{
     FixtureBeforeStep() {
         swmm_open(DATA_PATH_INP, DATA_PATH_RPT, DATA_PATH_OUT);
diff --git a/tests/solver/test_toolkit.cpp b/tests/solver/test_toolkit.cpp
index 5138c666d..b9d6db8a6 100644
--- a/tests/solver/test_toolkit.cpp
+++ b/tests/solver/test_toolkit.cpp
@@ -22,6 +22,7 @@
 #define ERR_TKAPI_SIM_NRUNNING 2002
 #define ERR_TKAPI_WRONG_TYPE 2003
 #define ERR_TKAPI_OBJECT_INDEX 2004
+#define ERR_TKAPI_SIM_RUNNING 2013
 
 using namespace std;
 
@@ -41,6 +42,10 @@ BOOST_AUTO_TEST_CASE(model_not_open) {
     //Project
     error = swmm_getObjectIndex(SM_NODE, id, &index);
     BOOST_CHECK_EQUAL(error, ERR_TKAPI_INPUTNOTOPEN);
+    error = swmm_hotstart(SM_HOTSTART_USE, id);
+    BOOST_CHECK_EQUAL(error, ERR_TKAPI_INPUTNOTOPEN);
+    error = swmm_hotstart(SM_HOTSTART_SAVE, id);
+    BOOST_CHECK_EQUAL(error, ERR_TKAPI_INPUTNOTOPEN);
 
     //Gage
     error = swmm_getGagePrecip(0, SM_TOTALPRECIP, &val);
@@ -108,10 +113,23 @@ BOOST_AUTO_TEST_SUITE_END()
 
 BOOST_AUTO_TEST_SUITE(test_toolkitapi_fixture)
 
+// Testing for Before Simulation Start Error
+BOOST_FIXTURE_TEST_CASE(sim_before_start, FixtureBeforeStart_TKAPI) {
+    int error;
+    char fakehsf[] = "FakeHSF.hsf";
+
+    error = swmm_hotstart(SM_HOTSTART_SAVE, fakehsf);
+    BOOST_CHECK_EQUAL(error, ERR_TKAPI_SIM_NRUNNING);
+}
+
 // Testing for Simulation Started Error
 BOOST_FIXTURE_TEST_CASE(sim_started_check, FixtureBeforeStep) {
     int error;
+    char fakehsf[] = "FakeHSF.hsf";
 
+    //Project
+    error = swmm_hotstart(SM_HOTSTART_USE, fakehsf);
+    BOOST_CHECK_EQUAL(error, ERR_TKAPI_SIM_RUNNING);
     //Subcatchment
     error = swmm_setSubcatchParam(0, SM_WIDTH, 1);
     BOOST_CHECK_EQUAL(error, ERR_TKAPI_SIM_NRUNNING);
@@ -419,6 +437,17 @@ BOOST_FIXTURE_TEST_CASE(project_info_metric, FixtureMetric) {
     error = swmm_getSimulationParam(SM_HEADTOL, &value);
     BOOST_REQUIRE(error == ERR_NONE);
     BOOST_CHECK_EQUAL(value, 0.015);
+
+    error = swmm_getSimulationParam(SM_THREADS, &value);
+    BOOST_REQUIRE(error == ERR_NONE);
+    BOOST_CHECK_EQUAL(value, 1);
+
+    #if defined(_OPENMP)
+      error = swmm_setSimulationParam(SM_THREADS, 2);
+      error = swmm_getSimulationParam(SM_THREADS, &value);
+      BOOST_REQUIRE(error == ERR_NONE);
+      BOOST_CHECK_EQUAL(value, 2);
+    #endif
 }
 
 
diff --git a/tests/solver/test_toolkit_hotstart.cpp b/tests/solver/test_toolkit_hotstart.cpp
new file mode 100644
index 000000000..617c17269
--- /dev/null
+++ b/tests/solver/test_toolkit_hotstart.cpp
@@ -0,0 +1,237 @@
+/*
+ *   test_toolkitAPI_hotstart.cpp
+ *
+ *   Created: 07/29/2019
+ *   Updated: 06/11/2023
+ *   Author: Bryant E. McDonnell and Jeff Sadler
+ *
+ *   Unit testing mechanics for the hotstart API using Boost Test.
+ */
+
+#include <boost/test/unit_test.hpp>
+#include "test_solver.hpp"
+#include <fstream>
+#include <iterator>
+
+#define HOTSTART_SWMM_SAVE_NORMAL "hotstart/INFILE_Simulation1.hsf"
+#define HOTSTART_API_SAVE_DURING_SIM1 "hotstart/swmm_api_test_during_Simulation1.hsf"
+#define HOTSTART_API_SAVE_AFTER_SIM1 "hotstart/swmm_api_test_after_Simulation1.hsf"
+#define HOTSTART_SWMM_SAVE_SIM2 "hotstart/INFILE_Simulation2.hsf"
+
+#define ERR_NONE 0
+#define ERR_HOTSTART_FILE_OPEN 331
+
+BOOST_AUTO_TEST_SUITE(test_hotstart)
+
+// Testing Run Simulation and Generate Hot Start File using Model (as normal)
+// and save a hot start file using the API swmm_saveHotstart()
+//
+// TEST #1 - Making and Comparing Hot Start Files.
+// In this test 2 simulations will be performed.  One simulation will
+// create hot start files at various time and the second simulation will
+// end at the
+//
+// Start Simulation 1
+// This simulation will produce 3 hot start files:
+//  1. API hotstart File at 1056 Steps into the model ~= 1998-1-1 2:59:58
+//     (HSF Name: HOTSTART_API_SAVE_DURING_SIM1)
+//  2. API created hotstart file at the end of the run
+//     (HSF Name: HOTSTART_API_SAVE_AFTER_SIM1)
+//  3. Normal SWMM [FILES] Generated HSF
+//     (HSF Name: HOTSTART_SWMM_SAVE_NORMAL)
+//
+//  Start Simulation 2
+//  This simulation will end at 1056 Steps into a simulation.
+//     (HSF Name: HOTSTART_SWMM_SAVE_SIM2
+//
+//  The follwing comparisons will be made from these artifacts
+//  1.  HOTSTART_SWMM_SAVE_NORMAL Should == HOTSTART_API_SAVE
+//  2.  HOTSTART_API_SAVE_DURING_SIM1 Should == HOTSTART_SWMM_SAVE_SIM2
+
+BOOST_AUTO_TEST_CASE(save_hotstart_file){
+    int error, step_ind;
+    int index;
+    int number_of_nodes;
+    double elapsedTime = 0.0;
+    double set_val;
+
+    // Start Simulation 1
+    swmm_open((char *)"hotstart/Simulation1.inp",
+              (char *)"hotstart/Simulation1.rpt",
+              (char *)"hotstart/Simulation1.out");
+    swmm_start(1);
+    step_ind = 0;
+    do
+    {
+        error = swmm_step(&elapsedTime);
+        step_ind += 1;
+        if (step_ind == 1056)
+        {
+          error = swmm_hotstart(SM_HOTSTART_SAVE, (char *) HOTSTART_API_SAVE_DURING_SIM1);
+          BOOST_CHECK_EQUAL(ERR_NONE, error);
+        }
+    }while (elapsedTime != 0 && !error);
+    BOOST_CHECK_EQUAL(ERR_NONE, error);
+    // Save New Hotstart File at the End of the Simulation
+    error = swmm_hotstart(SM_HOTSTART_SAVE, (char *) HOTSTART_API_SAVE_AFTER_SIM1);
+    BOOST_CHECK_EQUAL(ERR_NONE, error);
+    swmm_end();
+    swmm_report();
+    swmm_close();
+
+    // Start Simulation 2
+    swmm_open((char *)"hotstart/Simulation2.inp",
+              (char *)"hotstart/Simulation2.rpt",
+              (char *)"hotstart/Simulation2.out");
+    swmm_start(0);
+    step_ind = 0;
+    elapsedTime = 0.0;
+    do
+    {
+        error = swmm_step(&elapsedTime);
+        step_ind += 1;
+    }while (step_ind < 1056 && !error);
+    BOOST_CHECK_EQUAL(ERR_NONE, error);
+    swmm_end();
+    swmm_close();
+
+    std::ifstream ifs1(HOTSTART_SWMM_SAVE_NORMAL);
+    std::ifstream ifs2(HOTSTART_API_SAVE_AFTER_SIM1);
+    std::istream_iterator<char> b1(ifs1), e1;
+    std::istream_iterator<char> b2(ifs2), e2;
+    //iterate over the two hotstart files and check all of them
+    BOOST_CHECK_EQUAL_COLLECTIONS(b1, e1, b2, e2);
+
+    // Diff the three hot start files that come from the model.
+    std::ifstream ifsbench_1998(HOTSTART_SWMM_SAVE_SIM2);
+    std::ifstream ifs1_1998(HOTSTART_API_SAVE_DURING_SIM1);
+    std::istream_iterator<char> bench_1998(ifsbench_1998), ebench_1998;
+    std::istream_iterator<char> b_1998(ifs1_1998), e_1998;
+    // iterate over hotstart files and check all of them
+    BOOST_CHECK_EQUAL_COLLECTIONS(bench_1998, ebench_1998, b_1998, e_1998);
+
+    // Testing USE the new generated hotstart file
+    // Start Simulation 3
+    swmm_open((char *)"hotstart/Simulation3.inp",
+              (char *)"hotstart/Simulation3.rpt",
+              (char *)"hotstart/Simulation3.out");
+    swmm_start(0);
+    error = swmm_step(&elapsedTime);
+    // Iterate over nodes before stepping
+    error = swmm_countObjects(SM_NODE, &number_of_nodes);
+    // Known Values
+    std::vector<double> hotstart_vals {0.0046,
+                                       3.0,
+                                       3.0,
+                                       0.0117,
+                                       0.0,
+                                       0.0,
+                                       0.0,
+                                       0.0105,
+                                       0.0,
+                                       0.1209,
+                                       0.0,
+                                       0.0,
+                                       0.0484,
+                                       0.0};
+
+    for (index=0; index<number_of_nodes; index++)
+    {
+        error = swmm_getNodeResult(index, SM_NODEDEPTH, &set_val);
+        BOOST_CHECK_SMALL(set_val - hotstart_vals[index], 0.5);
+    }
+
+    BOOST_CHECK_EQUAL(ERR_NONE, error);
+    swmm_end();
+    swmm_close();
+}
+
+BOOST_AUTO_TEST_CASE(use_hotstart_bad_file){
+    // Testing USE a bad hotstart file
+    int error;
+    double elapsedTime = 0.0;
+    char fkid[] = "bad_hsf.hsf";
+
+    swmm_open((char *)"hotstart/Simulation1_use_hot_start.inp",
+              (char *)"hotstart/Simulation1_use_hot_start_fail.rpt",
+              (char *)"hotstart/Simulation1_use_hot_start_fail.out");
+    error = swmm_hotstart(SM_HOTSTART_USE, fkid);
+    BOOST_CHECK_EQUAL(ERR_NONE, error);
+    error = swmm_start(0);
+    BOOST_CHECK_EQUAL(ERR_HOTSTART_FILE_OPEN, error);
+    swmm_end();
+    swmm_close();
+}
+
+BOOST_AUTO_TEST_CASE(save_hotstart_file_fail){
+    int error, step_ind;
+    double elapsedTime = 0.0;
+
+    // Start Simulation 1
+    swmm_open((char *)"hotstart/Simulation1_use_hot_start.inp",
+              (char *)"hotstart/Simulation1_use_hot_start_fail1.rpt",
+              (char *)"hotstart/Simulation1_use_hot_start_fail1.out");
+    swmm_start(0);
+    step_ind = 0;
+    do
+    {
+        error = swmm_step(&elapsedTime);
+        step_ind += 1;
+        if (step_ind == 2)
+        {
+          error = swmm_hotstart(SM_HOTSTART_SAVE, (char *) "");
+          BOOST_CHECK_EQUAL(ERR_HOTSTART_FILE_OPEN, error);
+        }
+    }while (elapsedTime != 0 && !error);
+    BOOST_CHECK_EQUAL(ERR_HOTSTART_FILE_OPEN, error);
+    swmm_end();
+    swmm_close();
+    //   ERROR 331: cannot open hot start interface file .
+}
+
+BOOST_AUTO_TEST_CASE(use_hotstart_file){
+    // Testing USE the new generated hotstart file
+    int error;
+    int index;
+    int number_of_nodes;
+    double elapsedTime = 0.0;
+    double set_val;
+    char fkid[] = "hotstart/use_hot_start_test.hsf";
+
+    swmm_open((char *)"hotstart/Simulation1_use_hot_start.inp",
+              (char *)"hotstart/Simulation1_use_hot_start.rpt",
+              (char *)"hotstart/Simulation1_use_hot_start.out");
+    error = swmm_hotstart(SM_HOTSTART_USE, fkid);
+    BOOST_CHECK_EQUAL(ERR_NONE, error);
+    error = swmm_start(0);
+    BOOST_CHECK_EQUAL(ERR_NONE, error);
+    error = swmm_step(&elapsedTime);
+    // Iterate over nodes before stepping
+    error = swmm_countObjects(SM_NODE, &number_of_nodes);
+    // Known Values
+    std::vector<double> hotstart_vals {0.0046,
+                                       3.0,
+                                       3.0,
+                                       0.0117,
+                                       0.0,
+                                       0.0,
+                                       0.0,
+                                       0.0105,
+                                       0.0,
+                                       0.1209,
+                                       0.0,
+                                       0.0,
+                                       0.0484,
+                                       0.0};
+
+    for (index=0; index<number_of_nodes; index++)
+    {
+        error = swmm_getNodeResult(index, SM_NODEDEPTH, &set_val);
+        BOOST_CHECK_SMALL(set_val - hotstart_vals[index], 0.5);
+    }
+    BOOST_CHECK_EQUAL(ERR_NONE, error);
+    swmm_end();
+    swmm_close();
+}
+
+BOOST_AUTO_TEST_SUITE_END()