From df3123bc4f991aab402118dd211e62f6cef95793 Mon Sep 17 00:00:00 2001 From: Xylar Asay-Davis Date: Wed, 17 May 2023 14:12:55 -0600 Subject: [PATCH] Clean up design docs (#15) Updated formatting of existing design docs for new doc setup and code highlighting Includes: * Update formatting for Broadcast design doc * Update formatting for Config design doc * Update formatting for DataTypes design doc * Update formatting for Halo design doc * Update formatting for Logging design doc * Update formatting for MachEnv design doc * Update formatting for TimeMgr design doc --- components/omega/doc/design/Broadcast.md | 58 +- components/omega/doc/design/Config.md | 209 ++-- components/omega/doc/design/DataTypes.md | 66 +- components/omega/doc/design/Halo.md | 145 +-- components/omega/doc/design/Logging.md | 7 +- components/omega/doc/design/MachEnv.md | 129 ++- components/omega/doc/design/TimeMgr.md | 1334 +++++++++++----------- 7 files changed, 1006 insertions(+), 942 deletions(-) diff --git a/components/omega/doc/design/Broadcast.md b/components/omega/doc/design/Broadcast.md index 7e858894787a..099cb4bc5683 100644 --- a/components/omega/doc/design/Broadcast.md +++ b/components/omega/doc/design/Broadcast.md @@ -1,7 +1,5 @@ - - -# OMEGA Requirements and Design: -## *Broadcast* +(omega-design-broadcast)= +# Broadcast ## 1 Overview @@ -52,7 +50,9 @@ function with simplified arguments. For non-blocking broadcasts, we will alias the MPI_request type to a Broadcast ID: - using BroadcastID = MPI_Request; +```c++ +using BroadcastID = MPI_Request; +``` ### 4.2 Methods @@ -66,14 +66,18 @@ interfaces cleaner. The first form is the simplest for a broadcast within the default environment and from the master task: - int Broadcast([data type] value); +```c++ +int Broadcast([data type] value); +``` where `[data type]` is one of the supported types (I4, I8 R4, R8, Real, boolean, std::string). In actual use, this would look like: - ierr = Broadcast(myIntVar); - ierr = Broadcast(myRealVar); - [etc for all data types] +```c++ +ierr = Broadcast(myIntVar); +ierr = Broadcast(myRealVar); +[etc for all data types] +``` On the master task, the value would be broadcast and remain unchanged. The remaining tasks would receive the broadcast and store the value. @@ -83,26 +87,32 @@ The remaining tasks would receive the broadcast and store the value. This is similar to the above, but adds the additional argument for the source rank to broadcast from. - int Broadcast([data type] value, ///< [in] value to be broadcast - const int srcRank ///< [in] rank to broadcast from - ); // +```c++ +int Broadcast([data type] value, ///< [in] value to be broadcast + const int srcRank ///< [in] rank to broadcast from + ); // +``` #### 4.2.3 Broadcast from master rank within a different environment As in 4.2.1, but adds the machine environment as an argument: - int Broadcast([data type] value, ///< [in] value to be broadcast - const MachEnv subEnv, ///< [in] defined OMEGA environment - ); +```c++ +int Broadcast([data type] value, ///< [in] value to be broadcast + const MachEnv subEnv, ///< [in] defined OMEGA environment + ); +``` #### 4.2.4 Broadcast from another rank within a different environment As in 4.2.2, but adds the machine environment as an argument: - int Broadcast([data type] value, ///< [in] value to be broadcast - const MachEnv subEnv, ///< [in] defined OMEGA environment - const int srcRank ///< [in] rank to broadcast from - ); +```c++ +int Broadcast([data type] value, ///< [in] value to be broadcast + const MachEnv subEnv, ///< [in] defined OMEGA environment + const int srcRank ///< [in] rank to broadcast from + ); +``` #### 4.2.5 Broadcast of vector variables @@ -117,9 +127,11 @@ be named IBroadcast. In addition, an IBroadcastWait will be included to wait for the request to complete. A non-blocking sequence would look like: - BroadcastID myReqID = IBroadcast(myVar); - [ perform other tasks/computation ] - int err = IBroadcastWait(myReqID); +```c++ +BroadcastID myReqID = IBroadcast(myVar); +[ perform other tasks/computation ] +int err = IBroadcastWait(myReqID); +``` ## 5 Verification and Testing @@ -155,5 +167,3 @@ verification on the non-blocking results. Create a new MachEnv with a subset of ranks and repeat the above tests with the extra environment argument. Check also that ranks not in the environment are not corrupted/overwritten with the broadcast value. - - diff --git a/components/omega/doc/design/Config.md b/components/omega/doc/design/Config.md index aa69560e27bd..6714ebf45e4f 100644 --- a/components/omega/doc/design/Config.md +++ b/components/omega/doc/design/Config.md @@ -1,8 +1,5 @@ - - -# OMEGA Requirements and Design: - -# *Config* +(omega-design-config)= +# Config ## 1 Overview @@ -92,7 +89,7 @@ If extra or unexpected values are encountered, they will be ignored. ### 2.13 Desired: Automated generation of default input and error checking While the source code defines the configuration variables, it would -desirable to have a means to extract from the source code what the +be desirable to have a means to extract from the source code what the code is expecting into a default input config file. This would also enable some external error checking for missing or extra entries. @@ -142,7 +139,9 @@ There are no global parameters or shared constants. We define a Config type, which is actually an alias of YAML::node: - using Config = YAML::node; +```c++ +using Config = YAML::node; +``` from the yaml-cpp library. A YAML node is more fully and accurately defined in the YAML specification, but for the purposes of this @@ -157,50 +156,51 @@ but will be a similar hierarchy under the full omega config node. An example YAML input file might then look like: - omega: - timeManagement: - doRestart: false - restartTimestampName: restartTimestamp - startTime: 0001-01-01_00:00:00 - stopTime: none - runDuration: 0010_00:00:00 - calendarType: noleap - - [Other config options in a similar way] - - hmix: - hmixScaleWithMesh: false - maxMeshDensity: -1.0 - hmixUseRefWidth: false - hmixRefWidth: 30.0e3 - - [more config options] - - streams: - - mesh: - type: input - filenameTemplate: mesh.nc - inputInterval: initial_only - - output: - type: output - filenameTemplate: output/output.$Y-$M-$D_$h.$m.$s.nc - filenameInterval: 01-00-00_00:00:00 - referenceTime: 0001-01-01_00:00:00 - clobberMode: truncate - precision: single - outputInterval: 0001_00:00:00 - contents: - - tracers - - layerThickness - - ssh - - kineticEnergyCell - - relativeVorticityCell - - [other fields] - - [other streams in similar form] - +```yaml +omega: + timeManagement: + doRestart: false + restartTimestampName: restartTimestamp + startTime: 0001-01-01_00:00:00 + stopTime: none + runDuration: 0010_00:00:00 + calendarType: noleap + + [Other config options in a similar way] + + hmix: + hmixScaleWithMesh: false + maxMeshDensity: -1.0 + hmixUseRefWidth: false + hmixRefWidth: 30.0e3 + + [more config options] + + streams: + + mesh: + type: input + filenameTemplate: mesh.nc + inputInterval: initial_only + + output: + type: output + filenameTemplate: output/output.$Y-$M-$D_$h.$m.$s.nc + filenameInterval: 01-00-00_00:00:00 + referenceTime: 0001-01-01_00:00:00 + clobberMode: truncate + precision: single + outputInterval: 0001_00:00:00 + contents: + - tracers + - layerThickness + - ssh + - kineticEnergyCell + - relativeVorticityCell + - [other fields] + + [other streams in similar form] +``` ### 4.2 Methods @@ -213,7 +213,9 @@ to be associated with Config. The most common use case should be creating a Config by reading a YAML configuration file using: - Config omegaConfig = ConfigRead(“omega.yml”); +```c++ +Config omegaConfig = ConfigRead("omega.yml"); +``` where the argument is the name for the YAML input file. In OMEGA, we will retain this master configuration throughout the initialization @@ -228,11 +230,13 @@ associated with the local module/group. In the sample above, if we need to retrieve a variable from the hmix group, we first retrieve the hmix config and then the variable using: - Config hmixConfig = ConfigGet(omegaConfig,"hmix",iErr); - Real refWidth{0.0}; - bool useRefWidth{false}; - refWidth = ConfigGet(hmixConfig, "hmixRefWidth", iErr); - useRefWidth = ConfigGet(hmixConfig, "hmixUseRefWidth", iErr); +```c++ +Config hmixConfig = ConfigGet(omegaConfig,"hmix",iErr); +Real refWidth{0.0}; +bool useRefWidth{false}; +refWidth = ConfigGet(hmixConfig, "hmixRefWidth", iErr); +useRefWidth = ConfigGet(hmixConfig, "hmixUseRefWidth", iErr); +``` where there is a retrieval function for all supported Omega data types: bool, I4, I8, R4, R8, Real, std::string. These retrievals are just @@ -246,7 +250,9 @@ Another interface will allow the setting of a default value if the variable is missing from the input config. This interface simply adds the default value as an additional argument, for example: - refWidth = ConfigGet(hmixConfig, "hmixRefWidth", defaultVal, iErr); +```c++ +refWidth = ConfigGet(hmixConfig, "hmixRefWidth", defaultVal, iErr); +``` In this case, if the variable does not exist, it will not only use the default value but print a warning that the default is @@ -260,9 +266,11 @@ file read interface above, the capability modify a value is also required. The syntax is essentially the inverse of the get/retrieval above. Similar to that case, the sub-group will need to be retrieved first. - Config hmixConfig = ConfigGet(omegaConfig, "hmix", iErr); - ConfigSet(hmixConfig, "hmixRefWidth", 10.0e3, iErr); - ConfigSet(hmixConfig, "hmixUseRefWidth", true, iErr); +```c++ +Config hmixConfig = ConfigGet(omegaConfig, "hmix", iErr); +ConfigSet(hmixConfig, "hmixRefWidth", 10.0e3, iErr); +ConfigSet(hmixConfig, "hmixUseRefWidth", true, iErr); +``` There will be overloaded interfaces for each supported type. For literals (as in the example above), they will be cast to an appropriate @@ -276,16 +284,18 @@ It may be necessary to build up a configuration that does not yet exist or add new entries to an existing group. We provide an Add interface to distinguish this case from the Set case above. - // For an existing subgroup: - Config hmixConfig = ConfigGet(omegaConfig, "hmix", iErr); - ConfigAdd(hmixConfig, "hmixRefWidth", 10.0e3, iErr); - ConfigAdd(hmixConfig, "hmixUseRefWidth", true, iErr); +```c++ +// For an existing subgroup: +Config hmixConfig = ConfigGet(omegaConfig, "hmix", iErr); +ConfigAdd(hmixConfig, "hmixRefWidth", 10.0e3, iErr); +ConfigAdd(hmixConfig, "hmixUseRefWidth", true, iErr); - // To add a new subgroup: - Config hmixConfig; // empty Config constructor - ConfigAdd(hmixConfig, "hmixRefWidth", 10.0e3, iErr); // build subgroup - ConfigAdd(hmixConfig, "hmixUseRefWidth", true, iErr); - ConfigAdd(omegaConfig, hmixConfig); // add new subgroup to parent +// To add a new subgroup: +Config hmixConfig; // empty Config constructor +ConfigAdd(hmixConfig, "hmixRefWidth", 10.0e3, iErr); // build subgroup +ConfigAdd(hmixConfig, "hmixUseRefWidth", true, iErr); +ConfigAdd(omegaConfig, hmixConfig); // add new subgroup to parent +``` There will be overloaded interfaces for each supported type. For literals (as in the example above), they will be cast to an appropriate @@ -301,28 +311,36 @@ satisfy requirement 2.11, we will add a function to test the existence of an entry, given a config or sub-config. Using the hmix example again: - if (ConfigExists(hmixConfig,"hmixRefWidth") { - // variable exists, do stuff - } +```c++ +if (ConfigExists(hmixConfig,"hmixRefWidth") { + // variable exists, do stuff +} +``` Note that this can also be used to test the existence of a complete sub-group as well: - bool hmixExists = ConfigExists(omegaConfig, "hmix"); +```c++ +bool hmixExists = ConfigExists(omegaConfig, "hmix"); +``` #### 4.2.5 File write While we may decide to save provenance a different way, a write interface is supplied to write a configuration to an output YAML file: - err = ConfigWrite(myConfig, “outputFileName”); +```c++ +err = ConfigWrite(myConfig, "outputFileName"); +``` #### 4.2.6 Constructor/destructor A default constructor for an empty Config and destructor will be provided: - Config myConfig; - delete myConfig; +```c++ +Config myConfig; +delete myConfig; +``` The destructor may be important to free up space since the Config is likely to only be used during the init phase in the current plan. @@ -334,23 +352,25 @@ and avoid missing or extra entries, we propose inserting a block within each source code header (where other interfaces will be documented). This block would follow Doxygen-like format and look something like: - /// \ConfigInput - /// # - /// # Group description (eg. hmix: the horizontal mix configuration) - /// # - /// groupName: - /// # - /// # Parameter description (eg horizontal mixing coeff) - /// # more description (units, acceptable values or range) - /// # - /// varName1: defaultValue1 - /// # - /// # Parameter description - /// # - /// varName2: defaultValue2 - /// [ continue for remaining vars in this block] - /// - /// \EndConfigInput (might not be necessary?) +```c++ +/// \ConfigInput +/// # +/// # Group description (eg. hmix: the horizontal mix configuration) +/// # +/// groupName: +/// # +/// # Parameter description (eg horizontal mixing coeff) +/// # more description (units, acceptable values or range) +/// # +/// varName1: defaultValue1 +/// # +/// # Parameter description +/// # +/// varName2: defaultValue2 +/// [ continue for remaining vars in this block] +/// +/// \EndConfigInput (might not be necessary?) +``` The block between the ConfigInput lines could be extracted verbatim and written (with proper indenting) into a fully documented yaml @@ -406,4 +426,3 @@ read in the new file. Add an extra variable to the new file. Verify that the newly read Config matches the original, ignoring the extra variable. - tests 2.3, 2.12 - diff --git a/components/omega/doc/design/DataTypes.md b/components/omega/doc/design/DataTypes.md index e5c7237876a6..823f3efb1fba 100644 --- a/components/omega/doc/design/DataTypes.md +++ b/components/omega/doc/design/DataTypes.md @@ -1,9 +1,5 @@ - - -# OMEGA Requirements and Design: - -# *DataTypes* - +(omega-design-data-types)= +# DataTypes ## 1 Overview @@ -74,35 +70,35 @@ file DataTypes.h We will use the "using" syntax rather than the older typedef. For YAKL arrays, we require both device arrays (default) and host array types and will use C-ordering. - - // Standard integer and floating point types - using I4 = std::int32_t; - using I8 = std::int64_t; - using R4 = float; - using R8 = double; - #ifdef SINGLE_PRECISION - using Real = float; - #else - using Real = double; - #endif - - // Aliases for YAKL arrays - by default on device and in - // C-ordering. - using Array1DI4 = YAKL::Array - using Array1DI8 = YAKL::Array - using Array1DR4 = YAKL::Array - using Array1DR8 = YAKL::Array - using Array1DReal = YAKL::Array - using Array2DI4 = YAKL::Array - using Array2DI8 = YAKL::Array - using Array2DR4 = YAKL::Array - using Array2DR8 = YAKL::Array - using Array2DReal = YAKL::Array - // continue this pattern for higher-dimensional arrays - // Also need similar aliases for arrays on the host - using ArrayHost1DI4 = YAKL::Array - // replicated as above for each type, dimension - +```c++ +// Standard integer and floating point types +using I4 = std::int32_t; +using I8 = std::int64_t; +using R4 = float; +using R8 = double; +#ifdef SINGLE_PRECISION +using Real = float; +#else +using Real = double; +#endif + +// Aliases for YAKL arrays - by default on device and in +// C-ordering. +using Array1DI4 = YAKL::Array +using Array1DI8 = YAKL::Array +using Array1DR4 = YAKL::Array +using Array1DR8 = YAKL::Array +using Array1DReal = YAKL::Array +using Array2DI4 = YAKL::Array +using Array2DI8 = YAKL::Array +using Array2DR4 = YAKL::Array +using Array2DR8 = YAKL::Array +using Array2DReal = YAKL::Array +// continue this pattern for higher-dimensional arrays +// Also need similar aliases for arrays on the host +using ArrayHost1DI4 = YAKL::Array +// replicated as above for each type, dimension +``` ### 4.2 Methods diff --git a/components/omega/doc/design/Halo.md b/components/omega/doc/design/Halo.md index ee8a54e80b60..46534350d534 100644 --- a/components/omega/doc/design/Halo.md +++ b/components/omega/doc/design/Halo.md @@ -1,8 +1,5 @@ - - -# OMEGA Requirements and Design: - -## *Halo* +(omega-design-halo)= +# Halo ## 1 Overview @@ -47,8 +44,8 @@ communication. ### 2.6 Requirement: Non-blocking communication To efficiently handle exchanges between each rank and all of its neighbors, we -will use the non-blocking MPI routines ```MPI_Isend``` and ```MPI_Irecv```. The -```MPI_Test``` routine will be used to determine when each communication is +will use the non-blocking MPI routines `MPI_Isend` and `MPI_Irecv`. The +`MPI_Test` routine will be used to determine when each communication is completed. Boolean variables will be needed to track when messages have been received and when buffers have been unpacked. @@ -111,17 +108,21 @@ necessary for performing halo exchanges. An enum defining mesh element types would be helpful to control which exchange lists to use for a particular field array: - enum meshElement{onCell, onEdge, onVertex}; +```c++ +enum meshElement{onCell, onEdge, onVertex}; +``` An MPI datatype ```MPI_RealKind``` will be defined based on whether the default real data type is single or double precision via the SINGLE_PRECISION compile time switch: - #ifdef SINGLE_PRECISION - MPI_Datatype MPI_RealKind = MPI_FLOAT; - #else - MPI_Datatype MPI_RealKind = MPI_DOUBLE; - #endif +```c++ +#ifdef SINGLE_PRECISION +MPI_Datatype MPI_RealKind = MPI_FLOAT; +#else +MPI_Datatype MPI_RealKind = MPI_DOUBLE; +#endif +``` Halo exchanges will depend on the ```haloWidth``` parameter defined in the decomp configuration group. @@ -132,46 +133,50 @@ The ExchList class will hold both send and receive lists. Lists are separated by halo layer to allow for the possibility of exchanging individual layers. Buffer offsets are needed to pack/unpack all the halo layers into/from the same buffer. - class ExchList { +```c++ +class ExchList { - private: + private: - I4 nList[haloWidth]; ///< number of mesh elements in each - ///< layer of list - I4 nTot; ///< number of elements summed over layers - I4 offsets[haloWidth]; ///< offsets for each halo layer + I4 nList[haloWidth]; ///< number of mesh elements in each + ///< layer of list + I4 nTot; ///< number of elements summed over layers + I4 offsets[haloWidth]; ///< offsets for each halo layer - std::vector indices[haloWidth]; ///< list of local indices + std::vector indices[haloWidth]; ///< list of local indices - friend class Neighbor; - friend class Halo; - }; + friend class Neighbor; + friend class Halo; +}; +``` The Neighbor class contains all the information and buffer memory needed for carrying out each type of halo exchange with one neighboring rank. It contains the ID of the neighboring MPI rank, an object of the ExchList class for sends and receives for each mesh index space, a send and a receive buffer, MPI request -handles that are returned by ```MPI_Irecv``` and ```MPI_Isend``` which are +handles that are returned by `MPI_Irecv` and `MPI_Isend` which are needed to test for completion of an individual message transfer, and boolean switches to control the progress of a Halo exchange. To avoid the need for separate integer and floating-point buffers, during the packing process integer values can be recast as reals in a bit-preserving manner using -```reinterpret_cast``` and then recast as integers on the receiving end. +`reinterpret_cast` and then recast as integers on the receiving end. - class Neighbor { +```c++ +class Neighbor { - private: + private: - I4 rankID; ///< ID of neighboring MPI rank - ExchList sendLists[3], recvLists[3]; ///< 0 = onCell, 1 = onEdge, - ///< 2 = onVertex - std::vector sendBuffer, recvBuffer; - MPI_Request rReq, sReq; ///< MPI request handles - bool received = false; - bool unpacked = false; + I4 rankID; ///< ID of neighboring MPI rank + ExchList sendLists[3], recvLists[3]; ///< 0 = onCell, 1 = onEdge, + ///< 2 = onVertex + std::vector sendBuffer, recvBuffer; + MPI_Request rReq, sReq; ///< MPI request handles + bool received = false; + bool unpacked = false; - friend class Halo; - }; + friend class Halo; +}; +``` The Halo class collects all Neighbor objects needed by an MPI rank to perform a full halo exchange with each of its neighbors. The total number of neighbors, @@ -180,22 +185,23 @@ for the current array being transferred is also stored here. This class will be the user interface for halo exchanges, it is a friend class to the subordinate classes so that it has access to all private data. - class Halo { +```c++ +class Halo { - private: + private: - I4 nNghbr; ///< number of neighboring ranks - I4 myRank ///< local MPI rank ID - MPI_Comm myComm; ///< MPI communicator handle - meshElement elemType; ///< index space of current array - std::vector neighbors; + I4 nNghbr; ///< number of neighboring ranks + I4 myRank ///< local MPI rank ID + MPI_Comm myComm; ///< MPI communicator handle + meshElement elemType; ///< index space of current array + std::vector neighbors; - public: + public: - // methods - - }; + // methods +}; +``` ### 4.2 Methods @@ -205,7 +211,9 @@ The constructor for the Halo class will be the interface for declaring an instance of the Halo class and instances of all associated member classes, and requires info from the Decomp and MachEnv objects. - Halo(Decomp inDecomp, MachEnv inEnv); +```c++ +Halo(Decomp inDecomp, MachEnv inEnv); +``` The constructors for Neighbor and ExchList will be called from within the Halo constructor and will create instances of these classes based on info from the @@ -214,14 +222,16 @@ Decomp object. #### 4.2.2 Array halo exchange The primary use for the Halo class will be a member function called -```exchangeFullArrayHalo``` which will exchange halo elements for the input +`exchangeFullArrayHalo` which will exchange halo elements for the input array with each of its neighbors across all layers of the halo. The index space the array is located in (cells, edges, or vertices) needs to be fetched from the metadata associated with the array stored in the Halo object to determine which exchange lists to use. It will return an integer error code to catch errors (likewise for each subprocess below). - int exchangeFullArrayHalo(ArrayLocDDTT &array, meshElement elemType); +```c++ +int exchangeFullArrayHalo(ArrayLocDDTT &array, meshElement elemType); +``` This will be an interface for different exchange funcitons for each type of ArrayLocDDTT (where Loc is the array location, i.e. device or host, DD is the @@ -235,34 +245,42 @@ to host. The ordering of steps for completing a halo exchange is: #### 4.2.3 Start receive/send -A ```startReceives``` function will loop over all member Neighbor objects and -call ```MPI_Irecv``` for each neighbor. It takes no arguments because all the +A `startReceives` function will loop over all member Neighbor objects and +call `MPI_Irecv` for each neighbor. It takes no arguments because all the info needed is already contained in the Halo object and its member objects. - int StartReceives(); +```c++ +int StartReceives(); +``` -Likewise, ```startSends``` will loop over all Neighbor objects and call -```MPI_Isend``` to send the buffers to each neighbor. +Likewise, `startSends` will loop over all Neighbor objects and call +`MPI_Isend` to send the buffers to each neighbor. - int StartSends(); +```c++ +int StartSends(); +``` #### 4.2.4 Buffer pack/unpack For each type of ArrayDDTT, there will be a buffer pack function aliased to a -```packBuffer``` interface: +`packBuffer` interface: - int packBuffer(ArrayDDTT array, int iNeighbor); +```c++ +int packBuffer(ArrayDDTT array, int iNeighbor); +``` where halo elements of the potentially multidimensional array ArrayDDTT are packed into the 1D send buffer for a particular Neighbor in the member -```std::vector``` neighbors using the associated ExchList based on the -meshElement the array is defined on. The ```exchangeFullArrayHalo``` will loop -over the member neighbors and call ```packBuffer``` for each Neighbor. +`std::vector` neighbors using the associated ExchList based on the +meshElement the array is defined on. The `exchangeFullArrayHalo` will loop +over the member neighbors and call `packBuffer` for each Neighbor. Similarly, buffer unpack functions for each ArrayDDTT type will be aliased to -an ```unpackBuffer``` interface: +an `unpackBuffer` interface: - int unpackBuffer(ArrayDDTT &array, int iNeighbor); +```c++ +int unpackBuffer(ArrayDDTT &array, int iNeighbor); +``` ## 5 Verification and Testing @@ -277,4 +295,3 @@ exchange, all the elements in an array (owned+halo elements) would be checked to ensure they have the expected value to verify a successful test. A similar test utilizing a mesh decomposition with HaloWidth other than the default value would satisfy requirement 2.3 as well. - diff --git a/components/omega/doc/design/Logging.md b/components/omega/doc/design/Logging.md index c299b42f005a..b310fbd48257 100644 --- a/components/omega/doc/design/Logging.md +++ b/components/omega/doc/design/Logging.md @@ -1,8 +1,5 @@ - - -# OMEGA Requirements and Design: - -## *OMEGA logging system* +(omega-design-logging)= +# Logging ## 1 Overview diff --git a/components/omega/doc/design/MachEnv.md b/components/omega/doc/design/MachEnv.md index 801410d30466..9185c2f35cec 100644 --- a/components/omega/doc/design/MachEnv.md +++ b/components/omega/doc/design/MachEnv.md @@ -1,10 +1,5 @@ - - -# OMEGA Requirements and Design: - - -# *MachineEnv* - +(omega-design-machine-env)= +# MachineEnv ## 1 Overview @@ -100,20 +95,22 @@ There will be a simple class MachEnv. We use a class here rather than a struct so that we can make members private to prevent overwriting these variables. - class MachEnv { +```c++ +class MachEnv { - private: - int mComm; ///< MPI communicator for this environment - int mMyRank; ///< rank ID for local MPI rank - int mNumRanks; ///< total number of MPI ranks - int mMasterRank;///< rank ID for master rank - bool mIsMaster; ///< true if the local rank is the master + private: + int mComm; ///< MPI communicator for this environment + int mMyRank; ///< rank ID for local MPI rank + int mNumRanks; ///< total number of MPI ranks + int mMasterRank;///< rank ID for master rank + bool mIsMaster; ///< true if the local rank is the master - public: + public: - // Methods - [define methods here - see below] - } + // Methods + [define methods here - see below] +} +``` #### 4.1.3 Default environment @@ -131,12 +128,14 @@ these two must be called as early as possible in OMEGA initialization (typically the first call). Both forms will return an integer error code and will define the default environment `OMEGA::defaultEnv`. - // Initialization - standalone - int MachEnvInit(); +```c++ +// Initialization - standalone +int MachEnvInit(); - // Initialization - coupled - int MachEnvInit(int inCommunicator, ///< [in] parent MPI communicator - ); +// Initialization - coupled +int MachEnvInit(int inCommunicator, ///< [in] parent MPI communicator + ); +``` #### 4.2.2 Constructors @@ -144,37 +143,41 @@ We provide several constructors for creating instances of the environment. These will be used primarily by the above initialization routine, though can also be used to create additional environments per requirement 2.7. - // Generic constructor that uses `MPI_COMM_WORLD` - MachEnv(); - - // Constructor that uses an assigned communicator (eg from coupler) - MachEnv(const int inCommunicator ///< [in] parent MPI communicator - ); - - // Create a new environment from a contiguous subset of an - // existing environment - MachEnv(const int inCommunicator,///< [in] parent MPI communicator - const int newSize ///< [in] use first newSize ranks - ); - - // Create a new environment from a strided subset of an - // existing environment - MachEnv(const int inCommunicator,///< [in] parent MPI communicator - const int newSize, ///< [in] num ranks in new env - const int begin, ///< [in] starting parent rank - const int stride ///< [in] stride for ranks to incl - ); - - // Create a new environment from a custome subset of an - // existing environment, supplying list of parent ranks to include - MachEnv(const int inCommunicator ///< [in] parent MPI communicator - const int newSize, ///< [in] num ranks in new env - const int ranks[] ///< [in] vector of parent ranks to incl - ); +```c++ +// Generic constructor that uses `MPI_COMM_WORLD` +MachEnv(); + +// Constructor that uses an assigned communicator (eg from coupler) +MachEnv(const int inCommunicator ///< [in] parent MPI communicator + ); + +// Create a new environment from a contiguous subset of an +// existing environment +MachEnv(const int inCommunicator,///< [in] parent MPI communicator + const int newSize ///< [in] use first newSize ranks + ); + +// Create a new environment from a strided subset of an +// existing environment +MachEnv(const int inCommunicator,///< [in] parent MPI communicator + const int newSize, ///< [in] num ranks in new env + const int begin, ///< [in] starting parent rank + const int stride ///< [in] stride for ranks to incl + ); + +// Create a new environment from a custome subset of an +// existing environment, supplying list of parent ranks to include +MachEnv(const int inCommunicator ///< [in] parent MPI communicator + const int newSize, ///< [in] num ranks in new env + const int ranks[] ///< [in] vector of parent ranks to incl + ); +``` In standalone mode, the simple constructor would be used: - MachEnv omegaEnv(); // Initialize MPI and machine environment +```c++ +MachEnv omegaEnv(); // Initialize MPI and machine environment +``` and would define `MPI_COMM_WORLD` as the communicator as well as initialize various other environments as needed. In coupled mode, @@ -193,22 +196,28 @@ a vector of specific ranks of the parent to include in the new environment. We provide specific retrieval functions for each class member to mimic using this environment as a struct: - int Comm() const; ///< returns MPI communicator for this environment - int MyRank() const; ///< returns local MPI rank - int NumRanks() const; ///< total number of MPI ranks +```c++ +int Comm() const; ///< returns MPI communicator for this environment +int MyRank() const; ///< returns local MPI rank +int NumRanks() const; ///< total number of MPI ranks +``` In typical use, these would look like: - myRank = OMEGA::defaultEnv.MyRank(); // retrieve local rank id - if (OMEGA::defaultEnv.IsMaster()){ - // do stuff on master rank - } +```c++ +myRank = OMEGA::defaultEnv.MyRank(); // retrieve local rank id +if (OMEGA::defaultEnv.IsMaster()){ + // do stuff on master rank +} +``` #### 4.2.3 Change master task While most of the members should not be modified (read only using the get above), we will need a single set function to satisfy requirement 2.6. - int SetMaster(const int newMasterRank); +```c++ +int SetMaster(const int newMasterRank); +``` Note that this should occur as soon as possible after the environment is created. Resetting the master after other activities have already assumed @@ -261,5 +270,3 @@ and build the test with `-D OMEGA_VECTOR_SIZE=16`. Verify the internal variable is also 16 to test that the preprocessor properly propagates the value internally. * tests requirement 2.5 - - diff --git a/components/omega/doc/design/TimeMgr.md b/components/omega/doc/design/TimeMgr.md index 366498691af6..61d5d6514ac0 100644 --- a/components/omega/doc/design/TimeMgr.md +++ b/components/omega/doc/design/TimeMgr.md @@ -1,7 +1,5 @@ - - -# OMEGA Requirements and Design: -## *TimeManager* +(omega-design-time-manager)= +# TimeManager ## 1 Overview @@ -86,7 +84,8 @@ a beautiful Monday by most accounts) with conversion to various calendars following the algorithms in: Fliegel, H. F., and Van Flandern, T. C., 1968, A Machine Algorithm -for Processing Calendar Dates, Communications of the Association of Computing Machines, 11, 657. +for Processing Calendar Dates, Communications of the Association of +Computing Machines, 11, 657. Hatcher, D.A., 1984. Simple Formulae for Julian Day Numbers and Calendar Dates, Quart. J. of R. Astr. Soc., 25, 53-55. @@ -102,12 +101,12 @@ ESMF C++ version for the SciDAC CANGA project and will be used here. The time manager will consist of a number of classes/modules: -- TimeFrac: a base fraction representation -- TimeInstant: representation of a point in time -- TimeInterval: a time step or difference between time instants -- Calendar: support for various calendars -- Alarm: alarms that trigger at time instants or periodic intervals -- Clock: a clock that keeps track of model time as it marches forward +- `TimeFrac`: a base fraction representation +- `TimeInstant`: representation of a point in time +- `TimeInterval`: a time step or difference between time instants +- `Calendar`: support for various calendars +- `Alarm`: alarms that trigger at time instants or periodic intervals +- `Clock`: a clock that keeps track of model time as it marches forward ### 4.1 Data types and parameters @@ -117,43 +116,46 @@ A number of parameters are defined among the above classes. For all classes, it will be useful to define times and intervals with a number and units, so we define an enum class for time units: - enum class TimeUnits{ - None = 0, ///< value for undefined units - Seconds, ///< time units in seconds (typical) - Minutes, ///< time units in minutes - Hours, ///< time units in hours - Days, ///< time units in days - Months, ///< time units in months - Years, ///< time units in years - }; - +```c++ +enum class TimeUnits{ + None = 0, ///< value for undefined units + Seconds, ///< time units in seconds (typical) + Minutes, ///< time units in minutes + Hours, ///< time units in hours + Days, ///< time units in days + Months, ///< time units in months + Years, ///< time units in years + }; +``` For calendars, there will be an enum for supported calendars as well as a string name for each. - #define NUM_SUPPORTED_CALENDARS=9 - - enum CalendarKind { - CalendarGregorian=1, ///< usual Gregorian calendar - CalendarNoLeap, ///< Gregorian, but without leap yrs - CalendarJulian, ///< Julian - CalendarJulianDay, ///< Julian day - CalendarModJulianDay, ///< modified Julian day - Calendar360Day, ///< 12 months, 30 days each - CalendarCustom, ///< user defined - CalendarNoCalendar, ///< track elapsed time only - CalendarUnknown}; ///< uninitialized or invalid - - const std::string CalendarKindName[CALENDAR_KIND_COUNT] = { - "Gregorian", - "No Leap", - "Julian", - "Julian Day", - "Modified Julian Day", - "360 Day", - "Custom", - "No Calendar", - "Invalid" }; +```c++ +#define NUM_SUPPORTED_CALENDARS=9 + +enum CalendarKind { + CalendarGregorian=1, ///< usual Gregorian calendar + CalendarNoLeap, ///< Gregorian, but without leap yrs + CalendarJulian, ///< Julian + CalendarJulianDay, ///< Julian day + CalendarModJulianDay, ///< modified Julian day + Calendar360Day, ///< 12 months, 30 days each + CalendarCustom, ///< user defined + CalendarNoCalendar, ///< track elapsed time only + CalendarUnknown}; ///< uninitialized or invalid + +const std::string CalendarKindName[CALENDAR_KIND_COUNT] = { + "Gregorian", + "No Leap", + "Julian", + "Julian Day", + "Modified Julian Day", + "360 Day", + "Custom", + "No Calendar", + "Invalid" }; +``` #### 4.1.2 Class/structs/data types @@ -164,63 +166,69 @@ There are six classes that will make up the time interval. There will be a TimeFrac class for the base fractional time representation: - class TimeFrac { +```c++ +class TimeFrac { - // private variables - private: - long long whole; ///< whole seconds - long long numer; ///< fractional second (n/d) numerator - long long denom; ///< fractional second (n/d) denominator + // private variables + private: + long long whole; ///< whole seconds + long long numer; ///< fractional second (n/d) numerator + long long denom; ///< fractional second (n/d) denominator - public: - [methods described below] - }; + public: + [methods described below] +}; +``` ##### 4.1.2.2 Calendar class The calendar class holds useful information for the calendar to be used: - #define MONTHS_PER_YEAR=12 +```c++ +#define MONTHS_PER_YEAR=12 - class Calendar { +class Calendar { - // private variables - private: + // private variables + private: - int id; ///< unique id for quick checks - static int numCalendars; ///< number of calendars created - std::string name; ///< name of calendar - CalendarKind calKind; ///< enum for calendar kind - std::string calKindName; ///< name of calendar kind + int id; ///< unique id for quick checks + static int numCalendars; ///< number of calendars created + std::string name; ///< name of calendar + CalendarKind calKind; ///< enum for calendar kind + std::string calKindName; ///< name of calendar kind - // variables defining calendar characteristics for time - int daysPerMonth[MONTHS_PER_YEAR]; ///< days in each month - int monthsPerYear; ///< num months in year - int secondsPerDay; ///< seconds per day - int secondsPerYear; ///< seconds per normal year - int daysPerYear; ///< days per normal year + // variables defining calendar characteristics for time + int daysPerMonth[MONTHS_PER_YEAR]; ///< days in each month + int monthsPerYear; ///< num months in year + int secondsPerDay; ///< seconds per day + int secondsPerYear; ///< seconds per normal year + int daysPerYear; ///< days per normal year - // public methods - public: - [methods described below] - }; + // public methods + public: + [methods described below] +}; +``` ##### 4.1.2.3 TimeInstant class The time instant class represents a point in time within a given calendar: - class TimeInstant { +```c++ +class TimeInstant { - // private variables - private: - TimeFrac elapsedTime; ///< Fractional seconds since reference time - Calendar *calPtr; ///< Pointer to calendar in which time is based + // private variables + private: + TimeFrac elapsedTime; ///< Fractional seconds since reference time + Calendar *calPtr; ///< Pointer to calendar in which time is based - public: - [methods described below] - }; + public: + [methods described below] +}; +``` ##### 4.1.2.4 TimeInterval class @@ -232,18 +240,20 @@ time interval in calendar units (eg number of days, months or years). The latter is useful for periodic events that occur once per year, month or ndays. - class TimeInterval { +```c++ +class TimeInterval { - // private variables - private: - TimeFrac interval; ///< Non-calendar interval in fractional seconds - bool isCalendar; ///< True if calendar interval - long long calInterval; ///< Calendar interval length - TimeUnits units; ///< Calendar interval units + // private variables + private: + TimeFrac interval; ///< Non-calendar interval in fractional seconds + bool isCalendar; ///< True if calendar interval + long long calInterval; ///< Calendar interval length + TimeUnits units; ///< Calendar interval units - public: - [methods described below] - }; + public: + [methods described below] +}; +``` ##### 4.1.2.5 Alarm class @@ -252,23 +262,25 @@ The alarm class allows a user to set either one-time or periodic alarms to trigger events, like forcing updates, I/O, etc. that occur at specific times. - class Alarm { +```c++ +class Alarm { - // private variables - private: - std::string name; ///< name for the alarm + // private variables + private: + std::string name; ///< name for the alarm - bool ringing; ///< alarm is currently ringing - bool periodic; ///< alarm rings periodically on interval - bool stopped; ///< alarm has been stopped and not reset + bool ringing; ///< alarm is currently ringing + bool periodic; ///< alarm rings periodically on interval + bool stopped; ///< alarm has been stopped and not reset - TimeInstant ringTime; ///< time at/after which alarm rings - TimeInterval ringInterval; ///< interval at which this alarm rings - TimeInstant ringTimePrev; ///< previous alarm time for interval alarms + TimeInstant ringTime; ///< time at/after which alarm rings + TimeInterval ringInterval; ///< interval at which this alarm rings + TimeInstant ringTimePrev; ///< previous alarm time for interval alarms - public: - [methods described below] - }; + public: + [methods described below] +}; +``` ##### 4.1.2.6 Clock class @@ -276,24 +288,26 @@ The clock class is meant to track and manage the time for a model advancing in time. Alarms can be attached to the clock so that the ringing status can be updated as the clock marches forward. - class Clock { +```c++ +class Clock { - // private variables - private: + // private variables + private: - TimeInstant startTime; ///< initial time for this clock - TimeInstant currTime; ///< current time - TimeInstant prevTime; ///< time at previous timestep - TimeInstant nextTime; ///< time at next timestep - TimeInterval timeStep; ///< interval at which this clock advances + TimeInstant startTime; ///< initial time for this clock + TimeInstant currTime; ///< current time + TimeInstant prevTime; ///< time at previous timestep + TimeInstant nextTime; ///< time at next timestep + TimeInterval timeStep; ///< interval at which this clock advances - int numAlarms; ///< current number of attached alarms + int numAlarms; ///< current number of attached alarms - std::vector alarms; ///< pointers to alarms associated with this clock + std::vector alarms; ///< pointers to alarms associated with this clock - public: - [methods described below] - }; + public: + [methods described below] +}; +``` ### 4.2 Methods @@ -309,147 +323,149 @@ of operators to perform arithmetic on fractional integers and a number of accessor functions to convert units into a fractional time. - // Accessor methods - - /// Single call to set all native base time components - /// \return error code - int set(const long long whole, ///< [in] whole seconds - const long long numer, ///< [in] fractional second numerator - const long long denom ///< [in] fractional second denominator - ); - /// Set base time by converting from integer hours, minutes, seconds - /// \return error code - int setHMS(const int hours, ///< [in] integer hours - const int minutes, ///< [in] integer minutes - const int seconds ///< [in] integer seconds - - /// Set base time by converting from a real number of seconds - /// \return error code - int setSeconds(const double seconds ///< [in] Time in real seconds - ); - /// Set base time by converting from a real number of hours - /// \return error code - int setHours(const double hours ///< [in] Time in real hours - ); - /// Set base time by converting from a real number of minutes - /// \return error code - int setMinutes(const double minutes ///< [in] Time in real minutes - ); - - /// Set whole seconds separately - /// \return error code - int setWhole( - const long long whole ///< [in] Whole number of seconds - ); - /// Set numerator of fractional seconds separately - /// \return error code - int setNumer( - const long long numer ///< [in] Numerator of fractional seconds - ); - /// Set denominator of fractional seconds separately - /// \return error code - int setDenom( - const long long denom ///< [in] Denominator of fractional seconds - ); +```c++ +// Accessor methods - /// Single call to retrieve native base time components - /// \return error code - int get(long long &whole, ///< [out] whole seconds - long long &numer, ///< [out] fractional second numerator - long long &denom ///< [out] fractional second denominator - ) const; - /// Get base time converted to integer hours, minutes, seconds - /// \return error code - int getHMS(int &hours, ///< [out] integer hours - int &minutes, ///< [out] integer minutes - int &seconds ///< [out] integer seconds - ) const; - /// Get base time and convert to a real number of seconds - /// \return Time in real seconds - double getSeconds(void) const; - /// Get base time and convert to a real number of hours - /// \return Time in real hours - double getHours(void) const; - /// Get base time and convert to a real number of minutes - /// \return Time in real minutes - double getMinutes(void) const; - /// Retrieve the whole seconds component of base time - /// \return Whole number of seconds - long long getWhole(void) const; - /// Retrieve the numerator component of fractional base time - /// \return Numerator of fractional seconds - long long getNumer(void) const; - /// Retrieve the denominator component of fractional base time - /// \return Denominator of fractional seconds - long long getDenom(void) const; - - // constructors/destructors - /// Default base time constructor - TimeFrac(void); - /// Copy constructor for base time - TimeFrac(const TimeFrac& ///< [in] existing base time to be copied - ); - /// Construct base time by component - TimeFrac( - const long long whole, ///< [in] whole seconds +/// Single call to set all native base time components +/// \return error code +int set(const long long whole, ///< [in] whole seconds const long long numer, ///< [in] fractional second numerator const long long denom ///< [in] fractional second denominator ); - /// Construct base time by converting from a real number of seconds - TimeFrac(const double seconds ///< [in] Time in real seconds +/// Set base time by converting from integer hours, minutes, seconds +/// \return error code +int setHMS(const int hours, ///< [in] integer hours + const int minutes, ///< [in] integer minutes + const int seconds ///< [in] integer seconds + +/// Set base time by converting from a real number of seconds +/// \return error code +int setSeconds(const double seconds ///< [in] Time in real seconds + ); +/// Set base time by converting from a real number of hours +/// \return error code +int setHours(const double hours ///< [in] Time in real hours ); - /// Destructor for base time - ~TimeFrac(void); - - // operators - /// Equivalence comparison operator for TimeFrac - bool operator==(const TimeFrac &) const; - /// Non-equivalence comparison operator for TimeFrac - bool operator!=(const TimeFrac &) const; - /// Less than comparison operator for TimeFrac - bool operator< (const TimeFrac &) const; - /// Greater than comparison operator for TimeFrac - bool operator> (const TimeFrac &) const; - /// Less than or equal comparison operator for TimeFrac - bool operator<=(const TimeFrac &) const; - /// Greater than or equal comparison operator for TimeFrac - bool operator>=(const TimeFrac &) const; - /// Addition operator for TimeFrac - TimeFrac operator+ (const TimeFrac &) const; - /// Subtraction operator for TimeFrac - TimeFrac operator- (const TimeFrac &) const; - /// Increment operator for TimeFrac - TimeFrac& operator+=(const TimeFrac &); - /// Decrement operator for TimeFrac - TimeFrac& operator-=(const TimeFrac &); - /// Multiplication by integer scalar - TimeFrac operator* (const int multiplier) const; - /// Multiplication in place by integer scalar - TimeFrac& operator*=(const int multiplier); - /// Multiplication by real scalar - TimeFrac operator* (const double multiplier) const; - /// Multiplication in place by real scalar - TimeFrac& operator*=(const double multiplier); - /// Divide TimeFrac by integer scalar - TimeFrac operator/ (const int divisor) const; - /// Divide TimeFrac in place by integer scalar - TimeFrac& operator/=(const int divisor); - /// Divide two TimeFracs and return a real result - double operator/ (const TimeFrac &) const; - /// Modulus method for TimeFrac - TimeFrac operator% (const TimeFrac &) const; - /// Modulus method in place - TimeFrac& operator%=(const TimeFrac &); - /// Assignment operator for TimeFrac - TimeFrac& operator=(const TimeFrac &); - - // Other utility methods - /// Convert a time fraction to new denominator - /// \return error code - int convert(const long long denom ///< [in] new denominator - ); - /// Reduce a time fraction to simplest form - int simplify(void); +/// Set base time by converting from a real number of minutes +/// \return error code +int setMinutes(const double minutes ///< [in] Time in real minutes + ); + +/// Set whole seconds separately +/// \return error code +int setWhole( + const long long whole ///< [in] Whole number of seconds + ); +/// Set numerator of fractional seconds separately +/// \return error code +int setNumer( + const long long numer ///< [in] Numerator of fractional seconds + ); +/// Set denominator of fractional seconds separately +/// \return error code +int setDenom( + const long long denom ///< [in] Denominator of fractional seconds + ); + +/// Single call to retrieve native base time components +/// \return error code +int get(long long &whole, ///< [out] whole seconds + long long &numer, ///< [out] fractional second numerator + long long &denom ///< [out] fractional second denominator + ) const; +/// Get base time converted to integer hours, minutes, seconds +/// \return error code +int getHMS(int &hours, ///< [out] integer hours + int &minutes, ///< [out] integer minutes + int &seconds ///< [out] integer seconds + ) const; +/// Get base time and convert to a real number of seconds +/// \return Time in real seconds +double getSeconds(void) const; +/// Get base time and convert to a real number of hours +/// \return Time in real hours +double getHours(void) const; +/// Get base time and convert to a real number of minutes +/// \return Time in real minutes +double getMinutes(void) const; +/// Retrieve the whole seconds component of base time +/// \return Whole number of seconds +long long getWhole(void) const; +/// Retrieve the numerator component of fractional base time +/// \return Numerator of fractional seconds +long long getNumer(void) const; +/// Retrieve the denominator component of fractional base time +/// \return Denominator of fractional seconds +long long getDenom(void) const; + +// constructors/destructors +/// Default base time constructor +TimeFrac(void); +/// Copy constructor for base time +TimeFrac(const TimeFrac& ///< [in] existing base time to be copied + ); +/// Construct base time by component +TimeFrac( + const long long whole, ///< [in] whole seconds + const long long numer, ///< [in] fractional second numerator + const long long denom ///< [in] fractional second denominator + ); +/// Construct base time by converting from a real number of seconds +TimeFrac(const double seconds ///< [in] Time in real seconds + ); +/// Destructor for base time +~TimeFrac(void); + +// operators +/// Equivalence comparison operator for TimeFrac +bool operator==(const TimeFrac &) const; +/// Non-equivalence comparison operator for TimeFrac +bool operator!=(const TimeFrac &) const; +/// Less than comparison operator for TimeFrac +bool operator< (const TimeFrac &) const; +/// Greater than comparison operator for TimeFrac +bool operator> (const TimeFrac &) const; +/// Less than or equal comparison operator for TimeFrac +bool operator<=(const TimeFrac &) const; +/// Greater than or equal comparison operator for TimeFrac +bool operator>=(const TimeFrac &) const; +/// Addition operator for TimeFrac +TimeFrac operator+ (const TimeFrac &) const; +/// Subtraction operator for TimeFrac +TimeFrac operator- (const TimeFrac &) const; +/// Increment operator for TimeFrac +TimeFrac& operator+=(const TimeFrac &); +/// Decrement operator for TimeFrac +TimeFrac& operator-=(const TimeFrac &); +/// Multiplication by integer scalar +TimeFrac operator* (const int multiplier) const; +/// Multiplication in place by integer scalar +TimeFrac& operator*=(const int multiplier); +/// Multiplication by real scalar +TimeFrac operator* (const double multiplier) const; +/// Multiplication in place by real scalar +TimeFrac& operator*=(const double multiplier); +/// Divide TimeFrac by integer scalar +TimeFrac operator/ (const int divisor) const; +/// Divide TimeFrac in place by integer scalar +TimeFrac& operator/=(const int divisor); +/// Divide two TimeFracs and return a real result +double operator/ (const TimeFrac &) const; +/// Modulus method for TimeFrac +TimeFrac operator% (const TimeFrac &) const; +/// Modulus method in place +TimeFrac& operator%=(const TimeFrac &); +/// Assignment operator for TimeFrac +TimeFrac& operator=(const TimeFrac &); + +// Other utility methods +/// Convert a time fraction to new denominator +/// \return error code +int convert(const long long denom ///< [in] new denominator + ); +/// Reduce a time fraction to simplest form +int simplify(void); +``` #### 4.2.2 Calendar class @@ -463,105 +479,106 @@ is needed for the later TimeInstant equivalence. Utility functions to convert between elapsed time and calendar dates and incrementing calendar time are supplied for use by other time manager routines. - // accessor functions - // this is (mostly) an immutable class so use constructors - // and provide only one set accessor for renaming +```c++ +// accessor functions +// this is (mostly) an immutable class so use constructors +// and provide only one set accessor for renaming - // the only set function is for renaming - /// Renames a Calendar to the input string - /// \return Error code - int rename(const std::string inName ///< [in] name to use for calendar - ); - - /// Retrieve any/all calendar properties - /// \return Error code - int get(int *outId, ///< [out] id assigned to calendar - std::string *outName, ///< [out] Name of calendar - CalendarKind *outKind, ///< [out] Kind of calendar - int *outDaysPerMonth, ///< [out] Days per month - int *outMonthsPerYear, ///< [out] Months per year - int *outSecondsPerDay, ///< [out] Seconds per day - int *outSecondsPerYear,///< [out] Seconds per year - int *outDaysPerYear ///< [out] Days per year (DPY) - ) const; - - // Might also add specific retrievals for individual - // components, eg seconds per day/year? - - /// Default constructor - Calendar(void); - /// Copy constructor - Calendar(const Calendar &calendar); - /// Constructor based on kind of calendar - Calendar(std::string inName, ///< [in] name of calendar - CalendarKind calKind ///< [in] choice of calendar kind - ); - /// Constructs custom calendar based in inputs - Calendar(const std::string inName, ///< [in] name of calendar - int *inDaysPerMonth, ///< [in] array of days per month - int inSecondsPerDay, ///< [in] seconds per day - int inSecondsPerYear, ///< [in] seconds per year - int inDaysPerYear ///< [in] days per year (dpy) - ); - /// Calendar destructor - ~Calendar(void); - - /// Calendar equivalence operator - bool operator==(const Calendar &calendar) const; - /// Calendar non-equivalence operator - bool operator!=(const Calendar &calendar) const; - - /// Checks whether input year is a leap year - /// \return true if year is a leap year, false otherwise - bool isLeapYear(long long year, ///< [in] year to check - int &rc ///< [out] return code to flag errors - ) const; - - /// Computes the total elapsed time in seconds (in TimeFrac form) - /// since the calendar reference time, given a calendar date, time. - /// \return Elapsed time in TimeFrac form - TimeFrac getElapsedTime( - const long long year, ///< [in] calendar year - const long long month, ///< [in] calendar month - const long long day, ///< [in] calendar day - const long long hour, ///< [in] time of day-hour - const long long minute, ///< [in] time of day-min - const long long whole, ///< [in] time of day-whole seconds - const long long numer, ///< [in] time of day-frac secs (numerator) - const long long denom ///< [in] time of day-frac secs (denom) - ) const; +// the only set function is for renaming +/// Renames a Calendar to the input string +/// \return Error code +int rename(const std::string inName ///< [in] name to use for calendar + ); - /// Determines the calendar date and time of day, given an - /// elapsed time since the calendar reference time. - /// \return error code - int getDateTime( - const TimeFrac elapsedTime, ///< [in] time in secs from ref time - long long &year, ///< [out] calendar year - long long &month, ///< [out] calendar month - long long &day, ///< [out] calendar day - long long &hour, ///< [out] time of day-hours - long long &minute, ///< [out] time of day-minutes - long long &whole, ///< [out] time of day-whole seconds - long long &numer, ///< [out] time of day-frac secs (numerator) - long long &denom ///< [out] time of day-frac secs (denom) +/// Retrieve any/all calendar properties +/// \return Error code +int get(int *outId, ///< [out] id assigned to calendar + std::string *outName, ///< [out] Name of calendar + CalendarKind *outKind, ///< [out] Kind of calendar + int *outDaysPerMonth, ///< [out] Days per month + int *outMonthsPerYear, ///< [out] Months per year + int *outSecondsPerDay, ///< [out] Seconds per day + int *outSecondsPerYear,///< [out] Seconds per year + int *outDaysPerYear ///< [out] Days per year (DPY) ) const; - /// Increments (or decrements) a calendar date by a specified - /// interval, supplied by an integer interval in given time units. - /// Only calendar based intervals (years, months or days) are - /// supported. This is primarily meant to be called by other time - /// manager routines (eg to add/subtract time instants) for those - /// time intervals that are dependent on date and sensitive to - /// calendar features like leap years and varying days of the month. - /// \return error code - int incrementDate( - const long long interval, ///< [in] time interval to advance date - const TimeUnits units, ///< [in] time units for interval - long long &year, ///< [in,out] calendar year of time to be changed - long long &month, ///< [in,out] calendar month of ... - long long &day ///< [in,out] calendar day - ) const; +// Might also add specific retrievals for individual +// components, eg seconds per day/year? +/// Default constructor +Calendar(void); +/// Copy constructor +Calendar(const Calendar &calendar); +/// Constructor based on kind of calendar +Calendar(std::string inName, ///< [in] name of calendar + CalendarKind calKind ///< [in] choice of calendar kind + ); +/// Constructs custom calendar based in inputs +Calendar(const std::string inName, ///< [in] name of calendar + int *inDaysPerMonth, ///< [in] array of days per month + int inSecondsPerDay, ///< [in] seconds per day + int inSecondsPerYear, ///< [in] seconds per year + int inDaysPerYear ///< [in] days per year (dpy) + ); +/// Calendar destructor +~Calendar(void); + +/// Calendar equivalence operator +bool operator==(const Calendar &calendar) const; +/// Calendar non-equivalence operator +bool operator!=(const Calendar &calendar) const; + +/// Checks whether input year is a leap year +/// \return true if year is a leap year, false otherwise +bool isLeapYear(long long year, ///< [in] year to check + int &rc ///< [out] return code to flag errors + ) const; + +/// Computes the total elapsed time in seconds (in TimeFrac form) +/// since the calendar reference time, given a calendar date, time. +/// \return Elapsed time in TimeFrac form +TimeFrac getElapsedTime( + const long long year, ///< [in] calendar year + const long long month, ///< [in] calendar month + const long long day, ///< [in] calendar day + const long long hour, ///< [in] time of day-hour + const long long minute, ///< [in] time of day-min + const long long whole, ///< [in] time of day-whole seconds + const long long numer, ///< [in] time of day-frac secs (numerator) + const long long denom ///< [in] time of day-frac secs (denom) + ) const; + +/// Determines the calendar date and time of day, given an +/// elapsed time since the calendar reference time. +/// \return error code +int getDateTime( + const TimeFrac elapsedTime, ///< [in] time in secs from ref time + long long &year, ///< [out] calendar year + long long &month, ///< [out] calendar month + long long &day, ///< [out] calendar day + long long &hour, ///< [out] time of day-hours + long long &minute, ///< [out] time of day-minutes + long long &whole, ///< [out] time of day-whole seconds + long long &numer, ///< [out] time of day-frac secs (numerator) + long long &denom ///< [out] time of day-frac secs (denom) + ) const; + +/// Increments (or decrements) a calendar date by a specified +/// interval, supplied by an integer interval in given time units. +/// Only calendar based intervals (years, months or days) are +/// supported. This is primarily meant to be called by other time +/// manager routines (eg to add/subtract time instants) for those +/// time intervals that are dependent on date and sensitive to +/// calendar features like leap years and varying days of the month. +/// \return error code +int incrementDate( + const long long interval, ///< [in] time interval to advance date + const TimeUnits units, ///< [in] time units for interval + long long &year, ///< [in,out] calendar year of time to be changed + long long &month, ///< [in,out] calendar month of ... + long long &day ///< [in,out] calendar day + ) const; +``` #### 4.2.3 TimeInstant class @@ -573,47 +590,15 @@ time instants and time intervals (see following interval class). Finally, a method for creating a time string for a time instant is supplied. - // constructors/destructors - /// Default constructor creates empty time instant - TimeInstant(void); - - /// Construct time instant from date, time, calendar - /// Where seconds is supplied as real number. - TimeInstant(Calendar *Cal, ///< [in] Calendar to use - const long long year, ///< [in] year - const long long month, ///< [in] month - const long long day, ///< [in] day - const long long hour, ///< [in] hour - const long long minute, ///< [in] minute - const double rSecond ///< [in] second (real) - ); - - /// Construct time instant from date, time, calendar - /// Where seconds is supplied in integer fractional seconds. - TimeInstant( Calendar *Cal, ///< [in] Calendar to use - const long long year, ///< [in] year - const long long month, ///< [in] month - const long long day, ///< [in] day - const long long hour, ///< [in] hour - const long long minute, ///< [in] minute - const long long whole, ///< [in] second (whole integer) - const long long numer, ///< [in] second (fraction numerator) - const long long denom ///< [in] second (fraction denominator) - ); - - /// Destructor for time interval - ~TimeInstant(void); +```c++ +// constructors/destructors +/// Default constructor creates empty time instant +TimeInstant(void); - // Accessor methods - /// Set time instant calendar - /// \return error code - int set(Calendar *Cal ///< [in] Calendar to use for this time - ); - - /// Set time instant from date and time, where seconds is supplied - /// as a real number. - /// \return error code - int set(const long long year, ///< [in] year +/// Construct time instant from date, time, calendar +/// Where seconds is supplied as real number. +TimeInstant(Calendar *Cal, ///< [in] Calendar to use + const long long year, ///< [in] year const long long month, ///< [in] month const long long day, ///< [in] day const long long hour, ///< [in] hour @@ -621,10 +606,10 @@ instant is supplied. const double rSecond ///< [in] second (real) ); - /// Set time instant from date and time, where seconds is supplied - /// in integer fractional seconds. - /// \return error code - int set(const long long year, ///< [in] year +/// Construct time instant from date, time, calendar +/// Where seconds is supplied in integer fractional seconds. +TimeInstant( Calendar *Cal, ///< [in] Calendar to use + const long long year, ///< [in] year const long long month, ///< [in] month const long long day, ///< [in] day const long long hour, ///< [in] hour @@ -634,72 +619,104 @@ instant is supplied. const long long denom ///< [in] second (fraction denominator) ); - /// Retrieve calendar from time instant - /// \return error code - int get(Calendar *&cal ///< [out] Calendar ptr in which instant defined - ) const; - - /// Retrieve time in date, time form with real seconds. - /// \return error code - int get(long long &year, ///< [out] year of this time instant - long long &month, ///< [out] month of this time instant - long long &day, ///< [out] day of this time instant - long long &hour, ///< [out] hour of this time instant - long long &minute, ///< [out] minute of this time instant - double &second ///< [out] second of this time instant - ) const; - - /// Retrieve time in date, time form with fractional integer seconds. - /// \return error code - int get(long long &year, ///< [out] year of this time instant - long long &month, ///< [out] month of this time instant - long long &day, ///< [out] day of this time instant - long long &hour, ///< [out] hour of this time instant - long long &minute, ///< [out] minute of this time instant - long long &whole, ///< [out] whole seconds of this time - long long &numer, ///< [out] frac second numerator - long long &denom ///< [out] frac second denominator - ) const; - - // Operators on time instants - /// Equivalence comparison for TimeInstant - bool operator==(const TimeInstant &) const; - /// Non-equivalence comparison operator for TimeInstant - bool operator!=(const TimeInstant &) const; - /// Less than comparison operator for TimeInstant - bool operator< (const TimeInstant &) const; - /// Greater than comparison operator for TimeInstant - bool operator> (const TimeInstant &) const; - /// Less than or equal comparison operator for TimeInstant - bool operator<=(const TimeInstant &) const; - /// Greater than or equal comparison operator for TimeInstant - bool operator>=(const TimeInstant &) const; - /// Increment time by adding a time interval - TimeInstant operator+ (const TimeInterval &) const; - /// Decrement time by subtracting a time interval - TimeInstant operator- (const TimeInterval &) const; - /// Create a time interval by subtracting two time instants - TimeInterval operator- (const TimeInstant &) const; - /// Increment time in place by adding time interval - /// Increment time in place by adding time interval - TimeInstant& operator+=(const TimeInterval &); - /// Decrement time in place by subtracting time interval - TimeInstant& operator-=(const TimeInterval &); - - // Other utility methods - /// Get time as a string in the format - /// 'YYYYYY-MM-DD{separator}HH:MM:SS.SSSSSS' where the number - /// of digits in year, number of digits after the decimal in - /// seconds and the character to use as separator are all input - /// by the user. - /// \return time string - std::string getString( - const int yearWidth, ///< [in] number of digits in year - const int secondWidth, ///< [in] num digits after decimal in seconds - std::string separator ///< [in] string(char) to separate date/time +/// Destructor for time interval +~TimeInstant(void); + +// Accessor methods +/// Set time instant calendar +/// \return error code +int set(Calendar *Cal ///< [in] Calendar to use for this time + ); + +/// Set time instant from date and time, where seconds is supplied +/// as a real number. +/// \return error code +int set(const long long year, ///< [in] year + const long long month, ///< [in] month + const long long day, ///< [in] day + const long long hour, ///< [in] hour + const long long minute, ///< [in] minute + const double rSecond ///< [in] second (real) + ); + +/// Set time instant from date and time, where seconds is supplied +/// in integer fractional seconds. +/// \return error code +int set(const long long year, ///< [in] year + const long long month, ///< [in] month + const long long day, ///< [in] day + const long long hour, ///< [in] hour + const long long minute, ///< [in] minute + const long long whole, ///< [in] second (whole integer) + const long long numer, ///< [in] second (fraction numerator) + const long long denom ///< [in] second (fraction denominator) + ); + +/// Retrieve calendar from time instant +/// \return error code +int get(Calendar *&cal ///< [out] Calendar ptr in which instant defined + ) const; + +/// Retrieve time in date, time form with real seconds. +/// \return error code +int get(long long &year, ///< [out] year of this time instant + long long &month, ///< [out] month of this time instant + long long &day, ///< [out] day of this time instant + long long &hour, ///< [out] hour of this time instant + long long &minute, ///< [out] minute of this time instant + double &second ///< [out] second of this time instant ) const; +/// Retrieve time in date, time form with fractional integer seconds. +/// \return error code +int get(long long &year, ///< [out] year of this time instant + long long &month, ///< [out] month of this time instant + long long &day, ///< [out] day of this time instant + long long &hour, ///< [out] hour of this time instant + long long &minute, ///< [out] minute of this time instant + long long &whole, ///< [out] whole seconds of this time + long long &numer, ///< [out] frac second numerator + long long &denom ///< [out] frac second denominator + ) const; +// Operators on time instants +/// Equivalence comparison for TimeInstant +bool operator==(const TimeInstant &) const; +/// Non-equivalence comparison operator for TimeInstant +bool operator!=(const TimeInstant &) const; +/// Less than comparison operator for TimeInstant +bool operator< (const TimeInstant &) const; +/// Greater than comparison operator for TimeInstant +bool operator> (const TimeInstant &) const; +/// Less than or equal comparison operator for TimeInstant +bool operator<=(const TimeInstant &) const; +/// Greater than or equal comparison operator for TimeInstant +bool operator>=(const TimeInstant &) const; +/// Increment time by adding a time interval +TimeInstant operator+ (const TimeInterval &) const; +/// Decrement time by subtracting a time interval +TimeInstant operator- (const TimeInterval &) const; +/// Create a time interval by subtracting two time instants +TimeInterval operator- (const TimeInstant &) const; +/// Increment time in place by adding time interval +/// Increment time in place by adding time interval +TimeInstant& operator+=(const TimeInterval &); +/// Decrement time in place by subtracting time interval +TimeInstant& operator-=(const TimeInterval &); + +// Other utility methods +/// Get time as a string in the format +/// 'YYYYYY-MM-DD{separator}HH:MM:SS.SSSSSS' where the number +/// of digits in year, number of digits after the decimal in +/// seconds and the character to use as separator are all input +/// by the user. +/// \return time string +std::string getString( + const int yearWidth, ///< [in] number of digits in year + const int secondWidth, ///< [in] num digits after decimal in seconds + std::string separator ///< [in] string(char) to separate date/time + ) const; +``` #### 4.2.4 TimeInterval class @@ -713,191 +730,194 @@ class is treated as a friend class so that time instants can be incremented by a time interval and time intervals can be created by subtracting two time instants. - // constructors/destructors - /// Default time interval constructor - TimeInterval(void); - - /// Construct time interval from base time fractional integer seconds - TimeInterval(const long long whole, ///< Whole integer seconds - const long long numer, ///< Fractional seconds numerator - const long long denom ///< Fractional seconds denominator - ); - - /// Construct time interval from an integer length and units - TimeInterval(const int length, ///< length of time interval - const TimeUnits units ///< unit of time for interval - ); - - /// Construct time interval from a long long integer length and units - TimeInterval(const long long length, ///< length of time interval - const TimeUnits units ///< unit of time for interval - ); - - /// Construct time interval from an real length and units - TimeInterval(const double length, ///< length of time interval - const TimeUnits units ///< unit of time for interval - ); - - /// Destructor for time interval - ~TimeInterval(void); - - // Accessor methods - /// Set a non-calendar interval in native fractional integer seconds - /// \return error code - int set(const long long whole, ///< Whole integer seconds - const long long numer, ///< Fractional seconds numerator - const long long denom ///< Fractional seconds denominator - ); +```c++ +// constructors/destructors +/// Default time interval constructor +TimeInterval(void); + +/// Construct time interval from base time fractional integer seconds +TimeInterval(const long long whole, ///< Whole integer seconds + const long long numer, ///< Fractional seconds numerator + const long long denom ///< Fractional seconds denominator + ); - /// Set a time interval from integer length and units - /// \return error code - int set(const int length, ///< length of time interval - const TimeUnits units ///< unit of time for interval - ); +/// Construct time interval from an integer length and units +TimeInterval(const int length, ///< length of time interval + const TimeUnits units ///< unit of time for interval + ); - /// Set a time interval from long long integer length and units - /// \return error code - int set(const long long length, ///< length of time interval - const TimeUnits units ///< unit of time for interval - ); +/// Construct time interval from a long long integer length and units +TimeInterval(const long long length, ///< length of time interval + const TimeUnits units ///< unit of time for interval + ); - /// Set a time interval from an real length and units - /// Real length is only supported for non-calendar intervals since - /// a non-integral length has ambiguous meaning when months, years - /// have variable length. - /// \return error code - int set(const double length, ///< length of time interval - const TimeUnits units ///< unit of time for interval - ); +/// Construct time interval from an real length and units +TimeInterval(const double length, ///< length of time interval + const TimeUnits units ///< unit of time for interval + ); - /// Retrieve non-calendar interval in native fractional integer form - /// \return error code - int get(long long &whole, ///< [out] whole seconds - long long &numer, ///< [out] fractional second numerator - long long &denom ///< [out] fractional second denominator - ) const; - - /// Retrieve a time interval in integer length in specified units. - /// To avoid roundoff issues during conversions, integer retrieval - /// is only permitted in the same units in which the interval was - /// defined. - /// \return error code - int get(long long &length, ///< [out] requested integer length of interval - const TimeUnits units ///< [in] unit of time for interval - ) const; - - /// Retrieve a time interval in real length and specified units. - /// For calendar intervals, the units must match the units in which - /// the interval was defined. For non-calendar intervals, only conversions - /// between hours, minutes and seconds are allowed. - /// \return error code - int get(double &length, ///< [out] Requested time interval length - const TimeUnits units ///< [in] unit of time for interval - ) const; +/// Destructor for time interval +~TimeInterval(void); - /// Equivalence comparison operator for TimeInterval - bool operator==(const TimeInterval &) const; - /// Non-equivalence comparison operator for TimeInterval - bool operator!=(const TimeInterval &) const; - /// Less than comparison operator for TimeInterval - bool operator< (const TimeInterval &) const; - /// Greater than comparison operator for TimeInterval - bool operator> (const TimeInterval &) const; - /// Less than or equal comparison operator for TimeInterval - bool operator<=(const TimeInterval &) const; - /// Greater than or equal comparison operator for TimeInterval - bool operator>=(const TimeInterval &) const; - /// Addition operator for TimeInterval - TimeInterval operator+ (const TimeInterval &) const; - /// Subtraction operator for TimeInterval - TimeInterval operator- (const TimeInterval &) const; - /// Increment operator for TimeInterval - TimeInterval& operator+=(const TimeInterval &); - /// Decrement operator for TimeInterval - TimeInterval& operator-=(const TimeInterval &); - /// Multiplication by integer scalar - TimeInterval operator* (const int multiplier) const; - /// Multiplication by real scalar - /// This is primarily meant for non-calendar intervals, but - /// for calendar intervals, it will multiply the year, month or - /// day interval and convert to the nearest integer. - TimeInterval operator* (const double multiplier) const; - /// Multiplication in place by integer scalar - TimeInterval& operator*=(const int multiplier); - /// Multiplication in place by real scalar - /// This is primarily meant for non-calendar intervals, but - /// for calendar intervals, it will multiply the year, month or - /// day interval and convert to the nearest integer. - TimeInterval& operator*=(const double multiplier); - /// Divide interval by integer scalar - TimeInterval operator/ (const int divisor) const; - /// Divide interval in place by integer scalar - TimeInterval& operator/=(const int divisor); - - /// Absolute value - static TimeInterval absValue(const TimeInterval &); - /// Negative absolute value - static TimeInterval negAbsValue(const TimeInterval &); - - // Other utility methods - /// Check whether a time interval is positive - bool isPositive(void); - - /// Give the Time Instant access to Time Interval so - /// that incrementing/decrementing time is easier. - friend class TimeInstant; - - } +// Accessor methods +/// Set a non-calendar interval in native fractional integer seconds +/// \return error code +int set(const long long whole, ///< Whole integer seconds + const long long numer, ///< Fractional seconds numerator + const long long denom ///< Fractional seconds denominator + ); -#### 4.2.5 Alarm Class +/// Set a time interval from integer length and units +/// \return error code +int set(const int length, ///< length of time interval + const TimeUnits units ///< unit of time for interval + ); -The alarm class allows the creation of both one-time and -periodic alarms. There are also methods for querying the -state of an alarm and for resetting. +/// Set a time interval from long long integer length and units +/// \return error code +int set(const long long length, ///< length of time interval + const TimeUnits units ///< unit of time for interval + ); - // constructors/destructors - /// Constructs a one-time alarm using the input ring time. - Alarm(const std::string inName, ///< [in] Name of alarm - const TimeInstant alarmTime ///< [in] Time at/after which alarm rings - ); +/// Set a time interval from an real length and units +/// Real length is only supported for non-calendar intervals since +/// a non-integral length has ambiguous meaning when months, years +/// have variable length. +/// \return error code +int set(const double length, ///< length of time interval + const TimeUnits units ///< unit of time for interval + ); - /// Constructs a periodic/interval alarm based on an input periodic - /// time interval and a start time for the interval period. - Alarm(const std::string inName, ///< [in] Name of alarm - const TimeInterval alarmInterval, ///< [in] interval at which alarm rings - const TimeInstant intervalStart ///< [in] start time of first interval - ); +/// Retrieve non-calendar interval in native fractional integer form +/// \return error code +int get(long long &whole, ///< [out] whole seconds + long long &numer, ///< [out] fractional second numerator + long long &denom ///< [out] fractional second denominator + ) const; - /// Destructor for alarm - ~Alarm(void); +/// Retrieve a time interval in integer length in specified units. +/// To avoid roundoff issues during conversions, integer retrieval +/// is only permitted in the same units in which the interval was +/// defined. +/// \return error code +int get(long long &length, ///< [out] requested integer length of interval + const TimeUnits units ///< [in] unit of time for interval + ) const; - /// Check whether an alarm is ringing - /// \return true if alarm is ringing, false otherwise - bool isRinging(void); +/// Retrieve a time interval in real length and specified units. +/// For calendar intervals, the units must match the units in which +/// the interval was defined. For non-calendar intervals, only conversions +/// between hours, minutes and seconds are allowed. +/// \return error code +int get(double &length, ///< [out] Requested time interval length + const TimeUnits units ///< [in] unit of time for interval + ) const; + +/// Equivalence comparison operator for TimeInterval +bool operator==(const TimeInterval &) const; +/// Non-equivalence comparison operator for TimeInterval +bool operator!=(const TimeInterval &) const; +/// Less than comparison operator for TimeInterval +bool operator< (const TimeInterval &) const; +/// Greater than comparison operator for TimeInterval +bool operator> (const TimeInterval &) const; +/// Less than or equal comparison operator for TimeInterval +bool operator<=(const TimeInterval &) const; +/// Greater than or equal comparison operator for TimeInterval +bool operator>=(const TimeInterval &) const; +/// Addition operator for TimeInterval +TimeInterval operator+ (const TimeInterval &) const; +/// Subtraction operator for TimeInterval +TimeInterval operator- (const TimeInterval &) const; +/// Increment operator for TimeInterval +TimeInterval& operator+=(const TimeInterval &); +/// Decrement operator for TimeInterval +TimeInterval& operator-=(const TimeInterval &); +/// Multiplication by integer scalar +TimeInterval operator* (const int multiplier) const; +/// Multiplication by real scalar +/// This is primarily meant for non-calendar intervals, but +/// for calendar intervals, it will multiply the year, month or +/// day interval and convert to the nearest integer. +TimeInterval operator* (const double multiplier) const; +/// Multiplication in place by integer scalar +TimeInterval& operator*=(const int multiplier); +/// Multiplication in place by real scalar +/// This is primarily meant for non-calendar intervals, but +/// for calendar intervals, it will multiply the year, month or +/// day interval and convert to the nearest integer. +TimeInterval& operator*=(const double multiplier); +/// Divide interval by integer scalar +TimeInterval operator/ (const int divisor) const; +/// Divide interval in place by integer scalar +TimeInterval& operator/=(const int divisor); + +/// Absolute value +static TimeInterval absValue(const TimeInterval &); +/// Negative absolute value +static TimeInterval negAbsValue(const TimeInterval &); + +// Other utility methods +/// Check whether a time interval is positive +bool isPositive(void); + +/// Give the Time Instant access to Time Interval so +/// that incrementing/decrementing time is easier. +friend class TimeInstant; + +} +``` - /// Checks whether the alarm should ring based on the current - /// (or supplied) time instant (returns error code) - int updateStatus(const TimeInstant currentTime ///< [in] current time - ); +#### 4.2.5 Alarm Class - /// Stops a ringing alarm and sets next a new ring time. If the alarm - /// is a periodic/interval alarm, the next ring time is set to be the - /// next interval boundary after the input time. If the alarm is a - /// single instance, the input time is used as the next alarm time. - /// (returns error code) - int reset(const TimeInstant inTime ///< [in] new basis for alarm time - ); +The alarm class allows the creation of both one-time and +periodic alarms. There are also methods for querying the +state of an alarm and for resetting. - /// Stops a ringing alarm (returns error code). - int stop(void); +```c++ +// constructors/destructors +/// Constructs a one-time alarm using the input ring time. +Alarm(const std::string inName, ///< [in] Name of alarm + const TimeInstant alarmTime ///< [in] Time at/after which alarm rings + ); + +/// Constructs a periodic/interval alarm based on an input periodic +/// time interval and a start time for the interval period. +Alarm(const std::string inName, ///< [in] Name of alarm + const TimeInterval alarmInterval, ///< [in] interval at which alarm rings + const TimeInstant intervalStart ///< [in] start time of first interval + ); + +/// Destructor for alarm +~Alarm(void); + +/// Check whether an alarm is ringing +/// \return true if alarm is ringing, false otherwise +bool isRinging(void); + +/// Checks whether the alarm should ring based on the current +/// (or supplied) time instant (returns error code) +int updateStatus(const TimeInstant currentTime ///< [in] current time + ); - /// Rename an alarm (returns error code) - int rename(const std::string newName ///< [in] new name for alarm - ); +/// Stops a ringing alarm and sets next a new ring time. If the alarm +/// is a periodic/interval alarm, the next ring time is set to be the +/// next interval boundary after the input time. If the alarm is a +/// single instance, the input time is used as the next alarm time. +/// (returns error code) +int reset(const TimeInstant inTime ///< [in] new basis for alarm time + ); + +/// Stops a ringing alarm (returns error code). +int stop(void); - /// Get alarm name - std::string getName(void) const; +/// Rename an alarm (returns error code) +int rename(const std::string newName ///< [in] new name for alarm + ); +/// Get alarm name +std::string getName(void) const; +``` #### 4.2.6 Clock Class @@ -908,49 +928,51 @@ of alarms can be attached to a clock. Finally, there is a method to advance the clock one time and update the state of all attached alarms. - // constructors/destructors - /// Construct a clock from start time and time step - Clock(const TimeInstant startTime, ///< [in] Start time for clock - const TimeInterval timeStep ///< [in] Time step to advance clock - ); +```c++ +// constructors/destructors +/// Construct a clock from start time and time step +Clock(const TimeInstant startTime, ///< [in] Start time for clock + const TimeInterval timeStep ///< [in] Time step to advance clock + ); - /// Destructor for clocks - ~Clock(void); +/// Destructor for clocks +~Clock(void); - // Accessor Methods - /// Set the current time (returns error code) - int setCurrentTime( - const TimeInstant currTime ///< [in] new value for current time - ); +// Accessor Methods +/// Set the current time (returns error code) +int setCurrentTime( + const TimeInstant currTime ///< [in] new value for current time + ); - /// Changes the time step for this clock (returns error code) - int changeTimeStep( - const TimeInterval newTimeStep ///< [in] new value for time step - ); +/// Changes the time step for this clock (returns error code) +int changeTimeStep( + const TimeInterval newTimeStep ///< [in] new value for time step + ); - /// Retrieves current time of this clock - TimeInstant getCurrentTime(void) const; +/// Retrieves current time of this clock +TimeInstant getCurrentTime(void) const; - /// Retrieves time at the previous time step - TimeInstant getPreviousTime(void) const; +/// Retrieves time at the previous time step +TimeInstant getPreviousTime(void) const; - /// Retrieves time at the next time step - TimeInstant getNextTime(void) const; +/// Retrieves time at the next time step +TimeInstant getNextTime(void) const; - /// Retrieves start time for this clock - TimeInstant getStartTime(void) const; +/// Retrieves start time for this clock +TimeInstant getStartTime(void) const; - /// Retrieves time step for clock - TimeInterval getTimeStep(void) const; +/// Retrieves time step for clock +TimeInterval getTimeStep(void) const; - /// Attaches an alarm to this clock. The clock simply stores a - /// pointer to this alarm. (returns error code) - int attachAlarm(Alarm* inAlarm ///< [in] pointer to alarm to attach - ); +/// Attaches an alarm to this clock. The clock simply stores a +/// pointer to this alarm. (returns error code) +int attachAlarm(Alarm* inAlarm ///< [in] pointer to alarm to attach + ); - /// Advance a clock one timestep and update status of any attached - /// alarms. (returns error code) - int advance(void); +/// Advance a clock one timestep and update status of any attached +/// alarms. (returns error code) +int advance(void); +``` ## 5 Verification and Testing @@ -1029,7 +1051,3 @@ another clock with large time steps (years) that extend over a potential paleoclimate interval to test large number representations are supported correctly. - tests requirement 2.1, 2.2, 2.3, 2.4, 2.5, 2.6 - - - -