Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
70 commits
Select commit Hold shift + click to select a range
70c4e2e
NGWPC-4425 add logging to LASAM module
ngwpcareg Nov 19, 2024
f4d2726
Merge branch 'NGWPC-4425' into 'development'
ngwpcareg Nov 19, 2024
6957fd2
missed to commit Logger.cpp/hpp
ngwpcareg Nov 20, 2024
ecafc03
Merge branch 'NGWPC-4425' into 'development'
ngwpcareg Nov 20, 2024
8d90ca2
converted printfs, which on the first cut went under radar, into DEBU…
ngwpcareg Nov 21, 2024
78ef9c1
Merge branch 'NGWPC-4425' into 'development'
zhengtaocui Nov 21, 2024
112f713
Add version.txt file
cmaynard-ngwpc Jan 26, 2025
5e243ad
Merge branch 'cmaynard-add-version-file' into 'development'
cmaynard-ngwpc Jan 26, 2025
888cc57
Merge branch 'development' into 'release-candidate'
cmaynard-ngwpc Jan 26, 2025
c688b07
Merge branch 'release-candidate' into 'master'
cmaynard-ngwpc Feb 1, 2025
75d6d58
Update version file for Release 0.0.0
cmaynard-ngwpc Feb 1, 2025
2d04bb3
Merge branch 'release_0.0.0_udpate_version_file' into 'master'
cmaynard-ngwpc Feb 1, 2025
0d351e5
Merge branch 'master' into 'development'
cmaynard-ngwpc Feb 5, 2025
fb529f6
Revert "converted printfs, which on the first cut went under radar, i…
peterkronenberg-rtx Feb 6, 2025
548f732
Revert "Merge branch 'NGWPC-4425' into 'development'"
peterkronenberg-rtx Feb 6, 2025
1845400
Revert "Merge branch 'NGWPC-4425' into 'development'"
peterkronenberg-rtx Feb 6, 2025
adbe1be
Merge branch 'NGWPC-4425' into 'development'
ngwpcareg Nov 19, 2024
e7ff824
missed to commit Logger.cpp/hpp
ngwpcareg Nov 20, 2024
d82ee97
converted printfs, which on the first cut went under radar, into DEBU…
ngwpcareg Nov 21, 2024
d09248b
Merge branch 'peter_revert_logging' into 'development'
cmaynard-ngwpc Feb 6, 2025
6742d4e
Added RTX licensing verbiage
cmaynard-ngwpc Feb 6, 2025
46b5614
Merge branch 'add_rtx_licencing' into 'development'
cmaynard-ngwpc Feb 6, 2025
2464f9f
fix for NGWPC-5545 issue and some code cleanup/enhancement
ngwpcareg Feb 11, 2025
0d91e4f
Merge branch 'peter_with_logging_for_areg' into 'development'
cmaynard-ngwpc Feb 11, 2025
3edb1a1
Merge branch 'development' into 'release-candidate'
cmaynard-ngwpc Feb 13, 2025
3ce00bf
Update version file for release rc-1.1.0 on 2025-02-12
cmaynard-ngwpc Feb 13, 2025
52197fb
Merge branch 'update_version_file_rc-1.1.0' into 'release-candidate'
cmaynard-ngwpc Feb 13, 2025
723f4f8
Merge branch 'release-candidate' into 'development'
cmaynard-ngwpc Feb 13, 2025
9386553
Merge branch 'release-candidate' into 'master'
cmaynard-ngwpc Feb 26, 2025
4f9a2e2
Update version file for release 1.1.0 on 2025-02-25
cmaynard-ngwpc Feb 26, 2025
481ccf2
Merge branch 'update_version_file_1.1.0' into 'master'
cmaynard-ngwpc Feb 26, 2025
3553d03
Merge branch 'master' into 'development'
cmaynard-ngwpc Feb 26, 2025
150bbff
Fix missing curly braces for log entry
cmaynard-ngwpc Mar 5, 2025
8bd9ee6
Cleanup log entries
cmaynard-ngwpc Mar 5, 2025
1819921
Merge branch 'cmaynard_NGWPC-5694_logging_error' into 'development'
yuqiong77 Mar 6, 2025
9f1e579
Merge branch 'development' into 'release-candidate'
cmaynard-ngwpc Mar 14, 2025
9446ae2
Update version file for release 1.2.0-rc1 on 2025-03-14
cmaynard-ngwpc Mar 14, 2025
98dd2bf
Merge branch 'update_version_file_1.2.0-rc1' into 'release-candidate'
cmaynard-ngwpc Mar 14, 2025
e6f18e9
Merge branch 'release-candidate' into 'development'
cmaynard-ngwpc Mar 14, 2025
122a7dd
Merge branch 'release-candidate' into 'master'
cmaynard-ngwpc Mar 19, 2025
dd547e7
Update version file for release 1.2.0 on 2025-03-19
cmaynard-ngwpc Mar 19, 2025
08a5010
Merge branch 'update_version_file_1.2.0' into 'master'
cmaynard-ngwpc Mar 19, 2025
13c0591
Merge branch 'master' into 'development'
cmaynard-ngwpc Mar 19, 2025
7a2c210
Add CMake artifact generation directory to gitigmore
cmaynard-ngwpc Apr 7, 2025
63dd0e5
Merge branch 'cmaynard_fix_gitignore' into 'development'
cmaynard-ngwpc Apr 7, 2025
1e26bce
Delete version.txt
peterkronenberg-rtx Mar 19, 2025
642842e
Merge branch 'peter_delete_version' into 'development'
peterkronenberg-rtx Apr 9, 2025
976ae94
Add check for logging enabled, change log levels ERROR to WARNING and…
cmaynard-ngwpc May 2, 2025
fcb61a3
Merge branch 'cmaynard_NGWPC_5709_logging_enabled_updates' into 'deve…
cmaynard-ngwpc May 7, 2025
fed14a2
Merge branch 'development' into 'release-candidate'
cmaynard-ngwpc Jun 11, 2025
17b969c
Merge remote-tracking branch 'github/master' into owp-merge-github-ma…
PhilMiller Jul 16, 2025
40b1307
Merge branch 'owp-merge-github-master' into 'development'
cmaynard-ngwpc Jul 23, 2025
494356b
Add serialization methods for BmiLGAR
idtodd Jul 31, 2025
c15952d
Merge branch 'idt/bmi-serialization' into 'development'
idtodd Jul 31, 2025
1753966
Revert "Merge branch 'idt/bmi-serialization' into 'development'"
cmaynard-ngwpc Aug 6, 2025
2fa63cf
Merge branch 'revert-c15952de' into 'development'
cmaynard-ngwpc Aug 6, 2025
9d4e009
State serialization for BMI
idtodd Aug 15, 2025
8c8b605
Merge branch 'idt/bmi-serialization' into 'development'
cmaynard-ngwpc Aug 15, 2025
6bb88ce
Convert Update-related asserts to logging the error and throwing
idtodd Aug 25, 2025
fc9c369
Convert initialization asserts to EWTS messages
idtodd Aug 25, 2025
889ebef
Merge pull request #1 from NGWPC/ewts-message-on-update-asserts
cmaynard-ngwpc Aug 27, 2025
1200e47
Merge pull request #2 from NGWPC/release-candidate
cmaynard-ngwpc Sep 9, 2025
8581e6c
Adapt serialization to revised protocol
PhilMiller Sep 26, 2025
d20e7e3
Merge pull request #5 from NGWPC/PhilMiller-8300-fix-protocol
PhilMiller Oct 9, 2025
c0f5638
Add NWM_PONDED_DEPTH output
idtodd Dec 15, 2025
5ab49ea
Correct misspelling
idtodd Dec 15, 2025
88f18a5
Add GetLogLevel to src file
cmaynard-ngwpc Dec 17, 2025
764dc82
Add NWM Ponded Depth (NGWPC-9175)
idtodd Jan 13, 2026
664f5fb
Merge pull request #8 from NGWPC/development
cmaynard-ngwpc Jan 21, 2026
1352af8
Merge pull request #10 from NGWPC/ngwpc-candidate
cmaynard-ngwpc Feb 11, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -79,3 +79,6 @@ bower_components/
.grunt/
src/vendor/
dist/

