-
Notifications
You must be signed in to change notification settings - Fork 54
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Issue #153
- Loading branch information
Showing
5 changed files
with
222 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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_ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |