Constraint Check

Contents

Constraint Check#

Revision History#

Version

Date

Author

Purpose

1

March 2024

Gary Turner

Initial version

2

October 2026

Nino Tarantino

Convert to reStructuredText and clean up model


Introduction#

The constraint check model provides a generic capability to test the values of specified variables against threshold values to evaluate whether constraints have been violated.

The model can be configured to support various levels of complexity. For example:

  • A constraint requires that the variable, \(x\), not exceed some ceiling, \(y\); the constraint is violated immediately upon encountering a value \(x > y\)

  • A constraint requires that the value \(x\) not be within a bounded box; the constraint is violated immediately upon encountering a value \(y_{l} < x < y_{u}\), where \(y_{l}\), \(y_{u}\) are the lower and upper bounds, respectively.

  • A constraint requires that the value \(x\) not be larger than \(y\) for more than \(t\) seconds; for this type of constraint, the model enters an intermediate phase when \(x > y\) and starts a timer. If the timer reaches \(t\) before \(x \le y\), the constraint is marked as violated.

  • A constraint requires that the value x not be smaller than some set of values \(y_{1}\), \(y_{2}\), \(y_{3}\) for more time than allowed, with each \(y_{i}\) value having a corresponding duration \(t_{i}\). The constraint is violated if \({({{x < y_{1}}\mspace{9mu}\mathit{for}\mspace{9mu}\Delta{t > t_{1}}})} \vee {({{x < y_{2}}\mspace{9mu}\mathit{for}\mspace{9mu}\Delta{t > t_{2}}})} \vee {({{x < y_{3}}\mspace{9mu}\mathit{for}\mspace{9mu}\Delta{t > t_{3}}})}\).

Requirements#

Nomenclature and Concepts#

Requirements#

This model currently has no requirements and therefore has not been verified. Use at your own risk.

Model Specifications#

Architectural Considerations#

Existing External Capabilities#

Inheritance#

The top-level base-class, ConstraintSet, inherits from the SubscriptionBase model to handle activity within a linked set of constraints.

Support#

The model does not utilize other CML models in a supporting role.

Model Structure#

Conceptually, the required capabilities can be divided into three categories: constraint-test, constraint, and constraint-set.

Constraint-Test#

A constraint-test provides the mechanism for testing some value against some specified threshold using some specified logical comparison. e.g. \(x < y\), \(x \ge y\), \(x \neq y\). Constraint-tests are combined together to form a constraint; a constraint is conceptually violated when its constraint-tests are violated. There are two underlying concepts to constraint-tests:

  1. An instant-violation constraint-test (ConstraintTest) has a simple Boolean violation flag that is set according to whether the variable meets the required test.

  2. A timed-violation constraint-test (ConstraintTestTimed) extends the simpler instant-violation constraint-test, adding support for monitoring the duration over which the constraint-test has been returning success and failure. This type of test is marked as violated only when the numerical test has been consistently failing for a specified period of time.


Constraint Test Base Classes
class ConstraintTest#
#include "models/utilities/constraint_check/include/constraint_test.hh"

Provides the mechanism for testing some value against some threshold using some specified logical comparison.

Multiple constraint tests are combined together to form a constraint.

Subclassed by ConstraintTestTimed, ConstraintTest_Interval< DataType >, ConstraintTest_Threshold< DataType >, ConstraintTest_ValSet< DataType >

Public Functions

ConstraintTest() = default#

Constructor

virtual ~ConstraintTest() = default#

Virtual destructor

virtual bool initialize() = 0#

Verify that the model has been configured correctly

Returns:

false if the constraint has been configured improperly

inline virtual double get_time_limit() const#

Note

This is only meaningful for timed constraints.

Returns:

The duration for which a domain violation may exist before triggering a test violation

inline virtual double get_threshold() const#

Note

This is only meaningful for single-threshold-based constraints.

Returns:

The threshold value that, if crossed, will trigger a domain violation

inline bool is_active() const#
Returns:

true if the model is active and checking for violations

inline void activate()#

Activate the model

inline bool is_initialized() const#
Returns:

true if the model has been initialized

void set_violation_condition(ConstraintEnum::ViolationCondition cond)#

Set the violation condition to test against

Note

If the model has already been initialized, it will be re-initialized.

Parameters:

cond -- [in] Violation condition option

inline ConstraintEnum::ViolationCondition get_violation_condition() const#
Returns:

The violation condition being tested against

inline bool get_violation() const#
Returns:

true if the constraint has been violated

Public Members

bool enabled = {true}#

Flag indicating that the test is intended to be used by the associated constraint.

Units:

--

double equality_threshold = {1e-6}#

Threshold for evaluating when two values are equal when their data-types are floating-point representations.

Units:

--

Protected Functions

void count_violations()#

Update the counter tracking the number of unique violations

void initialize_threshold()#

Check that the model configuration is valid for a threshold-based constraint test

void initialize_interval()#

Check that the model configuration is valid for an interval-based constraint test

void initialize_val_set()#

Check that the model configuration is valid for a value-set-based constraint test

Protected Attributes

bool initialized = {false}#

Flag indicating that the test has been successfully initialized.

Units:

--

bool active = {false}#

Flag indicating that this test is currently in use within its constraint.

Units:

--

ConstraintEnum::ViolationCondition violation_condition = {ConstraintEnum::Undefined}#

The specific violation condition for this test.

Units:

--

bool violation = {false}#

Flag indicating that this test has failed. When used as part of ConstraintTestTimed, this flag means that the value has been outside the allowable domain for more than the allowable duration.

Units:

--

bool prev_violation = {false}#

Copy of previous value of violation. Used to identify whether a violation is "new".

Units:

--

unsigned int violation_count = {0}#

Count of the number of unique violations of this test.

Units:

1

class ConstraintTestTimed : public ConstraintTest#
#include "models/utilities/constraint_check/include/constraint_test.hh"

A constraint check which monitors the duration over which a test violation occurs

Extends the base ConstraintTest functionality to trigger violations after a constraint has been violated for a specified period of time.

Subclassed by ConstraintTest_IntervalTimed< DataType >, ConstraintTest_ThresholdTimed< DataType >, ConstraintTest_ValSetTimed< DataType >

Public Functions

ConstraintTestTimed() = default#

Constructor

