LandscapeDNDC 1.37.0
mbe_legacymodel.h
1
11#ifndef MOBILE_MODULE_H_
12#define MOBILE_MODULE_H_
13
14#include "ld_legacy.h"
15#include "legacy/mbe_setup.h"
16#include "legacy/mbe_plant.h"
17#include "legacy/state/mbe_state.h"
18
19#include <math/cbm_math.h>
20#include <time/cbm_time.h>
21#include <input/ecosystemtypes.h>
22#include <memory/cbm_mem.h>
23#include <memory/cbm_singleton.h>
24
25#include <list>
26
27/* oneleaf option has moved */
28
29#ifdef LDNDC_OPENMP
30# define CF_LMOD_QUERY_RETURN_(__rc__) /* no op */
31#else
32# define CF_LMOD_QUERY_RETURN_(__rc__) return __rc__;
33#endif
34#define CF_LMOD_QUERY(__cf__,__key__,__reg__,__dflt__) \
35{ \
36 lerr_t __rc ## __reg__ ( (__cf__)->query( info().id, __key__, &__reg__)); \
37 if (( __rc ## __reg__) == LDNDC_ERR_ATTRIBUTE_NOT_FOUND) \
38 { \
39 __reg__ = __dflt__; \
40 } \
41 else if (( __rc ## __reg__) == LDNDC_ERR_OK) \
42 { \
43 /* no op */ \
44 } \
45 else \
46 { \
47 /* fallback .. use default, and issue error message */ \
48 __reg__ = __dflt__; \
49 \
50 LOGERROR( "config query: invalid key or value"); \
51 CF_LMOD_QUERY_RETURN_(TOKENPASTE(__rc,__reg__)) \
52 } \
53}
54
55namespace cbm {
56 class io_kcomm_t; }
57namespace ldndc {
58 class config_file_t; }
59
60namespace ldndc {
61class MBE_LegacyModel;
62
63extern LDNDC_API lflags_t const TMODE_DEFAULTS;
65{
68
71
73 LMOD_FLAG_USER = 1u << 1,
74
83
86
89
90 LMOD_FLAG_CNT_,
91 LMOD_FLAG_CNT = 1 + 1 + cbm::log2_t< LMOD_FLAG_CNT_-1 >::LOG2
92};
93
94struct LDNDC_API module_info_t
95{
96 module_info_t(
97 char const * /*id*/, char const * /*name*/,
98 lflags_t /*timemode*/, lflags_t /*flags*/);
99
100 /* identifier */
101 char const * id;
102 /* human readable name */
103 char const * name;
104 /* valid time modes */
105 lflags_t timemode;
106
107 /* flags to control and specify behavior of model */
108 lflags_t mflags;
109};
110
111struct LDNDC_API MoBiLE_ModuleFactoryBase
112{
113 virtual ~MoBiLE_ModuleFactoryBase() = 0;
114
115 virtual module_info_t const & info() const = 0;
116 virtual mobile_module_options_t const & options_info() const = 0;
117
118 virtual MBE_LegacyModel * construct(
119 MoBiLE_State *, cbm::io_kcomm_t *,
120 cbm::sclock_t const *, timemode_e) const = 0;
121};
122
123template < class _M >
124struct MoBiLE_ModuleFactory : public MoBiLE_ModuleFactoryBase
125{
126 MoBiLE_ModuleFactory() : MoBiLE_ModuleFactoryBase()
127 { }
128
129 module_info_t const & info() const
130 { return _M::m_info(); }
131
132 mobile_module_options_t const & options_info() const
133 { return *_M::m_options_info(); }
134
135 MBE_LegacyModel * construct(
136 MoBiLE_State * _state, cbm::io_kcomm_t * _io,
137 cbm::sclock_t const * _clock, timemode_e _timemode)
138 const
139 { return static_cast< MBE_LegacyModel * >(
140 _M::new_instance( _state, _io, _clock, _timemode)); }
141};
142
143struct LDNDC_API MoBiLE_ModuleFactoryEnvelope
144{
145 bool exists() const
146 { return ( constructor != NULL); }
147
148 module_info_t const & info() const
149 { return constructor->info(); }
150
151 mobile_module_options_t const & options_info() const
152 { return constructor->options_info(); }
153
154 /* pointer to factory for class */
155 MoBiLE_ModuleFactoryBase const * constructor;
156};
157
158extern LDNDC_API MoBiLE_ModuleFactoryEnvelope const module_factories[];
159
160
161
162
163#define __MODULE_FACTORY(__m_type__) module_factory_ ## __m_type__
164#define MODULE_FACTORY(__m_type__) ldndc::__m_type__::__MODULE_FACTORY(__m_type__)
165
166#define __LMOD_EXPORT_MODULE_FACTORY(__m_type__) \
167 static MoBiLE_ModuleFactory< __m_type__ > const __MODULE_FACTORY(__m_type__)/*;*/
168
169
170#define __LMOD_MODULE_FACTORY(__m_type__) \
171 ldndc::MoBiLE_ModuleFactory< ldndc::__m_type__ > const MODULE_FACTORY(__m_type__)/*;*/
172
173
174#define EXPORT_MODULE_INFO(__m_id__,__m_name__) \
175 public: \
176 static module_info_t const & m_info() { return m_info_; } \
177 module_info_t const & info() const { return this->m_info(); } \
178 char const * name() const { return this->name_(); } \
179 char const * id() const { return this->id_(); } \
180 \
181 private: \
182 static char const * name_() { return __m_name__; } \
183 static char const * id_() { return __m_id__; } \
184 \
185 static module_info_t m_info_/*;*/
186
187
188#define MODULE_INFO(__m_type__,__m_timemode__,__m_flags__) \
189 module_info_t __m_type__::m_info_ = \
190 module_info_t( __m_type__::id_(), __m_type__::name_(), \
191 (__m_timemode__), (__m_flags__))/*;*/
192
193
194#define LDNDC_MOBILE_MODULE_OBJECT(__type__) \
195 public: \
196 static __type__ * allocate_instance() \
197 { \
198 return cbm::allocatable_t< __type__ >::allocate_instance(); \
199 } \
200 static __type__ * new_instance( \
201 MoBiLE_State * _state, \
202 cbm::io_kcomm_t * _io, \
203 cbm::sclock_t const *, \
204 timemode_e _timemode) \
205 { \
206 __type__ * this_instance = \
207 cbm::allocatable_t< __type__ >::allocate_instance(); \
208 \
209 if ( this_instance) \
210 { \
211 new ( this_instance) __type__( _state, _io, _timemode); \
212 } \
213 return this_instance; \
214 } \
215 \
216 virtual void delete_instance() \
217 { \
218 cbm::allocatable_t< __type__ >::delete_instance( this); \
219 } \
220 virtual void delete_instance() \
221 const \
222 { \
223 const_cast< __type__ * >( this)->delete_instance(); \
224 } \
225 private:
226
227#define LDNDC_MOBILE_MODULE_OBJECT_DEFN(__type__) LDNDC_OBJECT_DEFN(ldndc::__type__)
228
229#define EXPORT_MODULE_OPTIONS_INFO(__m_type__) \
230 public: \
231 static mobile_module_options_t const * m_options_info()\
232 { return &options_info_for(__m_type__)->options; } \
233 mobile_module_options_t const * options_info() \
234 const { return __m_type__::m_options_info(); }
235
236#define REGISTER_OPTION(__m_type__,__optkey__,__optvalue__)\
237 static ldndc::module_option_register_t< ldndc::__m_type__ > const \
238 __m_type__##_##__optkey__( #__optkey__, __optvalue__)/*;*/
239
240#define LMOD_EXPORT_MODULE_INFO(__m_type__,__m_id__,__m_name__) \
241 LDNDC_MOBILE_MODULE_OBJECT(__m_type__) \
242 public: \
243 __LMOD_EXPORT_MODULE_FACTORY(__m_type__); \
244 private: \
245 EXPORT_MODULE_OPTIONS_INFO(__m_type__); \
246 private: \
247 EXPORT_MODULE_INFO(__m_id__,__m_name__)
248
249
250#define LMOD_MODULE_INFO(__m_type__,__m_timemode__,__m_flags__) \
251 MODULE_INFO(ldndc::__m_type__,__m_timemode__,__m_flags__); \
252 LDNDC_MOBILE_MODULE_OBJECT_DEFN(__m_type__) \
253 /* also instantiate factory */ \
254 __LMOD_MODULE_FACTORY(__m_type__)
255
256
257template < typename _MODULE >
258struct module_options_info_t
259 : public ldndc::singleton_t< module_options_info_t< _MODULE > >
260{
261 mobile_module_options_t options;
262};
263#define options_info_for(__m_type__) \
264 module_options_info_t< __m_type__ >::get_instance()
265
266class LDNDC_API MBE_LegacyModelBase
267 : public cbm::object_t
268{
269public:
270 MBE_LegacyModelBase( lid_t const & _id)
271 : cbm::object_t( _id)
272 { }
273
274 cbm::sclock_t const * lclock() const
275 { return LD_RtCfg.clk; }
276 cbm::sclock_t const & lclock_ref() const
277 { return *this->lclock(); }
278};
279
280
281class LDNDC_API MBE_LegacyModel : public MBE_LegacyModelBase
282{
283protected:
284 explicit MBE_LegacyModel( MoBiLE_State *, timemode_e);
285public:
286 virtual ~MBE_LegacyModel() = 0;
287
288 /* the pure virtual methods in this block
289 * are implemented implicitely by the
290 * macro EXPORT_MODULE_INFO */
291 virtual char const * name() const = 0;
292 virtual char const * id() const = 0;
293 virtual module_info_t const & info() const = 0;
294 virtual mobile_module_options_t const *
295 options_info() const = 0;
296
297 timemode_e timemode() const;
298 /* test for existence of other legacy models in input */
299 bool have_legacymodel( char const * /*model ID*/) const;
300
305 lerr_t merge_options( mobile_module_options_t const &);
314 cbm::string_t const * get_option(
315 mobile_module_options_t::key_type const & /*option key*/) const;
320 cbm::string_t const * get_option( char const * /*option key*/) const;
325 template < typename _VALUE_TYPE >
326 _VALUE_TYPE get_option( mobile_module_options_t::key_type const & _option_key,
327 _VALUE_TYPE const & _default) const
328 {
329#ifdef _DEBUG
330 void const * check_registered_dummy =
331 this->get_option( _option_key);
332 LDNDC_FIX_UNUSED(check_registered_dummy);
333#endif
334 return this->m_options.get< _VALUE_TYPE >( _option_key, _default);
335 }
336
337 lerr_t set_option( char const * /*option key*/,
338 cbm::string_t const * /*option value*/);
339
340 /* get status */
341 inline bool active() const
342 { return this->m_active == 1; }
343
344 /* tag model as active */
345 void set_active_on()
346 { this->m_active = 1; }
347 /* tag model as inactive */
348 void set_active_off()
349 { this->m_active = 0; }
350
356 virtual lerr_t configure( config_file_t const *) = 0;
357
368 virtual lerr_t initialize() = 0;
369
370 virtual lerr_t register_ports( cbm::io_kcomm_t *)
371 { return LDNDC_ERR_OK; }
372 virtual lerr_t unregister_ports( cbm::io_kcomm_t *)
373 { return LDNDC_ERR_OK; }
374
375
376 virtual lerr_t read()
377 { return LDNDC_ERR_OK; }
378
379 virtual lerr_t solve()
380 { return LDNDC_ERR_OK; }
381
382 virtual lerr_t integrate()
383 { return LDNDC_ERR_OK; }
384
385 virtual lerr_t write()
386 { return LDNDC_ERR_OK; }
387
388
397 virtual lerr_t finalize() = 0;
398
403 virtual lerr_t sleep() = 0;
404
409 virtual lerr_t wake() = 0;
410
411#ifdef _HAVE_SERIALIZE
412 virtual int create_checkpoint(
413 cbm::io_kcomm_t *) { return 0; }
414 virtual int restore_checkpoint(
415 cbm::io_kcomm_t *, ldate_t const *) { return 0; }
416#endif
417
418protected:
419 MoBiLE_State * m_state;
420
421private:
422 /* run model at this time interval */
423 timemode_e m_timemode;
424
425 /* model options */
426 mobile_module_options_t m_options;
427
428 /* model is skipped if tagged inactive (active_ == 0) */
429 mutable int m_active;
430
431 MBE_LegacyModel( MBE_LegacyModel const &);
432 MBE_LegacyModel & operator=( MBE_LegacyModel const &);
433
434private:
435 friend class LK_LegacyModel;
436 /* legacy model info */
437 mobile_modules_info_t const * __m_moduleinfos;
438 cbm::io_kcomm_t * __m_iokcomm;
439};
440
441/*
442 * supported options shall be registered before
443 * referencing them
444 */
445template < typename _MODULE >
446struct module_option_register_t
447{
448 module_option_register_t(
449 char const * _key, char const * _description)
450 {
451 mobile_module_options_t::key_type option_key =
452 mobile_module_options_t::key_type( registered_key_prefix) + _key;
453 mobile_module_options_t::value_type option_description =
454 _description ? _description : "";
455 module_options_info_t< _MODULE > * m_options =
456 module_options_info_t< _MODULE >::get_instance();
457 m_options->options.insert( option_key, option_description);
458 }
459};
460
461struct LDNDC_API MoBiLE_ModuleEnvelope
462{
463 MoBiLE_ModuleEnvelope( MBE_LegacyModel *, char const * /*module id*/);
464 MoBiLE_ModuleEnvelope( MoBiLE_ModuleEnvelope const &);
465
466 MBE_LegacyModel * module;
467 cbm::string_t const id;
468
469 MoBiLE_State * mbe_state;
470 timemode_e mbe_tmmode;
471 mobile_modules_info_t const * mbe_info;
472 cbm::io_kcomm_t * iokcomm;
473
474 MoBiLE_ModuleFactoryBase const * factory;
475
476 private:
477 MoBiLE_ModuleEnvelope & operator=(
478 MoBiLE_ModuleEnvelope const &);
479};
480
481typedef std::list< MoBiLE_ModuleEnvelope > module_container_t;
482
483} /* namespace ldndc */
484
485#endif /* !MOBILE_MODULE_H_ */
486
Spatially explicit groundwater model.
Definition: airchemistryput.h:15
lmodule_flag_e
Definition: mbe_legacymodel.h:65
@ LMOD_FLAG_FINALIZER
Definition: mbe_legacymodel.h:80
@ LMOD_FLAG_TEST_MODULE
Definition: mbe_legacymodel.h:88
@ LMOD_FLAG_MAINTENANCE
Definition: mbe_legacymodel.h:82
@ LMOD_FLAG_INITIALIZER
Definition: mbe_legacymodel.h:78
@ LMOD_FLAG_USER
Definition: mbe_legacymodel.h:73
@ LMOD_FLAG_NONE
Definition: mbe_legacymodel.h:67
@ LMOD_FLAG_CONTROL
Definition: mbe_legacymodel.h:70
@ LMOD_FLAG_OUTPUT
Definition: mbe_legacymodel.h:85
@ LMOD_FLAG_SYSTEM
Definition: mbe_legacymodel.h:76
LDNDC_API lflags_t const TMODE_DEFAULTS
Definition: mbe_legacymodel.cpp:9