NGen
Loading...
Searching...
No Matches
Layer.hpp
1#ifndef __NGEN_LAYER__
2#define __NGEN_LAYER__
3
4#include <NGenConfig.h>
5
6#include "LayerData.hpp"
7#include "Simulation_Time.hpp"
8#include "State_Exception.hpp"
9
10#if NGEN_WITH_MPI
11#include "HY_Features_MPI.hpp"
12#else
13#include "HY_Features.hpp"
14#endif
15
16namespace ngen
17{
18
19 class Layer
20 {
21 public:
22
23 #if NGEN_WITH_MPI
24 using feature_type = hy_features::HY_Features_MPI;
25 #else
27 #endif
28
30 const LayerDescription& desc,
31 const std::vector<std::string>& p_u,
32 const Simulation_Time& s_t,
33 feature_type& f,
35 long idx) :
36 description(desc),
38 simulation_time(s_t),
39 features(f),
42 {
43
44 }
45
55 const LayerDescription& desc,
56 const Simulation_Time& s_t,
57 feature_type& f,
58 long idx) :
59 description(desc),
60 simulation_time(s_t),
61 features(f),
63 {
64
65 }
66
67 virtual ~Layer() {}
68
69
73
74
75
79
80
81
84 int get_id() const { return this->description.id; }
85
86
89 const std::string& get_name() const { return this->description.name; }
90
91
94 const double get_time_step() const { return this->description.time_step; }
95
96
99 const std::string& get_time_step_units() const { return this->description.time_step_units; }
100
101
104 virtual void update_models()
105 {
108
109 //std::cout<<"Output Time Index: "<<output_time_index<<std::endl;
110 if(output_time_index%100 == 0) std::cout<<"Running timestep " << output_time_index <<std::endl;
111 std::string current_timestamp = simulation_time.get_timestamp(output_time_index);
112 for(const auto& id : processing_units)
113 {
114 int sub_time = output_time_index;
115 //std::cout<<"Running cat "<<id<<std::endl;
116 auto r = features.catchment_at(id);
117 //TODO redesign to avoid this cast
118 auto r_c = std::dynamic_pointer_cast<realization::Catchment_Formulation>(r);
119 double response(0.0);
120 try{
121 response = r_c->get_response(output_time_index, simulation_time.get_output_interval_seconds());
122 }
124 std::string msg = e.what();
125 msg = msg+" at timestep "+std::to_string(output_time_index)
126 +" ("+current_timestamp+")"
127 +" at feature id "+id;
129 }
130 std::string output = std::to_string(output_time_index)+","+current_timestamp+","+
131 r_c->get_output_line_for_timestep(output_time_index)+"\n";
132 r_c->write_output(output);
133 //TODO put this somewhere else. For now, just trying to ensure we get m^3/s into nexus output
134 double area;
135 try{
136 area = catchment_data->get_feature(id)->get_property("areasqkm").as_real_number();
137 }
138 catch(std::invalid_argument &e)
139 {
140 area = catchment_data->get_feature(id)->get_property("area_sqkm").as_real_number();
141 }
142 double response_m_s = response * (area * 1000000);
143 //TODO put this somewhere else as well, for now, an implicit assumption is that a module's get_response returns
144 //m/timestep
145 //since we are operating on a 1 hour (3600s) dt, we need to scale the output appropriately
146 //so no response is m^2/hr...m^2/hr * 1hr/3600s = m^3/hr
147 double response_m_h = response_m_s / 3600.0;
148 //update the nexus with this flow
149 for(auto& nexus : features.destination_nexuses(id)) {
150 //TODO in a DENDRITIC network, only one destination nexus per catchment
151 //If there is more than one, some form of catchment partitioning will be required.
152 //for now, only contribute to the first one in the list
153 if(nexus == nullptr){
154 throw std::runtime_error("Invalid (null) nexus instantiation downstream of "+id+". "+SOURCE_LOC);
155 }
156 nexus->add_upstream_flow(response_m_h, id, output_time_index);
157 /*std::cerr << "Add water to nexus ID = " << nexus->get_id() << " from catchment ID = " << id << " value = "
158 << response << ", ID = " << id << ", time-index = " << output_time_index << std::endl; */
159 break;
160 }
161
162 } //done catchments
163
166 {
168 }
169 }
170
171
172 protected:
173
175 //TODO is this really required at the top level?
176 //See "minimum" constructor above used for DomainLayer impl...
177 const std::vector<std::string> processing_units;
180 //TODO is this really required at the top level? or can this be moved to SurfaceLayer?
183
184 };
185}
186
187#endif
Simulation Time class providing time-series variables and methods to the model.
Definition Simulation_Time.hpp:48
int get_output_interval_seconds()
Accessor to the output_interval_seconds.
Definition Simulation_Time.hpp:90
int get_total_output_times()
Accessor to the total number of time steps.
Definition Simulation_Time.hpp:81
void advance_timestep()
move this simulation time object to represent the next time step as the current time
Definition Simulation_Time.hpp:155
time_t get_current_epoch_time()
Accessor to the the current simulation time.
Definition Simulation_Time.hpp:100
std::string get_timestamp(int current_output_time_index)
Accessor to the current timestamp string.
Definition Simulation_Time.hpp:109
int next_timestep_index(int epoch_time_seconds)
Definition Simulation_Time.hpp:129
time_t next_timestep_epoch_time(int epoch_time_seconds)
Definition Simulation_Time.hpp:139
Collection interface to HY_Features objects and their associated model formulations.
Definition HY_Features.hpp:41
std::vector< std::shared_ptr< HY_HydroNexus > > destination_nexuses(const std::string &id)
Get a vector of destination (downstream) nexus pointers.
Definition HY_Features.hpp:152
std::shared_ptr< HY_CatchmentRealization > catchment_at(std::string id)
Get the HY_CatchmentRealization pointer identified by id.
Definition HY_Features.hpp:82
Custom exception indicating bad external model state.
Definition State_Exception.hpp:18
virtual char const * what() const noexcept override
Definition State_Exception.hpp:32
Definition Layer.hpp:20
const double get_time_step() const
Return this time_step interval used for this layer.
Definition Layer.hpp:94
time_t current_timestep_epoch_time()
Return the last timestep that was processed by this layer in epoch time units.
Definition Layer.hpp:78
long output_time_index
Definition Layer.hpp:182
Layer(const LayerDescription &desc, const Simulation_Time &s_t, feature_type &f, long idx)
Construct a minimum layer object.
Definition Layer.hpp:54
feature_type & features
Definition Layer.hpp:179
const std::string & get_time_step_units() const
Return the units for the time_step value of this layer.
Definition Layer.hpp:99
const geojson::GeoJSON catchment_data
Definition Layer.hpp:181
const std::vector< std::string > processing_units
Definition Layer.hpp:177
const LayerDescription description
Definition Layer.hpp:174
virtual ~Layer()
Definition Layer.hpp:67
Simulation_Time simulation_time
Definition Layer.hpp:178
time_t next_timestep_epoch_time()
Return the next timestep that will be processed by this layer in epoch time units.
Definition Layer.hpp:72
int get_id() const
Return the numeric id of this layer.
Definition Layer.hpp:84
const std::string & get_name() const
Return the name of this layer.
Definition Layer.hpp:89
Layer(const LayerDescription &desc, const std::vector< std::string > &p_u, const Simulation_Time &s_t, feature_type &f, geojson::GeoJSON cd, long idx)
Definition Layer.hpp:29
virtual void update_models()
Run one simulation timestep for each model in this layer.
Definition Layer.hpp:104
std::shared_ptr< FeatureCollection > GeoJSON
Easy short-hand for a smart pointer to a FeatureCollection.
Definition FeatureBuilder.hpp:21
Definition DomainLayer.hpp:9
A simple structure to hold meta data related to a computational layer.
Definition LayerData.hpp:18
std::string time_step_units
Definition LayerData.hpp:20
double time_step
Definition LayerData.hpp:22
std::string name
Definition LayerData.hpp:19
int id
Definition LayerData.hpp:21