inline virtual double get_time_limit() const override#
Returns:

time_limit

Public Members

bool use_timer = {true}#

Allows a ConstraintTestTimed to be treated as a ConstraintTest, circumventing the timing aspect if this is false.

Units:

--

double time_limit = {0.0}#

The duration for which a domain violation may exist before triggering a test violation.

Units:

s

double gap_time_limit = {0.0}#

Used if recover_quiet_violation; reset violation_timer to 0 if gap_timer > this value.

Units:

s

double time_limit_tolerance = {1E-10}#

Tolerance used when comparing time limits against accumulated simulation time. Used to protect against floating point rounding causing a violation to be true a simulation cycle too late or too early when running this model at certain update periods.

Units:

s

bool recover_quiet_violation = {false}#

If true, the violation timer will be reset only after a period of non-violation time greater than gap_time_limit.

Units:

--

Protected Functions

void initialize_gap_time()#

Set the gap_time_limit equal to the time_limit if it has not been set independently

void update_timer(double delta_time)#

Update the violation timer

A numerical-violation will result in checking the current timestamp against that at the start of the numerical-violation to identify whether the numerical-violation has been persistent for sufficient time. The violation flag is set accordingly.

Example: A constraint violation requires that the numerical-violation be persistent for 3 counts, and cleared after 2 counts of numerical-satisfaction.

t

numerical-violation

violation

notes

1

present

no

lack of persistence

2

present

no

lack of persistence

3

present

yes

3x persistent

4

present

yes

>3x persistent

5

absent

no

persistence timer not reset

6

present

yes

>3x persistence (retained)

7

absent

no

persistence timer not reset

8

absent

no

persistence timer reset

9

present

no

lack of persistence

Note

(violation = false) will be retained even if there is a numerical-violation until the persistence check has passed.

Note

The violation flag will be set to false automatically if there is no numerical-violation; there is no comparable "retention" of a violated status for any sort of persistence.

Note

The existing_numerical_violation flag does have a persistence check on it; it will mode down only after the gap-time requirement has been satisfied. A numerical violation that momentarily modes back into an acceptable range will not reset the violation-timer until this gap-time reset is reached.

Parameters:

delta_time -- [in] Elapsed time since the last violation check

Protected Attributes

bool numerical_violation = {false}#

An interim violation-flag. This identifies whether the numerical comparison test indicates a violation this cycle. The inherited violation flag is repurposed to represent a numerical violation with sufficient persistence.

Units:

--

bool existing_numerical_violation = {false}#

Flag indicating that a numerical violation has been identified, but not necessarily for a timer-violation.

Units:

--

bool checking_gap_timer = {false}#

Flag indicating that there is currently no violation but the gap timer is being monitored before resetting the violation-timer.

Units:

--

double violation_timer = {0.0}#

Time interval that the numerical-test has been persistently in violation.

Units:

s

double gap_timer = {0.0}#

Time interval that the numerical-test has been persistently satisfied.

Units:

s

double accumulated_violation_timer = {0.0}#

Accumulated durations for which the numerical-test has been in violation; this value does not reset if the numerical-test is satisfied; it exists for logging purposes.

Units:

s


struct ConstraintEnum#
#include "models/utilities/constraint_check/include/constraint_enum.hh"

Enumerations used by the Constraint Check model classes

Public Types

enum ViolationCondition#

Constraint test violation criteria

Note that not all options will be valid for the specific constraint type being checked.

Values:

enumerator Undefined#

Uninitialized condition

enumerator EQ#

Equality

enumerator NEQ#

Inequality

enumerator GT#

Greater-than

enumerator GE#

Greater-than or equal-to

enumerator LT#

Less-than

enumerator LE#

Less-than or equal-to

enumerator In#

Inside a bounded interval or set

enumerator Out#

Outside a bounded interval or set

enum IntervalBounds#

Options for whether the lower and/or upper bound of an interval are considered to be within the interval

Values:

enumerator ClosedClosed#

Lower and upper bounds are included in the interval

enumerator ClosedOpen#

Lower bound is included in the interval but the upper bound is not

enumerator OpenClosed#

Lower bound is not included in the interval but the upper bound is included

enumerator OpenOpen#

Neither the lower bound nor the upper bound are included in the interval


The two classes ConstraintTest and ConstraintTestTimed are then inherited into the following class-templates, which provide the actual constraint-tests. The class-templates use the data-type of the variable as the template parameter.

Instantaneous constraint-tests:

  1. ConstraintTest_Threshold compares the value of the variable against a single threshold value; this template does not have timer support.

  2. ConstraintTest_Interval checks for inclusion of the variable within (or without) an interval specified by an upper and lower bound; this template does not have timer support.

  3. ConstraintTest_ValSet checks for the variable matching (or not-matching) with one of a discrete set of values; this template does not have timer support.

Timed constraint-tests:

  1. ConstraintTest_ThresholdTimed compares the value of the variable against a single threshold value; this template does have timer support.

  2. ConstraintTest_IntervalTimed checks for inclusion of the variable within (or without) an interval specified by an upper and lower bound; this template does have timer support.

  3. ConstraintTest_ValSetTimed checks for the variable matching (or not-matching) with one of a discrete set of values; this template does have timer support.


Instantaneous Constraint Test Classes
template<typename DataType>
class ConstraintTest_Threshold : public ConstraintTest#
#include "models/utilities/constraint_check/include/constraint_test_templates.hh"

A constraint test which evaluates a variable against a threshold value

Configured by selecting the specific comparison behavior from ConstraintEnum, such as greater-than, less-than, equal-to, etc.

Template Parameters:

DataType -- The data type of the threshold

Public Functions

ConstraintTest_Threshold() = default#

Constructor

inline virtual bool initialize() override#

Verify that the model has been configured correctly

Returns:

Always true

inline bool test_violation(DataType variable)#

Evaluate whether the constraint has been violated

Note

If the model is not active, always returns false even if the constraint is technically violated.

Parameters:

variable -- [in] The value being tested

Returns:

true if the constraint was violated

inline virtual double get_threshold() const override#

Return the threshold being tested against

Returns:

threshold casted to double

Pre:

The data type of threshold must be convertible to double

Public Members

DataType threshold = {}#

The threshold value that, if crossed, will trigger a domain violation.

