<commit_before>#ifndef BART_SRC_MATERIAL_MATERIAL_PROPERTIES_H_
#define BART_SRC_MATERIAL_MATERIAL_PROPERTIES_H_

#include <string>
#include <unordered_map>
#include <unordered_set>
#include <vector>

#include <deal.II/base/exceptions.h>
#include <deal.II/base/parameter_handler.h>
#include <deal.II/lac/full_matrix.h>

#include <google/protobuf/io/zero_copy_stream_impl.h>
#include <google/protobuf/text_format.h>

#include "../../material.pb.h"

#include "../common/numbers.h"

//! This class reads in and pre-processes material properties.
/*!
 \author <NAME>
 \date 2017/04~06
 Modified by <EMAIL> August 2018

 \todo Add functionality to perform eigenvalue decomposition.
 */
class MaterialProperties {
 public:
  /*!
    constructor using map of numerical IDs to Material objects
    do_nda is currently unused, and may be removed in the future
    fissile_ids must be non-empty if is_eigen_problem is given as true
   */
  MaterialProperties(const std::unordered_map<int, Material>& materials,
                     bool is_eigen_problem,
                     bool do_nda,
                     int number_of_groups,
                     int number_of_materials,
                     const std::unordered_set<int>& fissile_ids = {});

  /*!
    gets the necessary information from the parameter handler and
    delegates to the other constructor
  */
  explicit MaterialProperties(dealii::ParameterHandler& prm);

  //! default destructor
  ~MaterialProperties();

  /*!
    returns an unordered_map from material ID to a
    boolean that is true if the material was labeled fissile
  */
  std::unordered_map<int, bool> GetFissileIDMap() const;

  //! Returns all \f$\sigma_\mathrm{t}\f$ for all groups.
  std::unordered_map<int, std::vector<double>> GetSigT() const;

  //! Returns all \f$1/\sigma_\mathrm{t}\f$ for all groups.
  std::unordered_map<int, std::vector<double>> GetInvSigT() const;

  //! Returns all fixed source value \f$Q\f$'s for all groups.
  std::unordered_map<int, std::vector<double>> GetQ() const;

  //! Returns all \f$Q/(4\pi)\f$'s for all groups.
  std::unordered_map<int, std::vector<double>> GetQPerSter() const;

  //! Returns all \f$\nu\sigma_\mathrm{f}\f$'s.
  std::unordered_map<int, std::vector<double>> GetNuSigF() const;

  //! Returns all scattering transfer matrices.
  std::unordered_map<int, dealii::FullMatrix<double>>
  GetSigS() const;

  //! Returns all scattering transfer matrices scaled by \f$4\pi\f$.
  std::unordered_map<int, dealii::FullMatrix<double>>
  GetSigSPerSter() const;

  //! Returns \f$\chi\nu\sigma_\mathrm{f}\f$ for all fissile materials.
  std::unordered_map<int, dealii::FullMatrix<double>>
  GetChiNuSigF() const;

  //! Returns \f$\chi\nu\sigma_\mathrm{f}/(4\pi)\f$ for all fissile materials.
  std::unordered_map<int, dealii::FullMatrix<double>>
  GetChiNuSigFPerSter() const;

  /*!
    asserts that a Material is self-consistent,
    contains the required data,
    and that that data is valid

    The energy groups, sigma_t, and the scattering matrix are always required.
    nu Sigma_f and Chi (normalized to 1) are required for fissile materials.

    If the material contains Q, the Q data will be required to be valid.
    Other properties are not checked except for MultipleDefinition,
    which will not be thrown for UNKNOWN_VECTOR.

    Can throw one of the following,
    with checks for each exception in the order they are listed:
      MultipleDefinition
      MissingProperty
      WrongNumberOfValues
      WrongSign
      EnergyGroupBoundariesNotSorted
      ChiDoesNotSumToOne (only if fission data is required)

    the name parameter is used for identifying the material in the
    generated exception
    by default, CombinedName(material) is used for the name
  */
  static void CheckValid(const Material& material,
                         bool require_fission_data = false,
                         std::string name = "");

