00001 ///////////////////////////////////////////////////////////////////////////////////////// 00002 /// \file spark.h 00003 /// \brief Header file required to define %SPARK inverses. 00004 /// 00005 /// This header file should be included in the file where the inverses of an atomic class 00006 /// are implemented : \n 00007 /// \li to define the preprocessor macros. 00008 /// \li to include the required header files. 00009 /// 00010 ///////////////////////////////////////////////////////////////////////////////////////// 00011 /// 00012 /// \author Dimitri Curtil 00013 /// \version %SPARK 2.0 00014 /// \date September 3, 2003 Added SET_DATA, GET_DATA and DELETE_DATA macros 00015 /// \date December 18, 2002 Original implementation 00016 /// 00017 ///////////////////////////////////////////////////////////////////////////////////////// 00018 /// \attention 00019 /// PORTIONS COPYRIGHT (C) 2003 AYRES SOWELL ASSOCIATES, INC. \n 00020 /// PORTIONS COPYRIGHT (C) 2003 THE REGENTS OF THE UNIVERSITY OF CALIFORNIA . 00021 /// PENDING APPROVAL BY THE US DEPARTMENT OF ENERGY. ALL RIGHTS RESERVED. 00022 /// 00023 ///////////////////////////////////////////////////////////////////////////////////////// 00024 00025 00026 #if !defined(__SPARK_H__) 00027 #define __SPARK_H__ 00028 00029 00030 ///////////////////////////////////////////////////////////////////////////////////////// 00031 // 00032 // Include basic header files that are needed for %SPARK class implementation 00033 // 00034 ///////////////////////////////////////////////////////////////////////////////////////// 00035 00036 #include <cmath> // for sqrt, pow, fabs... 00037 #include <cstdio> // for printf, stdout, stderr... 00038 00039 #include "problem.h" // for the TProblem class 00040 #include "component.h" // for the TComponent class 00041 #include "object.h" // for the TObject class 00042 #include "inverse.h" // for the TInverse class 00043 #include "requests.h" // for atomic class requests classes 00044 #include "sparkmath.h" // for SPARK::min(), SPARK::max(), SPARK::sign() 00045 #include "sparkapi.h" // for various utility functions such as SPARK::Log() 00046 #include "classapi.h" // for functions used to implement the atomic classes 00047 #include "consts.h" // defines various numerical constants used in the hvactk classes 00048 00049 00050 ///////////////////////////////////////////////////////////////////////////////////////// 00051 /// 00052 /// \name Preprocessor macro definitions used in the implementation of the various callbacks in the atomic classes 00053 /// 00054 /// \note The callback prototypes defined for each callback type must match the typedef's 00055 /// in the file callback.h 00056 //@{ 00057 00058 #if defined( _MSC_VER ) // VC++ compiler 00059 # define CALLBACK_DECLSPEC( callback_type ) extern "C" __declspec(dllexport) callback_type 00060 #else // Other compilers 00061 # define CALLBACK_DECLSPEC( callback_type ) extern "C" callback_type 00062 #endif /* defined(__cplusplus) */ 00063 00064 00065 /// Macros to define the prototype for a modifier callback 00066 #define NON_MODIFIER_CALLBACK( func ) CALLBACK_DECLSPEC(void) func(SPARK::TObject* this_pointer, SPARK::ArgList args) 00067 00068 /// Macros to define the prototype for a non-modifier callback 00069 #define MODIFIER_CALLBACK( func ) CALLBACK_DECLSPEC(void) func(SPARK::TObject* this_pointer, SPARK::ArgList args, SPARK::TargetList targets) 00070 00071 /// Macros to define the prototype for a predicate callback 00072 #define PREDICATE_CALLBACK( func ) CALLBACK_DECLSPEC(bool) func(SPARK::TObject* this_pointer, SPARK::ArgList args) 00073 00074 /// Macros to define the prototype for a static callback 00075 #define STATIC_NON_MODIFIER_CALLBACK( func ) CALLBACK_DECLSPEC(void) func(SPARK::TInverse* this_pointer) 00076 00077 /// Macros to define the prototype for a static predicate callback 00078 #define STATIC_PREDICATE_CALLBACK( func ) CALLBACK_DECLSPEC(bool) func(SPARK::TInverse* this_pointer) 00079 00080 00081 00082 /// Macros to declare an EVALUATE callback 00083 #define EVALUATE( func ) MODIFIER_CALLBACK( func ) 00084 00085 /// Macros to declare a PREDICT callback 00086 #define PREDICT( func ) MODIFIER_CALLBACK( func ) 00087 00088 /// Macros to declare a CONSTRUCT callback 00089 #define CONSTRUCT( func ) NON_MODIFIER_CALLBACK( func ) 00090 00091 /// Macros to declare a PREPARE_STEP callback 00092 #define PREPARE_STEP( func ) NON_MODIFIER_CALLBACK( func ) 00093 00094 /// Macros to declare a CHECK_INTEGRATION_STEP callback 00095 #define CHECK_INTEGRATION_STEP( func ) PREDICATE_CALLBACK( func ) 00096 00097 /// Macros to declare a COMMIT callback 00098 #define COMMIT( func ) NON_MODIFIER_CALLBACK( func ) 00099 00100 /// Macros to declare a ROLLBACK callback 00101 #define ROLLBACK( func ) NON_MODIFIER_CALLBACK( func ) 00102 00103 /// Macros to declare a DESTRUCT callback 00104 #define DESTRUCT( func ) NON_MODIFIER_CALLBACK( func ) 00105 00106 /// Macros to declare a STATIC_CONSTRUCT callback 00107 #define STATIC_CONSTRUCT( func ) STATIC_NON_MODIFIER_CALLBACK( func ) 00108 00109 /// Macros to declare a STATIC_PREPARE_STEP callback 00110 #define STATIC_PREPARE_STEP( func ) STATIC_NON_MODIFIER_CALLBACK( func ) 00111 00112 /// Macros to declare a STATIC_CHECK_INTEGRATION_STEP callback 00113 #define STATIC_CHECK_INTEGRATION_STEP( func ) STATIC_PREDICATE_CALLBACK( func ) 00114 00115 /// Macros to declare a STATIC_COMMIT callback 00116 #define STATIC_COMMIT( func ) STATIC_NON_MODIFIER_CALLBACK( func ) 00117 00118 /// Macros to declare a STATIC_ROLLBACK callback 00119 #define STATIC_ROLLBACK( func ) STATIC_NON_MODIFIER_CALLBACK( func ) 00120 00121 /// Macros to declare a STATIC_DESTRUCT callback 00122 #define STATIC_DESTRUCT( func ) STATIC_NON_MODIFIER_CALLBACK( func ) 00123 00124 00125 00126 /// \brief A macro that defines a reference named "name" to the TTarget object 00127 /// stored in position "pos" of the target list. 00128 #define TARGET( pos, name ) SPARK::TTarget& name = targets[pos] 00129 00130 /// \brief A macro that defines a const reference named "name" to the TArgument object of the 00131 /// argument stored in position "pos". 00132 #define ARGUMENT( pos , name ) const SPARK::TArgument& name = args[pos] 00133 00134 /// \brief A macro that defines a const reference named "name" to the TArgument object of the 00135 /// argument stored in position "pos". 00136 /// 00137 /// \note This macro is defined for backward-compatibility reasons since it was used in the 00138 /// HVAC toolkit and globalclass implementations of SPARK 1.xx. 00139 /// The new macro #ARGUMENT should be preferred to this one. 00140 #define ARGDEF( pos , name ) ARGUMENT( pos, name ) 00141 00142 /// \brief A macro that returns the scalar val for a single-valued inverse 00143 /// 00144 /// \note There is no equivalent macro for multivalued inverses. 00145 /// The target value must be explicitly assigned to each declared TTarget instances. 00146 #define RETURN( val ) { targets[0] = val; return; } 00147 00148 00149 /// Macros used in predicate callbacks to indicate that the step is accepted 00150 #define ACCEPT_STEP true 00151 00152 /// Macros used in predicate callbacks to indicate that the step is rejected 00153 #define REJECT_STEP false 00154 00155 //@} 00156 ///////////////////////////////////////////////////////////////////////////////////////// 00157 00158 00159 00160 ///////////////////////////////////////////////////////////////////////////////////////// 00161 /// \name Preprocessor macros to access active context from within a callback 00162 //@{ 00163 00164 /// \brief A macro to access the pointer to the current "this" pointer associated with the current callback. 00165 /// 00166 /// \note In an instance callback the private data object is implemented as a pointer to a TObject instance 00167 /// \note In a static callback the private data object is implemented as a pointer to a TInverse instance 00168 #if defined(THIS) 00169 # undef THIS 00170 #endif //THIS 00171 #define THIS this_pointer 00172 00173 00174 /// \brief A macro to access the pointer to the private data object stored as part of an object 00175 /// 00176 /// 00177 /// \param owner Either SPARK::TInverse* or SPARK::TObject* owner of the data 00178 /// \param concrete_type Concrete type of the data stored in owner used for type-casting 00179 /// \param name Name of the variable pointing to the data of type <code>concrete_type</code> to be stored in owner 00180 /// 00181 /// \note The macro implements a static_cast from void* to the specified <code>concrete_type</code>. 00182 #define GET_DATA( owner, concrete_type, name ) concrete_type* name = SPARK::AtomicClass::GetData<concrete_type>( owner ) 00183 00184 /// \brief A macro to store the pointer to the private data stored as part of an object. 00185 /// 00186 /// \param owner Either SPARK::TInverse* or SPARK::TObject* owner of the data 00187 /// \param concrete_type Concrete type of the data stored in owner used for type-casting 00188 /// \param name Name of the variable pointing to the data of type <code>concrete_type</code> to be stored in owner 00189 #define SET_DATA( owner, concrete_type, name ) SPARK::AtomicClass::SetData<concrete_type>( owner, name ) 00190 00191 /// \brief A macro to delete data pointed to by an object. 00192 /// 00193 /// \param owner Either SPARK::TInverse* or SPARK::TObject* owner of the data 00194 /// \param concrete_type Concrete type of the data stored in owner used for type-casting 00195 /// \param is_array_flag Boolean value (true or false) indicating whether the data is a built-in array or not 00196 /// 00197 /// \warning When deleting a built-in array, make sure to specify isArray == true to call the delete [] operator. 00198 /// Otherwise specify isArray = false for non "built-in array" types. 00199 #define DELETE_DATA( owner, concrete_type, is_array_flag ) SPARK::AtomicClass::DeleteData<concrete_type, SPARK::deleter<is_array_flag> >( owner ) 00200 00201 00202 /// \brief Returns pointer to TProblem object this object belongs to 00203 /// 00204 /// \note This applies to both static and non-static callbacks. 00205 #define ACTIVE_PROBLEM THIS->GetProblem() 00206 00207 /// \brief Returns pointer to TInverse object this object belongs to 00208 /// 00209 /// \warning This applies only to instance callbacks. 00210 #define ACTIVE_INVERSE THIS->GetInverse() 00211 00212 /// \brief Returns pointer to TComponent object this object belongs to 00213 /// 00214 /// \warning This applies only to instance callbacks. 00215 #define ACTIVE_COMPONENT THIS->GetComponent() 00216 00217 00218 #if defined(ERROR_LOG) 00219 # undef ERROR_LOG 00220 #endif 00221 /// \brief Writes msg specified as const char* to the error log file 00222 /// 00223 /// \note Users could also use the API function SPARK::GetErrorLog() to retrieve a reference 00224 /// to the std::ostream object for the error log file. 00225 #define ERROR_LOG( msg ) SPARK::Log( SPARK::GetErrorLog(), THIS, __LINE__, msg ) 00226 00227 00228 #if defined(RUN_LOG) 00229 # undef RUN_LOG 00230 #endif 00231 /// \brief Writes msg specified as const char* to the run log file 00232 /// 00233 /// \note Users could also use the API function SPARK::GetRunLog() to retrieve a reference 00234 /// to the std::ostream object for the run log file. 00235 #define RUN_LOG( msg ) SPARK::Log( SPARK::GetRunLog(), THIS, __LINE__, msg ) 00236 00237 00238 //@} 00239 ///////////////////////////////////////////////////////////////////////////////////////// 00240 00241 00242 00243 ///////////////////////////////////////////////////////////////////////////////////////// 00244 /// \name Preprocessor macros to send a request to the active problem from within a callback 00245 //@{ 00246 00247 /// \brief Macro to generate a request header with specific context information as <code>const char*</code> 00248 /// 00249 /// \param sender is a TInverse* or TObject* or TProblem* 00250 /// \param target is a TProblem* 00251 /// \param context is a <code>const char*</code> object that contains the description of the calling context 00252 #define REQUEST__HEADER( sender, target, context ) SPARK::Requests::THeader( (sender), (target), (context) ) 00253 00254 /// \brief Macro to send an abort request from an atomic class 00255 /// 00256 /// See SPARK::Requests::TDispatcher::abort() 00257 /// 00258 /// \param context is a <code>const char*</code> that contains the description of the calling context 00259 #define REQUEST__ABORT( context ) SPARK::Requests::TDispatcher::abort( REQUEST__HEADER( THIS, ACTIVE_PROBLEM, context ) ) 00260 00261 /// \brief Macro to send a stop request from an atomic class 00262 /// 00263 /// See SPARK::Requests::TDispatcher::stop() 00264 /// 00265 /// \param context is a <code>const char*</code> that contains the description of the calling context 00266 #define REQUEST__STOP( context ) SPARK::Requests::TDispatcher::stop( REQUEST__HEADER( THIS, ACTIVE_PROBLEM, context ) ) 00267 00268 00269 /// \brief Macro to send a set stop time request from an atomic class 00270 /// 00271 /// See SPARK::Requests::TDispatcher::set_stop_time() 00272 /// 00273 /// \param context is a <code>const char*</code> that contains the description of the calling context 00274 /// \param time is a double <code>value</code> that speicifies the desired stopping time for the simulator 00275 #define REQUEST__SET_STOP_TIME( context, time ) SPARK::Requests::TDispatcher::set_stop_time( REQUEST__HEADER( THIS, ACTIVE_PROBLEM, context ), time ) 00276 00277 00278 /// \brief Macro to send a report request from an atomic class 00279 /// 00280 /// See SPARK::Requests::TDispatcher::report() 00281 /// 00282 /// \param context is a <code>const char*</code> that contains the description of the calling context 00283 #define REQUEST__REPORT( context ) SPARK::Requests::TDispatcher::report( REQUEST__HEADER( THIS, ACTIVE_PROBLEM, context ) ) 00284 00285 /// \brief Macro to send a snapshot request from an atomic class 00286 /// 00287 /// See SPARK::Requests::TDispatcher::snapshot() 00288 /// 00289 /// \param context is a <code>const char*</code> that contains the description of the calling context 00290 /// \param filename is a <code>const char*</code> that contains the file name used to generate the problem snapshot 00291 #define REQUEST__SNAPSHOT( context, filename ) SPARK::Requests::TDispatcher::snapshot( REQUEST__HEADER( THIS, ACTIVE_PROBLEM, context ), filename ) 00292 00293 00294 /// \brief Macro to send a request to synchronize with a meeting point from an atomic class 00295 /// 00296 /// See SPARK::Requests::TDispatcher::set_meeting_point() 00297 /// 00298 /// \param context is a <code>const char*</code> that contains the description of the calling context 00299 /// \param time is a <code>double</code> value that indicates the meeting point the simulator will try to synchronize with 00300 #define REQUEST__SET_MEETING_POINT( context, time ) SPARK::Requests::TDispatcher::set_meeting_point( REQUEST__HEADER( THIS, ACTIVE_PROBLEM, context ), time ) 00301 00302 /// \brief Macro to send a clear meeting points request from an atomic class 00303 /// 00304 /// See SPARK::Requests::TDispatcher::clear_meeting_points() 00305 /// 00306 /// \param context is a <code>const char*</code> that contains the description of the calling context 00307 #define REQUEST__CLEAR_MEETING_POINTS( context ) SPARK::Requests::TDispatcher::clear_meeting_points( REQUEST__HEADER( THIS, ACTIVE_PROBLEM, context ) ) 00308 00309 00310 /// \brief Macro to send a restart request from an atomic class 00311 /// 00312 /// See SPARK::Requests::TDispatcher::restart() 00313 /// 00314 /// \param context is a <code>const char*</code> that contains the description of the calling context 00315 #define REQUEST__RESTART( context ) SPARK::Requests::TDispatcher::restart( REQUEST__HEADER( THIS, ACTIVE_PROBLEM, context ) ) 00316 00317 00318 /// \brief Macro to send a "set dynamic stepper" request from an atomic class 00319 /// 00320 /// See SPARK::Requests::TDispatcher::set_dynamic_stepper() 00321 /// 00322 /// \param context is a <code>const char*</code> that contains the description of the calling context. 00323 /// \param stepper is a <code>TDynamicStepper</code> object that defines the structure of the dynamic steps. 00324 /// 00325 /// \warning Not implemented yet. 00326 #define REQUEST__SET_DYNAMIC_STEPPER( context, stepper ) SPARK::Requests::TDispatcher::set_dynamic_stepper( REQUEST__HEADER( THIS, ACTIVE_PROBLEM, context ), stepper ) 00327 00328 /// \brief Macro to send a "set time step" request from an atomic class 00329 /// 00330 /// See SPARK::Requests::TDispatcher::set_time_step() 00331 /// 00332 /// \param context is a <code>const char*</code> that contains the description of the calling context 00333 /// \param h is a <code>double</code> value that indicates the next candidate time step to try 00334 #define REQUEST__SET_TIME_STEP( context, h ) SPARK::Requests::TDispatcher::set_time_step( REQUEST__HEADER( THIS, ACTIVE_PROBLEM, context ), h ) 00335 00336 //@} 00337 ///////////////////////////////////////////////////////////////////////////////////////// 00338 00339 00340 #endif //__SPARK_H__ 00341