Units:

--

template<typename DataType>
class ConstraintTest_Interval : public ConstraintTest#
#include "models/utilities/constraint_check/include/constraint_test_templates.hh"

A constraint test which evaluates whether a value is contained within an interval

Configured by selecting the specific comparison behavior from ConstraintEnum::IntervalBounds, such as a closed-closed interval, closed-open interval, etc.

Template Parameters:

DataType -- The data type of the interval

Public Functions

ConstraintTest_Interval() = default#

Constructor

inline virtual bool initialize() override#

Verify that the model has been configured correctly

If the upper_bound and lower_bound are within the equality_threshold (i.e., too close together), the model is not configured properly.

Returns:

true if the configuration is valid

inline bool test_violation(DataType variable)#

Evaluate whether the constraint has been violated

Checks for whether variable is included within the specified upper and lower bounds. This check is combined with the configuration for what determines a violation (i.e., whether being inside or outside the interval constitutes a violation) to determine the violation status.

Note

If the model is not active, always returns false even if the constraint is technically violated.

Parameters:

variable -- [in] The value being tested

Returns:

true if the constraint was violated

Public Members

DataType lower_bound = {0}#

The lower bound of the interval that, if crossed, will trigger a domain violation.

Units:

--

DataType upper_bound = {0}#

The upper bound of the interval that, if crossed, will trigger a domain violation.

Units:

--

ConstraintEnum::IntervalBounds interval_bounds = {ConstraintEnum::ClosedClosed}#

Option for how to treat a value at the edges of the interval.

Units:

--

template<typename DataType>
class ConstraintTest_ValSet : public ConstraintTest#
#include "models/utilities/constraint_check/include/constraint_test_templates.hh"

A constraint test which evaluates whether a value is contained within a set of predetermined values

Template Parameters:

DataType -- The data type of the set of values to test against

Public Functions

ConstraintTest_ValSet() = default#

Constructor

inline virtual bool initialize() override#

Verify that the model has been configured correctly

If no values have been defined to test against in values, the configuration is invalid.

Returns:

true if the configuration is valid

inline bool test_violation(DataType variable)#

Evaluate whether the constraint has been violated

Checks for whether variable is equal to one of the values in values. The result of this test is combined with the configuration for what constitutes a violation (i.e., violation if the value is contained in the list or if the value is not contained in the list) to determine the violation status.

Note

If the model is not active, always returns false even if the constraint is technically violated.

Parameters:

variable -- [in] The value being tested

Returns:

true if the constraint was violated

Public Members

std::list<DataType> values#

The values against which the variable under test is compared against.

Units:

--


Timed Constraint Test Classes
template<typename DataType>
class ConstraintTest_ThresholdTimed : public ConstraintTestTimed#
#include "models/utilities/constraint_check/include/constraint_test_timed_templates.hh"

A constraint test which evaluates a variable against a threshold value over a period of time

Configured by selecting the specific comparison behavior from ConstraintEnum, such as greater-than, less-than, equal-to, etc.

Template Parameters:

DataType -- The data type of the threshold

Public Functions

ConstraintTest_ThresholdTimed() = default#

Constructor

inline virtual bool initialize() override#

Verify that the model has been configured correctly

Returns:

Always true

inline bool test_violation(DataType variable, double delta_time)#

Evaluate whether the constraint has been violated

Note

If the model is not active, always returns false even if the constraint is technically violated.

Parameters:
  • variable -- [in] The value being tested

  • delta_time -- [in] Simulation job execution period

Returns:

true if the constraint was violated

inline virtual double get_threshold() const override#

Return the threshold being tested against

Returns:

threshold casted to double

Pre:

The data type of threshold must be convertible to double

Public Members

DataType threshold = {}#

The threshold value that, if crossed, will trigger a domain violation.

Units:

--

template<typename DataType>
class ConstraintTest_IntervalTimed : public ConstraintTestTimed#
#include "models/utilities/constraint_check/include/constraint_test_timed_templates.hh"

A constraint test which evaluates whether a value is contained within an interval over a period of time

Configured by selecting the specific comparison behavior from ConstraintEnum::IntervalBounds, such as a closed-closed interval, closed-open interval, etc.

Template Parameters:

DataType -- The data type of the interval

Public Functions

ConstraintTest_IntervalTimed() = default#

Constructor

inline virtual bool initialize() override#

Verify that the model has been configured correctly

If the upper_bound and lower_bound are within the equality_threshold (i.e., too close together), the model is not configured properly.

Returns:

true if the configuration is valid

inline bool test_violation(DataType variable, double delta_time)#

Evaluate whether the constraint has been violated

Checks for whether variable is included within the specified upper and lower bounds. This check is combined with the configuration for what determines a violation (i.e., whether being inside or outside the interval constitutes a violation) to determine the violation status.

Note

If the model is not active, always returns false even if the constraint is technically violated.

Parameters:
  • variable -- [in] The value being tested

  • delta_time -- [in] Simulation job execution period

Returns:

true if the constraint was violated

Public Members

DataType lower_bound = {0}#

The lower bound of the interval that, if crossed, will trigger a domain violation.

Units:

--

DataType upper_bound = {0}#

The upper bound of the interval that, if crossed, will trigger a domain violation.

Units:

--

ConstraintEnum::IntervalBounds interval_bounds = {ConstraintEnum::ClosedClosed}#

Option for how to treat a value at the edges of the interval.

Units:

--

template<typename DataType>
class ConstraintTest_ValSetTimed : public ConstraintTestTimed#
#include "models/utilities/constraint_check/include/constraint_test_timed_templates.hh"

A constraint test which evaluates whether a value is contained within a set of predetermined values over a period of time

Template Parameters:

DataType -- The data type of the set of values to test against

Public Functions

ConstraintTest_ValSetTimed() = default#

Constructor

inline virtual bool initialize() override#

Verify that the model has been configured correctly

If no values have been defined to test against in values, the configuration is invalid.

Returns:

true if the configuration is valid

inline bool test_violation(DataType variable, double delta_time)#

Evaluate whether the constraint has been violated

Checks for whether variable is equal to one of the values in values. The result of this test is combined with the configuration for what constitutes a violation (i.e., violation if the value is contained in the list or if the value is not contained in the list) to determine the violation status.

