Skip to content

packages/engine/scram-node/src/probability_analysis.h

Contains functionality to do numerical analysis of probabilities.

Namespaces

Name
scram
scram::mef
scram::core

Classes

Name
structscram::core::Sil <br>Safety Integrity Level metrics.
classscram::core::ProbabilityAnalysis <br>Main quantitative analysis class.
classscram::core::CutSetProbabilityCalculator <br>Quantitative calculator of a probability value of a single cut set.
classscram::core::RareEventCalculator <br>Quantitative calculator of probability values with the Rare-Event approximation.
classscram::core::McubCalculator <br>Quantitative calculator of probability values with the Min-Cut-Upper Bound approximation.
classscram::core::ProbabilityAnalyzerBase <br>Base class for Probability analyzers.
classscram::core::ProbabilityAnalyzer <br>Fault-tree-analysis-aware probability analyzer.
classscram::core::ProbabilityAnalyzer< Bdd > <br>Specialization of probability analyzer with Binary Decision Diagrams.

Source code

cpp
/*
 * Copyright (C) 2014-2018 Olzhas Rakhimov
 * Copyright (C) 2023 OpenPRA ORG Inc.
 *
 * 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/>.
 */


#pragma once

#include <utility>
#include <vector>

#include "analysis.h"
#include "bdd.h"
#include "fault_tree_analysis.h"
#include "pdag.h"

namespace scram::mef {
class MissionTime;
}  // namespace scram::mef

namespace scram::core {

struct Sil {
  double pfd_avg = 0;  
  double pfh_avg = 0;  

  std::array<std::pair<const double, double>, 6> pfd_fractions{
      {{1e-5, 0}, {1e-4, 0}, {1e-3, 0}, {1e-2, 0}, {1e-1, 0}, {1, 0}}};
  std::array<std::pair<const double, double>, 6> pfh_fractions{
      {{1e-9, 0}, {1e-8, 0}, {1e-7, 0}, {1e-6, 0}, {1e-5, 0}, {1, 0}}};
};

class ProbabilityAnalysis : public Analysis {
 public:
  ProbabilityAnalysis(const FaultTreeAnalysis* fta,
                      mef::MissionTime* mission_time);

  virtual ~ProbabilityAnalysis() = default;

  void Analyze() noexcept;

  double p_total() const { return p_total_; }

  const std::vector<std::pair<double, double>>& p_time() const {
    return p_time_;
  }

  const Sil& sil() const {
    assert(sil_ && "The SIL is not done!");
    return *sil_;
  }

 protected:
  mef::MissionTime& mission_time() { return *mission_time_; }

 private:
  virtual double CalculateTotalProbability() noexcept = 0;

  virtual std::vector<std::pair<double, double>>
  CalculateProbabilityOverTime() noexcept = 0;

  void ComputeSil() noexcept;

  double p_total_;  
  mef::MissionTime* mission_time_;  
  std::vector<std::pair<double, double>> p_time_;  
  std::unique_ptr<Sil> sil_;  
};

class CutSetProbabilityCalculator {
 public:
  double Calculate(const std::vector<int>& cut_set,
                   const Pdag::IndexMap<double>& p_vars) noexcept;
};

class Zbdd;  // The container of analysis products for computations.

class RareEventCalculator : private CutSetProbabilityCalculator {
 public:
  double Calculate(const Zbdd& cut_sets,
                   const Pdag::IndexMap<double>& p_vars) noexcept;
};

class McubCalculator : private CutSetProbabilityCalculator {
 public:
  double Calculate(const Zbdd& cut_sets,
                   const Pdag::IndexMap<double>& p_vars) noexcept;
};

class ProbabilityAnalyzerBase : public ProbabilityAnalysis {
 public:
  template <class Algorithm>
  ProbabilityAnalyzerBase(const FaultTreeAnalyzer<Algorithm>* fta,
                          mef::MissionTime* mission_time)
      : ProbabilityAnalysis(fta, mission_time),
        graph_(fta->graph()),
        products_(fta->algorithm()->products()) {
    ExtractVariableProbabilities();
  }

  const Pdag* graph() const { return graph_; }

  const Zbdd& products() const { return products_; }

  const Pdag::IndexMap<double>& p_vars() const { return p_vars_; }

 protected:
  ~ProbabilityAnalyzerBase() override = default;

 private:
  virtual double
  CalculateTotalProbability(const Pdag::IndexMap<double>& p_vars) noexcept = 0;

  double CalculateTotalProbability() noexcept final {
    return this->CalculateTotalProbability(p_vars_);
  }

  std::vector<std::pair<double, double>>
  CalculateProbabilityOverTime() noexcept final;

  void ExtractVariableProbabilities();

  const Pdag* graph_;  
  const Zbdd& products_;  
  Pdag::IndexMap<double> p_vars_;  
};

template <class Calculator>
class ProbabilityAnalyzer : public ProbabilityAnalyzerBase {
 public:
  using ProbabilityAnalyzerBase::ProbabilityAnalyzerBase;

  double CalculateTotalProbability(
      const Pdag::IndexMap<double>& p_vars) noexcept final {
    return calc_.Calculate(ProbabilityAnalyzerBase::products(), p_vars);
  }

 private:
  Calculator calc_;  
};

template <>
class ProbabilityAnalyzer<Bdd> : public ProbabilityAnalyzerBase {
 public:
  template <class Algorithm>
  ProbabilityAnalyzer(const FaultTreeAnalyzer<Algorithm>* fta,
                      mef::MissionTime* mission_time)
      : ProbabilityAnalyzerBase(fta, mission_time),
        current_mark_(false),
        owner_(true) {
    CreateBdd(*fta);
  }

  ProbabilityAnalyzer(FaultTreeAnalyzer<Bdd>* fta,
                      mef::MissionTime* mission_time);

  ~ProbabilityAnalyzer() noexcept;

  Bdd* bdd_graph() { return bdd_graph_; }

  double CalculateTotalProbability(
      const Pdag::IndexMap<double>& p_vars) noexcept final;

 private:
  void CreateBdd(const FaultTreeAnalysis& fta) noexcept;

  double CalculateProbability(const Bdd::VertexPtr& vertex, bool mark,
                              const Pdag::IndexMap<double>& p_vars) noexcept;

  Bdd* bdd_graph_;  
  bool current_mark_;  
  bool owner_;  
};

}  // namespace scram::core

Updated on 2025-11-11 at 16:51:09 +0000