  /*!
    asserts that the materials in the given map are compatible with one another
    the following things are required to be the same in all of the materials:
      number of groups (throws NumberOfGroupsMismatch if different)
      energy group boundaries  (throws EnergyGroupsMismatch if different)
  */
  static void CheckConsistent(const std::unordered_map<int, Material>& materials);

 private:
  //! protobuf generated Material object for each material ID
  const std::unordered_map<int, Material> materials_;

  //! Boolean to determine if it's an eigenvalue problem.
  const bool is_eigen_problem_;

  //! Boolean to determine if nonlinear diffusion acceleration is used.
  const bool do_nda_;

  //! Number of energy groups.
  const int n_group_;

  //! Number of materials.
  const int n_material_;

  //! Set of fissile material IDs.
  std::unordered_set<int> fissile_ids_;

  //! Map of material ID to a bool indicating if it is fissile.
  std::unordered_map<int, bool> is_material_fissile_;

  //! \f$\sigma_\mathrm{t}\f$ of all groups for all materials.
  std::unordered_map<int, std::vector<double>> sigt_;

  //! \f$1/\sigma_\mathrm{t}\f$ of all groups for all materials
  std::unordered_map<int, std::vector<double>> inv_sigt_;

  /*!
   \f$\chi\f$ for all materials. A mistake when designing this is that it was
   treated as other properties. Yet, it is group independent.

   \todo Change this to std::vector<double> chi, or using Hash table.
   */
  std::unordered_map<int, std::vector<double>> chi_;

  //! \f$\nu\sigma_\mathrm{f}\f$ of all groups for all materials.
  std::unordered_map<int, std::vector<double>> nusigf_;

  //! Fixed source value \f$Q\f$'s of all groups for all materials.
  std::unordered_map<int, std::vector<double>> q_;

  //! Fixed source value \f$Q/(4\pi)\f$'s of all groups for all materials.<commit_msg>removed out of date comment for chi_<commit_after>#ifndef BART_SRC_MATERIAL_MATERIAL_PROPERTIES_H_
#define BART_SRC_MATERIAL_MATERIAL_PROPERTIES_H_

#include <string>
#include <unordered_map>
#include <unordered_set>
#include <vector>

#include <deal.II/base/exceptions.h>
#include <deal.II/base/parameter_handler.h>
#include <deal.II/lac/full_matrix.h>

#include <google/protobuf/io/zero_copy_stream_impl.h>
#include <google/protobuf/text_format.h>

#include "../../material.pb.h"

#include "../common/numbers.h"

//! This class reads in and pre-processes material properties.
/*!
 \author <NAME>
 \date 2017/04~06
 Modified by <EMAIL> August 2018

 \todo Add functionality to perform eigenvalue decomposition.
 */
class MaterialProperties {
 public:
  /*!
    constructor using map of numerical IDs to Material objects
    do_nda is currently unused, and may be removed in the future
    fissile_ids must be non-empty if is_eigen_problem is given as true
   */
  MaterialProperties(const std::unordered_map<int, Material>& materials,
                     bool is_eigen_problem,
                     bool do_nda,
                     int number_of_groups,
                     int number_of_materials,
                     const std::unordered_set<int>& fissile_ids = {});

  /*!
    gets the necessary information from the parameter handler and
    delegates to the other constructor
  */
  explicit MaterialProperties(dealii::ParameterHandler& prm);

  //! default destructor
  ~MaterialProperties();

  /*!
    returns an unordered_map from material ID to a
    boolean that is true if the material was labeled fissile
  */
  std::unordered_map<int, bool> GetFissileIDMap() const;

  //! Returns all \f$\sigma_\mathrm{t}\f$ for all groups.
  std::unordered_map<int, std::vector<double>> GetSigT() const;

  //! Returns all \f$1/\sigma_\mathrm{t}\f$ for all groups.
  std::unordered_map<int, std::vector<double>> GetInvSigT() const;

  //! Returns all fixed source value \f$Q\f$'s for all groups.
  std::unordered_map<int, std::vector<double>> GetQ() const;