Note

If the model is not active, always returns false even if the constraint is technically violated.

Parameters:
  • variable -- [in] The value being tested

  • delta_time -- [in] Simulation job execution period

Returns:

true if the constraint was violated

Public Members

std::list<DataType> values#

The values against which the variable under test is compared against.

Units:

--


Constraint#

A constraint comprises some number (at least 1) of constraint-tests. The Constraint class is an abstract class, providing a common foundation on which the specifically-configured instantiable constraints are defined. The instantiable constraints are all represented as class-templates, taking two template parameters:

  1. the data-type of the variable being evaluated

  2. the number of constraint-tests being made by this constraint


class Constraint#
#include "models/utilities/constraint_check/include/constraint.hh"

An abstract class which holds an arbitrary number of constraint tests

Subclassed by IntervalInstantConstraint< DataType, NumIntervals >, IntervalTimedConstraint< DataType, NumIntervals >, ThresholdInstantConstraint< DataType, NumThresholds >, ThresholdTimedConstraint< DataType, NumThresholds >, ThresholdTimedConstraintSpecData< DataType, NumSpecs, NumTests >, ValSetInstantConstraint< DataType, NumValSets >, ValSetTimedConstraint< DataType, NumValSets >

Public Functions

Constraint() = default#

Constructor

virtual ~Constraint() = default#

Virtual destructor

Constraint(const Constraint&) = delete#

Copy constructor deleted

Constraint &operator=(const Constraint&) = delete#

Copy assignment operator deleted

virtual void initialize()#

Verify that the model was configured correctly

inline bool is_initialized() const#
Returns:

true if the model is initialized

inline bool is_active() const#
Returns:

true if the model is active

virtual void update() = 0#

The model's main update routine and customization point for child classes to implement their specific behaviors

template<typename TestType, std::size_t NumTests>
inline void register_tests(TestType (&new_tests)[NumTests])#

Add constraint tests to the internal list of tests which will execute during model updates

Usually, child classes contain a member array of the specific constraint-test type which they manage and will call this function in their constructor. See one of this class's children for an example.

Warning

Pointers to the contents of new_tests are stored internally. That array's lifetime must be at least as long as this object's.

Template Parameters:
  • TestType -- The test type, which must be derived from ConstraintTest

  • NumTests -- Size of the array

Parameters:

new_tests -- [in] Tests to register

void activate()#

Activate the constraint and all of its enabled constraint-tests

inline void deactivate()#

Deactivate the constraint

Public Members

ConstraintEnum::ViolationCondition violation_condition = {ConstraintEnum::Undefined}#

The default violation-condition to be applied to all constraint-tests within this constraint, unless they are configured separately.

Units:

--

std::string name = {"Unnamed Constraint"}#

Name of constraint; optional, used for debugging.

Units:

--

bool violated = {false}#

Flag indicating that after evaluating the associated ConstraintTest instances, at least one was found with a violation.

Units:

--

unsigned int violation_count = {0}#

Count of the number of violations encountered of this constraint.

Units:

--

bool violate_on_any_test = {true}#

For constraints with multiple tests, this flag identifies whether the constraint is violated when ANY or ALL tests indicate a violation. User-specified configuration option.

Units:

--

bool enabled = {true}#

Flag indicating this constraint is intended to be evaluated. Constraints may be disabled, which prevents them from being activated. An active constraint gets processed.

Units:

--

unsigned int test_violated_index = {0}#

Record of which test caused the constraint to be violated.

Units:

--

double test_violated_time_limit = {0.0}#

The time-limit -- where applicable -- of (one of) the test(s) that resulted in a violation. If multiple tests result in a violation, the value recorded here is that of the lowest indexed test. If the tests do not include time limits, this value will remain 0.0

Units:

s

double test_violated_threshold = {0.0}#

The threshold -- where applicable -- of (one of) the test(s) that resulted in a violation, cast to a double for logging purposes. If multiple tests result in a violation, the value recorded here is that of the lowest indexed test. If the tests do not include thresholds, this value will remain 0.0. Technically in the units of the threshold / test, which are unknown.

Units:

--

Protected Functions

void post_update()#

Determine the overall violation status of the constraint based on the violation status of its constituent constraint-tests

Runs after all constraint-tests have been evaluated.

Protected Attributes

bool active = {false}#

Flag indicating this constraint is going to be checked by the next cycle of the associated constraint-set.

Units:

--

bool initialized = {false}#

Flag indicating this constraint-checker has passed sanity checks and is ready to be used.

Units:

--

std::vector<ConstraintTest*> test_list#

List of pointers to constraint-tests, used for baseline functionality.

Units:

--


A constraint may utilize any number of any combination of the constraint-tests outlined above. There are seven pre-packaged class-templates for easy use, as follows:

  1. ThresholdInstantConstraint uses the specified number of ConstraintTest_Threshold tests.

  2. IntervalInstantConstraint uses the specified number of ConstraintTest_Interval tests.

  3. ValSetInstantConstraint uses the specified number of ConstraintTest_ValSet tests.

  4. ThresholdTimedConstraint uses the specified number of ConstraintTest_ThresholdTimed tests.

  5. IntervalTimedConstraint uses the specified number of ConstraintTest_IntervalTimed tests.

  6. ValSetTimedConstraint uses the specified number of ConstraintTest_ValSetTimed tests.

  7. ThresholdTimedConstraintSpecData provides an example of utilizing specified thresholds to define tests internally. This template takes three parameters:

    1. the data-type of the variable being evaluated

    2. the number of threshold values (and their respective violation times) per specification

    3. the number of threshold values (and their respective violation times) to test.

      An instance of this type will use the specified thresholds as interpolation anchor points, and compute the desired number of threshold-testing values to be equally spaced among those anchor values. The durations associated with each of these tests are then also interpolated from the anchor-durations; linear and logarithmic interpolation algorithms are included for computing the duration values.


Threshold Constraint Classes
template<typename DataType, std::size_t NumThresholds>
class ThresholdInstantConstraint : public Constraint#
#include "models/utilities/constraint_check/include/threshold_constraint.hh"

Uses the threshold constraint tests, which are violated when the variable has an unfavorable comparison against some threshold value

The comparison could be one of several options: ==, !=, >, >=, <, <= Combining these tests typically results in a constraint violation when the variable violates wither all thresholds, or any threshold.