# CMake artifact generation directory
/cmake_build
20 changes: 16 additions & 4 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -55,21 +55,30 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -I/usr/X11/include")
# add the executable
#message("CXXLIBS" ${CMAKE_CXX_FLAGS})

# -----------------------------------------------------------------------------
# Find the Boost library and configure usage
set(Boost_USE_STATIC_LIBS OFF)
set(Boost_USE_MULTITHREADED ON)
set(Boost_USE_STATIC_RUNTIME OFF)
find_package(Boost 1.79.0 REQUIRED COMPONENTS serialization)


IF((NOT ${NGEN}) AND (NOT ${STANDALONE}))
message("Pseudo-framework build")
ENDIF((NOT ${NGEN}) AND (NOT ${STANDALONE}))

if(STANDALONE)
add_executable(${exe_name} ./src/bmi_main_lgar.cxx ./src/bmi_lgar.cxx ./src/lgar.cxx ./src/soil_funcs.cxx
./src/linked_list.cxx ./src/mem_funcs.cxx ./src/util_funcs.cxx ./src/aet.cxx
./src/linked_list.cxx ./src/mem_funcs.cxx ./src/util_funcs.cxx ./src/aet.cxx ./src/Logger.cpp ./include/Logger.hpp
./giuh/giuh.h ./giuh/giuh.c)
target_link_libraries(${exe_name} PRIVATE m)
target_link_libraries(${exe_name} PRIVATE Boost::serialization)
elseif(UNITTEST)
add_executable(${exe_name} ./tests/main_unit_test_bmi.cxx ./src/bmi_lgar.cxx ./src/lgar.cxx ./src/soil_funcs.cxx
./src/linked_list.cxx ./src/mem_funcs.cxx ./src/util_funcs.cxx ./src/aet.cxx ./giuh/giuh.h
./src/linked_list.cxx ./src/mem_funcs.cxx ./src/util_funcs.cxx ./src/aet.cxx ./src/Logger.cpp ./include/Logger.hpp ./giuh/giuh.h
./giuh/giuh.c)
target_link_libraries(${exe_name} PRIVATE m)
target_link_libraries(${exe_name} PRIVATE Boost::serialization)
endif()


