Skip to content

Commit

Permalink
Add Alignment and Phase classes
Browse files Browse the repository at this point in the history
Issue #153
  • Loading branch information
rakhimov committed Aug 10, 2017
1 parent 8de2351 commit 34ca4bd
Show file tree
Hide file tree
Showing 5 changed files with 222 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ set(SCRAM_CORE_SRC
"${CMAKE_CURRENT_SOURCE_DIR}/ccf_group.cc"
"${CMAKE_CURRENT_SOURCE_DIR}/fault_tree.cc"
"${CMAKE_CURRENT_SOURCE_DIR}/event_tree.cc"
"${CMAKE_CURRENT_SOURCE_DIR}/alignment.cc"
"${CMAKE_CURRENT_SOURCE_DIR}/model.cc"
"${CMAKE_CURRENT_SOURCE_DIR}/pdag.cc"
"${CMAKE_CURRENT_SOURCE_DIR}/preprocessor.cc"
Expand Down
49 changes: 49 additions & 0 deletions src/alignment.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/*
* Copyright (C) 2017 Olzhas Rakhimov
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

/// @file alignment.cc
/// Implementation of alignment and phase classes.

#include "alignment.h"

#include "error.h"

namespace scram {
namespace mef {

Phase::Phase(std::string name, double time_fraction)
: Element(std::move(name)), time_fraction_(time_fraction) {
if (time_fraction_ <= 0 || time_fraction_ > 1)
throw InvalidArgument("The phase fraction must be in (0, 1].");
}

void Alignment::Add(PhasePtr phase) {
AddElement<DuplicateArgumentError>(std::move(phase), &phases_,
"Duplicate phase: ");
}

void Alignment::Validate() {
double sum = 0;
for (const PhasePtr& phase : phases_)
sum += phase->time_fraction();
if (sum != 1)
throw ValidationError("The phases of alignment '" + Element::name() +
"' do not sum to 1.");
}

} // namespace mef
} // namespace scram
93 changes: 93 additions & 0 deletions src/alignment.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
/*
* Copyright (C) 2017 Olzhas Rakhimov
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

/// @file alignment.h
/// Mission and phase constructs.

#ifndef SCRAM_SRC_ALIGNMENT_H_
#define SCRAM_SRC_ALIGNMENT_H_

#include <memory>
#include <string>
#include <vector>

#include <boost/noncopyable.hpp>

#include "element.h"
#include "instruction.h"

namespace scram {
namespace mef {

/// Phases of alignments the models spends its time fraction.
class Phase : public Element, private boost::noncopyable {
public:
/// @copydoc Element::Element
///
/// @param[in] time_fraction The fraction of mission-time spent in the phase.
///
/// @throws InvalidArgument The fraction is not a valid value in (0, 1].
Phase(std::string name, double time_fraction);

/// @returns The positive fraction of mission-time spent in this phase.
double time_fraction() const { return time_fraction_; }

/// @returns The instructions applied in this phase.
const std::vector<SetHouseEvent*>& instructions() const {
return instructions_;
}

/// @param[in] instructions Zero or more instructions for this phase.
void instructions(std::vector<SetHouseEvent*> instructions) {
instructions_ = std::move(instructions);
}

public:
double time_fraction_; ///< The positive fraction of the mission time.
std::vector<SetHouseEvent*> instructions_; ///< The phase modifiers.
};

using PhasePtr = std::unique_ptr<Phase>; ///< Phases are unique to alignments.

/// Alignment configuration for the whole model per analysis.
class Alignment : public Element, private boost::noncopyable {
public:
using Element::Element;

/// @returns The phases defined in the alignment.
const ElementTable<PhasePtr>& phases() const { return phases_; }

/// Adds a phase into alignment.
///
/// @param[in] phase One of the unique phases for the alignment.
///
/// @throws DuplicateArgumentError The phase is duplicate.
void Add(PhasePtr phase);

/// Ensures that all phases add up to be valid for the alignment.
///
/// @throws ValidationError Phases are incomplete (e.g., don't sum to 1).
void Validate();

private:
ElementTable<PhasePtr> phases_; ///< The partitioning of the alignment.
};

} // namespace mef
} // namespace scram

#endif // SCRAM_SRC_ALIGNMENT_H_
1 change: 1 addition & 0 deletions tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ set(SCRAM_CORE_TEST_SOURCE
"${CMAKE_CURRENT_SOURCE_DIR}/expression_tests.cc"
"${CMAKE_CURRENT_SOURCE_DIR}/ccf_group_tests.cc"
"${CMAKE_CURRENT_SOURCE_DIR}/fault_tree_tests.cc"
"${CMAKE_CURRENT_SOURCE_DIR}/alignment_tests.cc"
"${CMAKE_CURRENT_SOURCE_DIR}/pdag_tests.cc"
"${CMAKE_CURRENT_SOURCE_DIR}/initializer_tests.cc"
"${CMAKE_CURRENT_SOURCE_DIR}/risk_analysis_tests.cc"
Expand Down
78 changes: 78 additions & 0 deletions tests/alignment_tests.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
/*
* Copyright (C) 2017 Olzhas Rakhimov
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

#include "alignment.h"

#include <gtest/gtest.h>

#include "error.h"

namespace scram {
namespace mef {
namespace test {

TEST(PhaseTest, TimeFraction) {
EXPECT_NO_THROW(Phase("phase", 0.5));
EXPECT_NO_THROW(Phase("phase", 0.1));
EXPECT_NO_THROW(Phase("phase", 1));

EXPECT_THROW(Phase("phase", 0), InvalidArgument);
EXPECT_THROW(Phase("phase", 1.1), InvalidArgument);
EXPECT_THROW(Phase("phase", -0.1), InvalidArgument);
}

TEST(AlignmentTest, AddPhase) {
Alignment alignment("mission");
auto phase_one = std::make_unique<Phase>("one", 0.5);
auto phase_two = std::make_unique<Phase>("one", 0.1); // Duplicate name.
auto phase_three = std::make_unique<Phase>("three", 0.1);

EXPECT_TRUE(alignment.phases().empty());
auto* phase_one_address = phase_one.get();
ASSERT_NO_THROW(alignment.Add(std::move(phase_one)));
EXPECT_EQ(1, alignment.phases().size());
EXPECT_EQ(phase_one_address, alignment.phases().begin()->get());

EXPECT_THROW(alignment.Add(std::move(phase_two)), DuplicateArgumentError);
EXPECT_EQ(1, alignment.phases().size());
EXPECT_EQ(phase_one_address, alignment.phases().begin()->get());

ASSERT_NO_THROW(alignment.Add(std::move(phase_three)));
EXPECT_EQ(2, alignment.phases().size());
}

TEST(AlignmentTest, Validation) {
Alignment alignment("mission");
auto phase_one = std::make_unique<Phase>("one", 0.5);
auto phase_two = std::make_unique<Phase>("two", 0.5);
auto phase_three = std::make_unique<Phase>("three", 0.1);

EXPECT_THROW(alignment.Validate(), ValidationError);

ASSERT_NO_THROW(alignment.Add(std::move(phase_one)));
EXPECT_THROW(alignment.Validate(), ValidationError);

ASSERT_NO_THROW(alignment.Add(std::move(phase_two)));
EXPECT_NO_THROW(alignment.Validate());

ASSERT_NO_THROW(alignment.Add(std::move(phase_three)));
EXPECT_THROW(alignment.Validate(), ValidationError);
}

} // namespace test
} // namespace mef
} // namespace scram

0 comments on commit 34ca4bd

Please sign in to comment.