The tests used in this constraint are set to be marked as violated immediately upon the variable violating the specified threshold bounds.

Note

There is a lot of similarity between this class and the comparable ThresholdTimedConstraint class. An inheritance pattern was deliberately avoided here to avoid the complication of inheriting from a class-template (the common material would have to be templated), and having to expose all possible base classes to SWIG.

Note

There is limited value in having multiple threshold-violation tests without time delays on the individual tests. Using ANY logic, whichever constraint-test is least restrictive would always trip the constraint; using ALL logic, whichever constraint-test is most restrictive would always trip the constraint. In either case, only 1 constraint-test is actually useful. Nevertheless, the overhead of executing with the possibility of having multiple tests is negligible and simplifies the overall design.

Template Parameters:
  • DataType -- Data type of the variable being monitored

  • NumThresholds -- Number of threshold constraint tests which constitute this constraint

Pre:

NumThresholds cannot be zero.

Public Functions

inline explicit ThresholdInstantConstraint(const DataType &var)#

Construct the constraint and register its tests with the base class

Parameters:

var -- [in] Reference to the variable being monitored

inline ThresholdInstantConstraint(const DataType &var, ConstraintSet &set)#

Construct the constraint, register its tests with the base class, and register the constraint with a constraint-set

Parameters:
  • var -- [in] Reference to the variable being monitored

  • set -- [out] Constraint set which manages this constraint

ThresholdInstantConstraint(const ThresholdInstantConstraint&) = delete#

Copy constructor deleted

ThresholdInstantConstraint &operator=(const ThresholdInstantConstraint&) = delete#

Copy assignment operator deleted

inline virtual void update() override#

Check each constituent constraint-test for violations

Public Members

ConstraintTest_Threshold<DataType> tests[NumThresholds]#

The single Constraint-test for this constraint. Note -- cannot use a std::array here because Trick's checkpoint-restart prevents use of STL-arrays of templated instances.

Units:

--

Protected Attributes

const DataType &variable#

The variable being monitored for violation of the constraints.

Units:

--

template<typename DataType, std::size_t NumThresholds>
class ThresholdTimedConstraint : public Constraint#
#include "models/utilities/constraint_check/include/threshold_constraint.hh"

Uses the threshold constraint tests, which are violated when the variable has an unfavorable comparison against some threshold value.

The comparison could be one of several options: ==, !=, >, >=, <, <= Combining these tests typically results in a constraint violation when the variable violates wither all thresholds, or any threshold.

The tests used in this constraint are set to be marked as violated when the variable persistently violates the specified threshold for an assigned period of time.

Example: violation if: x > 1 for 3 seconds, OR x > 2 for 2 second, OR x > 3 for 1 second

Note

There is a lot of similarity between this class and the comparable ThresholdInstantConstraint class. An inheritance pattern was deliberately avoided here to avoid the complication of inheriting from a class-template (the common material would have to be templated), and having to expose all possible base classes to SWIG. It is simpler to duplicate some content.

Template Parameters:
  • DataType -- Data type of the variable being monitored

  • NumThresholds -- Number of timed threshold constraint tests which constitute this constraint

Pre:

NumThresholds cannot be zero.

Public Functions

inline ThresholdTimedConstraint(const DataType &variable_, const double &delta_time_)#

Construct the constraint and register its tests with the base class

Parameters:
  • variable_ -- [in] Reference to the variable being monitored

  • delta_time_ -- [in] Reference to the update period of this model

inline ThresholdTimedConstraint(const DataType &variable_, const double &delta_time_, ConstraintSet &set)#

Construct the constraint, register its tests with the base class, and register the constraint with a constraint-set

Parameters:
  • variable_ -- [in] Reference to the variable being monitored

  • delta_time_ -- [in] Reference to the update period of this class

  • set -- [inout] Constraint set which manages this constraint

ThresholdTimedConstraint(const ThresholdTimedConstraint&) = delete#

Copy constructor deleted

ThresholdTimedConstraint &operator=(const ThresholdTimedConstraint&) = delete#

Copy assignment operator deleted

inline virtual void update() override#

Check each constituent constraint-test for violations

Public Members

ConstraintTest_ThresholdTimed<DataType> tests[NumThresholds]#

The single Constraint-test for this constraint. Note -- cannot use a std::array here because Trick's checkpoint-restart prevents use of STL-arrays of templated instances.

Units:

--

Protected Attributes

const DataType &variable#

The variable being monitored for violation of the constraints.

Units:

--

const double &delta_time#

Reference to the time-elapsed between calls to update this constraint.

Units:

s

template<typename DataType, std::size_t NumSpecs, std::size_t NumTests>
class ThresholdTimedConstraintSpecData : public Constraint#
#include "models/utilities/constraint_check/include/threshold_constraint.hh"

An extension of ThresholdTimedConstraint, with the addition of arrays for specifying the data and the capability to interpolate between the specified data values to generate tests at interim data points.

The ThresholdTimedConstraint class only supports direct population of the values in its tests array.

Note

There is a lot of similarity between this class and the comparable ThresholdTimedConstraint class. An inheritance pattern was deliberately avoided here to avoid the complication of inheriting from a class-template (the common material would have to be templated), and having to expose all possible base classes to SWIG. It is simpler to duplicate some content.

Template Parameters:
  • DataType -- Data type of the variable being monitored

  • NumSpecs -- Number of specifications available

  • NumTests -- Number of timed threshold constraint tests which constitute this constraint

Pre:

NumTests cannot be zero.

Pre:

NumSpecs cannot be zero.

Public Functions

inline ThresholdTimedConstraintSpecData(const DataType &variable_, const double &delta_time_)#

Construct the constraint and register its tests with the base class

Parameters:
  • variable_ -- [in] Reference to the variable being monitored

  • delta_time_ -- [in] Reference to the update period of this model

inline ThresholdTimedConstraintSpecData(const DataType &variable_, const double &delta_time_, ConstraintSet &set)#

Construct the constraint, register its tests with the base class, and register the constraint with a constraint-set

Parameters:
  • variable_ -- [in] Reference to the variable being monitored

  • delta_time_ -- [in] Reference to the update period of this class

  • set -- [inout] Constraint set which manages this constraint