Expand All @@ -82,18 +91,21 @@ add_compile_definitions(BMI_ACTIVE)

if(WIN32)
add_library(lasambmi SHARED src/bmi_lgar.cxx src/lgar.cxx ./src/soil_funcs.cxx ./src/linked_list.cxx ./src/mem_funcs.cxx
./src/util_funcs.cxx ./src/aet.cxx ./giuh/giuh.c include/all.hxx ./giuh/giuh.h)
./src/util_funcs.cxx ./src/aet.cxx ./src/Logger.cpp ./include/Logger.hpp ./giuh/giuh.c include/all.hxx ./giuh/giuh.h)
else()
add_library(lasambmi SHARED src/bmi_lgar.cxx src/lgar.cxx ./src/soil_funcs.cxx ./src/linked_list.cxx ./src/mem_funcs.cxx
./src/util_funcs.cxx ./src/aet.cxx ./giuh/giuh.c include/all.hxx ./giuh/giuh.h)
./src/util_funcs.cxx ./src/aet.cxx ./src/Logger.cpp ./include/Logger.hpp ./giuh/giuh.c include/all.hxx ./giuh/giuh.h)
endif()


target_include_directories(lasambmi PRIVATE include)

set_target_properties(lasambmi PROPERTIES VERSION ${PROJECT_VERSION})

set_target_properties(lasambmi PROPERTIES PUBLIC_HEADER ./include/bmi_lgar.hxx)

target_link_libraries(lasambmi PRIVATE Boost::serialization)

include(GNUInstallDirs)

install(TARGETS lasambmi
Expand Down
23 changes: 23 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -1,3 +1,26 @@
Copyright 2025 Raytheon Company

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.

Licensed under: https://opensource.org/license/bsd-2-clause

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

All rights reserved. Based on Government sponsored work under contract GS-35F-204GA.

-----------------

“Software code created by U.S. Government employees is not subject to copyright
in the United States (17 U.S.C. §105). The United States/Department of Commerce
reserve all rights to seek and obtain copyright protection in countries other
than the United States for Software authored in its entirety by the Department
of Commerce. To this end, the Department of Commerce hereby grants to Recipient
a royalty-free, nonexclusive license to use, copy, and create derivative works
of the Software outside of the United States.”

Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
Expand Down
66 changes: 66 additions & 0 deletions include/Logger.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
#ifndef LOGGER_HPP
#define LOGGER_HPP

#include <ctime>
#include <fstream>
#include <iostream>
#include <memory>
#include <sstream>
#include <stdlib.h>
#include <string>

#define LOG Logger::Log

enum class LogLevel {
NONE = 0,
DEBUG = 1,
INFO = 2,
WARNING = 3,
SEVERE = 4,
FATAL = 5,
};

/**
* Logger Class Used to Output Details of Current Application Flow
All methods and variables are static so instantiating an object is unnecessary.
*/
class Logger {
public:
// Methods
static void Log(LogLevel messageLevel, const char* message, ...);
static void Log(LogLevel messageLevel, std::string message);
static void Log(std::string message, LogLevel messageLevel = LogLevel::INFO);
static bool IsLoggingEnabled(void);
static LogLevel GetLogLevel(void);

private:
// Methods
static std::string CreateDateString(void);
static std::string CreateTimestamp(bool appendMS = true, bool iso = true);
static bool CreateDirectory(const std::string& path);
static std::string ConvertLogLevelToString(LogLevel level);
static LogLevel ConvertStringToLogLevel(const std::string& logLevel);
static bool DirectoryExists(const std::string& path);
static std::string GetLogFilePath(void);
static bool LogFileReady(bool appendMode=true);
static void SetLogFilePath(void);
static void SetLoggingFlag(void);
static void SetLogLevel(void);
static void SetLogModuleName(void);
static void SetLogPreferences(void);
static std::string ToUpper(const std::string& input);
static std::string TrimString(const std::string& str);

// Variables
// Declaring these static so they exist in the class without needing to instantiate it.
static bool loggerInitialized;
static std::string logFilePath;
static bool loggingEnabled;
static std::fstream logFile;
static LogLevel logLevel;
static std::string moduleName;

static std::shared_ptr<Logger> loggerInstance;
};

#endif
13 changes: 13 additions & 0 deletions include/all.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include <vector>
#include <time.h>
#include <sstream>
#include <boost/serialization/access.hpp>

using namespace std;

Expand Down Expand Up @@ -53,6 +54,18 @@ struct wetting_front
bool to_bottom; // TRUE iff this wetting front is in contact with the layer bottom
double dzdt_cm_per_h; // use to store the calculated wetting front speed
struct wetting_front *next; // pointer to the next wetting front.

template <class Archive>
void serialize(Archive &ar, const unsigned int version) {
ar & this->depth_cm;
ar & this->theta;
ar & this->psi_cm;
ar & this->K_cm_per_h;
ar & this->layer_num;
ar & this->front_num;
ar & this->to_bottom;
ar & this->dzdt_cm_per_h;
}
};