  //! Returns all \f$Q/(4\pi)\f$'s for all groups.
  std::unordered_map<int, std::vector<double>> GetQPerSter() const;

  //! Returns all \f$\nu\sigma_\mathrm{f}\f$'s.
  std::unordered_map<int, std::vector<double>> GetNuSigF() const;

  //! Returns all scattering transfer matrices.
  std::unordered_map<int, dealii::FullMatrix<double>>
  GetSigS() const;

  //! Returns all scattering transfer matrices scaled by \f$4\pi\f$.
  std::unordered_map<int, dealii::FullMatrix<double>>
  GetSigSPerSter() const;

  //! Returns \f$\chi\nu\sigma_\mathrm{f}\f$ for all fissile materials.
  std::unordered_map<int, dealii::FullMatrix<double>>
  GetChiNuSigF() const;

  //! Returns \f$\chi\nu\sigma_\mathrm{f}/(4\pi)\f$ for all fissile materials.
  std::unordered_map<int, dealii::FullMatrix<double>>
  GetChiNuSigFPerSter() const;

  /*!
    asserts that a Material is self-consistent,
    contains the required data,
    and that that data is valid

    The energy groups, sigma_t, and the scattering matrix are always required.
    nu Sigma_f and Chi (normalized to 1) are required for fissile materials.

    If the material contains Q, the Q data will be required to be valid.
    Other properties are not checked except for MultipleDefinition,
    which will not be thrown for UNKNOWN_VECTOR.

    Can throw one of the following,
    with checks for each exception in the order they are listed:
      MultipleDefinition
      MissingProperty
      WrongNumberOfValues
      WrongSign
      EnergyGroupBoundariesNotSorted
      ChiDoesNotSumToOne (only if fission data is required)

    the name parameter is used for identifying the material in the
    generated exception
    by default, CombinedName(material) is used for the name
  */
  static void CheckValid(const Material& material,
                         bool require_fission_data = false,
                         std::string name = "");

  /*!
    asserts that the materials in the given map are compatible with one another
    the following things are required to be the same in all of the materials:
      number of groups (throws NumberOfGroupsMismatch if different)
      energy group boundaries  (throws EnergyGroupsMismatch if different)
  */
  static void CheckConsistent(const std::unordered_map<int, Material>& materials);

 private:
  //! protobuf generated Material object for each material ID
  const std::unordered_map<int, Material> materials_;

  //! Boolean to determine if it's an eigenvalue problem.
  const bool is_eigen_problem_;

  //! Boolean to determine if nonlinear diffusion acceleration is used.
  const bool do_nda_;

  //! Number of energy groups.
  const int n_group_;

  //! Number of materials.
  const int n_material_;

  //! Set of fissile material IDs.
  std::unordered_set<int> fissile_ids_;

  //! Map of material ID to a bool indicating if it is fissile.
  std::unordered_map<int, bool> is_material_fissile_;

  //! \f$\sigma_\mathrm{t}\f$ of all groups for all materials.
  std::unordered_map<int, std::vector<double>> sigt_;

  //! \f$1/\sigma_\mathrm{t}\f$ of all groups for all materials
  std::unordered_map<int, std::vector<double>> inv_sigt_;

  //! \f$\chi\f$ for all materials.
  std::unordered_map<int, std::vector<double>> chi_;

  //! \f$\nu\sigma_\mathrm{f}\f$ of all groups for all materials.
  std::unordered_map<int, std::vector<double>> nusigf_;

  //! Fixed source value \f$Q\f$'s of all groups for all materials.
  std::unordered_map<int, std::vector<double>> q_;

  //! Fixed source value \f$Q/(4\pi)\f$'s of all groups for all materials.
{'fraction_non_alphanumeric': 0.10461646480603827, 'fraction_numerical': 0.003335088643145515, 'mean_word_length': 3.538032656312226, 'pattern_counts': {'":': 0, '<': 96, '<?xml version=': 0, '>': 96, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2957862', 'n_tokens_mistral': 3551, 'n_tokens_neox': 3380, 'n_words': 1107}