ThresholdTimedConstraintSpecData(const ThresholdTimedConstraintSpecData&) = delete#

Copy constructor deleted

ThresholdTimedConstraintSpecData &operator=(const ThresholdTimedConstraintSpecData&) = delete#

Copy assignment operator deleted

inline void set_num_specs(std::size_t val)#

Set the number of specification values

inline virtual void initialize() override#

Generate the interpolated test points based on the provided specification values and perform sanity checks

inline bool interpolate_values()#

Interpolate the test values from the input values

Used when the test configuration values are to be populated from the input data arrays in this class, and the size of the input arrays is not the same as the number of tests.

inline virtual void update() override#

Check each constituent constraint-test for violations

Public Members

ConstraintTest_ThresholdTimed<DataType> tests[NumTests]#

The set of Constraint-tests for this constraint. Each test has a threshold value and a duration that, if the reference variable crosses the threshold for longer than duration, results in a violation. Note -- cannot use a std::array here because Trick's checkpoint-restart prevents use of STL-arrays of templated instances.

Units:

--

bool recover_quiet_violation = {false}#

Flag that is copied to each test if populate_tests_from_arrays to indicate that quiet test-violations can be reset.

Units:

--

bool populate_tests_from_arrays = {true}#

Flag indicating whether the test values should be populated directly by the user or indirectly by populating arrays and copying those data to the test data. If this option is set to false, the class becomes functionally equivalent to ThresholdTimedConstraint.

Units:

--

DataType threshold_spec[NumSpecs] = {}#

Set of specified values for the thresholds of tests. If populate_tests_from_arrays, these values are used to populate the threshold values in the constraint-tests. If (num_specs == NumTests), these threshold_spec values are copied directly; otherwise, they will be interpolated to generate the threshold values covering the same domain but in a different number of steps.

Units:

--

double time_spec[NumSpecs] = {}#

Set of specified values for the associated duration before a numerical violation of the threshold becomes an actual violation of the constraint-test. If populate_tests_from_arrays, these values are used to populate the time_limit values in the constraint-tests. If (num_specs == NumTests), these time_spec values are copied directly; Otherwise, they will be interpolated to generate the time_limit values covering the same range but in a different number of steps.

Units:

s

bool use_linear_interpolation = {true}#

Flag used only when interpolating time_limit values from time_spec values. Flag indicates whether the interpolation should be linear (true) or logarithmic (false).

Units:

--

DataType test_violation_value = {}#

The threshold value of (one of) the test that resulted in a violation. If multiple tests result in a violation, the value recorded here is that of the lowest indexed test.

Units:

--

Protected Attributes

const DataType &variable#

The variable being monitored for violation of the constraints.

Units:

--

const double &delta_time#

Reference to the time-elapsed between calls to update this constraint.

Units:

s

std::size_t num_specs = {NumSpecs}#

Number of specifications to be used. Note -- the separation of num_specs from num_specs_available supports the use of a subset of the available specifications for generating the testing parameters. num_specs and num_specs_available are initialized to the same value and num_specs can be modified via set_num_specs prior to initialization.

Units:

--

Protected Static Attributes

static constexpr std::size_t num_specs_available = {NumSpecs}#

Number of specifications available, as set at construction.

Units:

--


Interval Constraint Classes
template<typename DataType, std::size_t NumIntervals>
class IntervalInstantConstraint : public Constraint#
#include "models/utilities/constraint_check/include/interval_constraint.hh"

Uses the interval constraint tests, which are violated when the variable is either within or without a specified interval

Combining these tests typically results in a constraint violation when the variable is either:

  • within any of a set of forbidden intervals, or

  • without all of a set of permissible intervals

The tests used in this constraint are set to be marked as violated immediately upon the variable violating the specified interval bounds.

Pre:

NumIntervals cannot be zero.

Public Functions

inline explicit IntervalInstantConstraint(const DataType &var)#

Construct the constraint and register its tests with the base class

Parameters:

var -- [in] Reference to the variable being monitored

inline IntervalInstantConstraint(const DataType &var, ConstraintSet &set)#

Construct the constraint, register its tests with the base class, and register the constraint with a constraint-set

Parameters:
  • var -- [in] Reference to the variable being monitored

  • set -- [inout] Constraint set which manages this constraint

IntervalInstantConstraint(const IntervalInstantConstraint&) = delete#

Copy constructor deleted

IntervalInstantConstraint &operator=(const IntervalInstantConstraint&) = delete#

Copy assignment operator deleted

inline virtual void initialize() override#

Perform sanity checks

inline virtual void update() override#

Check each constituent constraint-test for violations

Public Members

ConstraintTest_Interval<DataType> tests[NumIntervals]#

The single Constraint-test for this constraint. Note -- cannot use a std::array here because Trick's checkpoint-restart prevents use of STL-arrays of templated instances.

Units:

--

Protected Attributes

const DataType &variable#

The variable being monitored for violation of the constraints.

Units:

--

template<typename DataType, std::size_t NumIntervals>
class IntervalTimedConstraint : public Constraint#
#include "models/utilities/constraint_check/include/interval_constraint.hh"

Uses the interval constraint tests, which are violated when the variable is either within or without a specified interval

Combining these tests typically results in a constraint violation when the variable is either:

  • within any of a set of forbidden intervals, or

  • without all of a set of permissible intervals

The tests used in this constraint are set to be marked as violated when the variable persistently violates the specified interval bounds for an assigned period of time.

Pre:

NumIntervals cannot be zero.

Public Functions

inline IntervalTimedConstraint(const DataType &variable_, const double &delta_time_)#

Construct the constraint and register its tests with the base class

Parameters:
  • variable_ -- [in] Reference to the variable being monitored

  • delta_time_ -- [in] Reference to the update period of this model

inline IntervalTimedConstraint(const DataType &variable_, const double &delta_time_, ConstraintSet &set)#

Construct the constraint, register its tests with the base class, and register the constraint with a constraint-set

Parameters:
  • variable_ -- [in] Reference to the variable being monitored

  • delta_time_ -- [in] Reference to the update period of this class

  • set -- [inout] Constraint set which manages this constraint

IntervalTimedConstraint(const IntervalTimedConstraint&) = delete#

Copy constructor deleted