/* head is a GLOBALLY defined pointer to the first link in the wetting front list.
Expand Down
29 changes: 26 additions & 3 deletions include/bmi_lgar.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,15 @@ using namespace std;
#include "../bmi/bmi.hxx"
#include "all.hxx"
#include <stdexcept>
#include "vecbuf.hpp"
#include <boost/serialization/access.hpp>

extern "C" {
#include "../giuh/giuh.h"
}

#define NWM_PONDED_DEPTH_OUT_VAR "nwm_ponded_depth"

namespace bmi_lgar {
class NotImplemented : public std::logic_error {
public:
Expand All @@ -30,7 +34,11 @@ class NotImplemented : public std::logic_error {
class BmiLGAR : public bmi::Bmi {
public:
~BmiLGAR();
BmiLGAR():giuh_ordinates(nullptr), giuh_runoff_queue(nullptr) {
BmiLGAR() :
giuh_ordinates(nullptr),
giuh_runoff_queue(nullptr),
m_serialized{}
{
this->input_var_names[0] = "precipitation_rate";
this->input_var_names[1] = "potential_evapotranspiration_rate";
this->input_var_names[2] = "soil_temperature_profile";
Expand All @@ -52,6 +60,7 @@ public:
this->output_var_names[12] = "percolation";
this->output_var_names[13] = "groundwater_to_stream_recharge";
this->output_var_names[14] = "mass_balance";
this->output_var_names[15] = NWM_PONDED_DEPTH_OUT_VAR;

/*
this->output_var_names[13] = "cum_precipitation";
Expand Down Expand Up @@ -130,12 +139,13 @@ public:
void global_mass_balance();
double update_calibratable_parameters();
struct model_state* get_model();

private:
friend class boost::serialization::access;
void realloc_soil();
struct model_state* state;
static const int input_var_name_count = 3;
static const int output_var_name_count = 15;
static const int output_var_name_count = 16;
static const int calib_var_name_count = 7;

std::string input_var_names[input_var_name_count];
Expand All @@ -146,6 +156,9 @@ private:
double *giuh_ordinates;
double *giuh_runoff_queue;

vecbuf<char> m_serialized;
uint64_t m_serialized_length; // needs a stable anchor for GetValuePtr

// unit conversion
//struct unit_conversion units;
struct bmi_unit_conversion {
Expand All @@ -156,13 +169,23 @@ private:
double volrech_timestep_m;
double volrunoff_timestep_m;
double volrunoff_giuh_timestep_m;
double volrunoff_giuh_ponded_m;
double volQ_timestep_m;
double volQ_gw_timestep_m;
double volPET_timestep_m;
double mass_balance_m;
};

struct bmi_unit_conversion bmi_unit_conv;

template<class Archive>
void serialize(Archive& ar, const unsigned int version);
template<class Archive>
void serialize_wetting_front_list(Archive &ar, wetting_front **head, int &count);

void new_serialized();
void load_serialized(const char* data);
void free_serialized();
};


Expand Down
115 changes: 115 additions & 0 deletions include/vecbuf.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
#ifndef HPP_STRING_VECBUF
#define HPP_STRING_VECBUF
// https://gist.github.com/stephanlachnit/4a06f8475afd144e73235e2a2584b000
// SPDX-FileCopyrightText: 2023 Stephan Lachnit
// SPDX-License-Identifier: MIT

#include <streambuf>
#include <string>
#include <vector>

template<class CharT = char, class Traits = std::char_traits<CharT>>
class vecbuf : public std::basic_streambuf<CharT> {
public:
using streambuf = std::basic_streambuf<CharT, Traits>;
using char_type = typename streambuf::char_type;
using int_type = typename streambuf::int_type;
using traits_type = typename streambuf::traits_type;
using vector = std::vector<char_type>;
using value_type = typename vector::value_type;
using size_type = typename vector::size_type;

// Constructor for vecbuf with optional initial capacity
vecbuf(size_type capacity = 0) : vector_() { reserve(capacity); }

// Forwarder for std::vector::shrink_to_fit()
constexpr void shrink_to_fit() { vector_.shrink_to_fit(); }

// Forwarder for std::vector::clear()
constexpr void clear() { vector_.clear(); }

// Forwarder for std::vector::reserve
constexpr void reserve(size_type capacity) { vector_.reserve(capacity); setp_from_vector(); }

// Increase the capacity of the buffer by reserving the current_size + additional_capacity
constexpr void reserve_additional(size_type additional_capacity) { reserve(size() + additional_capacity); }

// Forwarder for std::vector::data
constexpr const value_type* data() const { return vector_.data(); }

// Forwarder for std::vector::size
constexpr size_type size() const { return vector_.size(); }

// Forwarder for std::vector::capacity
constexpr size_type capacity() const { return vector_.capacity(); }

// Implements std::basic_streambuf::xsputn
std::streamsize xsputn(const char_type* s, std::streamsize count) override {
try {
reserve_additional(count);
}
catch (const std::bad_alloc& error) {
// reserve did not work, use slow algorithm
return xsputn_slow(s, count);
}
// reserve worked, use fast algorithm
return xsputn_fast(s, count);
}

protected:
// Calculates value to std::basic_streambuf::pbase from vector
constexpr value_type* pbase_from_vector() const { return const_cast<value_type*>(vector_.data()); }

// Calculates value to std::basic_streambuf::pptr from vector
constexpr value_type* pptr_from_vector() const { return const_cast<value_type*>(vector_.data() + vector_.size()); }

// Calculates value to std::basic_streambuf::epptr from vector
constexpr value_type* epptr_from_vector() const { return const_cast<value_type*>(vector_.data()) + vector_.capacity(); }

// Sets the values for std::basic_streambuf::pbase, std::basic_streambuf::pptr and std::basic_streambuf::epptr from vector
constexpr void setp_from_vector() { streambuf::setp(pbase_from_vector(), epptr_from_vector()); streambuf::pbump(size()); }

private:
// std::vector containing the data
vector vector_;

// Fast implementation of std::basic_streambuf::xsputn if reserve_additional(count) succeeded
std::streamsize xsputn_fast(const char_type* s, std::streamsize count) {
// store current pptr (end of vector location)
auto* old_pptr = pptr_from_vector();
// resize the vector, does not move since space already reserved
vector_.resize(vector_.size() + count);
// directly memcpy new content to old pptr (end of vector before it was resized)
traits_type::copy(old_pptr, s, count);
// reserve() already calls setp_from_vector(), only adjust pptr to new epptr
streambuf::pbump(count);

return count;
}

// Slow implementation of std::basic_streambuf::xsputn if reserve_additional(count) did not succeed, might calls std::basic_streambuf::overflow()
std::streamsize xsputn_slow(const char_type* s, std::streamsize count) {
// reserving entire vector failed, emplace char for char
std::streamsize written = 0;
while (written < count) {
try {
// copy one char, should throw eventually std::bad_alloc
vector_.emplace_back(s[written]);
}
catch (const std::bad_alloc& error) {
// try overflow(), if eof return, else continue
int_type c = this->overflow(traits_type::to_int_type(s[written]));
if (traits_type::eq_int_type(c, traits_type::eof())) {
return written;
}
}
// update pbase, pptr and epptr
setp_from_vector();
written++;
}
return written;
}

};

#endif
Loading