IntervalTimedConstraint &operator=(const IntervalTimedConstraint&) = delete#

Copy assignment operator deleted

inline virtual void initialize() override#

Perform sanity checks

inline virtual void update() override#

Check each constituent constraint-test for violations

Public Members

ConstraintTest_IntervalTimed<DataType> tests[NumIntervals]#

The single Constraint-test for this constraint. Note -- cannot use a std::array here because Trick's checkpoint-restart prevents use of STL-arrays of templated instances.

Units:

--

Protected Attributes

const DataType &variable#

The variable being monitored for violation of the constraints.

Units:

--

const double &delta_time#

Reference to the time-elapsed between calls to update this constraint.

Units:

s


Value-Set Constraint Classes
template<typename DataType, std::size_t NumValSets>
class ValSetInstantConstraint : public Constraint#
#include "models/utilities/constraint_check/include/valset_constraint.hh"

Uses the interval constraint tests, which are violated when the variable is either within or without a specified interval

Combining these tests typically results in a constraint violation when the variable is either:

  • within any of a set of forbidden intervals, or

  • without all of a set of permissible intervals

The tests used in this constraint are set to be marked as violated immediately upon the variable violating the specified interval bounds.

Template Parameters:
  • DataType -- Data type of the variable being monitored

  • NumValSets -- Number of value-set constraint tests which constitute this constraint

Pre:

NumValSets cannot be zero.

Public Functions

inline explicit ValSetInstantConstraint(const DataType &var)#

Construct the constraint and register its tests with the base class

Parameters:

var -- [in] Reference to the variable being monitored

ValSetInstantConstraint(const ValSetInstantConstraint&) = delete#

Copy constructor deleted

ValSetInstantConstraint &operator=(const ValSetInstantConstraint&) = delete#

Copy assignment operator deleted

inline virtual void initialize() override#

Perform sanity checks

inline virtual void update() override#

Check each constituent constraint-test for violations

Public Members

ConstraintTest_ValSet<DataType> tests[NumValSets]#

The single Constraint-test for this constraint. Note -- cannot use a std::array here because Trick's checkpoint-restart prevents use of STL-arrays of templated instances.

Units:

--

Protected Attributes

const DataType &variable#

The variable being monitored for violation of the constraints.

Units:

--

template<typename DataType, std::size_t NumValSets>
class ValSetTimedConstraint : public Constraint#
#include "models/utilities/constraint_check/include/valset_constraint.hh"

Uses the interval constraint tests, which are violated when the variable is either within or without a specified interval

Combining these tests typically results in a constraint violation when the variable is either:

  • within any of a set of forbidden intervals, or

  • without all of a set of permissible intervals

The tests used in this constraint are set to be marked as violated when the variable persistently violates the specified interval bounds for an assigned period of time.

Template Parameters:
  • DataType -- Data type of the variable being monitored

  • NumValSets -- Number of value-set constraint tests which constitute this constraint

Pre:

NumValSets cannot be zero.

Public Functions

inline ValSetTimedConstraint(const DataType &variable_, const double &delta_time_)#

Construct the constraint and register its tests with the base class

Warning

The lifetime of delta_time_ must be at least as long as this object. A reference to it is stored internally.

Parameters:
  • variable_ -- [in] Reference to the variable being monitored

  • delta_time_ -- [in] Reference to the update period of this model

inline ValSetTimedConstraint(const DataType &variable_, const double &delta_time_, ConstraintSet &set)#

Construct the constraint, register its tests with the base class, and register the constraint with a constraint-set

Warning

The lifetime of delta_time_ must be at least as long as this object. A reference to it is stored internally.

Parameters:
  • variable_ -- [in] Reference to the variable being monitored

  • delta_time_ -- [in] Reference to the update period of this class

  • set -- [inout] Constraint set which manages this constraint

ValSetTimedConstraint(const ValSetTimedConstraint&) = delete#

Copy constructor deleted

ValSetTimedConstraint &operator=(const ValSetTimedConstraint&) = delete#

Copy assignment operator deleted

inline virtual void initialize() override#

Perform sanity checks

inline virtual void update() override#

Check each constituent constraint-test for violations

Public Members

ConstraintTest_ValSetTimed<DataType> tests[NumValSets]#

The single Constraint-test for this constraint. Note -- cannot use a std::array here because Trick's checkpoint-restart prevents use of STL-arrays of templated instances.

Units:

--

Protected Attributes

const DataType &variable#

The variable being monitored for violation of the constraints.

Units:

--

const double &delta_time#

Reference to the time-elapsed between calls to update this constraint.

Units:

s


Constraint-Set#

A constraint-set provides a loosely-associated list of constraints. This is a type of constraint-manager, allowing constraints to be grouped so that they may be activated or deactivated together. A constraint-set cannot be “violated”, such a concept is meaningless in its manager role.


class ConstraintSet : public SubscriptionBase#
#include "models/utilities/constraint_check/include/constraint_set.hh"

Manages a set of constraints

Intended as a base class, to be extended for a particular purpose. The extended class would implement instances of various constraints and -- at the construction of those constraint instances -- have them loaded onto this base-class's constraints list. Additionally, the extended class would provide -- either by calculation or pass-through -- a value to be referenced by this class for the time interval between constraint-checking if necessary.

Public Functions

ConstraintSet() = default#

Constructor

ConstraintSet(ConstraintSet&) = delete#

Copy constructor deleted

ConstraintSet &operator=(ConstraintSet&) = delete#

Copy assignment operator deleted

virtual void initialize() override#

Initialize each constraint and the set itself

Note

If any of the constraints in this set are disabled, calling this function will make them permanently unavailable for the duration of the simulation.

void update()#

Update all constraints and check for violations

inline const std::string &get_violated_constraints() const#

Return a string containing the violated constraints

Example:

std::string violations = constraint_set.get_violated_constraints();
// violations == "Constraint 1, Constraint 4"

Returns:

String of comma-separated constraint names which were violated this timestep

Public Members

std::list<Constraint*> constraints#

Set of pointers to the instances of Constraint being managed by this class. Constraints should be instantiated independently and added to the set.

Units:

--

Public Static Functions

static inline bool constraint_disabled(const Constraint *constraint)#
Parameters:

constraint -- [in] Constraint to check

Returns:

true if the provided constraint is disabled

Pre:

constraint cannot be null

Protected Functions

virtual void activate() override#

Activate the constraints in this set

Called at subscription time

Protected Attributes

unsigned int num_violations = {0}#

Counts the number of constraints violated in this timestep. Do not confuse with Constraint::violation_count, which counts the number of occurrences of a specific constraint violation. across all cycles.

Units:

--

std::string violated_constraints#

Comma-separated list of the names of all constraints in the set that are violated on this timestep .

Units:

--


Example#

Consider a situation in which a condition should be flagged if any of a set of tests fails to pass: for example: ((\(x > 0\) for more than 3 seconds) or (\(x > 2\) for more than 1 second)).

  • Each of those tests will be represented as a ConstraintTest, specifically as a ConstraintTest_ThresholdTimed because both tests evaluate a variable against a threshold-value, with an associated timing constraint.

  • While each of those tests could be represented as a Constraint containing one ConstraintTest, doing so would not be optimal in this configuration.

    • Because the condition should be flagged when either test fails, if each test is represented as a separate Constraint, some external model would have to compile the results of the two constraints and set the overall test result.

    • Because both tests monitor the same variable, both tests can be included in one constraint, which can then be configured to be marked as violated when any of its constraint-tests are violated.

    The optimal configuration for this scenario is to have one constraint, including two constraint tests – in this case an instance of ThresholdTimedConstraint.

  • Even though this example includes a set of evaluative tests, the overall configuration CANNOT be a ConstraintSet because a ConstraintSet has no concept of pass/fail. The ConstraintSet concept is to manage the simultaneous evaluation of multiple constraints. The constraint (comprising multiple constraint-tests) may be managed by a constraint-set, but it cannot be conceptually represented by one.

Mathematical Formulation#

Interpolation#

The ThresholdTimedConstraintSpecData class-template includes the necessary to code to determine the threshold values for testing from a set of threshold-values per specification.

For the purposes of illustration, suppose the specification threshold and associated time-limits are:

threshold

time-limit

1

100

5

10

10

1

If the constraint is configured to use 1 test, the model will always take the first set of values as that test:

threshold

time-limit

1

100

If the constraint is configured to use 2 tests, the model will always take the first and last set of values as that test:

threshold

time-limit

1

100

10

1

If the constraint is configured to use any other number of tests, the model will interpolate the threshold values between the first and last set of values as that test: For example, if it was configured for 3 tests:

threshold

time-limit

1

100

5.5

*

10

1

The value for the time-limit for an interpolated threshold is interpolated between the time-limits of the adjacent specification values – in this case, 5.5 is between 5 and 10, so the time limit will be between 10 and 1 respectively. This interpolation can be conducted using linear or logarithmic interpolation.

Linear Interpolation#

Using subscripts 0 and 1 to represent the adjacent values from the specified data, we have for linear interpolation:

\begin{equation} \begin{aligned} t &= t_{0} + f(t_{1} - t_{0}) \\ &= t_{0}(1 - f) + t_{1} f \end{aligned} \end{equation}

where

\begin{equation} f = \frac{x - x_{0}}{x_{1} - x_{0}} \end{equation}

In the illustration example, this results in the time-limit associated with threshold of 5.5 being:

\begin{equation} \begin{aligned} t &= 10 + \left( \frac{5.5 - 5}{10 - 5} \right) (1 - 10) \\ &= 10 - 0.9 \\ &= 9.1 \end{aligned} \end{equation}

threshold

time-limit

1

100

5.5

9.1

10

1

Logarithmic Interpolation#

Using subscripts 0 and 1 to represent the adjacent values from the specified data, we have for logarithmic interpolation:

\begin{equation} log(t) = log(t_0) + f(log(t_1) - log(t_0)) \end{equation}

where

\begin{equation} f = \frac{log(x) - log(x_0)}{log(x_1) - log(x_0)} = \frac{log\left(\frac{x}{x_0}\right)} {log\left(\frac{x_1}{x_0}\right)} \end{equation}

Note – the code arbitrarily uses base-10 logarithm; due to the nature of logarithms, the selection of the base is irrelevant. Additionally, this set of calculations is only performed once at model initialization; if there is a performance difference it is going to be negligible and not worth the effort to evaluate.

i.e.

\begin{equation} log(t) = log(t_0) + f \times log\left(\frac{t_1}{t_0}\right) \Rightarrow t = t_0 \left( \frac{t_1}{t_0} \right)^f = t_0^{(1-f)} t_1^f \end{equation}

In the illustration example, this results in the fraction \(f\) associated with threshold of 5.5 being:

\begin{equation} f = \frac{log\left( \frac{5.5}{5} \right)} {log\left( \frac{10}{5} \right)} \approx 0.138 \end{equation}

and the corresponding time-limit:

\begin{equation} t = 10 \left(\frac{1}{10}\right)^{0.138} \approx 7.3 \end{equation}

threshold

time-limit

1

100

5.5

7.3

10

1

User’s Guide#

Implementation#

This section has not been filled out yet.

Initialization#

This section has not been filled out yet.

Routine Execution#

This section has not been filled out yet.

Optional Execution#

This section has not been filled out yet.

Configuration#

ThresholdTimedConstraintSpecData#

The ThresholdTimedConstraintSpecData has two important configuration settings not used by other constraints:

The use_linear_interpolation setting switches the computation of the time-limit between using linear and logarithmic interpolation between the specified data points.

The num_specs variable is constructed to be equal to the number of specifications identified in the template parameter. However, particularly for cases where the setting of those specification values is not known at the time of construction, it may be necessary to adjust the number of specifications post-construction.

For example, suppose a constraint may be populated from one of two specification data-sets, one of which contains 3 specific data points, and the other contains 4. The instance must be constructed to be capable of holding 4 in case the latter is used, but must be configurable to hold only 3 in case the former is used.

The set_num_specs() method adjusts the number of specification values to actually use. It cannot be adjusted to more than the instance was constructed to hold because the array has already been sized accordingly. It cannot be adjusted after initialization because the interpolation is conducted at initialization so there is no point in adjusting the number of data points to use for interpolation after interpolation has completed.

Verification#

Code Coverage#

Exceptions#

Simulation Configurations#

Unit-Test Cases#

Dynamic-Test Cases#