From e6b89a2b366186e6a4a1ed42a115c733f0f112e1 Mon Sep 17 00:00:00 2001 From: Baptiste Mouginot <mouginot.baptiste@gmail.com> Date: Thu, 7 Jan 2016 21:36:18 +0000 Subject: [PATCH] recreate BaM branch as a trunk copy git-svn-id: svn+ssh://svn.in2p3.fr/class@796 0e7d625b-0364-4367-a6be-d5be4a48d228 --- .../Equivalence/EQM_FBR_BakerRoss_MOX.cxx | 145 ++ .../Equivalence/EQM_FBR_BakerRoss_MOX.hxx | 95 ++ .../Model/Equivalence/EQM_FBR_MLP_Keff.cxx | 353 +++++ .../Model/Equivalence/EQM_FBR_MLP_Keff.hxx | 199 +++ .../Equivalence/EQM_FBR_MLP_Keff_BOUND.cxx | 434 ++++++ .../Equivalence/EQM_FBR_MLP_Keff_BOUND.hxx | 211 +++ .../BaM/Model/Equivalence/EQM_MLP_Kinf.cxx | 571 ++++++++ .../BaM/Model/Equivalence/EQM_MLP_Kinf.hxx | 220 +++ .../BaM/Model/Equivalence/EQM_PWR_LIN_MOX.cxx | 264 ++++ .../BaM/Model/Equivalence/EQM_PWR_LIN_MOX.hxx | 71 + .../BaM/Model/Equivalence/EQM_PWR_MLP_MOX.cxx | 185 +++ .../BaM/Model/Equivalence/EQM_PWR_MLP_MOX.hxx | 77 + .../Model/Equivalence/EQM_PWR_MLP_MOX_Am.cxx | 203 +++ .../Model/Equivalence/EQM_PWR_MLP_MOX_Am.hxx | 77 + .../BaM/Model/Equivalence/EQM_PWR_POL_UO2.cxx | 78 ++ .../BaM/Model/Equivalence/EQM_PWR_POL_UO2.hxx | 69 + .../Model/Equivalence/EQM_PWR_QUAD_MOX.cxx | 141 ++ .../Model/Equivalence/EQM_PWR_QUAD_MOX.hxx | 70 + .../BaM/Model/Irradiation/IM_Matrix.cxx | 301 ++++ .../BaM/Model/Irradiation/IM_Matrix.hxx | 83 ++ .../branches/BaM/Model/Irradiation/IM_RK4.cxx | 396 ++++++ .../branches/BaM/Model/Irradiation/IM_RK4.hxx | 122 ++ source/branches/BaM/Model/XS/XSM_CLOSEST.cxx | 372 +++++ source/branches/BaM/Model/XS/XSM_CLOSEST.hxx | 166 +++ source/branches/BaM/Model/XS/XSM_MLP.cxx | 511 +++++++ source/branches/BaM/Model/XS/XSM_MLP.hxx | 151 ++ source/branches/BaM/include/CLASSBackEnd.hxx | 154 ++ .../branches/BaM/include/CLASSConstante.hxx | 22 + source/branches/BaM/include/CLASSFacility.hxx | 217 +++ source/branches/BaM/include/CLASSFuel.hxx | 85 ++ source/branches/BaM/include/CLASSFuelPlan.hxx | 100 ++ source/branches/BaM/include/CLASSHeaders.hxx | 24 + source/branches/BaM/include/CLASSLogger.hxx | 216 +++ source/branches/BaM/include/CLASSMethod.hxx | 42 + .../BaM/include/CLASSNucleiFiliation.hxx | 123 ++ source/branches/BaM/include/CLASSObject.hxx | 102 ++ source/branches/BaM/include/DecayDataBank.hxx | 178 +++ .../branches/BaM/include/DynamicalSystem.hxx | 127 ++ .../branches/BaM/include/EquivalenceModel.hxx | 232 ++++ source/branches/BaM/include/EvolutionData.hxx | 268 ++++ .../branches/BaM/include/FabricationPlant.hxx | 240 ++++ .../branches/BaM/include/IrradiationModel.hxx | 264 ++++ .../branches/BaM/include/IsotopicVector.hxx | 183 +++ source/branches/BaM/include/PhysicsModels.hxx | 120 ++ source/branches/BaM/include/Pool.hxx | 173 +++ source/branches/BaM/include/Reactor.hxx | 320 +++++ source/branches/BaM/include/Scenario.hxx | 316 +++++ .../branches/BaM/include/SeparationPlant.hxx | 131 ++ source/branches/BaM/include/Storage.hxx | 157 +++ source/branches/BaM/include/StringLine.hxx | 306 ++++ source/branches/BaM/include/XSModel.hxx | 126 ++ source/branches/BaM/include/ZAI.hxx | 96 ++ source/branches/BaM/include/ZAIHeat.hxx | 70 + source/branches/BaM/include/ZAIMass.hxx | 70 + source/branches/BaM/include/ZAITox.hxx | 70 + source/branches/BaM/src/CLASSBackEnd.cxx | 138 ++ source/branches/BaM/src/CLASSFacility.cxx | 91 ++ source/branches/BaM/src/CLASSFuel.cxx | 26 + source/branches/BaM/src/CLASSFuelPlan.cxx | 69 + source/branches/BaM/src/CLASSLogger.cxx | 112 ++ .../branches/BaM/src/CLASSNucleiFiliation.cxx | 323 +++++ source/branches/BaM/src/CLASSObject.cxx | 24 + source/branches/BaM/src/DecayDataBank.cxx | 220 +++ source/branches/BaM/src/DynamicalSystem.cxx | 214 +++ source/branches/BaM/src/EquivalenceModel.cxx | 472 +++++++ source/branches/BaM/src/EvolutionData.cxx | 1234 +++++++++++++++++ source/branches/BaM/src/FabricationPlant.cxx | 700 ++++++++++ source/branches/BaM/src/IrradiationModel.cxx | 694 +++++++++ source/branches/BaM/src/IsotopicVector.cxx | 716 ++++++++++ source/branches/BaM/src/Makefile | 126 ++ source/branches/BaM/src/PhysicsModels.cxx | 57 + source/branches/BaM/src/Pool.cxx | 226 +++ source/branches/BaM/src/Reactor.cxx | 640 +++++++++ source/branches/BaM/src/Scenario.cxx | 1051 ++++++++++++++ source/branches/BaM/src/SeparationPlant.cxx | 137 ++ source/branches/BaM/src/Storage.cxx | 215 +++ source/branches/BaM/src/XSModel.cxx | 203 +++ source/branches/BaM/src/ZAI.cxx | 62 + source/branches/BaM/src/ZAIHeat.cxx | 99 ++ source/branches/BaM/src/ZAIMass.cxx | 81 ++ source/branches/BaM/src/ZAITox.cxx | 99 ++ 81 files changed, 18126 insertions(+) create mode 100644 source/branches/BaM/Model/Equivalence/EQM_FBR_BakerRoss_MOX.cxx create mode 100644 source/branches/BaM/Model/Equivalence/EQM_FBR_BakerRoss_MOX.hxx create mode 100644 source/branches/BaM/Model/Equivalence/EQM_FBR_MLP_Keff.cxx create mode 100644 source/branches/BaM/Model/Equivalence/EQM_FBR_MLP_Keff.hxx create mode 100644 source/branches/BaM/Model/Equivalence/EQM_FBR_MLP_Keff_BOUND.cxx create mode 100644 source/branches/BaM/Model/Equivalence/EQM_FBR_MLP_Keff_BOUND.hxx create mode 100644 source/branches/BaM/Model/Equivalence/EQM_MLP_Kinf.cxx create mode 100644 source/branches/BaM/Model/Equivalence/EQM_MLP_Kinf.hxx create mode 100644 source/branches/BaM/Model/Equivalence/EQM_PWR_LIN_MOX.cxx create mode 100644 source/branches/BaM/Model/Equivalence/EQM_PWR_LIN_MOX.hxx create mode 100644 source/branches/BaM/Model/Equivalence/EQM_PWR_MLP_MOX.cxx create mode 100644 source/branches/BaM/Model/Equivalence/EQM_PWR_MLP_MOX.hxx create mode 100755 source/branches/BaM/Model/Equivalence/EQM_PWR_MLP_MOX_Am.cxx create mode 100755 source/branches/BaM/Model/Equivalence/EQM_PWR_MLP_MOX_Am.hxx create mode 100644 source/branches/BaM/Model/Equivalence/EQM_PWR_POL_UO2.cxx create mode 100644 source/branches/BaM/Model/Equivalence/EQM_PWR_POL_UO2.hxx create mode 100644 source/branches/BaM/Model/Equivalence/EQM_PWR_QUAD_MOX.cxx create mode 100644 source/branches/BaM/Model/Equivalence/EQM_PWR_QUAD_MOX.hxx create mode 100644 source/branches/BaM/Model/Irradiation/IM_Matrix.cxx create mode 100644 source/branches/BaM/Model/Irradiation/IM_Matrix.hxx create mode 100644 source/branches/BaM/Model/Irradiation/IM_RK4.cxx create mode 100644 source/branches/BaM/Model/Irradiation/IM_RK4.hxx create mode 100644 source/branches/BaM/Model/XS/XSM_CLOSEST.cxx create mode 100644 source/branches/BaM/Model/XS/XSM_CLOSEST.hxx create mode 100644 source/branches/BaM/Model/XS/XSM_MLP.cxx create mode 100644 source/branches/BaM/Model/XS/XSM_MLP.hxx create mode 100644 source/branches/BaM/include/CLASSBackEnd.hxx create mode 100644 source/branches/BaM/include/CLASSConstante.hxx create mode 100644 source/branches/BaM/include/CLASSFacility.hxx create mode 100644 source/branches/BaM/include/CLASSFuel.hxx create mode 100644 source/branches/BaM/include/CLASSFuelPlan.hxx create mode 100755 source/branches/BaM/include/CLASSHeaders.hxx create mode 100755 source/branches/BaM/include/CLASSLogger.hxx create mode 100644 source/branches/BaM/include/CLASSMethod.hxx create mode 100644 source/branches/BaM/include/CLASSNucleiFiliation.hxx create mode 100644 source/branches/BaM/include/CLASSObject.hxx create mode 100644 source/branches/BaM/include/DecayDataBank.hxx create mode 100755 source/branches/BaM/include/DynamicalSystem.hxx create mode 100644 source/branches/BaM/include/EquivalenceModel.hxx create mode 100755 source/branches/BaM/include/EvolutionData.hxx create mode 100644 source/branches/BaM/include/FabricationPlant.hxx create mode 100644 source/branches/BaM/include/IrradiationModel.hxx create mode 100755 source/branches/BaM/include/IsotopicVector.hxx create mode 100644 source/branches/BaM/include/PhysicsModels.hxx create mode 100755 source/branches/BaM/include/Pool.hxx create mode 100755 source/branches/BaM/include/Reactor.hxx create mode 100755 source/branches/BaM/include/Scenario.hxx create mode 100644 source/branches/BaM/include/SeparationPlant.hxx create mode 100644 source/branches/BaM/include/Storage.hxx create mode 100755 source/branches/BaM/include/StringLine.hxx create mode 100644 source/branches/BaM/include/XSModel.hxx create mode 100755 source/branches/BaM/include/ZAI.hxx create mode 100644 source/branches/BaM/include/ZAIHeat.hxx create mode 100644 source/branches/BaM/include/ZAIMass.hxx create mode 100644 source/branches/BaM/include/ZAITox.hxx create mode 100644 source/branches/BaM/src/CLASSBackEnd.cxx create mode 100644 source/branches/BaM/src/CLASSFacility.cxx create mode 100644 source/branches/BaM/src/CLASSFuel.cxx create mode 100644 source/branches/BaM/src/CLASSFuelPlan.cxx create mode 100755 source/branches/BaM/src/CLASSLogger.cxx create mode 100644 source/branches/BaM/src/CLASSNucleiFiliation.cxx create mode 100644 source/branches/BaM/src/CLASSObject.cxx create mode 100644 source/branches/BaM/src/DecayDataBank.cxx create mode 100644 source/branches/BaM/src/DynamicalSystem.cxx create mode 100644 source/branches/BaM/src/EquivalenceModel.cxx create mode 100755 source/branches/BaM/src/EvolutionData.cxx create mode 100644 source/branches/BaM/src/FabricationPlant.cxx create mode 100644 source/branches/BaM/src/IrradiationModel.cxx create mode 100755 source/branches/BaM/src/IsotopicVector.cxx create mode 100755 source/branches/BaM/src/Makefile create mode 100644 source/branches/BaM/src/PhysicsModels.cxx create mode 100755 source/branches/BaM/src/Pool.cxx create mode 100755 source/branches/BaM/src/Reactor.cxx create mode 100755 source/branches/BaM/src/Scenario.cxx create mode 100644 source/branches/BaM/src/SeparationPlant.cxx create mode 100644 source/branches/BaM/src/Storage.cxx create mode 100644 source/branches/BaM/src/XSModel.cxx create mode 100755 source/branches/BaM/src/ZAI.cxx create mode 100644 source/branches/BaM/src/ZAIHeat.cxx create mode 100644 source/branches/BaM/src/ZAIMass.cxx create mode 100644 source/branches/BaM/src/ZAITox.cxx diff --git a/source/branches/BaM/Model/Equivalence/EQM_FBR_BakerRoss_MOX.cxx b/source/branches/BaM/Model/Equivalence/EQM_FBR_BakerRoss_MOX.cxx new file mode 100644 index 000000000..b0e83bae6 --- /dev/null +++ b/source/branches/BaM/Model/Equivalence/EQM_FBR_BakerRoss_MOX.cxx @@ -0,0 +1,145 @@ +#include "EQM_FBR_BakerRoss_MOX.hxx" +#include "CLASSLogger.hxx" + +#include <vector> + +//________________________________________________________________________ +// +// EQM_FBR_BakerRoss_MOX +// +// Equivalenve Model based on Plutonium 239 equivalent +// using the formula of Baker&Ross +// +//________________________________________________________________________ + + +EQM_FBR_BakerRoss_MOX::EQM_FBR_BakerRoss_MOX(double Weight_U_235, double Weight_Pu_238, double Weight_Pu_240, double Weight_Pu_241, double Weight_Pu_242, double Weight_Am_241, double EquivalentFissile):EquivalenceModel(new CLASSLogger("EQM_FBR_BakerRoss_MOX.log")) +{ + ZAI U8(92,238,0); + ZAI U5(92,235,0); + double U5_enrich = 0.0025; + fFertileList = U5*U5_enrich + U8*(1-U5_enrich); //Default Fertile composition (if no Fertile Storage is set for the FabricationPlant ) + + ZAI Pu8(94,238,0); + ZAI Pu9(94,239,0); + ZAI Pu0(94,240,0); + ZAI Pu1(94,241,0); + ZAI Pu2(94,242,0); + fFissileList = Pu8*1+Pu9*1+Pu0*1+Pu1*1+Pu2*1; //ZAI to be extracted by the FabricationPlant in its affiliated Fissile Storage + + fReferenceFissilContent = EquivalentFissile;//Equivalent fissile content + SetBuildFuelFirstGuess(fReferenceFissilContent); + + fWeight_U_235 = Weight_U_235 ; + fWeight_Pu_238 = Weight_Pu_238; + fWeight_Pu_240 = Weight_Pu_240; + fWeight_Pu_241 = Weight_Pu_241; + fWeight_Pu_242 = Weight_Pu_242; + fWeight_Am_241 = Weight_Am_241; + + + INFO << "__An equivalence model of FBR MOX has been defined__" << endl; + INFO << "\tThis model is based on Plutonium 239 equivalent" << endl; + INFO << "\t\t Weigt values : " << endl; + INFO << "\t\t Fertile : " << endl; + INFO << "\t\t\tU_235 " << Weight_U_235 << endl; + INFO << "\t\t\tU_238 0 (by definition)" << endl; + INFO << "\t\t Fissile : " << endl; + INFO << "\t\t\tPu_238 " << Weight_Pu_238 << endl; + INFO << "\t\t\tPu_239 1 (by definition)" << endl; + INFO << "\t\t\tPu_240 " << Weight_Pu_240 << endl; + INFO << "\t\t\tPu_241 " << Weight_Pu_241 << endl; + INFO << "\t\t\tPu_242 " << Weight_Pu_242 << endl; + INFO << "\t\t\tAm_241 " << Weight_Am_241 << endl; + EquivalenceModel::PrintInfo(); + +} +//________________________________________________________________________ +EQM_FBR_BakerRoss_MOX::EQM_FBR_BakerRoss_MOX(CLASSLogger* log, double Weight_U_235, double Weight_Pu_238, double Weight_Pu_240, double Weight_Pu_241, double Weight_Pu_242, double Weight_Am_241, double EquivalentFissile ):EquivalenceModel(log) +{ + ZAI U8(92,238,0); + ZAI U5(92,235,0); + double U5_enrich = 0.0025; + fFertileList = U5*U5_enrich + U8*(1-U5_enrich); //Default Fertile composition (if no Fertile Storage is set for the FabricationPlant ) + + ZAI Pu8(94,238,0); + ZAI Pu9(94,239,0); + ZAI Pu0(94,240,0); + ZAI Pu1(94,241,0); + ZAI Pu2(94,242,0); + fFissileList = Pu8*1+Pu9*1+Pu0*1+Pu1*1+Pu2*1; //ZAI to be extracted by the FabricationPlant in its affiliated Fissile Storage + + fReferenceFissilContent = EquivalentFissile;//Equivalent fissile content + SetBuildFuelFirstGuess(fReferenceFissilContent); + + fWeight_U_235 = Weight_U_235 ; + fWeight_Pu_238 = Weight_Pu_238; + fWeight_Pu_240 = Weight_Pu_240; + fWeight_Pu_241 = Weight_Pu_241; + fWeight_Pu_242 = Weight_Pu_242; + fWeight_Am_241 = Weight_Am_241; + + + INFO << "__An equivalence model of FBR MOX has been defined__" << endl; + INFO << "\tThis model is based on Plutonium 239 equivalent" << endl; + INFO << "\t\t Weigt values : " << endl; + INFO << "\t\t Fertile : " << endl; + INFO << "\t\t\tU_235 " << Weight_U_235 << endl; + INFO << "\t\t\tU_238 0 (by definition)" << endl; + INFO << "\t\t Fissile : " << endl; + INFO << "\t\t\tPu_238 " << Weight_Pu_238 << endl; + INFO << "\t\t\tPu_239 1 (by definition)" << endl; + INFO << "\t\t\tPu_240 " << Weight_Pu_240 << endl; + INFO << "\t\t\tPu_241 " << Weight_Pu_241 << endl; + INFO << "\t\t\tPu_242 " << Weight_Pu_242 << endl; + INFO << "\t\t\tAm_241 " << Weight_Am_241 << endl; + EquivalenceModel::PrintInfo(); + + +} +//________________________________________________________________________ +double EQM_FBR_BakerRoss_MOX::GetFissileMolarFraction(IsotopicVector Fissile,IsotopicVector Fertile,double BurnUp) +{ + + if( BurnUp != 0 ) + WARNING << "Burn up (third argument) has no effect " << endl; + + + double FissileContent = 0.; + + IsotopicVector FissileListPlusDecay; + FissileListPlusDecay.Add(94,238,0,1); + FissileListPlusDecay.Add(94,239,0,1); + FissileListPlusDecay.Add(94,240,0,1); + FissileListPlusDecay.Add(94,241,0,1); + FissileListPlusDecay.Add(94,242,0,1); + FissileListPlusDecay.Add(95,241,0,1); + + IsotopicVector FertileList; + FertileList.Add(92,238,0,1); + FertileList.Add(92,239,0,1); + + //Getting the fissile from the Fissile input & normalize it + IsotopicVector FissileFromInput = Fissile.GetThisComposition(FissileListPlusDecay); + FissileFromInput = FissileFromInput/FissileFromInput.GetSumOfAll(); + + //Getting the fissile from the Fissile input & normalize it + IsotopicVector FertileFromInput = Fertile.GetThisComposition(FertileList); + FertileFromInput = FertileFromInput/FertileFromInput.GetSumOfAll(); + + double SumWeightNFissile = fWeight_Pu_238 * FissileFromInput.GetZAIIsotopicQuantity(94,238,0) + + 1 * FissileFromInput.GetZAIIsotopicQuantity(94,239,0) + + fWeight_Pu_240 * FissileFromInput.GetZAIIsotopicQuantity(94,240,0) + + fWeight_Pu_241 * FissileFromInput.GetZAIIsotopicQuantity(94,241,0) + + fWeight_Pu_242 * FissileFromInput.GetZAIIsotopicQuantity(94,242,0) + + fWeight_Am_241 * FissileFromInput.GetZAIIsotopicQuantity(95,241,0) ; + + double SumWeightNFertile = fWeight_U_235 * FertileFromInput.GetZAIIsotopicQuantity(92,235,0); + + FissileContent = (fReferenceFissilContent - SumWeightNFertile )/(SumWeightNFissile-SumWeightNFertile); //Baker & Ross formula + + + return FissileContent; + + +} diff --git a/source/branches/BaM/Model/Equivalence/EQM_FBR_BakerRoss_MOX.hxx b/source/branches/BaM/Model/Equivalence/EQM_FBR_BakerRoss_MOX.hxx new file mode 100644 index 000000000..b6125293b --- /dev/null +++ b/source/branches/BaM/Model/Equivalence/EQM_FBR_BakerRoss_MOX.hxx @@ -0,0 +1,95 @@ +#ifndef _EQM_FBR_BakerRoss_MOX_HXX +#define _EQM_FBR_BakerRoss_MOX_HXX + +#include "EquivalenceModel.hxx" + +#include <string> + +using namespace std; + +//-----------------------------------------------------------------------------// +//! Defines an EquivalenceModel based on Baker and Ross formula + +/*! + The aim of these class is to constuct a fuel from an equivalence model + based on a @f$^{239}Pu@f$ equivalent from Baker and Ross formula : + + It returns Pu content (E) needed for the FBR-Na loaded with a given Pu vector according + : + + @f$E = \frac{E_{ref} - \sum_{fertile}N_{i}W_{i} }{\sum_{fissile}N_{i}W_{i}-\sum_{fertile}N_{i}W_{i}}@f$ + + with : + + @f$W_i = \frac{\alpha_{i} - \alpha_{^{238}U} }{\alpha_{^{239}Pu}-\alpha_{^{238}U}}@f$ + and + @f$\alpha_{i} = \bar{\nu_{i}}\cdot\sigma_{i}^{fis} - \sigma_{i}^{abs}@f$ + + @author BLG + @version 3.0 + */ +//________________________________________________________________________ + +class EQM_FBR_BakerRoss_MOX : public EquivalenceModel +{ + public : + + /*! + \name Constructor + */ + //@{ + //{ + /// Logger constructor + + /*! + Make a new EQM_FBR_BakerRoss_MOX : the default values have been calculated for a FBR-Na of type : ESFR like (without blanket) + \param log : use for the log + \param Weight_U_235 : reactivity weight @f$W_{^{235}U} = \frac{\alpha_{{^{235}U}} - \alpha_{^{238}U} }{\alpha_{^{239}Pu}-\alpha_{^{238}U}}@f$ + \param Weight_Pu_238 : reactivity weight @f$W_{^{238}Pu} = \frac{\alpha_{{^{238}Pu}} - \alpha_{^{238}U} }{\alpha_{^{239}Pu}-\alpha_{^{238}U}}@f$ + \param Weight_Pu_240 : reactivity weight @f$W_{^{240}Pu} = \frac{\alpha_{{^{240}Pu}} - \alpha_{^{238}U} }{\alpha_{^{239}Pu}-\alpha_{^{238}U}}@f$ + \param Weight_Pu_241 : reactivity weight @f$W_{^{241}Pu} = \frac{\alpha_{{^{241}Pu}} - \alpha_{^{238}U} }{\alpha_{^{239}Pu}-\alpha_{^{238}U}}@f$ + \param Weight_Pu_242 : reactivity weight @f$W_{^{242}Pu} = \frac{\alpha_{{^{242}Pu}} - \alpha_{^{238}U} }{\alpha_{^{239}Pu}-\alpha_{^{238}U}}@f$ + \param Weight_Am_241 : reactivity weight @f$W_{^{241}Pu} = \frac{\alpha_{{^{241}Am}} - \alpha_{^{238}U} }{\alpha_{^{239}Pu}-\alpha_{^{238}U}}@f$ + \param EquivalentFissile : reference fresh fuel @f$^{239}Pu@f$ content neeed in a @f$^{238}U@f$ + @f$^{239}Pu@f$ fuel to satisfy criticality at t = 0 + */ + EQM_FBR_BakerRoss_MOX(CLASSLogger* log, double Weight_U_235 = 0.791135, double Weight_Pu_238 = 0.686385, double Weight_Pu_240 = 0.13553, double Weight_Pu_241 = 1.54572 , double Weight_Pu_242 = 0.0829001, double Weight_Am_241 = -0.336945, double EquivalentFissile = 0.103213); + //} + + //{ + /// normal constructor + + /*! + Make a new EQM_FBR_BakerRoss_MOX : the default values have been calculated for a FBR-Na of type : ESFR like (without blanket) + \param Weight_U_235 : reactivity weight @f$W_{^{235}U} = \frac{\alpha_{{^{235}U}} - \alpha_{^{238}U} }{\alpha_{^{239}Pu}-\alpha_{^{238}U}}@f$ + \param Weight_Pu_238 : reactivity weight @f$W_{^{238}Pu} = \frac{\alpha_{{^{238}Pu}} - \alpha_{^{238}U} }{\alpha_{^{239}Pu}-\alpha_{^{238}U}}@f$ + \param Weight_Pu_240 : reactivity weight @f$W_{^{240}Pu} = \frac{\alpha_{{^{240}Pu}} - \alpha_{^{238}U} }{\alpha_{^{239}Pu}-\alpha_{^{238}U}}@f$ + \param Weight_Pu_241 : reactivity weight @f$W_{^{241}Pu} = \frac{\alpha_{{^{241}Pu}} - \alpha_{^{238}U} }{\alpha_{^{239}Pu}-\alpha_{^{238}U}}@f$ + \param Weight_Pu_242 : reactivity weight @f$W_{^{242}Pu} = \frac{\alpha_{{^{242}Pu}} - \alpha_{^{238}U} }{\alpha_{^{239}Pu}-\alpha_{^{238}U}}@f$ + \param Weight_Am_241 : reactivity weight @f$W_{^{241}Pu} = \frac{\alpha_{{^{241}Am}} - \alpha_{^{238}U} }{\alpha_{^{239}Pu}-\alpha_{^{238}U}}@f$ + \param EquivalentFissile : reference fresh fuel @f$^{239}Pu@f$ content neeed in a @f$^{238}U@f$ + @f$^{239}Pu@f$ fuel to satisfy criticality at t = 0 + */ + EQM_FBR_BakerRoss_MOX(double Weight_U_235 = 0.791135, double Weight_Pu_238 = 0.686385, double Weight_Pu_240 = 0.13553, double Weight_Pu_241 = 1.54572 , double Weight_Pu_242 = 0.0829001, double Weight_Am_241 = -0.336945, double EquivalentFissile = 0.103213); + //} + //@} + + virtual double GetFissileMolarFraction(IsotopicVector Fissil, IsotopicVector Fertil, double BurnUp = 0); + + private : + double fReferenceFissilContent; //!<The reference fraction of Pu for BurnUp = 100Gwj/t with a ideal model(only @f$^{239}Pu@f$ and &@f$^{238}U@f$ are taken into account) + + /*! + \name Reactivity coefficients : + */ + //@{ + double fWeight_U_235; //!< weight for @f$^{235}U@f$ + double fWeight_Pu_238; //!< weight for @f$^{238}Pu@f$ + double fWeight_Pu_240; //!< weight for @f$^{240}Pu@f$ + double fWeight_Pu_241; //!< weight for @f$^{241}Pu@f$ + double fWeight_Pu_242; //!< weight for @f$^{242}Pu@f$ + double fWeight_Am_241; //!< weight for @f$^{241}Am@f$ + //@} +}; + +#endif + + diff --git a/source/branches/BaM/Model/Equivalence/EQM_FBR_MLP_Keff.cxx b/source/branches/BaM/Model/Equivalence/EQM_FBR_MLP_Keff.cxx new file mode 100644 index 000000000..c6998f89e --- /dev/null +++ b/source/branches/BaM/Model/Equivalence/EQM_FBR_MLP_Keff.cxx @@ -0,0 +1,353 @@ +#include "EQM_FBR_MLP_Keff.hxx" +#include "CLASSLogger.hxx" +#include "CLASSMethod.hxx" +#include "StringLine.hxx" + +#include <string> +#include <iostream> +#include <fstream> +#include <algorithm> +#include <cmath> +#include <cassert> +#include <map> + +#include "TSystem.h" +#include "TMVA/Reader.h" +#include "TMVA/Tools.h" +#include "TMVA/MethodCuts.h" + +//________________________________________________________________________ +// +// EQM_FBR_MLP_Keff +// +// Equivalenve Model based on multi layer perceptron from TMVA (root cern) +// For FBR +// +//________________________________________________________________________ + + +//________________________________________________________________________ +// +// Objects & Methods for content prediction with calculation of Keff at +// one given time (often BOC or EOC) +// +//________________________________________________________________________ + +//________________________________________________________________________ +EQM_FBR_MLP_Keff::EQM_FBR_MLP_Keff(string TMVAWeightPath, double keff_target, string InformationFile):EquivalenceModel(new CLASSLogger("EQM_FBR_MLP_Keff.log")) +{ + DBGL + + /**The tmva weight*/ + fTMVAWeightPath = TMVAWeightPath; + + + /* INFORMATION FILE HANDLING */ + + if(InformationFile == "") + InformationFile = StringLine::ReplaceAll(TMVAWeightPath,".xml",".nfo"); + + fMaximalContent = 0; + fInformationFile = InformationFile; + LoadKeyword(); + ReadNFO();//Getting information from fMLPInformationFile + + if(fMaximalContent == 0 ) + { + ERROR<<"Can't find the k_maxfiscontent keyword in .nfo file\n this is mandatory"<<endl; + exit(0); + } + + fTargetKeff = keff_target; + + SetPCMprecision(10); + SetBuildFuelFirstGuess(0.15); //First fissile content guess for the EquivalenceModel::BuildFuel algorithm + fActualFissileContent = fFirstGuessFissilContent ; + + INFO << "__An equivalence model has been define__" << endl; + INFO << "\tThis model is based on the prediction of keff at a specific time" << endl; + INFO << "\tThe TMVA (weight | information) files are :" << endl; + INFO << "\t" << "( " << fTMVAWeightPath[0] << " | " << fInformationFile << " )" << endl; + INFO << "Maximal fissile content (molar proportion) : "<<fMaximalContent<<endl; + EquivalenceModel::PrintInfo(); + + if(fMapOfTMVAVariableNames.empty() || fFertileList.GetIsotopicQuantity().empty() || fFissileList.GetIsotopicQuantity().empty()) + { + ERROR<<"Missing information file in : "<<fInformationFile<<endl; + exit(1); + } + + DBGL +} +//________________________________________________________________________ +EQM_FBR_MLP_Keff::EQM_FBR_MLP_Keff(CLASSLogger* log, string TMVAWeightPath, double keff_target, string InformationFile):EquivalenceModel(log) +{ + DBGL + + /**The tmva weight*/ + fTMVAWeightPath = TMVAWeightPath; + + + /* INFORMATION FILE HANDLING */ + + if(InformationFile == "") + InformationFile = StringLine::ReplaceAll(TMVAWeightPath,".xml",".nfo"); + + fMaximalContent = 0; + fInformationFile = InformationFile; + LoadKeyword(); + ReadNFO();//Getting information from fMLPInformationFile + + if(fMaximalContent == 0 ) + { + ERROR<<"Can't find the k_maxfiscontent keyword in .nfo file\n this is mandatory"<<endl; + exit(0); + } + + fTargetKeff = keff_target; + + SetPCMprecision(10); + SetBuildFuelFirstGuess(0.15); //First fissile content guess for the EquivalenceModel::BuildFuel algorithm + fActualFissileContent = fFirstGuessFissilContent ; + + INFO << "__An equivalence model has been define__" << endl; + INFO << "\tThis model is based on the prediction of keff at a specific time" << endl; + INFO << "\tThe TMVA (weight | information) files are :" << endl; + INFO << "\t" << "( " << fTMVAWeightPath[0] << " | " << fInformationFile << " )" << endl; + EquivalenceModel::PrintInfo(); + + if(fMapOfTMVAVariableNames.empty() || fFertileList.GetIsotopicQuantity().empty() || fFissileList.GetIsotopicQuantity().empty()) + { + ERROR<<"Missing information file in : "<<fInformationFile<<endl; + exit(1); + } + + DBGL +} +//________________________________________________________________________ +TTree* EQM_FBR_MLP_Keff::CreateTMVAInputTree(IsotopicVector TheFreshfuel, double ThisTime) +{ + DBGL + + /******Create Input data tree to be interpreted by TMVA::Reader***/ + TTree* InputTree = new TTree("InTMPKef", "InTMPKef"); + + vector<float> InputTMVA; + for(int i = 0 ; i< (int)fMapOfTMVAVariableNames.size() ; i++) + InputTMVA.push_back(0); + + float Time = 0; + + IsotopicVector IVInputTMVA; + map<ZAI ,string >::iterator it; + int j = 0; + + for( it = fMapOfTMVAVariableNames.begin() ; it != fMapOfTMVAVariableNames.end() ; it++) + { + InputTree->Branch( ((*it).second).c_str() ,&InputTMVA[j], ((*it).second + "/F").c_str()); + IVInputTMVA+= ((*it).first)*1; + j++; + } + + if(ThisTime != -1) + InputTree->Branch( "Time" ,&Time ,"Time/F" ); + + IsotopicVector IVAccordingToUserInfoFile = TheFreshfuel.GetThisComposition(IVInputTMVA); + + double Ntot = IVAccordingToUserInfoFile.GetSumOfAll(); + + IVAccordingToUserInfoFile = IVAccordingToUserInfoFile/Ntot; + + j = 0; + map<ZAI ,string >::iterator it2; + + for( it2 = fMapOfTMVAVariableNames.begin() ; it2 != fMapOfTMVAVariableNames.end() ; it2++) + { + InputTMVA[j] = IVAccordingToUserInfoFile.GetZAIIsotopicQuantity( (*it2).first ) ; + j++; + } + + Time = ThisTime; + + InputTree->Fill(); + + DBGL + return InputTree; + +} +//________________________________________________________________________ +double EQM_FBR_MLP_Keff::ExecuteTMVA(TTree* InputTree, bool IsTimeDependent) +{ + DBGL + + // --- Create the Reader object + TMVA::Reader *reader = new TMVA::Reader( "Silent" ); + + // Create a set of variables and declare them to the reader + // - the variable names MUST corresponds in name and type to those given in the weight file(s) used + vector<float> InputTMVA; + for(int i = 0 ; i< (int)fMapOfTMVAVariableNames.size() ; i++) + InputTMVA.push_back(0); + + Float_t Time = 0; + + + map<ZAI ,string >::iterator it; + int j = 0; + + + for( it = fMapOfTMVAVariableNames.begin() ; it != fMapOfTMVAVariableNames.end() ; it++) + { reader->AddVariable( ( (*it).second ).c_str(),&InputTMVA[j]); + j++; + } + + if(IsTimeDependent) + reader->AddVariable( "Time" ,&Time); + + + + // --- Book the MVA methods + + // Book method MLP + TString methodName = "MLP method"; + reader->BookMVA( methodName, fTMVAWeightPath ); + + map<ZAI ,string >::iterator it2; + j = 0; + for( it2 = fMapOfTMVAVariableNames.begin() ; it2 != fMapOfTMVAVariableNames.end() ; it2++) + { + InputTree->SetBranchAddress(( (*it2).second ).c_str(),&InputTMVA[j]); + j++; + } + + if(IsTimeDependent) + InputTree->SetBranchAddress( "Time" ,&Time ); + + InputTree->GetEntry(0); + + Float_t val = (reader->EvaluateRegression( methodName ))[0]; + + delete reader; + + DBGL + return (double)val; //return k_{eff}(t = Time) +} +//________________________________________________________________________ +void EQM_FBR_MLP_Keff::LoadKeyword() +{ + DBGL + + fDKeyword.insert( pair<string, FBR_MLP_Keff_DMthPtr>( "k_zainame", & EQM_FBR_MLP_Keff::ReadZAIName) ); + + fDKeyword.insert( pair<string, FBR_MLP_Keff_DMthPtr>( "k_maxfiscontent", &EQM_FBR_MLP_Keff::ReadMaxFisContent) ); + + DBGL +} +//________________________________________________________________________ +void EQM_FBR_MLP_Keff::ReadZAIName(const string &line) +{ + DBGL + + int pos = 0; + string keyword = tlc(StringLine::NextWord(line, pos, ' ')); + if( keyword != "k_zainame" ) // Check the keyword + { + ERROR << " Bad keyword : \"k_zainame\" not found !" << endl; + exit(1); + } + + int Z = atoi(StringLine::NextWord(line, pos, ' ').c_str()); + int A = atoi(StringLine::NextWord(line, pos, ' ').c_str()); + int I = atoi(StringLine::NextWord(line, pos, ' ').c_str()); + + string name = StringLine::NextWord(line, pos, ' '); + + fMapOfTMVAVariableNames.insert( pair<ZAI,string>( ZAI(Z, A, I), name ) ); + + DBGL +} +//________________________________________________________________________ +void EQM_FBR_MLP_Keff::ReadMaxFisContent(const string &line) +{ + DBGL + int pos = 0; + string keyword = tlc(StringLine::NextWord(line, pos, ' ')); + if( keyword != "k_maxfiscontent" ) // Check the keyword + { + ERROR << " Bad keyword : \"k_maxfiscontent\" not found !" << endl; + exit(1); + } + + fMaximalContent = atof(StringLine::NextWord(line, pos, ' ').c_str()); + + DBGL +} +//________________________________________________________________________ +void EQM_FBR_MLP_Keff::ReadLine(string line) +{ + DBGL + + int pos = 0; + string keyword = tlc(StringLine::NextWord(line, pos, ' ')); + + map<string, FBR_MLP_Keff_DMthPtr>::iterator it = fDKeyword.find(keyword); + + if(it != fDKeyword.end()) + (this->*(it->second))( line ); + + DBGL +} +//________________________________________________________________________ +double EQM_FBR_MLP_Keff::GetFissileMolarFraction(IsotopicVector Fissile,IsotopicVector Fertile,double TargetBU) +{ + DBGL + + if(TargetBU != 0) + WARNING << "The third arguement : Burnup has no effect here."; + + + //initialization + double FissileContent = GetActualFissileContent(); + double OldFissileContentMinus = 0; + double OldFissileContentPlus = fMaximalContent; + double PredictedKeff = 0 ; + IsotopicVector FreshFuel = (1-FissileContent)*(Fertile/Fertile.GetSumOfAll()) + FissileContent*(Fissile/Fissile.GetSumOfAll()); + double OldPredictedKeff = GetKeffAtFixedTime(FreshFuel); + + double Precision = fPCMprecision/1e5*fTargetKeff; //pcm to 1 + + int count = 0; + int MaximumLoopCount = 100; + do + { + if(count > MaximumLoopCount ) + { + ERROR << "CRITICAL ! Can't manage to predict fissile content\nHint : Try to decrease the precision on keff using :\nYourEQM_FBR_MLP_Keff->SetPCMPrecision(prop); with prop the precision (default 0.5percent : 0.005) INCREASE IT \n If this message still appear mail to leniau@subatech.in2p3.fr\nor nicolas.thiolliere@subatech.in2p3.fr " << endl; + exit(1); + } + + if( (OldPredictedKeff - fTargetKeff) < 0 ) //The Content can be increased + { + OldFissileContentMinus = FissileContent; + FissileContent = FissileContent + fabs(OldFissileContentPlus-FissileContent)/2.; + } + else if( (OldPredictedKeff - fTargetKeff) > 0) //The Content is too high + { + OldFissileContentPlus = FissileContent; + FissileContent = FissileContent - fabs(OldFissileContentMinus-FissileContent)/2.; + } + + IsotopicVector FreshFuel = (1-FissileContent)*(Fertile/Fertile.GetSumOfAll()) + FissileContent*(Fissile/Fissile.GetSumOfAll()); + + PredictedKeff = GetKeffAtFixedTime(FreshFuel); + + OldPredictedKeff = PredictedKeff; + count ++; + + }while(fabs(fTargetKeff-PredictedKeff)>Precision); + + DBGV( "Predicted keff " << PredictedKeff << " FissileContent " << FissileContent << endl); + return FissileContent; + +} +//________________________________________________________________________ \ No newline at end of file diff --git a/source/branches/BaM/Model/Equivalence/EQM_FBR_MLP_Keff.hxx b/source/branches/BaM/Model/Equivalence/EQM_FBR_MLP_Keff.hxx new file mode 100644 index 000000000..9a12a9d59 --- /dev/null +++ b/source/branches/BaM/Model/Equivalence/EQM_FBR_MLP_Keff.hxx @@ -0,0 +1,199 @@ +#ifndef _EQM_FBR_MLP_Keff_HXX +#define _EQM_FBR_MLP_Keff_HXX + +#include "EquivalenceModel.hxx" +#include "TTree.h" +#include "TGraph.h" +#include <string> +#include <fstream> +#include <iostream> +#include <map> +#include <vector> + +using namespace std; + +class EQM_FBR_MLP_Keff; +#ifndef __CINT__ +typedef void (EQM_FBR_MLP_Keff::*FBR_MLP_Keff_DMthPtr)( const string & ) ; +#endif + +//-----------------------------------------------------------------------------// +//! Defines an EquivalenceModel based on neural network to predict @f$k_{eff}@f$. + +/*! +The aim of these class is to constuct a fuel from an equivalence model +based on a Multi layer perceptron (MLP). +This MLP aims to predict the Pu content such as it has to verify + @f$ k(WantedTime) = k_{target}@f$ with @f$k_{target}@f$ is often close to 1.0 + but can be set by user. The wanted time is often either + the begining of cycle or end of cycle. WantedTime can't be set by user since it is + contain in the .xml file. Indeed this method suppose you have trained your MLP to predict + the @f$k_{eff}@f$ either at BOC or EOC (or any other time) + + @author BLG + @author BaM + @version 1.0 + */ +//________________________________________________________________________ + +class EQM_FBR_MLP_Keff : public EquivalenceModel +{ + public: + /*! + \name Constructor + */ + //@{ + + + + //{ + /// Create a EQM_FBR_MLP_Keff using Keffective at a given time + /// (see class desctiption) + /*! + Create a EQM_FBR_MLP_Keff + \param TMVAWeightPath : Path to the .xml file containing neural network informations for prediction of keff(t = tfixed) + \param keff_target : Wanted @f$k_{eff}@f$ (see detailed description) + \param InformationFile : Total path to the file containing time steps, fissile and ferile list (ante and post fabrication time cooling). Default is the same total path as TMVAWeightPath but extension is replaced by .nfo (see manual for format) + */ + EQM_FBR_MLP_Keff(string TMVAWeightPath, double keff_target = 1.00, string InformationFile = ""); + //} + + //{ + /// Create a EQM_FBR_MLP_Keff using Keffective at a given time + /// (see class desctiption) + /*! + Create a EQM_FBR_MLP_Keff + \param log: CLASSLogger object to handle log messages + \param TMVAWeightPath : Path to the .xml file containing neural network informations for prediction of keff(t = tfixed) + \param keff_target : Wanted @f$k_{eff}@f$ (see detailed description) + \param InformationFile : Total path to the file containing time steps, fissile and ferile list (ante and post fabrication time cooling). Default is the same total path as TMVAWeightPath but extension is replaced by .nfo (see manual for format) + */ + EQM_FBR_MLP_Keff(CLASSLogger* log, string TMVAWeightPath, double keff_target = 1.00, string InformationFile = ""); + //} + + //@} + + //{ + /// Return the molar fissile fraction according fissile & ferile content using @f$<k_{\infty}>(t)@f$ prediction + /*! + \param Fissil : The composition of the fissile matter + \param Fertil : The composition of the Fertil matter + \param BurnUp : Maximum achievable burn up envisaged + */ + virtual double GetFissileMolarFraction(IsotopicVector Fissil,IsotopicVector Fertil,double BurnUp = 0); + //} + + /*! + \name Get/Set methods + */ + //@{ + void SetPCMprecision(double pcm){fPCMprecision = pcm;} //!< Set the precision on @f$\langle k \rangle@f$ prediction [pcm]. Neural network predictor constructors + double GetPCMprecision(){return fPCMprecision/1e5;} //!< Get the precision on @f$\langle k \rangle@f$ prediction []. Neural network predictor constructors + + //@} + + + + + + /*! + \name TMVA related methods + */ + //@{ + TTree* CreateTMVAInputTree(IsotopicVector FreshFuel, double ThisTime);//!<Create input tmva tree to be read by ExecuteTMVA + + double ExecuteTMVA(TTree* theTree, bool IsTimeDependant);//!<Execute the MLP according to the input tree created by CreateTMVAInputTree + //@} + + + + /*! + \name Reading NFO related Method + */ + //@{ + + //{ + /// LoadKeyword() : make the correspondance between keyword and reading method + void LoadKeyword(); + //} + + //{ + /// ReadTimeSteps : read the time step of the model + /*! + \param line : line suppossed to contain the time step information starts with "k_timestep" keyword + */ + void ReadTimeSteps(const string &line); + //} + + + //{ + /// ReadZAIName : read the zai name in the TMWA MLP model + /*! + \param line : line suppossed to contain the ZAI name starts with "k_zainame" keyword + */ + void ReadZAIName(const string &line); + //} + + //{ + /// ReadMaxFisContent : read a guessed (very overestimated) maximum fissile content (purpose : algorithm initialization) + /*! + \param line : line suppossed to contain the ZAI name starts with "k_maxfiscontent" keyword + */ + void ReadMaxFisContent(const string &line); + //} + + //{ + /// ReadLine : read a line + /*! + \param line : line to read + */ + void ReadLine(string line); + //} + + //@} + + + + private : + + string fTMVAWeightPath; //!<The weight needed by TMVA to construct and execute the multilayer perceptron + +#ifndef __CINT__ + map<string, FBR_MLP_Keff_DMthPtr> fDKeyword; +#endif + + + map<ZAI,string> fMapOfTMVAVariableNames;//!< List of TMVA input variable names (read from fMLPInformationFile ) , name depends on the training step + + vector<double> fMLP_Time; //!< Time (in seconds) when the MLP(t) = keff(t) has been trained. + double fMaximalContent; //!< The approx. maximum fissile content reachable by the MLP model + + + + int fNumberOfBatch; //!< The number of batches for the loading plan + + double fKThreshold; //!< The @f$k_{Threshold}@f$ + double fPCMprecision; //!< precision on @f$\langle k \rangle@f$ prediction [pcm] + + double fTargetKeff; //!< Use for Varying Fissile content to reach fTargetKeff at time used in the MLP Training + + + /*! + \name keff prediction methods & keff averaging + */ + //@{ + + double GetKeffAtFixedTime(IsotopicVector FreshFuel){TTree* Input = CreateTMVAInputTree(FreshFuel,-1); double Keff = ExecuteTMVA( Input, false ); delete Input; return Keff;} //!<time independant since the MLP is trained for 1 time + + TGraph* BuildKeffGraph(IsotopicVector FreshFuel); + TGraph* BuildAverageKeffGraph(TGraph* GRAPH_KEFF); + double GetKeffAt(TGraph* GRAPH_KEFF, int Step); + + //@} + + + +}; + +#endif + diff --git a/source/branches/BaM/Model/Equivalence/EQM_FBR_MLP_Keff_BOUND.cxx b/source/branches/BaM/Model/Equivalence/EQM_FBR_MLP_Keff_BOUND.cxx new file mode 100644 index 000000000..47cc75a67 --- /dev/null +++ b/source/branches/BaM/Model/Equivalence/EQM_FBR_MLP_Keff_BOUND.cxx @@ -0,0 +1,434 @@ +#include "EQM_FBR_MLP_Keff_BOUND.hxx" +#include "CLASSMethod.hxx" +#include "CLASSLogger.hxx" +#include "StringLine.hxx" + +#include <string> +#include <iostream> +#include <fstream> +#include <algorithm> +#include <cmath> +#include <cassert> + +#include "TSystem.h" +#include "TMVA/Reader.h" +#include "TMVA/Tools.h" +#include "TMVA/MethodCuts.h" + +//________________________________________________________________________ +// +// EQM_FBR_MLP_Keff_BOUND +// +// Equivalenve Model based on multi layer perceptron from TMVA (root cern) +// For FBR +// +//________________________________________________________________________ + + + +//________________________________________________________________________ +// +// Objects & Methods for content prediction with calculation of Keff bounded +// over batches. +// +//________________________________________________________________________ + +//________________________________________________________________________ +EQM_FBR_MLP_Keff_BOUND::EQM_FBR_MLP_Keff_BOUND(string TMVAWeightPath, int NumOfBatch, double LowerKeffective, double UpperKeffective, string InformationFile):EquivalenceModel(new CLASSLogger("EQM_FBR_MLP_Keff_BOUND.log")) +{ + DBGL + + /** The tmva weight **/ + + fTMVAWeightPath = TMVAWeightPath; + + + /* INFORMATION FILE HANDLING */ + + if(InformationFile == "") + InformationFile = StringLine::ReplaceAll(TMVAWeightPath,".xml",".nfo"); + + fInformationFile = InformationFile; + + LoadKeyword(); + ReadNFO();//Getting information from fInformationFile + + + /* OTHER MODEL PARAMETERS */ + + fNumberOfBatch = NumOfBatch; + fKmin = LowerKeffective ; + fKmax = UpperKeffective ; + + + /* MODEL PARAMETERS INITIALIZATION */ + + SetPCMprecision(10); + SetBuildFuelFirstGuess(0.15);//First fissile content guess for the EquivalenceModel::BuildFuel algorithm + fActualFissileContent = fFirstGuessFissilContent ; + + + /* INFO */ + + INFO << "__An equivalence model has been define__" << endl; + INFO << "\tThis model is based on the prediction of keff averaged over the number of batch" << endl; + INFO << "\tThe TMVA (weight | information) files are :" << endl; + INFO << "\t" << "( " << fTMVAWeightPath << " | " << fInformationFile << " )" << endl; + INFO << "Time (s) :"<<endl; + for(int i=0;i< (int) fMLP_Time.size();i++) + INFO<<fMLP_Time[i]<<endl; + INFO<<endl; + INFO<<"Z A I Name (input MLP) :"<<endl; + map<ZAI ,string >::iterator it; + for( it = fMapOfTMVAVariableNames.begin() ; it != fMapOfTMVAVariableNames.end() ; it++) + INFO<<(*it).first.Z()<<" "<<(*it).first.A()<<" "<<(*it).first.I()<<" "<<(*it).second<<endl; + INFO<<endl; + EquivalenceModel::PrintInfo(); + + + + + if(fMapOfTMVAVariableNames.empty() || fFertileList.GetIsotopicQuantity().empty() || fFissileList.GetIsotopicQuantity().empty() || fMLP_Time.size()== 0 ) + { + ERROR<<"Missing information file in : "<<fInformationFile<<endl; + exit(1); + } + + DBGL +} +//________________________________________________________________________ +EQM_FBR_MLP_Keff_BOUND::EQM_FBR_MLP_Keff_BOUND(CLASSLogger* log, string TMVAWeightPath, int NumOfBatch, double LowerKeffective, double UpperKeffective, string InformationFile):EquivalenceModel(log) +{ + DBGL + + /** The tmva weight **/ + + fTMVAWeightPath = TMVAWeightPath; + + + /* INFORMATION FILE HANDLING */ + + if(InformationFile == "") + InformationFile = StringLine::ReplaceAll(TMVAWeightPath,".xml",".nfo"); + + fInformationFile = InformationFile; + LoadKeyword(); + ReadNFO();//Getting information from fInformationFile + + + + /* OTHER MODEL PARAMETERS */ + + fNumberOfBatch = NumOfBatch; + fKmin = LowerKeffective ; + fKmax = UpperKeffective ; + + + /* INFO */ + + SetPCMprecision(10); + SetBuildFuelFirstGuess(0.15);//First fissile content guess for the EquivalenceModel::BuildFuel algorithm + fActualFissileContent = fFirstGuessFissilContent ; + + INFO << "__An equivalence model has been define__" << endl; + INFO << "\tThis model is based on the prediction of keff averaged over the number of batch" << endl; + INFO << "\tThe TMVA (weight | information) files are :" << endl; + INFO << "\t" << "( " << fTMVAWeightPath << " | " << fInformationFile << " )" << endl; + INFO << "Time (s) :"<<endl; + for(int i=0;i< (int) fMLP_Time.size();i++) + INFO<<fMLP_Time[i]<<endl; + INFO<<endl; + INFO<<"Z A I Name (input MLP) :"<<endl; + map<ZAI ,string >::iterator it; + for( it = fMapOfTMVAVariableNames.begin() ; it != fMapOfTMVAVariableNames.end() ; it++) + INFO<<(*it).first.Z()<<" "<<(*it).first.A()<<" "<<(*it).first.I()<<" "<<(*it).second<<endl; + INFO<<endl; + EquivalenceModel::PrintInfo(); + + + if(fMapOfTMVAVariableNames.empty() || fFertileList.GetIsotopicQuantity().empty() || fFissileList.GetIsotopicQuantity().empty() || fMLP_Time.size()== 0 ) + { + ERROR<<"Missing information file in : "<<fInformationFile<<endl; + exit(1); + } + + DBGL + + + +} +//________________________________________________________________________ +TGraph* EQM_FBR_MLP_Keff_BOUND::BuildKeffGraph(IsotopicVector FreshFuel) +{ + DBGL + + TGraph * keffGraph = new TGraph(); + for(int i = 0 ; i < (int) fMLP_Time.size() ; i++) + { + TTree *InputTree = CreateTMVAInputTree(FreshFuel,(float) fMLP_Time[i]); + double keff_t = ExecuteTMVA( InputTree, true ); + delete InputTree; + keffGraph->SetPoint(i, (double)fMLP_Time[i], keff_t ); + } + + DBGL + return keffGraph; +} +//________________________________________________________________________ +TGraph* EQM_FBR_MLP_Keff_BOUND::BuildAverageKeffGraph(TGraph* GRAPH_KEFF) +{ + DBGL + + TGraph * AveragekeffGraph = new TGraph(); + int NumberOfPoint = 50; + + int NumOfInputGraphPoint = GRAPH_KEFF->GetN()-1 ; + double TimeFinal = 0; + double KFinal = 0; + + GRAPH_KEFF->GetPoint(NumOfInputGraphPoint, TimeFinal, KFinal); + + double step = TimeFinal/NumberOfPoint; + int p = 0; + for(int n = 0 ;n<NumberOfPoint;n++) + { + double k_av = 0; + for(int b = 0;b<fNumberOfBatch;b++) + { + if((step*p)> TimeFinal/(double)fNumberOfBatch) + p = 0; + k_av += GRAPH_KEFF->Eval( (step*p + b*TimeFinal/(double)fNumberOfBatch) , 0 , "S" ); + + } + p++; + k_av/= (double)fNumberOfBatch; + + AveragekeffGraph->SetPoint(n, step*n, k_av); + } + + DBGL + return AveragekeffGraph; +} +//________________________________________________________________________ +double EQM_FBR_MLP_Keff_BOUND::GetKeffAt(TGraph* GRAPH_KEFF, int Step) +{ + DBGL + + double Time = 0; + double Keff = 0; + GRAPH_KEFF->GetPoint(Step, Time, Keff); + + DBGL + return Keff; +} +//________________________________________________________________________ +TTree* EQM_FBR_MLP_Keff_BOUND::CreateTMVAInputTree(IsotopicVector TheFreshfuel, double ThisTime) +{ + DBGL + + /******Create Input data tree to be interpreted by TMVA::Reader***/ + TTree* InputTree = new TTree("InTMPKef", "InTMPKef"); + + vector<float> InputTMVA; + for(int i = 0 ; i< (int)fMapOfTMVAVariableNames.size() ; i++) + InputTMVA.push_back(0); + + float Time = 0; + + IsotopicVector IVInputTMVA; + map<ZAI ,string >::iterator it; + int j = 0; + + for( it = fMapOfTMVAVariableNames.begin() ; it != fMapOfTMVAVariableNames.end() ; it++) + { + InputTree->Branch( ((*it).second).c_str() ,&InputTMVA[j], ((*it).second + "/F").c_str()); + IVInputTMVA+= ((*it).first)*1; + j++; + } + + if(ThisTime != -1) + InputTree->Branch( "Time" ,&Time ,"Time/F" ); + + IsotopicVector IVAccordingToUserInfoFile = TheFreshfuel.GetThisComposition(IVInputTMVA); + + double Ntot = IVAccordingToUserInfoFile.GetSumOfAll(); + + IVAccordingToUserInfoFile = IVAccordingToUserInfoFile/Ntot; + + j = 0; + map<ZAI ,string >::iterator it2; + + for( it2 = fMapOfTMVAVariableNames.begin() ; it2 != fMapOfTMVAVariableNames.end() ; it2++) + { + InputTMVA[j] = IVAccordingToUserInfoFile.GetZAIIsotopicQuantity( (*it2).first ) ; + j++; + } + + Time = ThisTime; + + InputTree->Fill(); + + DBGL + return InputTree; + +} +//________________________________________________________________________ +double EQM_FBR_MLP_Keff_BOUND::ExecuteTMVA(TTree* InputTree, bool IsTimeDependent) +{ + DBGL + + // --- Create the Reader object + TMVA::Reader *reader = new TMVA::Reader( "Silent" ); + + // Create a set of variables and declare them to the reader + // - the variable names MUST corresponds in name and type to those given in the weight file(s) used + vector<float> InputTMVA; + for(int i = 0 ; i< (int)fMapOfTMVAVariableNames.size() ; i++) + InputTMVA.push_back(0); + Float_t Time; + + map<ZAI ,string >::iterator it; + int j = 0; + for( it = fMapOfTMVAVariableNames.begin() ; it != fMapOfTMVAVariableNames.end() ; it++) + { reader->AddVariable( ( (*it).second ).c_str(),&InputTMVA[j]); + j++; + } + + if(IsTimeDependent) + reader->AddVariable( "Time" ,&Time); + + // --- Book the MVA methods + + // Book method MLP + TString methodName = "MLP method"; + reader->BookMVA( methodName, fTMVAWeightPath ); + + map<ZAI ,string >::iterator it2; + j = 0; + for( it2 = fMapOfTMVAVariableNames.begin() ; it2 != fMapOfTMVAVariableNames.end() ; it2++) + { + InputTree->SetBranchAddress(( (*it2).second ).c_str(),&InputTMVA[j]); + j++; + } + + if(IsTimeDependent) + InputTree->SetBranchAddress( "Time" ,&Time ); + + InputTree->GetEntry(0); + Float_t val = (reader->EvaluateRegression( methodName ))[0]; + + delete reader; + + DBGL + return (double)val; //return k_{eff}(t = Time) +} +//________________________________________________________________________ +void EQM_FBR_MLP_Keff_BOUND::LoadKeyword() +{ + DBGL + + fDKeyword.insert( pair<string, FBR_MLP_Keff_BOUND_DMthPtr>( "k_timestep", & EQM_FBR_MLP_Keff_BOUND::ReadTimeSteps)); + fDKeyword.insert( pair<string, FBR_MLP_Keff_BOUND_DMthPtr>( "k_zainame", & EQM_FBR_MLP_Keff_BOUND::ReadZAIName) ); + + DBGL +} +//________________________________________________________________________ +void EQM_FBR_MLP_Keff_BOUND::ReadZAIName(const string &line) +{ + DBGL + int pos = 0; + string keyword = tlc(StringLine::NextWord(line, pos, ' ')); + if( keyword != "k_zainame" ) // Check the keyword + { + ERROR << " Bad keyword : \"k_zainame\" not found !" << endl; + exit(1); + } + + int Z = atoi(StringLine::NextWord(line, pos, ' ').c_str()); + int A = atoi(StringLine::NextWord(line, pos, ' ').c_str()); + int I = atoi(StringLine::NextWord(line, pos, ' ').c_str()); + + string name = StringLine::NextWord(line, pos, ' '); + + fMapOfTMVAVariableNames.insert( pair<ZAI,string>( ZAI(Z, A, I), name ) ); + DBGL +} +//________________________________________________________________________ +void EQM_FBR_MLP_Keff_BOUND::ReadTimeSteps(const string &line) +{ + DBGL + int pos = 0; + string keyword = tlc(StringLine::NextWord(line, pos, ' ')); + if( keyword != "k_timestep" ) // Check the keyword + { + ERROR << " Bad keyword : \"k_timestep\" not found !" << endl; + exit(1); + } + + while( pos < (int)line.size() ) + fMLP_Time.push_back( atof( (StringLine::NextWord(line,pos,' ')).c_str() )); + DBGL +} +//________________________________________________________________________ +void EQM_FBR_MLP_Keff_BOUND::ReadLine(string line) +{ + DBGL + + int pos = 0; + string keyword = tlc(StringLine::NextWord(line, pos, ' ')); + + map<string, FBR_MLP_Keff_BOUND_DMthPtr>::iterator it = fDKeyword.find(keyword); + + if(it != fDKeyword.end()) + (this->*(it->second))( line ); + + DBGL +} +//________________________________________________________________________ +double EQM_FBR_MLP_Keff_BOUND::GetFissileMolarFraction(IsotopicVector Fissile, IsotopicVector Fertile, double TargetBU) +{ + DBGL + if(TargetBU != 0) + WARNING << "The third arguement : Burnup has no effect here."; + + /**Algorithm not so clever ...**/ + /**need improvements to make it faster*/ + + double FissileContent = 0.01; + double test_Keff_beg = fKmin - 0.01; + double test_keff_end = fKmax + 0.01; + + double speedstep = 1; + + while(fKmin >= test_Keff_beg || fKmax <= test_keff_end) + { + IsotopicVector FreshFuel = (1-FissileContent)*(Fertile/Fertile.GetSumOfAll()) + FissileContent*(Fissile/Fissile.GetSumOfAll()); + + TGraph* KEFF = BuildKeffGraph(FreshFuel); + TGraph* KEFF_avg = BuildAverageKeffGraph(KEFF); + + test_Keff_beg = GetKeffAt(KEFF_avg , 0); + test_keff_end = GetKeffAt(KEFF_avg , fMLP_Time.size()-1); + delete KEFF; + delete KEFF_avg; + + if(test_Keff_beg < 0.9) //why 0.9 ? exactly + speedstep = 10; + else + speedstep = 1; + + FissileContent+= 0.001*speedstep; + + if( test_Keff_beg > 1.30 ) + { + ERROR << "This plutonium can not satisfy the criticality condition imposed" << endl; + FissileContent = -1; + break; + } + + } + + DBGL + return FissileContent; +} +//________________________________________________________________________ diff --git a/source/branches/BaM/Model/Equivalence/EQM_FBR_MLP_Keff_BOUND.hxx b/source/branches/BaM/Model/Equivalence/EQM_FBR_MLP_Keff_BOUND.hxx new file mode 100644 index 000000000..e9984b5b4 --- /dev/null +++ b/source/branches/BaM/Model/Equivalence/EQM_FBR_MLP_Keff_BOUND.hxx @@ -0,0 +1,211 @@ +#ifndef _EQM_FBR_MLP_Keff_BOUND_HXX_ +#define _EQM_FBR_MLP_Keff_BOUND_HXX_ + +#include "EquivalenceModel.hxx" +#include "TTree.h" +#include "TGraph.h" + +using namespace std; + +class EQM_FBR_MLP_Keff_BOUND; +#ifndef __CINT__ +typedef void (EQM_FBR_MLP_Keff_BOUND::*FBR_MLP_Keff_BOUND_DMthPtr)( const string & ) ; +#endif + +//-----------------------------------------------------------------------------// +//! Defines an EquivalenceModel based on neural network to predict @f$k_{\infty}@f$ + +/*! + The aim of these class is to constuct a fuel from an equivalence model + based on a Multi layer perceptron (MLP). + This MLP aims to predict : + + The @f$k_{\infty}(t)@f$ of a FBR-MOX from a given fresh fuel composition. + With this MLP prediction and a given number of batch (for the loading plan) an + average @f$<k_{\infty}(t)>@f$ is calculated according : + @f$<k_{\infty}>^{batch}(t) = \frac{1}{N}\sum_{i}^{N} k_{\infty}(t + \frac{iT}{N} )@f$ + The Fissile content has to verify this condition : + @f$ k_{\infty Max} \geq <k_{\infty}>^{batch}(T/N) \geq k_{\infty Min} @f$ + Where @f$ k_{\infty Max}@f$ and @f$k_{\infty Min}@f$ are arguments of the constructor. + + + \warning + it is not guaranted that there is a solution for Pu content verifying : + @f$ k_{\infty Max} \geq <k_{\infty}>^{batch}(T/N) \geq k_{\infty Min} @f$ + + @author BLG + @author BaM + @version 1.0 + */ +//________________________________________________________________________ + +class EQM_FBR_MLP_Keff_BOUND : public EquivalenceModel +{ + public: + /*! + \name Constructor + */ + //@{ + + //{ + /// Create a EQM_FBR_MLP_Keff_BOUND using @f$k_{\infty}@f$ average over batch + /// (see class desctiption) + /*! + Create a EQM_FBR_MLP_Keff_BOUND using @f$k_{\infty}@f$ average over batch + \param TMVAWeightPath0: Path to the .xml file containing neural network informations for prediction of keff(t) + \param NumOfBatch : Number of batch for the loading plan (often 5 for FBR-Na) + \param KeffMin : Lower average @f$<k_{\infty}>@f$ value + \param KeffMax : Upper average @f$<k_{\infty}>@f$ value + \param InformationFile : Total path to the file containing time steps, fissile and ferile list (ante and post fabrication time cooling). Default is the same total path as TMVAWeightPath but extension is replaced by .nfo (see manual for format) + */ + EQM_FBR_MLP_Keff_BOUND(string TMVAWeightPath, int NumOfBatch , double LowerKeffective, double UpperKeffective, string InformationFile = ""); + //} + + //{ + /// Create a EQM_FBR_MLP_Keff_BOUND using @f$k_{\infty}@f$ average over batch + /// (see class desctiption) + /*! + Create a EQM_FBR_MLP_Keff_BOUND using @f$k_{\infty}@f$ average over batch + \param log: CLASSLogger object to handle log messages + \param TMVAWeightPath0: Path to the .xml file containing neural network informations for prediction of keff(t) + \param NumOfBatch : Number of batch for the loading plan (often 5 for FBR-Na) + \param KeffMin : Lower average @f$<k_{\infty}>@f$ value + \param KeffMax : Upper average @f$<k_{\infty}>@f$ value + \param InformationFile : Total path to the file containing time steps, fissile and ferile list (ante and post fabrication time cooling). Default is the same total path as TMVAWeightPath but extension is replaced by .nfo (see manual for format) + */ + EQM_FBR_MLP_Keff_BOUND(CLASSLogger* log, string TMVAWeightPath, int NumOfBatch , double LowerKeffective, double UpperKeffective, string InformationFile = ""); + //} + + + //@} + + //{ + /// Return the molar fissile fraction according fissile & ferile content using @f$<k_{\infty}>(t)@f$ prediction + /*! + \param Fissil : The composition of the fissile matter + \param Fertil : The composition of the Fertil matter + \param BurnUp : Maximum achievable burn up envisaged + */ + virtual double GetFissileMolarFraction(IsotopicVector Fissil,IsotopicVector Fertil,double BurnUp = 0); + //} + + /*! + \name Get/Set methods + */ + //@{ + void SetPCMprecision(double pcm){fPCMprecision = pcm;} //!< Set the precision on @f$\langle k \rangle@f$ prediction [pcm]. Neural network predictor constructors + double GetPCMprecision(){return fPCMprecision/1e5;} //!< Get the precision on @f$\langle k \rangle@f$ prediction []. Neural network predictor constructors + + //@} + + + + + + /*! + \name TMVA related methods + */ + //@{ + TTree* CreateTMVAInputTree(IsotopicVector FreshFuel, double ThisTime);//!<Create input tmva tree to be read by ExecuteTMVA + + double ExecuteTMVA(TTree* theTree, bool IsTimeDependant);//!<Execute the MLP according to the input tree created by CreateTMVAInputTree + //@} + + + + /*! + \name Reading NFO related Method + */ + //@{ + + //{ + /// LoadKeyword() : make the correspondance between keyword and reading method + void LoadKeyword(); + //} + + //{ + /// ReadTimeSteps : read the time step of the model + /*! + \param line : line suppossed to contain the time step information starts with "k_timestep" keyword + */ + void ReadTimeSteps(const string &line); + //} + + + //{ + /// ReadZAIName : read the zai name in the TMWA MLP model + /*! + \param line : line suppossed to contain the ZAI name starts with "k_zainame" keyword + */ + void ReadZAIName(const string &line); + //} + + + + //{ + /// ReadLine : read a line + /*! + \param line : line to read + */ + void ReadLine(string line); + //} + + //@} + + + + private : + + string fTMVAWeightPath; //!<The weight needed by TMVA to construct and execute the multilayer perceptron + +#ifndef __CINT__ + map<string, FBR_MLP_Keff_BOUND_DMthPtr> fDKeyword; +#endif + + map<ZAI,string> fMapOfTMVAVariableNames;//!< List of TMVA input variable names (read from fInformationFile ) , name depends on the training step + + vector<double> fMLP_Time; //!< Time (in seconds) when the MLP(t) = keff(t) has been trained. + + + + + + int fNumberOfBatch; //!< The number of batches for the loading plan + + double fKThreshold; //!< The @f$k_{Threshold}@f$ + double fPCMprecision; //!< precision on @f$\langle k \rangle@f$ prediction [pcm] + double fKmin; //!< Lower edge of kedd Used by second constructor (fissile content prediction using keff at BOC (or other time) + double fKmax; //!< Upper edge of kedd Used by second constructor (fissile content prediction using keff at BOC (or other time) + double fTargetKeff; //!< Use for Varying Fissile content to reach fTargetKeff at time used in the MLP Training + + + + + + /*! + \name kinf prediction methods & keff averaging + */ + //@{ + + double GetKeffAtFixedTime(IsotopicVector FreshFuel){TTree* Input = CreateTMVAInputTree(FreshFuel,-1); double Keff = ExecuteTMVA( Input, false ); delete Input; return Keff;} //!<time independant since the MLP is trained for 1 time + + TGraph* BuildKeffGraph(IsotopicVector FreshFuel); + TGraph* BuildAverageKeffGraph(TGraph* GRAPH_KEFF); + + double GetKeffAt(TGraph* GRAPH_KEFF, int Step); + + //@} + + + +}; + +#endif + + + + + + + + diff --git a/source/branches/BaM/Model/Equivalence/EQM_MLP_Kinf.cxx b/source/branches/BaM/Model/Equivalence/EQM_MLP_Kinf.cxx new file mode 100644 index 000000000..24a8eb53f --- /dev/null +++ b/source/branches/BaM/Model/Equivalence/EQM_MLP_Kinf.cxx @@ -0,0 +1,571 @@ +#include "EQM_MLP_Kinf.hxx" +#include "CLASSLogger.hxx" +#include "CLASSMethod.hxx" +#include "StringLine.hxx" + +#include <string> +#include <iostream> +#include <fstream> +#include <algorithm> +#include <cmath> +#include <cassert> + +#include "TSystem.h" +#include "TMVA/Reader.h" +#include "TMVA/Tools.h" +#include "TMVA/MethodCuts.h" + + +//________________________________________________________________________ +// +// EQM_MLP_Kinf +// +// Equivalenve Model based on multi layer perceptron from TMVA (root cern) +// For REP MOX use +// +//________________________________________________________________________ +EQM_MLP_Kinf::EQM_MLP_Kinf(string WeightPathAlpha0, string WeightPathAlpha1, string WeightPathAlpha2, string InformationFile, int NumOfBatch, double CriticalityThreshold):EquivalenceModel(new CLASSLogger("EQM_MLP_Kinf.log")) +{ + /**The information file and tmva weight*/ + fTMVAWeightPath.push_back(WeightPathAlpha0); + fTMVAWeightPath.push_back(WeightPathAlpha1); + fTMVAWeightPath.push_back(WeightPathAlpha2); + + fMaximalBU = 0; + fMaximalContent = 0; + fInformationFile = InformationFile; + LoadKeyword(); + ReadNFO();//Getting information from fInformationFile + + fNumberOfBatch = NumOfBatch; + fKThreshold = CriticalityThreshold ; + SetBurnUpPrecision(0.005);//1 % of the targeted burnup + SetBuildFuelFirstGuess(0.04);//First fissile content guess for the EquivalenceModel::BuildFuel algorithm + + INFO << "__An equivalence model has been define__" << endl; + INFO << "\tThis model is based on the prediction of kinf" << endl; + INFO << "\tThe TMVA weight files are :" << endl; + INFO << "\t" << fTMVAWeightPath[0] << endl; + INFO << "\t" << fTMVAWeightPath[1] << endl; + INFO << "\t" << fTMVAWeightPath[2] << endl; + INFO << "\tThe Information file is :" << endl; + INFO << "\t" << fInformationFile << endl; + INFO << "Maximal fissile content (molar proportion) : " << fMaximalContent << endl; + INFO << "Maximal burnup (GWd/tHM) : " << fMaximalBU << endl; + EquivalenceModel::PrintInfo(); + + if(fMapOfTMVAVariableNames.empty() || fFertileList.GetIsotopicQuantity().empty() || fFissileList.GetIsotopicQuantity().empty() || fMaximalBU == 0 || fMaximalContent == 0 ) + { + ERROR<<"Missing information file in : "<<fInformationFile<<endl; + exit(1); + } + +} +//________________________________________________________________________ +EQM_MLP_Kinf::EQM_MLP_Kinf(CLASSLogger* log, string WeightPathAlpha0, string WeightPathAlpha1, string WeightPathAlpha2, string InformationFile, int NumOfBatch, double CriticalityThreshold):EquivalenceModel(log) +{ + /**The information file and tmva weight*/ + fTMVAWeightPath.push_back(WeightPathAlpha0); + fTMVAWeightPath.push_back(WeightPathAlpha1); + fTMVAWeightPath.push_back(WeightPathAlpha2); + + fMaximalBU = 0; + fMaximalContent = 0; + fInformationFile = InformationFile; + LoadKeyword(); + ReadNFO();//Getting information from fInformationFile + + fNumberOfBatch = NumOfBatch; + fKThreshold = CriticalityThreshold ; + SetBurnUpPrecision(0.005);//1 % of the targeted burnup + SetBuildFuelFirstGuess(0.04);//First fissile content guess for the EquivalenceModel::BuildFuel algorithm + + INFO << "__An equivalence model has been define__" << endl; + INFO << "\tThis model is based on the prediction of kinf" << endl; + INFO << "\tThe TMVA weight files are :" << endl; + INFO << "\t" << fTMVAWeightPath[0] << endl; + INFO << "\t" << fTMVAWeightPath[1] << endl; + INFO << "\t" << fTMVAWeightPath[2] << endl; + INFO << "\tThe Information file is :" << endl; + INFO << "\t" << fInformationFile << endl; + INFO << "Maximal fissile content (molar proportion) : " << fMaximalContent << endl; + INFO << "Maximal burnup (GWd/tHM) : " << fMaximalBU << endl; + EquivalenceModel::PrintInfo(); + + if(fMapOfTMVAVariableNames.empty() || fFertileList.GetIsotopicQuantity().empty() || fFissileList.GetIsotopicQuantity().empty() || fMaximalBU == 0 || fMaximalContent == 0 ) + { + ERROR<<"Missing information file in : "<<fInformationFile<<endl; + exit(1); + } + +} +//________________________________________________________________________ +EQM_MLP_Kinf::EQM_MLP_Kinf(string TMVAWeightPath, int NumOfBatch, string InformationFile, double CriticalityThreshold):EquivalenceModel(new CLASSLogger("EQM_MLP_Kinf.log")) +{ + /**The information file and tmva weight*/ + fTMVAWeightPath.push_back(TMVAWeightPath); + + /* INFORMATION FILE HANDLING */ + + if(InformationFile == "") + InformationFile = StringLine::ReplaceAll(TMVAWeightPath,".xml",".nfo"); + + fMaximalBU = 0; + fMaximalContent = 0; + fInformationFile = InformationFile; + LoadKeyword(); + ReadNFO();//Getting information from fInformationFile + + fNumberOfBatch = NumOfBatch; + fKThreshold = CriticalityThreshold ; + SetBurnUpPrecision(0.005);//1 % of the targeted burnup + SetPCMprecision(10); + SetBuildFuelFirstGuess(0.04);//First fissile content guess for the EquivalenceModel::BuildFuel algorithm + + INFO << "__An equivalence model has been define__" << endl; + INFO << "\tThis model is based on the prediction of kinf" << endl; + INFO << "\tThe TMVA (weight | information) files are :" << endl; + INFO << "\t" << "( " << fTMVAWeightPath[0] << " | " << fInformationFile << " )" << endl; + INFO << "Maximal fissile content (molar proportion) : " << fMaximalContent << endl; + INFO << "Maximal burnup (GWd/tHM) : " << fMaximalBU << endl; + EquivalenceModel::PrintInfo(); + + if(fMapOfTMVAVariableNames.empty() || fFertileList.GetIsotopicQuantity().empty() || fFissileList.GetIsotopicQuantity().empty() || fMaximalBU == 0 || fMaximalContent == 0 ) + { + ERROR<<"Missing information file in : "<<fInformationFile<<endl; + exit(1); + } + +} +//________________________________________________________________________ +EQM_MLP_Kinf::EQM_MLP_Kinf(CLASSLogger* log, string TMVAWeightPath, int NumOfBatch, string InformationFile, double CriticalityThreshold):EquivalenceModel(log) +{ + + /**The information file and tmva weight*/ + fTMVAWeightPath.push_back(TMVAWeightPath); + + if(InformationFile == "") + InformationFile = StringLine::ReplaceAll(TMVAWeightPath,".xml",".nfo"); + + fMaximalBU = 0; + fMaximalContent = 0; + fInformationFile = InformationFile; + LoadKeyword(); + ReadNFO();//Getting information from fMLPInformationFile + + fNumberOfBatch = NumOfBatch; + fKThreshold = CriticalityThreshold ; + SetBurnUpPrecision(0.005);//1 % of the targeted burnup + SetPCMprecision(10); + SetBuildFuelFirstGuess(0.04);//First fissile content guess for the EquivalenceModel::BuildFuel algorithm + + INFO << "__An equivalence model has been define__" << endl; + INFO << "\tThis model is based on the prediction of kinf" << endl; + INFO << "\tThe TMVA (weight | information) files are :" << endl; + INFO << "\t" << "( " << fTMVAWeightPath[0] << " | " << fInformationFile << " )" << endl; + INFO << "Maximal fissile content (molar proportion) : " << fMaximalContent << endl; + INFO << "Maximal burnup (GWd/tHM) : " << fMaximalBU << endl; + + + EquivalenceModel::PrintInfo(); + + if(fMapOfTMVAVariableNames.empty() || fFertileList.GetIsotopicQuantity().empty() || fFissileList.GetIsotopicQuantity().empty() || fMaximalBU == 0 || fMaximalContent == 0 ) + { + ERROR<<"Missing information file in : "<<fInformationFile<<endl; + exit(1); + } + + +} +//________________________________________________________________________ +void EQM_MLP_Kinf::LoadKeyword() +{ + DBGL + + fDKeyword.insert( pair<string, PWR_MLP_KINF_DMthPtr>( "k_zainame", &EQM_MLP_Kinf::ReadZAIName) ); + fDKeyword.insert( pair<string, PWR_MLP_KINF_DMthPtr>( "k_maxburnup", &EQM_MLP_Kinf::ReadMaxBurnUp) ); + fDKeyword.insert( pair<string, PWR_MLP_KINF_DMthPtr>( "k_maxfiscontent", &EQM_MLP_Kinf::ReadMaxFisContent) ); + DBGL +} +//________________________________________________________________________ +void EQM_MLP_Kinf::ReadZAIName(const string &line) +{ + DBGL + + int pos = 0; + string keyword = tlc(StringLine::NextWord(line, pos, ' ')); + if( keyword != "k_zainame" ) // Check the keyword + { + ERROR << " Bad keyword : \"k_zainame\" not found !" << endl; + exit(1); + } + + int Z = atoi(StringLine::NextWord(line, pos, ' ').c_str()); + int A = atoi(StringLine::NextWord(line, pos, ' ').c_str()); + int I = atoi(StringLine::NextWord(line, pos, ' ').c_str()); + + string name = StringLine::NextWord(line, pos, ' '); + + fMapOfTMVAVariableNames.insert( pair<ZAI,string>( ZAI(Z, A, I), name ) ); + + DBGL +} +//________________________________________________________________________ +void EQM_MLP_Kinf::ReadMaxBurnUp(const string &line) +{ + DBGL + int pos = 0; + string keyword = tlc(StringLine::NextWord(line, pos, ' ')); + if( keyword != "k_maxburnup" ) // Check the keyword + { + ERROR << " Bad keyword : \"k_maxburnup\" not found !" << endl; + exit(1); + } + + fMaximalBU = atof(StringLine::NextWord(line, pos, ' ').c_str()); + + DBGL +} +//________________________________________________________________________ +void EQM_MLP_Kinf::ReadMaxFisContent(const string &line) +{ + DBGL + int pos = 0; + string keyword = tlc(StringLine::NextWord(line, pos, ' ')); + if( keyword != "k_maxfiscontent" ) // Check the keyword + { + ERROR << " Bad keyword : \"k_maxfiscontent\" not found !" << endl; + exit(1); + } + + fMaximalContent = atof(StringLine::NextWord(line, pos, ' ').c_str()); + + DBGL +} +//________________________________________________________________________ +void EQM_MLP_Kinf::ReadLine(string line) +{ + DBGL + + int pos = 0; + string keyword = tlc(StringLine::NextWord(line, pos, ' ')); + + map<string, PWR_MLP_KINF_DMthPtr>::iterator it = fDKeyword.find(keyword); + + if(it != fDKeyword.end()) + (this->*(it->second))( line ); + + DBGL +} +//________________________________________________________________________ +TTree* EQM_MLP_Kinf::CreateTMVAInputTree(IsotopicVector TheFreshfuel, double ThisTime) +{ + /******Create Input data tree to be interpreted by TMVA::Reader***/ + TTree* InputTree = new TTree("InTMPKinf", "InTMPKinf"); + + vector<float> InputTMVA; + for(int i = 0 ; i< (int)fMapOfTMVAVariableNames.size() ; i++) + InputTMVA.push_back(0); + + float Time = 0; + + IsotopicVector IVInputTMVA; + map<ZAI ,string >::iterator it; + int j = 0; + + for( it = fMapOfTMVAVariableNames.begin() ; it != fMapOfTMVAVariableNames.end() ; it++) + { + InputTree->Branch( ((*it).second).c_str() ,&InputTMVA[j], ((*it).second + "/F").c_str()); + IVInputTMVA+= ((*it).first)*1; + j++; + } + + if(ThisTime != -1) + InputTree->Branch( "Time" ,&Time ,"Time/F" ); + + IsotopicVector IVAccordingToUserInfoFile = TheFreshfuel.GetThisComposition(IVInputTMVA); + + double Ntot = IVAccordingToUserInfoFile.GetSumOfAll(); + + IVAccordingToUserInfoFile = IVAccordingToUserInfoFile/Ntot; + + j = 0; + map<ZAI ,string >::iterator it2; + + for( it2 = fMapOfTMVAVariableNames.begin() ; it2 != fMapOfTMVAVariableNames.end() ; it2++) + { + InputTMVA[j] = IVAccordingToUserInfoFile.GetZAIIsotopicQuantity( (*it2).first ) ; + j++; + } + + Time = ThisTime; + + InputTree->Fill(); + + return InputTree; + +} +//________________________________________________________________________ +double EQM_MLP_Kinf::ExecuteTMVA(TTree* InputTree,string WeightPath, bool IsTimeDependent) +{ + + // --- Create the Reader object + TMVA::Reader *reader = new TMVA::Reader( "Silent" ); + + // Create a set of variables and declare them to the reader + // - the variable names MUST corresponds in name and type to those given in the weight file(s) used + vector<float> InputTMVA; + for(int i = 0 ; i< (int)fMapOfTMVAVariableNames.size() ; i++) + InputTMVA.push_back(0); + Float_t Time; + + map<ZAI ,string >::iterator it; + int j = 0; + for( it = fMapOfTMVAVariableNames.begin() ; it != fMapOfTMVAVariableNames.end() ; it++) + { reader->AddVariable( ( (*it).second ).c_str(),&InputTMVA[j]); + j++; + } + + if(IsTimeDependent) + reader->AddVariable( "Time" ,&Time); + + // --- Book the MVA methods + + // Book method MLP + TString methodName = "MLP method"; + reader->BookMVA( methodName, WeightPath ); + + map<ZAI ,string >::iterator it2; + j = 0; + for( it2 = fMapOfTMVAVariableNames.begin() ; it2 != fMapOfTMVAVariableNames.end() ; it2++) + { + InputTree->SetBranchAddress(( (*it2).second ).c_str(),&InputTMVA[j]); + j++; + } + + if(IsTimeDependent) + InputTree->SetBranchAddress( "Time" ,&Time ); + + InputTree->GetEntry(0); + Float_t val = (reader->EvaluateRegression( methodName ))[0]; + + delete reader; + + return (double)val;//retourn k_{inf}(t = Time) +} +//________________________________________________________________________ +double EQM_MLP_Kinf::GetMaximumBurnUp_MLP(IsotopicVector TheFuel, double TargetBU) +{ + /**************************************************************************/ + //With a dichotomy, the maximal irradiation time (TheFinalTime) is calculated + //When average Kinf is very close (according "Precision") to the threshold + //then the corresponding irradiation time is convert in burnup and returned + /**************************************************************************/ + //Algorithm initialization + double TheFinalTime = BurnupToSecond(TargetBU); + double OldFinalTimeMinus = 0; + double MaximumBU = fMaximalBU; + double OldFinalTimePlus = BurnupToSecond(MaximumBU); + double k_av = 0; //average kinf + double OldPredictedk_av = 0; + for(int b = 0;b<fNumberOfBatch;b++) + { + float TheTime = (b+1)*TheFinalTime/fNumberOfBatch; + TTree* InputTree = CreateTMVAInputTree(TheFuel,TheTime); + OldPredictedk_av += ExecuteTMVA(InputTree,fTMVAWeightPath[0],true); + delete InputTree; + } + OldPredictedk_av/= fNumberOfBatch; + + //Algorithm control + int count = 0; + int MaximumLoopCount = 500; + do + { + if(count > MaximumLoopCount ) + { + ERROR << "CRITICAL ! Can't manage to predict burnup\nHint : Try to increase the precision on k effective using :\n YourEQM_MLP_Kinf->SetPCMprecision(pcm); with pcm the precision in pcm (default 10) REDUCE IT\n If this message still appear mail to leniau@subatech.in2p3.fr\nor nicolas.thiolliere@subatech.in2p3.fr " << endl; + exit(1); + } + + if( (OldPredictedk_av-fKThreshold) > 0) //The burnup can be increased + { + OldFinalTimeMinus = TheFinalTime; + TheFinalTime = TheFinalTime + fabs(OldFinalTimePlus - TheFinalTime)/2.; + + if(SecondToBurnup(TheFinalTime) >= (MaximumBU-MaximumBU*GetBurnUpPrecision() ) ) + return MaximumBU; + } + + else if( (OldPredictedk_av-fKThreshold) < 0)//The burnup is too high + { + OldFinalTimePlus = TheFinalTime; + TheFinalTime = TheFinalTime - fabs(OldFinalTimeMinus-TheFinalTime)/2.; + if( SecondToBurnup(TheFinalTime) < TargetBU*GetBurnUpPrecision() ) + return 0; + } + + k_av = 0; + for(int b = 0;b<fNumberOfBatch;b++) + { + float TheTime = (b+1)*TheFinalTime/fNumberOfBatch; + TTree* InputTree = CreateTMVAInputTree(TheFuel,TheTime); + k_av += ExecuteTMVA(InputTree,fTMVAWeightPath[0],true); + delete InputTree; + } + k_av/= fNumberOfBatch; + + OldPredictedk_av = k_av; + count++; + } while( fabs(OldPredictedk_av-fKThreshold) > GetPCMprecision() ) ; + + + return SecondToBurnup(TheFinalTime); +} +//________________________________________________________________________ +double EQM_MLP_Kinf::GetMaximumBurnUp_Pol2(IsotopicVector TheFuel,double TargetBU) +{ + + TTree* InputTree = CreateTMVAInputTree(TheFuel,-1); + double Alpha_0 = ExecuteTMVA(InputTree,fTMVAWeightPath[0],false); + double Alpha_1 = ExecuteTMVA(InputTree,fTMVAWeightPath[1],false); + double Alpha_2 = ExecuteTMVA(InputTree,fTMVAWeightPath[2],false); + delete InputTree; + + if(Alpha_0 < fKThreshold) //not enought fissile for sure !! + return 0; + + double Sum = 0; + double SumSquare = 0; + + for(int i = 1 ; i<= fNumberOfBatch; i++) + { Sum+= double(i)/double(fNumberOfBatch); + SumSquare+= double(i*i)/double(fNumberOfBatch*fNumberOfBatch); + } + + double C = (Alpha_0-fKThreshold)*fNumberOfBatch; + double B = Alpha_1*Sum; + double A = Alpha_2*SumSquare; + + double Delta = B*B-4*A*C; + + double T = 0; + if( Delta > 0) + { + double T_1 = (-B + sqrt(Delta))/(2*A); + double T_2 = (-B - sqrt(Delta))/(2*A); + + if(T_1 < 0 && T_2 > 0) + T = T_2; + else if(T_1 > 0 && T_2 < 0) + T = T_1; + + else if( T_1 > 0 && T_2 > 0 ) + { + if(T_2 < T_1) + T = T_2; + else + T = T_1; + } + else + { + ERROR << "No positive solution" << endl; + exit(1); + } + } + else if(Delta == 0) + { T = -B/(2*A); + if(T<0) + { ERROR << "No positive solution" << endl; + exit(1); + } + } + else + { + WARNING << "No real solution" << endl; + double K_LongTime = Alpha_0+BurnupToSecond(10*TargetBU)*Alpha_1+Alpha_2*BurnupToSecond(10*TargetBU)*BurnupToSecond(10*TargetBU); + DBGV("K_LongTime " << K_LongTime) + + if(K_LongTime > fKThreshold) + return 10000; + else + { + ERROR << " CRITICAL ! Can't find a physical solution ! \n Should not happening please contact BLG :" << endl; + ERROR << "mail to baptiste.leniau@subatech.in2p2.fr\nor nicolas.thiolliere@subatech.in2p3.fr " << endl; + exit(1); + } + + } + + return SecondToBurnup(T); +} +//________________________________________________________________________ +double EQM_MLP_Kinf::GetMaximumBurnUp(IsotopicVector TheFuel, double TargetBU) +{ + double TheBurnUp = -1; + if(fTMVAWeightPath.size() == 1) + TheBurnUp = GetMaximumBurnUp_MLP(TheFuel,TargetBU); + else if(fTMVAWeightPath.size() == 3) + TheBurnUp = GetMaximumBurnUp_Pol2(TheFuel,TargetBU); + + else + { + ERROR << "This method is not yet set up" << endl; + exit(0); + } + + return TheBurnUp; +} +//________________________________________________________________________ +double EQM_MLP_Kinf::GetFissileMolarFraction(IsotopicVector Fissil,IsotopicVector Fertil,double TargetBU) +{ + + //initialization + double FissileContent = GetActualFissileContent(); + double OldFissileContentMinus = 0; + double OldFissileContentPlus = fMaximalContent; + double PredictedBU = 0 ; + IsotopicVector FreshFuel = (1-FissileContent)*(Fertil/Fertil.GetSumOfAll()) + FissileContent*(Fissil/Fissil.GetSumOfAll()); + double OldPredictedBU = GetMaximumBurnUp(FreshFuel,TargetBU); + + double Precision = GetBurnUpPrecision()*TargetBU; //1 % of the targeted burnup + int count = 0; + int MaximumLoopCount = 500; + do + { + if(count > MaximumLoopCount ) + { + ERROR << "CRITICAL ! Can't manage to predict fissile content\nHint : Try to decrease the precision on burnup using :\nYourEQM_MLP_Kinf->SetBurnUpPrecision(prop); with prop the precision (default 0.5percent : 0.005) INCREASE IT\nIf this message still appear mail to leniau@subatech.in2p3.fr\nor nicolas.thiolliere@subatech.in2p3.fr " << endl; + ERROR << "Targeted Burnup :" <<TargetBU<<endl; + ERROR << "Last calculated Burnup :" <<OldPredictedBU<<endl; + ERROR << "Last Fresh fuel composition :" <<endl; + ERROR << FreshFuel.sPrint()<<endl; + + exit(1); + } + + if( (OldPredictedBU - TargetBU) < 0 ) //The Content can be increased + { + OldFissileContentMinus = FissileContent; + FissileContent = FissileContent + fabs(OldFissileContentPlus-FissileContent)/2.; + } + else if( (OldPredictedBU - TargetBU) > 0) //The Content is too high + { + OldFissileContentPlus = FissileContent; + FissileContent = FissileContent - fabs(OldFissileContentMinus-FissileContent)/2.; + } + + IsotopicVector FreshFuel = (1-FissileContent)*(Fertil/Fertil.GetSumOfAll()) + FissileContent*(Fissil/Fissil.GetSumOfAll()); + PredictedBU = GetMaximumBurnUp(FreshFuel,TargetBU); + + OldPredictedBU = PredictedBU; + count ++; + + }while(fabs(TargetBU-PredictedBU)>Precision); + + + + DBGV("Predicted BU " << PredictedBU << " FissileContent " << FissileContent); + return FissileContent; +} +//________________________________________________________________________ \ No newline at end of file diff --git a/source/branches/BaM/Model/Equivalence/EQM_MLP_Kinf.hxx b/source/branches/BaM/Model/Equivalence/EQM_MLP_Kinf.hxx new file mode 100644 index 000000000..48e0296bb --- /dev/null +++ b/source/branches/BaM/Model/Equivalence/EQM_MLP_Kinf.hxx @@ -0,0 +1,220 @@ +#ifndef _EQM_MLP_Kinf_HXX +#define _EQM_MLP_Kinf_HXX + +#include "EquivalenceModel.hxx" +#include "TTree.h" +#include <map> + +using namespace std; + +class EQM_MLP_Kinf; +#ifndef __CINT__ +typedef void (EQM_MLP_Kinf::*PWR_MLP_KINF_DMthPtr)( const string & ) ; +#endif + +//-----------------------------------------------------------------------------// +//! Defines an EquivalenceModel based on neural network to predict @f$k_{\infty}@f$. + +/*! +The aim of these class is to constuct a fuel from an equivalence model +based on a Multi layer perceptron (MLP) +This MLP aims to predict the @f$k_{\infty}(t)@f$ of a PWR-MOX from a given fresh fuel +composition +With this MLP prediction and a given number of batch (for the loading plan) an +average @f$\langle k_{\infty}\rangle (t)@f$ is calculated according : + +@f$\langle k_{\infty}\rangle ^{batch}(t) = \frac{1}{N}\sum_{i}^{N}k_{\infty}(t+\frac{iT}{N})@f$ +The maximal reachable burnup has to verify the following conditions : +@f$\langle k_{\infty}\rangle ^{batch}(T/N) = \langle k_{\infty}\rangle ^{batch}(2T/N) = ... = k_{Threshold}@f$ +Where @f$k_{Threshold}@f$ is the criticality threshold which take into account leakage and capture +in non simulated devices such as control rods and mixing grid. + + @author BLG + @version 1.0 + */ +//________________________________________________________________________ + + +class EQM_MLP_Kinf : public EquivalenceModel +{ + public: + /*! + \name Constructor + */ + //@{ + + //{ + /// Polynnomial 2nd order constructor @f$k_{\infty} = \alpha_{0} + \alpha_{1}t + \alpha_{2}t^{2}@f$ + /// @f$\alpha_{0}@f$, @f$\alpha_{1}@f$, @f$\alpha_{2}@f$ are predict by 3 MLP (one for each) + /*! + Create a EQM_MLP_Kinf + \param TMVAWeightPath0 : PAth to the .xml file containing neural network informations for @f$\alpha_{0}@f$ prediction : PATH/TMVAWeight.xml (total path to tmva weight) + \param TMVAWeightPath1 : PAth to the .xml file containing neural network informations for @f$\alpha_{1}@f$ prediction: PATH/TMVAWeight.xml (total path to tmva weight) + \param TMVAWeightPath2 : PAth to the .xml file containing neural network informations for @f$\alpha_{2}@f$ prediction: PATH/TMVAWeight.xml (total path to tmva weight) + \param InformationFile : Total path to the file containing time steps, fissile and ferile list (ante and post fabrication time cooling). Default is the same total path as TMVAWeightPath but extension is replaced by .nfo + \param NumOfBatch : Number of batch for the loading plan (often 3 or 4 for PWR) + \param CriticalityThreshold : Threshold for the @f$k_{\infty}@f$ (see detailed description) + */ + EQM_MLP_Kinf(string WeightPathAlpha0, string WeightPathAlpha1, string WeightPathAlpha2, string InformationFile, int NumOfBatch, double CriticalityThreshold = 1.01); + //} + //{ + /// Polynnomial 2nd order constructor @f$k_{\infty} = \alpha_{0} + \alpha_{1}t + \alpha_{2}t^{2}@f$ + /// @f$\alpha_{0}@f$, @f$\alpha_{1}@f$, @f$\alpha_{2}@f$ are predict by 3 MLP (one for each) + /*! + Create a EQM_MLP_Kinf + \param log : use for log + \param TMVAWeightPath0 : PAth to the .xml file containing neural network informations for @f$\alpha_{0}@f$ prediction : PATH/TMVAWeight.xml (total path to tmva weight) + \param TMVAWeightPath1 : PAth to the .xml file containing neural network informations for @f$\alpha_{1}@f$ prediction: PATH/TMVAWeight.xml (total path to tmva weight) + \param TMVAWeightPath2 : PAth to the .xml file containing neural network informations for @f$\alpha_{2}@f$ prediction: PATH/TMVAWeight.xml (total path to tmva weight) + \param InformationFile : Total path to the file containing time steps, fissile and ferile list (ante and post fabrication time cooling). Default is the same total path as TMVAWeightPath but extension is replaced by .nfo + \param NumOfBatch : Number of batch for the loading plan (often 3 or 4 for PWR) + \param CriticalityThreshold : Threshold for the @f$k_{\infty}@f$ (see detailed description) + */ + EQM_MLP_Kinf(CLASSLogger* log, string WeightPathAlpha0, string WeightPathAlpha1, string WeightPathAlpha2, string InformationFile, int NumOfBatch, double CriticalityThreshold = 1.01 ); + //} + //{ + /// Neural network predictor. The kinf(t) is predicted with a MLP + /*! + Create a EQM_MLP_Kinf + \param TMVAWeightPath : PAth to the .xml file containing neural network informations : PATH/TMVAWeight.xml (total path to tmva weight) + \param NumOfBatch : Number of batch for the loading plan (often 3 or 4 for PWR) + \param InformationFile : Total path to the file containing time steps, fissile and ferile list (ante and post fabrication time cooling). Default is the same total path as TMVAWeightPath but extension is replaced by .nfo + \param CriticalityThreshold : Threshold for the @f$k_{\infty}@f$ (see detailed description) + */ + EQM_MLP_Kinf(string TMVAWeightPath,int NumOfBatch, string InformationFile = "", double CriticalityThreshold = 1.01); + //} + + //{ + /// Neural network predictor. The kinf(t) is predicted with a MLP + /*! + Create a EQM_MLP_Kinf + \param log : use for log + \param TMVAWeightPath : PAth to the .xml file containing neural network informations : PATH/TMVAWeight.xml (total path to tmva weight) + \param NumOfBatch : Number of batch for the loading plan (often 3 or 4 for PWR) + \param InformationFile : Total path to the file containing time steps, fissile and ferile list (ante and post fabrication time cooling). Default is the same total path as TMVAWeightPath but extension is replaced by .nfo + \param CriticalityThreshold : Threshold for the @f$k_{\infty}@f$ (see detailed description) + */ + EQM_MLP_Kinf(CLASSLogger* log, string TMVAWeightPath,int NumOfBatch, string InformationFile = "", double CriticalityThreshold = 1.01); + //} + //@} + + //{ + /// Return the molar fissile fraction according fissile & ferile content + /*! + \param Fissil : The composition of the fissile matter + \param Fertil : The composition of the Fertil matter + \param BurnUp : Maximum achievable burn up envisaged + */ + virtual double GetFissileMolarFraction(IsotopicVector Fissil,IsotopicVector Fertil,double BurnUp); + //} + + /*! + \name Get/Set methods + */ + //@{ + + void SetBurnUpPrecision(double prop){fBurnUpPrecision = prop;} //!< Set the precision on Burnup : proportion of the targeted burnup + void SetPCMprecision(double pcm){fPCMprecision = pcm;} //!< Set the precision on @f$\langle k \rangle@f$ prediction [pcm]. Neural network predictor constructors + double GetBurnUpPrecision(){return fBurnUpPrecision;}//!< Get the precision on Burnup : proportion of the targeted burnup + double GetPCMprecision(){return fPCMprecision/1e5;}//!< Get the precision on @f$\langle k \rangle@f$ prediction []. Neural network predictor constructors + + double GetMaximumBurnUp(IsotopicVector TheFuel, double TargetBU);//!<Get the maximum reachable burnup according the freshfuel composition + void GetModelInformation();//!<Read the fMLPInformationFile and fill containers and variables + + //@} + + /*! + \name Time <-> Burnup conversion + */ + //@{ + + double SecondToBurnup(double Second){return Second*fSpecificPower/(24*3.6e6);} + double BurnupToSecond(double BurnUp){return BurnUp/fSpecificPower*(24*3.6e6);} + + //@} + + /*! + \name TMVA related methods + */ + //@{ + + TTree* CreateTMVAInputTree(IsotopicVector FreshFuel, double ThisTime);//!<Create input tmva tree to be read by ExecuteTMVA + double ExecuteTMVA(TTree* theTree, string WeightPath, bool IsTimeDependant);//!<Execute the MLP according to the input tree created by CreateTMVAInputTree + + //@} + + /*! + \name Reading NFO related Method + */ + //@{ + + //{ + /// LoadKeyword() : make the correspondance between keyword and reading method + void LoadKeyword(); + //} + + //{ + /// ReadZAIName : read the zai name in the TMWA MLP model + /*! + \param line : line suppossed to contain the ZAI name starts with "k_zainame" keyword + */ + void ReadZAIName(const string &line); + //} + + //{ + /// ReadMaxBurnUp : read a guessed (very overestimated) maximum burnup a fuel can reach (purpose : algorithm initialization) + /*! + \param line : line suppossed to contain the ZAI name starts with "k_maxburnup" keyword + */ + void ReadMaxBurnUp(const string &line); + //} + + //{ + /// ReadMaxFisContent : read a guessed (very overestimated) maximum fissile content (purpose : algorithm initialization) + /*! + \param line : line suppossed to contain the ZAI name starts with "k_maxfiscontent" keyword + */ + void ReadMaxFisContent(const string &line); + //} + + //{ + /// ReadLine : read a line + /*! + \param line : line to read + */ + void ReadLine(string line); + //} + + //@} + + private : + vector <string> fTMVAWeightPath; //!<The weight needed by TMVA to construct and execute the multilayer perceptron + +#ifndef __CINT__ + map<string, PWR_MLP_KINF_DMthPtr> fDKeyword; +#endif + + map<ZAI,string> fMapOfTMVAVariableNames;//!< List of TMVA input variable names (read from fMLPInformationFile ) , name depends on the training step + + /*! + \name private Get/Set methods + */ + //@{ + + double GetMaximumBurnUp_MLP(IsotopicVector TheFuel, double TargetBU); + double GetMaximumBurnUp_Pol2(IsotopicVector TheFuel, double TargetBU); + + //@} + + int fNumberOfBatch; //!< The number of batches for the loading plan + double fKThreshold; //!< The @f$k_{Threshold}@f$ + double fMaximalBU; //!< The approx. maximum burnup reachable by the MLP model + double fMaximalContent; //!< The approx. maximum fissile content reachable by the MLP model + double fBurnUpPrecision; //!< precision on Burnup + double fPCMprecision; //!< precision on @f$\langle k \rangle@f$ prediction [pcm] + + +}; + +#endif + diff --git a/source/branches/BaM/Model/Equivalence/EQM_PWR_LIN_MOX.cxx b/source/branches/BaM/Model/Equivalence/EQM_PWR_LIN_MOX.cxx new file mode 100644 index 000000000..6a1a76d03 --- /dev/null +++ b/source/branches/BaM/Model/Equivalence/EQM_PWR_LIN_MOX.cxx @@ -0,0 +1,264 @@ +#include "EQM_PWR_LIN_MOX.hxx" + +#include "CLASSConstante.hxx" + +#include <vector> + +#include "StringLine.hxx" +#include "CLASSLogger.hxx" +#include "IsotopicVector.hxx" + + + +EQM_PWR_LIN_MOX::EQM_PWR_LIN_MOX(string WeightPath):EquivalenceModel(new CLASSLogger("EQM_PWR_LIN_MOX.log")) +{ + fWeightPath = WeightPath; + + ifstream DataDB(fWeightPath.c_str()); // Open the File + if(!DataDB) + WARNING << "Can't open \"" << fWeightPath << "\"\n" << endl; + + string line; + int start = 0; // First Get Fuel Parameter + getline(DataDB, line); + + if( StringLine::NextWord(line, start, ' ') != "PARAM") + { + ERROR << " Bad Database file : " << fWeightPath << " Can't find the Parameter of the DataBase " << endl; + exit (1); + } + while(start < (int)line.size()) + fFuelParameter.push_back(atof(StringLine::NextWord(line, start, ' ').c_str())); + + INFO << " " << (int)fFuelParameter.size() << " parameters have been read " << endl; + + + + //-----------------------------------------------------------------------------// + //-----------------------------------------------------------------------------// + //-----------------------------------------------------------------------------// + //-----------------------------------------------------------------------------// + //-----------------------------------------------------------------------------// + // ADD ENrichment of the U reading !!!!!!!!!!!!!!!!!!!!!!!!!!!! // + //-----------------------------------------------------------------------------// + //-----------------------------------------------------------------------------// + //-----------------------------------------------------------------------------// + //-----------------------------------------------------------------------------// + + ZAI U8(92,238,0); + ZAI U5(92,235,0); + double U5_enrich = 0.0025; + fFertileList = U5*U5_enrich + U8*(1-U5_enrich); + + + ZAI Pu8(94,238,0); + ZAI Pu9(94,239,0); + ZAI Pu0(94,240,0); + ZAI Pu1(94,241,0); + ZAI Pu2(94,242,0); + fFissileList = Pu8*1+Pu9*1+Pu0*1+Pu1*1+Pu2*1; + + EquivalenceModel::PrintInfo(); + + +} + + +EQM_PWR_LIN_MOX::EQM_PWR_LIN_MOX(CLASSLogger* log, string WeightPath):EquivalenceModel(log) +{ + fWeightPath = WeightPath; + + ifstream DataDB(fWeightPath.c_str()); // Open the File + if(!DataDB) + WARNING << " Can't open \"" << fWeightPath << "\"\n" << endl; + + string line; + int start = 0; // First Get Fuel Parameter + getline(DataDB, line); + + if( StringLine::NextWord(line, start, ' ') != "PARAM") + { + ERROR << " Bad Database file : " << fWeightPath << " Can't find the Parameter of the DataBase" << endl; + exit (1); + } + while(start < (int)line.size()) + fFuelParameter.push_back(atof(StringLine::NextWord(line, start, ' ').c_str())); + + INFO << fFuelParameter.size() << " have been read" << endl; + + + + //-----------------------------------------------------------------------------// + //-----------------------------------------------------------------------------// + //-----------------------------------------------------------------------------// + //-----------------------------------------------------------------------------// + //-----------------------------------------------------------------------------// + // ADD ENrichment of the U reading !!!!!!!!!!!!!!!!!!!!!!!!!!!! // + //-----------------------------------------------------------------------------// + //-----------------------------------------------------------------------------// + //-----------------------------------------------------------------------------// + //-----------------------------------------------------------------------------// + + ZAI U8(92,238,0); + ZAI U5(92,235,0); + double U5_enrich = 0.0025; + fFertileList = U5*U5_enrich + U8*(1-U5_enrich); + + + ZAI Pu8(94,238,0); + ZAI Pu9(94,239,0); + ZAI Pu0(94,240,0); + ZAI Pu1(94,241,0); + ZAI Pu2(94,242,0); + fFissileList = Pu8*1+Pu9*1+Pu0*1+Pu1*1+Pu2*1; + + +} + +EQM_PWR_LIN_MOX::~EQM_PWR_LIN_MOX() +{ + +} + +//________________________________________________________________________ +vector<double> EQM_PWR_LIN_MOX::BuildFuel(double BurnUp, double HMMass,vector<IsotopicVector> FissilArray, vector<IsotopicVector> FertilArray) +{ + + //-----------------------------------------------------------------------------// + //-----------------------------------------------------------------------------// + //-----------------------------------------------------------------------------// + //-----------------------------------------------------------------------------// + //-----------------------------------------------------------------------------// + // ADD ENrichment of the U check ++ Check Un seul fertile !!!! // + //-----------------------------------------------------------------------------// + //-----------------------------------------------------------------------------// + //-----------------------------------------------------------------------------// + //-----------------------------------------------------------------------------// + + + vector<double> lambda; + for(int i = 0; i < (int) (FissilArray.size() + FertilArray.size()); i++) + lambda.push_back(0); + + + double Na = 6.02214129e23; //N Avogadro + + IsotopicVector FullUsedStock; + IsotopicVector stock; + + bool FuelBuild = false; + if(FissilArray.size() == 0) + { + for(int i = 0; i < (int)lambda.size(); i++) + lambda[i] = -1; + + FuelBuild = true; + } + int N_FissilStock_OnCheck = 0; + + while(!FuelBuild) + { + + double nPu_0 = 0; + double MPu_0 = 0; + { + map<ZAI ,double>::iterator it; + + map<ZAI ,double> isotopicquantity = FullUsedStock.GetSpeciesComposition(94).GetIsotopicQuantity(); + for( it = isotopicquantity.begin(); it != isotopicquantity.end(); it++ ) + nPu_0 += (*it).second; + + IsotopicVector IV_Pm_Am = (FullUsedStock.GetSpeciesComposition(94) + + ZAI(94,241,0)*FullUsedStock.GetZAIIsotopicQuantity(95,241,0)); + //Add the 241Am as 241Pu... the Pu is not old in the Eq Model but is in the FissileArray....; + MPu_0 += cZAIMass.GetMass(IV_Pm_Am); + } + stock = FissilArray[N_FissilStock_OnCheck]; + double nPu_1 = 0; + double MPu_1 = 0; + double Sum_AlphaI_nPuI = 0; + double Sum_AlphaI_nPuI0 = 0; + { + map<ZAI ,double>::iterator it; + map<ZAI ,double> isotopicquantity = stock.GetSpeciesComposition(94).GetIsotopicQuantity(); + + for( it = isotopicquantity.begin(); it != isotopicquantity.end(); it++ ) + { + if ((*it).first.A() >= 238 && (*it).first.A() <= 242) + { + nPu_1 += (*it).second; + Sum_AlphaI_nPuI += fFuelParameter[(*it).first.A() -237]*(*it).second; + } + } + + isotopicquantity = (stock.GetSpeciesComposition(94) + ZAI(94,241,0)*stock.GetZAIIsotopicQuantity(95,241,0)).GetIsotopicQuantity(); + IsotopicVector IV_Pm_Am = (stock.GetSpeciesComposition(94) + + ZAI(94,241,0)*stock.GetZAIIsotopicQuantity(95,241,0)); + //Add the 241Am as 241Pu... the Pu is not old in the Eq Model but is in the FissileArray.... + MPu_1 += cZAIMass.GetMass(IV_Pm_Am); + + isotopicquantity = FullUsedStock.GetSpeciesComposition(94).GetIsotopicQuantity(); + for( it = isotopicquantity.begin(); it != isotopicquantity.end(); it++ ) + if ((*it).first.A() >= 238 && (*it).first.A() <= 242) + { + Sum_AlphaI_nPuI0 += fFuelParameter[(*it).first.A() -237]*(*it).second; + } + } + + double StockFactionToUse = 0; + + double NT = HMMass*1e6 * Na / (cZAIMass.GetMass( ZAI(92,238,0) ) * 0.997 + + cZAIMass.GetMass( ZAI(92,235,0) ) * 0.003 ); + + double N1 = (BurnUp - fFuelParameter[6]) * NT; + double N2 = -Sum_AlphaI_nPuI0; + double N3 = -fFuelParameter[0] * Na / (cZAIMass.GetMass( ZAI(92,238,0) )*0.997 + + cZAIMass.GetMass( ZAI(92,235,0) )*0.003 ) + * (HMMass*1e6 - MPu_0*1e6); + + double D1 = Sum_AlphaI_nPuI; + double D2 = -fFuelParameter[0] * MPu_1*1e6 * Na / (cZAIMass.GetMass( ZAI(92,238,0) )*0.997 + + cZAIMass.GetMass( ZAI(92,235,0) )*0.003 ); + + StockFactionToUse = (N1 + N2 + N3) / (D1 + D2); + + if(StockFactionToUse < 0) + { + WARNING << "!!!FabricationPlant!!! Oups Bug in calculating stock fraction to use " << endl; + lambda[N_FissilStock_OnCheck] = 0.; + N_FissilStock_OnCheck++; + FuelBuild = false; + } + else if( StockFactionToUse > 1 ) + { + + FullUsedStock += stock; + lambda[N_FissilStock_OnCheck] = 1; + N_FissilStock_OnCheck++; + FuelBuild = false; + } + else + { + lambda[N_FissilStock_OnCheck] = StockFactionToUse; + + FuelBuild = true; + + double U8_Quantity = (HMMass - (MPu_0+StockFactionToUse*MPu_1 ))/(cZAIMass.GetMass( ZAI(92,238,0))*0.997 + cZAIMass.GetMass( ZAI(92,235,0))*0.003 )*Na/1e-6; + + lambda.back() = U8_Quantity / FertilArray[0].GetSumOfAll(); + } + + + if( N_FissilStock_OnCheck == (int) FissilArray.size() ) // Check if the last Fissil stock has been tested... quit if so... + { + for(int i = 0; i < (int)lambda.size(); i++) + lambda[i] = -1; + + FuelBuild = true; + } + } + + + + return lambda; +} diff --git a/source/branches/BaM/Model/Equivalence/EQM_PWR_LIN_MOX.hxx b/source/branches/BaM/Model/Equivalence/EQM_PWR_LIN_MOX.hxx new file mode 100644 index 000000000..4946ad7d7 --- /dev/null +++ b/source/branches/BaM/Model/Equivalence/EQM_PWR_LIN_MOX.hxx @@ -0,0 +1,71 @@ +#ifndef _EQM_PWR_LIN_MOX_HXX +#define _EQM_PWR_LIN_MOX_HXX + +#include "EquivalenceModel.hxx" + +#include <string> + +using namespace std; + +//-----------------------------------------------------------------------------// +//! Defines an EquivalenceModel based on a linear fit + +/*! + The aim of these class is to constuct a fuel from an equivalence model + based on a Linear Eq Model @f$BU = \alpha_{0} + \sum_{i\in fissile}\alpha_{i}\cdot n_{i} @f$ + For one set of @f$\alpha @f$ values the fabrication time is fixed in order to decrease + the dimentionality by 1 (@f$^{241}Am@f$ is thus fixed by this fixed decay time) . + @author BaM + @version 3.0 + */ +//________________________________________________________________________ + +class EQM_PWR_LIN_MOX : public EquivalenceModel +{ + public : + /*! + \name Constructor + */ + //@{ + + //{ + /// Simple constructor + + /*! + Make a new EQM_PWR_LIN_MOX + \param WeightPath : Path to the file containing the @f$\alpha_{i}@f$. The file is format as : + + @f$PARAM@f$ @f$\alpha_{0}@f$ @f$\alpha_{^{238}Pu}@f$ @f$\alpha_{^{239}Pu}@f$ @f$\alpha_{^{240}Pu}@f$ @f$\alpha_{^{241}Pu}@f$ @f$\alpha_{^{242}Pu}@f$ + + */ + EQM_PWR_LIN_MOX(string WeightPath); + //} + + //{ + /// Logger constructor + + /*! + Make a new EQM_PWR_LIN_MOX + \param log : use for the log + \param WeightPath : Path to the file containing the @f$\alpha_{i}@f$. The file is format as : + + @f$PARAM@f$ @f$\alpha_{0}@f$ @f$\alpha_{^{238}Pu}@f$ @f$\alpha_{^{239}Pu}@f$ @f$\alpha_{^{240}Pu}@f$ @f$\alpha_{^{241}Pu}@f$ @f$\alpha_{^{242}Pu}@f$ + + */ + EQM_PWR_LIN_MOX(CLASSLogger* log, string WeightPath); + //} + + ~EQM_PWR_LIN_MOX(); + //@} + + virtual vector<double> BuildFuel(double BurnUp, double HMMass, vector<IsotopicVector> FissilArray, vector<IsotopicVector> FertilArray ); + + private : + + string fWeightPath; //!< The full path to the file containing the @f$\alpha_{i}@f$ + vector<double> fFuelParameter; //!< The vector of @f$\alpha_{i}@f$ + +}; + +#endif + diff --git a/source/branches/BaM/Model/Equivalence/EQM_PWR_MLP_MOX.cxx b/source/branches/BaM/Model/Equivalence/EQM_PWR_MLP_MOX.cxx new file mode 100644 index 000000000..af3b7c820 --- /dev/null +++ b/source/branches/BaM/Model/Equivalence/EQM_PWR_MLP_MOX.cxx @@ -0,0 +1,185 @@ +#include "EquivalenceModel.hxx" +#include "EQM_PWR_MLP_MOX.hxx" +#include "CLASSLogger.hxx" +#include "StringLine.hxx" + +#include <string> +#include <iostream> +#include <fstream> +#include <algorithm> +#include <cmath> +#include <cassert> + +#include "TSystem.h" +#include "TMVA/Reader.h" +#include "TMVA/Tools.h" +#include "TMVA/MethodCuts.h" + + +//________________________________________________________________________ +// +// EQM_PWR_MLP_MOX +// +// Equivalenve Model based on multi layer perceptron from TMVA (root cern) +// For REP MOX use +// +//________________________________________________________________________ + +EQM_PWR_MLP_MOX::EQM_PWR_MLP_MOX(string TMVAWeightPath):EquivalenceModel(new CLASSLogger("EQM_PWR_MLP_MOX.log")) +{ + fTMVAWeightPath = TMVAWeightPath; + + ZAI U8(92,238,0); + ZAI U5(92,235,0); + double U5_enrich = 0.0025; + + ZAI Pu8(94,238,0); + ZAI Pu9(94,239,0); + ZAI Pu0(94,240,0); + ZAI Pu1(94,241,0); + ZAI Pu2(94,242,0); + + fFissileList = Pu8*1+Pu9*1+Pu0*1+Pu1*1+Pu2*1; + fFertileList = U5*U5_enrich + U8*(1-U5_enrich); + + SetBuildFuelFirstGuess(0.04); + + INFO << "__An equivalence model of PWR MOX has been define__" << endl; + INFO << "\tThis model is based on a multi layer perceptron" << endl; + INFO << "\t\tThe TMVA weight file is :" << endl; + INFO << "\t\t\t" << fTMVAWeightPath << endl; + EquivalenceModel::PrintInfo(); + +} + +//________________________________________________________________________ +EQM_PWR_MLP_MOX::EQM_PWR_MLP_MOX(CLASSLogger* log, string TMVAWeightPath):EquivalenceModel(log) +{ + fTMVAWeightPath = TMVAWeightPath; + + ZAI U8(92,238,0); + ZAI U5(92,235,0); + double U5_enrich = 0.0025; + + ZAI Pu8(94,238,0); + ZAI Pu9(94,239,0); + ZAI Pu0(94,240,0); + ZAI Pu1(94,241,0); + ZAI Pu2(94,242,0); + + fFissileList = Pu8*1+Pu9*1+Pu0*1+Pu1*1+Pu2*1; + fFertileList = U5*U5_enrich + U8*(1-U5_enrich); + + SetBuildFuelFirstGuess(0.04); + + INFO << "__An equivalence model of PWR MOX has been define__" << endl; + INFO << "\tThis model is based on a multi layer perceptron" << endl; + INFO << "\t\tThe TMVA weight file is :" << endl; + INFO << "\t\t\t" << fTMVAWeightPath << endl; + EquivalenceModel::PrintInfo(); + +} + +//________________________________________________________________________ +TTree* EQM_PWR_MLP_MOX::CreateTMVAInputTree(IsotopicVector Fissil,IsotopicVector Fertil,double BurnUp) +{ + TTree* InputTree = new TTree("EQTMP", "EQTMP"); + float Pu8 = 0; + float Pu9 = 0; + float Pu10 = 0; + float Pu11 = 0; + float Pu12 = 0; + float Am1 = 0; + float U5_enrichment = 0; + float BU = 0; + + InputTree->Branch( "Pu8" ,&Pu8 ,"Pu8/F" ); + InputTree->Branch( "Pu9" ,&Pu9 ,"Pu9/F" ); + InputTree->Branch( "Pu10" ,&Pu10 ,"Pu10/F" ); + InputTree->Branch( "Pu11" ,&Pu11 ,"Pu11/F" ); + InputTree->Branch( "Pu12" ,&Pu12 ,"Pu12/F" ); + InputTree->Branch( "Am1" ,&Am1 ,"Am1/F" ); + InputTree->Branch( "U5_enrichment" ,&U5_enrichment ,"U5_enrichment/F" ); + InputTree->Branch( "BU" ,&BU ,"BU/F" ); + + + float U8 = Fertil.GetZAIIsotopicQuantity(92,238,0); + float U5 = Fertil.GetZAIIsotopicQuantity(92,235,0); + float U4 = Fertil.GetZAIIsotopicQuantity(92,234,0); + + float UTOT = U8 + U5 + U4; + + Pu8 = Fissil.GetZAIIsotopicQuantity(94,238,0); + Pu9 = Fissil.GetZAIIsotopicQuantity(94,239,0); + Pu10 = Fissil.GetZAIIsotopicQuantity(94,240,0); + Pu11 = Fissil.GetZAIIsotopicQuantity(94,241,0); + Pu12 = Fissil.GetZAIIsotopicQuantity(94,242,0); + Am1 = Fissil.GetZAIIsotopicQuantity(95,241,0); + + double TOTPU = (Pu8+Pu9+Pu10+Pu11+Pu12+Am1); + + Pu8 = Pu8 / TOTPU; + Pu9 = Pu9 / TOTPU; + Pu10 = Pu10 / TOTPU; + Pu11 = Pu11 / TOTPU; + Pu12 = Pu12 / TOTPU; + Am1 = Am1 / TOTPU; + + U5_enrichment = U5 / UTOT; + + BU = BurnUp; + if(Pu8 + Pu9 + Pu10 + Pu11 + Pu12 + Am1 > 1.00001 )//?????1.00001??? I don't know it! goes in condition if = 1 !! may be float/double issue ... + { + ERROR << Pu8 << " " << Pu9 << " " << Pu10 << " " << Pu11 << " " << Pu12 << " " << Am1 << endl; + exit(0); + } + // All value are molar (!weight) + + InputTree->Fill(); + return InputTree; +} +//________________________________________________________________________ +double EQM_PWR_MLP_MOX::ExecuteTMVA(TTree* theTree) +{ + // --- Create the Reader object + TMVA::Reader *reader = new TMVA::Reader( "Silent" ); + // Create a set of variables and declare them to the reader + // - the variable names MUST corresponds in name and type to those given in the weight file(s) used + Float_t Pu8,Pu9,Pu10,Pu11,Pu12,Am1,BU,U5_enrichment; + + reader->AddVariable( "BU" ,&BU ); + reader->AddVariable( "U5_enrichment",&U5_enrichment ); + reader->AddVariable( "Pu8" ,&Pu8 ); + reader->AddVariable( "Pu9" ,&Pu9 ); + reader->AddVariable( "Pu10" ,&Pu10); + reader->AddVariable( "Pu11" ,&Pu11); + reader->AddVariable( "Pu12" ,&Pu12); + reader->AddVariable( "Am1" ,&Am1 ); + + // --- Book the MVA methods + + // Book method MLP + TString methodName = "MLP method"; + reader->BookMVA( methodName, fTMVAWeightPath ); + theTree->SetBranchAddress( "BU" ,&BU ); + theTree->SetBranchAddress( "U5_enrichment" ,&U5_enrichment ) ; + theTree->SetBranchAddress( "Pu8" ,&Pu8 ); + theTree->SetBranchAddress( "Pu9" ,&Pu9 ); + theTree->SetBranchAddress( "Pu10" ,&Pu10 ); + theTree->SetBranchAddress( "Pu11" ,&Pu11 ); + theTree->SetBranchAddress( "Pu12" ,&Pu12 ); + theTree->SetBranchAddress( "Am1" ,&Am1 ); + theTree->GetEntry(0); + + Float_t val = (reader->EvaluateRegression( methodName ))[0]; + + delete reader; + delete theTree; + + return (double)val; //retourne teneur +} +//________________________________________________________________________ +double EQM_PWR_MLP_MOX::GetFissileMolarFraction(IsotopicVector Fissil,IsotopicVector Fertil,double BurnUp) +{DBGL + return ExecuteTMVA(CreateTMVAInputTree(Fissil,Fertil,BurnUp)); +} diff --git a/source/branches/BaM/Model/Equivalence/EQM_PWR_MLP_MOX.hxx b/source/branches/BaM/Model/Equivalence/EQM_PWR_MLP_MOX.hxx new file mode 100644 index 000000000..f0a9bae11 --- /dev/null +++ b/source/branches/BaM/Model/Equivalence/EQM_PWR_MLP_MOX.hxx @@ -0,0 +1,77 @@ +#ifndef _EQM_PWR_MLP_MOX_HXX +#define _EQM_PWR_MLP_MOX_HXX + +#include "EquivalenceModel.hxx" +#include "TTree.h" + +using namespace std; + +//-----------------------------------------------------------------------------// +//! Defines an EquivalenceModel based on neural network + +/*! + The aim of these class is to constuct a fuel from an equivalence model + based on a Multi layer perceptron + + @author BLG + @version 3.0 + */ +//________________________________________________________________________ + +class EQM_PWR_MLP_MOX : public EquivalenceModel +{ + public : + /*! + \name Constructor + */ + //@{ + + //{ + /// normal constructor + /*! + Create a EQM_PWR_MLP_MOX + \param TMVAWeightPath : PAth to the .xml file containing neural network informations : PATH/TMVAWeight.xml (total path to tmva weight) + */ + EQM_PWR_MLP_MOX(string TMVAWeightPath); + //} + + //{ + /// Logger constructor + /*! + Create a EQM_PWR_MLP_MOX + \param log : use for log + \param TMVAWeightPath : PAth to the .xml file containing neural network informations : PATH/TMVAWeight.xml (total path to tmva weight) + */ + EQM_PWR_MLP_MOX(CLASSLogger* log, string TMVAWeightPath); + //} + //@} + + //{ + /// Return the molar fissile fraction according fissile & ferile content using a Multi Layer Peceptron (MLP) + /*! + \param Fissil : The composition of the fissile matter + \param Fertil : The composition of the Fertil matter + \param BurnUp : Maximum achievable burn up envisaged + */ + virtual double GetFissileMolarFraction(IsotopicVector Fissil,IsotopicVector Fertil,double BurnUp); + //} + + /*! + \name TMVA related methods + */ + //@{ + + TTree* CreateTMVAInputTree(IsotopicVector Fissil,IsotopicVector Fertil,double BurnUp);//!<Create input tmva tree to be read by ExecuteTMVA + double ExecuteTMVA(TTree* theTree);//!<Execute the MLP according to the input tree created by CreateTMVAInputTree + + //@} + + private : + + + string fTMVAWeightPath;;//!<The weight needed by TMVA to construct and execute the multilayer perceptron + +}; + +#endif + diff --git a/source/branches/BaM/Model/Equivalence/EQM_PWR_MLP_MOX_Am.cxx b/source/branches/BaM/Model/Equivalence/EQM_PWR_MLP_MOX_Am.cxx new file mode 100755 index 000000000..d6e914c4a --- /dev/null +++ b/source/branches/BaM/Model/Equivalence/EQM_PWR_MLP_MOX_Am.cxx @@ -0,0 +1,203 @@ +#include "EquivalenceModel.hxx" +#include "EQM_PWR_MLP_MOX_Am.hxx" +#include "CLASSLogger.hxx" +#include "StringLine.hxx" + +#include <string> +#include <iostream> +#include <fstream> +#include <algorithm> +#include <cmath> +#include <cassert> + +#include "TSystem.h" +#include "TMVA/Reader.h" +#include "TMVA/Tools.h" +#include "TMVA/MethodCuts.h" + + +//________________________________________________________________________ +// +// EQM_PWR_MLP_MOX_AM +// +// Equivalenve Model based on multi layer perceptron from TMVA (root cern) +// For REP MOX use +// +//________________________________________________________________________ + +EQM_PWR_MLP_MOX_AM::EQM_PWR_MLP_MOX_AM(string TMVAWeightPath):EquivalenceModel(new CLASSLogger("EQM_PWR_MLP_MOX_AM.log")) +{ + fTMVAWeightPath = TMVAWeightPath; + + ZAI U8(92,238,0); + ZAI U5(92,235,0); + double U5_enrich = 0.0025; + + ZAI Pu8(94,238,0); + ZAI Pu9(94,239,0); + ZAI Pu0(94,240,0); + ZAI Pu1(94,241,0); + ZAI Pu2(94,242,0); + ZAI Am1(95,241,0); + ZAI Am2(95,242,1); + ZAI Am3(95,243,0); + + fFissileList = Pu8*1 + Pu9*1 + Pu0*1 + Pu1*1 + Pu2*1 + Am1*1 + Am2*1 + Am3*1; + fFertileList = U5*U5_enrich + U8*(1-U5_enrich); + + SetBuildFuelFirstGuess(0.04); + + INFO << "__An equivalence model of PWR MOX has been define__" << endl; + INFO << "\tThis model is based on a multi layer perceptron" << endl; + INFO << "\t\tThe TMVA weight file is :" << endl; + INFO << "\t\t\t"<<fTMVAWeightPath << endl; + EquivalenceModel::PrintInfo(); + +} + +//________________________________________________________________________ +EQM_PWR_MLP_MOX_AM::EQM_PWR_MLP_MOX_AM(CLASSLogger* log, string TMVAWeightPath):EquivalenceModel(log) +{ + fTMVAWeightPath = TMVAWeightPath; + + ZAI U8(92,238,0); + ZAI U5(92,235,0); + double U5_enrich = 0.0025; + + ZAI Pu8(94,238,0); + ZAI Pu9(94,239,0); + ZAI Pu0(94,240,0); + ZAI Pu1(94,241,0); + ZAI Pu2(94,242,0); + ZAI Am1(95,241,0); + ZAI Am2(95,242,1); + ZAI Am3(95,243,0); + + fFissileList = Pu8*1 + Pu9*1 + Pu0*1 + Pu1*1 + Pu2*1 + Am1*1 + Am2*1 + Am3*1; + fFertileList = U5*U5_enrich + U8*(1-U5_enrich); + + SetBuildFuelFirstGuess(0.04); + + INFO << "__An equivalence model of PWR MOX has been define__" << endl; + INFO << "\tThis model is based on a multi layer perceptron" << endl; + INFO << "\t\tThe TMVA weight file is :" << endl; + INFO << "\t\t\t"<<fTMVAWeightPath << endl; + EquivalenceModel::PrintInfo(); + +} + +//________________________________________________________________________ +TTree* EQM_PWR_MLP_MOX_AM::CreateTMVAInputTree(IsotopicVector Fissil,IsotopicVector Fertil,double BurnUp) +{ + TTree* InputTree = new TTree("EQTMP", "EQTMP"); + float Pu8 = 0; + float Pu9 = 0; + float Pu10 = 0; + float Pu11 = 0; + float Pu12 = 0; + float Am1 = 0; + float Am2 = 0; + float Am3 = 0; + float U5_enrichment = 0; + float BU = 0; + + InputTree->Branch( "Pu8" ,&Pu8 ,"Pu8/F" ); + InputTree->Branch( "Pu9" ,&Pu9 ,"Pu9/F" ); + InputTree->Branch( "Pu10" ,&Pu10 ,"Pu10/F" ); + InputTree->Branch( "Pu11" ,&Pu11 ,"Pu11/F" ); + InputTree->Branch( "Pu12" ,&Pu12 ,"Pu12/F" ); + InputTree->Branch( "Am1" ,&Am1 ,"Am1/F" ); + InputTree->Branch( "Am2" ,&Am2 ,"Am2/F" ); + InputTree->Branch( "Am3" ,&Am3 ,"Am3/F" ); + InputTree->Branch( "U5_enrichment" ,&U5_enrichment ,"U5_enrichment/F" ); + InputTree->Branch( "BU" ,&BU ,"BU/F" ); + + + float U8 = Fertil.GetZAIIsotopicQuantity(92,238,0); + float U5 = Fertil.GetZAIIsotopicQuantity(92,235,0); + float U4 = Fertil.GetZAIIsotopicQuantity(92,234,0); + + float UTOT = U8 + U5 + U4; + + Pu8 = Fissil.GetZAIIsotopicQuantity(94,238,0); + Pu9 = Fissil.GetZAIIsotopicQuantity(94,239,0); + Pu10 = Fissil.GetZAIIsotopicQuantity(94,240,0); + Pu11 = Fissil.GetZAIIsotopicQuantity(94,241,0); + Pu12 = Fissil.GetZAIIsotopicQuantity(94,242,0); + Am1 = Fissil.GetZAIIsotopicQuantity(95,241,0); + Am2 = Fissil.GetZAIIsotopicQuantity(95,242,1); + Am3 = Fissil.GetZAIIsotopicQuantity(95,243,0); + + double TOTPU = (Pu8+Pu9+Pu10+Pu11+Pu12+Am1+Am2+Am3); + + Pu8 = Pu8 / TOTPU; + Pu9 = Pu9 / TOTPU; + Pu10 = Pu10 / TOTPU; + Pu11 = Pu11 / TOTPU; + Pu12 = Pu12 / TOTPU; + Am1 = Am1 / TOTPU; + Am2 = Am2 / TOTPU; + Am3 = Am3 / TOTPU; + + U5_enrichment = U5 / UTOT; + + BU = BurnUp; + if(Pu8 + Pu9 + Pu10 + Pu11 + Pu12 + Am1 + Am2 + Am3 > 1.00001 )//?????1.00001??? I don't know it! goes in condition if = 1 !! may be float/double issue ... + { + ERROR << Pu8 << " " << Pu9 << " " << Pu10 << " " << Pu11 << " " << Pu12 << " " << Am1 << " " << Am2 << " " << Am3 << endl; + exit(0); + } + // All value are molar (!weight) + + InputTree->Fill(); + return InputTree; +} +//________________________________________________________________________ +double EQM_PWR_MLP_MOX_AM::ExecuteTMVA(TTree* theTree) +{ + // --- Create the Reader object + TMVA::Reader *reader = new TMVA::Reader( "Silent" ); + // Create a set of variables and declare them to the reader + // - the variable names MUST corresponds in name and type to those given in the weight file(s) used + Float_t Pu8,Pu9,Pu10,Pu11,Pu12,Am1, Am2,Am3,BU,U5_enrichment; + + reader->AddVariable( "BU" ,&BU ); + reader->AddVariable( "U5_enrichment",&U5_enrichment ); + reader->AddVariable( "Pu8" ,&Pu8 ); + reader->AddVariable( "Pu9" ,&Pu9 ); + reader->AddVariable( "Pu10" ,&Pu10); + reader->AddVariable( "Pu11" ,&Pu11); + reader->AddVariable( "Pu12" ,&Pu12); + reader->AddVariable( "Am1" ,&Am1 ); + reader->AddVariable( "Am2" ,&Am2 ); + reader->AddVariable( "Am3" ,&Am3 ); + + // --- Book the MVA methods + + // Book method MLP + TString methodName = "MLP method"; + reader->BookMVA( methodName, fTMVAWeightPath ); + theTree->SetBranchAddress( "BU" ,&BU ); + theTree->SetBranchAddress( "U5_enrichment" ,&U5_enrichment ) ; + theTree->SetBranchAddress( "Pu8" ,&Pu8 ); + theTree->SetBranchAddress( "Pu9" ,&Pu9 ); + theTree->SetBranchAddress( "Pu10" ,&Pu10 ); + theTree->SetBranchAddress( "Pu11" ,&Pu11 ); + theTree->SetBranchAddress( "Pu12" ,&Pu12 ); + theTree->SetBranchAddress( "Am1" ,&Am1 ); + theTree->SetBranchAddress( "Am2" ,&Am2 ); + theTree->SetBranchAddress( "Am3" ,&Am3 ); + theTree->GetEntry(0); + + Float_t val = (reader->EvaluateRegression( methodName ))[0]; + + delete reader; + delete theTree; + + return (double)val; //retourne teneur +} +//________________________________________________________________________ +double EQM_PWR_MLP_MOX_AM::GetFissileMolarFraction(IsotopicVector Fissil,IsotopicVector Fertil,double BurnUp) +{DBGL + return ExecuteTMVA(CreateTMVAInputTree(Fissil,Fertil,BurnUp)); +} diff --git a/source/branches/BaM/Model/Equivalence/EQM_PWR_MLP_MOX_Am.hxx b/source/branches/BaM/Model/Equivalence/EQM_PWR_MLP_MOX_Am.hxx new file mode 100755 index 000000000..f742c9220 --- /dev/null +++ b/source/branches/BaM/Model/Equivalence/EQM_PWR_MLP_MOX_Am.hxx @@ -0,0 +1,77 @@ +#ifndef _EQM_PWR_MLP_MOX_AM_HXX +#define _EQM_PWR_MLP_MOX_AM_HXX + +#include "EquivalenceModel.hxx" +#include "TTree.h" + +using namespace std; + +//-----------------------------------------------------------------------------// +//! Defines an EquivalenceModel based on neural network + +/*! + The aim of these class is to constuct a fuel from an equivalence model + based on a Multi layer perceptron + + @author BLG + @version 3.0 + */ +//________________________________________________________________________ + +class EQM_PWR_MLP_MOX_AM : public EquivalenceModel +{ + public : + /*! + \name Constructor + */ + //@{ + + //{ + /// normal constructor + /*! + Create a EQM_PWR_MLP_MOX_AM + \param TMVAWeightPath : PAth to the .xml file containing neural network informations : PATH/TMVAWeight.xml (total path to tmva weight) + */ + EQM_PWR_MLP_MOX_AM(string TMVAWeightPath); + //} + + //{ + /// Logger constructor + /*! + Create a EQM_PWR_MLP_MOX_AM + \param log : use for log + \param TMVAWeightPath : PAth to the .xml file containing neural network informations : PATH/TMVAWeight.xml (total path to tmva weight) + */ + EQM_PWR_MLP_MOX_AM(CLASSLogger* log, string TMVAWeightPath); + //} + //@} + + //{ + /// Return the molar fissile fraction according fissile & ferile content using a Multi Layer Peceptron (MLP) + /*! + \param Fissil : The composition of the fissile matter + \param Fertil : The composition of the Fertil matter + \param BurnUp : Maximum achievable burn up envisaged + */ + virtual double GetFissileMolarFraction(IsotopicVector Fissil,IsotopicVector Fertil,double BurnUp); + //} + + /*! + \name TMVA related methods + */ + //@{ + + TTree* CreateTMVAInputTree(IsotopicVector Fissil,IsotopicVector Fertil,double BurnUp);//!<Create input tmva tree to be read by ExecuteTMVA + double ExecuteTMVA(TTree* theTree);//!<Execute the MLP according to the input tree created by CreateTMVAInputTree + + //@} + + private : + + + string fTMVAWeightPath;;//!<The weight needed by TMVA to construct and execute the multilayer perceptron + +}; + +#endif + diff --git a/source/branches/BaM/Model/Equivalence/EQM_PWR_POL_UO2.cxx b/source/branches/BaM/Model/Equivalence/EQM_PWR_POL_UO2.cxx new file mode 100644 index 000000000..0c25731ef --- /dev/null +++ b/source/branches/BaM/Model/Equivalence/EQM_PWR_POL_UO2.cxx @@ -0,0 +1,78 @@ +#include "EquivalenceModel.hxx" +#include "EQM_PWR_POL_UO2.hxx" +#include "CLASSLogger.hxx" +#include "StringLine.hxx" + + +// ________________________________________________________________________ +// EQM_PWR_POL_UO2 +// +// ________________________________________________________________________ + + + + +//Constructor(s) +EQM_PWR_POL_UO2::EQM_PWR_POL_UO2(string PathToWeightFile):EquivalenceModel(new CLASSLogger("EQM_PWR_POL_UO2.log")) +{ + + // Fertile + ZAI U8(92 ,238 ,0) ; + fFertileList = U8*1; + // Fissile + ZAI U5(92 ,235 ,0) ; + // ... + fFissileList = U5*1; + + ReadWeightFile(PathToWeightFile); + EquivalenceModel::PrintInfo(); + +} +// _______________________________________________________________________ +EQM_PWR_POL_UO2::EQM_PWR_POL_UO2(CLASSLogger* log,string PathToWeightFile):EquivalenceModel(log) +{ + + // Fertile + ZAI U8(92 ,238 ,0) ; + fFertileList = U8*1; + // Fissile + ZAI U5(92 ,235 ,0) ; + // ... + fFissileList = U5*1; + + ReadWeightFile(PathToWeightFile); + EquivalenceModel::PrintInfo(); + +} +// _______________________________________________________________________ +void EQM_PWR_POL_UO2::ReadWeightFile(string PathToWeightFile) +{ + ifstream DataDB(PathToWeightFile.c_str()); // Open the File + if(!DataDB) + WARNING << " Can't open \"" << PathToWeightFile << "\"" << endl; + + string line; + int start = 0; // First Get Fuel Parameter + getline(DataDB, line); + + if( StringLine::NextWord(line, start, ' ') != "PARAM") + { + ERROR << "Bad Database file : " << PathToWeightFile << " Can't find the Parameter of the DataBase " << endl; + exit (1); + } + fParam_Bu_0 = atof(StringLine::NextWord(line, start, ' ').c_str()) ; + fParam_Bu = atof(StringLine::NextWord(line, start, ' ').c_str()); + fParam_BuSquare = atof(StringLine::NextWord(line, start, ' ').c_str()); + + INFO << "Weight parameters has been read " << endl; + INFO << "\t U enrichment = " << fParam_Bu_0 << " + " << fParam_Bu << "*Burnup + " << fParam_BuSquare << "*Burnup*Burnup" << endl; +} +// _______________________________________________________________________ +double EQM_PWR_POL_UO2::GetFissileMolarFraction ( IsotopicVector Fissil , IsotopicVector Fertil , double BurnUp ) +{ + double Fraction = fParam_Bu_0 + fParam_Bu*BurnUp + fParam_BuSquare*BurnUp*BurnUp; + DBGV("Fissile molar fraction : "<<Fraction) + + return Fraction ; + +} \ No newline at end of file diff --git a/source/branches/BaM/Model/Equivalence/EQM_PWR_POL_UO2.hxx b/source/branches/BaM/Model/Equivalence/EQM_PWR_POL_UO2.hxx new file mode 100644 index 000000000..d6b855dd5 --- /dev/null +++ b/source/branches/BaM/Model/Equivalence/EQM_PWR_POL_UO2.hxx @@ -0,0 +1,69 @@ +#ifndef _EQM_PWR_POL_UO2_HXX +#define _EQM_PWR_POL_UO2_HXX + +#include "EquivalenceModel.hxx" + +using namespace std; + +//−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−--------------−−−−−−−−−−−−−−−// +//! Define an EquivalenceModel based on a polynomial fit + +/*! + Defines a EQM_PWR_POL_UO2 + It returns the @f$^{235}U@f$ enrichment e according to this polynom : + + @f$e = \alpha_{0} + \alpha_{1}\cdot Burnup + \alpha_{2}\cdot Burnup \cdot Burnup @f$ + + BU : Maximum achievable burnup + + @author BaM + @version 3.0 + */ +//________________________________________________________________________ + +class EQM_PWR_POL_UO2 : public EquivalenceModel +{ + +public: + /*! + \name Constructor + */ + //@{ + + //{ + /// normal constructor + /*! + Create a EQM_PWR_POL_UO2 + \param PathToWeightFile : Path to the file containing the @f$\alpha_{i}@f$ + Format : @f$PARAM@f$ @f$\alpha_{0}@f$ @f$\alpha_{1}@f$ @f$\alpha_{2}@f$ + */ + EQM_PWR_POL_UO2(string PathToWeightFile); + //} + + //{ + /// logger constructor + /*! + Create a EQM_PWR_POL_UO2 + \param log : Use for the log + \param PathToWeightFile : Path to the file containing the @f$\alpha_{i}@f$ + Format : @f$PARAM@f$ @f$\alpha_{0}@f$ @f$\alpha_{1}@f$ @f$\alpha_{2}@f$ + */ + EQM_PWR_POL_UO2(CLASSLogger* log, string PathToWeightFile); + //} + + //@} + /**This function IS the equivalence model**/ + double GetFissileMolarFraction(IsotopicVector Fissil, IsotopicVector Fertil,double BurnUp) ; // !<Return the molar fraction of fissile element + + +private: + + void ReadWeightFile(string PathToWeightFile); //!< Function to read the weight file & file the parameters + + double fParam_Bu_0 ; //!< @f$\alpha_{0}@f$ + double fParam_Bu ; //!< @f$\alpha_{1}@f$ + double fParam_BuSquare ; //!< @f$\alpha_{2}@f$ + +}; + +#endif \ No newline at end of file diff --git a/source/branches/BaM/Model/Equivalence/EQM_PWR_QUAD_MOX.cxx b/source/branches/BaM/Model/Equivalence/EQM_PWR_QUAD_MOX.cxx new file mode 100644 index 000000000..5f984d08f --- /dev/null +++ b/source/branches/BaM/Model/Equivalence/EQM_PWR_QUAD_MOX.cxx @@ -0,0 +1,141 @@ +#include "EQM_PWR_QUAD_MOX.hxx" + +#include <vector> + +#include "StringLine.hxx" +#include "CLASSLogger.hxx" + + + + +EQM_PWR_QUAD_MOX::EQM_PWR_QUAD_MOX(string WeightPath):EquivalenceModel(new CLASSLogger("EQM_PWR_QUAD_MOX.log")) +{ + fWeightPath = WeightPath; + + ifstream DataDB(fWeightPath.c_str()); // Open the File + if(!DataDB) + WARNING << " Can't open \"" << fWeightPath << "\"" << endl; + + string line; + int start = 0; // First Get Fuel Parameter + getline(DataDB, line); + + if( StringLine::NextWord(line, start, ' ') != "PARAM") + { + ERROR << "Bad Database file : " << fWeightPath << " Can't find the Parameter of the DataBase " << endl; + exit (1); + } + while(start < (int)line.size()) + fFuelParameter.push_back(atof(StringLine::NextWord(line, start, ' ').c_str())); + + INFO << fFuelParameter.size() << " have been read " << endl; + + + ZAI U8(92,238,0); + ZAI U5(92,235,0); + double U5_enrich = 0.0025; + fFertileList = U5*U5_enrich + U8*(1-U5_enrich); + + + ZAI Pu8(94,238,0); + ZAI Pu9(94,239,0); + ZAI Pu0(94,240,0); + ZAI Pu1(94,241,0); + ZAI Pu2(94,242,0); + fFissileList = Pu8*1+Pu9*1+Pu0*1+Pu1*1+Pu2*1; + + SetBuildFuelFirstGuess(0.04); + EquivalenceModel::PrintInfo(); + + +} + +EQM_PWR_QUAD_MOX::EQM_PWR_QUAD_MOX(CLASSLogger* log, string WeightPath):EquivalenceModel(log) +{ + fWeightPath = WeightPath; + + ifstream DataDB(fWeightPath.c_str()); // Open the File + if(!DataDB) + WARNING << " Can't open \"" << fWeightPath << "\"" << endl; + + string line; + int start = 0; // First Get Fuel Parameter + getline(DataDB, line); + + if( StringLine::NextWord(line, start, ' ') != "PARAM") + { + ERROR << "Bad Database file : " << fWeightPath << " Can't find the Parameter of the DataBase " << endl; + exit (1); + } + while(start < (int)line.size()) + fFuelParameter.push_back(atof(StringLine::NextWord(line, start, ' ').c_str())); + + INFO << fFuelParameter.size() << " have been read " << endl; + + + ZAI U8(92,238,0); + ZAI U5(92,235,0); + double U5_enrich = 0.0025; + fFertileList = U5*U5_enrich + U8*(1-U5_enrich); + + + ZAI Pu8(94,238,0); + ZAI Pu9(94,239,0); + ZAI Pu0(94,240,0); + ZAI Pu1(94,241,0); + ZAI Pu2(94,242,0); + fFissileList = Pu8*1+Pu9*1+Pu0*1+Pu1*1+Pu2*1; + + SetBuildFuelFirstGuess(0.04); + EquivalenceModel::PrintInfo(); + +} + + + +EQM_PWR_QUAD_MOX::~EQM_PWR_QUAD_MOX() +{ + +} + + + + +double EQM_PWR_QUAD_MOX::GetFissileMolarFraction(IsotopicVector Fissile,IsotopicVector Fertile,double BurnUp) +{ + + + ZAI ZAIList[6] = {ZAI(94,238,0), ZAI(94,239,0), ZAI(94,240,0), ZAI(94,241,0), ZAI(94,242,0), ZAI(95,241,0) }; + + vector<double> PuCompo; + double Sum = Fissile.GetSumOfAll(); + + + for(int i = 0; i< 5; i++) + PuCompo.push_back( Fissile.GetZAIIsotopicQuantity(ZAIList[i])/Sum); + + PuCompo[2] += Fissile.GetZAIIsotopicQuantity(ZAIList[5])/Sum; + double A = 0; + + if(PuCompo[0] <= PuCompo[2] && PuCompo[0] <= PuCompo[4] && PuCompo[1] + PuCompo[3] >= 0.40 && PuCompo[1] >0 ) + { + int par = 0; + for(int j = 0 ; j < 5 ; j++) + { + A += fFuelParameter[par] * PuCompo[j] ; + par++; + for(int i = j ; i < 5 ; i++) + { + A += fFuelParameter[par] *PuCompo[i] *PuCompo[j]; + par++; + } + } + A += fFuelParameter[par]; + } + else + { + cout << "the composition is not in the range of the Model" << endl; + } + return A; +} + diff --git a/source/branches/BaM/Model/Equivalence/EQM_PWR_QUAD_MOX.hxx b/source/branches/BaM/Model/Equivalence/EQM_PWR_QUAD_MOX.hxx new file mode 100644 index 000000000..94bbe4c65 --- /dev/null +++ b/source/branches/BaM/Model/Equivalence/EQM_PWR_QUAD_MOX.hxx @@ -0,0 +1,70 @@ +#ifndef _EQM_PWR_QUAD_MOX_HXX +#define _EQM_PWR_QUAD_MOX_HXX + +#include "EquivalenceModel.hxx" + +#include <string> + +using namespace std; + +//-----------------------------------------------------------------------------// +//! Defines an EquivalenceModel based on a quadratic fit + +/*! + The aim of these class is to constuct a fuel from an equivalence model + based on a Quadratic Pu equivalent Model + The Plutonium content e is calculated using : + + @f$ e = \alpha_{0} + \sum_{i\in Pu}^{N} \left(\alpha_{i} \cdot n_{i}\ + \sum_{j\leq i} \alpha_{ij} \cdot n_{i}\cdot n_{j}\right)@f$ + + @author BaM + @version 3.0 + */ +//________________________________________________________________________ + +class EQM_PWR_QUAD_MOX : public EquivalenceModel +{ + public : + + /*! + \name Constructor + */ + //@{ + + //{ + /// normal constructor + /*! + Create a EQM_PWR_POL_UO2 + \param WeightPath : Path to the file containing the @f$\alpha_{i}@f$ + Format : @f$PARAM@f$ @f$\alpha_{^{238}Pu}@f$ @f$\alpha_{^{238}Pu ^{238}Pu}@f$ @f$\alpha_{^{238}Pu ^{239}Pu}@f$ .... @f$\alpha_{^{238}Pu ^{242}Pu}@f$ @f$\alpha_{^{239}Pu}@f$ ... + @f$\alpha_{^{242}Pu}@f$ @f$\alpha_{^{242}Pu ^{242}Pu}@f$ @f$\alpha_{0}@f$ + */ + EQM_PWR_QUAD_MOX(string WeightPath); + //} + + //{ + /// Logger constructor + /*! + Create a EQM_PWR_POL_UO2 + \param log : Use for the log + \param WeightPath : Path to the file containing the @f$\alpha_{i}@f$ + Format : @f$PARAM@f$ @f$\alpha_{^{238}Pu}@f$ @f$\alpha_{^{238}Pu ^{238}Pu}@f$ @f$\alpha_{^{238}Pu ^{239}Pu}@f$ .... @f$\alpha_{^{238}Pu ^{242}Pu}@f$ @f$\alpha_{^{239}Pu}@f$ ... + @f$\alpha_{^{242}Pu}@f$ @f$\alpha_{^{242}Pu ^{242}Pu}@f$ @f$\alpha_{0}@f$ + */ + EQM_PWR_QUAD_MOX(CLASSLogger* log, string WeightPath); + //} + + ~EQM_PWR_QUAD_MOX(); + //@} + + virtual double GetFissileMolarFraction(IsotopicVector Fissil,IsotopicVector Fertil,double BurnUp); + + private : + + string fWeightPath; //!< Path to the file containing the @f$\alpha_{ij}@f$ + vector<double> fFuelParameter; //!< vector containing the @f$\alpha_{ij}@f$ + +}; + +#endif + diff --git a/source/branches/BaM/Model/Irradiation/IM_Matrix.cxx b/source/branches/BaM/Model/Irradiation/IM_Matrix.cxx new file mode 100644 index 000000000..4b08351d8 --- /dev/null +++ b/source/branches/BaM/Model/Irradiation/IM_Matrix.cxx @@ -0,0 +1,301 @@ +// +// IM_Matrix.cxx +// CLASSSource +// +// Created by BaM on 04/05/2014. +// Copyright (c) 2014 BaM. All rights reserved. +// + +#include "IM_Matrix.hxx" + +#include "IsotopicVector.hxx" +#include "CLASSConstante.hxx" +#include "CLASSLogger.hxx" +#include "StringLine.hxx" + +#include <TGraph.h> +#include <TString.h> + + +#include <sstream> +#include <string> +#include <iostream> +#include <fstream> +#include <algorithm> +#include <cmath> + + + +using namespace std; + + +//________________________________________________________________________ +IM_Matrix::IM_Matrix():IrradiationModel(new CLASSLogger("IM_Matrix.log")) +{ + fShorstestHalflife = 3600.*24*160.; //cut by default all nuclei with a shorter liftime than the Cm242 -> remain 33 actinides +} + + +IM_Matrix::IM_Matrix(CLASSLogger* log):IrradiationModel(log) +{ + fShorstestHalflife = 3600.*24*160.; //cut by default all nuclei with a shorter liftime than the Cm242 -> remain 33 actinides +} + + + + +//________________________________________________________________________ +/* Evolution Calculation */ +//________________________________________________________________________ +EvolutionData IM_Matrix::GenerateEvolutionData(IsotopicVector isotopicvector, EvolutionData XSSet, double Power, double cycletime) +{ + DBGL + if(fFastDecay.size() == 0) + NuclearDataInitialization(); + + + string ReactorType; + + + vector< TMatrixT<double> > NMatrix ;// TMatrixT<double>(decayindex.size(),1)) + { // Filling the t = 0 State; + map<ZAI, double > isotopicquantity = isotopicvector.GetIsotopicQuantity(); + TMatrixT<double> N_0Matrix = TMatrixT<double>( fReverseMatrixIndex.size(),1) ; + for(int i = 0; i < (int)fReverseMatrixIndex.size(); i++) + N_0Matrix[i] = 0; + + map<ZAI, double >::iterator it ; + for(int i = 0; i < (int)fReverseMatrixIndex.size(); i++) + N_0Matrix[i] = 0; + + for(it = isotopicquantity.begin(); it != isotopicquantity.end(); it++) + { + /// Need TO change with FP managment + map<ZAI, int >::iterator it2; + + if( (*it).first.Z() < fZAIThreshold ) + it2 = fMatrixIndex.find( ZAI(-2,-2,-2) ); + else it2 = fMatrixIndex.find( (*it).first ); + + if(it2 == fMatrixIndex.end() ) //If not in index should be TMP, can't be fast decay for new Fuel !!! + it2 = fMatrixIndex.find( ZAI(-3,-3,-3) ); + N_0Matrix[ (*it2).second ][0] = (*it).second ; + + + } + + isotopicquantity.clear(); + + NMatrix.push_back(N_0Matrix); + N_0Matrix.Clear(); + + } + + + //-------------------------// + //--- Perform Evolution ---// + //-------------------------// + ReactorType = XSSet.GetReactorType(); + + double M_ref = XSSet.GetHeavyMetalMass(); + double M = cZAIMass.GetMass(isotopicvector.GetActinidesComposition()); + double Power_ref = XSSet.GetPower(); + + int NStep = XSSet.GetFissionXS().begin()->second->GetN(); + double* DBTimeStep = XSSet.GetFissionXS().begin()->second->GetX(); + + int InsideStep = 10; + + double timevector[NStep]; + timevector[0] = 0; + + double Flux[NStep]; + + TMatrixT<double> FissionEnergy = TMatrixT<double>(fReverseMatrixIndex.size(),1); + for(int i = 0; i < (int)fReverseMatrixIndex.size(); i++) + FissionEnergy[i] = 0; + + { + map< ZAI, int >::iterator it; + for(it = fMatrixIndex.begin(); it != fMatrixIndex.end(); it++) + { + map< ZAI, double >::iterator it2 = fFissionEnergy.find(it->first); + if(it2 == fFissionEnergy.end()) + { + if(it->first.Z() > fZAIThreshold) + FissionEnergy[it->second][0] = 1.9679e6*it->first.A()-2.601e8; // //simple linear fit to known values ;extrapolation to unknown isotopes + else FissionEnergy[it->second][0] = 0; + } + else + FissionEnergy[it->second][0] = it2->second; + + } + } + + vector< TMatrixT<double> > FissionXSMatrix; // Store The Fisison XS Matrix + vector< TMatrixT<double> > CaptureXSMatrix; // Store The Capture XS Matrix + vector< TMatrixT<double> > n2nXSMatrix; // Store The n2N XS Matrix + DBGL + for(int i = 0; i < NStep-1; i++) + { + double TStepMax = ( (DBTimeStep[i+1]-DBTimeStep[i] ) ) * Power_ref/M_ref / Power*M ; // Get the next Time step + + + TMatrixT<double> BatemanMatrix = TMatrixT<double>(fReverseMatrixIndex.size(),fReverseMatrixIndex.size()); + TMatrixT<double> BatemanReactionMatrix = TMatrixT<double>(fReverseMatrixIndex.size(),fReverseMatrixIndex.size()); + + TMatrixT<double> NEvolutionMatrix = TMatrixT<double>(fReverseMatrixIndex.size(),1); + NEvolutionMatrix = NMatrix.back(); + + + + FissionXSMatrix.push_back(GetFissionXsMatrix(XSSet, DBTimeStep[i])); //Feel the fission reaction Matrix + CaptureXSMatrix.push_back(GetCaptureXsMatrix(XSSet, DBTimeStep[i])); //Feel the capture reaction Matrix + n2nXSMatrix.push_back(Getn2nXsMatrix(XSSet, DBTimeStep[i])); //Feel the (n,2n) reaction Matrix + + // ---------------- Evolution + + BatemanReactionMatrix = FissionXSMatrix[i]; + BatemanReactionMatrix += CaptureXSMatrix[i]; + BatemanReactionMatrix += n2nXSMatrix[i]; + + for(int k = 0; k < InsideStep; k++) + { + double ESigmaN = 0; + for (int j = 0; j < (int)fReverseMatrixIndex.size() ; j++) + ESigmaN -= FissionXSMatrix[i][j][j]*NEvolutionMatrix[j][0]*1.6e-19*FissionEnergy[j][0]; + // Update Flux + double Flux_k = Power/ESigmaN; + + if(k == 0) + Flux[i] = Flux_k; + + BatemanMatrix = BatemanReactionMatrix; + BatemanMatrix *= Flux_k; + BatemanMatrix += fDecayMatrix ; + BatemanMatrix *= TStepMax/InsideStep ; + + + TMatrixT<double> IdMatrix = TMatrixT<double>(fReverseMatrixIndex.size(),fReverseMatrixIndex.size()); + for(int j = 0; j < (int)fReverseMatrixIndex.size(); j++) + for(int k = 0; k < (int)fReverseMatrixIndex.size(); k++) + { + if(k == j) IdMatrix[j][k] = 1; + else IdMatrix[j][k] = 0; + } + + + TMatrixT<double> BatemanMatrixDL = TMatrixT<double>(fReverseMatrixIndex.size(),fReverseMatrixIndex.size()); // Order 0 Term from the DL : Id + TMatrixT<double> BatemanMatrixDLTermN = TMatrixT<double>(fReverseMatrixIndex.size(),fReverseMatrixIndex.size()); // Addind it; + + { + BatemanMatrix *= TStepMax ; + BatemanMatrixDLTermN = IdMatrix; + BatemanMatrixDL = BatemanMatrixDLTermN; + int j = 1; + double NormN; + + do + { + TMatrixT<double> BatemanMatrixDLTermtmp = TMatrixT<double>(fReverseMatrixIndex.size(),fReverseMatrixIndex.size()); // Adding it; + BatemanMatrixDLTermtmp = BatemanMatrixDLTermN; + + BatemanMatrixDLTermN.Mult(BatemanMatrixDLTermtmp, BatemanMatrix ); + + BatemanMatrixDLTermN *= 1./j; + BatemanMatrixDL += BatemanMatrixDLTermN; + + NormN = 0; + for(int m = 0; m < (int)fReverseMatrixIndex.size(); m++) + for(int n = 0; n < (int)fReverseMatrixIndex.size(); n++) + NormN += BatemanMatrixDLTermN[m][n]*BatemanMatrixDLTermN[m][n]; + j++; + + } while ( NormN != 0 ); + } + NEvolutionMatrix = BatemanMatrixDL * NEvolutionMatrix ; + } + NMatrix.push_back(NEvolutionMatrix); + + + timevector[i+1] = timevector[i] + TStepMax; + + BatemanMatrix.Clear(); + BatemanReactionMatrix.Clear(); + NEvolutionMatrix.Clear(); + + + } + DBGL + FissionXSMatrix.push_back(GetFissionXsMatrix(XSSet, DBTimeStep[NStep-1])); //Feel the reaction Matrix + CaptureXSMatrix.push_back(GetCaptureXsMatrix(XSSet, DBTimeStep[NStep-1])); //Feel the reaction Matrix + n2nXSMatrix.push_back(Getn2nXsMatrix(XSSet, DBTimeStep[NStep-1])); //Feel the reaction Matrix + + + EvolutionData GeneratedDB = EvolutionData(GetLog()); + + double ESigmaN = 0; + for (int j = 0; j < (int)fReverseMatrixIndex.size() ; j++) + ESigmaN -= FissionXSMatrix.back()[j][j]*NMatrix.back()[j][0]*1.6e-19*FissionEnergy[j][0]; + + Flux[NStep-1] = Power/ESigmaN; + + GeneratedDB.SetFlux( new TGraph(NStep, timevector, Flux) ); + + for(int i = 0; i < (int)fReverseMatrixIndex.size(); i++) + { + double ZAIQuantity[NMatrix.size()]; + double FissionXS[NStep]; + double CaptureXS[NStep]; + double n2nXS[NStep]; + for(int j = 0; j < (int)NMatrix.size(); j++) + ZAIQuantity[j] = (NMatrix[j])[i][0]; + + for(int j = 0; j < NStep; j++) + { + FissionXS[j] = FissionXSMatrix[j][i][i]; + CaptureXS[j] = CaptureXSMatrix[j][i][i]; + n2nXS[j] = n2nXSMatrix[j][i][i]; + } + + GeneratedDB.NucleiInsert(pair<ZAI, TGraph*> (fReverseMatrixIndex[i], new TGraph(NMatrix.size(), timevector, ZAIQuantity))); +/* GeneratedDB.FissionXSInsert(pair<ZAI, TGraph*> (fReverseMatrixIndex[i], new TGraph(NStep, timevector, FissionXS))); + GeneratedDB.CaptureXSInsert(pair<ZAI, TGraph*> (fReverseMatrixIndex[i], new TGraph(NStep, timevector, CaptureXS))); + GeneratedDB.n2nXSInsert(pair<ZAI, TGraph*> (fReverseMatrixIndex[i], new TGraph(NStep, timevector, n2nXS))); +*/ } + + GeneratedDB.SetPower(Power ); + GeneratedDB.SetHeavyMetalMass(M); + GeneratedDB.SetReactorType(ReactorType ); + GeneratedDB.SetCycleTime(cycletime); + + for (int i = 0; i < (int) FissionXSMatrix.size(); i++) + { + FissionXSMatrix[i].Clear(); + CaptureXSMatrix[i].Clear(); + n2nXSMatrix[i].Clear(); + } + FissionXSMatrix.clear(); + CaptureXSMatrix.clear(); + n2nXSMatrix.clear(); + DBGL + return GeneratedDB; + +} + + + + + + + + + + + + + + + + + diff --git a/source/branches/BaM/Model/Irradiation/IM_Matrix.hxx b/source/branches/BaM/Model/Irradiation/IM_Matrix.hxx new file mode 100644 index 000000000..7bc03449a --- /dev/null +++ b/source/branches/BaM/Model/Irradiation/IM_Matrix.hxx @@ -0,0 +1,83 @@ +#ifndef _IMMATRIX_ +#define _IMMATRIX_ + + +/*! + \file + \brief Header file for IrradiationModel class. + + + @author BaM + @version 2.0 + */ +#include "IrradiationModel.hxx" + + +using namespace std; + + +class CLASSLogger; + +//-----------------------------------------------------------------------------// +//! Defines an IrradiationModel based on power series of the exponential of the Bateman matrix + +/*! + Define a IM_Matrix. + The aim of these class is to solve numericaly the Bateman equations using the + development in a power series of the exponential of the Bateman matrix. + + @author BaM + @version 3.0 + */ +//________________________________________________________________________ + +class EvolutionData; + +class IM_Matrix : public IrradiationModel +{ + + public : + /*! + \name Constructor + */ + //@{ + + //{ + /// Default constructor + + /*! + Make a new IM_Matrix : */ + IM_Matrix(); + //} + + /// Logger constructor + + /*! + Make a new IM_Matrix : */ + //param log : Use for the log + IM_Matrix(CLASSLogger* log); + //} + + //@} + + + /// virtual method called to perform the irradiation calculation using a set of cross section. + /*! + Perform the Irradiation Calcultion using the XSSet data + \param IsotopicVector IV isotopic vector to irradiate + \param EvolutionData XSSet set of corss section to use to perform the evolution calculation + */ + virtual EvolutionData GenerateEvolutionData(IsotopicVector IV, EvolutionData XSSet, double Power, double cycletime); + //} + + + + + private : + + + +}; + +#endif + diff --git a/source/branches/BaM/Model/Irradiation/IM_RK4.cxx b/source/branches/BaM/Model/Irradiation/IM_RK4.cxx new file mode 100644 index 000000000..0dc720759 --- /dev/null +++ b/source/branches/BaM/Model/Irradiation/IM_RK4.cxx @@ -0,0 +1,396 @@ +// +// IM_RK4.cxx +// CLASSSource +// +// Created by BaM on 04/05/2014. +// Copyright (c) 2014 BaM. All rights reserved. +// + +#include "IM_RK4.hxx" + +#include "IsotopicVector.hxx" +#include "CLASSConstante.hxx" +#include "CLASSLogger.hxx" + +#include "StringLine.hxx" + +#include <TGraph.h> +#include <TString.h> + + +#include <sstream> +#include <string> +#include <iostream> +#include <fstream> +#include <algorithm> +#include <cmath> + + + +using namespace std; + + +//________________________________________________________________________ +IM_RK4::IM_RK4():IrradiationModel(new CLASSLogger("IM_RK4.log")), DynamicalSystem() +{ + fTheNucleiVector = 0; + fTheMatrix = 0; + + SetForbidNegativeValue(); + +} + + +IM_RK4::IM_RK4(CLASSLogger* log):IrradiationModel(log), DynamicalSystem() +{ + fTheNucleiVector = 0; + fTheMatrix = 0; + + SetForbidNegativeValue(); + +} + + + + + + + + + +//________________________________________________________________________ +/* Evolution Calculation */ +//________________________________________________________________________ +EvolutionData IM_RK4::GenerateEvolutionData(IsotopicVector isotopicvector, EvolutionData XSSet, double Power, double cycletime) +{ + DBGL + if(fFastDecay.size() == 0) + { + NuclearDataInitialization(); + fNVar = fReverseMatrixIndex.size(); + } + + SetTheMatrixToZero(); + SetTheNucleiVectorToZero(); + + string ReactorType; + + + vector< TMatrixT<double> > NMatrix ;// TMatrixT<double>(decayindex.size(),1)) + { // Filling the t = 0 State; + map<ZAI, double > isotopicquantity = isotopicvector.GetIsotopicQuantity(); + TMatrixT<double> N_0Matrix = TMatrixT<double>( fReverseMatrixIndex.size(),1) ; + for(int i = 0; i < (int)fReverseMatrixIndex.size(); i++) + N_0Matrix[i] = 0; + + map<ZAI, double >::iterator it ; + for(int i = 0; i < (int)fReverseMatrixIndex.size(); i++) + N_0Matrix[i] = 0; + + for(it = isotopicquantity.begin(); it != isotopicquantity.end(); it++) + { + /// Need TO change with FP managment + map<ZAI, int >::iterator it2; + + if( (*it).first.Z() < fZAIThreshold ) + it2 = fMatrixIndex.find( ZAI(-2,-2,-2) ); + else it2 = fMatrixIndex.find( (*it).first ); + + if(it2 == fMatrixIndex.end() ) //If not in index should be TMP, can't be fast decay for new Fuel !!! + it2 = fMatrixIndex.find( ZAI(-3,-3,-3) ); + + N_0Matrix[ (*it2).second ][0] = (*it).second ; + + + } + + isotopicquantity.clear(); + + NMatrix.push_back(N_0Matrix); + N_0Matrix.Clear(); + + } + + + //-------------------------// + //--- Perform Evolution ---// + //-------------------------// + ReactorType = XSSet.GetReactorType(); + + double M_ref = XSSet.GetHeavyMetalMass(); + double M = cZAIMass.GetMass(isotopicvector.GetActinidesComposition()); + double Power_ref = XSSet.GetPower(); + + + int NStep = XSSet.GetFissionXS().begin()->second->GetN(); + double* DBTimeStep = XSSet.GetFissionXS().begin()->second->GetX(); + + int InsideStep = 10; + + double timevector[NStep]; + timevector[0] = 0; + + double Flux[NStep]; + + TMatrixT<double> FissionEnergy = TMatrixT<double>(fReverseMatrixIndex.size(),1); + for(int i = 0; i < (int)fReverseMatrixIndex.size(); i++) + FissionEnergy[i] = 0; + + { + map< ZAI, int >::iterator it; + for(it = fMatrixIndex.begin(); it != fMatrixIndex.end(); it++) + { + map< ZAI, double >::iterator it2 = fFissionEnergy.find(it->first); + if(it2 == fFissionEnergy.end()) + { + if(it->first.Z() > fZAIThreshold) + FissionEnergy[it->second][0] = 1.9679e6*it->first.A()-2.601e8; // //simple linear fit to known values ;extrapolation to unknown isotopes + else FissionEnergy[it->second][0] = 0; + } + else + FissionEnergy[it->second][0] = it2->second; + + } + } + + vector< TMatrixT<double> > FissionXSMatrix; // Store The Fisison XS Matrix + vector< TMatrixT<double> > CaptureXSMatrix; // Store The Capture XS Matrix + vector< TMatrixT<double> > n2nXSMatrix; // Store The n2N XS Matrix + DBGL + for(int i = 0; i < NStep-1; i++) + { + double TStepMax = ( (DBTimeStep[i+1]-DBTimeStep[i] ) ) * Power_ref/M_ref / Power*M ; // Get the next Time step + + + TMatrixT<double> BatemanMatrix = TMatrixT<double>(fReverseMatrixIndex.size(),fReverseMatrixIndex.size()); + TMatrixT<double> BatemanReactionMatrix = TMatrixT<double>(fReverseMatrixIndex.size(),fReverseMatrixIndex.size()); + + TMatrixT<double> NEvolutionMatrix = TMatrixT<double>(fReverseMatrixIndex.size(),1); + NEvolutionMatrix = NMatrix.back(); + + + + FissionXSMatrix.push_back(GetFissionXsMatrix(XSSet, DBTimeStep[i])); //Feel the fission reaction Matrix + CaptureXSMatrix.push_back(GetCaptureXsMatrix(XSSet, DBTimeStep[i])); //Feel the capture reaction Matrix + n2nXSMatrix.push_back(Getn2nXsMatrix(XSSet, DBTimeStep[i])); //Feel the (n,2n) reaction Matrix + + // ---------------- Evolution + + BatemanReactionMatrix = FissionXSMatrix[i]; + BatemanReactionMatrix += CaptureXSMatrix[i]; + BatemanReactionMatrix += n2nXSMatrix[i]; + + for(int k = 0; k < InsideStep; k++) + { + double ESigmaN = 0; + for (int j = 0; j < (int)fReverseMatrixIndex.size() ; j++) + ESigmaN -= FissionXSMatrix[i][j][j]*NEvolutionMatrix[j][0]*1.6e-19*FissionEnergy[j][0]; + // Update Flux + double Flux_k = Power/ESigmaN; + + if(k == 0) + Flux[i] = Flux_k; + + BatemanMatrix = BatemanReactionMatrix; + BatemanMatrix *= Flux_k; + BatemanMatrix += fDecayMatrix ; + SetTheMatrixToZero(); + SetTheNucleiVectorToZero(); + + SetTheMatrix(BatemanMatrix); + SetTheNucleiVector(NEvolutionMatrix); + + + RungeKutta(fTheNucleiVector, timevector[i]+TStepMax/InsideStep*k, timevector[i]+TStepMax/InsideStep*(k+1), fNVar); + NEvolutionMatrix = GetTheNucleiVector(); + + } + NEvolutionMatrix = GetTheNucleiVector(); + NMatrix.push_back(NEvolutionMatrix); + + timevector[i+1] = timevector[i] + TStepMax; + + BatemanMatrix.Clear(); + BatemanReactionMatrix.Clear(); + NEvolutionMatrix.Clear(); + + + } + FissionXSMatrix.push_back(GetFissionXsMatrix(XSSet, DBTimeStep[NStep-1])); //Feel the reaction Matrix + CaptureXSMatrix.push_back(GetCaptureXsMatrix(XSSet, DBTimeStep[NStep-1])); //Feel the reaction Matrix + n2nXSMatrix.push_back(Getn2nXsMatrix(XSSet, DBTimeStep[NStep-1])); //Feel the reaction Matrix + + + EvolutionData GeneratedDB = EvolutionData(GetLog()); + + double ESigmaN = 0; + for (int j = 0; j < (int)fReverseMatrixIndex.size() ; j++) + ESigmaN -= FissionXSMatrix.back()[j][j]*NMatrix.back()[j][0]*1.6e-19*FissionEnergy[j][0]; + + Flux[NStep-1] = Power/ESigmaN; + + GeneratedDB.SetFlux( new TGraph(NStep, timevector, Flux) ); + + for(int i = 0; i < (int)fReverseMatrixIndex.size(); i++) + { + double ZAIQuantity[NMatrix.size()]; + double FissionXS[NStep]; + double CaptureXS[NStep]; + double n2nXS[NStep]; + for(int j = 0; j < (int)NMatrix.size(); j++) + ZAIQuantity[j] = (NMatrix[j])[i][0]; + + for(int j = 0; j < NStep; j++) + { + FissionXS[j] = FissionXSMatrix[j][i][i]; + CaptureXS[j] = CaptureXSMatrix[j][i][i]; + n2nXS[j] = n2nXSMatrix[j][i][i]; + } + + GeneratedDB.NucleiInsert(pair<ZAI, TGraph*> (fReverseMatrixIndex[i], new TGraph(NMatrix.size(), timevector, ZAIQuantity))); +/* GeneratedDB.FissionXSInsert(pair<ZAI, TGraph*> (fReverseMatrixIndex[i], new TGraph(NStep, timevector, FissionXS))); + GeneratedDB.CaptureXSInsert(pair<ZAI, TGraph*> (fReverseMatrixIndex[i], new TGraph(NStep, timevector, CaptureXS))); + GeneratedDB.n2nXSInsert(pair<ZAI, TGraph*> (fReverseMatrixIndex[i], new TGraph(NStep, timevector, n2nXS))); +*/ } + DBGL + GeneratedDB.SetPower(Power ); + GeneratedDB.SetHeavyMetalMass(M); + GeneratedDB.SetReactorType(ReactorType ); + GeneratedDB.SetCycleTime(cycletime); + + ResetTheMatrix(); + ResetTheNucleiVector(); + + for (int i = 0; i < (int) FissionXSMatrix.size(); i++) + { + FissionXSMatrix[i].Clear(); + CaptureXSMatrix[i].Clear(); + n2nXSMatrix[i].Clear(); + } + FissionXSMatrix.clear(); + CaptureXSMatrix.clear(); + n2nXSMatrix.clear(); + DBGL + return GeneratedDB; + +} + + +void IM_RK4::ResetTheMatrix() +{ + + if(fTheMatrix) + { + for(int i = 0; i<fNVar; i++) + delete [] fTheMatrix[i]; + delete [] fTheMatrix; + } + fTheMatrix = 0; +} + +void IM_RK4::SetTheMatrixToZero() +{ + ResetTheMatrix(); + + fNVar = fReverseMatrixIndex.size(); + fTheMatrix = new double*[fNVar]; + +#pragma omp parallel for + for(int i = 0; i < fNVar; i++) + fTheMatrix[i] = new double[fNVar]; + + for(int i = 0; i < fNVar; i++) + for(int k = 0; k < fNVar; k++) + { + fTheMatrix[i][k] = 0.0; + } + +} + +//________________________________________________________________________ +void IM_RK4::ResetTheNucleiVector() +{ + if(fTheNucleiVector) + delete [] fTheNucleiVector; + fTheNucleiVector = 0; +} + +//________________________________________________________________________ +void IM_RK4::SetTheNucleiVectorToZero() +{ + ResetTheNucleiVector(); + fTheNucleiVector = new double[fNVar]; + +#pragma omp parallel for + for(int i = 0; i < fNVar; i++) + fTheNucleiVector[i] = 0.0; + +} + +//________________________________________________________________________ +void IM_RK4::BuildEqns(double t, double *N, double *dNdt) +{ + double sum = 0; + // pragma omp parallel for reduction(+:sum) + for(int i = 0; i < fNVar; i++) + { + sum = 0; + for(int k = 0; k < fNVar; k++) + { + sum += fTheMatrix[i][k]*N[k]; + } + dNdt[i] = sum; + } +} + +//________________________________________________________________________ +void IM_RK4::SetTheMatrix(TMatrixT<double> BatemanMatrix) +{ + for (int k = 0; k < (int)fNVar; k++) + for (int l = 0; l < (int)fMatrixIndex.size(); l++) + fTheMatrix[l][k] = BatemanMatrix[l][k]; +} + +//________________________________________________________________________ +TMatrixT<double> IM_RK4::GetTheMatrix() +{ + TMatrixT<double> BatemanMatrix = TMatrixT<double>(fReverseMatrixIndex.size(),fReverseMatrixIndex.size()); + for (int k = 0; k < (int)fNVar; k++) + for (int l = 0; l < (int)fMatrixIndex.size(); l++) + BatemanMatrix[l][k] = fTheMatrix[l][k]; + + return BatemanMatrix; +} + +//________________________________________________________________________ +void IM_RK4::SetTheNucleiVector(TMatrixT<double> NEvolutionMatrix) +{ + for (int k = 0; k < (int)fNVar; k++) + fTheNucleiVector[k] = NEvolutionMatrix[k][0]; +} + +//________________________________________________________________________ +TMatrixT<double> IM_RK4::GetTheNucleiVector() +{ + TMatrixT<double> NEvolutionMatrix = TMatrixT<double>(fReverseMatrixIndex.size(),1); + for (int k = 0; k < (int)fNVar; k++) + NEvolutionMatrix[k][0] = fTheNucleiVector[k]; + + return NEvolutionMatrix; +} + + + + + + + + + + + + + + + + diff --git a/source/branches/BaM/Model/Irradiation/IM_RK4.hxx b/source/branches/BaM/Model/Irradiation/IM_RK4.hxx new file mode 100644 index 000000000..6c8a9bb97 --- /dev/null +++ b/source/branches/BaM/Model/Irradiation/IM_RK4.hxx @@ -0,0 +1,122 @@ +#ifndef _IMRK4_ +#define _IMRK4_ + + +/*! + \file + \brief Header file for IrradiationModel class. + + + @author BaM + @version 2.0 + */ +#include "DynamicalSystem.hxx" +#include "IrradiationModel.hxx" + + +using namespace std; + + +class CLASSLogger; + +//-----------------------------------------------------------------------------// +//! Defines an IrradiationModel based on Runge Kutta 4th order +/*! + The aim of these class is to solve numericaly the Bateman equations using + Runge Kutta 4th order method + + @author BaM + @version 3.0 + */ +//________________________________________________________________________ + +class EvolutionData; + +class IM_RK4 : public IrradiationModel, DynamicalSystem +{ + + public : + + /*! + \name Constructor + */ + //@{ + + //{ + /// Default constructor + // + /*! + Make a new IM_Matrix : */ + IM_RK4(); + //} + + //{ + /// Logger constructor + // + /*! + Make a new IM_Matrix : + \param log : Use for the log + */ + IM_RK4(CLASSLogger* Log); + //} + + //@} + + /// virtual method called to perform the irradiation calculation using a set of cross section. + /*! + Perform the Irradiation Calcultion using the XSSet data + \param IsotopicVector IV isotopic vector to irradiate + \param EvolutionData XSSet set of corss section to use to perform the evolution calculation + */ + virtual EvolutionData GenerateEvolutionData(IsotopicVector IV, EvolutionData XSSet, double Power, double cycletime); + //} + + //********* RK4 Method *********// + + //@} + /*! + \name RK4 Method + */ + //@{ + + + using DynamicalSystem::RungeKutta; + //! Pre-treatment Runge-Kutta method. + /*! + // This method does initialization and then call DynamicalSystem::RungeKutta + // \param t1: initial time + // \param t2: final time + */ + + + void BuildEqns(double t, double *N, double *dNdt); + void SetTheMatrixToZero(); //!< Initialize the evolution Matrix + void ResetTheMatrix(); + void SetTheMatrix(TMatrixT<double> BatemanMatrix); //!< Set the Evolution Matrix (Bateman equations) + TMatrixT<double> GetTheMatrix(); //!< return the Evolution Matrix (Bateman equations) + + void SetTheNucleiVectorToZero(); //!< Initialize the evolution Matrix + void ResetTheNucleiVector(); + void SetTheNucleiVector(TMatrixT<double> NEvolutionMatrix); //!< Set the Evolution Matrix (Bateman equations) + TMatrixT<double> GetTheNucleiVector(); //!< return the Evolution Matrix (Bateman equations) + //@} + + + + private : + + double *fTheNucleiVector; //!< The evolving atoms copied from Material proportions. + double **fTheMatrix; //!< The evolution Matrix + + double fPrecision; //!< Precision of the RungeKutta + double fHestimate; //!< RK Step estimation. + double fHmin; //!< RK minimum Step. + double fMaxHdid; //!< store the effective RK max step + double fMinHdid; //!< store the effective RK min step + bool fIsNegativeValueAllowed; //!< whether or not negative value are physical. + + +}; + +#endif + diff --git a/source/branches/BaM/Model/XS/XSM_CLOSEST.cxx b/source/branches/BaM/Model/XS/XSM_CLOSEST.cxx new file mode 100644 index 000000000..10c579534 --- /dev/null +++ b/source/branches/BaM/Model/XS/XSM_CLOSEST.cxx @@ -0,0 +1,372 @@ +#include "XSModel.hxx" +#include "XSM_CLOSEST.hxx" +#include "CLASSLogger.hxx" +#include "StringLine.hxx" + + +#include <TGraph.h> +#include <TString.h> +#include "TSystem.h" +#include "TROOT.h" + +#include <sstream> +#include <string> +#include <iostream> +#include <fstream> +#include <algorithm> +#include <cmath> + + + + +//________________________________________________________________________ +// +// XSM_CLOSEST +// +// +// +// +//________________________________________________________________________ + +XSM_CLOSEST::XSM_CLOSEST(string DB_index_file, bool oldreadmethod ): XSModel(new CLASSLogger("XSM_CLOSEST.log")) +{ + fOldReadMethod = oldreadmethod; + fDataBaseIndex = DB_index_file; + fDistanceType = 0; + fWeightedDistance = false; + fEvolutionDataInterpolation = false; + ReadDataBase(); + + // Warning + INFO << " A EvolutionData has been define :" << endl; + INFO << "\t His index is : \"" << DB_index_file << "\" " << endl; + INFO << "\t " << fFuelDataBank.size() << " EvolutionData have been read." << endl << endl; + +} + +//________________________________________________________________________ +XSM_CLOSEST::XSM_CLOSEST(CLASSLogger* Log,string DB_index_file, bool oldreadmethod ): XSModel(Log) +{ + fOldReadMethod = oldreadmethod; + fDataBaseIndex = DB_index_file; + fDistanceType = 0; + fWeightedDistance = false; + fEvolutionDataInterpolation = false; + ReadDataBase(); + + // Warning + INFO << " A EvolutionData has been define :" << endl; + INFO << "\t His index is : \"" << DB_index_file << "\" " << endl; + INFO << "\t " << fFuelDataBank.size() << " EvolutionData have been read." << endl << endl; + +} + +//________________________________________________________________________ +XSM_CLOSEST::~XSM_CLOSEST() +{ + for( int i = 0; i < (int)fFuelDataBank.size(); i++) + fFuelDataBank[i].DeleteEvolutionData(); + fFuelDataBank.clear(); +} + +//________________________________________________________________________ +void XSM_CLOSEST::ReadDataBase() +{ + + if(fFuelDataBank.size() != 0) + { + for( int i = 0; i < (int)fFuelDataBank.size(); i++) + fFuelDataBank[i].DeleteEvolutionData(); + fFuelDataBank.clear(); + } + + + ifstream DataDB(fDataBaseIndex.c_str()); // Open the File + if(!DataDB) + WARNING << " Can't open \"" << fDataBaseIndex << "\"\n" << endl; + + vector<double> vTime; + vector<double> vTimeErr; + + string line; + int start = 0; + + + // First Get Fuel Type + getline(DataDB, line); + if( StringLine::NextWord(line, start, ' ') != "TYPE") + { + ERROR << " Bad Database file : " << fDataBaseIndex << " Can't find the type of the DataBase" << endl; + exit (1); + } + fFuelType = StringLine::NextWord(line, start, ' '); + + //Then Get All the Database + + while (!DataDB.eof()) + { + getline(DataDB, line); + if(line != "") + { + EvolutionData evolutionproduct(GetLog(), line, fOldReadMethod); + fFuelDataBank.push_back(evolutionproduct); + } + } + +} +//________________________________________________________________________ +//________________________________________________________________________ +//________________________________________________________________________ +/* Distance Calculation */ +//________________________________________________________________________ +//________________________________________________________________________ +//________________________________________________________________________ +map<double, int> XSM_CLOSEST::GetDistancesTo(IsotopicVector isotopicvector, double t) +{ + + map<double, int> distances; + + for( int i = 0; i < (int)fFuelDataBank.size(); i++) + { + pair<map<double, int>::iterator, bool> IResult; + + IsotopicVector ActinidesCompositionAtT = fFuelDataBank[i].GetIsotopicVectorAt(t).GetActinidesComposition(); + IsotopicVector IV_ActinidesComposition = isotopicvector.GetActinidesComposition(); + + double NormalisationFactor = Norme(IV_ActinidesComposition) / Norme( ActinidesCompositionAtT ); + + + double distance = Distance( IV_ActinidesComposition, + ActinidesCompositionAtT / NormalisationFactor, + fDistanceType, + fDistanceParameter); + + IResult = distances.insert( pair< double, int >(distance, i) ); + } + + return distances; + +} +//________________________________________________________________________ +EvolutionData XSM_CLOSEST::GetCrossSections(IsotopicVector isotopicvector, double t) +{ + DBGL + double distance = 0; + int N_BestEvolutionData = 0; + + + if(fWeightedDistance) + { + DBGL + IsotopicVector ActinidesCompositionAtT = fFuelDataBank[0].GetIsotopicVectorAt(t).GetActinidesComposition(); + IsotopicVector IV_ActinidesComposition = isotopicvector.GetActinidesComposition(); + + double NormalisationFactor = Norme( ActinidesCompositionAtT ) / Norme(IV_ActinidesComposition); + + + distance = Distance( IV_ActinidesComposition / NormalisationFactor, + fFuelDataBank[0]); + + + for( int i = 1; i < (int)fFuelDataBank.size(); i++) + { + double D = 0; + ActinidesCompositionAtT = fFuelDataBank[i].GetIsotopicVectorAt(t).GetActinidesComposition(); + IV_ActinidesComposition = isotopicvector.GetActinidesComposition(); + NormalisationFactor = Norme( ActinidesCompositionAtT ) / Norme(IV_ActinidesComposition); + + D = Distance( IV_ActinidesComposition / NormalisationFactor, + fFuelDataBank[i]); + + + if (D< distance) + { + distance = D; + N_BestEvolutionData = i; + } + } + DBGL + return fFuelDataBank[N_BestEvolutionData]; + } + else if (fEvolutionDataInterpolation) + { + DBGL + map<double, int> distance_map = GetDistancesTo(isotopicvector, t); + map<double, int>::iterator it_distance; + int NClose = 64; + int Nstep = 0; + EvolutionData EvolInterpolate; + double SumOfDistance = 0; + for( it_distance = distance_map.begin(); it_distance != distance_map.end(); it_distance++) + { + + double distance = (*it_distance).first; + int ED_Indice = (*it_distance).second; + + if(distance == 0 ) + { + EvolInterpolate = Multiply(1,fFuelDataBank[ED_Indice]); + return EvolInterpolate; + } + + if(Nstep == 0) + EvolInterpolate = Multiply(1./distance, fFuelDataBank[ED_Indice]); + else + { + + EvolutionData Evoltmp = EvolInterpolate; + EvolutionData Evoltmp2 = Multiply(1./distance, fFuelDataBank[ED_Indice]); + + EvolInterpolate = Sum(Evoltmp, Evoltmp2); + Evoltmp.DeleteEvolutionData(); + Evoltmp2.DeleteEvolutionData(); + + + } + + SumOfDistance += 1./distance; + Nstep++; + if(Nstep == NClose) break; + + } + + EvolutionData Evoltmp = EvolInterpolate; + EvolInterpolate.Clear(); + + EvolInterpolate = Multiply(1/SumOfDistance, Evoltmp); + + Evoltmp.DeleteEvolutionData(); + DBGL + return EvolInterpolate; + + } + else + { + DBGL + IsotopicVector ActinidesCompositionAtT = fFuelDataBank[0].GetIsotopicVectorAt(t).GetActinidesComposition(); + IsotopicVector IV_ActinidesComposition = isotopicvector.GetActinidesComposition(); + + + double NormalisationFactor = Norme(IV_ActinidesComposition) / Norme( ActinidesCompositionAtT ); + + + distance = Distance( IV_ActinidesComposition, + ActinidesCompositionAtT / NormalisationFactor, + fDistanceType, + fDistanceParameter); + + for( int i = 1; i < (int)fFuelDataBank.size(); i++) + { + double D = 0; + ActinidesCompositionAtT = fFuelDataBank[i].GetIsotopicVectorAt(t).GetActinidesComposition(); + IV_ActinidesComposition = isotopicvector.GetActinidesComposition(); + + NormalisationFactor = Norme(IV_ActinidesComposition) / Norme( ActinidesCompositionAtT ); + D = Distance( IV_ActinidesComposition, + ActinidesCompositionAtT / NormalisationFactor, + fDistanceType, + fDistanceParameter); + + if (D< distance) + { + distance = D; + N_BestEvolutionData = i; + } + } + + + INFO << distance << endl; + DBGL + + return fFuelDataBank[N_BestEvolutionData]; + } + +} +//________________________________________________________________________ +void XSM_CLOSEST::CalculateDistanceParameter() +{ + DBGL + if(fDistanceType != 1){ + WARNING << " Distance Parameter will be calculate even if the distance type is not the good one. Any Distance Parameters given by the user will be overwriten" << endl; + } + + fDistanceParameter.Clear(); + + //We calculate the weight for the distance calculation. + int NevolutionDatainFuelDataBank = 0; + + for( int i = 0; i < (int)fFuelDataBank.size(); i++) + { + NevolutionDatainFuelDataBank++; + map<ZAI ,double>::iterator itit; + map<ZAI ,double> isovector = fFuelDataBank[i].GetIsotopicVectorAt(0).GetIsotopicQuantity(); + for(itit = isovector.begin(); itit != isovector.end(); itit++) //Boucle sur ZAI + { + double TmpXS = 0; + + for( int i = 1; i<4; i++ ) //Loop on Reactions 1 == fission, 2 == capture, 3 == n2n + TmpXS+= fFuelDataBank[i].GetXSForAt(0, (*itit).first, i); + + fDistanceParameter.Add((*itit).first,TmpXS); + } + + + } + fDistanceParameter.Multiply( (double)1.0/NevolutionDatainFuelDataBank ); + + if(GetLog()) + { + INFO << "!!INFO!! Distance Parameters " << endl; + map<ZAI ,double >::iterator it2; + for(it2 = fDistanceParameter.GetIsotopicQuantity().begin();it2 != fDistanceParameter.GetIsotopicQuantity().end(); it2++) + { + INFO << (*it2).first.Z() << " "; + INFO << (*it2).first.A() << " "; + INFO << (*it2).first.I() << " "; + INFO << ": " << (*it2).second; + INFO << endl; + } + INFO << endl; + } + + DBGL +} +//________________________________________________________________________ +void XSM_CLOSEST::SetDistanceParameter(IsotopicVector DistanceParameter) +{ + + fDistanceParameter = DistanceParameter; + + INFO << "!!INFO!! Distance Parameters " << endl; + map<ZAI ,double >::iterator it2; + for(it2 = fDistanceParameter.GetIsotopicQuantity().begin();it2 != fDistanceParameter.GetIsotopicQuantity().end(); it2++) + { + INFO << (*it2).first.Z() << " "; + INFO << (*it2).first.A() << " "; + INFO << (*it2).first.I() << " "; + INFO << ": " << (*it2).second; + INFO << endl; + } + INFO << endl; + +} + +//________________________________________________________________________ +void XSM_CLOSEST::SetDistanceType(int DistanceType) +{ + + fDistanceType = DistanceType; + if(fDistanceType == 1){ + CalculateDistanceParameter(); + } + else if(fDistanceType == 2 && Norme(fDistanceParameter) == 0){ + // This is so bad!! You will probably unsynchronize all the reactor.... + WARNING << " Distance use weight defined by user for each isotope, but no weight have been given" << endl << "Use SetDistanceParameter()" << endl; + exit(1); + } + else if (fDistanceType != 0 && fDistanceType != 1 && fDistanceType != 2 ){ + ERROR << " Distancetype defined by the user isn't recognized by the code" << endl; + exit(1); + } + +} \ No newline at end of file diff --git a/source/branches/BaM/Model/XS/XSM_CLOSEST.hxx b/source/branches/BaM/Model/XS/XSM_CLOSEST.hxx new file mode 100644 index 000000000..574046280 --- /dev/null +++ b/source/branches/BaM/Model/XS/XSM_CLOSEST.hxx @@ -0,0 +1,166 @@ + +#ifndef _XSM_CLOSEST_HXX +#define _XSM_CLOSEST_HXX + + +/*! + \file + \brief Header file for XSM_MLP_PWR_MOX class. + + + @authors BaM,BLG + @version 1.0 + */ +#include "XSModel.hxx" +#include <string> +#include <fstream> +#include <iostream> +#include <map> +#include <vector> +typedef long long int cSecond; +using namespace std; + +//-----------------------------------------------------------------------------// +//! Defines a XSModel getting mean cross sections from the closest EvolutionData + +/*! + Define a XSM_CLOSEST. + Class to get cross sections from a set of pre-calculation + (with MURE,or other depletion code). +With this class, cross sections needed to solves Bateman equation come from an + already performed depletion calculation contained in a set of many depletion calculations. + The way to pick up these or these depletion calculation is related to a distance : + The depletion calculation (or EvolutionData) the closest from the new fresh fuel composition + is selected. Different distances are defined : + + \li Standard euclidean distance (weights : 1) IS THE DEFAULT + \li Euclidean distance with weights assigned according mean cross section values + \li Euclidean distance with weights assigned by user + + @authors BaM,BLG + @version 1.0 + */ +//________________________________________________________________________ + + +class XSM_CLOSEST : public XSModel +{ + + public : + + /*! + \name Constructor/Desctructor + */ + //@{ + + //{ + /// normal constructor + // + /*! + Make a new XSM_CLOSEST + \param DB_index_file : File listing the path of all depletion calculations (in EvolutionData format (.dat file) ) + \param oldreadmethod : + */ + XSM_CLOSEST(string DB_index_file, bool oldreadmethod = false ); + //} + + //{ + /// Logger constructor + // + /*! + Make a new XSM_CLOSEST + \param log : Use for the log + \param DB_index_file : File listing the path of all depletion calculations (in EvolutionData format (.dat file) ) + \param oldreadmethod : + */ + XSM_CLOSEST(CLASSLogger* Log, string DB_index_file, bool oldreadmethod = false ); + //} + + ~XSM_CLOSEST(); + //@} + + + //********* Get Method *********// + /*! + \name Get Method + */ + //@{ + virtual EvolutionData GetCrossSections(IsotopicVector isotopicvector,double t = 0) ; //!< Reason to live of this CLASS : Return the closest Evolutiondata + vector< EvolutionData > GetFuelDataBank() const { return fFuelDataBank; } //!< Return the FuelDataBank + string GetDataBaseIndex() const { return fDataBaseIndex; } //!< Return the index Name + string GetFuelType() const { return fFuelType; } //!< Return the fuel type of the DB + vector<double> GetFuelParameter() const { return fFuelParameter; } //!< Return the Fuel parameters of the DB + pair<double,double> GetBurnUpRange() const { return fBurnUpRange;} //!< Return the Burnup range of the DB + bool IsDefine(IsotopicVector IV) const; //!< True if the key is define, false instead + + map<double, int> GetDistancesTo(IsotopicVector isotopicvector, double t = 0); //! Return a map containing the distance of each EvolutionData in the DataBase to the set IV at the time t + //@} + + //********* Set Method *********// + + /*! + \name Set Method + */ + //@{ + + void SetFuelDataBank(vector< EvolutionData > mymap) { fFuelDataBank = mymap; } //!< Set the FuelDataBank map + + void SetDataBaseIndex(string database) { fDataBaseIndex = database;; ReadDataBase(); } //!< Set the Name of the database index + void SetOldReadMethod(bool val) { fOldReadMethod = val; ReadDataBase();} //!< use the old reading method + + + + void SetWeightedDistanceCalculation(bool val = true) { fWeightedDistance = val;} //!< Set weighted distance calculation + void SetInventoryEvolutionInterpolation(bool val = true) { fEvolutionDataInterpolation = val;} //!< \deprecated The 64 closest EvolutionData (ED) are used to build a new ED. The cross section from each ED are weighted according to their distance + void SetDistanceParameter(IsotopicVector DistanceParameter); //!< Define mannually the weight for each ZAI in the distance calculation + //@} + + //{ + /// Choose the way to calculate the distance between two isotopic vectors. + /*! + // The different algorythms are: + // \li 0 is for the standard norme, + // \li 1 for each ZAI weighted with its XS, + // \li 2 for each ZAI weighted with coefficient given by the user. + */ + void SetDistanceType(int DistanceType); + //} + + //********* Other Method *********// + /*! + \name Other Method + */ + //@{ + void ReadDataBase(); //!< read the index file and fill the evolutionData map + void CalculateDistanceParameter(); //!< Calcul of the weight for each ZAI in the distance calculation from the mean XS of the FuelDataBank + + //@} + + private : + + vector< EvolutionData > fFuelDataBank; //!< DataBank map + + string fDataBaseIndex; //!< Name of the index + + bool fOldReadMethod; //!< use old DB format + bool fWeightedDistance; //!< USe XS weighted distance calculation + bool fEvolutionDataInterpolation; //!< USe XS weighted distance calculation + + + string fFuelType; //!< Type of fuel of the FuelDataBank + pair<double,double> fBurnUpRange; //!< Range of the Burn-up range of the FuelDataBank + vector<double> fFuelParameter; //!< Parameter needed by the equivalence model + + + + int fDistanceType; //!< Set the distance calculation algorythm + /// \li 0 is for the standard norm (Default = 0), + /// \li 1 for each ZAI weighted with its XS, + /// \li 2 for each ZAI weighted with coefficient given by the user. + + IsotopicVector fDistanceParameter; //!< weight for each ZAI in the distance calculation + +}; + +#endif + diff --git a/source/branches/BaM/Model/XS/XSM_MLP.cxx b/source/branches/BaM/Model/XS/XSM_MLP.cxx new file mode 100644 index 000000000..c79d57493 --- /dev/null +++ b/source/branches/BaM/Model/XS/XSM_MLP.cxx @@ -0,0 +1,511 @@ + +#include "XSModel.hxx" +#include "XSM_MLP.hxx" +#include "CLASSLogger.hxx" +#include "CLASSMethod.hxx" +#include "StringLine.hxx" + +#include "TMVA/Reader.h" +#include "TMVA/Tools.h" +#include "TMVA/MethodCuts.h" + +#include <TGraph.h> +#include <TString.h> +#include "TFile.h" +#include "TSystem.h" +#include "TROOT.h" +#include "TStopwatch.h" + +#include <dirent.h> +#include <errno.h> +#include <sstream> +#include <string> +#include <iostream> +#include <fstream> +#include <algorithm> +#include <cmath> + +//________________________________________________________________________ +// +// XSM_MLP +// +// +// +// +//________________________________________________________________________ +XSM_MLP::XSM_MLP(string TMVA_Weight_Directory,string InformationFile, bool IsTimeStep):XSModel(new CLASSLogger("XSM_MLP.log")) +{ + + fIsStepTime = IsTimeStep; + fTMVAWeightFolder = TMVA_Weight_Directory; + + fInformationFile = fTMVAWeightFolder+InformationFile; + + GetMLPWeightFiles(); + + INFO << "__A cross section interpolator using" << endl; + INFO << "Multi Layer Perceptron has been define__" << endl; + INFO << " \t His TMVA folder is : \" " << fTMVAWeightFolder << "\"" << endl; + + LoadKeyword(); + ReadNFO(); + +} + +//________________________________________________________________________ +XSM_MLP::XSM_MLP(CLASSLogger* Log,string TMVA_Weight_Directory,string InformationFile, bool IsTimeStep):XSModel(Log) +{ + + fIsStepTime = IsTimeStep; + fTMVAWeightFolder = TMVA_Weight_Directory; + + fInformationFile = fTMVAWeightFolder+InformationFile; + + GetMLPWeightFiles(); + + INFO << "__A cross section interpolator using" << endl; + INFO << "Multi Layer Perceptron has been define__" << endl; + INFO << " \t His TMVA folder is : \" " << fTMVAWeightFolder << "\"" << endl; + + LoadKeyword(); + ReadNFO(); + +} + +//________________________________________________________________________ +XSM_MLP::~XSM_MLP() +{ + DBGL + fMapOfTMVAVariableNames.clear(); + fDKeyword.clear(); + DBGL +} + + +//________________________________________________________________________ +void XSM_MLP::LoadKeyword() +{ + DBGL + fDKeyword.insert( pair<string, XS_MLP_DMthPtr>( "k_timestep", & XSM_MLP::ReadTimeSteps)); + fDKeyword.insert( pair<string, XS_MLP_DMthPtr>( "k_zainame", & XSM_MLP::ReadZAIName) ); + DBGL +} + + +//________________________________________________________________________ +void XSM_MLP::ReadZAIName(const string &line) +{ + DBGL + int pos = 0; + string keyword = tlc(StringLine::NextWord(line, pos, ' ')); + if( keyword != "k_zainame" ) // Check the keyword + { + ERROR << " Bad keyword : \"k_zainame\" not found !" << endl; + exit(1); + } + + int Z = atoi(StringLine::NextWord(line, pos, ' ').c_str()); + int A = atoi(StringLine::NextWord(line, pos, ' ').c_str()); + int I = atoi(StringLine::NextWord(line, pos, ' ').c_str()); + + string name = StringLine::NextWord(line, pos, ' '); + + fMapOfTMVAVariableNames.insert( pair<ZAI,string>( ZAI(Z, A, I), name ) ); + + DBGL +} + +//________________________________________________________________________ +void XSM_MLP::ReadTimeSteps(const string &line) +{ + DBGL + int pos = 0; + string keyword = tlc(StringLine::NextWord(line, pos, ' ')); + if( keyword != "k_timestep" ) // Check the keyword + { + ERROR << " Bad keyword : \"k_timestep\" not found !" << endl; + exit(1); + } + + while( pos < (int)line.size() ) + fMLP_Time.push_back( atof( (StringLine::NextWord(line,pos,' ')).c_str() )); + DBGL +} + + +//________________________________________________________________________ +void XSM_MLP::ReadLine(string line) +{ + DBGL + + int pos = 0; + string keyword = tlc(StringLine::NextWord(line, pos, ' ')); + + map<string, XS_MLP_DMthPtr>::iterator it = fDKeyword.find(keyword); + + if(it != fDKeyword.end()) + (this->*(it->second))( line ); + + DBGL +} + + + +//________________________________________________________________________ +void XSM_MLP::GetMLPWeightFiles() +{ + DBGL + /**********Get All TMVA weight files*******************/ + //check if the folder containing weights exists + DIR* rep = NULL; + struct dirent* fichierLu = NULL; + rep = opendir(fTMVAWeightFolder.c_str()); + + if (rep == NULL) + { + ERROR << " Reading error for TMVA weight folder " << fTMVAWeightFolder.c_str() << " : " << strerror(errno) << endl; + exit(1); + } + + /**Save file names of TMVA weights*/ + fWeightFiles.resize(0); + while ((fichierLu = readdir(rep)) != NULL) + { + string FileName = fichierLu->d_name ; + if(FileName != "." && FileName != ".." ) + { + if(FileName[FileName.size()-3] == 'x' && FileName[FileName.size()-2] == 'm' && FileName[FileName.size()-1] == 'l' && FileName[0] != '.' ) + fWeightFiles.push_back(FileName); + + } + } + DBGL +} +//________________________________________________________________________ +//________________________________________________________________________ +// +// Time (MLP take time as parameter) +//________________________________________________________________________ +//________________________________________________________________________ +void XSM_MLP::ReadWeightFile(string Filename, int &Z, int &A, int &I, int &Reaction) +{ + Z = -1; + A = -1; + I = -1; + Reaction = -1; + + size_t found = Filename.find("XS"); + + string NameJOB; + NameJOB = Filename.substr(found); + int pos = 0; + + StringLine::NextWord(NameJOB, pos, '_'); + + Z = atof( (StringLine::NextWord(NameJOB,pos,'_') ).c_str() ); + + A = atof( (StringLine::NextWord(NameJOB,pos,'_') ).c_str() ); + + I = atof( (StringLine::NextWord(NameJOB,pos,'_') ).c_str() ); + + string sReaction = (StringLine::NextWord(NameJOB,pos,'_') ).c_str() ; + size_t foundext = sReaction.find(".weights.xml"); + sReaction = sReaction.substr(0,foundext); + + if(sReaction == "fis") + Reaction = 0; + if(sReaction == "cap") + Reaction = 1; + if(sReaction == "n2n") + Reaction = 2; + + if(Z<= 0 || A<= 0 || I<0 || Reaction == -1) + { + ERROR << " wrong TMVA weight format " << endl; + exit(0); + } + +} +//________________________________________________________________________ +TTree* XSM_MLP::CreateTMVAInputTree(IsotopicVector isotopicvector,int TimeStep) +{ + /******Create Input data tree to be interpreted by TMVA::Reader***/ + TTree* InputTree = new TTree("InTMP", "InTMP"); + + vector<float> InputTMVA; + for(int i = 0 ; i< (int)fMapOfTMVAVariableNames.size() ; i++) + InputTMVA.push_back(0); + + float Time = 0; + + IsotopicVector IVInputTMVA; + map<ZAI ,string >::iterator it; + int j = 0; + + for( it = fMapOfTMVAVariableNames.begin() ; it != fMapOfTMVAVariableNames.end() ; it++) + { + InputTree->Branch( ((*it).second).c_str() ,&InputTMVA[j], ((*it).second + "/F").c_str()); + IVInputTMVA+= ((*it).first)*1; + j++; + } + + if( !fIsStepTime) + InputTree->Branch( "Time" ,&Time ,"Time/F" ); + + IsotopicVector IVAccordingToUserInfoFile = isotopicvector.GetThisComposition(IVInputTMVA); + + double Ntot = IVAccordingToUserInfoFile.GetSumOfAll(); + + IVAccordingToUserInfoFile = IVAccordingToUserInfoFile/Ntot; + + j = 0; + map<ZAI ,string >::iterator it2; + DBGV("INPUT TMVA"); + for( it2 = fMapOfTMVAVariableNames.begin() ; it2 != fMapOfTMVAVariableNames.end() ; it2++) + { + InputTMVA[j] = IVAccordingToUserInfoFile.GetZAIIsotopicQuantity( (*it2).first ) ; + DBGV((*it2).first.Z() << " " << (*it2).first.A() << " " << InputTMVA[j]); + j++; + } + + Time = fMLP_Time[TimeStep]; + + InputTree->Fill(); + + return InputTree; +} +//________________________________________________________________________ +double XSM_MLP::ExecuteTMVA(string WeightFile,TTree* InputTree) +{ + DBGV( "File :" << WeightFile); + // --- Create the Reader object + TMVA::Reader *reader = new TMVA::Reader( "Silent" ); + + // Create a set of variables and declare them to the reader + // - the variable names MUST corresponds in name and type to those given in the weight file(s) used + vector<float> InputTMVA; + for(int i = 0 ; i< (int)fMapOfTMVAVariableNames.size() ; i++) + InputTMVA.push_back(0); + Float_t Time; + + map<ZAI ,string >::iterator it; + int j = 0; + for( it = fMapOfTMVAVariableNames.begin() ; it != fMapOfTMVAVariableNames.end() ; it++) + { reader->AddVariable( ( (*it).second ).c_str(),&InputTMVA[j]); + j++; + } + if(!fIsStepTime) + reader->AddVariable( "Time" ,&Time); + + // --- Book the MVA methods + + string dir = fTMVAWeightFolder; + if(dir[dir.size()-1] != '/') + dir+= "/"; + + // Book method MLP + TString methodName = "MLP method"; + TString weightpath = dir + WeightFile ; + reader->BookMVA( methodName, weightpath ); + + map<ZAI ,string >::iterator it2; + j = 0; + for( it2 = fMapOfTMVAVariableNames.begin() ; it2 != fMapOfTMVAVariableNames.end() ; it2++) + { + InputTree->SetBranchAddress(( (*it2).second ).c_str(),&InputTMVA[j]); + j++; + } + + if(!fIsStepTime) + InputTree->SetBranchAddress( "Time" ,&Time ); + + InputTree->GetEntry(0); + Float_t val = (reader->EvaluateRegression( methodName ))[0]; + + delete reader; + DBGL + + return (double)val; +} +//________________________________________________________________________ +EvolutionData XSM_MLP::GetCrossSectionsTime(IsotopicVector IV) +{ + DBGL + + EvolutionData EvolutionDataFromMLP = EvolutionData(); + + map<ZAI,TGraph*> ExtrapolatedXS[3]; + /*************DATA BASE INFO****************/ + EvolutionDataFromMLP.SetReactorType(fDBRType); + EvolutionDataFromMLP.SetFuelType(fDBFType); + EvolutionDataFromMLP.SetPower(fDBPower); + EvolutionDataFromMLP.SetHeavyMetalMass(fDBHMMass); + /************* The Cross sections***********/ + for(int i = 0;i<int(fWeightFiles.size());i++) + { + int Z = -2; + int A = -2; + int I = -2; + int Reaction = -2; + ReadWeightFile( fWeightFiles[i], Z, A, I, Reaction); + if( Z >= GetZAIThreshold() ) + { + for(int TimeStep = 0;TimeStep<int(fMLP_Time.size());TimeStep++) + { + TTree* InputTree = CreateTMVAInputTree(IV,TimeStep); + + pair< map<ZAI, TGraph*>::iterator, bool> IResult; + + IResult = ExtrapolatedXS[Reaction].insert( pair<ZAI ,TGraph* >(ZAI(Z,A,I), new TGraph()) ); + + double XSValue = ExecuteTMVA(fWeightFiles[i],InputTree ); + if(IResult.second ) + { + (IResult.first)->second->SetPoint(0, (double)fMLP_Time[TimeStep], XSValue ); + + } + else + { + (IResult.first)->second->SetPoint( (IResult.first)->second->GetN(), (double)fMLP_Time[TimeStep], XSValue ); + } + + delete InputTree; + } + } + } + + /**********Sorting TGraph*********/ + for(int x = 0;x<3;x++) + { map<ZAI,TGraph*>::iterator it; + for(it = ExtrapolatedXS[x].begin(); it != ExtrapolatedXS[x].end(); it++) + it->second->Sort(); + + } + /**********Filling Matrices*/ + EvolutionDataFromMLP.SetFissionXS(ExtrapolatedXS[0]); + EvolutionDataFromMLP.SetCaptureXS(ExtrapolatedXS[1]); + EvolutionDataFromMLP.Setn2nXS(ExtrapolatedXS[2]); + + + DBGL + return EvolutionDataFromMLP; +} +//________________________________________________________________________ +//________________________________________________________________________ +// +// Time step (1 MLP per time step) +//________________________________________________________________________ +//________________________________________________________________________ +void XSM_MLP::ReadWeightFileStep(string Filename, int &Z, int &A, int &I, int &Reaction, int &TimeStep) +{ + Z = -1; + A = -1; + I = -1; + Reaction = -1; + + size_t found = Filename.find("XS"); + + string NameJOB; + NameJOB = Filename.substr(found); + int pos = 0; + + StringLine::NextWord(NameJOB, pos, '_'); + + Z = atof( (StringLine::NextWord(NameJOB,pos,'_') ).c_str() ); + A = atof( (StringLine::NextWord(NameJOB,pos,'_') ).c_str() ); + I = atof( (StringLine::NextWord(NameJOB,pos,'_') ).c_str() ); + + string sReaction = (StringLine::NextWord(NameJOB,pos,'_') ).c_str() ; + if(sReaction == "fis") + Reaction = 0; + if(sReaction == "cap") + Reaction = 1; + if(sReaction == "n2n") + Reaction = 2; + + TimeStep = atof( (StringLine::NextWord(NameJOB,pos,'_') ).c_str() ); + + if(Z == -1 || A == -1 || I == -1 || Reaction == -1 || TimeStep == -1) + { + ERROR << " wrong TMVA weight format " << endl; + exit(0); + } +} + +//________________________________________________________________________ +EvolutionData XSM_MLP::GetCrossSectionsStep(IsotopicVector IV) +{ + DBGL + TTree* InputTree = CreateTMVAInputTree(IV); + + EvolutionData EvolutionDataFromMLP = EvolutionData(); + + map<ZAI,TGraph*> ExtrapolatedXS[3]; + /*************DATA BASE INFO****************/ + EvolutionDataFromMLP.SetReactorType("PWR"); + EvolutionDataFromMLP.SetFuelType("MOX"); + EvolutionDataFromMLP.SetPower(fDBPower); + EvolutionDataFromMLP.SetHeavyMetalMass(fDBHMMass); + + /************* The Cross sections***********/ + + for(int i = 0;i<int(fWeightFiles.size());i++) + { + int Z = -2; + int A = -2; + int I = -2; + int Reaction = -2; + int TimeStep = -2; + ReadWeightFileStep( fWeightFiles[i], Z, A, I, Reaction, TimeStep); + if( Z >= GetZAIThreshold() ) + { + ZAI zaitmp = ZAI(Z,A,I); + + pair< map<ZAI, TGraph*>::iterator, bool> IResult; + + IResult = ExtrapolatedXS[Reaction].insert(pair<ZAI ,TGraph* >(ZAI(Z,A,I), new TGraph() ) ); + + if( IResult.second ) + { + (IResult.first)->second->SetPoint(0, (double)fMLP_Time[TimeStep], ExecuteTMVA(fWeightFiles[i],InputTree) ); + } + else + { + (IResult.first)->second->SetPoint( (IResult.first)->second->GetN(), (double)fMLP_Time[TimeStep], ExecuteTMVA(fWeightFiles[i],InputTree) ); + } + } + } + + /**********Sorting TGraph*********/ + for(int x = 0;x<3;x++) + { map<ZAI,TGraph*>::iterator it; + for(it = ExtrapolatedXS[x].begin(); it != ExtrapolatedXS[x].end(); it++) + it->second->Sort(); + } + /**********Filling Matrices*/ + EvolutionDataFromMLP.SetFissionXS(ExtrapolatedXS[0]); + EvolutionDataFromMLP.SetCaptureXS(ExtrapolatedXS[1]); + EvolutionDataFromMLP.Setn2nXS(ExtrapolatedXS[2]); + + delete InputTree; + DBGL + return EvolutionDataFromMLP; +} +//________________________________________________________________________ +EvolutionData XSM_MLP::GetCrossSections(IsotopicVector IV ,double t) +{ + DBGL + if(t != 0) + WARNING << " Argument t has non effect here " << endl; + + EvolutionData EV; + if(fIsStepTime) + EV = GetCrossSectionsStep(IV); + + else + EV = GetCrossSectionsTime(IV); + + DBGL + return EV; +} +//________________________________________________________________________ diff --git a/source/branches/BaM/Model/XS/XSM_MLP.hxx b/source/branches/BaM/Model/XS/XSM_MLP.hxx new file mode 100644 index 000000000..f7c748f12 --- /dev/null +++ b/source/branches/BaM/Model/XS/XSM_MLP.hxx @@ -0,0 +1,151 @@ + +#ifndef _XSM_MLP_HXX +#define _XSM_MLP_HXX + + +/*! + \file + \brief Header file for XSM_MLP class. + + + @authors BaM + @authors BLG + @version 1.0 + */ +#include "XSModel.hxx" +#include "TTree.h" +#include <string> +#include <fstream> +#include <iostream> +#include <map> +#include <vector> + + +typedef long long int cSecond; +using namespace std; + + +class XSM_MLP; +#ifndef __CINT__ +typedef void (XSM_MLP::*XS_MLP_DMthPtr)( const string & ) ; +#endif +//-----------------------------------------------------------------------------// +//! Defines a XSModel getting mean cross sections from neural network execution + +/*! + Define a XSM_MLP. + This is the class to predict cross sections with a + set of Multi Layer Perceptrons (MLP) + + @authors BLG + @version 1.0 + */ +//________________________________________________________________________ + + +class XSM_MLP : public XSModel +{ + public : + + /*! + \name Constructor/Desctructor + */ + //@{ + + //{ + /// Normal Constructor + /*! + \param TMVA_Weight_Directory : The directory where all the TMVA weight are located + \param InformationFile : Name of the information file located in TMVA_Weight_Directory (default : Data_Base_Info.nfo) + \param IsTimeStep : if true , one TMVA weihgt per step time is requiered otherwise it assumes time is part of the MLP inputs + + */ + XSM_MLP(string TMVA_Weight_Directory,string InformationFile = "/Data_Base_Info.nfo",bool IsTimeStep = false); + //} + + //{ + /// CLASSLogger Constructor + /*! + \param log : The CLASSLogger + \param TMVA_Weight_Directory : The directory where all the TMVA weight are located + \param InformationFile : Name of the information file located in TMVA_Weight_Directory (default : Data_Base_Info.nfo) + \param IsTimeStep : if true , one TMVA weihgt per step time is requiered otherwise it assumes time is part of the MLP inputs + + */ + XSM_MLP(CLASSLogger* Log,string TMVA_Weight_Directory,string InformationFile = "/Data_Base_Info.nfo",bool IsTimeStep = false); + //} + + ~XSM_MLP(); + //@} + + /*! + \name Reading NFO related Method + */ + //@{ + + //{ + /// LoadKeyword() : make the correspondance between keyword and reading method + void LoadKeyword(); + //} + + //{ + /// ReadTimeSteps : read the time step of the model + /*! + \param line : line suppossed to contain the time step information starts with "k_timestep" keyword + */ + void ReadTimeSteps(const string &line); + //} + + //{ + /// ReadZAIName : read the zai name in the TMWA MLP model + /*! + \param line : line suppossed to contain the ZAI name starts with "k_zainame" keyword + */ + void ReadZAIName(const string &line); + //} + //{ + /// ReadLine : read a line + /*! + \param line : line to read + */ + void ReadLine(string line); + //} + + //@} + + + EvolutionData GetCrossSections(IsotopicVector IV,double t = 0); //!< Return calculated cross section by the MLP regression + + + private : + + void GetMLPWeightFiles(); //!< Find all .xml file in TMVA_Weight_Directory + EvolutionData GetCrossSectionsStep(IsotopicVector IV); //!< Return calculated cross section by the MLP regression when fIsTimeStep == true + EvolutionData GetCrossSectionsTime(IsotopicVector IV); //!< Return calculated cross section by the MLP regression when fIsTimeStep == false + + void ReadWeightFile(string Filename, int &Z, int &A, int &I, int &Reaction) ; //!< Select the reaction according to the weight file name + void ReadWeightFileStep(string Filename, int &Z, int &A, int &I, int &Reaction, int &TimeStep);; //!< Select the reaction according to the weight file name + + + + double ExecuteTMVA(string WeightFile, TTree* InputTree); //!<Execute the MLP according to the input tree created + TTree* CreateTMVAInputTree(IsotopicVector isotopicvector,int TimeStep = 0); //!<Create input tmva tree to be read by ExecuteTMVA + + + vector<double> fMLP_Time; //!< Time vector of the data base + vector<string> fWeightFiles; //!< All the weight file contains in fTMVAWeightFolder + + string fTMVAWeightFolder; //!< folder containing all the weight file + + + bool fIsStepTime; //!< true if one TMVA weihgt per step time is requiered otherwise it assumes time is part of the MLP inputs + + map<ZAI,string> fMapOfTMVAVariableNames;//!< List of TMVA input variable names (read from fMLPInformationFile ) , name depends on the training step + +#ifndef __CINT__ + map<string, XS_MLP_DMthPtr> fDKeyword; +#endif +}; + +#endif + diff --git a/source/branches/BaM/include/CLASSBackEnd.hxx b/source/branches/BaM/include/CLASSBackEnd.hxx new file mode 100644 index 000000000..334e95ecd --- /dev/null +++ b/source/branches/BaM/include/CLASSBackEnd.hxx @@ -0,0 +1,154 @@ + +#ifndef _CLASSBACKEND_ +#define _CLASSBACKEND_ + + +/*! + \file + \brief Header file for CLASSFacility class. + + */ + +#include <string> +#include <fstream> +#include <map> + + +#include "CLASSFacility.hxx" +#include "IsotopicVector.hxx" +#include "DecayDataBank.hxx" + +#include "TNamed.h" + +using namespace std; + +//-----------------------------------------------------------------------------// +//! Class defining the common properties of all back end fuel cycle facilities + +/*! + Define a CLASS Facility. + The aim of these class is to gather all the commom properties of the + facilities which are involve in the BackEnd Fuel cycle. + + @author BaM + @version 2.0 + */ +//________________________________________________________________________ + + +class CLASSBackEnd : public CLASSFacility +{ + public : + //{ + /// Default Constructor. + /*!Create an empty CLASSBackEnd + \param type + \li -2 :SeparationPlant + \li -1 :Storage + \li 8 :Pool + */ + CLASSBackEnd(int type = 0); + //} + + //{ + /// CLASSLogger Constructor. + /*! + Create an empty CLASSBackEnd loading a CLASSLogger + \param log : used for the log. + \param type + \li -2 :SeparationPlant + \li -1 :Storage + \li 8 :Pool */ + CLASSBackEnd(CLASSLogger* log,int type = 0); + //} + + //{ + /// Cycle time Constructor. + /*! + Create an empty CLASSBackEnd loading a CLASSLogger + \param log : used for the log. + \param cycletime Cycle time of the CLASSBackend (e.g. Cooling time for the pool) in [s], + \param type -2 :SeparationPlant -1 : Storage ; 8 :Pool + */ + CLASSBackEnd(CLASSLogger* log, cSecond cycletime, int type = 0); + //} + //@} + + //********* Get Method *********// + /*! + \name Get Function + */ + //@{ + + + vector<IsotopicVector> GetIVArray() const { return fIVArray; } //!< Return the IsotopicVector Array + vector<cSecond> GetIVArrayArrivalTime() const { return fIVArrayArrivalTime;} //!<Vector of arrival time of each IV in the CLASSBackEnd + + int GetIVNumber() const { return fIVArray.size();} //!< Return the number of Isotopic Vector present in the CLASSBackEnd object + bool GetStorageType() const { return fIsStorageType;} //!< Return the storageType : True if it is a Storage + IsotopicVector GetIV(int i) const { if(i < (int)fIVArray.size()) return fIVArray[i]; + else return IsotopicVector(); } +#ifndef __CINT__ + DecayDataBank* GetDecayDataBank() { return fDecayDataBase;} //!< Return the pointer to the decay DataBank + CLASSBackEnd* GetOutBackEndFacility() const { return fOutBackEndFacility;} //!<Return the pointer to the OUtBackEndFacility + virtual map<cSecond,int> GetTheBackEndTimePath(); //!< Get the full path + +#endif + + //@} + + //********* Set Method *********// + /*! + \name Set Function + */ + //@{ + void SetIsStorageType(bool val = true) { fIsStorageType = val;} //! Set the fIsStorage bool + virtual void SetIVArray(vector<IsotopicVector> ivarray) { fIVArray = ivarray; } //!< Set The isotopicVector Array +#ifndef __CINT__ + void SetDecayDataBank(DecayDataBank* decayDB) { fDecayDataBase = decayDB;} //! Set the Decay DataBank + virtual void SetOutBackEndFacility(CLASSBackEnd* befacility) { fOutBackEndFacility = befacility; + fIsStorageType = false; } //! Set an out Facility + +#endif + + using CLASSFacility::SetName; + + //@} + + + /*! + \name BackEndFacility specific Method + */ + //@{ + virtual void ApplyZAIThreshold(int z = 90); //!< Put all nuclei below the threshold in -2 -2 -2 ZAI... + + virtual void AddIV(IsotopicVector isotopicvector); //!< Add an Isotopicvector to the IVArray + void ClearIVArray(); //!< Empty the IVArray removing all fuel stored + + //@} + virtual void Evolution(cSecond t) {} //!< Performs the Evolution until time t + void UpdateInsideIV(); + + + protected : + IsotopicVector GetDecay(IsotopicVector isotopicvector, cSecond t); //!< Get IsotopicVector decay at time t [s] + vector<IsotopicVector> fIVArray; ///< Vector containning all the fuel stored. + vector<cSecond> fIVArrayArrivalTime; ///< Vector containning the arrival time of each fuel in [s] + +#ifndef __CINT__ + CLASSBackEnd* fOutBackEndFacility; //!< Facility getting the fuel at the end of the cycle +#endif + + //********* Internal Parameter *********// + private : + bool fIsStorageType; //!< True if there is no out CLASSBackEnd facility (like a Storage...) + +#ifndef __CINT__ + DecayDataBank* fDecayDataBase; //!< Pointer to the DecayDataBank +#endif + + ClassDef(CLASSBackEnd,2); +}; + +#endif + diff --git a/source/branches/BaM/include/CLASSConstante.hxx b/source/branches/BaM/include/CLASSConstante.hxx new file mode 100644 index 000000000..489b48acd --- /dev/null +++ b/source/branches/BaM/include/CLASSConstante.hxx @@ -0,0 +1,22 @@ +#ifndef _CLASSConstante_ +#define _CLASSConstante_ + +//CLASS library +#include "ZAIMass.hxx" +#include "ZAIHeat.hxx" +#include "ZAITox.hxx" +#include "DecayDataBank.hxx" + +typedef long long int cSecond; + +static const double AVOGADRO = 6.02214129e23; // Avogadro Number [1/mol] + +static const ZAIMass cZAIMass; // Mass list of all nuclei stored in [g/mol] +static const ZAIHeat cZAIHeat; // Thermal power list of all nuclei [W/nucleus] +static const ZAITox cZAITox; + +static const cSecond cYear = 3600*24*365.25; // Seconds in a year +static DecayDataBank cDecayData; // Seconds in a year + + +#endif diff --git a/source/branches/BaM/include/CLASSFacility.hxx b/source/branches/BaM/include/CLASSFacility.hxx new file mode 100644 index 000000000..8ea649e0c --- /dev/null +++ b/source/branches/BaM/include/CLASSFacility.hxx @@ -0,0 +1,217 @@ + +#ifndef _CLASSFACILITY_ +#define _CLASSFACILITY_ + + +/*! + \file + \brief Header file for CLASSFacility class. + + */ + +#include <string> +#include <fstream> + +#include "CLASSObject.hxx" +#include "IsotopicVector.hxx" + +#include "TNamed.h" + +using namespace std; + +class Scenario; +//-----------------------------------------------------------------------------// +//! Defines the common properties of all facilities + +/*! + Define a CLASS Facility. + The aim of these class is to gather all the commom properties of the facilities. + + + @author BaM + @version 2.0 + */ +//________________________________________________________________________ + + + + +class CLASSFacility : public CLASSObject +{ +public : + /*! + \name Constructor/Desctructor + */ + //@{ + + //{ + /// Normal Constructor. + /*! + Make a new Facility + \param type identification type of the facility : + \li 4 Reactor, + \li 8 Pool, + \li 16 FabricationPlant. + */ + + CLASSFacility(int type = 0); + //} + + //{ + /// Special Constructor. + /*! + Make a new Facility + \param log : used for the log. + \param type identification type of the facility : + \li 4 Reactor, + \li 8 Pool, + \li 16 FabricationPlant. + + */ + CLASSFacility(CLASSLogger* log, int type = 0); + //} + + //{ + /// Special Constructor. + /*! + Make a new Facility + \param log : used for the log. + \param cycletime duration of the cycle [s], + \param type identification type of the facility : + \li 4 Reactor, + \li 8 Pool, + \li 16 FabricationPlant. + + */ + CLASSFacility(CLASSLogger* log, cSecond cycletime, int type = 0); + //} + + //{ + /// Special Constructor. + /*! + Make a new Facility + \param log : used for the log. + \param creationtime creation date of the Facility [s], + \param lifetime operating duration [s], + \param type identification type of the facility : + \li 4 Reactor, + \li 8 Pool, + \li 16 FabricationPlant. + + */ + CLASSFacility(CLASSLogger* log, cSecond creationtime, cSecond lifetime, int type = 0); + //} + + //{ + /// Special Constructor. + /*! + Make a new Facility + \param log : used for the log. + \param creationtime creation date of the Facility [s], + \param lifetime operating duration [s], + \param cycletime duration of the cycle [s], + \param type identification type of the facility : + \li 4 Reactor, + \li 8 Pool, + \li 16 FabricationPlant. + + */ + CLASSFacility(CLASSLogger* log, cSecond startingtime, cSecond lifetime, cSecond cycletime, int type = 0); + //} + + //********* Get Method *********// + /*! + \name Get Function + */ + //@{ + + int GetId() const { return fId; } //!< Return the Facility Parc'Is + IsotopicVector GetInsideIV() const { return fInsideIV; } //!< Return the IV contained in the Facility + + int GetFacilityType() const { return fFacilityType; } //!< Return the Facility Type id + + cSecond GetInternalTime() const { return fInternalTime; } //!< Return Creation Time + + cSecond GetCycleTime() const { return fCycleTime; } //!< Return the cycle time of the Facility + cSecond GetCreationTime() const { return fCreationTime; } //!< Return the creation time of the Facility + cSecond GetLifeTime() const { return fLifeTime; } //!< Return the life time of the Facility + Scenario* GetParc() { return fParc; } //!< return the pointer to the Park + + + IsotopicVector GetCumulativeIVIn() { return fCumulativeIVIn;} //!< return the cumulative sum of all incoming IV + IsotopicVector GetCumulativeIVOut() { return fCumulativeIVOut;} //!< return the cumulative sum of all outcoming IV + //@} + + //********* Set Method *********// + /*! + \name Set Function + */ + //@{ + void SetId(int id) { fId = id; } //!< Set The Facility Parc'Id + void SetParc(Scenario* parc) { fParc = parc; } //!< Set the Pointer to the Parc + void SetFacilityType(int type) { fFacilityType = type; } //!< Set the facility type : + /// \li 2 reactor Studown + /// \li 4 start/End of reactor cycle, + /// \li 8 end of Cooling, + /// \li 16 fuel Fabrication + using CLASSObject::SetName; + using CLASSObject::GetName; + + + void SetInsideIV(IsotopicVector isotopicvector) { fInsideIV = isotopicvector; } //!< Set the IV inside the Facility + + void SetCreationTime(cSecond CTtime) { fCreationTime = CTtime;} //!< Set the creation Time + void SetLifeTime(cSecond Ltime) { fLifeTime = Ltime; } //!< Set the life time of the facility + void SetShutDownTime(cSecond SDTime) { fLifeTime = SDTime-fCreationTime; } //!< Set the shutdown time of the facility + + void SetInCycleTime(cSecond ICtime) { fInCycleTime = ICtime; fIsStarted = true; } //!< Set the In cycle time + void SetInternalTime(cSecond INtime) { fInternalTime = INtime; } //!< Set the Internal Time + virtual void SetCycleTime(cSecond Ctime){ fCycleTime = Ctime; } //!< Set the cycle time (Cycle of the loading Plan) + + //@} + + + /*! + \name Evolution Method + */ + //@{ + virtual void ApplyZAIThreshold(int z = 90); //!< Put all nuclei below the threshold in -2 -2 -2 ZAI... + void AddCumulativeIVIn(IsotopicVector IV) { fCumulativeIVIn += IV;} //!< Add the Input IsotopicVector in the cumulative IV IN + void AddCumulativeIVOut(IsotopicVector IV) { fCumulativeIVOut += IV;} //!< Add the Input IsotopicVector in the cumulative IV OUT + virtual void Evolution(cSecond t) = 0; //!< Performs the Evolution to time t + virtual void Dump() { } //!< Write Modification (IV In/Out, filling the TF...) + + //@} +protected : + bool fIsStarted; ///< True if Running, False Otherwise + bool fIsShutDown; ///< True if the facility is stoped, False Otherwise + bool fIsAtEndOfCycle; ///< True if Reaching the end of a Facility cycle + + + cSecond fInternalTime; ///< Internal Clock [s] + cSecond fInCycleTime; ///< Time spent since the beginning of the last Cycle [s] + cSecond fCycleTime; ///< Cycle duration Time [s] + + IsotopicVector fInsideIV; ///< All IV in the Facility (fuel for reactor, total for all others...) + IsotopicVector fCumulativeIVIn; ///< All IV in the Facility (fuel for reactor, total for all others...) + IsotopicVector fCumulativeIVOut; ///< All IV in the Facility (fuel for reactor, total for all others...) + + //********* Internal Parameter *********// +private : + int fId; //!< Identity of the Facility inside the Scenario + int fFacilityType; ///< Type of facility : + /// \li 4 reactor, + /// \li 8 Pool, + /// \li 16 FabricationPlant. + + + Scenario* fParc; //!< Pointer to the main Scenario + + cSecond fCreationTime; ///< CLASS Universal Time of Creation [s] + cSecond fLifeTime; ///< Time of life Of the Reactor (operating's duration) [s] + + ClassDef(CLASSFacility,1); +}; + +#endif + diff --git a/source/branches/BaM/include/CLASSFuel.hxx b/source/branches/BaM/include/CLASSFuel.hxx new file mode 100644 index 000000000..03d9dbc96 --- /dev/null +++ b/source/branches/BaM/include/CLASSFuel.hxx @@ -0,0 +1,85 @@ + +#ifndef _CLASSFUEL_ +#define _CLASSFUEL_ + + +/*! + \file + \brief Header file for CLASSFuel class. + + + @author BaM + @version 2.0 + */ + +#include <string> +#include <fstream> + +#include "CLASSObject.hxx" +#include "PhysicsModels.hxx" +#include "EvolutionData.hxx" + +using namespace std; + +//-----------------------------------------------------------------------------// +//! Allows to define PhysicsModels & EvolutionData as a CLASSFuel + +/*! + Define a CLASS Object. + The aim of these class is to handle PhysicsModels & + EvolutionData as a CLASSFuel . + + @author BaM + @version 3.0 + */ +//________________________________________________________________________ + + + +class CLASSFuel : public CLASSObject +{ + public : + /*! + \name Constructor/Desctructor + */ + //@{ + + //{ + /// EvolutionData Constructor. + /*! + Make a new CLASSObject + /param evo : EvolutionData stored + */ + CLASSFuel(EvolutionData* evo); + //} + + //{ + /// PhysicsModels Constructor. + /*! + Make a new CLASSObject + /param evo : PhysicsModels stored + */ + CLASSFuel(PhysicsModels* evo); + //} + //@} + + + virtual CLASSFuel* Clone() { return new CLASSFuel(*this); } //!< Correct way to copy a CLASSFuel in case of derivation + + + EvolutionData* GetEvolutionData() {return fEvolutionData;} //!< Return the EvolutionData (NULL if PhysicsModels) + PhysicsModels* GetPhysicsModels() {return fPhysicsModels;} //!< Return the PhysicsModels (NULL if EvolutionData) + + using CLASSObject::SetName; + using CLASSObject::GetName; + protected : + + + private : + + EvolutionData* fEvolutionData; //!< the EvolutionData (NULL if PhysicsModels) + PhysicsModels* fPhysicsModels; //!< the PhysicsModels (NULL if EvolutionData) +}; + +#endif + diff --git a/source/branches/BaM/include/CLASSFuelPlan.hxx b/source/branches/BaM/include/CLASSFuelPlan.hxx new file mode 100644 index 000000000..e0042f747 --- /dev/null +++ b/source/branches/BaM/include/CLASSFuelPlan.hxx @@ -0,0 +1,100 @@ + +#ifndef _CLASSFUELPLAN_HXX +#define _CLASSFUELPLAN_HXX + + +/*! + \file + \brief Header file for CLASSFuelPlan class. + + + @author BaM + @version 2.0 + */ + +#include <string> +#include <fstream> +#include <map> + +#include "CLASSObject.hxx" +#include "CLASSFuel.hxx" + +using namespace std; +typedef long long int cSecond; + + +//-----------------------------------------------------------------------------// +//! Allows a Reactor to change its CLASSFuel and/or burnup + +/*! + Define a CLASS Object. + The aim of these class is to allow a Reactor to change its CLASSFuel and/or burnup + during its lifetime + + @author BaM + @version 2.0 + */ +//________________________________________________________________________ + + + +class CLASSFuelPlan : public CLASSObject +{ + public : + /*! + \name Constructor/Desctructor + */ + //@{ + + //{ + /// CLASSFuelPlan Constructor. + /*! + Make a new CLASSFuelPlan + */ + CLASSFuelPlan(); + //} + + //{ + /// CLASSFuelPlan Constructor. + /*! + Make a new CLASSFuelPlan + \param log : used for the log. + */ CLASSFuelPlan(CLASSLogger* log); + //} + //@} + + /*! + \name Adding Method + */ + //@{ + + void AddFuel(cSecond time, CLASSFuel fuel, double BurnUp); //!< Add A new CLASSFuel at the corresponding time and Burnup + void AddFuel(cSecond time, EvolutionData* fuel, double BurnUp) + { AddFuel( time, CLASSFuel(fuel), BurnUp); } //!< Add A new EvolutionData at the corresponding time and Burnup + void AddFuel(cSecond time, PhysicsModels* fuel, double BurnUp) + { AddFuel( time, CLASSFuel(fuel), BurnUp); } //!< Add A new Physicis Model at the corresponding time and Burnup + + //a} + + /*! + \name Get Method + */ + //@{ + + pair< CLASSFuel, double> GetFuelAt(cSecond t); //!< Get fuel and associated Burnup loaded at the time t + + + //@} + using CLASSObject::SetName; + using CLASSObject::GetName; + protected : + + + private : + + map< cSecond, pair< CLASSFuel, double > > fLoadingPlan; ///< Loading plan to change the EvolutionData (and the associeted Burnup) according to the plan + +}; + +#endif + diff --git a/source/branches/BaM/include/CLASSHeaders.hxx b/source/branches/BaM/include/CLASSHeaders.hxx new file mode 100755 index 000000000..8fb55cd2f --- /dev/null +++ b/source/branches/BaM/include/CLASSHeaders.hxx @@ -0,0 +1,24 @@ +#ifndef _CLASSHEADERS_ +#define _CLASSHEADERS_ + + + + +//CLASS library +#include "CLASSConstante.hxx" +#include "Scenario.hxx" +#include "Reactor.hxx" +#include "Pool.hxx" +#include "FabricationPlant.hxx" +#include "SeparationPlant.hxx" +#include "Storage.hxx" +#include "IsotopicVector.hxx" +#include "ZAI.hxx" +#include "CLASSLogger.hxx" + +#include "EvolutionData.hxx" +#include "PhysicsModels.hxx" + + + +#endif diff --git a/source/branches/BaM/include/CLASSLogger.hxx b/source/branches/BaM/include/CLASSLogger.hxx new file mode 100755 index 000000000..3c9ab8de5 --- /dev/null +++ b/source/branches/BaM/include/CLASSLogger.hxx @@ -0,0 +1,216 @@ +#ifndef _LOG_ +#define _LOG_ + + +/*! + \file + \brief Header file for CLASSLogger class. + + + @author BaM + @version 2.0 + */ + +#include <string> +#include <fstream> + +#include <iostream> +#include <cstring> +#include <sstream> +#include "stdlib.h" +using namespace std; + + +#ifndef __CINT__ + +#define ERROR if(fLog)if(fLog->GetMaxOutPutLVL() >= 0) fLog->E() << "!!!ERROR!!! " << "[" << __FILE__ << ":" << __FUNCTION__ << "] " +#define WARNING if(fLog)if(fLog->GetMaxOutPutLVL() >= 1) fLog->W() << "!!WARNING!! " << "[" << __FILE__ << ":" << __FUNCTION__ << "] " +#define INFO if(fLog)if(fLog->GetMaxOutPutLVL() >= 2) fLog->I() << "!!!!INFO!!! " << "[" << __FILE__ << "] " + +#define DBGL if(fLog)if(fLog->GetMaxOutPutLVL() >= 3) fLog->D() << __FILE__ << " : " << __LINE__ << " [" << __FUNCTION__ << "]" << endl; +#define DBGV(x) {if(fLog)if(fLog->GetMaxOutPutLVL() >= 3) fLog->D() << __FILE__ << " : " << __LINE__ << " [" << __FUNCTION__ << "]" << x << endl;} + +#else + +#define ERROR cout +#define INFO cout +#define WARNING cout +#define DBGL +#define DBGV(x) + + +#endif + + + +#ifndef _LOGTYPE_ +#define _LOGTYPE_ + +//-----------------------------------------------------------------------------// +//!handles output stream in CLASS + +/*! + Define a LogType. + The aim of this class is to handle output stream in CLASS. + + + @author BaM + @version 2.0 + */ +//________________________________________________________________________ + + +class LogType +{ +public: + //********* Constructor/Destructor Method *********// + + /*! + \name Constructor/Desctructor + */ + //@{ + + //{ + /// Normal Constructor. + /*! + Make a new LogType + \param Log : ostream output + */ + LogType(ostream &Log) { fLog = &Log; fLog2 = 0; } //!< Normal Constructor + //} + + ~LogType() {} //!< Normal Destructor + + //@} + + //********* In/Out Method *********// + + /*! + \name In/Out + */ + //@{ + string GetCLASSLoggerName() const { return fCLASSLoggerName; } //!< return the CLASSLogger name + + LogType &operator << (std::ostream& (*manip)(std::ostream &)) + { + manip( *(this->fLog) ); + if(fLog2) + manip( *(this->fLog2) ); + return *this; + } + + + template<typename T> + inline LogType& operator << (T something) + { + *(this->fLog) << something; + if(fLog2) + *(this->fLog2) << something; + return *this; + } + //} + + void SetSecondOutput(ostream &log) {fLog2 = &log;} // used to direct the stream into two output ostream + + private : + + ostream *fLog; //!< Main ostream output + ostream *fLog2; //!< secondary ostream output + + string fCLASSLoggerName; //!< Log File name +}; + + +#endif + + +#ifndef _CLASSLogger_ +#define _CLASSLogger_ + +//-----------------------------------------------------------------------------// +//! Object to handle output messages + +/*! + Define a CLASSLogger. + The aim of this class is to centralize the all CLASS software message inside a file. + + + @author BaM + @version 2.0 + */ +//________________________________________________________________________ + + +class CLASSLogger +{ +public: + + //********* Constructor/Destructor Method *********// + + /*! + \name Constructor/Desctructor + */ + //@{ + //{ + /// Normal Constructor. + /*! + Make a new LogType + \param CLASSLoggerName : name of the CLASSLogFile wnated for the log + \param VerboseLvl : verbose level in terminal + \param OutputLvl : verbose level in the CLASSLogFile + + The different available levels are : + \li 0 : ERROR only + \li 1 : WARNING + lvl 0 + \li 2 : INFO + lvl 1 + \li 3 : DEBUG + lvl 2 + + */ + CLASSLogger(string CLASSLoggerName = "CLASS_OUTPUT.log", int VerboseLvl = 0, int OutputLvl = 1 ); + //} + + ~CLASSLogger(); //!< Normal Destructor + + //@} + + //********* In/Out Method *********// + + /*! + \name In/Out + */ + //@{ + string GetCLASSLoggerName() const { return fCLASSLoggerName; } //!< return the CLASSLogger name + int GetMaxOutPutLVL() const { return fMaxOutPutLVL; } //!< Return File Output lvl + int GetVerboseLVL() const { return fVerboseLVL; } + + LogType E() {return *fError;} //!< Return the ERROR Streamer + LogType W() {return *fWarning;} //!< Return the WARNING Streamer + LogType I() {return *fInfo;} //!< Return the INFO Streamer + LogType D() {return *fDebug;} //!< Return the DEBUG Streamer + +//@} + + + + + private : + int fMaxOutPutLVL; //!< Maximal output/verbose lvl + int fVerboseLVL; + + LogType* fError; //!< ERROR streamer + LogType* fInfo; //!< INFO streamer + LogType* fWarning; //!< WARNING streamer + LogType* fDebug; //!< DEBUG streamer + + ofstream fOutPutFile; //!< Log Output File name + string fCLASSLoggerName; //!< Log File name +}; + +#endif + + + +#endif + + + diff --git a/source/branches/BaM/include/CLASSMethod.hxx b/source/branches/BaM/include/CLASSMethod.hxx new file mode 100644 index 000000000..b59391f9e --- /dev/null +++ b/source/branches/BaM/include/CLASSMethod.hxx @@ -0,0 +1,42 @@ +#ifndef _CLASSMETHOD_ +#define _CLASSMETHOD_ + +#include <cmath> +#include <iostream> +#include <iomanip> +#include <stdlib.h> +#include <algorithm> + +struct my_tolower +{ + char operator()(char c) const + { + return std::tolower(static_cast<unsigned char>(c)); + } +}; + +//To Lower Case, convert any string in lower case +static std::string tlc(string data) +{ + transform(data.begin(), data.end(), data.begin(), my_tolower()); + return data; +}; + + + +static float random(float a, float b) //peak random numebr between a and b +{ + float range = pow(2., 31); + srand(time(NULL)); //initialize the srand + return (float)a + (float)(b-a)*rand()/range; +}; + +static std::string dtoa(double num) +{ + std::ostringstream os(std::ostringstream::out); + os << setprecision(3) << num; + return os.str(); +}; + + +#endif diff --git a/source/branches/BaM/include/CLASSNucleiFiliation.hxx b/source/branches/BaM/include/CLASSNucleiFiliation.hxx new file mode 100644 index 000000000..46e6b2d4b --- /dev/null +++ b/source/branches/BaM/include/CLASSNucleiFiliation.hxx @@ -0,0 +1,123 @@ +#ifndef _CLASSNucleiFiliation_ +#define _CLASSNucleiFiliation_ + +/*! + \file + \brief Header file for CLASSNucleiFiliation classes. + */ + +#include "CLASSObject.hxx" +#include "IsotopicVector.hxx" + +using namespace std; + +//-----------------------------------------------------------------------------// +//! Handles connection between nuclei (decay/reaction) + +/*! + Define a nuclei as : Z A I. + The aim of this class is to discribe each CLASSNucleiFiliation. It connects nuclei to their daughter nuclei through a nuclear process using the correct branching ratio. + Note that this class can be used to connect nulei to their daughter through any reaction (Fission, capture...) or natural decay process... + + In the case of decay process, it is possible to put (by multiplying) the decay constant to the branching ratio (ie : BR*log(2)/HalfLife, see IrradiationModel).... + + + @author BaM + @version 2.0 + */ +//________________________________________________________________________ + + + +class CLASSNucleiFiliation : public CLASSObject +{ +public: + + + //********* Constructor/Destructor Method *********// + + /*! + \name Constructor/Desctructor + */ + //@{ + + CLASSNucleiFiliation(); ///< Default constructor + + + /*! + \name Constructor/Desctructor + */ + //@{ + //{ + /*! + Use to load a CLASSNucleiFiliation + \param log : used for the log. + */ + CLASSNucleiFiliation(CLASSLogger* log); ///< Default constructor + //} + + CLASSNucleiFiliation(const CLASSNucleiFiliation& CNF); ///< Copy Constructor + + + ~CLASSNucleiFiliation(); ///< Normal Destructor. + + //@} + + + //********* Get Method *********// + + /*! + \name Set/Get Method + */ + //@{ + map<ZAI, IsotopicVector> GetNucleiFIliation() const {return fNucleiFiliation;} //!< Return the full filiation list + vector<ZAI> GetZAIList() const; //!< Return the list of mother ZAI present in the filiation list + int size() const{return (int)fNucleiFiliation.size();} //!< Return the number of mother ZAI (then filiation path) + + IsotopicVector GetFiliation(ZAI Mother); //!< Return the filiation isotopic vector of the ZAI mother + + ZAI GetArtificialDecay(ZAI Mother); //!< Make an artificial and instantaneus decay of the ZAI, (desexcitation, or Beta decay) + + + void SetNucleiFIliation(map<ZAI, IsotopicVector> Fiiliation) { fNucleiFiliation = Fiiliation;} //!< Set the full filiation list + + //} + + //********* Add Method *********// + + /*! + \name Adding Method + */ + //@{ + void Add(ZAI Mother, IsotopicVector Daughter ); //!< Add A ZAI and its IsotopicVector of daughter(s) to the filiation + //} + + + //********* Modification Method *********// + + /*! + \name Modification Method + */ + //@{ + + + void FiliationCleanUp(map<ZAI, int> GoodNuclei, CLASSNucleiFiliation CuttedNuclei); //!< Cutting all pathway until each path ends on a nuclei in the GoodList following the CuttedNuclei. If nuclei are neither in the GoodNuclei list or in CuttedNuclei, then artificial decay are performed + + void SelfFiliationCleanUp(map<ZAI, int> GoodNuclei); //!< Cutting all the pathway ending on a nuclei not present as a mother nuclei + + void NormalizeBranchingRatio(double Value = 1); //!< Normalization of all the branching ratio to 1 + + void NormalizeBranchingRatio(ZAI Mother, double Value); //!< Normalize the branching ratio pathway of the Mother ZAI to the set value + + //} + + + protected : + + map<ZAI, IsotopicVector> fNucleiFiliation; //! Map of all the pathway + + +}; + + +#endif diff --git a/source/branches/BaM/include/CLASSObject.hxx b/source/branches/BaM/include/CLASSObject.hxx new file mode 100644 index 000000000..8d2f1d538 --- /dev/null +++ b/source/branches/BaM/include/CLASSObject.hxx @@ -0,0 +1,102 @@ + +#ifndef _CLASSOBJECT_ +#define _CLASSOBJECT_ + + +/*! + \file + \brief Header file for CLASSObject class. + + + @author BaM + @version 2.0 + */ + +#include <string> +#include <fstream> + +#include "CLASSLogger.hxx" + +#include "TNamed.h" + +using namespace std; + +//-----------------------------------------------------------------------------// +//! Define common proporties of all objects + +/*! + Defines a CLASS Object. + The aim of these class is to gather all the commom properties of all CLASS objects. + + + @author BaM + @version 2.0 + */ +//________________________________________________________________________ + + + +class CLASSObject : public TNamed +{ +public : + /*! + \name Constructor/Desctructor + */ + //@{ + + //{ + /// Normal Constructor. + /*! + Make a new CLASSObject + */ + CLASSObject(); + //} + + //{ + /// Log Constructor. + /*! + Make a new CLASSObject + \param log : used for the log. + */ + + CLASSObject(CLASSLogger* log); + //} + //@} + + /*! + \name Clone + */ + //@{ + + virtual CLASSObject* Clone() { return new CLASSObject(*this); } //!< Correct way to copy a CLASSObject in case of derivation + //} + //@} + + + /*! + \name Set/Get + */ + //@{ + + +#ifndef __CINT__ + void SetLog(CLASSLogger* log) { fLog = log;} //!< Set the CLASSLogger + CLASSLogger* GetLog() { return fLog; } //!< Return the Pointer to the Log +#endif + //@} + + using TNamed::SetName; + using TNamed::GetName; +protected : +#ifndef __CINT__ + CLASSLogger* fLog; //!< Pointer to the Log +#endif + + +private : + + ClassDef(CLASSObject,0); +}; + +#endif + diff --git a/source/branches/BaM/include/DecayDataBank.hxx b/source/branches/BaM/include/DecayDataBank.hxx new file mode 100644 index 000000000..539dafedb --- /dev/null +++ b/source/branches/BaM/include/DecayDataBank.hxx @@ -0,0 +1,178 @@ +#ifndef _DecayDataBank_ +#define _DecayDataBank_ + +/*! + \file + \brief Header file for DecayDataBank class. + @version 2.0 + */ + +#include "CLASSObject.hxx" +#include "EvolutionData.hxx" +#include "IsotopicVector.hxx" + +#include <map> +#include <vector> + + +using namespace std; +typedef long long int cSecond; + +class ZAI; +class CLASSLogger; + +double ReactionRateWeightedDistance(IsotopicVector IV1, EvolutionData DB ); +double ReactionRateWeightedDistance(EvolutionData DB, IsotopicVector IV1 ); + +//-----------------------------------------------------------------------------// +//! Describes outcore radioactive decays + +/*! + Define a DecayDataBank. + The aim of these class is to describe the evolution of "all" evoluting systems in CLASS. + + For the Decay Matrix the DecayDataBank mainly contains a map of <ZAI,EvolutionData>.This map do the correspondance between a ZAI and its decay evolution (containing all the daughter nuclei comming from the decay of the original ZAI and quantities evolutions). + + @author BaM + @author Marc + @author PTO for a part of the Decay management -- steal from MURE (Even if he does not kown it!! :)) + @version 2.0 + */ +//________________________________________________________________________ + + + +class DecayDataBank : public CLASSObject +{ + + public : + + + //********* Constructor/Desctructor *********// + + /*! + \name Constructor/Desctructor + */ + //@{ + /// Normal Constructor. + DecayDataBank(); + + + //{ + /// Special Constructor. + /*! + Use to load a DecayDataBank + \param DB_index_file : path to the index file + \param olfreadmethod : true if the old format of EvolutionData are used (deprecated) (ie without the key word such as Inv, XSFiss...) + */ + DecayDataBank(string DB_index_file ); + //} + //{ + /// Special Constructor. + /*! + Use to load a DecayDataBank + \param Log : CLASSLogger used for the log. + \param DB_index_file : path to the index file + \param olfreadmethod : true if the old format of EvolutionData are used (ie without the key word such as Inv, XSFiss...) + */ + DecayDataBank(CLASSLogger* Log, string DB_index_file ); + //} + + //{ + /// Normal Destructor. + /*! + Delete the DecayDataBank and all associated EvolutionData(s)... + */ + ~DecayDataBank(); + //} + + //{ + /// Reset the DecayDataBank. + /*! + Use to reset the DecayDataBank to its default values whihout deleting the EvolutionData (which contain pointer... ). + it just clears the different maps + */ + void Clear(); + //} + //@} + + + + + //********* Get Method *********// + /*! + \name Get Method + */ + //@{ + map<ZAI ,EvolutionData > GetDecayDataBank() const { return fDecayDataBank; } //!< Return the DecayDataBank + bool IsDefine(const ZAI& zai) const; //!< True if the key is define, false unstead + + string GetDataBaseIndex() const { return fDataBaseIndex; } //!< Return the index name + + IsotopicVector GetDecay(IsotopicVector isotopicvector, cSecond t); //!< Get IsotopicVector decay at time t + + //@} + + + + + //********* Set Method *********// + + /*! + \name Set Method + */ + //@{ + + void SetDecayDataBank(map<ZAI ,EvolutionData > mymap) + { fDecayDataBank = mymap; } //!< Set the DecayDataBank map + + void SetDataBaseIndex(string database) { fDataBaseIndex = database;; ReadDataBase(); } //!< Set the name of the database index + + void SetFastCalculation(bool val) { fFastCalculation = val; } + //} + + + + + //********* Evolution Method *********// + + //@} + /*! + \name Evolution Method + */ + //@{ + + IsotopicVector Evolution(const ZAI& zai, double dt); ///< Return the IsotopicVector from the decay of zai during a dt period + + //@} + + + + + //********* Other Method *********// + /*! + \name Other Method + */ + //@{ + void ReadDataBase(); ///< Read the index file and fill the EvolutionData map + + void Print() const; + + //@} + + + + + + protected : + + bool fFastCalculation; + + map<ZAI, EvolutionData> fDecayDataBank; ///< DataBank map + string fDataBaseIndex; ///< Name of the index + +}; + + + +#endif diff --git a/source/branches/BaM/include/DynamicalSystem.hxx b/source/branches/BaM/include/DynamicalSystem.hxx new file mode 100755 index 000000000..a98d012d5 --- /dev/null +++ b/source/branches/BaM/include/DynamicalSystem.hxx @@ -0,0 +1,127 @@ +#ifndef _DynamicalSystem_ +#define _DynamicalSystem_ +/*! + \file + \brief Header file for DynamicalSystem class. +*/ + +#include <math.h> +#include <vector> + + +using namespace std; + +//-----------------------------------------------------------------------------// + + + +//! DynamicalSystem class solves system of differential equations. +/*! +// A DynamicalSystem is a base class that solves system differential equations of 1st order. +// @f[ \frac{d\vec{Y}}{dt} = A\vec{Y}@f] +// The differential equations are built in DynamicalSystem::BuildEqns ; the method MUST be +// defined in the derived classes. +// In this first version only Runge-Kutta method is implemented, but the aim of this class +// is to provide also other methods such as CRAM (Chebyshev rational approximation method). +// +// +// @author PTO. +// @version 1.0 +*/ +//________________________________________________________________________ + +class DynamicalSystem +{ + public : + + DynamicalSystem(); //!< Normal Constructor + DynamicalSystem(const DynamicalSystem & DS); //!< Copy Constructor + virtual ~DynamicalSystem(); //!< Destructor + + /*! + \name Mains attributes of the DynamicalSystem + */ + //@{ + int GetNumberOfEquationSize(){return fNVar;} //!< return the number of equations. + void SetNumberOfEquationSize(int n){fNVar = n;} //!< set the number of equations. + //@} + + /*! + \name Runge-Kutta related methods + Algorithms are taken from Numerical Receipes. + */ + //@{ + + void SetPrecision(double eps = 1e-5){fPrecision = eps;} //!< set RK precision to change the integration step + + //! Forbid negative value during integration. + /*! + For some quantities (such as nuclei composition), negative values are forbidden. + But, due to integration step and very fast variation of the integrated variables + Runge-Kutta wil produce very small negative value. This method is used to force + negative value to be zero. + */ + void SetForbidNegativeValue(){fIsNegativeValueAllowed = false;} + + //! Runge Kutta calling method. + /*! + // \param YStart: input : the initial condition Y(t1) ; output the final value Y(t2) + // \param t1: initial time + // \param t2: final time + */ + void RungeKutta(double *YStart, double t1, double t2, int EquationNumber); + + //! Builds the equations for integration. + /*! + This method is an abstract method ; it MUST be overwritten by derived classes. + // \param t: time at which the equations are built + // \param Y: array of variable at time t + // \param dYdt: ode's variable. + */ + virtual void BuildEqns(double t, double *Y, double *dYdt){} + + //@} + + /*! + \name Miscellaneous methods + */ + //@{ + + //@} + + protected : + //! Runge Kutta main method. + /*! + // Call by RungeKutta + // \param y: initial values to integrate + // \param dydx: ode's equations (variable is x) + // \param x: variable of integration + // \param h: step size for integration + // \param yout: result after integration + */ + void RK4(double *y, double *dydx, double x, double h, double *yout); + //! Adaptative Step Size method for RK. + /*! + // Call by RK4 + // \param y: initial values to integrate + // \param dydx: ode's equations (variable is x) + // \param x: new value of the variable after the adaptative step + // \param htry: try step size for integration + // \param eps: precision + // \param yscal: result after hdid step integration + // \param hdid: did step size for integration + // \param hnext: next step size for integration + */ + void AdaptStepSize(double *y, double *dydx, double *x, double htry, double eps, double *yscal, double *hdid, double *hnext); + + int fNVar; //!< The size of the composition vector and /or number of ZAIs involved. + double fPrecision; //!< Precision of the RungeKutta + double fHestimate; //!< RK Step estimation. + double fHmin; //!< RK minimum Step. + double fMaxHdid; //!< store the effective RK max step + double fMinHdid; //!< store the effective RK min step + bool fIsNegativeValueAllowed; //!< whether or not negative value are physical. +}; + +#endif + diff --git a/source/branches/BaM/include/EquivalenceModel.hxx b/source/branches/BaM/include/EquivalenceModel.hxx new file mode 100644 index 000000000..338cc0920 --- /dev/null +++ b/source/branches/BaM/include/EquivalenceModel.hxx @@ -0,0 +1,232 @@ +#ifndef _EQUIVALENCEMODEL_ +#define _EQUIVALENCEMODEL_ + + +/*! + \file + \brief Header file for EquivalenceModel class. + + + @author BaM + @author BLG + @version 3.0 + */ + +#include "IsotopicVector.hxx" +#include <math.h> +#include <map> +#include "CLASSObject.hxx" + + +using namespace std; + +class EquivalenceModel; +#ifndef __CINT__ +typedef void (EquivalenceModel::*EQM_MthPtr)( const string & ); +#endif + +//-----------------------------------------------------------------------------// + +//! Determines how to build a fresh fuel +/*! + Define an EquivalenceModel. + The aim of these class is to gather all the commum properties of all + Equivalence Model. + + \warning + Never instantiate EquivalenceModel in your CLASS input but it's derivated class + @see EQM_FBR_BakerRoss_MOX. + @see EQM_PWR_MLP_MOX + @see EQM_FBR_MLP_Keff.hxx + @see EQM_PWR_MLP_MOX_Am + @see EQM_FBR_MLP_Keff_BOUND + @see EQM_PWR_POL_UO2 + @see EQM_MLP_Kinf.hxx + @see EQM_PWR_QUAD_MOX + @see EQM_PWR_LIN_MOX + + @author BLG + @author BaM + + @version 3.0 + */ +//________________________________________________________________________ + + +class EquivalenceModel : public CLASSObject +{ + public : + /*! + \name Constructor/Desctructor + */ + //@{ + EquivalenceModel(); //!< Default constructor + EquivalenceModel(CLASSLogger* log); //!< Logger constructor + + virtual ~EquivalenceModel(); //!< Destructor + //@} + + /*! + \name Fuel Construction Method + */ + //@{ + + //{ + /// BuildFuel function. + /*! + Build the fuel following the equivalance model with the proper requierment in term of mass, burnup.... + \param double burnup reached by the fuel at the end of irradiation + \param double HMMass, Heavy metal mass needed + \param vector<double> &lambda, fraction of the stock to take (initialy should be 0) + \param vector<IsotopicVector> FissilArray, isotopicvectors to use to get the fissile part of the fuel + \param vector<IsotopicVector> FertilArray, isotopicvectors to use to get the fertile part of the fuel (if empty take it from the OutIncome) + */ + virtual vector<double> BuildFuel(double BurnUp, double HMMass, vector<IsotopicVector> FissilArray, vector<IsotopicVector> FertilArray ); + //} + + //@} + + /*! + \name Get/Set Method + */ + //@{ + + IsotopicVector GetFertileList() {return fFertileList;} //!<return the fertile list + IsotopicVector GetFissileList() {return fFissileList;} //!<return the fissile list + + double GetBuildFuelFirstGuess(){return fFirstGuessFissilContent;} //!<Get the initialization value for BuildFuel algorithm + virtual double GetFissileMolarFraction(IsotopicVector Fissil,IsotopicVector Fertil,double BurnUp) {return 0;} //!< Return the molar fraction of fissile element in the fuel according to the burnup, and a given fuel composition (this is the heart of the equivalence model) + + double GetRelativMassPrecision() const { return fRelativMassPrecision; } //!< Mass precision + int GetMaxInterration() const { return fMaxInterration; } //!< Max iterration in build fueld algorythm + + double GetActualFissileContent() const { return fActualFissileContent; } //!< Get the fissile content at the actual algorithm step (usefull for EQM_MLP_Kinf) + + void SetFertileList(IsotopicVector IV) {fFertileList = IV;}//!<set the fertile list + void SetFissileList(IsotopicVector IV) {fFissileList = IV;}//!<set the fissile list + void SetBuildFuelFirstGuess(double FirstGuess){fFirstGuessFissilContent = FirstGuess;} //!<set the initialization value for BuildFuel algorithm + void SetRelativMassPrecision( double val) { fRelativMassPrecision = val; } //!< Mass precision + void SetMaxInterration(int val) { fMaxInterration = val; } //!< Max iterration in build fueld algorythm + + //@} + + + + /*! + \name Reading NFO related Method + */ + //@{ + void ReadNFO(); + virtual void ReadLine(string line); + + + virtual void LoadKeyword(); + void ReadZAIlimits(const string &line); + void ReadType(const string &line); + + + //{ + /// ReadSpecificPower : read the Specific Power of the DataBase + /*! + \param line : line suppossed to contain the Specific Power information starts with "k_specpower" keyword + */ + void ReadSpecificPower(const string &line); + //} + + //{ + /// ReadMaximalContent : read the approx. maximum fissile content reachable by the MLP model + /*! + \param line : line suppossed to contain the maximal content information starts with "k_contentmax" keyword + */ + void ReadMaximalContent(const string &line); + //} + + + //{ + /// ReadFissil : read the zai name in the TMWA MLP model starts with "k_fissil" keyword + /*! + \param line : line suppossed to contain the fissil list + */ + void ReadFissil(const string &line); + //} + + //{ + /// ReadFertil : read the zai name in the TMWA MLP model starts with "k_fertil" keyword + /*! + \param line : line suppossed to contain the fertil list & their default isotopic fraction + */ + void ReadFertil(const string &line); + //} + + void PrintInfo(); //Print the information red in the INFO stream + + //@} + + + bool isIVInDomain(IsotopicVector IV); + + + protected : + + IsotopicVector fFertileList; //!< contain the list of zai, needed as fertile, taken in a stock before fabrication + //!< if no stock are provided, will take the isotopic vector in the Park income + + IsotopicVector fFissileList; //!< contain the list of zai, needed as fissile, taken in a stock before fabrication + //!< if no stock are provided the fuel will not be made + + double fFirstGuessFissilContent;//!< fissile content for BuildFuel initialization (in weight proportion) + double fActualFissileContent; //!< fissile content at the actual dichotomy step (usefull for EQM_MLP_Kinf) + + + protected : + /*! + \name Algorithm parameters + */ + //@{ + double fRelativMassPrecision; //!< Mass precision + int fMaxInterration; //!< Max iterration in build fueld algorythm + //@} + + /*! + \name Algorithm related functions for default BuildFuel function + */ + //@{ + void SetLambda(vector<double>& lambda ,int FirstStockID, int LastStockID, double LAMBDA_TOT); //!< Set individual lambda according to the LAMBDA_TOT (lambda of all stocks) + void SetLambdaToErrorCode(vector<double>& lambda); //!< Set all vector elements to -1 + double LAMBDA_TOT_FOR(double MassNeeded, vector<IsotopicVector> StockArray, string FisOrFer); //!< Calculate the proportion of each stocks in StockArray to take in oder to get a mass of MassNeeded (can be Fer(fertile) or Fis(Fissile)) + bool Build_Fuel_According_Lambda(vector<double> &lambda,vector<IsotopicVector> FissilArray, vector<IsotopicVector> FertilArray, double HMMass,IsotopicVector &Fissile, IsotopicVector &Fertile); //!< Compute the fuel isotopy according to the proportion of each IV taken + + //@} + +#ifndef __CINT__ + map<string, EQM_MthPtr> fKeyword; +#endif + + bool freaded; + map< ZAI, pair<double,double> > fZAILimits; //!< Fresh fuel range : map<ZAI<min edge ,max edge >> + + string fInformationFile; //!< file containing Reactor Type, Fuel type, HM mass, Power, time vector, and TMVA input variables names (looks the manual for format details) + string fDBFType; //!< Fuel Type (e.g MOX, UOX, ThU, ThPu ...) + string fDBRType; //!< Reactor Type (e.g PWR, FBR-Na, ADS..) + double fSpecificPower; //!< The specific power in W/gHM (HM: heavy Metal) + double fMaximalContent; //!< The approx. maximum fissile content reachable by the model + + /*! + \name Others + */ + //@{ + double fTotalFissileMassInStocks;//!< Total mass in fissile stocks + double fTotalFertileMassInStocks;//!< Total mass in fertile stocks + //@} +}; + +#endif + + + + + + + + + diff --git a/source/branches/BaM/include/EvolutionData.hxx b/source/branches/BaM/include/EvolutionData.hxx new file mode 100755 index 000000000..94be6c6e1 --- /dev/null +++ b/source/branches/BaM/include/EvolutionData.hxx @@ -0,0 +1,268 @@ +#ifndef _EvolutionData_ +#define _EvolutionData_ + +/*! + \file + \brief Header file for EvolutionData class. + @version 2.0 + */ + +#include <string> +#include <map> + +#include "IsotopicVector.hxx" +#include "CLASSObject.hxx" +#include "ZAI.hxx" + +#include "TMatrix.h" + +class TGraph; +class EvolutionData; +class CLASSLogger; + +using namespace std; +typedef long long int cSecond; + + +EvolutionData operator*(EvolutionData const& evol, double F); +EvolutionData operator*(double F, EvolutionData const& evol); +EvolutionData operator/(EvolutionData const& evol, double F); +EvolutionData Sum(EvolutionData const& evol1, EvolutionData const& evol2); +EvolutionData Multiply(EvolutionData const& evol, double F); +EvolutionData Multiply(double F, EvolutionData const& evol); + +double Distance(IsotopicVector IV1, EvolutionData Evd1 ); +double Distance(EvolutionData Evd1, IsotopicVector IV1 ); + +//-----------------------------------------------------------------------------// +//! Stores fuel inventory evolution , mean cross sections evolution, flux evolution, power , ... + +/*! + Define an EvolutionData. + The aim of these class is to describe the evolution of a single evoluting system in CLASS. + The system can either be a fuel evolution trough irradiation or a nuclei which produce, trough its decay, a large nuclei tree. + + The nuclei tree resulting of the evolution are stored in a map of ZAI and TGraph, each TGraph correspond to the evolution of the quantity of the associeted ZAI. + + @author BaM + @version 2.0 + */ +//________________________________________________________________________ + + + +class EvolutionData : public CLASSObject +{ + +public : + +//********* Constructor/Destructor Method *********// + + /*! + \name Constructor/Desctructor + */ + //@{ + + EvolutionData(); ///< Normal DB Constructor. + + + //{ + /// CLASSLogger Constructor. + /*! + Use create an empty EvolutionData loading a CLASSLogger + \param log : used for the log. + */ + EvolutionData(CLASSLogger* log); ///< Make a new Evolutive Product evolution + //} + + //{ + /// Special Constructor. + /*! + Make a new EvolutionData + \param log : used for the log. + \param DB_file path to the DataBase file + \param oldread true if the oldmethod should be use to read the DatBase File (deprecated) + \param zai set the ZAI if you want to add a stable nuclei. + */ + EvolutionData(CLASSLogger* log, string DB_file, bool isDecay = false, ZAI zai = ZAI(0,0,0) ); + //} + + //{ + /// Special Constructor. + /*! + Make a new EvolutionData + \param log : used for the log. + \param DB_file path to the DataBase file + \param oldread true if the oldmethod should be use to read the DatBase File (deprecated) + \param zai set the ZAI if you want to add a stable nuclei. + */ + EvolutionData(bool oldread, CLASSLogger* log, string DB_file, bool isDecay = false, ZAI zai = ZAI(0,0,0) ); + //} + + + //{ + /// Normal Destructor. + /*! + Only remove the map without deleting the pointer to TGraph... + One need to call the DeleteEvolutionData() method to fully delete the EvolutionData, and then avoiding memory leak... + */ + ~EvolutionData(); + //} + + //{ + /// Delete the EvolutionData. + /*! + Use to fully delete the EvolutionData and all associeted TGraph. + In some case needed to be called to avoid memory leaks. + */ + void DeleteEvolutionData(); + + void DeleteEvolutionDataCopy(); + + //} + + //@} + + + + +//********* Set Method *********// + + /*! + \name Set Method + */ + //@{ + void SetHeavyMetalMass(double Mass) {fHeavyMetalMass = Mass;} //!< Set the heavy metal Mass [t] + + void SetReactorType(string reactortype) { fReactorType = reactortype; } ///< Set the reactor type (e.g PWR, FBR-Na,...) + void SetFuelType(string fueltype) { fFuelType = fueltype; } ///< Set the fuel type (e.g MOX,UOX,...) + void SetPower(double power) { fPower = power; } ///< Set the power of the EvolutionData [W] + void SetFlux(TGraph* flux ) { fFlux = flux; } ///< Set the neutron flux of the EvolutionData [cm^{-2}.s^{-1}] + void SetCycleTime(cSecond cycletime) { fCycleTime = cycletime; } ///< Set cycletime of the EvolutionData [s] + + + void SetInventoryEvolution(map<ZAI, TGraph*> maptoinsert) { fInventoryEvolution = maptoinsert;}///< Set EvolutionData map + void SetFissionXS(map<ZAI, TGraph*> maptoinsert) { fFissionXS = maptoinsert;} ///< Set fission cross section map + void SetCaptureXS(map<ZAI, TGraph*> maptoinsert) { fCaptureXS = maptoinsert;} ///< Set capture cross section map + void Setn2nXS(map<ZAI, TGraph*> maptoinsert) { fn2nXS = maptoinsert;} ///< Set (n,2n) cross section map + + //@} + + + + +//********* Get Method *********// + + /*! + \name Get Method + */ + //@{ + +#ifndef __CINT__ + map<ZAI ,TGraph* > GetInventoryEvolution() const { return fInventoryEvolution; } //!< return the EvolutionData map + map<ZAI ,TGraph* > GetFissionXS() const { return fFissionXS; } //!< return the fission cross section map + map<ZAI ,TGraph* > GetCaptureXS() const { return fCaptureXS; } //!< return the capture cross section map + map<ZAI ,TGraph* > Getn2nXS() const { return fn2nXS; } //!< return the (n,2n) cross section map + TGraph* GetKeff() const { return fKeff; } //!< return the evolution of the keff (TGraph*) + TGraph* GetFlux() const { return fFlux; } //!< return the evolution of the neutron flux (TGraph*) +#endif + + double GetFinalTime() const { return fFinalTime; } //!< return the final time - last point (double) + double GetCycleTime() const { return fCycleTime; } //!< return the cycletime (double) + double GetPower() const { return fPower; } //!< return the power (double) + string GetDB_file() const { return fDB_file; } //!< return the name of the Database file (string) + string GetReactorType() const { return fReactorType; } //!< return the type of reactor (string) + TGraph* GetEvolutionTGraph(const ZAI& zai); //!< return the evolution of the ZAI quantity (TGraph*) + + IsotopicVector GetIsotopicVectorAt(double t); ///< Return the Product IsotopicVector at time t + + double GetHeavyMetalMass() const { return fHeavyMetalMass; } //!< Return the heavy metal mass in the core at the begining of the cycle [t] + + + //{ + /// Return the XS for a reactionId on zai at t time + /*! + // This method cross section of a reaction for a ZAI at a time + // \param t time + // \param ZAI ZAI for which the cross section if asked + // \param ReactionId ID of the reaction asked + + // The different reaction ID are : + \li 1 fission, + \li 2 capture, + \li 3 (n,2n). + */ + double GetXSForAt(double t, ZAI zai, int ReactionId); + //} + + //@} + + + + +//********* Insertion Method *********// + + //@} + /*! + \name Insertion Method + */ + //@{ + + bool NucleiInsert(pair<ZAI, TGraph*> zaitoinsert); //!< Add a nuclei evolution to the evolution map + bool FissionXSInsert(pair<ZAI, TGraph*> zaitoinsert); //!< Add a nuclei to the fission cross section map + bool CaptureXSInsert(pair<ZAI, TGraph*> zaitoinsert); //!< Add a nuclei to the capture cross section map + bool n2nXSInsert(pair<ZAI, TGraph*> zaitoinsert); //!< Add a nuclei to the (n,2n) cross section map + + + //@} + + + +protected : + + string fDB_file; ///!< path to the DataBase file + + +#ifndef __CINT__ + map<ZAI ,TGraph* > fInventoryEvolution; //!< evolution map + map<ZAI ,TGraph* > fFissionXS; //!< fission cross section map + map<ZAI ,TGraph* > fCaptureXS; //!< capture cross section map + map<ZAI ,TGraph* > fn2nXS; //!< (n,2n) cross section map + TGraph* fKeff; //!< Keff evolution + TGraph* fFlux; //!< Flux evolution +#endif + + cSecond fFinalTime; ///< time of the last point + bool fIsCrossSection; ///< true if some cross section are present in the database + bool fisDecay; + + + string fReactorType; ///< Type of reactor + string fFuelType; ///< Type of fuel + double fPower; ///< Power in W + double fCycleTime; ///< Cycle time of the DataBase + double fHeavyMetalMass; ///< Cycle time of the DataBase + + + void OldReadDB(string DBfile); //!< Read old format database + void ReadDB(string DBfile, bool oldread = false); //!< Main function to read database + void ReadKeff(string line, double* time, int NTimeStep); //!< Read the Keff in the database + void ReadFlux(string line, double* time, int NTimeStep); //!< Read the Flux in the database + void ReadInv(string line, double* time, int NTimeStep); //!< Read the Inventory evolution in the database + void ReadXSFis(string line, double* time, int NTimeStep); //!< Read the fission cross section evolution in the database + void ReadXSCap(string line, double* time, int NTimeStep); //!< Read the capture cross evolution in the database + void ReadXSn2n(string line, double* time, int NTimeStep); //!< Read the (n,2n) cross evolution in the database + void ReadInfo(); //!< Read the info file of the database + + + double Interpolate(double t, TGraph& EvolutionGraph); ///< Interpolating the value of EvolutionGraph at the t time + + void AddAsStable(ZAI zai); ///< Use when adding an EvolutionData of a stable nuclei (for "non" decay) + + ClassDef(EvolutionData,0); +}; + + + + +#endif diff --git a/source/branches/BaM/include/FabricationPlant.hxx b/source/branches/BaM/include/FabricationPlant.hxx new file mode 100644 index 000000000..47c9c0d36 --- /dev/null +++ b/source/branches/BaM/include/FabricationPlant.hxx @@ -0,0 +1,240 @@ +#ifndef _FabricationPlant_ +#define _FabricationPlant_ + +/*! + \file + \brief Header file for FabricationPlant class. + @version 2.0 + */ + + + +#include <vector> +#include <map> + +#include "CLASSConstante.hxx" +#include "CLASSFacility.hxx" +#include "IsotopicVector.hxx" +#include "EvolutionData.hxx" +#include "Scenario.hxx" +#include "Storage.hxx" +#include "Reactor.hxx" +#include "CLASSLogger.hxx" +#include "ZAI.hxx" + +using namespace std; +typedef long long int cSecond; + +//-----------------------------------------------------------------------------// +//! CLASS object to build the fresh fuel (do chemical separation) & store it until core loading + +/*! + Define a FabricationPLant. + The aim of these class is to manage the manufacturing of reprocessed fuel. + It includes the fabrication of the fuel from a stock of material, using the appropriate + algrorithm, and the storage of the fresh fuel until reactor loading. + The parameters used for the fuel fabrication are recover from a PhysicsModels. + The PhysicsModels MUST include an EquivalenceModel to build the fuel. +Some EquivalenceModel are available in the CLASS package, but an user can make his own. + +Once the fuel is built, the FabricationPlant store the corresponding EvolutionData + generated using the PhysicsModels. + @see PhysicsModels.hxx + @see EquivalenceModel.hxx + + @author BaM + @version 2.0 + */ +//________________________________________________________________________ + +class DecayDataBank; +class FuelDataBank; + + +class FabricationPlant : public CLASSFacility +{ + +public : + +//********* Constructor/Destructor Method *********// + + /*! + \name Constructor/Desctructor + */ + //@{ + + FabricationPlant(); ///< Normal constructor + + + //{ + /// Special Constructor. + /*! + Make a new FabricationPlant + \param log : used for the log. + \param fabricationtime duration of the fabrication process (default : 2 years) in [s]. + */ + FabricationPlant(CLASSLogger* log, double fabricationtime = cYear*2); + //} + + ~FabricationPlant(); ///< Normal Destructor. + + //@} + + + + +//********* Set Method *********// + + /*! + \name Set Method + */ + //@{ + +#ifndef __CINT__ + void SetDecayDataBank(DecayDataBank* decayDB) {fDecayDataBase = decayDB;} //! Set the Decay DataBank + + void SetFiFo(bool bval = true) { fFiFo = bval;} //!< Set the chronological priority (true for chronological, false instead) + + void SetSubstitutionFuel(EvolutionData fuel, bool ReplaceTheStock = false); //!< To use a substitution fuel if the fabrication fail (not enough material in stock) + void SetSubstitutionFissile(IsotopicVector IV); //!< To use a substitution fissile if the fabrication fail (not enough material in stock) the composition of the fissile is given normalize to 1 by IV. + + + void AddReactor(int reactorid, double creationtime) + { fReactorNextStep.insert( pair<int,cSecond> (reactorid, (cSecond)creationtime-GetCycleTime() ) ); } //!< Add a new reactor to be filled with the fresh fuel build by the FabricationPlant + + void SetReUsableStorage(Storage* store) { fReUsable = store; fIsReusable = true;} //!< Set the Storage where all the separated matetial not used in the fabrication process will be sent. (if not present it goes to WASTE) +#endif + + using CLASSFacility::SetName; + + //@} + + + + +//********* Get Method *********// + + /*! + \name Get Method + */ + //@{ + +#ifndef __CINT__ + vector<Storage*> GetFissileStorage() { return fFissileStorage; } //!< Return the Pointer to the fissile Storage + vector<Storage*> GetFertileStorage() { return fFertileStorage; } //!< Return the Pointer to the fertile Storage + + EvolutionData GetReactorEvolutionDB(int ReactorId); //!< Return the EvolutionData of Reactor ReactorId + IsotopicVector GetDecay(IsotopicVector isotopicvector, cSecond t); //!< Get IsotopicVector Decay at time t +#endif + + map<int, IsotopicVector > GetReactorFuturIncome() const + { return fReactorFuturIV;} //!< Return the list of the futur fuel IV + + cSecond GetFabricationTime() const {return GetCycleTime();} + //@} + + + +#ifndef __CINT__ + void AddFissileStorage(Storage* stock) { fFissileStorage.push_back(stock); } //!< Add a new Storage to the list of fissile material provider. + void AddFertileStorage(Storage* stock) { fFertileStorage.push_back(stock); } //!< Add a new Storage to the list of fertile material provider. +#endif + +//********* Fabrication & Evolution Method *********// + + /*! + \name Fabrication & Evolution Method + */ + //@{ + + void SetSeparartionEfficiencyIV(ZAI zai, double factor); //!< Set the extraction efficiency of zai to factor (0<= factor<= 1) + void Evolution(cSecond t); //!< Perform the FabricationPlant evolution + + void DumpStock(vector<double> lambdaArray); //!< Update the Stock status after building process + + void TakeReactorFuel(int ReactorId) ; //!< Remove the fuel of reactor ReactorId from stock + void UpdateInsideIV(); + + IsotopicVector BuildFuelFromEqModel(vector<double> LambdaArray); //!<Build the fresh fuel for the reactor according the results of the EquivalenceModel (@see EquivalenceModel) + void BuildFissileArray(); //!< virtualy extract fissile nuclei from Storage according EquivalenceModel fFissileList and make it virtually decay FabricationTime + void BuildFertileArray(); //!< virtualy extract fertile nuclei from Storage according EquivalenceModel fFertileList and make it virtually decay FabricationTime + +#ifndef __CINT__ + void BuildFuelForReactor(int ReactorId, cSecond t); //!< Build a fuel for the reactor ReactorId +#endif + + void SortArray(int i); //!< Sort IsotopicVector array according priority preferences (e.g first in first out) + + //@} + + + + +protected : + + + +//********* Internal Parameter *********// + IsotopicVector fSeparationLostFraction; ///< The lost fraction table during separation (1- efficiency) + map<int, cSecond > fReactorNextStep; ///< Next time step to build a new fuel + +#ifndef __CINT__ + map< int,EvolutionData > fReactorFuturDB; ///< List of the futur EvolutionData use in the reactor +#endif + map< int,IsotopicVector > fReactorFuturIV; ///< List of the futur fuel IsotopicVector used in the reactor + + + + + bool fFiFo; //!< First In First Out flag + + bool fSubstitutionFuel; //!< true if a substitution fuel as been set + bool fSubstitutionFissile; //!< true if a substitution fissile as been set + bool fIsReplaceFissileStock; //!< If there is not enough fissile: true all the fissile comes from an infinite stock; false: just the missing Pu quantity comes from this infinite stock + + void FabricationPlantEvolution(cSecond t); //!< Deal the FabricationPlant evolution + void ResetArrays(); //!< empty the fFertileArray and fFissileArray + + +#ifndef __CINT__ + + vector<Storage*> fFissileStorage; //!< Pointer to the Storage used to get the fissile part of the fuel + vector<IsotopicVector> fFissileArray; //!< The vector of isotopicVector use as fissile material + vector<cSecond> fFissileArrayTime; //!< Time when a IsotopicVector arrives in its storage + vector< pair<int,int> > fFissileArrayAdress; + IsotopicVector fFissileList; //!< The list of fissile ZAI to consider + + vector<Storage*> fFertileStorage; //!< Pointer to the Storage used to get the fertile part of the fuel + vector<IsotopicVector> fFertileArray; //!< The vector of isotopicVector used as fissile material + vector<cSecond> fFertileArrayTime; //!< Time when a IsotopicVector arrives in its storage + + vector< pair<int,int> > fFertileArrayAdress; + IsotopicVector fFertileList; //!< The List of fertile ZAI to consider + + Storage* fReUsable; //!< Pointer to the Storage using for storing unused material + bool fIsReusable; + + EvolutionData fSubstitutionEvolutionData; //!< EvolutionData of the subtitution fuel + IsotopicVector fSubstitutionFissileIV; //!< IsotopicVector of the subtitution fissile + + DecayDataBank* fDecayDataBase; //!< Pointer to the DecayDataBank + + + //{ + /// Separation Method + /*! + Make the Separation + \li IV[0] -> To Keep + \li IV[1] -> To Waste + */ + pair<IsotopicVector, IsotopicVector> Separation(IsotopicVector isotopicvector, IsotopicVector ExtractedList); + //} + +#endif + + + ClassDef(FabricationPlant,3); + +}; + +#endif diff --git a/source/branches/BaM/include/IrradiationModel.hxx b/source/branches/BaM/include/IrradiationModel.hxx new file mode 100644 index 000000000..08a0eaf60 --- /dev/null +++ b/source/branches/BaM/include/IrradiationModel.hxx @@ -0,0 +1,264 @@ +#ifndef _IRRADIATIONMODEL_ +#define _IRRADIATIONMODEL_ + + +/*! + \file + \brief Header file for IrradiationModel class. + + + @author BaM + @author BLG + @version 2.0 + */ + + +#include "CLASSObject.hxx" + +#include "IsotopicVector.hxx" +#include "CLASSNucleiFiliation.hxx" +#include "EvolutionData.hxx" + +#include "TMatrix.h" + + +#include <map> +#include <vector> + + +using namespace std; +typedef long long int cSecond; + +class ZAI; +class CLASSLogger; +//-----------------------------------------------------------------------------// +//! The Bateman equation solver + +/*! + Define an IrradiationModel. + An IrradiationModel is a Bateman equation solving method. + This is the mother class. + see derivated classes : + \li @see IM_Matrix + \li @see IM_RK4 + + The aim of these class is to gather all the commom properties of all the + derivated Irradiation Model. + + @author BaM + @author BLG + @version 3.0 + */ +//________________________________________________________________________ + +class IrradiationModel : public CLASSObject +{ + + public : + /*! + \name Constructors + */ + //@{ + IrradiationModel(); //!< Default constructor + + IrradiationModel(CLASSLogger* log); //!< Logger constructor + + //@} + + //{ + /// virtual method called to perform the irradiation calculation using a set of cross section. + /*! + Perform the Irradiation Calcultion using the XSSet data + \param IV : isotopic vector to irradiate + \param XSSet : set of mean cross section to use in order to perform the depletion calculation + \param Power : constant power to use for irradation [W] + \param irradiationtime : irradiation time [s] + */ + virtual EvolutionData GenerateEvolutionData(IsotopicVector IV, EvolutionData XSSet, double Power, double cycletime) {return EvolutionData();} + //} + + + + + //********* Get Method *********// + /*! + \name Get Method + */ + //@{ + string GetDataFileName() const { return fDataFileName; } // File name where decay constants and branching ratios are written. + string GetDataDirectoryName() const { return fDataDirectoryName; } //!< Path to fDataFileName + + double GetShorstestHalflife() const { return fShorstestHalflife; } //!< Nuclei with HL below fShorstestHalflife are cut (replaced by their daughter(s)) + + + void GetNuclearProcessMatrix(TMatrixT<double> &myMatrix, ZAI Mother, IsotopicVector ProductedIV, double XSValue = 1); + + void BuildReactionFiliation(); + + string GetSpectrumType(){return fSpectrumType;} //!< Get the type of neutron spectrum (thermal or fast) + + IsotopicVector GetDecayConstant() const {return fDecayConstante;}//!< Get the decay constants + double GetDecayConstant(const ZAI& zai) const;//!< Get the decay constants of ZAI + + + //@} + + + + + //********* Set Method *********// + + /*! + \name Set Method + */ + //@{ + + + //{ + /// set Fission Energy using a file + /*! + // This method fill the Fission Energy [eV] map using a file + // \param FissionEnergyFile: filename containing the Fission Energy of some nuclei + (format : Z A I Energy[eV]) + */ + void SetFissionEnergy(string FissionEnergyFile); + //} + + //{ + /// set Fission Energy for a ZAI using ZAI(Z,A,I) + /*! + // This method fill the Fission Energy map of a set ZAI + // \param zai : the ZAI + // \param E : Energy released by fission for nuclei zai [eV] + */ + void SetFissionEnergy(ZAI zai, double E); + //} + + //{ + /// set Fission Energy for a ZAI using the Z, A, I + /*! + // This method fill the Fission Energy map of a set ZAI + // \param Z : Z of the ZAI + // \param A : A of the ZAI + // \param I : I of the ZAI + // \param E : Fission energy of the ZAI [eV] + */ + void SetFissionEnergy(int Z, int A, int I, double E ) { SetFissionEnergy(ZAI(Z,A,I), E);} + //} + + void SetShortestHalfLife(double halflife) { fShorstestHalflife = halflife;} //!< Set the Half Life cut + void SetZAIThreshold(double zaithreshold) { fZAIThreshold = zaithreshold;} //!< Set the zai threshold + + void LoadFPYield(string SponfaneusYield, string ReactionYield); //!< Build Fision Yields maps + + void SetSpectrumType(string type); //!< Set the type of neutron spectrum (thermal or fast) + + //@} + + + + //********* Evolution Method *********// + /*! + \name Evolution Method + */ + //@{ + + + void BuildDecayMatrix(); //!< Build the Decay Matrix for the futur time step + virtual void LoadDecay(); //!< Load the decay properties (HL,BR) + + virtual void NuclearDataInitialization(); //!< Build Decay matrices & read FpYields if any + //@} + + + //********* Other Method *********// + /*! + \name Other Method + */ + //@{ + void Print() const; + + int GetZAIThreshold(){return fZAIThreshold;} //!< Gives the threshold (in charge number Z). The nuclei below this threshold are not managed + //@} + + //{ + //! Returns a particular decay mode. + /*! + \param DecayModes : a list of decay modes with their branching ratios and isomeric state of the Daughters. + \param BR : branching ratio of the current decay mode + \param Iso : isomeric state of the Daughter of the current decay mode. + \param StartPos : the current decay mode to extract. + */ + string GetDecay(string DecayModes, double &BR,int &Iso, int &StartPos); + //} + + + protected : + + double fShorstestHalflife; //!< Limit on the half life of nuclei to take it into account + int fZAIThreshold; //!< Lowest Mass deal by the evolution (default 90) + string fDataFileName; //!< Name of the decay list + string fDataDirectoryName; //!< Path to the decay list file + + map<ZAI, double > fFissionEnergy; //!< Store the Energy per fission use for the flux normalisation. + + map<ZAI, int> fMatrixIndex; //!< correspondance matrix from ZAI to the column (or line) of the different Reaction/Decay matrix + vector<ZAI> fReverseMatrixIndex; //!< correspondance matrix from the column (or line) of the different Reaction/Decay matrix to the ZAI + + TMatrixT<double> fDecayMatrix; //!< Matrix with half life for each nuclei + + CLASSNucleiFiliation fFastDecay; //!< Store the nuclei being cut (HL threshold) + CLASSNucleiFiliation fNormalDecay; //!< Store the uncut nuclei + IsotopicVector fDecayConstante; //!< List of decay constants + + CLASSNucleiFiliation fSpontaneusYield; //!< Store the spontaneus fission yield + CLASSNucleiFiliation fReactionYield; //!< Store the reaction fission yield + + CLASSNucleiFiliation fCaptureReaction; //!< Store the reaction capture Filiation + CLASSNucleiFiliation fn2nReaction; //!< Store the reaction n,2n Filiation + + string fSpontaneusYieldFile; //!< Store the name of the spontaneus fission yield file + string fReactionYieldFile; //!< Store the name of the reaction fission yield file + + string fSpectrumType; //!< Type of the spectrum : thermal or fast. (needed for Isomeric branching ratios) + + //{ + /// Return the Fission XS Matrix at the time TStep + /*! + // This method extract the fission cross section of an EvolutionData at the set time + // \param EvolutionDataStep : EvolutionData + // \param TStep : time + */ + TMatrixT<double> GetFissionXsMatrix(EvolutionData EvolutionDataStep,double TStep); + //} + + //{ + /// Return the capture cross section matrix at the time TStep + /*! + // This Method extract the capture cross section of an EvolutionData at the set time + // \param EvolutionDataStep : EvolutionData + // \param TStep : time + */ + TMatrixT<double> GetCaptureXsMatrix(EvolutionData EvolutionDataStep,double TStep); + //} + + //{ + /// Return the n2n XS matrix at the time TStep + /*! + // This Method extract the (n,2n) Cross section of an EvolutionData at the set time + // \param EvolutionDataStep : EvolutionData + // \param TStep : time + */ + TMatrixT<double> Getn2nXsMatrix(EvolutionData EvolutionDataStep,double TStep); + //} + + + + CLASSNucleiFiliation ReadFPYield(string Yield); ///< Read a CLASSYield file and return the correpsponding map + + private : + +}; + +#endif + diff --git a/source/branches/BaM/include/IsotopicVector.hxx b/source/branches/BaM/include/IsotopicVector.hxx new file mode 100755 index 000000000..f830fc638 --- /dev/null +++ b/source/branches/BaM/include/IsotopicVector.hxx @@ -0,0 +1,183 @@ +#ifndef _ISOTOPICVECTOR_ +#define _ISOTOPICVECTOR_ + + +/*! + \file + \brief Header file for IsotopicVector class. + @version 2.0 + */ +#include "ZAI.hxx" + +#include "TObject.h" +#include <string> +#include <vector> +#include <map> + +using namespace std; +typedef long long int cSecond; + +//-----------------------------------------------------------------------------// +//! Allows to store & operate on radioactive sample + +/*! + Defines an Isotopicvector. + An isotopicVector is a map of ZAI and double (e.g number of atoms). + Its aim is to define a radioactive sample. + + @author BaM + @author BLG + @author Marc + @version 2.0 + */ +//________________________________________________________________________ + + + +class IsotopicVector : public TObject +{ +public : + +//********* Constructor/Destructor Method *********// + + /*! + \name Constructor/Desctructor + */ + //@{ + + IsotopicVector(); ///< Normal Constructor. + + + ~IsotopicVector(); ///< Normal Destructor. + + //@} + + +//********* Get Method *********// + + /*! + \name Get Method + */ + //@{ + + map<ZAI ,double> GetIsotopicQuantity() const + { return fIsotopicQuantity; } //!< Return the IsotopicVector as a map + map<ZAI ,double> GetIsotopicQuantityNeeded() const + { return fIsotopicQuantityNeeded; } //!< Return the needed IsotopicVector as a map + IsotopicVector GetSpeciesComposition(int z) const; //!< Return the Species composition of the "z" atom + IsotopicVector GetThisComposition(IsotopicVector IV) const; //!< Return the composition according the IV list... + vector<ZAI> GetZAIList() const; //!< Return the list of ZAI present in the IV + IsotopicVector GetActinidesComposition() const; //!< Return the Actinides composition (Z >= 89) + + double GetZAIIsotopicQuantity(const ZAI& zai) const; ///< Return the quantity of the ZAI + double GetZAIIsotopicQuantity(const int z, const int a, const int i) const; ///< Return the quantity of the ZAI + double GetQuantity(const int z, const int a, const int i) const {return GetZAIIsotopicQuantity(z,a,i);} + double GetQuantity(const ZAI& zai) const {return GetZAIIsotopicQuantity(zai);} + + void Initiatlize(double val); + + + double GetTotalMass() const; //!< Return the mass (in tons) of the isotopic vector + double GetMeanMolarMass() const; //<! Return the mean molar mass of the isotopic vector + + vector<int> GetChemicalSpecies() const; //!< Return the list of chemichal species contained + int GetZAIQuantity() const + {return fIsotopicQuantity.size(); } //!< Return the number of different ZAI in the IsotopicVector + + double GetSumOfAll() const; //!< Return the Sum of nuclei in the IsotopicVector + + //@} + + + + +//********* Internal Operation Method *********// + + /*! + \name Internal Operation Method + */ + //@{ + + + void Clear(); //!< Empty all the IV + void ClearNeed(); //!< Empty Need componant of the IV + + void Add(const ZAI& zai, double quantity); //!< Add Quantity gramme of the ZAI Element + void Add(const IsotopicVector& isotopicvector); //!< Add IsotopicVector to the existing IsotopicVector + void Add(const map<ZAI ,double>& quantity); //!< Add IsotopicVector to the existing IsotopicVector + void Add(int Z, int A, int I, double quantity) + { (*this).Add(ZAI(Z,A,I), quantity); } //!< Add Quantity gramme of the ZAI Element + + + void Need(const ZAI& zai, double quantity); //!< Fill the fIsotopicQuantityNeeded + void Need(const IsotopicVector& isotopicvector); //!< Fill the fIsotopicQuantityNeeded + void Need(const map<ZAI ,double>& quantityneeded) { fIsotopicQuantityNeeded = quantityneeded; } + //!< Fill the fIsotopicQuantityNeeded + + void Remove(const ZAI& zai, double quantity); //!< Remove Quantity gramme of the ZAI Element + void Remove(const IsotopicVector& isotopicvector); //!< Remove IsotopicVector to the existing IsotopicVector + + void Multiply(double factor); //!< Multiply the IV by a Factor + + void ApplyZAIThreshold(int z = 90); //!< Put all nuclei below the threshold in -2 -2 -2 ZAI... + + IsotopicVector& operator+= (IsotopicVector const& IVb); //!< Operator += definition + IsotopicVector& operator-= (IsotopicVector const& IVb); //!< Operator -= definition + IsotopicVector& operator*= (IsotopicVector const& IVb); //!< Operator *= definition + IsotopicVector& operator*= (double const& factor); //!< Operator *= definition (scalar) + bool operator <(const IsotopicVector& isotopicvector) const; //!< IsotopicVector Comparator + + //@} + + + +//********* In/Out related Method *********// + + /*! + \name In/Out Method + */ + //@{ + + void Write(string filename, cSecond time = -1 ) const; //!< Write the Content of the IV in the filename file + + void Print(string o = " ") const ; //!< Print the composition of the IV in terminal + string sPrint() const ; //!< Print the composition of the IV in a string + + void PrintList(string o = " ") const ; //!< Print the composition of the IV + + //@} + + +//***************************************************///< + + + protected : + + map<ZAI ,double> fIsotopicQuantity; ///< Isotopic vector composition in atomes Number + + map<ZAI ,double> fIsotopicQuantityNeeded; ///< map where negative value are saved + + ClassDef(IsotopicVector,1); +}; + +IsotopicVector operator/(IsotopicVector const& IVA, double F); +IsotopicVector operator/(ZAI const& zai, double F); +IsotopicVector operator*(IsotopicVector const& IVA, double F); +IsotopicVector operator*(ZAI const& zai, double F); +IsotopicVector operator*(double F, IsotopicVector const& IVA); +IsotopicVector operator*(double F, ZAI const& zai); +IsotopicVector operator+(IsotopicVector const& IVa, IsotopicVector const& IVb); +IsotopicVector operator-(IsotopicVector const& IVa, IsotopicVector const& IVb); + +IsotopicVector operator*(IsotopicVector const& IVa, IsotopicVector const& IVb); + + +double RelativDistance(IsotopicVector IV1, IsotopicVector IV2 ); //!< return the euclidean distance between two IV. The two IV are normalize to unity +double Distance(IsotopicVector IV1, IsotopicVector IV2 ,int DistanceType = 0, IsotopicVector DistanceParameter = IsotopicVector()); //!< return weighted euclidean distance between two IV + +double DistanceStandard(IsotopicVector IV1, IsotopicVector IV2); //!< return the euclidean distance between two IV +double DistanceAdjusted(IsotopicVector IV1, IsotopicVector IV2, IsotopicVector DistanceParameter); //!< return the weighted euclidean distance between two IV +double Norme(IsotopicVector IV1,int DistanceType = 0, IsotopicVector DistanceParameter = IsotopicVector()); //!< return the norm of an IV + + +#endif diff --git a/source/branches/BaM/include/PhysicsModels.hxx b/source/branches/BaM/include/PhysicsModels.hxx new file mode 100644 index 000000000..43bfb8201 --- /dev/null +++ b/source/branches/BaM/include/PhysicsModels.hxx @@ -0,0 +1,120 @@ + +#ifndef _PhysicsModels_ +#define _PhysicsModels_ + + +/*! + \file + \brief Header file for XS_INTERPOLATOR class. + + + @author BaM + @author BLG + @version 1.0 + */ +#include "EquivalenceModel.hxx" +#include "XSModel.hxx" +#include "IrradiationModel.hxx" +#include "EvolutionData.hxx" + + +using namespace std; +typedef long long int cSecond; + +//-----------------------------------------------------------------------------// +//! Container object of XSModel, EquivalenceModel and IrradiationModel + +/*! + Define a contener of all physics models used for a specific couple (reactor,fuel). + +These class aim is basicaly to store 3 differents physics model : + + The 2 following are data base related (for one Reactor and one fuel type ) : +User can either define his own (see manual) or uses the provided ones : +\li XSModel : Mean cross section prediction (Closest, MLP ) +\li EquivalenceModel : Fissile content prediction ( Linear,Quadratique, MLP , Baker & Ross, ...) + + This one is bateman solvers related : +\li IrradiationModel : can be Runge Kutta 4 or Matrix + + + @author BaM + @author BLG + @version 1.0 + */ +//________________________________________________________________________ + + +class PhysicsModels : public CLASSObject +{ + + public : + + /*! + \name Constructor/Desctructor + */ + //@{ + + PhysicsModels(); //!< Default Constructor + + //{ + /// XS, EM, IM Contructor + /*! + \param XS : The XSModel (Mean cross section predictor) + \param EM : The EquivalenceModel (Fissile content predictor) + \param IM : The IrradiationModel (Bateman solver) + */ + PhysicsModels(XSModel* XS, EquivalenceModel* EM, IrradiationModel* IM ); + //} + + //{ + /// CLASSLogger Contructor + /*! + \param log : The CLASSLogger + \param XS : The XSModel (Mean cross section predictor) + \param EM : The EquivalenceModel (Fissile content predictor) + \param IM : The IrradiationModel (Bateman solver) + */ + PhysicsModels(CLASSLogger* log, XSModel* XS, EquivalenceModel* EM, IrradiationModel* IM ); + //} + + ~PhysicsModels() {;} + //@} + + //{ + + //{ + /// GenerateEvolutionData + /*! + Call the 3 Physics models to compute the depletion calculation for the right fresh fuel with + the right mean cross sections + \param IV : The fresh fuel composition + \param cycletime : The irradiation time [s] + \param Power : The thermal (as always in CLASS) Power [W] + */ + EvolutionData GenerateEvolutionData(IsotopicVector IV, double cycletime, double Power); + //} + + XSModel* GetXSModel() {return fXSModel;} //!< return the mean cross section predictor + EquivalenceModel* GetEquivalenceModel() {return fEquivalenceModel;} //!< return Fissile content predictor + IrradiationModel* GetIrradiationModel() {return fIrradiationModel;} //!< return the Bateman solver + + PhysicsModels* GetPhysicsModels() {return this;}//!< return the PhysicsModels + + + + + + + private : + + XSModel* fXSModel; //!< The XSModel (mean cross sections prediction) + EquivalenceModel* fEquivalenceModel; //!< The EquivalenceModel (fresh fissile content prediction) + IrradiationModel* fIrradiationModel; //!< The IrradiationModel (The Bateman's solver) + + + +}; + +#endif + diff --git a/source/branches/BaM/include/Pool.hxx b/source/branches/BaM/include/Pool.hxx new file mode 100755 index 000000000..c1c8da2a5 --- /dev/null +++ b/source/branches/BaM/include/Pool.hxx @@ -0,0 +1,173 @@ +#ifndef _Pool_ +#define _Pool_ +/*! + \file + \brief Header file for Pool class. + */ + +#include <string> +#include <map> + +#include "CLASSConstante.hxx" +#include "CLASSBackEnd.hxx" +#include "IsotopicVector.hxx" + +using namespace std; +typedef long long int cSecond; + +class CLASSBackEnd; +class CLASSLogger; +class DecayDataBank; + +//-----------------------------------------------------------------------------// +//! Defines the spent fuel pool + +/*! + This class deal with the management of the spent fuel pool + + + @author BaM + @version 2.0 + */ +//________________________________________________________________________ + + + +class Pool : public CLASSBackEnd +{ +public : + + +//********* Constructor/Destructor Method *********// + + /*! + \name Constructor/Desctructor + */ + //@{ + + Pool(); ///< Normal Constructor. + + //{ + /// Special Constructor. + /*! + Make a new Pool + \param log : used for the log. + \param coolingtime : duration of the cooling (default : 5 years) in [s]. + */ + Pool(CLASSLogger* Log, cSecond coolingtime = 5*cYear); //!< + //} + + + //{ + /// Special Constructor. + /*! + Make a new Pool + \param log : used for the log. + \param backend : CLASSBackend which get the fuel after the cooling + \param coolingtime : duration of the cooling (default : 5 years) in [s]. + */ + Pool(CLASSLogger* log, CLASSBackEnd* backend, + cSecond coolingtime = 5*cYear); //!< + //} + + + ~Pool(); ///< Normal Destructor. + //@} + + + + +//********* Set Method *********// + + /*! + \name Set Method + */ + //@{ + + void SetOutBackEndFacility(CLASSBackEnd* befacility) + { fOutBackEndFacility = befacility; + SetIsStorageType(false); + fPutToWaste = false; } //!< Set the pointer to facility at the back end of the pool + + void SetPutToWaste(bool val) { fPutToWaste = val; } //!< Set true if IV goes to waste after cooling false instead + + void SetIVArray(vector<IsotopicVector> ivarray); //! not use there (does nothing) + void SetIVArray(vector<IsotopicVector> ivarray, vector<cSecond> timearray); //!< Set the IsotopicVector Array at the corresponding time + + + using CLASSBackEnd::SetName; + + //@} + + + + +//********* Get Method *********// + + /*! + \name Get Method + */ + //@{ + + bool GetPutToWaste() const { return fPutToWaste; } //!< Return true if IV goes to waste after cooling, false instead + + //@} + + + + +//********* IsotopicVector Managment Method *********// + + /*! + \name IsotopicVector Managment Method + */ + //@{ + + vector<cSecond> GetCoolingStartingTime() const + { return GetIVArrayArrivalTime(); } //!< Return vector of the arrival time of each IV in the Pool + void RemoveIVCooling(int i); //!< Remove a IsotopicVector from cooling + + void AddIV(IsotopicVector isotopicvector); //!< Add an Isotopicvector to the IVArray + //@} + + + + +//********* Other Method *********// + + //@} + /*! + \name Other Method + */ + //@{ + + void Evolution(cSecond t); //!< Perform the evolution until time t + void Dump(); //!< Write modification (exchange between Cooling, Separation and Storage) + + //@} + +protected : + + + +//********* Internal Parameter *********// + bool fPutToWaste; //!< True if IV goes to waste after cooling false instead + + +//********* Isotopic Quantity *********// +//--------- Cooling ---------// + vector<int> fCoolingIndex; ///< Vector of the cooling index + int fCoolingLastIndex; //!< Number of cooling IV handle + vector<int> fCoolingEndOfCycle; //!< Index of the cooling IV reaching the end of a cooling cycle + + +//********* Private Method *********// + void CoolingEvolution(cSecond t); //!< Deal the cooling evolution + + + + + ClassDef(Pool,3); +}; + +#endif diff --git a/source/branches/BaM/include/Reactor.hxx b/source/branches/BaM/include/Reactor.hxx new file mode 100755 index 000000000..e575438e7 --- /dev/null +++ b/source/branches/BaM/include/Reactor.hxx @@ -0,0 +1,320 @@ +#ifndef _Reactor_ +#define _Reactor_ + +/*! + \file + \brief Header file for reactor classes. + */ + +#include <string> +#include <map> + +#include "CLASSFacility.hxx" +#include "IsotopicVector.hxx" +#include "EvolutionData.hxx" +#include "PhysicsModels.hxx" +#include "CLASSFuelPlan.hxx" + +using namespace std; + + +class CLASSBackEnd; +class EvolutionData; +class FabricationPlant; +class Storage; +class CLASSLogger; + +//-----------------------------------------------------------------------------// +//! Defines the Reactor + +/*! + The aim of this class is to deal the evolution of the fuel inside a reactor. + The fuel state in the reactor is describe in the IsotopicVector. Its evolution is contained in an EvolutionData + + @author BaM + @version 2.0 + */ +//________________________________________________________________________ + + + +class Reactor : public CLASSFacility +{ + public : + + + //********* Constructor/Destructor Method *********// + + /*! + \name Constructor/Desctructor + */ + //@{ + + Reactor(); ///< Normal Constructor. + + //{ + /// CLASSLogger Constructor. + /*! + Use create an empty Reactor loading a CLASSLogger + \param log: used for the log. + */ + Reactor(CLASSLogger* log); + //} + + //{ + /// Special Constructor for reprocessed fuel using cycletime and Burn-Up. + /*! + Make a new reactor + \param log: used for the log, + \param backend: CLASSBackend which get the fuel after the cooling, + \param creationtime: creation time in [s], + \param lifetime: working time duration in [s], + \param Power: Thermal power of the reactor in [W], + \param HMMass: Mass of Heavy Metal in the Reactor in [t] of heavy metal, + \param CapacityFactor effective charge of the reactor, fraction between 0 & 1. + */ + Reactor(CLASSLogger* log, CLASSBackEnd* backend, + cSecond creationtime , cSecond lifetime, double Power, + double HMMass, double CapacityFactor = 1); + //} + + //{ + /// Special Constructor for reprocessed fuel using cycletime and Burn-Up. + /*! + Make a new reactor + \param log: used for the log. + \param backend: CLASSBackend which get the fuel after the cooling, + \param creationtime: creation time in [s], + \param lifetime: working time duration in [s], + \param cycletime: duration of a cycle in [s], + \param Power: Thermal power of the reactor in [W], + \param HMMass: Mass of Heavy Metal in the Reactor in [t] of heavy metal, + \param CapacityFactor effective charge of the reactor, fraction between 0 & 1. + */ + Reactor(CLASSLogger* log, + FabricationPlant* fabricationplant, CLASSBackEnd* backend, + cSecond creationtime , cSecond lifetime, double Power, + double HMMass, double CapacityFactor = 1); + //} + + //{ + /// Special Constructor for reprocessed fuel using cycletime and Burn-Up. + /*! + Make a new reactor + \param log: used for the log, + \param fueltypeDB Databank describing the evolution of the fuel; + \param backend: CLASSBackend which get the fuel after the cooling, + \param creationtime: creation time in [s], + \param lifetime: working time duration in [s], + \param cycletime: duration of a cycle in [s], + \param HMMass: Mass of Heavy Metal in the Reactor in [t] of heavy metal, + \param BurnUp: Burnup reach by the fuel at the end of the cycle in [GWd/t]. + */ + Reactor(CLASSLogger* log, PhysicsModels* fueltypeDB, + FabricationPlant* fabricationplant, CLASSBackEnd* Pool, + cSecond creationtime , cSecond lifetime, cSecond cycletime, + double HMMass, double BurnUp); + //} + + //{ + /// Special Constructor for reprocessed fuel using Power and Burn-Up. + /*! + Make a new reactor + \param log: used for the log, + \param fueltypeDB Databank describing the evolution of the fuel, + \param backend: CLASSBackend which get the fuel after the cooling, + \param creationtime: creation time in [s], + \param lifetime: working time duration in [s], + \param Power: Thermal power of the reactor in [W], + \param HMMass: Mass of Heavy Metal in the Reactor in [t] of heavy metal, + \param BurnUp: Burnup reach by the fuel at the end of the cycle in [GWd/t], + \param CapacityFactor effective charge of the reactor, fraction between 0 & 1. + */ + Reactor(CLASSLogger* log, PhysicsModels* fueltypeDB, + FabricationPlant* fabricationplant, CLASSBackEnd* backend, + cSecond creationtime , cSecond lifetime, + double Power, double HMMass, double BurnUp, double CapacityFactor); + //} + + //{ + /// Special Constructor for fixed fuel using Power and Burn-Up. + /*! + Make a new reactor + \param log: used for the log, + \param evolutivedb: EvolutionData describing the evolution of the fuel, + \param backend: CLASSBackend which get the fuel after the cooling, + \param creationtime: creation time in [s], + \param lifetime: working time duration in [s], + \param Power: Thermal power of the reactor in [W], + \param HMMass: Mass of Heavy Metal in the Reactor in [t] of heavy metal, + \param BurnUp: Burnup reach by the fuel at the end of the cycle in [GWd/t], + \param CapacityFactor: effective charge of the reactor, fraction between 0 & 1. + */ + Reactor(CLASSLogger* log, EvolutionData* evolutivedb, CLASSBackEnd* backend, + cSecond creationtime, cSecond lifetime, + double power, double HMMass, double BurnUp, double CapacityFactor); + //} + + //{ + /// Special Constructor for fixed fuel using Power and Burn-Up. + /*! + Make a new reactor + \param log: used for the log, + \param evolutivedb: EvolutionData describing the evolution of the fuel, + \param backend: CLASSBackend which get the fuel after the cooling, + \param creationtime: creation time in [s], + \param lifetime: working time duration in [s] + \param Power: Thermal power of the reactor in [W], + \param HMMass: Mass of Heavy Metal in the Reactor in [t] of heavy metal, + \param BurnUp: Burnup reach by the fuel at the end of the cycle in [GWd/t], + */ + Reactor(CLASSLogger* log, EvolutionData* evolutivedb, CLASSBackEnd* backend, + cSecond creationtime, cSecond lifetime, + cSecond cycletime, double HMMass, double BurnUp); + //} + + ~Reactor(); ///< Normal Destructor + + //@} + + + + + //********* Get Method *********// + + /*! + \name Get Method + */ + //@{ + + IsotopicVector GetIVReactor() const { return GetInsideIV(); } //!< Return the IV contain in the Reactor + IsotopicVector GetIVBeginCycle() const { return fIVBeginCycle; } //!< Return the Starting Cycle IV + //!< (Note : IVBegin != IVIn, only if using charging plan) + IsotopicVector GetIVOutCycle() const { return fIVOutCycle; } //!< Return the Out Cycle IV + IsotopicVector GetIVInCycle() const { return fIVInCycle; } //!< Return the In Cycle IV + //!< (Note : IVIn != IVBegin, only if using charging plan) + + cSecond GetNextCycleTime(cSecond time); + + bool IsFuelFixed() const { return fFixedFuel; } //!< True if using fixed fuel, False otherwise + double GetHeavyMetalMass() const { return fHeavyMetalMass; } //!< Return the HeavyMetal Mass in the Core at the begining of the cycle + double GetBurnUp() const { return fBurnUp; } //!< Return the Burn Up of the Fuel at the end of the cycle + double GetPower() const { return fPower; } //!< Return the cycle time of the Reactor + +#ifndef __CINT__ + + EvolutionData GetEvolutionDB() const { return fEvolutionDB; } //!< Return the Evolution database of the fuel + CLASSBackEnd* GetOutBackEndFacility() const { return fOutBackEndFacility; } //!< Return the pointer to Associeted BackEnd Facility + FabricationPlant* GetFabricationPlant() const { return fFabricationPlant; } //!< Return the pointer to the FabricationPlant + + + CLASSFuelPlan* GetFuelPlan() const { return fFuelPlan; } //!< return the LoadingPlan + +#endif + //@} + + + + + //********* Set Method *********// + + /*! + \name Set Method + */ + //@{ + + void SetFuelPlan(CLASSFuelPlan* fuelplan) { fFuelPlan = fuelplan; } //!< return the LoadingPlan + void SetHMMass(double Mass) {fHeavyMetalMass = Mass;} //!< Set the heavy metal mass in the core at the begining of the cycle + void SetCycleTime(double cycletime); //!< Set the cycle time (Power fixed) + void SetPower(double Power); //!< Set the power (burnup cte) + void SetBurnUp(double BU); //!< Set the burnUp reach at end of cycle (Power cte) + + void SetIVReactor(IsotopicVector isotopicvector) { fInsideIV = isotopicvector; } //!< Set the IV inside the Reactor core + void SetIVBeginCycle(IsotopicVector isotopicvector) { fIVBeginCycle = isotopicvector;} //!< Set the IV at the beginging of the Reactor cycle + void SetIVOutCycle(IsotopicVector isotopicvector){ fIVOutCycle = isotopicvector;} //!< Set the IV Going out at the end of the cycle + void SetIVInCycle(IsotopicVector isotopicvector) { fIVInCycle = isotopicvector;} //!< Set the IV coming In at the beginning of the cycle + + + + +#ifndef __CINT__ + + void SetOutBackEndFacility(CLASSBackEnd* pool) { fOutBackEndFacility = pool; } //!< Return the pointer to OutBackEnd Facility + void SetStorage(Storage* storage) { fStorage = storage; fIsStorage = true;} //!< Set the pointer to the Storage + void SetFabricationPlant(FabricationPlant* FP) { fFabricationPlant = FP;} //!< Set the Pointer to the FabricationPlant + void SetEvolutionDB(EvolutionData evolutionDB); //!< Set the pointer to the DB evolution of the Reactor +#endif + + using CLASSFacility::SetName; + using CLASSFacility::GetName; + + //@} + + + + + //********* Evolution & Modification Method *********// + + /*! + \name Evolution & Modification Method + */ + //@{ + + void Evolution(cSecond t); //!< Performs the Evolution until time t + void Dump(); //!< Write modification (IV In/Out, filling the TF...) + void SetNewFuel(EvolutionData ivdb); //!< Change the Evolutive DB of the Reactor + +#ifndef __CINT__ + + void AddFuel(cSecond time, CLASSFuel fuel, double BurnUp) //!< Add A new CLASSFuel at the corresponding time and Burnup + { fFuelPlan->AddFuel( time, fuel, BurnUp); } //!< Add A new EvolutionData at the corresponding time and Burnup + void AddFuel(cSecond time, EvolutionData* fuel, double BurnUp) + { fFuelPlan->AddFuel( time, CLASSFuel(fuel), BurnUp); } //!< Add A new EvolutionData at the corresponding time and Burnup + void AddFuel(cSecond time, PhysicsModels* fuel, double BurnUp) + { fFuelPlan->AddFuel( time, CLASSFuel(fuel), BurnUp); } //!< Add A new EvolutionData at the corresponding time and Burnup +#endif + + //@} + + + + protected : + + bool fFixedFuel; //!< true if the fuel is fixed (not reprocessed) + bool fIsStorage; //!< true if a storage has been define (to approximate the reprocessing using fixed fuel) + + //********* Internal Parameter *********// + + double fPower; ///< Power (in Watt) + double fElectricPower; ///< ElectrocPower (in Watt) + double fEfficiencyFactor; ///< ElectrocPower (in Watt) + + IsotopicVector fIVBeginCycle; ///< Fuel IV at the beginning of a cycle + IsotopicVector fIVInCycle; ///< IVBegin add at the beginning of the cycle + IsotopicVector fIVOutCycle; ///< IV wich get out at the end of a cycle + +#ifndef __CINT__ + EvolutionData fEvolutionDB; //!< Pointer to the actual evolution DataBase + + CLASSBackEnd* fOutBackEndFacility; //!< Pointer to the BackEnd Facility which collect the spend fuel + + + CLASSFuelPlan* fFuelPlan; //!< Pointer to the fuel Plan + + FabricationPlant* fFabricationPlant; //!< Pointer to the FabricationPlant + + Storage* fStorage; //!< Pointer to the Stock (only for reprocessing fuel in fixed base...) + + +#endif + //********* Unfixed Fuel Parameter *********// + + + double fHeavyMetalMass; ///< In tons + double fBurnUp; ///< In GWd/tHM + + ClassDef(Reactor,3); +}; + + +#endif diff --git a/source/branches/BaM/include/Scenario.hxx b/source/branches/BaM/include/Scenario.hxx new file mode 100755 index 000000000..591d94ab5 --- /dev/null +++ b/source/branches/BaM/include/Scenario.hxx @@ -0,0 +1,316 @@ +#ifndef _SCENARIO_ +#define _SCENARIO_ +/*! + \file + \brief Header file for CLASS classes. + */ + +#include "CLASSObject.hxx" +#include "IsotopicVector.hxx" + +#include <TFile.h> +#include <TTree.h> +#include <vector> +#include <string> +#include <map> +#include <iostream> + + + +using namespace std; +typedef long long int cSecond; + +class DecayDataBank; +class FabricationPlant; +class SeparationPlant; +class Reactor; +class Pool; +class Storage; + +//-----------------------------------------------------------------------------// +//! Defines a Scenario (the whole electro-nuclear system) + +/*! + The aim of these Scenario is to manage the park and its evolution and to lead all Storage, FabricationPlant, Reactor, Pool,... + + + @author BaM + @author BLG + @version 2.0 + */ +//________________________________________________________________________ + + +class Scenario : public CLASSObject +{ + public : + + //********* Constructor/Destructor Method *********// + + /*! + \name Constructor/Desctructor + */ + //@{ + //{ + /*! + Use to load a CLASSLogger + \param log : used for the log. + \param abstime: Starting time of the Parc in second + */ + Scenario(CLASSLogger* Log, cSecond abstime = 0); ///< Log Constructor. + //} + + //{ + /*! + Use to set the starting time of the Parc + \param abstime: Starting time of the Parc in second + */ + Scenario(cSecond abstime); + //} + + //{ + /*! + Use to set the starting time of the Parc + \param abstime: Starting time of the Parc in second + \param log : used for the log. + */ + Scenario(cSecond abstime, CLASSLogger* log); + //} + + ~Scenario(); ///< Normal Destructor. + //@} + + + //********* Get Method *********// + /*! + \name Get Function + */ + //@{ + cSecond GetAbsoluteTime() { return fAbsoluteTime; } ///< Return the Absolute Clock + map<cSecond, int> GetTimeStep() { return fTimeStep; } ///< Return the Time Step vector + vector<Reactor*> GetReactor() { return fReactor; } ///< Return the Reactor vector + vector<Storage*> GetStorage() { return fStorage; } ///< Return the Storage vector + vector<Pool*> GetPool() { return fPool; } ///< Return the Pool Vector + vector<FabricationPlant*> GetFabricationPlant() { return fFabricationPlant; } ///< Return the FabricationPlant vector + DecayDataBank* GetDecayDataBase() { return fDecayDataBase; } //!< Return the Pointer to the DecayDataBank + + cSecond GetPrintSet() { return fPrintStep; } ///< Return the print step periodicity + bool GetStockManagement() { return fStockManagement; } ///< Return the StockManagement method (True or False) + string GetOutputFileName() { return fOutputFileName; } ///< Return the Output File name + string GetOutputTreeName() { return fOutputTreeName; } ///< Return the Output ROOT TTree name + + IsotopicVector GetWaste() { return fWaste;} ///< Return the waste IsotopicVcetor + + //@} + + + + + //********* Set Method *********// + /*! + \name Set Function + */ + //@{ + + //{ + /// Set the printing step periodicity + /*! + Use to set the periodicity of the output + \param timestep: periodicity of outpout in second + */ + void SetTimeStep(cSecond timestep) { fPrintStep = timestep; } + //} + + //{ + /// Set the StockManagement method + /*! + Use to define the stock managment method : true all fuel are stored individualy and false all fuel are mixed in a stock, and one can separate each isotope as needed + \param val: true or false depending on the stock management method used + */ + void SetStockManagement(bool val) { fStockManagement = val; } + //} + + //{ + /// Set the DecayDataBank + /*! + Use to define Decay DataBank to be used + \param decaydatabase: a DecayDataBank which should contain the evolution of each nuclei of the chart + */ + void SetDecayDataBase(DecayDataBank* decaydatabase) { fDecayDataBase = decaydatabase; } + //} + + //{ + /// Set the Output File Name + /*! + Use to define name of the output file + \param name: a string which correspond to the output file name + */ + void SetOutputFileName(string name) { fOutputFileName = name; } + //} + + + //{ + /// Set the Output TTree Name + /*! + Use to define name of the output ROOT TTree + \param name: a string which correspond to the output ROOT TTree name + */ + void SetOutputTreeName(string name) { fOutputTreeName = name; } + //} + //@} + + void SetLogTimeStep(bool val = true) { fLogTimeStep = true; } + + + void SetZAIThreshold(int z = 90) { fZAIThreshold = z;} + + + //********* Add Method *********// + /*! + \name Adding Facilities + */ + //@{ + + void AddPool(Pool* Pool); ///< Add a Pool to the Park + void AddReactor(Reactor* reactor); ///< Add a Reactor to the Park + void AddStorage(Storage* storage); ///< Add a Storage to the Park + void AddFabricationPlant(FabricationPlant* fabricationplant); ///< Add a Storage to the Park + void AddSeparationPlant(SeparationPlant* separationplant); + + void Add(Pool* Pool) {AddPool(Pool);} ///< Add a Pool to the Park + void Add(Reactor* reactor) {AddReactor(reactor);} ///< Add a Reactor to the Park + void Add(Storage* storage) {AddStorage(storage);} ///< Add a Storage to the Park + void Add(FabricationPlant* fabricationplant) {AddFabricationPlant(fabricationplant);} ///< Add a Storage to the Park + void Add(SeparationPlant* separationplant) {AddSeparationPlant(separationplant);} ///< Add a Storage to the Park + + //@} + + + + //********* Evolution Method *********// + /*! + \name Evolution Method + */ + //@{ + + void BuildTimeVector(cSecond t); ///< Build the Time Evolution Vector where : + /// \li 1 printing, + /// \li 2 reactor Studown + /// \li 4 start/End of reactor cycle, + /// \li 8 end of Cooling, + /// \li 16 fuel Fabrication + + void Evolution(cSecond t); ///< Perform the Evolution + void BackEndEvolution(); ///< Perform BackEnd Evolution + void PoolEvolution(); ///< Perform Pool Evolution + void PoolDump(); + + void ReactorEvolution(); ///< Perform the Reactor Evolution + void FabricationPlantEvolution(); ///< Perform the FabricationPlant Evolution + void StorageEvolution(); ///< Perform the Storage Evolution + + //@} + + + + //-------- IsotopicVector --------// + + /*! + \name IsotopicVector Sum + */ + //@{ + + + IsotopicVector GetOutIncome() const { return fOutIncome; } //!< Return the OutIncome Providings IsotopicVector + + void AddOutIncome(ZAI zai, double quantity) { AddOutIncome(zai*quantity); } //!< Add a ZAI*quantity to OutIncomeIncome + void AddOutIncome(IsotopicVector isotopicvector){ fOutIncome.Add(isotopicvector); } //!< Add a isotopicVector to OutIncomeIncome + void AddWaste(ZAI zai, double quantity) { AddWaste(zai*quantity); } //!< Add a ZAI*quantity to Waste + void AddWaste(IsotopicVector isotopicvector) { fWaste.Add(isotopicvector); } //!< Add a isotopicVector to Waste + void AddToPower(double power, double elpower) { fParcPower += power; fParcElectricPower += elpower; } + //!< Add power to the installed power in the Parc + + + void ApplyZAIThreshold(); + //@} + + + + //********* In/Out related Method *********// + + /*! + \name In/Out Method + */ + //@{ + + void PrintCLASSPresentation(); //!< CLASS informations when first running the code + void PrintClover(int i); //!< Print a nuclear clover for progression + + void ProgressPrintout(cSecond t); //!< Update the prompt output to the time t + void OldProgressPrintout(cSecond t); //!< Update the prompt output to the time t (without nuclear clover) + void SetSoberTerminalOutput(){fOldProgressBar = true;} //!< Dont display animated nuclear clover in terminal + + void Print(); //!< Print some information about the Parc + void Write(); //!< Write information in a file + + void OpenOutputTree(); //!< Open and define the Ouput ROOT TTree + void CloseOutputTree(); //!< Close and delete the Ouput ROOT TTree + void OutAttach(); //!< Attach the Branch to the Ouput ROOT TTree + + void ResetQuantity(); //!< Reset the values of the GLobal IsotopicVector + void UpdateParc(); //!< Update the Global IsotopicVector + + //@} + + + + protected : + bool fNewTtree; //!< Tru if we want to define a new TTree in the output File + bool fStockManagement; ///< True if real StockManagement false unstead (Default = true) + bool fLogTimeStep; + bool fOldProgressBar; ///< if set to true : no nuclear clover are drawn in terminal + + cSecond fPrintStep; ///< Time interval between two output update in [s] + cSecond fAbsoluteTime; ///< Absolute Clock in [s] + cSecond fStartingTime; ///< Starting Time in [s] + map<cSecond, int> fTimeStep; ///< Time Step Vector in [s] for the evolution : + /// \li 1 printing, + /// \li 2 reactor Studown + /// \li 4 start/End of reactor cycle, + /// \li 8 end of Cooling, + /// \li 16 fuel Fabrication + + int fZAIThreshold; + int fCloverCount; ///< + + vector<Storage*> fStorage; ///< Vector of Storages + vector<Pool*> fPool; ///< Vector of Pool + vector<Reactor*> fReactor; ///< Vector of Reactor + vector<FabricationPlant*> fFabricationPlant; ///< Vector of FabricationPlant + vector<SeparationPlant*> fSeparationPlant; ///< Vector of FabricationPlant + DecayDataBank* fDecayDataBase; //!< Pointer to the Decay DataBase + + + TFile* fOutFile; ///< Pointer to the Root Output File + string fOutputFileName; //! Name of the Output File + TTree* fOutT; ///< Pointer to the Root Output TTr3ee + string fOutputTreeName; //! Name of the Output TTree + string fOutputLogName; ///< Name of the Ouput log File + + IsotopicVector fWaste; ///< Waste IV + IsotopicVector fTotalStorage; ///< Sum of all IV in Storage IV + IsotopicVector fOutIncome; ///< OutIncomeIncome IV + IsotopicVector fTotalCooling; ///< Sum of all IV in Cooling IV + IsotopicVector fFuelFabrication; ///< Sum of all IV in Fabrication IV + IsotopicVector fTotalInReactor; ///< Sum of all IV in Reactor IV + + + IsotopicVector fIVInCycleTotal; ///< Sum of all IV in the cycle (without Waste) IV + IsotopicVector fIVTotal; ///< Sum of all IV in the parc (including Waste) IV + double fParcPower; ///< Sum of the Power of all reactor in the parc + double fParcElectricPower; ///< Sum of the Power of all reactor in the parc + +}; + + +#endif diff --git a/source/branches/BaM/include/SeparationPlant.hxx b/source/branches/BaM/include/SeparationPlant.hxx new file mode 100644 index 000000000..cf988d6b9 --- /dev/null +++ b/source/branches/BaM/include/SeparationPlant.hxx @@ -0,0 +1,131 @@ +#ifndef _SeparationPlant_ +#define _SeparationPlant_ +/*! + \file + \brief Header file for SeparationPlant class. + */ + +#include <string> +#include <map> + +#include "CLASSConstante.hxx" +#include "CLASSBackEnd.hxx" +#include "Storage.hxx" +#include "IsotopicVector.hxx" + +using namespace std; +typedef long long int cSecond; + +class CLASSBackEnd; +class CLASSLogger; +class DecayDataBank; + +//-----------------------------------------------------------------------------// +//! Defines a SeparationPlant. + +/*! + The aim of this class is to separate an IV into several IV (MA, Pu, PF, etc...) and + to send it to one or several Storage + + @author NT + @author BaM + @version 1.0 + */ +//________________________________________________________________________ + + + +class SeparationPlant : public CLASSBackEnd +{ +public : + + +//********* Constructor/Destructor Method *********// + + /*! + \name Constructor/Desctructor + */ + //@{ + + SeparationPlant(); ///< Normal Constructor. + + //{ + /// Special Constructor. + /*! + Make a new SeparationPlant + \param log : used for the log. + */ + SeparationPlant(CLASSLogger* Log); + //} + + ~SeparationPlant(); ///< Normal Destructor. + //@} + + +//********* Set Method *********// + + /*! + \name Set Method + */ + //@{ + + + void SetBackEndDestination(CLASSBackEnd* storagedestination, IsotopicVector isotopicvector, cSecond destinationstartingtime); //!< Tell Separation plant to begin separation at time destinationstartingtime according efficiency (between [0-1]) defined in isotopicvector and to send the separated materials to storagedestination + + void AddIV(IsotopicVector IV); + + void SetPutToWaste(bool val) { fPutToWaste = val; } //!< Set True if IV goes to waste after cooling false instead + + + using CLASSBackEnd::SetName; + + //@} + + + + +//********* Get Method *********// + + /*! + \name Get Method + */ + //@{ + + bool GetPutToWaste() const { return fPutToWaste; } //!< Return True if IV goes to waste after cooling false instead + + //@} + + + map<cSecond,int> GetTheBackEndTimePath(); + + +//********* IsotopicVector Managment Method *********// + + /*! + \name IsotopicVector Managment Method + */ + //@{ + + vector<cSecond> GetCoolingStartingTime() const + { return GetIVArrayArrivalTime(); } //!< Return the vector of Cooling starting Time + //@} + +protected : + + + +//********* Internal Parameter *********// + bool fPutToWaste; //!< True if IV goes to waste after cooling false instead + vector<CLASSBackEnd* > fDestinationStorage; //!< Vector containing destination storage of the IV in the Separation Plant + vector<IsotopicVector > fDestinationStorageIV; //!< Vector containing destination storage of the IV in the Separation Plant + vector<cSecond> fDestinationStorageStartingTime; //!< Vector containing destination storage starting time of the IV in the Separation Plant + +//********* Private Method *********// + + + + + ClassDef(SeparationPlant,3); +}; + +#endif diff --git a/source/branches/BaM/include/Storage.hxx b/source/branches/BaM/include/Storage.hxx new file mode 100644 index 000000000..01b37eeb7 --- /dev/null +++ b/source/branches/BaM/include/Storage.hxx @@ -0,0 +1,157 @@ +#ifndef _Storage_ +#define _Storage_ + +/*! + \file + \brief Header file for Storage class. + */ + + +#include <vector> + +#include "CLASSBackEnd.hxx" +#include "IsotopicVector.hxx" + + +using namespace std; +typedef long long int cSecond; + +class CLASSLogger; +class DecayDataBank; + +//-----------------------------------------------------------------------------// +//! Defines a Storage object + +/*! + A Storage is a CLASSBackEnd facility. It is almost the same as a Pool with a + infinite cooling time. + A CLASSFacility can take IsotopicVector(s) contained in a Storage but a Storage + cannot send its content in other CLASSFacility (its a kind of passive facility) + + @author BaM + @version 2.0 + */ +//________________________________________________________________________ + + + +class Storage : public CLASSBackEnd +{ +public : + + +//********* Constructor/Destructor Method *********// + + /*! + \name Constructor/Desctructor + */ + //@{ + + Storage(); ///< Normal Constructor. + + //{ + /// CLASSLogger Constructor. + /*! + Use to create an empty Storage with a CLASSLogger + \param log : used for the log. + */ + Storage(CLASSLogger* log); + //} + + + //{ + /// Special Constructor. + /*! + Make a new Storage + \param log : used for the log. + \param evolutivedb : DecayDataBank for decay management + */ + Storage(CLASSLogger* log, DecayDataBank* evolutivedb); + //} + + + ~Storage(); ///< Normal Destructor. + + //@} + + + + +//********* Set Method *********// + + /*! + \name Set Method + */ + //@{ + + using CLASSBackEnd::SetName; + using CLASSBackEnd::SetIsStorageType; + + //@} + +//********* Storage specific Method *********// + + /*! + \name Storage specific methods + */ + //@{ + + void TakeFractionFromStock(int IVId,double fraction); //!< Take a part from an IV in sotck; + void TakeFromStock(IsotopicVector isotopicvector); //!< Take an entire IV from stock + + + void AddIV(IsotopicVector isotopicvector); //!< Add an Isotopicvector to the IVArray + void AddToStock(IsotopicVector isotopicvector) { if( (int) isotopicvector.GetIsotopicQuantity().size() > 0 ) AddIV(isotopicvector);} //!< Add an Isotopicvector to the IVArray if it is not empty + void RemoveEmptyStocks(); //!< delete the empty Isotopicvector(s) contained in IVArray + + //@} + + + + +//********* Evolution Method *********// + + /*! + \name Evolution Method + */ + //@{ + + void Evolution(cSecond t); //!< Perform the evolution until time t + + //@} + + //********* In/Out Method *********// + + /*! + \name In/Out Method + */ + //@{ + + //{ + /// Write the Isotope composition of all IsotopicVector stored. + /*! + Make a new reactor + \param filename : CLASSLogger used for the log. + \param date : only use to write a date in the file + */ + void Write(string filename,cSecond date = -1); + //} + + //@} + +protected : + +//********* Isotopic Quantity *********// + + + +//********* Private Method *********// + void StorageEvolution(cSecond t); //!< Deal the Storage Decay Evolution + + + + + ClassDef(Storage,3); +}; + +#endif diff --git a/source/branches/BaM/include/StringLine.hxx b/source/branches/BaM/include/StringLine.hxx new file mode 100755 index 000000000..aaac1fb53 --- /dev/null +++ b/source/branches/BaM/include/StringLine.hxx @@ -0,0 +1,306 @@ +#ifndef _STRINGLINE_ +#define _STRINGLINE_ + +#include <string> +#include <sstream> +#include <iostream> +#include <algorithm> +#include <cctype> +using namespace std; +/*! + \file + \brief Header file for StingLine class. +*/ + +//! Class extracting fields from a string / line. +/*! + The aim of this class is to provide tools to extract fields ("word") from + a string and convert a string in Upper/Lower case. + All methods are static so that it is not necessary to create object to use them + + example: + \code + string line = "The temperature is : 300.6 K"; + int start; + + 1st method: creation of StringLine + + start = 0; + StringLine SL; + string the = SL.NextWord(line,start); + string temperature_is = SL.NextWord(line,start,':'); + string colon = SL.NextWord(line,start); + double T = atof(SL.NextWord(line,start).c_str()); + cout << the << endl << temperature_is << endl << T << endl; + + 2nd method: "using" the static methods + + start = 0; + the = StringLine::NextWord(line,start); + temperature_is = StringLine::NextWord(line,start,':'); + colon = StringLine::NextWord(line,start); + T = atof(StringLine::NextWord(line,start).c_str()); + cout << the << endl << temperature_is << endl << T << endl; + \endcode + @author PTO + @version 0.1 +*/ + +class StringLine +{ + public: + //! Find the next word in a line. + /*! + Find Next word in a line starting from position "start" in the line. If an alternative + separator is given, the word length is defined by the first position of sep or alt_sep found. + The first value of start is in general 0 (i.e. the beginning of the Line) + \param Line : a line containing words + \param start : from where to start to find the begining of a word + \param sep : the separator between 2 words (default = space) + \param alt_sep : the alternative separator between 2 words (default = '') + */ + static string NextWord(string Line,int &start,char sep = ' ', char alt_sep = '\0'); + //! Find the previous word in a line. + /*! + Find Previous word in a line starting from position "start" in the line. If an alternative + separator is given, the word length is defined by the first position of sep or alt_sep found. + The first value of start is in general the end of the Line. + \param Line : a line containing words + \param start : from where to start to find the begining of a word + \param sep : the separator between 2 words (default = space) + \param alt_sep : the alternative separator between 2 words (default = '') + */ + static string PreviousWord(string Line,int &start,char sep = ' ', char alt_sep = '\0'); + static void ToLower(string &Line); //!< convert a string to Lower case + static void ToUpper(string &Line); //!< convert a string to Upper case + + //! Find \p search in \p Line from the begining. + /*! + returns the position, starting from the begenning of the first occurence + of \p search in \p Line if it is found, else returns -1 + \param search : a string to find + \param Line : where to search + */ + static int Find(const char *search,string Line); + //! Find \p search in \p Line from the end. + /*! + returns the position, starting from the end of the first occurence + of \p search in \p Line if it is found, else returns -1 + \param search : a string to find + \param Line : where to search + */ + static int rFind(const char *search,string Line); + //! convert a input type (\p in_T) to another (\p out_T). + /*! + Example: + \code + string s = "32.12"; + double t = StringLine::convert<double>(s); + string temperature = StringLine::convert<string>(300.); + \endcode + \param t : the input value + */ + template <class out_T, class in_T> static out_T convert(const in_T & t); + //! try to convert a string to a number. + /*! + Example: + \code + string s = "32.12"; + double d; + if(StringLine::ToNumber(d,s,std::dec)) + cout << "double = " << d << endl; + string hexanum = "ff"; + int i; + if(StringLine::ToNumber(i,hexanum,std::hex)) + cout << "int = " << i << endl; + \endcode + \param s : the input string + \param t : the output value + \param f : string format (ie hex, dec, oct) + */ + template <class T> static bool ToNumber(T& t, const std::string& s, std::ios_base& (*f)(std::ios_base&)) + { + if(s.size() == 0) return true; + std::istringstream iss(s); + return !(iss >> f >> t).fail(); + } + //! Find the start of a word in a line. + /*! + \param Line : a line containing words + \param CurrentPosition : from where to start to find the begining of a word + \param sep : the separator between 2 words (default = space) + \param alt_sep : the alternative separator between 2 words (default = '') + */ + static int GetStartWord(string Line,int CurrentPosition,char sep = ' ', char alt_sep = '\0'); + //! Find the end of a word in a line. + /*! + \param Line : a line containing words + \param CurrentPosition : from where to start to find the end of a word + \param sep : the separator between 2 words (default = space) + \param alt_sep : the alternative separator between 2 words (default = '') + */ + static int GetEndWord(string Line,int CurrentPosition,char sep = ' ', char alt_sep = '\0'); + //! Replace a sub-string by an other in a string. + /*! + \param InLine : the string which contains the sub-string to replace + \param ToReplace : the sub-string to replace + \param By : the sub-string ToReplace is replaced by the sub-string By in Inline + */ + static string ReplaceAll(string InLine, string ToReplace, string By); + static bool IsDouble(const std::string& s); +}; + + +//_________________________________________________________________________________ +inline string StringLine::NextWord(string Line,int &start,char sep, char alt_sep) +{ + string Word = ""; + if(start>= int(Line.size())) + { + return Word; + } + start = GetStartWord(Line,start,sep,alt_sep); + int wordlength = GetEndWord(Line,start,sep,alt_sep)-start; + + Word = Line.substr(start,wordlength); + + start+= wordlength; + return Word; +} +//_________________________________________________________________________________ +inline string StringLine::PreviousWord(string Line,int &start,char sep, char alt_sep) +{ + string Word = ""; + if(start<= 0) + { + return Word; + } + int pos = Line.rfind(sep,start); + int alt_pos = -1; + int real_pos = pos; + char real_sep = sep; + if(alt_sep != '\0') + { + alt_pos = Line.rfind(alt_sep,start); + real_pos = max(pos,alt_pos); + if(real_pos != pos) + real_sep = alt_sep; + } + int wordlength = start-Line.rfind(real_sep,real_pos); + if(real_pos<= 0) + { + Word = Line.substr(0,start+1); + start = 0; + return Word; + } + Word = Line.substr(real_pos+1,wordlength); + + start-= wordlength+1; + return Word; +} + +//_________________________________________________________________________________ +inline void StringLine::ToLower(string &Line) +{ + transform (Line.begin(), Line.end(), // source + Line.begin(), // destination + (int(*)(int))tolower); // operation +} + +//_________________________________________________________________________________ +inline void StringLine::ToUpper(string &Line) +{ + transform (Line.begin(), Line.end(), // source + Line.begin(), // destination + (int(*)(int))toupper); // operation +} + +//_________________________________________________________________________________ +inline int StringLine::GetStartWord(string Line,int CurrentPosition,char sep, char alt_sep) +{ + int pos = Line.find(sep,CurrentPosition); + int alt_pos = -1; + if(alt_sep != '\0') + alt_pos = Line.find(alt_sep,CurrentPosition); + int real_pos = pos; + char real_sep = sep; + if(alt_pos>= 0) + { + real_pos = min(pos,alt_pos); + if(pos == int(string::npos))real_pos = alt_pos; + if(real_pos != pos) + real_sep = alt_sep; + } + if(real_pos == int(string::npos)) return CurrentPosition; + while(CurrentPosition<int(Line.size()) && Line[CurrentPosition] == real_sep) + CurrentPosition++; + return CurrentPosition; +} + +//_________________________________________________________________________________ +inline int StringLine::GetEndWord(string Line,int CurrentPosition,char sep, char alt_sep) +{ + int pos = Line.find(sep,CurrentPosition); + int alt_pos = -1; + if(alt_sep != '\0') + alt_pos = Line.find(alt_sep,CurrentPosition); + int real_pos = pos; + if(alt_pos>= 0) + { + real_pos = min(pos,alt_pos); + if(pos == int(string::npos))real_pos = alt_pos; + } + if(real_pos == int(string::npos)) + return Line.size(); + return real_pos; +} + +//_________________________________________________________________________________ +inline int StringLine::Find(const char *search,string Line) +{ + size_t Pos = Line.find(search); + if(Pos != string::npos ) return Pos; + return -1; +} + +//_________________________________________________________________________________ +inline int StringLine::rFind(const char *search,string Line) +{ + size_t Pos = Line.rfind(search); + if(Pos != string::npos) return Pos; + return -1; +} + +//_________________________________________________________________________________ +template <class out_T, class in_T> +inline out_T StringLine::convert(const in_T & t) +{ + stringstream stream; + stream << t; // insert value to stream + out_T result; // store conversion's result here + stream >> result; // write value to result + return result; +} + +//_________________________________________________________________________________ +inline string StringLine::ReplaceAll(string InLine, string ToReplace, string By) +{ + int start = 0; + int pos = InLine.find(ToReplace,start); + while(pos != int(string::npos)) + { + InLine.replace(pos,ToReplace.size(),By); + start = 0; + pos = InLine.find(ToReplace,start); + } + return InLine; +} +//_________________________________________________________________________________ +inline bool StringLine::IsDouble(const std::string& s) +{ + std::istringstream i(s); + double temp; + return ( (i >> temp) ? true : false ); +} + +#endif diff --git a/source/branches/BaM/include/XSModel.hxx b/source/branches/BaM/include/XSModel.hxx new file mode 100644 index 000000000..2c78ac42b --- /dev/null +++ b/source/branches/BaM/include/XSModel.hxx @@ -0,0 +1,126 @@ +#ifndef _XSMODEL_ +#define _XSMODEL_ + + +/*! + \file + \brief Header file for XSMODEL class. + + + @author BaM + @author BLG + @version 2 + */ +#include "EvolutionData.hxx" +#include "CLASSObject.hxx" + +#include <iostream> +#include <map> + +using namespace std; + +class IsotopicVector; + +class XSModel; +#ifndef __CINT__ +typedef void (XSModel::*XSM_MthPtr)( const string & ) ; +#endif + +//-----------------------------------------------------------------------------// +//! Defines a mean cross section predictor + +/*! + This is the mother class for methods related to XS prediction + + \warning + Never instantiate XSModel in your CLASS input but it's derivated class + + @see XSM_CLOSEST + @see XSM_MLP + + @author BaM + @author BLG + @version 2 + */ +//________________________________________________________________________ + + +class XSModel : public CLASSObject +{ + + public : + + /*! + \name Constructor/Desctructor + */ + //@{ + + XSModel(); //!<Default constructor + + + XSModel(CLASSLogger* log); //!<Logger constructor + + //@} + + + /*! + \name Virtual methods : This following methods are overloaded in the derivated classes : XSM_CLOSEST & XSM_MLP & ... + */ + //@{ + + //{ + /// Pure virtual method called to estimates mean cross sections. + /*! + Estimates the mean cross sections evolution according the fresh fuel composition + \param IV : Fresh fuel composition + \param t : deprecated parameter : + \deprecated t : XS update time (used in XSM_Closest) + */ + //} + virtual EvolutionData GetCrossSections(IsotopicVector IV,double t = 0) = 0 ; + + /// Check either the IsotopicVector IV is in the validity domain of the models. + /*! + return true if IV is in ValidityDomain + return false + a warning if IV is not in ValidityDomain + \param IsotopicVector IV, Fresh fuel composition + \param t : deprecated parameter : + \deprecated t : XS update time (used in XSM_Closest) + */ + virtual bool isIVInDomain(IsotopicVector IV) ; + //@} + + void ReadNFO(); + virtual void ReadLine(string line); + + + void ReadZAIlimits(const string &line); + void ReadType(const string &line); + void ReadRParam(const string &line); + + virtual void LoadKeyword(); + + + void SetZAIThreshold(int Z_Threshold){fZAIThreshold = Z_Threshold;}//!< Set the Z threshold : ZAI with Z < fZAIThreshold are not manage by CLASS + int GetZAIThreshold(){return fZAIThreshold;}//!< Get the Z threshold + + protected : + bool freaded; + string fInformationFile; //!< file containing Reactor Type, Fuel type, HM mass, Power, time vector, and TMVA input variables names (looks the manual for format details) + + double fDBPower; //!< Power of the data base (read from fMLPInformationFile ) + double fDBHMMass; //!< Heavy metal mass of the data base (read from fMLPInformationFile ) + string fDBFType; //!< Fuel Type (e.g MOX, UOX, ThU, ThPu ...) + string fDBRType; //!< Reactor Type (e.g PWR, FBR-Na, ADS..) + + map< ZAI, pair<double,double> > fZAILimits; //!< Fresh fuel range : map<ZAI<min edge ,max edge >> + +#ifndef __CINT__ + map<string, XSM_MthPtr> fKeyword; +#endif + + int fZAIThreshold; //!< Z threshold for handling nuclei mean cross section (take only ZAI reaction of Z>= fZAIThresold) +}; + +#endif + diff --git a/source/branches/BaM/include/ZAI.hxx b/source/branches/BaM/include/ZAI.hxx new file mode 100755 index 000000000..1ddb39d43 --- /dev/null +++ b/source/branches/BaM/include/ZAI.hxx @@ -0,0 +1,96 @@ +#ifndef _ZAI_ +#define _ZAI_ + +/*! + \file + \brief Header file for ZAI classes. + */ + +#include <string> +#include "TObject.h" +#include <iostream> + +using namespace std; + +//-----------------------------------------------------------------------------// +//! Defines a nucleus + +/*! + Define a nuclei as 3 integer Z,A,I: + \li its charge number : Z + \li its mass number : A + \li its Isomeric state : I (0 : fundamental, 1 : first isomeric state ,...) + + The aim of this class is to discribe each ZAI. + + @author BaM + @version 2.0 + */ +//________________________________________________________________________ + + + +class ZAI : public TObject +{ +public: + + +//********* Constructor/Destructor Method *********// + + /*! + \name Constructor/Desctructor + */ + //@{ + + ZAI(); ///< Default constructor + + //{ + ///< Normal Constructor. + /*! + Default: No parent + \param Z : number of protons + \param A : number of nucleons (A = 0 means natural isotopes) + */ + ZAI(int Z, int A, int I = 0); + //} + + + ~ZAI(); ///< Normal Destructor. + + +//********* ZAI main attributes Method *********// + + /*! + \name ZAI main attributes + */ + //@{ + int Z() const { return fZ; } //!< returns the number of protons + int A() const { return fA; } //!< returns the number of nucleons + int I() const { return fI; } //!< returns the Isomeric State + int N() const { return fA-fZ; } //!< returns the number of neutrons + + //@} + + + + ZAI operator = (ZAI IVa); //!< + bool operator <(const ZAI& zai) const { return (fZ != zai.Z())? + (fZ < zai.Z()) : ( (fA != zai.A())? + (fA < zai.A()) : (fI < zai.I()) ); }//!< Compartor operator + + bool operator != (const ZAI& zai) const { return ( fZ != zai.Z() ) || ( fA != zai.A() ) || ( fI != zai.I() ); }//!< Compartor operator + bool operator == (const ZAI& zai) const { return ( fZ == zai.Z() && fA == zai.A() && fI == zai.I()); }//!< Compartor operator + void Print() const { cout << fZ << " " << fA << " " << fI << endl;}//!< Print in standard output : Z A I + + +protected : + + short fZ; ///< number of protons + short fA; ///< number of nucleons (A = 0 means natural isotopes) + short fI; ///< Isomeric state + + ClassDef(ZAI,1); +}; + + +#endif diff --git a/source/branches/BaM/include/ZAIHeat.hxx b/source/branches/BaM/include/ZAIHeat.hxx new file mode 100644 index 000000000..f126c7348 --- /dev/null +++ b/source/branches/BaM/include/ZAIHeat.hxx @@ -0,0 +1,70 @@ +#ifndef _ZAIHeat_ +#define _ZAIHeat_ + +/*! + \file + \brief Header file for ZAIHeat classes. + + + @author BaM + @author BLG + @version 2.0 + */ + +#include <map> + +#include "ZAI.hxx" +#include "TObject.h" +#include <iostream> + +using namespace std; + + +class IsotopicVector; + +//-----------------------------------------------------------------------------// +//! Defines the decay heat of a ZAI + /*! + The aims of this class is to handle decay heat + Activity-to-Heat factors are from (92SDOe + M.e.Brendan, dec 98). + Values are in CLASS_PATH/data/HeatTox.dat + + @author BLG + @author BaM + @version 1.0 + */ +//________________________________________________________________________ + + +class ZAIHeat +{ + + +public: + /*! + \name Constructor/Desctructor + */ + //@{ + + ZAIHeat();//!< Normal Constructor. + + ~ZAIHeat();//!< Normal Destructor. + //@} + + /*! + \name Fucntions returning decay Heat [W] + */ + //@{ + double GetHeat(ZAI zai ) const; //!< get with ZAI + double GetHeat(const int Z, const int A, const int I ) const { return GetHeat( ZAI(Z, A, I) ); } //!< Get with Z, A + + double GetHeat(const IsotopicVector IV) const; //return Heat of IV [W] + //@} +private: + map<ZAI, double> fZAIHeat; //! ZAI Heat list + + +}; + + +#endif diff --git a/source/branches/BaM/include/ZAIMass.hxx b/source/branches/BaM/include/ZAIMass.hxx new file mode 100644 index 000000000..252e69c90 --- /dev/null +++ b/source/branches/BaM/include/ZAIMass.hxx @@ -0,0 +1,70 @@ +#ifndef _ZAIMass_ +#define _ZAIMass_ + +/*! + \file + \brief Header file for ZAIMass classes. + + + @author BaM + @author BLG + @version 2.0 + */ + +#include <map> + +#include "ZAI.hxx" +#include "TObject.h" +#include <iostream> + +using namespace std; + + +class IsotopicVector; + +//-----------------------------------------------------------------------------// +//! Defines the molar mass of a ZAI + +/*! + The aims of this class is to handle the molar mass of each ZAI + + @author BaM + @author BLG + @version 1.0 + */ +//________________________________________________________________________ + + +class ZAIMass +{ + + +public: + /*! + \name Constructor/Desctructor + */ + //@{ + + ZAIMass();//!< Normal Constructor. + + ~ZAIMass();//!< Normal Destructor. + //@} + + /*! + \name Fucntions returning molar mass [g/mol] + */ + //@{ + double GetMass(ZAI zai ) const; //!< get with ZAI + double GetMass(const int Z, const int A ) const { return GetMass( ZAI(Z, A, 0) ); } //!< Get with Z, A + //@} + + double GetMass(const IsotopicVector IV) const; //return Mass of IV [t] + +private: + map<ZAI, double> fZAIMass; //! ZAI mass list + + +}; + + +#endif diff --git a/source/branches/BaM/include/ZAITox.hxx b/source/branches/BaM/include/ZAITox.hxx new file mode 100644 index 000000000..9a7b05904 --- /dev/null +++ b/source/branches/BaM/include/ZAITox.hxx @@ -0,0 +1,70 @@ +#ifndef _ZAITox_ +#define _ZAITox_ + +/*! + \file + \brief Header file for ZAITox classes. + + + @author BaM + @author BLG + @version 2.0 + */ + +#include <map> + +#include "ZAI.hxx" +#include "TObject.h" +#include <iostream> + +using namespace std; + + +class IsotopicVector; + +//-----------------------------------------------------------------------------// +//! Defines the Radiotoxicity of a ZAI + /*! + The aims of this class is to handle radiotoxicity + Activity-to-Sievert factors are from (??). + Values are in CLASS_PATH/data/HeatTox.dat + + @author BLG + @author BaM + @version 1.0 + */ +//________________________________________________________________________ + + +class ZAITox +{ + + +public: + /*! + \name Constructor/Desctructor + */ + //@{ + + ZAITox();//!< Normal Constructor. + + ~ZAITox();//!< Normal Destructor. + //@} + + /*! + \name Fucntions returning radiotoxicity [Sv] + */ + //@{ + double GetRadioTox(ZAI zai ) const; //!< get with ZAI + double GetRadioTox(const int Z, const int A, const int I ) const { return GetRadioTox( ZAI(Z, A, I) ); } //!< Get with Z, A + + double GetRadioTox(const IsotopicVector IV) const; //return Heat of IV [W] + //@} +private: + map<ZAI, double> fZAITox; //! ZAI Radiotox list + + +}; + + +#endif diff --git a/source/branches/BaM/src/CLASSBackEnd.cxx b/source/branches/BaM/src/CLASSBackEnd.cxx new file mode 100644 index 000000000..37c5659f2 --- /dev/null +++ b/source/branches/BaM/src/CLASSBackEnd.cxx @@ -0,0 +1,138 @@ +#include "CLASSBackEnd.hxx" + +#include "DecayDataBank.hxx" +#include "Scenario.hxx" +#include "CLASSLogger.hxx" + + +#include <sstream> +#include <string> +#include <iostream> +#include <cmath> +#include <algorithm> + +//________________________________________________________________________ +// +// CLASSBackEnd +// +// +// +// +//________________________________________________________________________ +ClassImp(CLASSBackEnd) + +CLASSBackEnd::CLASSBackEnd(int type):CLASSFacility(type) +{ + fDecayDataBase = 0; +} + +CLASSBackEnd::CLASSBackEnd(CLASSLogger* log, int type):CLASSFacility(log, type) +{ + fDecayDataBase = 0; +} + + +CLASSBackEnd::CLASSBackEnd(CLASSLogger* log, cSecond cycletime, int type):CLASSFacility(log, cycletime, type) +{ + fDecayDataBase = 0; +} + +//________________________________________________________________________ +void CLASSBackEnd::ClearIVArray() +{ + + IsotopicVector EmptyIV; + fInsideIV = EmptyIV; + fIVArray.clear(); + fIVArrayArrivalTime.clear(); +} + +//________________________________________________________________________ +void CLASSBackEnd::AddIV(IsotopicVector isotopicvector) +{ + + AddCumulativeIVIn(isotopicvector); + + fIVArray.push_back(isotopicvector); + fIVArrayArrivalTime.push_back(fInternalTime); + + +} +//________________________________________________________________________ +void CLASSBackEnd::UpdateInsideIV() +{ + DBGL + fInsideIV = IsotopicVector(); + for(int i = 0; i < (int)fIVArray.size(); i++) + fInsideIV += fIVArray[i]; + DBGL +} + + +//________________________________________________________________________ +// Get Decay +//________________________________________________________________________ +IsotopicVector CLASSBackEnd::GetDecay(IsotopicVector isotopicvector, cSecond t) +{ + DBGL + + IsotopicVector IV; + + map<ZAI ,double> isotopicquantity = isotopicvector.GetIsotopicQuantity(); + map<ZAI ,double >::iterator it; + for( it = isotopicquantity.begin(); it != isotopicquantity.end(); it++) + { + if((*it).second > 0) + { + IsotopicVector ivtmp = fDecayDataBase->Evolution(it->first, t) * (*it).second ; + IV += ivtmp; + } + } + + DBGL + return IV; +} + + +void CLASSBackEnd::ApplyZAIThreshold(int z) +{ + fInsideIV.ApplyZAIThreshold(z); + fCumulativeIVIn.ApplyZAIThreshold(z); + fCumulativeIVOut.ApplyZAIThreshold(z); + + for(int i = 0; i < (int)fIVArray.size(); i++) + fIVArray[i].ApplyZAIThreshold(z); + +} + + +map<cSecond,int> CLASSBackEnd::GetTheBackEndTimePath() +{ + DBGL + map<cSecond, int> TheBackEndTimePath; + + if(!fIsStorageType) + { + int FacilityType = GetFacilityType(); + cSecond step = GetCycleTime(); + + pair< map<cSecond, int>::iterator, bool > IResult = TheBackEndTimePath.insert(pair<cSecond,int> (step, FacilityType)); + if( !IResult.second ) IResult.first->second |= FacilityType; + + map<cSecond, int> TheBackEndTimePath_tmp = GetOutBackEndFacility()->GetTheBackEndTimePath(); + + map<cSecond, int>::iterator it; + for (it = TheBackEndTimePath_tmp.begin(); it != TheBackEndTimePath_tmp.end(); it++) + { + pair< map<cSecond, int>::iterator, bool > IResult; + + IResult = TheBackEndTimePath.insert( pair<cSecond ,int>(step + (*it).first, (*it).second) ); + if( !IResult.second ) + IResult.first->second |= (*it).second; + + } + } + + DBGL + return TheBackEndTimePath; +} \ No newline at end of file diff --git a/source/branches/BaM/src/CLASSFacility.cxx b/source/branches/BaM/src/CLASSFacility.cxx new file mode 100644 index 000000000..e2c19f2c2 --- /dev/null +++ b/source/branches/BaM/src/CLASSFacility.cxx @@ -0,0 +1,91 @@ +#include "CLASSFacility.hxx" +#include "Scenario.hxx" + +using namespace std; + + //________________________________________________________________________ + // + // CLASSFacility + // + // + // + // + //________________________________________________________________________ + +ClassImp(CLASSFacility) + + + + +CLASSFacility::CLASSFacility(int type):CLASSObject() +{ + fParc = 0; + + fFacilityType = type; + + fInternalTime = 0; + fInCycleTime = 0; + fCycleTime = -1; +} + +CLASSFacility::CLASSFacility(CLASSLogger* log, int type):CLASSObject(log) +{ + fParc = 0; + + fFacilityType = type; + + fInternalTime = 0; + fInCycleTime = 0; + fCycleTime = -1; +} + + +CLASSFacility::CLASSFacility(CLASSLogger* log, cSecond cycletime, int type):CLASSObject(log) +{ + fParc = 0; + + fFacilityType = type; + + fInternalTime = 0; + fInCycleTime = 0; + fCycleTime = cycletime; + +} + +CLASSFacility::CLASSFacility(CLASSLogger* log, cSecond creationtime, cSecond lifetime, int type):CLASSObject(log) +{ + fParc = 0; + + fFacilityType = type; + + fInternalTime = fCreationTime; + fInCycleTime = 0; + fCycleTime = -1; + + fCreationTime = creationtime; + fLifeTime = lifetime; +} + +CLASSFacility::CLASSFacility(CLASSLogger* log, cSecond creationtime, cSecond lifetime, cSecond cycletime, int type):CLASSObject(log) +{ + fParc = 0; + + fFacilityType = type; + + fInternalTime = fCreationTime; + fInCycleTime = 0; + fCycleTime = cycletime; + + fCreationTime = creationtime; + fLifeTime = lifetime; +} + + + +void CLASSFacility::ApplyZAIThreshold(int z) +{ + fInsideIV.ApplyZAIThreshold(z); + fCumulativeIVIn.ApplyZAIThreshold(z); + fCumulativeIVOut.ApplyZAIThreshold(z); + +} \ No newline at end of file diff --git a/source/branches/BaM/src/CLASSFuel.cxx b/source/branches/BaM/src/CLASSFuel.cxx new file mode 100644 index 000000000..de1d23c3a --- /dev/null +++ b/source/branches/BaM/src/CLASSFuel.cxx @@ -0,0 +1,26 @@ +#include "CLASSFuel.hxx" + +#include "CLASSLogger.hxx" + +using namespace std; + +//________________________________________________________________________ +// +// CLASSFuel +// +// +// +// +//________________________________________________________________________ + +CLASSFuel::CLASSFuel(EvolutionData* evo) +{ + fEvolutionData = evo; + fPhysicsModels = 0; +} + +CLASSFuel::CLASSFuel(PhysicsModels* evo) +{ + fEvolutionData = 0; + fPhysicsModels = evo; +} \ No newline at end of file diff --git a/source/branches/BaM/src/CLASSFuelPlan.cxx b/source/branches/BaM/src/CLASSFuelPlan.cxx new file mode 100644 index 000000000..95f897329 --- /dev/null +++ b/source/branches/BaM/src/CLASSFuelPlan.cxx @@ -0,0 +1,69 @@ +#include "CLASSFuelPlan.hxx" + +#include "CLASSLogger.hxx" + +using namespace std; + +//________________________________________________________________________ +// +// CLASSFuelPlan +// +// +// +// +//________________________________________________________________________ + +CLASSFuelPlan::CLASSFuelPlan():CLASSObject() +{ + DBGL +} + +CLASSFuelPlan::CLASSFuelPlan(CLASSLogger* log):CLASSObject(log) +{ + DBGL + DBGL +} + +void CLASSFuelPlan::AddFuel(cSecond time, CLASSFuel fuel, double BurnUp) +{ + DBGL + fLoadingPlan.insert(pair< cSecond, pair< CLASSFuel, double > >(time, pair< CLASSFuel, double > (fuel, BurnUp)) ); + DBGL +} + +pair< CLASSFuel, double > CLASSFuelPlan::GetFuelAt(cSecond t) +{ + DBGL + + pair< CLASSFuel, double > FuelAtT = fLoadingPlan.begin()->second; + + map< cSecond, pair< CLASSFuel, double > >::iterator it; + + cSecond ThisFuelTime; + + for (it = fLoadingPlan.begin(); it != fLoadingPlan.end(); it++ ) + { + if( it == fLoadingPlan.begin()) + { + FuelAtT = (*it).second; + } + else + { + ThisFuelTime = (*it).first; + + if( t < ThisFuelTime ) + { + DBGL + return FuelAtT; + } + else + { + FuelAtT = (*it).second; + } + + } + } + + DBGL + return FuelAtT; +} diff --git a/source/branches/BaM/src/CLASSLogger.cxx b/source/branches/BaM/src/CLASSLogger.cxx new file mode 100755 index 000000000..31839ca64 --- /dev/null +++ b/source/branches/BaM/src/CLASSLogger.cxx @@ -0,0 +1,112 @@ + +#include "CLASSLogger.hxx" + +#include <iostream> +#include <ostream> +#include <algorithm> +using namespace std; + +//________________________________________________________________________ +// +// CLASSLogger +// +// +// +// +//________________________________________________________________________ +CLASSLogger::CLASSLogger(string CLASSLoggerName, int VerboseLvl, int OutputLvl ) +{ + fCLASSLoggerName = CLASSLoggerName; + fOutPutFile.open(CLASSLoggerName.c_str()); + fVerboseLVL = VerboseLvl; + if(!fOutPutFile) + { + cout << "Could not open the CLASSLogger: " << CLASSLoggerName << " !" << endl; + exit(-1); + } + + fError = 0; + fWarning = 0; + fDebug = 0; + fInfo = 0; + + if (VerboseLvl <= OutputLvl) + fMaxOutPutLVL = OutputLvl; + else + fMaxOutPutLVL = VerboseLvl; + + if(VerboseLvl >= 0) + { + if (!fError) + fError = new LogType(std::cout); + else + fError->SetSecondOutput(std::cout); + } + + if(VerboseLvl >= 1) + { + if (!fWarning) + fWarning = new LogType(std::cout); + else + fWarning->SetSecondOutput(std::cout); + } + if(VerboseLvl >= 2) + { + if (!fInfo) + fInfo = new LogType(std::cout); + else + fInfo->SetSecondOutput(std::cout); + } + if(VerboseLvl >= 3) + { + if (!fDebug) + fDebug = new LogType(std::cout); + else + fDebug->SetSecondOutput(std::cout); + } + + + if(OutputLvl >= 0) + { + if (!fError) + fError = new LogType(fOutPutFile); + else + fError->SetSecondOutput(fOutPutFile); + } + if(OutputLvl >= 1) + { + if (!fWarning) + fWarning = new LogType(fOutPutFile); + else + fWarning->SetSecondOutput(fOutPutFile); + } + if(OutputLvl >= 2) + { + if (!fInfo) + fInfo = new LogType(fOutPutFile); + else + fInfo->SetSecondOutput(fOutPutFile); + } + if(OutputLvl >= 3) + { + if (!fDebug) + fDebug = new LogType(fOutPutFile); + else + fDebug->SetSecondOutput(fOutPutFile); + } + + + +} + +//________________________________________________________________________ +CLASSLogger::~CLASSLogger() +{ + + fOutPutFile.close(); + +} + + + + diff --git a/source/branches/BaM/src/CLASSNucleiFiliation.cxx b/source/branches/BaM/src/CLASSNucleiFiliation.cxx new file mode 100644 index 000000000..e5c172ef6 --- /dev/null +++ b/source/branches/BaM/src/CLASSNucleiFiliation.cxx @@ -0,0 +1,323 @@ +#include "CLASSNucleiFiliation.hxx" +#include "ZAI.hxx" +#include "IsotopicVector.hxx" + +#include <map> +#include <vector> +#include <cmath> + +using namespace std; + +//const string DEFAULTDATABASE = "DecayBase.dat"; +//________________________________________________________________________ +// +// CLASSNucleiFiliation +// +// +// +// +//________________________________________________________________________ +//____________________________InClass Operator____________________________ +//________________________________________________________________________ + +CLASSNucleiFiliation::CLASSNucleiFiliation():CLASSObject() +{ +} +CLASSNucleiFiliation::CLASSNucleiFiliation(CLASSLogger* log):CLASSObject(log) +{ +} + +CLASSNucleiFiliation::CLASSNucleiFiliation(const CLASSNucleiFiliation& CNF):CLASSObject() +{ + fNucleiFiliation = CNF.GetNucleiFIliation(); +} +//________________________________________________________________________ +CLASSNucleiFiliation::~CLASSNucleiFiliation() +{ + fNucleiFiliation.clear() ; +} +//________________________________________________________________________ +void CLASSNucleiFiliation::Add( ZAI Mother, IsotopicVector Daughter ) +{ + DBGL + + pair< map<ZAI, IsotopicVector>::iterator, bool> IResult; + + + IResult = fNucleiFiliation.insert( pair<ZAI, IsotopicVector> ( Mother, Daughter ) ); + + if( !IResult.second) + (*IResult.first).second += Daughter ; + + + DBGL +} + + +//________________________________________________________________________ +IsotopicVector CLASSNucleiFiliation::GetFiliation(ZAI Mother) +{ + DBGV(Mother.Z() << " " << Mother.A() << " " << Mother.I()); + map<ZAI, IsotopicVector>::iterator it_Filiation; + + it_Filiation = fNucleiFiliation.find(Mother); // search for the ZAI in the map + + DBGL + if(it_Filiation != fNucleiFiliation.end()) // test if it is present in the map + return it_Filiation->second; + else + return ZAI(-1,-1,-1)*1; // return -1 -1 _1 ZAI if unknown nuclei.... + +} + +//________________________________________________________________________ +void CLASSNucleiFiliation::FiliationCleanUp(map<ZAI, int> GoodNuclei, CLASSNucleiFiliation CuttedNuclei) +{ + DBGL + map<ZAI, IsotopicVector>::iterator it_Filiation; + for(it_Filiation = fNucleiFiliation.begin(); it_Filiation != fNucleiFiliation.end(); it_Filiation++) // loop on the filiation map (on the Mother ZAI) + { + vector<ZAI> DautherList = it_Filiation->second.GetZAIList(); // recover for each mother ZAI, the list of its daughter ZAI + + for (int i = 0; i < (int)DautherList.size(); i++) // Loop on the Daughter ZAI + { + if(GoodNuclei.find(DautherList[i]) == GoodNuclei.end() ) // if the ZAI is not in a dealed nuclei (cutted or unknown) + { + double Daughter_BR = it_Filiation->second.GetQuantity(DautherList[i]); // Get the quantity of the ZAI + it_Filiation->second -= Daughter_BR * DautherList[i]; // Remove it from the daughter list + + + IsotopicVector FastDecayChain = CuttedNuclei.GetFiliation(DautherList[i]); // Get the fast decay chain of it + + if(FastDecayChain.GetQuantity(-1, -1, -1) == 0) // Check if the FastDecayChain is known + it_Filiation->second += Daughter_BR * FastDecayChain; // Add the FastDecayCHain & apply the BR for the cutted Daughter + else + { + + ZAI Mother = DautherList[i]; + while (FastDecayChain.GetQuantity(-1, -1, -1) != 0 && GoodNuclei.find(Mother) == GoodNuclei.end()) + { + Mother = GetArtificialDecay(Mother); // Do an Artifial decay on the nuclei + FastDecayChain = CuttedNuclei.GetFiliation(Mother); // Get the fast decay chain of it + } + + if(GoodNuclei.find(Mother) != GoodNuclei.end()) + it_Filiation->second += Mother * Daughter_BR; + + else if ( FastDecayChain.GetQuantity(-1, -1, -1) == 0) + it_Filiation->second += FastDecayChain * Daughter_BR; + + else + { + ERROR << "Problem in Articial Decay!! check it!!" << endl; + exit(1); + } + + } + } + } + + } + DBGL +} +//________________________________________________________________________ + +ZAI CLASSNucleiFiliation::GetArtificialDecay(ZAI Mother) +{ + DBGL + + int A = Mother.A(); + int Z = Mother.Z(); + int I = Mother.I(); + + if(I != 0) + return ZAI(Z,A,I-1); + else + { + //Coef Ac & As of Bette & Weisacker are approximativ but precise enough for this application.... + double Ac = 0.695; + double As = 23.2; + + double ZTh = A/2 * ( 1 )/ ( 1 + Ac / (4*As) * pow(A,2/3) ); // Stable Z from isobarn calculation using Bette & Weisacker formula. + + + if( Z > ZTh ) // Then Beta+ + return ZAI(Z-1,A,I); + else // Then Beta- + return ZAI(Z+1,A,I); + + } + + + DBGL +} + + +//________________________________________________________________________ +void CLASSNucleiFiliation::SelfFiliationCleanUp(map<ZAI, int> GoodNuclei) +{ + DBGL + + bool Cleaned = false; + + while (!Cleaned) // loop until all the map is cleaned (all cut have been done) + { + int count = 0; + map<ZAI, IsotopicVector> CopyfNucleiFiliation = fNucleiFiliation; + map<ZAI, IsotopicVector>::iterator it_Filiation; + for(it_Filiation = fNucleiFiliation.begin(); it_Filiation != fNucleiFiliation.end(); it_Filiation++) // Loop on the mother ZAI + { + vector<ZAI> DautherList = it_Filiation->second.GetZAIList(); // Get the list of daughter ZAI + + for (int i = 0; i < (int)DautherList.size(); i++) //Loop on daughter + { + if(GoodNuclei.find(DautherList[i]) == GoodNuclei.end() ) // if the ZAI is not in a dealed nuclei (cutted or unknown) + { count++; + map<ZAI, IsotopicVector>::iterator it_FiliationCopy = CopyfNucleiFiliation.find(it_Filiation->first) ; + + double Daughter_BR = it_FiliationCopy->second.GetQuantity(DautherList[i]); // Get the quantity of the ZAI + it_FiliationCopy->second -= Daughter_BR * DautherList[i]; // Remove it from the daughter list + IsotopicVector FastDecayChain = (*this).GetFiliation(DautherList[i]); // Get the fast decay chain of it + + if(FastDecayChain.GetQuantity(-1, -1, -1) == 0) // Check if the FastDecayChain is known + it_FiliationCopy->second += Daughter_BR * FastDecayChain; // Add the FastDecayCHain & apply the BR for the cutted Daughter + else + { + ZAI Mother = DautherList[i]; + while (FastDecayChain.GetQuantity(-1, -1, -1) != 0 && GoodNuclei.find(Mother) == GoodNuclei.end()) + { + Mother = GetArtificialDecay(Mother); // Do an Artifial decay on the nuclei + FastDecayChain = (*this).GetFiliation(Mother); // Get the fast decay chain of it + } + + if(GoodNuclei.find(Mother) != GoodNuclei.end()) + it_FiliationCopy->second += Mother * Daughter_BR; + + else if ( FastDecayChain.GetQuantity(-1, -1, -1) == 0) + it_FiliationCopy->second += FastDecayChain * Daughter_BR; + + else + { + ERROR << "Problem in Articial Decay!! check it!!" << endl; + exit(1); + } + + } + } + } + + } + fNucleiFiliation = CopyfNucleiFiliation; + Cleaned = true; + + for(it_Filiation = fNucleiFiliation.begin(); it_Filiation != fNucleiFiliation.end(); it_Filiation++) // Loop on the mother ZAI + { + vector<ZAI> DautherList = it_Filiation->second.GetZAIList(); // Get the list of daughter ZAI + + for (int i = 0; i < (int)DautherList.size(); i++) //Loop on daughter + if(GoodNuclei.find(DautherList[i]) == GoodNuclei.end() ) // if the ZAI is not in a dealed nuclei (cutted or unknown) + Cleaned = false; + } + + } + + NormalizeBranchingRatio(); + DBGL +} + + + +//________________________________________________________________________ +void CLASSNucleiFiliation::NormalizeBranchingRatio(double Value) +{ + DBGL + map<ZAI, IsotopicVector>::iterator it_Filiation; + for(it_Filiation = fNucleiFiliation.begin(); it_Filiation != fNucleiFiliation.end(); it_Filiation++) + { + it_Filiation->second *= Value/it_Filiation->second.GetSumOfAll(); + } + + DBGL +} + + +//________________________________________________________________________ +void CLASSNucleiFiliation::NormalizeBranchingRatio(ZAI Mother, double Value) +{ + DBGL + map<ZAI, IsotopicVector>::iterator it_Filiation = fNucleiFiliation.find(Mother); + + if( it_Filiation != fNucleiFiliation.end()) + it_Filiation->second *= Value/it_Filiation->second.GetSumOfAll(); + else + WARNING << "Trying to normaliza a Branching Ratio for a Mother wich are not present in the Filiatiuon List...." << endl; + + DBGL +} + + +//________________________________________________________________________ + +vector<ZAI> CLASSNucleiFiliation::GetZAIList() const +{ + + map<ZAI ,IsotopicVector > IsotopicQuantity = GetNucleiFIliation(); + map<ZAI ,IsotopicVector >::iterator it; + vector<ZAI> zailist; + for( it = IsotopicQuantity.begin(); it != IsotopicQuantity.end(); it++) + zailist.push_back( (*it).first ); + + return zailist; + +} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/source/branches/BaM/src/CLASSObject.cxx b/source/branches/BaM/src/CLASSObject.cxx new file mode 100644 index 000000000..85413d5b2 --- /dev/null +++ b/source/branches/BaM/src/CLASSObject.cxx @@ -0,0 +1,24 @@ +#include "CLASSObject.hxx" + +using namespace std; + + //________________________________________________________________________ + // + // CLASSObject + // + // + // + // + //________________________________________________________________________ + +ClassImp(CLASSObject) + +CLASSObject::CLASSObject() +{ + fLog = 0; +} + +CLASSObject::CLASSObject(CLASSLogger* log) +{ + fLog = log; +} \ No newline at end of file diff --git a/source/branches/BaM/src/DecayDataBank.cxx b/source/branches/BaM/src/DecayDataBank.cxx new file mode 100644 index 000000000..2a9e1891e --- /dev/null +++ b/source/branches/BaM/src/DecayDataBank.cxx @@ -0,0 +1,220 @@ +#include "DecayDataBank.hxx" + +#include "CLASSLogger.hxx" +#include "StringLine.hxx" + +#include <TGraph.h> +#include <TString.h> + + +#include <sstream> +#include <string> +#include <iostream> +#include <fstream> +#include <algorithm> +#include <cmath> + + +//________________________________________________________________________ +// +// DecayDataBank +// +// +// +// +//________________________________________________________________________ + +DecayDataBank::DecayDataBank():CLASSObject(new CLASSLogger("DecayDataBank.log")) +{ + + string CLASSPATH = getenv("CLASS_PATH"); + string DB_index_file = CLASSPATH + "/DATA_BASES/DECAY/ALL/Decay.idx"; + fDataBaseIndex = DB_index_file; + fFastCalculation = true; + + // Warning + INFO << " A EvolutionData has been define :" << endl; + INFO << "\t His index is : \"" << DB_index_file << "\"" << endl << endl; + +} + +//________________________________________________________________________ +//________________________________________________________________________ +//________________________________________________________________________ +//________________________________________________________________________ + +//________________________________________________________________________ + +DecayDataBank::DecayDataBank(string DB_index_file):CLASSObject(new CLASSLogger("DecayDataBank.log")) +{ + + fDataBaseIndex = DB_index_file; + fFastCalculation = true; + + // Warning + INFO << " A EvolutionData has been define :" << endl; + INFO << "\t His index is : \"" << DB_index_file << "\"" << endl << endl; + +} +//________________________________________________________________________ + +DecayDataBank::DecayDataBank(CLASSLogger* log, string DB_index_file):CLASSObject(log) +{ + + fDataBaseIndex = DB_index_file; + fFastCalculation = true; + + // Warning + INFO << " A EvolutionData has been define :" << endl; + INFO << "\t His index is : \"" << DB_index_file << "\"" << endl << endl; + +} + +//________________________________________________________________________ +DecayDataBank::~DecayDataBank() +{ + +} + +//________________________________________________________________________ +IsotopicVector DecayDataBank::Evolution(const ZAI& zai, double dt) +{ +DBGL + IsotopicVector returnIV; + + map<ZAI ,EvolutionData >::iterator it = fDecayDataBank.find(zai); + + if (it == fDecayDataBank.end() ) + { + ifstream DB_index(fDataBaseIndex.c_str()); + if( !DB_index) + { + ERROR << " Can't open \"" << fDataBaseIndex << "\"" << endl; + exit (1); + } + bool zaifind = false; + string tmp; + getline(DB_index,tmp); // Read first line + while (!DB_index.eof()) + { + string line; + int start = 0; + getline(DB_index,line); // Read first line + string first = StringLine::NextWord(line,start); // Read first word + + if(first.size() == 0) break; // If First word is null.... quit + + int rZ = atoi(first.c_str()); // Get Z + int rA = atoi(StringLine::NextWord(line,start).c_str()); // Get A + int rI = atoi(StringLine::NextWord(line,start).c_str()); // Get Isomeric State + + if(rZ == zai.Z() && rA == zai.A() && rI == zai.I() ) + { + string file_name = StringLine::NextWord(line,start); + EvolutionData evolutionproduct = EvolutionData(GetLog(), file_name, true); +#pragma omp critical(DBupdate) + {fDecayDataBank.insert( pair<ZAI ,EvolutionData >(zai, evolutionproduct) );} + returnIV = evolutionproduct.GetIsotopicVectorAt(dt); + zaifind = true; + } + } + + if(!zaifind) + { + WARNING << " Oups... Can't Find the ZAI : " + << zai.Z() << " " << zai.A() << " " << zai.I() << "!!! It will be considered as stable !!" << endl; + + EvolutionData evolutionproduct = EvolutionData(GetLog()," " , true, zai); + {fDecayDataBank.insert( pair<ZAI, EvolutionData >(zai, evolutionproduct) );} + returnIV = evolutionproduct.GetIsotopicVectorAt(dt); + + + } + + + } + else returnIV = (*it).second.GetIsotopicVectorAt(dt); + +DBGL + return returnIV; +} + +//________________________________________________________________________ +bool DecayDataBank::IsDefine(const ZAI& zai) const +{ + + map<ZAI ,EvolutionData > evolutiondb = (*this).GetDecayDataBank(); + if (evolutiondb.find(zai) != evolutiondb.end()) + return true; + else + return false; + +} + + + +//________________________________________________________________________ +// Get Decay +//________________________________________________________________________ + +IsotopicVector DecayDataBank::GetDecay(IsotopicVector isotopicvector, cSecond t) +{ + DBGL + IsotopicVector IV; + + // Time slicing + + if( t > 1e16) + { + ERROR << " To long decay ... cut it !!! (max = 1e16 s ~ 300 000 000 years )" << endl; + exit(1); + } + + if(fFastCalculation) // If using fast calculation simply interpolate between 2 timesteps + { + map<ZAI ,double> isotopicquantity = isotopicvector.GetIsotopicQuantity(); + map<ZAI ,double >::iterator it; + for( it = isotopicquantity.begin(); it != isotopicquantity.end(); it++) + { + if((*it).second > 0) + { + IsotopicVector ivtmp = Evolution(it->first, t) * (*it).second ; + IV += ivtmp; + } + } + + } + else // If using precise calculation calculate the evolution at each digit + { + int evolutionDecade[17]; + cSecond remainingTime = t; + for(int i = 16; i >= 0; i--) + { + evolutionDecade[i] = (cSecond)remainingTime/pow(10,i); + remainingTime -= evolutionDecade[i]*pow(10,i); + } + + + IV = isotopicvector; + + for (int i = 16; i >= 0; i--) + { + if(evolutionDecade[i] != 0) + { + map<ZAI ,double> isotopicquantity = IV.GetIsotopicQuantity(); + map<ZAI ,double >::iterator it; + + IV = IsotopicVector(); + for( it = isotopicquantity.begin(); it != isotopicquantity.end(); it++) + IV += Evolution(it->first, evolutionDecade[i]*pow(10,i) ) * (*it).second ; + } + } + } + DBGL + return IV; +} +//________________________________________________________________________ +//________________________________________________________________________ +//________________________________________________________________________ +//________________________________________________________________________ +//________________________________________________________________________ diff --git a/source/branches/BaM/src/DynamicalSystem.cxx b/source/branches/BaM/src/DynamicalSystem.cxx new file mode 100644 index 000000000..7f374b698 --- /dev/null +++ b/source/branches/BaM/src/DynamicalSystem.cxx @@ -0,0 +1,214 @@ +#include <cstdio> +#include <iostream> +#include <fstream> +#include <cmath> +#include <vector> +#include <algorithm> + +#include "DynamicalSystem.hxx" + +using namespace std; + +//________________________________________________________________________ +DynamicalSystem::DynamicalSystem() +{ + + SetPrecision(); + fHestimate = 1.; //this value is change in DynamicalSystem::RungeKutta + fHmin = 0.; + fMaxHdid = -1e30; + fMinHdid = 1e30; + fIsNegativeValueAllowed = true; +} + +//________________________________________________________________________ +DynamicalSystem::DynamicalSystem(const DynamicalSystem & DS) +{ + fNVar = DS.fNVar; + fPrecision = DS.fPrecision; + fHestimate = DS.fHestimate; + fHmin = DS.fHmin; + fMaxHdid = DS.fMaxHdid; + fMinHdid = DS.fMinHdid; + fIsNegativeValueAllowed = DS.fIsNegativeValueAllowed; +} + +//________________________________________________________________________ +DynamicalSystem::~DynamicalSystem() +{ + +} + +//________________________________________________________________________ +void DynamicalSystem::RungeKutta(double *YStart,double t1, double t2, int EquationNumber) +{ + //double shortestHalfLife = gMURE->GetShortestHalfLife(); + fNVar = EquationNumber; + int nstp; + double t,hnext,hdid,h; + double *yscal = new double[fNVar]; + double *y = new double[fNVar]; + double *dydt = new double[fNVar]; + + const double MAXSTP = 10000; + const double TINY = 1.0e-30; + + + + if(fabs(t1-t2)<= TINY) + cout << "Integration time is 0." << endl; + + t = t1; + fHestimate = (t2-t1)/100; + //h = (t2 > t1) ? fabs(fHestimate) : -fabs(fHestimate); + h = fHestimate; + + // pragma omp parallel for + for (int i = 0; i < fNVar; i++) y[i] = YStart[i]; + + for ( nstp = 1; nstp <= MAXSTP; nstp++) + { + BuildEqns(t,y,dydt); + + // pragma omp parallel for + for ( int i = 0; i < fNVar; i++) + yscal[i] = fabs(y[i]) + fabs(dydt[i]*h)+TINY; + + if ( (t+h-t2) * (t+h-t1) > 0.0 ) h = t2-t; + + AdaptStepSize(y,dydt,&t,h,fPrecision,yscal,&hdid,&hnext); + + if(fMaxHdid<hdid) fMaxHdid = hdid; + if(fMinHdid>hdid) fMinHdid = hdid; + + if ((t-t2)*(t2-t1) >= 0.0) + { + // pragma omp parallel for + for (int i = 0;i<fNVar;i++) YStart[i] = y[i]; + + delete [] dydt; + delete [] y; + delete [] yscal; + //cout << "The maximum step used in RK was " << fMaxHdid << " Step NUM in RK was " << nstp << endl; + return; + } + if (fabs(hnext) <= fHmin) + cout << "Step size too small in RungeKutta" << endl; + + h = hnext; + } + cout << "Too many steps in routine RungeKutta" << endl; +} + +//________________________________________________________________________ +void DynamicalSystem::RK4(double *y, double *dydx, double x, double h, double *yout) +{ + //cout << "Calling Function RK4" << endl; + double xh,hh,h6; + + double *dym = new double[fNVar]; + double *dyt = new double[fNVar]; + double *yt = new double[fNVar]; + hh = h*0.5; + h6 = h/6.0; + xh = x+hh; + + // pragma omp parallel for + for (int i = 0;i<fNVar;i++) yt[i] = y[i]+hh*dydx[i]; + + BuildEqns(xh,yt,dyt); + + // pragma omp parallel for + for (int i = 0;i<fNVar;i++) yt[i] = y[i]+hh*dyt[i]; + + BuildEqns(xh,yt,dym); + + for (int i = 0;i<fNVar;i++) + { + yt[i] = y[i]+h*dym[i]; + dym[i] += dyt[i]; + } + + BuildEqns(x+h,yt,dyt); + // pragma omp parallel for + for (int i = 0;i<fNVar;i++) + { + yout[i] = y[i]+h6*(dydx[i]+dyt[i]+2.0*dym[i]); + if(!fIsNegativeValueAllowed && yout[i]<0) + { + //cout << "Material composition is negative " + // << "i = " << i << " ("/* << fEvolvingMaterial->GetComposition()[i]->GetZAI()->PrintName() + // */ << ") old proportion = " << y[i] << " new = " << yout[i] + // << ". Setting to 0." << endl; + yout[i] = 0.; + } + } + delete [] yt; + delete [] dyt; + delete [] dym; +} + +//________________________________________________________________________ +void DynamicalSystem::AdaptStepSize(double *y, double *dydx, double *x, double htry, + double eps, double *yscal, double *hdid, double *hnext) +{ + //cout << "Calling Function AdaptStepSize()" << endl; + double xsav,hh,h,temp,errmax; + double *dysav = new double[fNVar]; + double *ysav = new double[fNVar]; + double *ytemp = new double[fNVar]; + + const double PGROW = -0.20; + const double PSHRNK = -0.25; + const double FCOR = 0.06666666 ; + const double SAFETY = 0.9; + const double ERRCON = 6.0e-4; + + xsav = (*x); + + // pragma omp parallel for + for (int i = 0;i<fNVar;i++) + { + ysav[i] = y[i]; + dysav[i] = dydx[i]; + } + h = htry; + for (;;) + { + hh = 0.5*h; + RK4(ysav,dysav,xsav,hh,ytemp); + *x = xsav+hh; + + BuildEqns(*x,ytemp,dydx); + RK4(ytemp,dydx,*x,hh,y); + *x = xsav+h; + if (*x == xsav ) + { + //cout << "Step size (" << h << ") too small in routine AdaptStepSize" << endl; + } + RK4(ysav,dysav,xsav,h,ytemp); + errmax = 0.0; + + for (int i = 0;i<fNVar;i++) + { + ytemp[i] = y[i]-ytemp[i]; + temp = fabs(ytemp[i]/yscal[i]); + if (errmax < temp) errmax = temp; + } + errmax /= eps; + if (errmax <= 1.0) + { + *hdid = h; + *hnext = (errmax > ERRCON ? SAFETY*h*exp(PGROW*log(errmax)) : 4.0*h); + break; + } + h = SAFETY*h*exp(PSHRNK*log(errmax)); + } + + for (int i = 0;i<fNVar;i++) y[i] += ytemp[i]*FCOR; + + delete [] ytemp; + delete [] dysav; + delete [] ysav; +} + diff --git a/source/branches/BaM/src/EquivalenceModel.cxx b/source/branches/BaM/src/EquivalenceModel.cxx new file mode 100644 index 000000000..460e5f285 --- /dev/null +++ b/source/branches/BaM/src/EquivalenceModel.cxx @@ -0,0 +1,472 @@ +#include "EquivalenceModel.hxx" +#include "StringLine.hxx" +#include "CLASSMethod.hxx" + +//________________________________________________________________________ +EquivalenceModel::EquivalenceModel():CLASSObject() +{ + fRelativMassPrecision = 5/10000.; // Mass precision + fMaxInterration = 100; // Max iterration in build fueld algorythum + fFirstGuessFissilContent = 0.02; + freaded = false; + EquivalenceModel::LoadKeyword(); +} +//________________________________________________________________________ +EquivalenceModel::EquivalenceModel(CLASSLogger* log):CLASSObject(log) +{ + fRelativMassPrecision = 5/10000.; // Mass precision + fMaxInterration = 100; // Max iterration in build fueld algorythm + fFirstGuessFissilContent = 0.02; + freaded = false; + EquivalenceModel::LoadKeyword(); + +} +//________________________________________________________________________ +EquivalenceModel::~EquivalenceModel() +{ + +} +//________________________________________________________________________ +void EquivalenceModel::ReadNFO() +{ + DBGL + ifstream NFO(fInformationFile.c_str()); + + if(!NFO) + { + ERROR << "Can't find/open file " << fInformationFile << endl; + exit(0); + } + + do + { + string line; + getline(NFO,line); + + EquivalenceModel::ReadLine(line); + + } while(!NFO.eof()); + + DBGL +} +//________________________________________________________________________ +void EquivalenceModel::ReadLine(string line) +{ + DBGL + + if (!freaded) + { + int pos = 0; + string keyword = tlc(StringLine::NextWord(line, pos, ' ')); + + map<string, EQM_MthPtr>::iterator it = fKeyword.find(keyword); + + if(it != fKeyword.end()) + (this->*(it->second))( line ); + + freaded = true; + ReadLine(line); + + } + + freaded = false; + + DBGL +} +//________________________________________________________________________ +void EquivalenceModel::LoadKeyword() +{ + DBGL + fKeyword.insert( pair<string, EQM_MthPtr>( "k_zail", & EquivalenceModel::ReadZAIlimits)); + fKeyword.insert( pair<string, EQM_MthPtr>( "k_reactor", & EquivalenceModel::ReadType) ); + fKeyword.insert( pair<string, EQM_MthPtr>( "k_fuel", & EquivalenceModel::ReadType) ); + fKeyword.insert( pair<string, EQM_MthPtr>( "k_fissil", & EquivalenceModel::ReadFissil) ); + fKeyword.insert( pair<string, EQM_MthPtr>( "k_fertil", & EquivalenceModel::ReadFertil) ); + fKeyword.insert( pair<string, EQM_MthPtr>( "k_specpower", & EquivalenceModel::ReadSpecificPower)); + DBGL +} +//________________________________________________________________________ +void EquivalenceModel::PrintInfo() +{ + INFO << "Reactor Type : "<< fDBRType << endl; + INFO << "Fuel Type : "<< fDBFType << endl; + INFO << "Specific Power [W/g]: "<< fSpecificPower << endl; + + INFO << "Fissile Liste (Z A I) :" << endl; + map<ZAI ,double >::iterator it1; + map<ZAI ,double > fMap1 = fFissileList.GetIsotopicQuantity(); + for(it1 = fMap1.begin() ; it1 != fMap1.end() ; it1++) + INFO << (*it1).first.Z() <<" "<< (*it1).first.A() <<" "<< (*it1).first.I() << endl; + + INFO<<"Fertile Liste (Z A I Quantity) :"<<endl; + map<ZAI ,double >::iterator it2; + map<ZAI ,double > fMap2 = fFertileList.GetIsotopicQuantity(); + for(it2 = fMap2.begin() ; it2 != fMap2.end() ; it2++) + INFO << (*it2).first.Z() <<" "<< (*it2).first.A() << " "<< (*it2).first.I() <<" "<< (*it2).second << endl; + + + INFO<<"ZAI limits (validity domain)[prop in fresh fuel] (Z A I min max) :"<<endl; + for (map< ZAI,pair<double,double> >::iterator Domain_it = fZAILimits.begin(); Domain_it != fZAILimits.end(); Domain_it++) + { + double ThatZAIMin = Domain_it->second.first; + double ThatZAIMax = Domain_it->second.second; + int Z = Domain_it->first.Z(); + int A = Domain_it->first.A(); + int I = Domain_it->first.I(); + + INFO <<ThatZAIMin<<" < ZAI ("<< Z<< " " << A << " " << I<<")"<<" < "<<ThatZAIMax<< endl; + } + +} +//________________________________________________________________________ +void EquivalenceModel::ReadType(const string &line) +{ + DBGL + int pos = 0; + string keyword = tlc(StringLine::NextWord(line, pos, ' ')); + if( keyword != "k_fuel" && keyword != "k_reactor" ) // Check the keyword + { + ERROR << " Bad keyword : " << keyword << " Not found !" << endl; + exit(1); + } + if( keyword == "k_fuel" ) + fDBFType = StringLine::NextWord(line, pos, ' '); + else if( keyword == "k_reactor" ) + fDBRType = StringLine::NextWord(line, pos, ' '); + + DBGL +} +//________________________________________________________________________ +void EquivalenceModel::ReadZAIlimits(const string &line) +{ + DBGL + int pos = 0; + string keyword = tlc(StringLine::NextWord(line, pos, ' ')); + if( keyword != "k_zail" ) // Check the keyword + { + ERROR << " Bad keyword : \"k_zail\" not found !" << endl; + exit(1); + } + + int Z = atoi(StringLine::NextWord(line, pos, ' ').c_str()); + int A = atoi(StringLine::NextWord(line, pos, ' ').c_str()); + int I = atoi(StringLine::NextWord(line, pos, ' ').c_str()); + + double downLimit = atof(StringLine::NextWord(line, pos, ' ').c_str()); + double upLimit = atof(StringLine::NextWord(line, pos, ' ').c_str()); + + if (upLimit < downLimit) + { + double tmp = upLimit; + upLimit = downLimit; + downLimit = tmp; + } + fZAILimits.insert(pair<ZAI, pair<double, double> >(ZAI(Z,A,I), pair<double,double>(downLimit, upLimit))); + DBGL +} +//________________________________________________________________________ +void EquivalenceModel::ReadFissil(const string &line) +{ + DBGL + int pos = 0; + string keyword = tlc(StringLine::NextWord(line, pos, ' ')); + if( keyword != "k_fissil" ) // Check the keyword + { + ERROR << " Bad keyword : \"k_fissil\" not found !" << endl; + exit(1); + } + + int Z = atoi(StringLine::NextWord(line, pos, ' ').c_str()); + int A = atoi(StringLine::NextWord(line, pos, ' ').c_str()); + int I = atoi(StringLine::NextWord(line, pos, ' ').c_str()); + + fFissileList.Add(Z, A, I, 1.0); + + DBGL +} +//________________________________________________________________________ +void EquivalenceModel::ReadFertil(const string &line) +{ + DBGL + int pos = 0; + string keyword = tlc(StringLine::NextWord(line, pos, ' ')); + if( keyword != "k_fertil" ) // Check the keyword + { + ERROR << " Bad keyword : \"k_fertil\" not found !" << endl; + exit(1); + } + + int Z = atoi(StringLine::NextWord(line, pos, ' ').c_str()); + int A = atoi(StringLine::NextWord(line, pos, ' ').c_str()); + int I = atoi(StringLine::NextWord(line, pos, ' ').c_str()); + double Q = atof(StringLine::NextWord(line, pos, ' ').c_str()); + + fFertileList.Add(Z, A, I, Q); + + + DBGL +} +//________________________________________________________________________ +void EquivalenceModel::ReadSpecificPower(const string &line) +{ + DBGL + int pos = 0; + string keyword = tlc(StringLine::NextWord(line, pos, ' ')); + if( keyword != "k_specpower") // Check the keyword + { + ERROR << " Bad keyword : \"k_specpower\" Not found !" << endl; + exit(1); + } + + fSpecificPower = atof(StringLine::NextWord(line, pos, ' ').c_str()); + + DBGL +} +//________________________________________________________________________ +double EquivalenceModel::LAMBDA_TOT_FOR(double MassNeeded, vector<IsotopicVector> Stocks, string FisOrFer) +{ + double Lambda_tot = 0; + + // Calculating total mass of stock once and for all + if( fTotalFissileMassInStocks == 0 || fTotalFertileMassInStocks == 0 ) + { + double TotalMassInStocks = 0; + for( int i = 0 ; i<(int)Stocks.size() ; i++ ) + TotalMassInStocks += Stocks[i].GetTotalMass() ; + + if(FisOrFer == "Fis") + fTotalFissileMassInStocks = TotalMassInStocks * 1e6; // in grams + else + fTotalFertileMassInStocks = TotalMassInStocks * 1e6; // in grams + } + + double TotalMassInStocks = 0; + + if(FisOrFer == "Fis") + TotalMassInStocks = fTotalFissileMassInStocks; + else + TotalMassInStocks = fTotalFertileMassInStocks; + + // If there is not enought matter in stocks construction fails + if( MassNeeded > TotalMassInStocks ) + { + WARNING << "Not enought " << FisOrFer << " material to build fuel" << endl; + WARNING << TotalMassInStocks << endl; + return -1; + } + + for( int i = 0 ; i<(int)Stocks.size() ; i++ ) + { + + if( MassNeeded >= (Stocks[i].GetTotalMass()*1e6) ) + { + Lambda_tot+= 1; + MassNeeded -= (Stocks[i].GetTotalMass()*1e6); + } + else + { + Lambda_tot+= MassNeeded/(Stocks[i].GetTotalMass()*1e6); + break; + } + } + + return Lambda_tot; +} +//________________________________________________________________________ +bool EquivalenceModel::Build_Fuel_According_Lambda(vector<double> &lambda,vector<IsotopicVector> FissilArray, vector<IsotopicVector> FertilArray, double HMMass, IsotopicVector &Fissile, IsotopicVector &Fertile) +{ + //Build the Plutonium vector from stocks + Fissile.Clear(); + for( int i = 0; i < (int)FissilArray.size(); i++ ) + Fissile += lambda[i] * FissilArray[i]; + + + double AvailablePuMass = Fissile.GetTotalMass() * 1e6; // in grams + + // Building complementary Fertile from stocks + double FertilMassNeeded = HMMass - AvailablePuMass; + double LAMBDA_FERTILE = LAMBDA_TOT_FOR( FertilMassNeeded , FertilArray , "Fer" ); + + SetLambda(lambda, (int)FissilArray.size(), (int)lambda.size()-1, LAMBDA_FERTILE); + + int j = -1; + Fertile.Clear(); + for(int i = (int)FissilArray.size() ; i < (int)FissilArray.size()+(int)FertilArray.size() ; i++) + { + j++; + Fertile += lambda[i] * FertilArray[j]; + } + + if( fabs(Fertile.GetTotalMass()*1e6 - FertilMassNeeded) > FertilMassNeeded * 1e-6) // Not enought fertile in stocks + { + WARNING << "Not enought fertile material to build fuel" << endl; + return false; + } + + return true; +} +//________________________________________________________________________ +vector<double> EquivalenceModel::BuildFuel(double BurnUp, double HMMass, vector<IsotopicVector> FissilArray, vector<IsotopicVector> FertilArray) +{ + + DBGL + vector<double> lambda ; // vector of portion of stocks taken (fissile & fertil) + for(int i = 0 ; i < (int)FissilArray.size() + (int)FertilArray.size() ; i++ ) + lambda.push_back(0); + + /*** Test if there is a stock **/ + if( (int)FissilArray.size() == 0 ) + { + WARNING << " No fissile stocks available ! Fuel not build" << endl; + SetLambdaToErrorCode(lambda); + return lambda; + } + + HMMass *= 1e6; // Unit onversion : tons to gram + + /**** Some initializations **/ + fTotalFissileMassInStocks = 0; + fTotalFertileMassInStocks = 0; + + fActualFissileContent = GetBuildFuelFirstGuess(); + + IsotopicVector Fertile; + IsotopicVector Fissile; + + double AvailablePuMass = 0; + double PuMassNeeded = HMMass * fActualFissileContent; + double WeightPuContent = 0; + int loopCount = 0; + + do + { + double LAMBDA_NEEDED = LAMBDA_TOT_FOR(PuMassNeeded,FissilArray,"Fis"); + if( LAMBDA_NEEDED == -1 ) // Check if previous lambda was well calculated + { + SetLambdaToErrorCode(lambda); + WARNING << "Not enought fissile material to build fuel" << endl; + return lambda; + } + + SetLambda(lambda, 0, FissilArray.size()-1, LAMBDA_NEEDED ); + + bool succeed = Build_Fuel_According_Lambda(lambda, FissilArray, FertilArray, HMMass, Fissile, Fertile); + + if(!succeed) + { + SetLambdaToErrorCode(lambda); + return lambda; + } + + AvailablePuMass = Fissile.GetTotalMass() * 1e6; //in grams + + if (loopCount > fMaxInterration) + { + ERROR << "Too much iterration in BuildFuel Method !"; + ERROR << "Need improvement in fuel fabrication ! Ask for it or D.I.Y. !!" << endl; + exit(1); + } + + /* Calcul the quantity of this composition needed to reach the burnup */ + double MolarPuContent = GetFissileMolarFraction(Fissile, Fertile, BurnUp); + + if( MolarPuContent < 0 || MolarPuContent > 1 ) + { SetLambdaToErrorCode(lambda); + WARNING << "GetFissileMolarFraction return negative or greater than one value"; + return lambda; + } + + double MeanMolarPu = Fissile.GetMeanMolarMass(); + double MeanMolarDepletedU = Fertile.GetMeanMolarMass(); + + double MeanMolar = MeanMolarPu * MolarPuContent + (1-MolarPuContent) * MeanMolarDepletedU; + + + WeightPuContent = MolarPuContent * MeanMolarPu / MeanMolar; + fActualFissileContent = MolarPuContent; //fActualFissileContent can be accessed by a derivated EquivalenModel to accelerate GetFissileMolarFraction function (exemple in EQM_MLP_Kinf) + PuMassNeeded = WeightPuContent * HMMass ; + + DBGV( "MolarPuContent " << MolarPuContent << " DeltaM " << PuMassNeeded - AvailablePuMass << " g" ); + + loopCount++; + + }while( fabs( PuMassNeeded - AvailablePuMass )/HMMass > fRelativMassPrecision ); + + (*this).isIVInDomain(Fissile); + + DBGV( "Weight percent fissile : " << PuMassNeeded/HMMass ); + DBGV( "Lambda vector : " ); + + for(int i = 0; i < (int)FissilArray.size() + (int)FertilArray.size(); i++ ) + DBGV(lambda[i]); + + return lambda; +} +//________________________________________________________________________ +void EquivalenceModel::SetLambda(vector<double>& lambda ,int FirstStockID, int LastStockID, double LAMBDA_TOT) +{ + if( LAMBDA_TOT > LastStockID - FirstStockID + 1 ) + { + ERROR << " FATAL ERROR " << endl; + exit(0); + } + + for( int i = FirstStockID; i <= LastStockID; i++ ) //set to 0 all non touched value (to be sure) + lambda[i] = 0 ; + + int IntegerPart = floor( LAMBDA_TOT ); + double DecimalPart = LAMBDA_TOT - IntegerPart; + + for( int i = FirstStockID; i < FirstStockID +IntegerPart; i++ ) + lambda[i] = 1; + + lambda[FirstStockID + IntegerPart] = DecimalPart; +} + +//________________________________________________________________________ +void EquivalenceModel::SetLambdaToErrorCode(vector<double>& lambda) +{ + for(int i = 0 ; i < (int)lambda.size() ;i++ ) + lambda[i] = -1; +} +//________________________________________________________________________ +bool EquivalenceModel::isIVInDomain(IsotopicVector IV) +{ + DBGL + bool IsInDomain = true; + + if(fZAILimits.empty()) + { + WARNING << "Fresh Fuel variation domain is not set" << endl; + WARNING << "CLASS has no clue if the computed evolution for this fresh fuel is correct" << endl; + WARNING << "Proceed finger crossed !!" << endl; + return true; + } + + else + { + IsotopicVector IVNorm = IV /IV.GetSumOfAll(); + for (map< ZAI,pair<double,double> >::iterator Domain_it = fZAILimits.begin(); Domain_it != fZAILimits.end(); Domain_it++) + { + double ThatZAIProp = IVNorm.GetIsotopicQuantity()[Domain_it->first] ; + double ThatZAIMin = Domain_it->second.first; + double ThatZAIMax = Domain_it->second.second; + if( (ThatZAIProp > ThatZAIMax) || (ThatZAIProp < ThatZAIMin) ) + { + IsInDomain = false; + + WARNING << "Fresh fuel out of model range" << endl; + WARNING << "\t AT LEAST this ZAI is accused to be outrange :" << endl; + WARNING << "\t\t" << Domain_it->first.Z() << " " << Domain_it->first.A() << " " << Domain_it->first.I() << endl; + WARNING << "\t\t min = " << ThatZAIMin << " value = " << ThatZAIProp << " max = " << ThatZAIMax << endl; + WARNING << "\t IV accused :" << endl << endl; + WARNING << IVNorm.sPrint() << endl; + break; + } + } + } + DBGL + return IsInDomain; + +} + diff --git a/source/branches/BaM/src/EvolutionData.cxx b/source/branches/BaM/src/EvolutionData.cxx new file mode 100755 index 000000000..152ba1b2b --- /dev/null +++ b/source/branches/BaM/src/EvolutionData.cxx @@ -0,0 +1,1234 @@ +#include "EvolutionData.hxx" +#include "CLASSMethod.hxx" + +#include "CLASSLogger.hxx" +#include "CLASSConstante.hxx" +#include "StringLine.hxx" + +#include <TGraph.h> +#include <TString.h> + +#include <cmath> +#include <iostream> +#include <fstream> +#include <algorithm> + +//________________________________________________________________________ +// +// EvolutionData +// +// +// +// +//________________________________________________________________________ + + +double Distance(IsotopicVector IV1, EvolutionData Evd1 ) +{ + + double d2 = 0; + IsotopicVector IV2 = Evd1.GetIsotopicVectorAt(0.); + + IsotopicVector IVtmp = IV1; + map<ZAI ,double> IVtmpIsotopicQuantity = IVtmp.GetIsotopicQuantity(); + map<ZAI ,double >::iterator it; + + double SumOfXs = 0; + for( it = IVtmpIsotopicQuantity.begin(); it != IVtmpIsotopicQuantity.end(); it++) + { + + SumOfXs += Evd1.GetXSForAt(0., (*it).first, 1); + SumOfXs += Evd1.GetXSForAt(0., (*it).first, 2); + SumOfXs += Evd1.GetXSForAt(0., (*it).first, 3); + + } + + + for( it = IVtmpIsotopicQuantity.begin(); it != IVtmpIsotopicQuantity.end(); it++) + { + double Z1 = 0.0; + double Z2 = 0.0; + double XS = 0.0; + + Z1 = IV1.GetZAIIsotopicQuantity( (*it).first ); + Z2 = IV2.GetZAIIsotopicQuantity( (*it).first ); + XS = Evd1.GetXSForAt(0., (*it).first, 1) + + Evd1.GetXSForAt(0., (*it).first, 2) + + Evd1.GetXSForAt(0., (*it).first, 3); + + d2 += pow(Z1-Z2 , 2 ) * pow(XS,2); + + } + + return sqrt(d2)/SumOfXs; + +} + +double Distance(EvolutionData Evd1, IsotopicVector IV1 ) +{ + return Distance(IV1,Evd1); +} +//________________________________________________________________________ +//________________________________________________________________________ +//________________________________________________________________________ +EvolutionData operator*(EvolutionData const& evol, double F) +{ + + EvolutionData evoltmp; + + map<ZAI ,TGraph* > EvolutionData = evol.GetInventoryEvolution(); + map<ZAI ,TGraph* >::iterator it; + for(it = EvolutionData.begin(); it != EvolutionData.end(); it++) + { + double X[(*it).second->GetN()]; + double Y[(*it).second->GetN()]; + + for(int i = 0; i < (*it).second->GetN(); i++) + { + double y; + (*it).second->GetPoint( i, X[i], y ); + Y[i] = y*F; + } + evoltmp.NucleiInsert( pair<ZAI, TGraph*> ( (*it).first,new TGraph((*it).second->GetN(), X, Y) ) ); + + } + evoltmp.SetPower(evol.GetPower()*F); + evoltmp.SetFissionXS(evol.GetFissionXS()); + evoltmp.SetCaptureXS(evol.GetCaptureXS()); + evoltmp.Setn2nXS(evol.Getn2nXS()); + + + return evoltmp; + +} +//________________________________________________________________________ +EvolutionData operator*(double F, EvolutionData const& evol) +{ + + return evol*F; + +} +//________________________________________________________________________ +EvolutionData operator/(EvolutionData const& evol, double F) +{ + + return evol*(1./F); + +} + +EvolutionData Multiply(EvolutionData const& evol, double F) +{ + + EvolutionData evoltmp; + map<ZAI ,TGraph* > EvolutionData = evol.GetInventoryEvolution(); + map<ZAI ,TGraph* >::iterator it; + for(it = EvolutionData.begin(); it != EvolutionData.end(); it++) + { + double X[(*it).second->GetN()]; + double Y[(*it).second->GetN()]; + + for(int i = 0; i < (*it).second->GetN(); i++) + { + double y; + (*it).second->GetPoint( i, X[i], y ); + Y[i] = y*F; + } + evoltmp.NucleiInsert( pair<ZAI, TGraph*> ( (*it).first,new TGraph((*it).second->GetN(), X, Y) ) ); + + } + + + EvolutionData = evol.GetFissionXS(); + for(it = EvolutionData.begin(); it != EvolutionData.end(); it++) + { + double X[(*it).second->GetN()]; + double Y[(*it).second->GetN()]; + + for(int i = 0; i < (*it).second->GetN(); i++) + { + double y; + (*it).second->GetPoint( i, X[i], y ); + Y[i] = y*F; + } + evoltmp.FissionXSInsert( pair<ZAI, TGraph*> ( (*it).first,new TGraph((*it).second->GetN(), X, Y) ) ); + + } + + EvolutionData = evol.GetCaptureXS(); + for(it = EvolutionData.begin(); it != EvolutionData.end(); it++) + { + double X[(*it).second->GetN()]; + double Y[(*it).second->GetN()]; + + for(int i = 0; i < (*it).second->GetN(); i++) + { + double y; + (*it).second->GetPoint( i, X[i], y ); + Y[i] = y*F; + } + evoltmp.CaptureXSInsert( pair<ZAI, TGraph*> ( (*it).first,new TGraph((*it).second->GetN(), X, Y) ) ); + + } + EvolutionData = evol.Getn2nXS(); + for(it = EvolutionData.begin(); it != EvolutionData.end(); it++) + { + double X[(*it).second->GetN()]; + double Y[(*it).second->GetN()]; + + for(int i = 0; i < (*it).second->GetN(); i++) + { + double y; + (*it).second->GetPoint( i, X[i], y ); + Y[i] = y*F; + } + evoltmp.n2nXSInsert( pair<ZAI, TGraph*> ( (*it).first,new TGraph((*it).second->GetN(), X, Y) ) ); + + } + + evoltmp.SetPower(evol.GetPower()*F); + + + + return evoltmp; + +} + +//________________________________________________________________________ +EvolutionData Multiply(double F, EvolutionData const& evol) +{ + + return Multiply(evol,F); + +} + +EvolutionData Sum(EvolutionData const& evol1, EvolutionData const& evol2) +{ + EvolutionData EvolSum = evol1; + map<ZAI ,TGraph* > EvolutionData1 = EvolSum.GetInventoryEvolution(); + map<ZAI ,TGraph* > EvolutionData2 = evol2.GetInventoryEvolution(); + map<ZAI ,TGraph* >::iterator it; + + for(it = EvolutionData2.begin(); it != EvolutionData2.end(); it++) + { + pair<map<ZAI, TGraph*>::iterator, bool> IResult; + + IResult = EvolutionData1.insert( pair<ZAI, TGraph*> ( *it ) ); + if(!(IResult.second) ) + { + double X[(*it).second->GetN()]; + double Y[(*it).second->GetN()]; + map<ZAI ,TGraph* >::iterator it2 = EvolutionData1.find( (*it).first ); + + + for(int i = 0; i < (*it).second->GetN(); i++) + { + double y; + (*it).second->GetPoint( i, X[i], y ); + Y[i] = y + (*it2).second->Eval(X[i]); + } + IResult.first->second = new TGraph((*it).second->GetN(), X, Y); + + } + + } + EvolSum.SetInventoryEvolution(EvolutionData1); + + + EvolutionData1 = evol1.GetFissionXS(); + EvolutionData2 = evol2.GetFissionXS(); + + for(it = EvolutionData2.begin(); it != EvolutionData2.end(); it++) + { + pair<map<ZAI, TGraph*>::iterator, bool> IResult; + + IResult = EvolutionData1.insert( pair<ZAI, TGraph*> ( *it ) ); + + if(!(IResult.second) ) + { + double X[(*it).second->GetN()]; + double Y[(*it).second->GetN()]; + map<ZAI ,TGraph* >::iterator it2 = EvolutionData1.find( (*it).first ); + + + for(int i = 0; i < (*it).second->GetN(); i++) + { + double y; + (*it).second->GetPoint( i, X[i], y ); + Y[i] = y + (*it2).second->Eval(X[i]); + } + IResult.first->second = new TGraph((*it).second->GetN(), X, Y); + } + } + EvolSum.SetFissionXS(EvolutionData1); + + + EvolutionData1 = EvolSum.GetCaptureXS(); + EvolutionData2 = evol2.GetCaptureXS(); + + for(it = EvolutionData2.begin(); it != EvolutionData2.end(); it++) + { + pair<map<ZAI, TGraph*>::iterator, bool> IResult; + + IResult = EvolutionData1.insert( pair<ZAI, TGraph*> ( *it ) ); + + if(!(IResult.second) ) + { + double X[(*it).second->GetN()]; + double Y[(*it).second->GetN()]; + map<ZAI ,TGraph* >::iterator it2 = EvolutionData1.find( (*it).first ); + + + for(int i = 0; i < (*it).second->GetN(); i++) + { + double y; + (*it).second->GetPoint( i, X[i], y ); + Y[i] = y + (*it2).second->Eval(X[i]); + } + IResult.first->second = new TGraph((*it).second->GetN(), X, Y); + } + } + EvolSum.SetCaptureXS(EvolutionData1); + + + EvolutionData1 = EvolSum.Getn2nXS(); + EvolutionData2 = evol2.Getn2nXS(); + + for(it = EvolutionData2.begin(); it != EvolutionData2.end(); it++) + { + pair<map<ZAI, TGraph*>::iterator, bool> IResult; + + IResult = EvolutionData1.insert( pair<ZAI, TGraph*> ( *it ) ); + + if(!(IResult.second) ) + { + double X[(*it).second->GetN()]; + double Y[(*it).second->GetN()]; + map<ZAI ,TGraph* >::iterator it2 = EvolutionData1.find( (*it).first ); + + + for(int i = 0; i < (*it).second->GetN(); i++) + { + double y; + (*it).second->GetPoint( i, X[i], y ); + Y[i] = y + (*it2).second->Eval(X[i]); + } + IResult.first->second = new TGraph((*it).second->GetN(), X, Y); + } + } + EvolSum.Setn2nXS(EvolutionData1); + + return EvolSum; +} + + + + +//________________________________________________________________________ +//________________________________________________________________________ +//________________________________________________________________________ +//________________________________________________________________________ +//________________________________________________________________________ +//________________________________________________________________________ +//________________________________________________________________________ +//________________________________________________________________________ +//________________________________________________________________________ +//________________________________________________________________________ +//________________________________________________________________________ +//________________________________________________________________________ +//________________________________________________________________________ +//________________________________________________________________________ + + +ClassImp(EvolutionData) + + + +EvolutionData::EvolutionData():CLASSObject() +{ + fIsCrossSection = false; + fPower = 0; + fCycleTime = 0; + fKeff = 0; + fFlux = 0; + fDB_file = ""; +} + +//________________________________________________________________________ +EvolutionData::EvolutionData(CLASSLogger* log):CLASSObject(log) +{ + fIsCrossSection = false; + fPower = 0; + fCycleTime = 0; + fKeff = 0; + fFlux = 0; + fDB_file = ""; +} + +//________________________________________________________________________ +EvolutionData::EvolutionData(CLASSLogger* log, string DB_file, bool isDecay, ZAI zai):CLASSObject(log) +{ + + fIsCrossSection = false; + fDB_file = DB_file; + fPower = 0; + fCycleTime = 0; + fKeff = 0; + fFlux = 0; + fisDecay = isDecay; + + if(zai != ZAI(0,0,0)) + AddAsStable(zai); + else + ReadDB( fDB_file, false); // Read Evolution Produc DB file name + + + + +} + + +//________________________________________________________________________ +EvolutionData::EvolutionData(bool oldread, CLASSLogger* log, string DB_file, bool isDecay, ZAI zai):CLASSObject(log) +{ + + fIsCrossSection = false; + fDB_file = DB_file; + fPower = 0; + fCycleTime = 0; + fKeff = 0; + fFlux = 0; + fisDecay = isDecay; + + if(zai != ZAI(0,0,0)) + AddAsStable(zai); + else + ReadDB( fDB_file, oldread); // Read Evolution Produc DB file name + + + + +} + +//________________________________________________________________________ +EvolutionData::~EvolutionData() +{ + +} +//________________________________________________________________________ +void EvolutionData::DeleteEvolutionData() +{ + + map<ZAI ,TGraph* >::iterator it_del; + + for( it_del = fInventoryEvolution.begin(); it_del != fInventoryEvolution.end(); it_del++) + { + delete (*it_del).second; + (*it_del).second = 0; + } + for( it_del = fFissionXS.begin(); it_del != fFissionXS.end(); it_del++) + { + delete (*it_del).second; + (*it_del).second = 0; + } + for( it_del = fCaptureXS.begin(); it_del != fCaptureXS.end(); it_del++) + { + delete (*it_del).second; + (*it_del).second = 0; + } + for( it_del = fn2nXS.begin(); it_del != fn2nXS.end(); it_del++) + { + delete (*it_del).second; + (*it_del).second = 0; + } + + + delete fKeff; + delete fFlux; + + fInventoryEvolution.clear(); + fFissionXS.clear(); + fCaptureXS.clear(); + fn2nXS.clear(); + + fFlux = 0; + fKeff = 0; + + +} + + +//________________________________________________________________________ +void EvolutionData::DeleteEvolutionDataCopy() +{ + + if(fDB_file == "") + { + map<ZAI ,TGraph* >::iterator it_del; + + for( it_del = fInventoryEvolution.begin(); it_del != fInventoryEvolution.end(); it_del++) + { + delete (*it_del).second; + (*it_del).second = 0; + } + for( it_del = fFissionXS.begin(); it_del != fFissionXS.end(); it_del++) + { + delete (*it_del).second; + (*it_del).second = 0; + } + for( it_del = fCaptureXS.begin(); it_del != fCaptureXS.end(); it_del++) + { + delete (*it_del).second; + (*it_del).second = 0; + } + for( it_del = fn2nXS.begin(); it_del != fn2nXS.end(); it_del++) + { + delete (*it_del).second; + (*it_del).second = 0; + } + + + delete fKeff; + delete fFlux; + + fInventoryEvolution.clear(); + fFissionXS.clear(); + fCaptureXS.clear(); + fn2nXS.clear(); + + fFlux = 0; + fKeff = 0; + } + + +} + +bool EvolutionData::NucleiInsert(pair<ZAI, TGraph*> zaitoinsert) +{ + + pair<map<ZAI, TGraph*>::iterator, bool> IResult; + IResult = fInventoryEvolution.insert( zaitoinsert); + return IResult.second; + +} + +bool EvolutionData::FissionXSInsert(pair<ZAI, TGraph*> zaitoinsert) +{ + + pair<map<ZAI, TGraph*>::iterator, bool> IResult; + IResult = fFissionXS.insert( zaitoinsert); + return IResult.second; + +} + +bool EvolutionData::CaptureXSInsert(pair<ZAI, TGraph*> zaitoinsert) +{ + + pair<map<ZAI, TGraph*>::iterator, bool> IResult; + IResult = fCaptureXS.insert( zaitoinsert); + return IResult.second; + +} + +bool EvolutionData::n2nXSInsert(pair<ZAI, TGraph*> zaitoinsert) +{ + + pair<map<ZAI, TGraph*>::iterator, bool> IResult; + IResult = fn2nXS.insert( zaitoinsert); + return IResult.second; + +} + +//________________________________________________________________________ +void EvolutionData::AddAsStable(ZAI zai) +{ + + double time[2] = {0, (500*cYear)}; + double quantity[2] = {1., 1.}; + + fInventoryEvolution.insert(pair<ZAI ,TGraph* >(zai, new TGraph(2, time, quantity) ) ); + +} + +//________________________________________________________________________ +Double_t EvolutionData::Interpolate(double t, TGraph& EvolutionGraph) +{ + + TString fOption; + return (double)EvolutionGraph.Eval(t,0x0,fOption); + +} + +//________________________________________________________________________ +TGraph* EvolutionData::GetEvolutionTGraph(const ZAI& zai) +{ + + map<ZAI ,TGraph *>::iterator it = GetInventoryEvolution().find(zai) ; + + if ( it != GetInventoryEvolution().end() ) + return it->second; + else + return new TGraph(); + + +} + +//________________________________________________________________________ +IsotopicVector EvolutionData::GetIsotopicVectorAt(double t) +{ + + IsotopicVector IsotopicVectorTmp; + map<ZAI ,TGraph* >::iterator it; + for( it = fInventoryEvolution.begin(); it != fInventoryEvolution.end(); it++ ) + { + IsotopicVectorTmp.Add( (*it).first, Interpolate(t, *((*it).second)) ); + } + + + return IsotopicVectorTmp; +} + +//________________________________________________________________________ +double EvolutionData::GetXSForAt(double t, ZAI zai, int ReactionId) +{ + + map<ZAI ,TGraph* > XSEvol; + switch(ReactionId) + { + case 1: XSEvol = GetFissionXS(); + break; + case 2: XSEvol = GetCaptureXS(); + break; + case 3: XSEvol = Getn2nXS(); + break; + default:ERROR << " Wrong ReactionId !!" << endl; + exit(1); + } + + map<ZAI ,TGraph* >::iterator it = XSEvol.find(zai); + + + if (it == XSEvol.end()) + return 0.; + else + return Interpolate(t, *((*it).second) ); + +} + + + + + + + + + + + +//________________________________________________________________________ + +//________________________________________________________________________ + + + + +void EvolutionData::ReadDB(string DBfile, bool oldread) +{ + + if(oldread) + { + + OldReadDB(DBfile); + return; + } + + if(!fisDecay) + ReadInfo(); // Read the .info associeted + + ifstream DecayDB(DBfile.c_str()); // Open the File + if(!DecayDB) //check if file is correctly open + { + ERROR << " \n Can't open \"" << DBfile << "\"\n" << endl; + ERROR << "\t-> Hint : If loading .dat files using a .idx file (like for a decay data base)\nmake sure the paths in it are correct" << endl;; + exit(1); + } + vector<double> vTime; + + string line; + int start = 0; + + getline(DecayDB, line); + if( tlc(StringLine::NextWord(line, start, ' ')) != "time") + { + ERROR << " Bad Database file : " << DBfile << endl; + ERROR << " The first Line MUST be the time line !!!" << endl; + ERROR << " last line red : \n" <<line<< endl; + exit (1); + } + + while(start < (int)line.size()) + vTime.push_back(atof(StringLine::NextWord(line, start, ' ').c_str())); + + fFinalTime = vTime.back(); + double Time[vTime.size()]; + for(int i = 0; i < (int)vTime.size();i++) + Time[i] = vTime[i]; + const int NTimeStep = sizeof(Time)/sizeof(double); + + + enum { Keff = 1, Flux, Inv, XSFis, XSCap, XSn2n }; + + map<string, int> keyword_map; + keyword_map["keff"] = Keff; + keyword_map["flux"] = Flux; + keyword_map["xsfis"] = XSFis; + keyword_map["xscap"] = XSCap; + keyword_map["xsn2n"] = XSn2n; + keyword_map["inv"] = Inv; + + getline(DecayDB, line); + do + { + start = 0; + switch (keyword_map[tlc(StringLine::NextWord(line, start, ' '))]) + { + case Keff: + ReadKeff(line, Time, NTimeStep); + break; + + case Flux: + ReadFlux(line, Time, NTimeStep); + break; + + case Inv: + ReadInv(line, Time, NTimeStep); + break; + + case XSFis: + ReadXSFis(line, Time, NTimeStep); + break; + + case XSCap: + ReadXSCap(line, Time, NTimeStep); + break; + + case XSn2n: + ReadXSn2n(line, Time, NTimeStep); + break; + + + default: + break; + } + + getline(DecayDB, line); + + + }while ( !DecayDB.eof() ); + + fHeavyMetalMass = cZAIMass.GetMass( GetIsotopicVectorAt(0.).GetActinidesComposition() ); + + DecayDB.close(); + + +} + +void EvolutionData::ReadKeff(string line, double* time, int NTimeStep) +{ + if(fKeff != 0) + delete fKeff; + + int start = 0; + if( tlc(StringLine::NextWord(line, start, ' ')) != "keff" ) // Check the keyword + { + ERROR << " Bad keyword : \"keff\" not found !" << endl; + exit(1); + } + + + double Keff[NTimeStep]; + + int i = 0; + while(start < (int)line.size() && i < NTimeStep ) // Read the Data + { + Keff[i] = atof(StringLine::NextWord(line, start, ' ').c_str()) ; + i++; + } + + + fKeff = new TGraph(NTimeStep, time, Keff); // Add the TGraph + + + + +} + +void EvolutionData::ReadFlux(string line, double* time, int NTimeStep) +{ + + if(fFlux != 0) + delete fFlux; + + int start = 0; + + if( tlc(StringLine::NextWord(line, start, ' ')) != "flux" ) // Check the keyword + { + ERROR << " Bad keyword : \"flux\" not found !" << endl; + exit(1); + } + + double Flux[NTimeStep]; + + int i = 0; + while(start < (int)line.size() && i < NTimeStep ) // Read the Data + { + Flux[i] = atof(StringLine::NextWord(line, start, ' ').c_str()) ; + i++; + } + + + fFlux = new TGraph(NTimeStep, time, Flux); // Add the TGraph + + + +} + + +void EvolutionData::ReadInv(string line, double* time, int NTimeStep) +{ + + + int start = 0; + if( tlc(StringLine::NextWord(line, start, ' ')) != "inv" ) // Check the keyword + { + ERROR << " Bad keyword : \"inv\" not found !" << endl; + exit(1); + } + // Read the Z A I + int Z = atoi(StringLine::NextWord(line, start, ' ').c_str()); + int A = atoi(StringLine::NextWord(line, start, ' ').c_str()); + int I = atoi(StringLine::NextWord(line, start, ' ').c_str()); + + if(A != 0 && Z != 0) + { + double Inv[NTimeStep]; + + int i = 0; + while(start < (int)line.size() && i < NTimeStep ) // Read the Data + { + Inv[i] = atof(StringLine::NextWord(line, start, ' ').c_str()) ; + i++; + } + // Add the TGraph + fInventoryEvolution.insert(pair<ZAI ,TGraph* >(ZAI(Z,A,I), new TGraph(NTimeStep, time, Inv) ) ); + } + + +} + + +void EvolutionData::ReadXSFis(string line, double* time, int NTimeStep) +{ + + + int start = 0; + if( tlc(StringLine::NextWord(line, start, ' ')) != "xsfis" ) // Check the keyword + { + ERROR << " Bad keyword : \"xsfis\" not found !" << endl; + exit(1); + } + // Read the Z A I + int Z = atoi(StringLine::NextWord(line, start, ' ').c_str()); + int A = atoi(StringLine::NextWord(line, start, ' ').c_str()); + int I = atoi(StringLine::NextWord(line, start, ' ').c_str()); + + if(A != 0 && Z != 0) + { + double XSFis[NTimeStep]; + + int i = 0; + while(start < (int)line.size() && i < NTimeStep ) // Read the Data + { + XSFis[i] = atof(StringLine::NextWord(line, start, ' ').c_str()) ; + i++; + } + + // Add the TGraph + fFissionXS.insert(pair<ZAI ,TGraph* >(ZAI(Z,A,I), new TGraph(NTimeStep, time, XSFis) ) ); + } + + +} + +void EvolutionData::ReadXSCap(string line, double* time, int NTimeStep) +{ + + + int start = 0; + if( tlc(StringLine::NextWord(line, start, ' ')) != "xscap" ) // Check the keyword + { + ERROR << " Bad keyword : \"xscap\" not found !" << endl; + exit(1); + } + // Read the Z A I + int Z = atoi(StringLine::NextWord(line, start, ' ').c_str()); + int A = atoi(StringLine::NextWord(line, start, ' ').c_str()); + int I = atoi(StringLine::NextWord(line, start, ' ').c_str()); + + if(A != 0 && Z != 0) + { + double XSCap[NTimeStep]; + + int i = 0; + while(start < (int)line.size() && i < NTimeStep ) // Read the Data + { + XSCap[i] = atof(StringLine::NextWord(line, start, ' ').c_str()) ; + i++; + } + + // Add the TGraph + fCaptureXS.insert(pair<ZAI ,TGraph* >(ZAI(Z,A,I), new TGraph(NTimeStep, time, XSCap) ) ); + } + + +} + +void EvolutionData::ReadXSn2n(string line, double* time, int NTimeStep) +{ + + + int start = 0; + if( tlc(StringLine::NextWord(line, start, ' ')) != "xsn2n" ) // Check the keyword + { + ERROR << " Bad keyword : \"xsn2n\" not found !" << endl; + exit(1); + } + // Read the Z A I + int Z = atoi(StringLine::NextWord(line, start, ' ').c_str()); + int A = atoi(StringLine::NextWord(line, start, ' ').c_str()); + int I = atoi(StringLine::NextWord(line, start, ' ').c_str()); + + if(A != 0 && Z != 0) + { + double XSn2n[NTimeStep]; + + int i = 0; + while(start < (int)line.size() && i < NTimeStep ) // Read the Data + { + XSn2n[i] = atof(StringLine::NextWord(line, start, ' ').c_str()) ; + i++; + } + // Add the TGraph + fn2nXS.insert(pair<ZAI ,TGraph* >(ZAI(Z,A,I), new TGraph(NTimeStep, time, XSn2n) ) ); + } + + +} + + + +void EvolutionData::ReadInfo() +{ + string InfoDBFile = fDB_file.erase(fDB_file.size()-3,fDB_file.size()); + InfoDBFile += "Info"; + ifstream InfoDB_tmp(InfoDBFile.c_str()); // Open the File + + if(!InfoDB_tmp) + { + InfoDBFile = InfoDBFile.erase(InfoDBFile.size()-4,InfoDBFile.size()); + InfoDBFile += "info"; + + } + InfoDB_tmp.close(); + + ifstream InfoDB(InfoDBFile.c_str()); // Open the File + if(!InfoDB) + { + WARNING << "!!ERROR!! !!!EvolutionData!!! \n Can't open \"" << InfoDBFile << "\"\n" << endl; + } + + int start = 0; + string line; + getline(InfoDB, line); + if ( tlc(StringLine::NextWord(line, start, ' ')) == "reactor") + fReactorType = StringLine::NextWord(line, start, ' '); + + start = 0; + getline(InfoDB, line); + if (tlc(StringLine::NextWord(line, start, ' ')) == "fueltype") + fFuelType = StringLine::NextWord(line, start, ' '); + start = 0; + getline(InfoDB, line); + if ( tlc(StringLine::NextWord(line, start, ' ')) == "cycletime") + fCycleTime = atof(StringLine::NextWord(line, start, ' ').c_str());; + getline(InfoDB, line); // Assembly HM Mass + start = 0; + getline(InfoDB, line); + if ( tlc(StringLine::NextWord(line, start, ' ')) == "constantpower") + fPower = atof(StringLine::NextWord(line, start, ' ').c_str()); + InfoDB.close(); +} + +void EvolutionData::OldReadDB(string DBfile) +{ + + + ifstream DecayDB(DBfile.c_str()); // Open the File + if(!DecayDB) + { + ERROR << " Can't open \"" << DBfile << "\"\n" << endl; + ERROR << "\t-> Hint : If loading .dat files using a .idx file (like for a decay data base)\nmake sure the paths in it are correct"; + + exit(1); + } + vector<double> vTime; + vector<double> vTimeErr; + + string line; + int start = 0; + + getline(DecayDB, line); + if( StringLine::NextWord(line, start, ' ') != "time") + { + ERROR << " Bad Database file : " << DBfile << endl; + exit (1); + } + + while(start < (int)line.size()) + vTime.push_back(atof(StringLine::NextWord(line, start, ' ').c_str())); + + fFinalTime = vTime.back(); + double Time[vTime.size()]; + for(int i = 0; i < (int)vTime.size();i++) + Time[i] = vTime[i]; + vector<double> vFlux; + start = 0; + getline(DecayDB, line); + string tmp = StringLine::NextWord(line, start, ' '); + if ( tmp == "keff" || tmp == "Keff" ) + { + vector<double> vKeff; + while(start < (int)line.size()) + vKeff.push_back(atof(StringLine::NextWord(line, start, ' ').c_str())); + + double Keff[vKeff.size()]; + for(int i = 0; i < (int)vKeff.size();i++) + Keff[i] = vKeff[i]; + + fKeff = new TGraph(vTime.size(), Time, Keff); + + start = 0; + getline(DecayDB, line); + if (StringLine::NextWord(line, start, ' ') == "flux") + { + + + while(start < (int)line.size()) + vFlux.push_back(atof(StringLine::NextWord(line, start, ' ').c_str())); + + double Flux[vFlux.size()]; + for(int i = 0; i < (int)vFlux.size();i++) + Flux[i] = vFlux[i]; + + fFlux = new TGraph(vTime.size(), Time, Flux); + + } + } + + + do + { + + + start = 0; + int Z = atoi(StringLine::NextWord(line, start, ' ').c_str()); + int A = atoi(StringLine::NextWord(line, start, ' ').c_str()); + int I = atoi(StringLine::NextWord(line, start, ' ').c_str()); + + if(A != 0 && Z != 0) + { + double DPQuantity[vTime.size()]; + for(int k = 0; k < (int)vTime.size(); k++ ) + DPQuantity[k] = 0; + + + ZAI zaitmp(Z, A, I); + int i = 0; + while(start < (int)line.size()) + { + double DPQuantityTmp = atof(StringLine::NextWord(line, start, ' ').c_str()); + DPQuantity[i] = (double)DPQuantityTmp; + i++; + + } + TGraph* tgraphtmp = new TGraph((int)vTime.size()-1, Time, DPQuantity); + fInventoryEvolution.insert(pair<ZAI ,TGraph* >(zaitmp, tgraphtmp) ); + } + + getline(DecayDB, line); + if(line == "" || line == "CrossSection" ) break; + }while (!DecayDB.eof() ); + + if(line == "CrossSection") + { + fIsCrossSection = true; + getline(DecayDB, line); + + if (line == "Fission") + { + getline(DecayDB, line); + + do + { + double DPQuantity[vTime.size()]; + for(int k = 0; k < (int)vTime.size(); k++ ) + DPQuantity[k] = 0; + + start = 0; + int Z = atoi(StringLine::NextWord(line, start, ' ').c_str()); + int A = atoi(StringLine::NextWord(line, start, ' ').c_str()); + int I = atoi(StringLine::NextWord(line, start, ' ').c_str()); + if(A != 0 && Z != 0) + { + + + ZAI zaitmp(Z, A, I); + int i = 0; + while(start < (int)line.size()) + { + long double DPQuantityTmp = atof(StringLine::NextWord(line, start, ' ').c_str()); + DPQuantity[i] = (double)DPQuantityTmp; + i++; + + } + fFissionXS.insert(pair<ZAI ,TGraph* >(zaitmp, new TGraph(vTime.size()-1, Time, DPQuantity) ) ); + } + getline(DecayDB, line); + if(line == "" || line == "Capture" ) break; + }while ( !DecayDB.eof() ); + } + + if (line == "Capture") + { + getline(DecayDB, line); // Nuclei is given with "A Z" + + do + { + double DPQuantity[vTime.size()]; + for(int k = 0; k < (int)vTime.size(); k++ ) + DPQuantity[k] = 0; + + + start = 0; + int Z = atoi(StringLine::NextWord(line, start, ' ').c_str()); + int A = atoi(StringLine::NextWord(line, start, ' ').c_str()); + int I = atoi(StringLine::NextWord(line, start, ' ').c_str()); + + if(A != 0 && Z != 0) + { + + + ZAI zaitmp(Z, A, I); + int i = 0; + while(start < (int)line.size()) + { + long double DPQuantityTmp = atof(StringLine::NextWord(line, start, ' ').c_str()); + DPQuantity[i] = (double)DPQuantityTmp; + i++; + + } + fCaptureXS.insert(pair<ZAI ,TGraph* >(zaitmp, new TGraph(vTime.size()-1, Time, DPQuantity) ) ); + } + getline(DecayDB, line); // Nuclei is given with "A Z" + if(line == "" || line == "n2n" ) break; + }while ( !DecayDB.eof() ); + + } + + if (line == "n2n") + { + + getline(DecayDB, line); // Nuclei is given with "A Z" + + do + { + double DPQuantity[vTime.size()]; + for(int k = 0; k < (int)vTime.size(); k++ ) + DPQuantity[k] = 0; + + start = 0; + int Z = atoi(StringLine::NextWord(line, start, ' ').c_str()); + int A = atoi(StringLine::NextWord(line, start, ' ').c_str()); + int I = atoi(StringLine::NextWord(line, start, ' ').c_str()); + + if(A != 0 && Z != 0) + { + + + ZAI zaitmp(Z, A, I); + int i = 0; + while(start < (int)line.size()) + { + long double DPQuantityTmp = atof(StringLine::NextWord(line, start, ' ').c_str()); + DPQuantity[i] = (double)DPQuantityTmp; + i++; + + } + fn2nXS.insert(pair<ZAI ,TGraph* >(zaitmp, new TGraph(vTime.size()-1, Time, DPQuantity) ) ); + } + getline(DecayDB, line); // Nuclei is given with "A Z" + if(line == "" ) break; + + }while ( !DecayDB.eof() ); + } + + } + DecayDB.close(); + start = 0; + + string InfoDBFile = DBfile.erase(DBfile.size()-3,DBfile.size()); + InfoDBFile += "info"; + ifstream InfoDB(InfoDBFile.c_str()); // Open the File + if(!InfoDB) + { + INFO << " Can't open \"" << InfoDBFile << "\"\n" << endl; + return; + } + + start = 0; + getline(InfoDB, line); + if (StringLine::NextWord(line, start, ' ') == "Reactor") + fReactorType = StringLine::NextWord(line, start, ' '); + start = 0; + getline(InfoDB, line); + if (StringLine::NextWord(line, start, ' ') == "Fueltype") + fFuelType = StringLine::NextWord(line, start, ' '); + start = 0; + getline(InfoDB, line); + if (StringLine::NextWord(line, start, ' ') == "CycleTime") + fCycleTime = atof(StringLine::NextWord(line, start, ' ').c_str());; + getline(InfoDB, line); // Assembly HM Mass + start = 0; + getline(InfoDB, line); + if (StringLine::NextWord(line, start, ' ') == "ConstantPower") + fPower = atof(StringLine::NextWord(line, start, ' ').c_str()); + getline(InfoDB, line); // cutoff + getline(InfoDB, line); // NUmber of Nuclei + start = 0; + getline(InfoDB, line); + if (StringLine::NextWord(line, start, ' ') == "NormalizationFactor") + { + double NormFactor = atof(StringLine::NextWord(line, start, ' ').c_str()); + fPower = fPower * NormFactor; + double Flux[vFlux.size()]; + for(int i = 0; i < (int)vFlux.size();i++) + Flux[i] = vFlux[i]; + + fFlux = new TGraph(vTime.size()-1, Time, Flux); + } + InfoDB.close(); +} + + + + + diff --git a/source/branches/BaM/src/FabricationPlant.cxx b/source/branches/BaM/src/FabricationPlant.cxx new file mode 100644 index 000000000..40918aa77 --- /dev/null +++ b/source/branches/BaM/src/FabricationPlant.cxx @@ -0,0 +1,700 @@ +#include "FabricationPlant.hxx" + +#include "Storage.hxx" +#include "Reactor.hxx" +#include "EvolutionData.hxx" +#include "PhysicsModels.hxx" +#include "IsotopicVector.hxx" +#include "Scenario.hxx" +#include "CLASSLogger.hxx" +#include "CLASSConstante.hxx" + + + + +#include "TMatrixT.h" + +#include <sstream> +#include <string> +#include <iostream> +#include <cmath> +#include <algorithm> + +ClassImp(FabricationPlant) + + //________________________________________________________________________ + //________________________________________________________________________ + //________________________________________________________________________ + // + // FabricationPlant + // + // + // + // + //________________________________________________________________________ + //________________________________________________________________________ + + +FabricationPlant::FabricationPlant():CLASSFacility(16) +{ + SetName("F_FabricationPLant."); + + fReUsable = 0; + fIsReusable = false; +} + + +FabricationPlant::FabricationPlant(CLASSLogger* log, double fabricationtime):CLASSFacility(log, fabricationtime, 16) +{ +DBGL + SetName("F_FabricationPLant."); + + fFiFo = false; + fSubstitutionFuel = false; + fSubstitutionFissile = false; + fIsReplaceFissileStock = false; + + fReUsable = 0; + fIsReusable = false; + + INFO << " A FabricationPlant has been define :" << endl; + INFO << "\t Chronological Stock Priority has been set! " << endl; + INFO << "\t Fabrication time set to \t " << (double)(GetCycleTime()/cYear) << " year" << endl << endl; +DBGL +} + + + + //________________________________________________________________________ +FabricationPlant::~FabricationPlant() +{ + + +} + + + //________________________________________________________________________ +void FabricationPlant::SetSeparartionEfficiencyIV(ZAI zai, double factor) +{ + + pair<map<ZAI, double>::iterator, bool> IResult; + if(factor > 1) factor = 1; + + if(factor > 0) + { + IResult = fSeparationLostFraction.GetIsotopicQuantity().insert( pair<ZAI ,double>(zai, 1 - factor)); + if(!IResult.second) + IResult.first->second = 1 - factor; + } + +} + + + + //________________________________________________________________________ + //_______________________________ Evolution ______________________________ + //________________________________________________________________________ +void FabricationPlant::Evolution(cSecond t) +{ + + // Check if the FabricationPlant has been created ... + if(t == fInternalTime && t != 0) return; + // Make the evolution for the FabricationPlant ... + FabricationPlantEvolution(t); + //Update Inside IsotopicVector + UpdateInsideIV(); + // ... And Finaly update the AbsoluteInternalTime + fInternalTime = t; + +} + + //________________________________________________________________________ +void FabricationPlant::FabricationPlantEvolution(cSecond t) +{ +DBGL + map<int ,cSecond >::iterator it; + for( it = fReactorNextStep.begin(); it != fReactorNextStep.end(); it++ ) + { + double R_CreactionTime = GetParc()->GetReactor()[ (*it).first ]->GetCreationTime(); + double R_LifeTime = GetParc()->GetReactor()[ (*it).first ]->GetLifeTime(); + + int ReactorId = (*it).first; + pair<CLASSFuel, double> R_Fuel = GetParc()->GetReactor()[ReactorId]->GetFuelPlan()->GetFuelAt( t + GetCycleTime() ); + double R_BU = R_Fuel.second; + double R_Power = GetParc()->GetReactor()[ReactorId]->GetPower(); + double R_HMMass = GetParc()->GetReactor()[ReactorId]->GetHeavyMetalMass(); + cSecond R_CycleTime = (cSecond) (R_BU*1e9 / (R_Power) * R_HMMass * 3600 * 24); + + + if( R_CycleTime < GetCycleTime()) + { + ERROR << "Reactor Cycle Time is shorter than Fabrication Time of the fuel, we cannot deal it upto now!!!" << endl; + exit(1); + } + + if( t + GetCycleTime() >= R_CreactionTime + && t + GetCycleTime() < R_CreactionTime + R_LifeTime) + { + if( (*it).second == t ) + { +#pragma omp critical(FuelBuild) + { + if( R_Fuel.first.GetPhysicsModels() ) + { + BuildFuelForReactor( (*it).first, t ); + } + (*it).second += R_CycleTime; + } + + } + else if ( (*it).second - R_CycleTime + GetCycleTime() >= t && (*it).second - R_CycleTime < t ) + { + map<int ,IsotopicVector >::iterator it2 = fReactorFuturIV.find( (*it).first ); + if (it2 != fReactorFuturIV.end()) + (*it2).second = GetDecay((*it2).second, t - fInternalTime ); + } + } + } + + +DBGL +} + +void FabricationPlant::UpdateInsideIV() +{ + DBGL + fInsideIV = IsotopicVector(); + + map< int,IsotopicVector >::iterator it; + for( it = fReactorFuturIV.begin(); it != fReactorFuturIV.end(); it++ ) + fInsideIV += (*it).second; + + DBGL +} + + + //________________________________________________________________________ +void FabricationPlant::BuildFuelForReactor(int ReactorId, cSecond t) +{ + DBGL + if(fFissileStorage.size() == 0) + { + ERROR << " One need at least one Fissile storage to build fuel " << endl; + ERROR << " Use AddFissileStorage to add a stock to provide fissil material... " << endl; + ERROR << " One need at least one Fissile storage to build fuel " << endl; + exit(1); + } + + + + double R_HM_Mass = GetParc()->GetReactor()[ ReactorId ]->GetHeavyMetalMass(); + double R_CycleTime = GetParc()->GetReactor()[ ReactorId ]->GetCycleTime(); + double R_Power = GetParc()->GetReactor()[ ReactorId ]->GetPower(); + + pair<CLASSFuel, double > FuelBU = GetParc()->GetReactor()[ReactorId]->GetFuelPlan()->GetFuelAt(t+GetCycleTime()) ; + PhysicsModels FuelType = *FuelBU.first.GetPhysicsModels(); + double R_BU = FuelBU.second; + + fFissileList = FuelType.GetEquivalenceModel()->GetFissileList(); + BuildFissileArray(); + + // If there is not enough Fissile its possible to take from an infinite fissile stock + if( !fIsReplaceFissileStock && fSubstitutionFissile )//if it is defined and wanted + { IsotopicVector CooledSeparatedIV = GetDecay( fSubstitutionFissileIV , GetCycleTime()); + fFissileArray.push_back( CooledSeparatedIV/ CooledSeparatedIV.GetTotalMass() * R_HM_Mass ); + } + + + fFertileList = FuelType.GetEquivalenceModel()->GetFertileList(); + + + if(fFertileStorage.size() != 0) // If the fertile need to be taken in stock + BuildFertileArray(); + else // if their is not stock and the fertile come from outside of the park + { + fFertileArray.push_back( fFertileList / fFertileList.GetTotalMass() * R_HM_Mass ); + DBGV("Fertile Array size : " << fFertileArray.size()) + } + + + vector<double> LambdaArray = FuelType.GetEquivalenceModel()->BuildFuel(R_BU, R_HM_Mass, fFissileArray, fFertileArray); + + double LambdaSum = 0; + for(int i = 0; i < (int)fFissileArray.size();i++) + LambdaSum += LambdaArray[i]; + + if(LambdaArray[0] != -1 && LambdaSum > 0 ) + { + DBGV("Building process suceed: ") + + IsotopicVector IV = BuildFuelFromEqModel(LambdaArray); + EvolutionData EvolDB = FuelType.GenerateEvolutionData( GetDecay(IV,fCycleTime), R_CycleTime, R_Power); + + { + pair<map<int, IsotopicVector>::iterator, bool> IResult; + IResult = fReactorFuturIV.insert( pair<int, IsotopicVector>(ReactorId, IV) ); + if(!IResult.second) + IResult.first->second = IV; + } + { + pair<map<int, EvolutionData>::iterator, bool> IResult; + IResult = fReactorFuturDB.insert( pair<int, EvolutionData>(ReactorId,EvolDB) ); + if(!IResult.second) + IResult.first->second = EvolDB; + } + fInsideIV += IV; + AddCumulativeIVIn(IV); + DBGL + return; + } + else + { + DBGV("Building process failed: ") + if (!fSubstitutionFuel) + { + DBGV("Reactor not loaded ") + { + EvolutionData EmptyDB; + pair<map<int, EvolutionData>::iterator, bool> IResult; + IResult = fReactorFuturDB.insert( pair<int, EvolutionData>(ReactorId,EmptyDB) ); + if(!IResult.second) + IResult.first->second = EmptyDB; + } + { + IsotopicVector EmptyIV; + pair<map<int, IsotopicVector>::iterator, bool> IResult; + IResult = fReactorFuturIV.insert( pair<int, IsotopicVector>(ReactorId,EmptyIV) ); + if(!IResult.second) + IResult.first->second = EmptyIV; + } + } + else + { + DBGV("Using substitute : ") + if(fSubstitutionFissile)//if the build fail possibility to take a fissile material from an infinite fissile stock (if infinite stock defined) + { + DBGV("->From an infinite stock") + //make the user specified fissil composition to decay the fabrication time + IsotopicVector CooledSeparatedIV = GetDecay(fSubstitutionFissileIV, GetCycleTime()); + //Building the fuel : + double MolarFissileContent = FuelType.GetEquivalenceModel()->GetFissileMolarFraction(CooledSeparatedIV,fFertileList, R_BU); + IsotopicVector BuiltFuel = MolarFissileContent*fSubstitutionFissileIV/fSubstitutionFissileIV.GetSumOfAll() + (1-MolarFissileContent)*fFertileList/fFertileList.GetSumOfAll(); + IsotopicVector IV = BuiltFuel/ BuiltFuel.GetTotalMass() * R_HM_Mass; + + //Generating the EvolutionData + EvolutionData EvolDB = FuelType.GenerateEvolutionData( GetDecay(IV,fCycleTime), R_CycleTime, R_Power); + + { + pair<map<int, IsotopicVector>::iterator, bool> IResult; + IResult = fReactorFuturIV.insert( pair<int, IsotopicVector>(ReactorId, IV) ); + if(!IResult.second) + IResult.first->second = IV; + } + { + pair<map<int, EvolutionData>::iterator, bool> IResult; + IResult = fReactorFuturDB.insert( pair<int, EvolutionData>(ReactorId,EvolDB) ); + if(!IResult.second) + IResult.first->second = EvolDB; + } + + GetParc()->AddOutIncome(IV); + fInsideIV += IV; + AddCumulativeIVIn(IV); + + DBGL + } + else + { + DBGV("->From a fixed data base") + IsotopicVector IV = fSubstitutionEvolutionData.GetIsotopicVectorAt(0); + EvolutionData evolutiondb = fSubstitutionEvolutionData * R_HM_Mass / IV.GetTotalMass(); + + IV = IV* R_HM_Mass / IV.GetTotalMass(); + { + pair<map<int, IsotopicVector>::iterator, bool> IResult; + IResult = fReactorFuturIV.insert( pair<int, IsotopicVector>(ReactorId, IV) ); + if(!IResult.second) + IResult.first->second = IV; + } + { + pair<map<int, EvolutionData>::iterator, bool> IResult; + IResult = fReactorFuturDB.insert( pair<int, EvolutionData>(ReactorId,evolutiondb) ); + if(!IResult.second) + IResult.first->second = evolutiondb; + } + GetParc()->AddOutIncome( IV ); + fInsideIV += IV; + AddCumulativeIVIn(IV); + } + + } + DBGL + ResetArrays(); + + return; + } +DBGL +} + + + +void FabricationPlant::BuildFissileArray() +{ +DBGL + + for(int i = 0; i < (int)fFissileStorage.size(); i++) + { + + vector<IsotopicVector> IVArray = fFissileStorage[i]->GetIVArray(); + + for(int j = 0; j < (int)IVArray.size(); j++) + { + + IsotopicVector SeparatedIV = Separation(IVArray[j], fFissileList).first; + + if(Norme(SeparatedIV) != 0) + { + IsotopicVector CooledSeparatedIV = GetDecay( SeparatedIV , GetCycleTime()); + + fFissileArray.push_back( CooledSeparatedIV ); + fFissileArrayAdress.push_back( pair<int,int>(i,j) ); + fFissileArrayTime.push_back(fFissileStorage[i]->GetIVArrayArrivalTime()[j]); + } + + } + + } + + SortArray(0); +DBGL +} + + +void FabricationPlant::BuildFertileArray() +{ +DBGL + + for(int i = 0; i < (int)fFertileStorage.size(); i++) + { + vector<IsotopicVector> IVArray = fFertileStorage[i]->GetIVArray(); + for(int j = 0; j < (int)IVArray.size(); j++) + { + + IsotopicVector SeparatedIV = Separation(IVArray[j], fFertileList).first; + if(Norme(SeparatedIV) != 0) + { + IsotopicVector CooledSeparatedIV = GetDecay( SeparatedIV , GetCycleTime()); + + fFertileArray.push_back( CooledSeparatedIV ); + fFertileArrayAdress.push_back( pair<int,int>(i,j) ); + fFertileArrayTime.push_back(fFertileStorage[i]->GetIVArrayArrivalTime()[j]); + } + } + + } + + SortArray(1); +DBGL +} + +void FabricationPlant::SortArray(int i) +{ + + + vector<IsotopicVector> IVArray; + vector<cSecond> TimeArray; + vector< pair<int,int> > AdressArray; + + if(i == 0) //Fissile + { + IVArray = fFissileArray; + TimeArray = fFissileArrayTime; + AdressArray = fFissileArrayAdress; + } + else if (i == 1) //Fertile + { + IVArray = fFertileArray; + TimeArray = fFertileArrayTime; + AdressArray = fFertileArrayAdress; + + } + + if(fFiFo) + { + for(int j = 0; j < (int)TimeArray.size(); j++) + { + for (int k = j+1; k < (int)TimeArray.size(); k++) + { + cSecond time_tmp = TimeArray[j]; + pair<int,int> Adress_tmp = AdressArray[j]; + IsotopicVector IV_tmp = IVArray[j]; + + if(time_tmp > TimeArray[k]) + { + TimeArray[j] = TimeArray[k]; + TimeArray[k] = time_tmp; + + AdressArray[j] = AdressArray[k]; + AdressArray[k] = Adress_tmp; + + IVArray[j] = IVArray[k]; + IVArray[k] = IV_tmp; + } + + } + } + } + else + { + for(int j = 0; j < (int)fFissileArrayTime.size(); j++) + { + for (int k = j+1; k < (int)TimeArray.size(); k++) + { + cSecond time_tmp = TimeArray[j]; + pair<int,int> Adress_tmp = AdressArray[j]; + IsotopicVector IV_tmp = IVArray[j]; + + if(time_tmp < TimeArray[k]) + { + TimeArray[j] = TimeArray[k]; + TimeArray[k] = time_tmp; + + AdressArray[j] = AdressArray[k]; + AdressArray[k] = Adress_tmp; + + IVArray[j] = IVArray[k]; + IVArray[k] = IV_tmp; + } + + } + } + } + + + if(i == 0) //Fissile + { + fFissileArray = IVArray; + fFissileArrayTime = TimeArray; + fFissileArrayAdress = AdressArray; + } + else if (i == 1) //Fertile + { + fFertileArray = IVArray; + fFertileArrayTime = TimeArray; + fFertileArrayAdress = AdressArray; + + } + + +} + + + + +//________________________________________________________________________ +void FabricationPlant::SetSubstitutionFuel(EvolutionData fuel, bool ReplaceTheStock) +{ + + fSubstitutionFuel = true; + fIsReplaceFissileStock = ReplaceTheStock; + + double M0 = cZAIMass.GetMass( fuel.GetIsotopicVectorAt(0.).GetActinidesComposition() ); + fSubstitutionEvolutionData = fuel / M0; + +} +//________________________________________________________________________ +void FabricationPlant::SetSubstitutionFissile(IsotopicVector IV) +{ + + fSubstitutionFuel = true; + fSubstitutionFissile = true; + + fSubstitutionFissileIV = IV / IV.GetSumOfAll(); + +} + + //________________________________________________________________________ + //_____________________________ Reactor & DB _____________________________ + //________________________________________________________________________ + //________________________________________________________________________ +void FabricationPlant::TakeReactorFuel(int Id) +{ +DBGL + IsotopicVector IV; + map<int ,IsotopicVector >::iterator it2 = fReactorFuturIV.find( Id ); + + AddCumulativeIVOut(it2->second); + + if (it2 != fReactorFuturIV.end()) + (*it2).second = IV; + + map< int,EvolutionData >::iterator it = fReactorFuturDB.find(Id); + (*it).second.DeleteEvolutionDataCopy(); + + UpdateInsideIV(); +DBGL +} + +//________________________________________________________________________ +EvolutionData FabricationPlant::GetReactorEvolutionDB(int ReactorId) +{ + + map< int,EvolutionData >::iterator it = fReactorFuturDB.find(ReactorId); + return (*it).second; +} + //________________________________________________________________________ + //_______________________________ Storage ________________________________ + //________________________________________________________________________ +IsotopicVector FabricationPlant::BuildFuelFromEqModel(vector<double> LambdaArray) +{ +DBGL + IsotopicVector BuildedFuel; + IsotopicVector Lost; + + int StockCorrection = 0; + if( !fIsReplaceFissileStock && fSubstitutionFissile) + { + StockCorrection = 1; + BuildedFuel += fFissileArray.back()*LambdaArray[fFissileArray.size()-1]; + } + + for(int i = 0; i < (int)fFissileArray.size() - StockCorrection ; i++) + { + if(LambdaArray[i] != 0) + { + int Stor_N = fFissileArrayAdress[i].first; + int IV_N = fFissileArrayAdress[i].second; + + pair<IsotopicVector, IsotopicVector> Separated_Lost; + Separated_Lost = Separation( fFissileStorage[Stor_N]->GetIVArray()[IV_N]*LambdaArray[i], fFissileList ); + BuildedFuel += Separated_Lost.first; + Lost += Separated_Lost.second; + + } + } + + if(fFertileStorage.size() != 0) + { + for(int i = fFissileArray.size(); i < (int)(fFertileArray.size()+fFissileArray.size()); i++) + { + if(LambdaArray[i] != 0) + { + int Stor_N = fFertileArrayAdress[i].first; + int IV_N = fFertileArrayAdress[i].second; + + pair<IsotopicVector, IsotopicVector> Separated_Lost; + Separated_Lost = Separation( fFertileStorage[Stor_N]->GetIVArray()[IV_N]*LambdaArray[i], fFertileList); + BuildedFuel += Separated_Lost.first; + Lost += Separated_Lost.second; + } + } + } + else + BuildedFuel += fFertileArray[0]*LambdaArray.back(); + + if(fIsReusable) + fReUsable->AddIV(Lost); + else + GetParc()->AddWaste(Lost); + + DumpStock(LambdaArray); + +DBGL + return BuildedFuel; +} + + + //________________________________________________________________________ +void FabricationPlant::DumpStock(vector<double> LambdaArray) +{ +DBGL + int StockCorrection = 0; + if( !fIsReplaceFissileStock && fSubstitutionFissile) + { StockCorrection = 1; + GetParc()->AddOutIncome( fFissileArray.back()*LambdaArray[fFissileArray.size()-1] ); + } + for(int i = 0; i < (int)fFissileArray.size() - StockCorrection; i++) + { + if(LambdaArray[i] != 0) + { + int Stor_N = fFissileArrayAdress[i].first; + int IV_N = fFissileArrayAdress[i].second; + fFissileStorage[Stor_N]->TakeFractionFromStock( IV_N, LambdaArray[i] ); + } + } + if(fFertileStorage.size() != 0) + { + for(int i = fFissileArray.size(); i < (int)(fFertileArray.size()+fFissileArray.size()); i++) + { + if(LambdaArray[i] != 0) + { + int Stor_N = fFertileArrayAdress[i].first; + int IV_N = fFertileArrayAdress[i].second; + + fFertileStorage[Stor_N]->TakeFractionFromStock( IV_N, LambdaArray[i] ); + } + } + } + else + GetParc()->AddOutIncome( fFertileArray[0]*LambdaArray.back() ); + + ResetArrays(); + + +DBGL +} +//________________________________________________________________________ +void FabricationPlant::ResetArrays() +{ + //Clear the Building Array (Fissile and Fertile) + fFissileArray.clear(); + fFissileArrayTime.clear(); + fFissileArrayAdress.clear(); + fFertileArray.clear(); + fFertileArrayTime.clear(); + fFertileArrayAdress.clear(); + + fFertileList = fFissileList = IsotopicVector(); +} +//________________________________________________________________________ +pair<IsotopicVector, IsotopicVector> FabricationPlant::Separation(IsotopicVector isotopicvector, IsotopicVector ExtractedList) +{ +DBGL + //[0] = re-use ; [1] = waste + IsotopicVector LostInReprocessing = isotopicvector.GetThisComposition(ExtractedList) * fSeparationLostFraction; + IsotopicVector SeparatedPart = isotopicvector.GetThisComposition(ExtractedList) - LostInReprocessing; + IsotopicVector LostPart = isotopicvector - SeparatedPart; +DBGL + return pair<IsotopicVector, IsotopicVector> (SeparatedPart, LostPart); +} + + + +//________________________________________________________________________ +// Get Decay +//________________________________________________________________________ +IsotopicVector FabricationPlant::GetDecay(IsotopicVector isotopicvector, cSecond t) +{ + + IsotopicVector IV; + + map<ZAI ,double> isotopicquantity = isotopicvector.GetIsotopicQuantity(); + map<ZAI ,double >::iterator it; + for( it = isotopicquantity.begin(); it != isotopicquantity.end(); it++) + { + if((*it).second > 0) + { + IsotopicVector ivtmp = fDecayDataBase->Evolution(it->first, t) * (*it).second ; + IV += ivtmp; + } + } + + return IV; + +} + + + + + + diff --git a/source/branches/BaM/src/IrradiationModel.cxx b/source/branches/BaM/src/IrradiationModel.cxx new file mode 100644 index 000000000..2b70f5095 --- /dev/null +++ b/source/branches/BaM/src/IrradiationModel.cxx @@ -0,0 +1,694 @@ +// +// IrradiationModel.cxx +// CLASSSource +// +// Created by BaM on 04/05/2014. +// Copyright (c) 2014 BaM. All rights reserved. +// + +#include "IrradiationModel.hxx" + +#include "CLASSLogger.hxx" +#include "StringLine.hxx" + +#include <TGraph.h> +#include <TString.h> + + +#include <sstream> +#include <string> +#include <iostream> +#include <fstream> +#include <algorithm> +#include <cmath> + + +using namespace std; + +IrradiationModel::IrradiationModel():CLASSObject() +{ + fShorstestHalflife = 3600.*24*2.; + fZAIThreshold = 90; + fSpectrumType = "thermal"; + + + fDataDirectoryName = getenv("CLASS_PATH"); + fDataDirectoryName += "/data/"; + fDataFileName = "chart.JEF3T"; + +} + +IrradiationModel::IrradiationModel(CLASSLogger* log):CLASSObject(log) +{ + fShorstestHalflife = 3600.*24*2.; + fZAIThreshold = 90; + fSpectrumType = "thermal"; + + fDataDirectoryName = getenv("CLASS_PATH"); + fDataDirectoryName += "/data/"; + fDataFileName = "chart.JEF3T"; + + fNormalDecay = CLASSNucleiFiliation( log ); + fFastDecay = CLASSNucleiFiliation( log ); + + fCaptureReaction = CLASSNucleiFiliation( log ); + fn2nReaction = CLASSNucleiFiliation( log ); +} +//________________________________________________________________________ +//________________________________________________________________________ +/* Physics */ +//________________________________________________________________________ +//________________________________________________________________________ + + + +//________________________________________________________________________ +/* Decay Stuff */ +//________________________________________________________________________ +string IrradiationModel::GetDecay(string DecayModes, double &BR,int &Iso, int &StartPos) +{ + string header; + + BR = 0; + string DecayBR = StringLine::NextWord(DecayModes,StartPos,','); //extraction of the decay mode and the BR + + int ss = 0; + string Decay = StringLine::NextWord(DecayBR,ss,':'); //extraction of the decay + + + if( ss < (int)DecayBR.size() ) //extraction of the BR if exist (i.e. for non stable isotop) + BR = atof(DecayBR.substr(ss+1).c_str()); + + BR /= 100.; //BR in % -> BR + + + Iso = 0; + if( Decay.find("/",0) < string::npos ) //find the Isomeric state of Daughter + { + Iso = atoi( Decay.substr( Decay.find("/") + 1 ).c_str() ); + Decay = Decay.substr( 0, Decay.find("/") ); + } + return Decay; +} + +//________________________________________________________________________ +void IrradiationModel::LoadDecay() +{ + DBGL + + // Add TMP and PF as a stable nuclei in the normal decay lsit + fNormalDecay.Add(ZAI(-3,-3,-3), IsotopicVector() ); // TMP + fNormalDecay.Add(ZAI(-2,-2,-2), IsotopicVector() ); // PF + + + + string DataFullPathName = GetDataDirectoryName()+ GetDataFileName(); + ifstream infile(DataFullPathName.c_str()); + + if(!infile) + WARNING << " Can't open \"" << DataFullPathName << "\"" << endl; + + + do + { + int A = -1; + int Z = -1; + int I = -1; + string zainame; + string Iname; + int unkown; + double HalfLife; + string DecayModes; + + infile >> A >> Z >> zainame >> Iname >> unkown >> HalfLife >> DecayModes; + if(Z >= fZAIThreshold ) + { + // Get Isomeric State; + + if(Iname == "gs") + I = 0; + else + { + if(Iname[0] == 'm') + { + if( atoi( Iname.substr(1).c_str() ) == 0 ) + I = 1; + else + I = atoi( Iname.substr(1).c_str() ); + } + } + + int start = 0; + double branch_test = 0; + double branch_test_f = 0; + + ZAI ParentZAI = ZAI(Z,A,I); + IsotopicVector DaughtersIV; + bool stable = true; + + while(start<int(DecayModes.size())) + { + double BR; + int daughter_A = 0; + int daughter_N = 0; + int daughter_Z = 0; + int Iso = 0; + int DM = -1; + // FPDistribution *FP = 0; + string decay_name = GetDecay(DecayModes, BR, Iso, start); + + if (decay_name == "s") {DM = 0;daughter_N = (A-Z); daughter_Z = Z;BR = 1;} + if (decay_name == "b-") {DM = 1;stable = false; daughter_N = (A-Z)-1; daughter_Z = Z+1;} + if (decay_name == "n") {DM = 2;stable = false; daughter_N = (A-Z)-1; daughter_Z = Z;} + if (decay_name == "nn") {DM = 3;stable = false; daughter_N = (A-Z)-2; daughter_Z = Z;} + if (decay_name == "b-n"){DM = 4;stable = false; daughter_N = (A-Z)-2; daughter_Z = Z+1;} + if (decay_name == "p") {DM = 5;stable = false; daughter_N = (A-Z); daughter_Z = Z-1;} + if (decay_name == "b-a"){DM = 6;stable = false; daughter_N = (A-Z)-3; daughter_Z = Z-1;} + if (decay_name == "pp") {DM = 7;stable = false; daughter_N = (A-Z); daughter_Z = Z-2;} + if (decay_name == "ce") {DM = 8;stable = false; daughter_N = (A-Z)+1; daughter_Z = Z-1;} + if (decay_name == "a") {DM = 9;stable = false; daughter_N = (A-Z)-2; daughter_Z = Z-2;} + if (decay_name == "cen"){DM = 10;stable = false; daughter_N = (A-Z); daughter_Z = Z-1;} + if (decay_name == "cep"){DM = 11;stable = false; daughter_N = (A-Z)+1; daughter_Z = Z-2;} + if (decay_name == "it") {DM = 12;stable = false; daughter_N = (A-Z); daughter_Z = Z;} + if (decay_name == "db-"){DM = 13;stable = false; daughter_N = (A-Z)-2; daughter_Z = Z+2;} + if (decay_name == "db+"){DM = 14;stable = false; daughter_N = (A-Z)+2; daughter_Z = Z-2;} + if (decay_name == "ita"){DM = 15;stable = false; daughter_N = (A-Z)-2; daughter_Z = Z-2;} + if (decay_name == "sf") {DM = 16;stable = false; daughter_N = 0; daughter_Z = -2; Iso = -2;} + if (decay_name == "cesf"){DM = 17;stable = false; daughter_N = 0; daughter_Z = -2; Iso = -2;} + if (decay_name == "b-sf"){DM = 18;stable = false; daughter_N = 0; daughter_Z = -2; Iso = -2;} + + daughter_A = daughter_Z + daughter_N; + { + if( daughter_Z < fZAIThreshold && daughter_Z != -2 ) + daughter_A = daughter_Z = Iso = -3; + // not spontaneous fission + + if((BR>1e-10) && (!stable)) + { + if(DM <= 15) + { + ZAI DaughterZAI = ZAI(daughter_Z,daughter_A,Iso); + DaughtersIV += BR * DaughterZAI; + branch_test+= BR; + } + else if( DM <= 18) + { + if(fSpontaneusYield.size() == 0 ) + { + DaughtersIV += 2*BR * ZAI(-2,-2,-2); + + branch_test_f += 2*BR; + } + else + { + + IsotopicVector SpontanuesFissionProduct = fSpontaneusYield.GetFiliation( ParentZAI ); + if(SpontanuesFissionProduct.GetQuantity(-1,-1,-1) == 0) + { + DaughtersIV += BR* SpontanuesFissionProduct ; + branch_test_f += BR* SpontanuesFissionProduct.GetSumOfAll(); + + } + else + { + WARNING << " Unknwon Spontanues yield for ZAI : " << ParentZAI.Z() << " " << ParentZAI.A() << " " << ParentZAI.I() << endl; + DaughtersIV += 2*BR * ZAI(-2,-2,-2); + branch_test_f += 2*BR; + } + } + } + + } + + } + if (DM != 0) + stable = false; + // End of While loop + } + + double btest = fabs(branch_test + branch_test_f/2.-1.0); + if ( btest > 1e-8 && !stable ) + DaughtersIV = DaughtersIV / (branch_test+branch_test_f/2.); + + + + if (HalfLife < fShorstestHalflife && !stable) + fFastDecay.Add( ParentZAI, DaughtersIV ); // Fill the FastDecay by the Daughter IV + else if (stable) + { + fNormalDecay.Add(ParentZAI, IsotopicVector() ); // Fill the NormalDecay with a empty IV (mother is stable) + } + else + { + fNormalDecay.Add( ParentZAI, DaughtersIV ); // FIll the NormalDecay with the daughter IV scaled by the decay constante. + fDecayConstante += ParentZAI*log(2)/HalfLife; + } + } + + } while (!infile.eof()); + DBGL + + //Build the Matrix index : + fReverseMatrixIndex = fNormalDecay.GetZAIList(); + for(int i = 0; i< (int)fReverseMatrixIndex.size(); i++) + fMatrixIndex.insert(pair<ZAI, int> (fReverseMatrixIndex[i], i) ); + + DBGL + fFastDecay.SelfFiliationCleanUp(fMatrixIndex); + DBGL + fNormalDecay.FiliationCleanUp(fMatrixIndex, fFastDecay); + + + DBGL +} + + +void IrradiationModel::BuildDecayMatrix() +{ + DBGL + fDecayMatrix.Clear(); + + fDecayMatrix.ResizeTo( fMatrixIndex.size(), fMatrixIndex.size() ); + for(int i = 0; i < (int)fMatrixIndex.size(); i++) + for(int j = 0; j < (int)fMatrixIndex.size(); j++) + fDecayMatrix[i][j] = 0; + + for(int i = 0; i < (int)fReverseMatrixIndex.size(); i++) + { + + IsotopicVector DaughterIV = fNormalDecay.GetFiliation(fReverseMatrixIndex[i]); + (*this).GetNuclearProcessMatrix(fDecayMatrix, fReverseMatrixIndex[i], DaughterIV, fDecayConstante.GetQuantity(fReverseMatrixIndex[i]) ); + + } + DBGL +} + + +void IrradiationModel::GetNuclearProcessMatrix(TMatrixT<double> &NuclearProcessMatrix, ZAI Mother, IsotopicVector ProductedIV, double XSValue) +{ + DBGL + + vector<ZAI> ProductedZAIList = ProductedIV.GetZAIList(); + + if(fMatrixIndex.find(Mother) != fMatrixIndex.end()) + { + + + int i = fMatrixIndex[Mother]; + + NuclearProcessMatrix[i][i] -= XSValue; + + for(int j = 0; j < (int)ProductedZAIList.size(); j++) + { + if(fMatrixIndex.find(ProductedZAIList[j]) != fMatrixIndex.end() ) + { NuclearProcessMatrix[fMatrixIndex[ ProductedZAIList[j] ]][i] += ProductedIV.GetQuantity(ProductedZAIList[j])*XSValue; + } + else + NuclearProcessMatrix[0][i] += ProductedIV.GetQuantity(ProductedZAIList[j])*XSValue; + } + } + else + WARNING << " Can't have nuclear process on this nucleus, ZAI " << Mother.Z() << " " << Mother.A() << " " << Mother.I() << " : its halflife seems to be below the threshold!" << endl; + + DBGL +} + + +//________________________________________________________________________ +/* Fission Stuff */ +//________________________________________________________________________ +void IrradiationModel::SetFissionEnergy(ZAI zai, double E) +{ + pair<map<ZAI, double>::iterator, bool> IResult; + IResult = fFissionEnergy.insert( pair<ZAI ,double>(zai, E)); + if(!IResult.second) + IResult.first->second = E; + +} + +//________________________________________________________________________ +void IrradiationModel::SetFissionEnergy(string FissionEnergyFile) +{ + ifstream FissionFile( FissionEnergyFile.c_str() ); // Open the File + if(!FissionFile) //check if file is correctly open + WARNING << " Can't open \"" << FissionEnergyFile << "\" File" << endl; + + do + { + int Z = 0; + int A = 0; + int I = 0; + double E = 0; + FissionFile >> Z >> A >> I >> E; + SetFissionEnergy(Z, A, I, E); + } while (!FissionFile.eof()); +} + +//________________________________________________________________________ +CLASSNucleiFiliation IrradiationModel::ReadFPYield(string Yield) +{ + DBGL + + CLASSNucleiFiliation MyYield = CLASSNucleiFiliation( fLog ); + + ifstream infile(Yield.c_str()); + if(!infile) + WARNING << " Can't open \"" << Yield << "\" File !!!" << endl; + + + string line; + int start = 0; + + getline(infile, line); + vector<ZAI> Fissile; + vector<IsotopicVector> FPYields; + do + { + int Z = atof(StringLine::NextWord(line, start, ' ').c_str()); + int A = atof(StringLine::NextWord(line, start, ' ').c_str()); + int I = atof(StringLine::NextWord(line, start, ' ').c_str()); + Fissile.push_back(ZAI(Z,A,I)); + FPYields.push_back( IsotopicVector() ); + + }while(start < (int)line.size()-1); + + getline(infile, line); + do + { + start = 0; + + int Z = atof(StringLine::NextWord(line, start, ' ').c_str()); + int A = atof(StringLine::NextWord(line, start, ' ').c_str()); + int I = atof(StringLine::NextWord(line, start, ' ').c_str()); + int i = 0; + + do + { + double Yield_values = atof(StringLine::NextWord(line, start, ' ').c_str()); + + FPYields[i] += Yield_values * ZAI(Z,A,I); + + i++; + + }while(start < (int)line.size()-1); + + getline(infile, line); + + } while (!infile.eof()); + + + for(int i = 0 ; i<(int) Fissile.size() ; i++) // Fill the CLASSNucleiFiliation + MyYield.Add( Fissile[i], FPYields[i] ); + + + DBGL + return MyYield; +} + +//________________________________________________________________________ +void IrradiationModel::LoadFPYield(string SpontaneusYield, string ReactionYield) +{ + fSpontaneusYieldFile = SpontaneusYield; + fReactionYieldFile = ReactionYield; + fZAIThreshold = 0; +} +//________________________________________________________________________ +void IrradiationModel::NuclearDataInitialization() +{ + DBGL + + if(fSpontaneusYieldFile != "") + fSpontaneusYield = ReadFPYield(fSpontaneusYieldFile); + if(fReactionYieldFile != "") + fReactionYield = ReadFPYield(fReactionYieldFile); + + LoadDecay(); + + + if(fSpontaneusYieldFile != "") + fSpontaneusYield.FiliationCleanUp(fMatrixIndex, fFastDecay); // remove the cutted nuclei.... + if(fReactionYieldFile != "") + fReactionYield.FiliationCleanUp(fMatrixIndex, fFastDecay); // remove the cutted nuclei.... + + + BuildDecayMatrix(); + BuildReactionFiliation(); + + DBGL +} + + +void IrradiationModel::BuildReactionFiliation() +{ + DBGL + + //Isomeric Branching ratios : + + double BR_AM_242M = 0; + double BR_HO_166M = 0; + double BR_PM_148M = 0; + double BR_AG_110M = 0; + double BR_AG_108M = 0; + double BR_NP_236M = 0; + if(GetSpectrumType() == "thermal") + { + BR_AM_242M =1-0.8733; + BR_HO_166M =1-0.9490; + BR_PM_148M =1-0.5330; + BR_AG_110M =1-0.9508; + BR_AG_108M =1-0.9895; + BR_NP_236M =1-0.2000; + } + if(GetSpectrumType() == "fast") + { + BR_AM_242M = 1-0.8500; + BR_HO_166M = 1-0.9481; + BR_PM_148M = 1-0.5340; + BR_AG_110M = 1-0.9224; + BR_AG_108M = 1-0.9865; + BR_NP_236M = 1-0.2000; + } + // (n,Gamma) Special Reaction..... + { + // 241Am(n,Gamma) + { + fCaptureReaction.Add( ZAI(95,241,0), ZAI(96,242,0) * (1-BR_AM_242M)*0.827 ); //directly cut the Am242 as in MURE + fCaptureReaction.Add( ZAI(95,241,0), ZAI(94,242,0) * (1-BR_AM_242M)*0.173 ); //directly cut the Am242 as in MURE + fCaptureReaction.Add( ZAI(95,241,0), ZAI(95,242,1) * BR_AM_242M ); + } + + if(fReactionYieldFile != "") + {// 165Ho(n,Gamma) + { + fCaptureReaction.Add( ZAI(67,165,0), ZAI(68,166,0) * (1-BR_HO_166M) ); // + fCaptureReaction.Add( ZAI(67,165,0), ZAI(67,166,1) * BR_HO_166M ); // + } + + // 147Pm(n,Gamma) + { + fCaptureReaction.Add( ZAI(61,147,0), ZAI(61,148,0) * (1-BR_PM_148M) ); + fCaptureReaction.Add( ZAI(61,147,0), ZAI(61,148,1) * BR_PM_148M ); + + } + + // 109Ag(n, Gamma) + { + fCaptureReaction.Add( ZAI(47,109,0), ZAI(48,110,0) * 0.9970*(1-BR_AG_110M)); + fCaptureReaction.Add( ZAI(47,109,0), ZAI(46,110,0) * 0.0030*(1-BR_AG_110M)); + fCaptureReaction.Add( ZAI(47,109,0), ZAI(47,110,1) *BR_AG_110M); + } + + + // 107Ag(n, Gamma) + { + fCaptureReaction.Add( ZAI(47,107,0), ZAI(48,108,0) * 0.9715*(1-BR_AG_108M) ); + fCaptureReaction.Add( ZAI(47,107,0), ZAI(46,108,0) * 0.0285*(1-BR_AG_108M) ); + fCaptureReaction.Add( ZAI(47,107,0), ZAI(47,108,1) *BR_AG_108M); + } + } + } + + + // (n,2n) Special Reaction..... + { + // 237Np(n,2n) + { + fn2nReaction.Add(ZAI(93,237,0), ZAI(93,236,0) * (1-BR_NP_236M) ); + fn2nReaction.Add(ZAI(93,237,0), ZAI(93,236,1) * BR_NP_236M); + } + + } + + + + for(int i = 2; i < (int)fReverseMatrixIndex.size(); i++) // Start at 2 to skeep "TMP" ZAI and "PF" ZAI + { + + int Z = fReverseMatrixIndex[i].Z(); + int A = fReverseMatrixIndex[i].A(); + + if(fCaptureReaction.GetFiliation(fReverseMatrixIndex[i]).GetQuantity(ZAI(-1,-1,-1)) == 1 ) + { + fCaptureReaction.Add(fReverseMatrixIndex[i], ZAI(Z,A+1)*1); + } + if(fn2nReaction.GetFiliation(fReverseMatrixIndex[i]).GetQuantity(ZAI(-1,-1,-1)) == 1 ) + { + if(A>1) + fn2nReaction.Add(fReverseMatrixIndex[i], ZAI(Z,A-1)*1); + } + } + + + fCaptureReaction.FiliationCleanUp(fMatrixIndex, fFastDecay); // clean the filiation link + fCaptureReaction.NormalizeBranchingRatio(); // normalize it + + + fn2nReaction.FiliationCleanUp(fMatrixIndex, fFastDecay); // clean the filiation link + fn2nReaction.NormalizeBranchingRatio(); // normalize it + + + DBGL +} + + +//________________________________________________________________________ +/* Reaction Stuff */ +//________________________________________________________________________ +TMatrixT<double> IrradiationModel::GetFissionXsMatrix(EvolutionData EvolutionDataStep,double TStep) +{ + DBGL + TMatrixT<double> FissionMatrix = TMatrixT<double>( fReverseMatrixIndex.size(),fReverseMatrixIndex.size() ); + for(int i = 0; i < (int)fReverseMatrixIndex.size(); i++) + for(int j = 0; j < (int)fReverseMatrixIndex.size(); j++) + FissionMatrix[i][j] = 0; + + // ---------------- A(n,.) X+Y + + map<ZAI ,TGraph* > FissionXS = EvolutionDataStep.GetFissionXS(); + map<ZAI ,TGraph* >::iterator it_XS; + + for(it_XS = FissionXS.begin() ; it_XS != FissionXS.end(); it_XS++) //loop on fissionable nuclei + { + ZAI Mother = (*it_XS).first; // Note the Mother ZAI (not necessary but help for reading the code) + double XS_Value = (*it_XS).second->Eval(TStep) * 1e-24; // Get Cross section values + + IsotopicVector FissionProductIV = fReactionYield.GetFiliation(Mother); // Get the Isotopicvector produced by the reaction + + if(FissionProductIV.GetQuantity(ZAI(-1,-1,-1)) != 1) // Check if ZAI is dealed + GetNuclearProcessMatrix( FissionMatrix, Mother, FissionProductIV, XS_Value ); // add the Nuclear process in the Reaction Matrix + else + { + if(fReactionYieldFile != "") + WARNING << "Don't have fission Yield for this nuclei, ZAI : " << Mother.Z() << " " << Mother.A() << " " << Mother.I() << endl; + + GetNuclearProcessMatrix(FissionMatrix, Mother, ZAI(-2, -2, -2) * 2 , XS_Value ); // add the Nuclear process in the Reaction Matrix + } + + + } + + DBGL + return FissionMatrix; +} + +//________________________________________________________________________ +TMatrixT<double> IrradiationModel::GetCaptureXsMatrix(EvolutionData EvolutionDataStep,double TStep) +{ + DBGL + TMatrixT<double> CaptureMatrix = TMatrixT<double>( fReverseMatrixIndex.size(),fReverseMatrixIndex.size() ); + for(int i = 0; i < (int)fReverseMatrixIndex.size(); i++) + for(int j = 0; j < (int)fReverseMatrixIndex.size(); j++) + CaptureMatrix[i][j] = 0; + + // ---------------- A(n,Gamma) A+1 + + map<ZAI ,TGraph* > CaptureXS = EvolutionDataStep.GetCaptureXS(); + map<ZAI ,TGraph* >::iterator it_XS; + + for(it_XS = CaptureXS.begin() ; it_XS != CaptureXS.end(); it_XS++) //loop on nuclei + { + ZAI Mother = (*it_XS).first; // Note the Mother ZAI (not necessary but help for reading the code) + double XS_Value = (*it_XS).second->Eval(TStep) * 1e-24; // Get Cross section values + + IsotopicVector CaptureProductIV = fCaptureReaction.GetFiliation(Mother); // Get the Isotopicvector produced by the reaction + + if(CaptureProductIV.GetQuantity(ZAI(-1,-1,-1)) != 1) // Check if ZAI is dealed + GetNuclearProcessMatrix(CaptureMatrix, Mother, CaptureProductIV, XS_Value ); // add the Nuclear process in the Reaction Matrix + else + WARNING << "Can't have capture reaction on this nuclei, ZAI : " << Mother.Z() << " " << Mother.A() << " " << Mother.I() << endl; + + + + + + } + + DBGL + return CaptureMatrix; +} + + +//________________________________________________________________________ +TMatrixT<double> IrradiationModel::Getn2nXsMatrix(EvolutionData EvolutionDataStep,double TStep) +{ + DBGL + + TMatrixT<double> n2nMatrix = TMatrixT<double>( fReverseMatrixIndex.size(),fReverseMatrixIndex.size() ); + for(int i = 0; i < (int)fReverseMatrixIndex.size(); i++) + for(int j = 0; j < (int)fReverseMatrixIndex.size(); j++) + n2nMatrix[i][j] = 0; + + // ---------------- A(n,2n) A-1 + + map<ZAI ,TGraph* > CaptureXS = EvolutionDataStep.Getn2nXS(); + map<ZAI ,TGraph* >::iterator it_XS; + + for(it_XS = CaptureXS.begin() ; it_XS != CaptureXS.end(); it_XS++) //loop on nuclei + { + ZAI Mother = (*it_XS).first; // Note the Mother ZAI (not necessary but help for reading the code) + double XS_Value = (*it_XS).second->Eval(TStep) * 1e-24; // Get Cross section values + + IsotopicVector n2nProductIV = fn2nReaction.GetFiliation(Mother); // Get the Isotopicvector produced by the reaction + + if(n2nProductIV.GetQuantity(ZAI(-1,-1,-1)) != 1) // Check if ZAI is dealed + GetNuclearProcessMatrix(n2nMatrix, Mother, n2nProductIV, XS_Value ); // add the Nuclear process in the Reaction Matrix + else + WARNING << "Can't have n,2n reaction on this nuclei, ZAI : " << Mother.Z() << " " << Mother.A() << " " << Mother.I() << endl; + + + } + + DBGL + return n2nMatrix; +} +//________________________________________________________________________ +void IrradiationModel::SetSpectrumType(string type) +{ + if(type != "fast" && type != "thermal") + { + ERROR << type << " is not a valid spectrum type" << endl; + ERROR << "\tSpectrum type must be either fast or thermal" << endl; + exit(0); + } + else + fSpectrumType = type; + +} +//________________________________________________________________________ +double IrradiationModel::GetDecayConstant(const ZAI& zai) const +{ + map<ZAI ,double> DecayConstante = fDecayConstante.GetIsotopicQuantity(); + + map<ZAI ,double>::iterator it; + it = DecayConstante.find(zai); + + + if ( it != DecayConstante.end() ) + { + return it->second; + } + else + { + return 0; + } +} diff --git a/source/branches/BaM/src/IsotopicVector.cxx b/source/branches/BaM/src/IsotopicVector.cxx new file mode 100755 index 000000000..0a939f731 --- /dev/null +++ b/source/branches/BaM/src/IsotopicVector.cxx @@ -0,0 +1,716 @@ +#include "IsotopicVector.hxx" + +#include "CLASSLogger.hxx" +#include "CLASSConstante.hxx" + + +#include <cmath> +#include <iostream> +#include <fstream> +#include <string> +#include <algorithm> +//________________________________________________________________________ +//________________________________________________________________________ +// +// +// +// IsotopicVector +// +// +//________________________________________________________________________ +//________________________________________________________________________ + + + + +//________________________________________________________________________ +//__________________________Operator Overlaoding__________________________ +//________________________________________________________________________ + + + +//____________________________General Operator____________________________ +//________________________________________________________________________ + +ClassImp(IsotopicVector) + +double Norme(IsotopicVector IV1, int DistanceType, IsotopicVector DistanceParameter) +{ + + IsotopicVector IV; + + return Distance(IV1, IV, DistanceType,DistanceParameter); + +} +double DistanceStandard(IsotopicVector IV1, IsotopicVector IV2) +{ + + double d2 = 0; + IsotopicVector IVtmp = IV1 + IV2; + map<ZAI ,double> IVtmpIsotopicQuantity = IVtmp.GetIsotopicQuantity(); + map<ZAI ,double >::iterator it; + for( it = IVtmpIsotopicQuantity.begin(); it != IVtmpIsotopicQuantity.end(); it++) + { + double Z1 = IV1.GetZAIIsotopicQuantity( (*it).first ); + double Z2 = IV2.GetZAIIsotopicQuantity( (*it).first ); + d2 += pow(Z1-Z2 , 2 ); + } + return sqrt(d2); + +} +double DistanceAdjusted(IsotopicVector IV1, IsotopicVector IV2, IsotopicVector DistanceParameter) +{ + + double d2 = 0; + IsotopicVector IVtmp = IV1 + IV2; + map<ZAI ,double> IVtmpIsotopicQuantity = IVtmp.GetIsotopicQuantity(); + map<ZAI ,double >::iterator it; + for( it = IVtmpIsotopicQuantity.begin(); it != IVtmpIsotopicQuantity.end(); it++) + { + double Z1 = IV1.GetZAIIsotopicQuantity( (*it).first ); + double Z2 = IV2.GetZAIIsotopicQuantity( (*it).first ); + double lambda = DistanceParameter.GetZAIIsotopicQuantity( (*it).first ); + d2 += lambda*abs(Z1-Z2); + } + return d2; + +} + + + +double Distance(IsotopicVector IV1, IsotopicVector IV2, int DistanceType, IsotopicVector DistanceParameter) +{ + + if(DistanceType == 0) + { + return DistanceStandard(IV1,IV2); + } + else if(DistanceType == 1||DistanceType == 2){ + return DistanceAdjusted(IV1,IV2,DistanceParameter); + } + else + { + cout << " DistanceType defined by the user isn't recognized by the code" << endl; + + exit(1); + } + +} + + +double RelativDistance(IsotopicVector IV1, IsotopicVector IV2 ) +{ + + double d2 = 0; + + IsotopicVector IVtmp = IV1 + IV2; + map<ZAI ,double> IVtmpIsotopicQuantity = IVtmp.GetIsotopicQuantity(); + + double Z1total = 0; + double Z2total = 0; + map<ZAI ,double >::iterator it; + for( it = IVtmpIsotopicQuantity.begin(); it != IVtmpIsotopicQuantity.end(); it++) + { + Z1total += IV1.GetZAIIsotopicQuantity( (*it).first ); + Z2total += IV2.GetZAIIsotopicQuantity( (*it).first ); + } + for( it = IVtmpIsotopicQuantity.begin(); it != IVtmpIsotopicQuantity.end(); it++) + { + double Z1 = IV1.GetZAIIsotopicQuantity( (*it).first ); + double Z2 = IV2.GetZAIIsotopicQuantity( (*it).first ); + d2 += pow( (Z1/Z1total - Z2/Z2total) , 2 ); + } + + + return sqrt(d2); +} + + +IsotopicVector operator+(IsotopicVector const& IVa, IsotopicVector const& IVb) +{ + + IsotopicVector IVtmp; + IVtmp = IVa; + return IVtmp += IVb; +} + +//________________________________________________________________________ +IsotopicVector operator-(IsotopicVector const& IVa, IsotopicVector const& IVb) +{ + + IsotopicVector IVtmp; + IVtmp = IVa; + return IVtmp -= IVb; +} + + +//________________________________________________________________________ +IsotopicVector operator*(ZAI const& zai, double F) +{ + + IsotopicVector IVtmp; + + IVtmp.Add( zai, F); + return IVtmp; +} + + +//________________________________________________________________________ +IsotopicVector operator/(ZAI const& zai, double F) +{ + IsotopicVector IVtmp; + + IVtmp.Add( zai, 1./F); + + return IVtmp; +} + + +//________________________________________________________________________ +IsotopicVector operator*(double F, IsotopicVector const& IVA) {return IVA*F;} + +//________________________________________________________________________ +IsotopicVector operator*(IsotopicVector const& IVA, double F) +{ + + IsotopicVector IV = IVA; + IV.Multiply(F); + return IV; +} + +//________________________________________________________________________ +IsotopicVector operator*(double F, ZAI const& zai) +{ + return zai*F; +} + +//________________________________________________________________________ +IsotopicVector operator*(IsotopicVector const& IVa, IsotopicVector const& IVb) +{ + + IsotopicVector IVtmp; + IVtmp = IVa; + IVtmp *= IVb; + return IVtmp; +} + +//________________________________________________________________________ +IsotopicVector operator/(IsotopicVector const& IVA, double F) +{ + + IsotopicVector IV = IVA; + IV.Multiply(1./F); + return IV; +} + + +//____________________________InClass Operator____________________________ + +//________________________________________________________________________ +IsotopicVector& IsotopicVector::operator+= (const IsotopicVector& IVa) +{ + + Add(IVa); + return *this; + +} + +//________________________________________________________________________ +IsotopicVector& IsotopicVector::operator-= (const IsotopicVector& IVa) +{ + + Remove(IVa); + return *this; + +} +//________________________________________________________________________ +IsotopicVector& IsotopicVector::operator*= (const IsotopicVector& IVa) +{ + map<ZAI, double> IVA_isotopicquantity = IVa.GetIsotopicQuantity(); + + map<ZAI, double> isotopicquantity = (*this).GetIsotopicQuantity(); // get the isotopic quantity to loop on it + map<ZAI, double>::iterator isotopicIT; // iterator on a isotopic quantity map + + for(isotopicIT = isotopicquantity.begin(); isotopicIT != isotopicquantity.end(); isotopicIT++) // loop on the isotopicquantity... + { + map<ZAI, double>::iterator IVa_isotopicIT = IVA_isotopicquantity.find( (*isotopicIT).first ); + + if( IVa_isotopicIT != IVA_isotopicquantity.end() ) + (*isotopicIT).second *= (*IVa_isotopicIT).second; + else + (*isotopicIT).second = 0; + + } + + fIsotopicQuantity = isotopicquantity; + + return *this; + +} + +//________________________________________________________________________ +IsotopicVector& IsotopicVector::operator*= (const double& factor) +{ + + Multiply(factor); + + return *this; + +} + + +//________________________________________________________________________ +bool IsotopicVector::operator<(const IsotopicVector& isotopicvector) const +{ + + if( Norme(*this) != Norme(isotopicvector) ) + return Norme(*this) < Norme(isotopicvector); + else if( (*this).GetIsotopicQuantity().size() != isotopicvector.GetIsotopicQuantity().size() ) + return (*this).GetIsotopicQuantity().size() < isotopicvector.GetIsotopicQuantity().size(); + else + { + map<ZAI ,double>::iterator it; + map<ZAI ,double>::iterator it2 = isotopicvector.GetIsotopicQuantity().begin(); + map<ZAI ,double> IsotopicQuantity = (*this).GetIsotopicQuantity(); + for( it = IsotopicQuantity.begin(); it != IsotopicQuantity.end(); it++ ) + { + if( (*it).first != (*it2).first ) + return (*it).first < (*it2).first; + else it2++; + } + return false; + } + +} + + +//________________________________________________________________________ +//________________________Constructor & Destructor________________________ +//________________________________________________________________________ +IsotopicVector::IsotopicVector() +{ +} + + +//_____________________________________________________GetSpeciesComposition___________________ +IsotopicVector::~IsotopicVector() +{ + fIsotopicQuantity.clear(); + fIsotopicQuantityNeeded.clear(); +} + + + +//________________________________________________________________________ +//_____________________________General Method_____________________________ +//________________________________________________________________________ +void IsotopicVector::Clear() +{ + + fIsotopicQuantityNeeded.clear(); + fIsotopicQuantity.clear(); + +} +//________________________________________________________________________ +void IsotopicVector::ClearNeed() +{ + + fIsotopicQuantityNeeded.clear(); + +} + +//________________________________________________________________________ +void IsotopicVector::Multiply(double factor) +{ + + map<ZAI ,double >::iterator it; + for( it = fIsotopicQuantity.begin(); it != fIsotopicQuantity.end(); it++) + (*it).second = (*it).second * factor; + for( it = fIsotopicQuantityNeeded.begin(); it != fIsotopicQuantityNeeded.end(); it++) + (*it).second = (*it).second * factor; + + +} + +//________________________________________________________________________ + +double IsotopicVector::GetSumOfAll() const +{ + double Sum = 0; + map<ZAI ,double >::iterator it; + map<ZAI ,double > isotopicquantity = GetIsotopicQuantity(); + for( it = isotopicquantity.begin(); it != isotopicquantity.end(); it++) + Sum += (*it).second; + + return Sum; + +} +//________________________________________________________________________ +void IsotopicVector::Add(const ZAI& zai, double quantity) +{ + + if( ceil(quantity*1e50) - quantity*1e50 > quantity*1e50 - floor(quantity*1e50) ) + quantity = floor(quantity*1e50)*1/1e50; + else quantity = ceil(quantity*1e50)*1/1e50; + + + if(quantity > 0) + { + pair<map<ZAI, double>::iterator, bool> IResult; + IResult = fIsotopicQuantity.insert( pair<ZAI ,double>(zai, quantity)); + if(!IResult.second) + IResult.first->second += quantity; + } + + +} +//________________________________________________________________________ + +void IsotopicVector::Add(const IsotopicVector& isotopicvector) +{ + + map<ZAI ,double> isotopicquantity = isotopicvector.GetIsotopicQuantity(); + map<ZAI ,double >::iterator it; + for( it = isotopicquantity.begin(); it != isotopicquantity.end(); it++) + Add( (*it).first, (*it).second); + + +} +//________________________________________________________________________ + +void IsotopicVector::Add(const map<ZAI ,double>& quantity) +{ + + map<ZAI ,double> isotopicquantity = quantity; + map<ZAI ,double >::iterator it; + for( it = isotopicquantity.begin(); it != isotopicquantity.end(); it++) + Add( (*it).first, (*it).second); + + +} + + +//________________________________________________________________________ +void IsotopicVector::Remove(const ZAI& zai, double quantity) +{ + + + map<ZAI ,double>::iterator it; + it = fIsotopicQuantity.find(zai); + + if(quantity > 0) + { + if ( it != fIsotopicQuantity.end() ) + { + if (it->second > quantity) + it->second = it->second - quantity; + else + { + if( (it->second - quantity)/it->second > 1e-16 ) // to fit with double precision : 16 digits + Need(zai, quantity - it->second ); + it->second = 0; + } + } + else + { + Need(zai, quantity); + } + } + + if(it->second == 0) + fIsotopicQuantity.erase(it); +} + +//________________________________________________________________________ +void IsotopicVector::Remove(const IsotopicVector& isotopicvector) +{ + + map<ZAI ,double> isotopicquantity = isotopicvector.GetIsotopicQuantity(); + map<ZAI ,double >::iterator it; + for( it = isotopicquantity.begin(); it != isotopicquantity.end(); it++) + Remove( (*it).first, (*it).second); + +} + +//________________________________________________________________________ + +void IsotopicVector::ApplyZAIThreshold(int z) +{ + map<ZAI ,double> cleanedIsotopicQuantity; + cleanedIsotopicQuantity.insert( pair<ZAI ,double>(ZAI(-2,-2,-2), 0)); + + map<ZAI ,double> isotopicquantity = (*this).GetIsotopicQuantity(); + map<ZAI ,double >::iterator it; + for( it = isotopicquantity.begin(); it != isotopicquantity.end(); it++) + { + if( (*it).first.Z() < z) + cleanedIsotopicQuantity[ZAI(-2,-2,-2)] += (*it).second; + else + cleanedIsotopicQuantity.insert(*it); + + } + + fIsotopicQuantity = cleanedIsotopicQuantity; + +} + + + + +//________________________________________________________________________ +void IsotopicVector::Need(const ZAI& zai, double quantity) +{ + if(quantity < 0.5) quantity = 0; + + pair<map<ZAI, double>::iterator, bool> IResult; + if(quantity > 0) + { cout << "Negative quantity : " << quantity << " for ZAI " << zai.Z() << " " << zai.A() << " " << zai.I() << " in this IsotopicVector" << endl; + exit(0); + IResult = fIsotopicQuantityNeeded.insert( pair<ZAI ,double>(zai, quantity)); + if(!IResult.second) + IResult.first->second += quantity; + } + + +} + +//________________________________________________________________________ +void IsotopicVector::Need(const IsotopicVector& isotopicvector) +{ + + map<ZAI ,double> isotopicquantity = isotopicvector.GetIsotopicQuantity(); + map<ZAI ,double >::iterator it; + for( it = isotopicquantity.begin(); it != isotopicquantity.end(); it++) + Need( (*it).first, (*it).second); + +} + + +//________________________________________________________________________ +double IsotopicVector::GetZAIIsotopicQuantity(const ZAI& zai) const +{ + + map<ZAI ,double> IsotopicQuantity = fIsotopicQuantity; + + map<ZAI ,double>::iterator it; + it = IsotopicQuantity.find(zai); + + + if ( it != IsotopicQuantity.end() ) + { + return it->second; + } + else + { + return 0; + } +} + +//________________________________________________________________________ +double IsotopicVector::GetZAIIsotopicQuantity(const int z, const int a, const int i) const +{ + + ZAI zai(z, a, i); + return GetZAIIsotopicQuantity(zai); +} + +IsotopicVector IsotopicVector::GetSpeciesComposition(int z) const +{ + + IsotopicVector IV; + map<ZAI ,double > IsotopicQuantity = GetIsotopicQuantity(); + map<ZAI ,double >::iterator it; + for( it = IsotopicQuantity.begin(); it != IsotopicQuantity.end(); it++) + if( (*it).first.Z() == z ) + IV += (*it).first * (*it).second; + + return IV; + +} + + +IsotopicVector IsotopicVector::GetThisComposition(IsotopicVector IV) const +{ + IsotopicVector IVtmp; + map<ZAI ,double > IsotopicQuantity = IV.GetIsotopicQuantity(); + map<ZAI ,double > THISIsotopicQuantity = (*this).GetIsotopicQuantity(); + + map<ZAI ,double >::iterator it; + for( it = IsotopicQuantity.begin(); it != IsotopicQuantity.end(); it++) + { + map<ZAI ,double >::iterator it2 = THISIsotopicQuantity.find( (*it).first ); + if(it2 != THISIsotopicQuantity.end()) + IVtmp += (*it2).first * (*it2).second ; + + } + + return IVtmp; + +} +//________________________________________________________________________ +double IsotopicVector::GetTotalMass() const +{ + return cZAIMass.GetMass(*this);//in tons +} +//________________________________________________________________________ + +double IsotopicVector::GetMeanMolarMass() const +{ + return GetTotalMass() * 1e6 * AVOGADRO / GetActinidesComposition().GetSumOfAll(); +} +//________________________________________________________________________ + +vector<ZAI> IsotopicVector::GetZAIList() const +{ + + map<ZAI ,double > IsotopicQuantity = GetIsotopicQuantity(); + map<ZAI ,double >::iterator it; + vector<ZAI> zailist; + for( it = IsotopicQuantity.begin(); it != IsotopicQuantity.end(); it++) + zailist.push_back( (*it).first ); + + return zailist; + +} + +void IsotopicVector::Initiatlize(double val) +{ + map<ZAI ,double >::iterator it; + vector<ZAI> zailist; + for( it = fIsotopicQuantity.begin(); it != fIsotopicQuantity.end(); it++) + (*it).second = 1; + +} + + +IsotopicVector IsotopicVector::GetActinidesComposition() const +{ + + IsotopicVector IV; + for (int i = 0; i <12; i++) + IV += GetSpeciesComposition(89+i); + return IV; + +} + +vector<int> IsotopicVector::GetChemicalSpecies() const +{ + + vector<int> ChemicalSpecies; + + map<ZAI ,double > IsotopicQuantity = GetIsotopicQuantity(); + map<ZAI ,double >::iterator it; + for( it = IsotopicQuantity.begin(); it != IsotopicQuantity.end(); it++) + if( (int)ChemicalSpecies.size() == 0 || (*it).first.Z() != ChemicalSpecies.back() ) + ChemicalSpecies.push_back((*it).first.Z()); + + + return ChemicalSpecies; +} + + +//________________________________________________________________________ +void IsotopicVector::Write(string filename, cSecond time) const +{ + ofstream IVfile(filename.c_str(), ios_base::app); // Open the File + if(!IVfile) + cout << "!!Warning!! !!!IsotopicVector!!! \n Can't open \"" << filename << "\"\n" << endl; + + if(time != -1) + IVfile << "Time " << time/cYear << endl; + + map<ZAI ,double> IsotopicQuantity = GetIsotopicQuantity(); + map<ZAI ,double >::iterator it; + for(it = IsotopicQuantity.begin(); it != IsotopicQuantity.end(); it++) + { + IVfile << (*it).first.Z() << " "; + IVfile << (*it).first.A() << " "; + IVfile << (*it).first.I() << " "; + IVfile << (*it).second << " " << endl; + } + IVfile << endl; +} +//________________________________________________________________________ +void IsotopicVector::Print(string option) const +{ + + cout << sPrint(); + +} +//________________________________________________________________________ +string IsotopicVector::sPrint() const +{ + stringstream ss; + ss << "**************************" << endl; + ss << "*Isotopic Vector Property*" << endl; + ss << "**************************" << endl << endl; + + bool QuantityPrint = false; + bool DBPrint = false; + + QuantityPrint = true; + + if(QuantityPrint) + { + ss << "*Isotopic Vector Quantity*" << endl; + map<ZAI ,double> IsotopicQuantity = GetIsotopicQuantity(); + map<ZAI ,double >::iterator it; + for(it = IsotopicQuantity.begin();it != IsotopicQuantity.end(); it++) + { + ss << (*it).first.Z() << " "; + ss << (*it).first.A() << " "; + ss << (*it).first.I() << " "; + ss << ": " << (*it).second; + ss << endl; + } + ss << endl; + ss << "*Isotopic Vector Quantity Needed*" << endl; + map<ZAI ,double> IsotopicQuantityNeeded = GetIsotopicQuantityNeeded(); + for(it = IsotopicQuantityNeeded.begin(); it != IsotopicQuantityNeeded.end(); it++) + { + ss << (*it).first.Z() << " "; + ss << (*it).first.A() << " "; + ss << (*it).first.I() << " "; + ss << ": " << (*it).second; + ss << endl; + } + ss << endl; + } + if(DBPrint) + { + ss << "****Isotopic Vector DB****" << endl; + } +return ss.str(); +} +//________________________________________________________________________ +void IsotopicVector::PrintList(string option) const +{ + bool QuantityPrint = false; + bool DBPrint = false; + + QuantityPrint = true; + + if(QuantityPrint) + { + map<ZAI ,double> IsotopicQuantity = GetIsotopicQuantity(); + map<ZAI ,double >::iterator it; + for(it = IsotopicQuantity.begin();it != IsotopicQuantity.end(); it++) + { + cout << (*it).first.Z() << " "; + cout << (*it).first.A() << " "; + cout << (*it).first.I() << " "; + cout << endl; + } + cout << endl; + + } + if(DBPrint) + { + cout << "****Isotopic Vector DB****" << endl; + } + +} + + + + diff --git a/source/branches/BaM/src/Makefile b/source/branches/BaM/src/Makefile new file mode 100755 index 000000000..277e7ee8e --- /dev/null +++ b/source/branches/BaM/src/Makefile @@ -0,0 +1,126 @@ +#################### CLASS main Makefile ######################### +# include config file + +include ../../config/Makefile.config +# Directory containing includes for CLASS +LOCALINC = ../include + +EQMINC = ../Model/Equivalence +IMINC = ../Model/Irradiation +XSMINC = ../Model/XS + + +######### nothing to change from here ######### +INCLUDES = $(LOCALINC)/*.hxx +LIBNAME = CLASSpkg +OBJS = CLASSLogger.o \ + ZAI.o ZAIDict.o \ + IsotopicVector.o IsotopicVectorDict.o \ + ZAIMass.o ZAIHeat.o ZAITox.o \ + CLASSNucleiFiliation.o \ + CLASSObject.o CLASSObjectDict.o\ + CLASSFacility.o CLASSFacilityDict.o\ + FabricationPlant.o FabricationPlantDict.o \ + Reactor.o ReactorDict.o \ + CLASSBackEnd.o CLASSBackEndDict.o\ + SeparationPlant.o SeparationPlantDict.o\ + Storage.o StorageDict.o\ + Pool.o PoolDict.o\ + DecayDataBank.o \ + DynamicalSystem.o\ + IrradiationModel.o \ + EquivalenceModel.o \ + XSModel.o \ + CLASSFuel.o\ + PhysicsModels.o \ + EvolutionData.o EvolutionDataDict.o \ + CLASSFuelPlan.o\ + Scenario.o + +OBJMODEL = $(EQMINC)/EQM_PWR_MLP_MOX.o $(EQMINC)/EQM_PWR_MLP_MOX_Am.o \ + $(EQMINC)/EQM_PWR_QUAD_MOX.o $(EQMINC)/EQM_PWR_POL_UO2.o\ + $(EQMINC)/EQM_PWR_LIN_MOX.o $(EQMINC)/EQM_FBR_BakerRoss_MOX.o $(EQMINC)/EQM_MLP_Kinf.o\ + $(EQMINC)/EQM_FBR_MLP_Keff.o $(EQMINC)/EQM_FBR_MLP_Keff_BOUND.o\ + $(XSMINC)/XSM_MLP.o $(XSMINC)/XSM_CLOSEST.o \ + $(IMINC)/IM_RK4.o $(IMINC)/IM_Matrix.o + + +ROOTOBJS = CLASSLogger.o \ + ZAI.o ZAIDict.o \ + IsotopicVector.o IsotopicVectorDict.o \ + ZAIMass.o ZAIHeat.o ZAITox.o \ + CLASSNucleiFiliation.o \ + CLASSObject.o CLASSObjectDict.o\ + CLASSFacility.o CLASSFacilityDict.o\ + Reactor.o ReactorDict.o \ + FabricationPlant.o FabricationPlantDict.o \ + CLASSBackEnd.o CLASSBackEndDict.o\ + Storage.o StorageDict.o\ + Pool.o PoolDict.o\ + SeparationPlant.o SeparationPlantDict.o\ + DecayDataBank.o \ + IrradiationModel.o \ + CLASSFuel.o\ + EvolutionData.o EvolutionDataDict.o \ + CLASSFuelPlan.o\ + PhysicsModels.o + + +CXXFLAGS += -I$(LOCALINC) $(ROOTCFLAGS) +LD = $(CXX) +LIBS = -L$(LIBDIR) $(ROOTLIBS) -lTMVA $(OMPLIB) +LDFLAGS += -shared + +all: $(OBJS) $(OBJMODEL) + $(LD) $(LDFLAGS) $(OBJS) $(OBJMODEL) $(LIBS) -o $(LIBDIR)/lib$(LIBNAME).so + @echo "lib$(LIBNAME).so done" + $(LD) $(LDFLAGS) $(ROOTOBJS) $(LIBS) -o $(LIBDIR)/lib$(LIBNAME)_root.so + @echo "lib$(LIBNAME)_root.so done" + +clean: + @rm -vf $(OBJS) $(OBJMODEL) *~ core *Dict.cxx *Dict.h + + +install: + @ln -sf ../Model/* ../include/ + + + +CLASSObjectDict.cxx: $(LOCALINC)/CLASSObject.hxx + rootcint -f $@ -c $^ + +CLASSFacilityDict.cxx: $(LOCALINC)/CLASSFacility.hxx + rootcint -f $@ -c $^ + +CLASSBackEndDict.cxx: $(LOCALINC)/CLASSBackEnd.hxx + rootcint -f $@ -c $^ + +StorageDict.cxx: $(LOCALINC)/Storage.hxx + rootcint -f $@ -c $^ + +ReactorDict.cxx: $(LOCALINC)/Reactor.hxx + rootcint -f $@ -c $^ + +FabricationPlantDict.cxx: $(LOCALINC)/FabricationPlant.hxx + rootcint -f $@ -c $^ + +PoolDict.cxx: $(LOCALINC)/Pool.hxx + rootcint -f $@ -c $^ + +SeparationPlantDict.cxx: $(LOCALINC)/SeparationPlant.hxx + rootcint -f $@ -c $^ + +IsotopicVectorDict.cxx: $(LOCALINC)/IsotopicVector.hxx + rootcint -f $@ -c $^ + +ZAIDict.cxx: $(LOCALINC)/ZAI.hxx + rootcint -f $@ -c $^ + +EvolutionDataDict.cxx: $(LOCALINC)/EvolutionData.hxx + rootcint -f $@ -c $^ + + +.SUFFIXES: .cxx + +%.o: %.cxx $(INCLUDES) + $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c $*.cxx -o $*.o diff --git a/source/branches/BaM/src/PhysicsModels.cxx b/source/branches/BaM/src/PhysicsModels.cxx new file mode 100644 index 000000000..c441edd8c --- /dev/null +++ b/source/branches/BaM/src/PhysicsModels.cxx @@ -0,0 +1,57 @@ +#include "PhysicsModels.hxx" + +//________________________________________________________________________ +// +// PhysicsModels +// +// +// +// +//________________________________________________________________________ + + + +PhysicsModels::PhysicsModels():CLASSObject() +{ + + fXSModel = 0; + fEquivalenceModel = 0; + fIrradiationModel = 0; + + +} +//________________________________________________________________________ +PhysicsModels::PhysicsModels(XSModel* XS, EquivalenceModel* EM, IrradiationModel* IM ):CLASSObject() +{ + + fXSModel = XS; + fEquivalenceModel = EM; + fIrradiationModel = IM; + + int Z_ZAIThreshold = fIrradiationModel->GetZAIThreshold(); + fXSModel->SetZAIThreshold(Z_ZAIThreshold); + + +} +//________________________________________________________________________ +PhysicsModels::PhysicsModels(CLASSLogger* log, XSModel* XS, EquivalenceModel* EM, IrradiationModel* IM ):CLASSObject(log) +{ + + fXSModel = XS; + fEquivalenceModel = EM; + fIrradiationModel = IM; + + int Z_ZAIThreshold = fIrradiationModel->GetZAIThreshold(); + fXSModel->SetZAIThreshold(Z_ZAIThreshold); + + +} + +//________________________________________________________________________ +EvolutionData PhysicsModels::GenerateEvolutionData(IsotopicVector IV, double cycletime, double Power) +{ + fXSModel->isIVInDomain(IV); + + return fIrradiationModel->GenerateEvolutionData(IV, fXSModel->GetCrossSections(IV), Power, cycletime); +} +//________________________________________________________________________ diff --git a/source/branches/BaM/src/Pool.cxx b/source/branches/BaM/src/Pool.cxx new file mode 100755 index 000000000..88981155a --- /dev/null +++ b/source/branches/BaM/src/Pool.cxx @@ -0,0 +1,226 @@ +#include "Pool.hxx" + +#include "IsotopicVector.hxx" +#include "Storage.hxx" +#include "Scenario.hxx" +#include "CLASSLogger.hxx" + +#include <sstream> +#include <string> +#include <iostream> +#include <cmath> +#include <algorithm> + +//________________________________________________________________________ +// +// Pool +// +// +// +// +//________________________________________________________________________ +ClassImp(Pool) + + +Pool::Pool():CLASSBackEnd(8) +{ + fOutBackEndFacility = 0; + SetName("P_Pool."); +} + + //________________________________________________________________________ +Pool::Pool(CLASSLogger* log, cSecond coolingtime):CLASSBackEnd(log, coolingtime, 8) +{ + DBGL + + + fCycleTime = (cSecond)coolingtime; + fPutToWaste = true; + fCoolingLastIndex = 0; + + fOutBackEndFacility = 0; + SetName("P_Pool."); + + + INFO << " A new Pool has been define :" << endl; + INFO << "\t The Cooling Time set at\t " << (double)(fCycleTime/cYear) << " year" << endl; + WARNING << " All Cooled Fuel goes directly to WASTE after cooling !! " << endl; + + DBGL + +} + +//________________________________________________________________________ +Pool::Pool(CLASSLogger* log, CLASSBackEnd* storage, cSecond coolingtime):CLASSBackEnd(log, coolingtime, 8) +{ + DBGL + + fOutBackEndFacility = storage; + SetIsStorageType(false); + + fPutToWaste = false; + fCoolingLastIndex = 0; + SetName("P_Pool."); + + + + INFO << " A new Pool has been define :" << endl; + INFO << "\t The Cooling Time set at\t " << (double)(fCycleTime/cYear) << " year" << endl; + + DBGL + +} + +//________________________________________________________________________ +Pool::~Pool() +{ + + +} + +//________________________________________________________________________ +//________________________________________________________________________ +void Pool::SetIVArray(vector<IsotopicVector> ivarray) +{ + INFO << "This method as no effect !!!" << endl; + INFO << "Use SetIVArray(vector<IsotopicVector> ivarray, vector<cSecond>n timearray) unstead!!!!" << endl; +} + + +//________________________________________________________________________ +void Pool::SetIVArray(vector<IsotopicVector> ivarray, vector<cSecond> timearray) +{ + fIVArray = ivarray; + fIVArrayArrivalTime = timearray; + +} +//________________________________________________________________________ +// Add Temporary IV : +// Cooling +// +//________________________________________________________________________ +void Pool::AddIV(IsotopicVector IV) +{ + + fIVArray.push_back(IV); + fInsideIV += IV; + fIVArrayArrivalTime.push_back(fInternalTime); + fCoolingLastIndex++; + fCoolingIndex.push_back(fCoolingLastIndex); + + AddCumulativeIVIn(IV); + +} + + +//________________________________________________________________________ +void Pool::RemoveIVCooling(int i) //!< Remove a Cooling IsotopicVector +{ + AddCumulativeIVOut(fIVArray[i]); + + fIVArray.erase(fIVArray.begin()+i); + fIVArrayArrivalTime.erase( fIVArrayArrivalTime.begin()+i); + fCoolingIndex.erase(fCoolingIndex.begin()+i); + UpdateInsideIV(); +} + + + + +//________________________________________________________________________ +// Time Action with the reste of the Universe : +// Out Storage +// Evolution : +// Cooling +//________________________________________________________________________ + + + + +//________________________________________________________________________ +void Pool::CoolingEvolution(cSecond t) +{ +DBGL + + if(t == fInternalTime && t != 0) return; + int RemainingCoolingTime; + cSecond EvolutionTime = t - fInternalTime; + +#pragma omp parallel for + for ( int i = 0 ; i < (int)fIVArray.size() ; i++) + { + if ( abs(t - fIVArrayArrivalTime[i] - fCycleTime) < 3600 ) // ">" should not append, only " = " is normal... + { + if (t - fIVArrayArrivalTime[i] > fCycleTime) // Warning & Quit + { + ERROR << " Cooling Step : " << t/cYear << " :" << " an evolution Step is probably missing ! " << " " << endl; + exit (1); + } + + RemainingCoolingTime = fCycleTime - (fInternalTime - fIVArrayArrivalTime[i]); + //Cooling Decay + fIVArray[i] = GetDecay( fIVArray[i], RemainingCoolingTime); + + +#pragma omp critical(DeleteCoolingIVPB) + {fCoolingEndOfCycle.push_back(i);} + + } + else if ( fIVArrayArrivalTime[i] != t ) + { + fIVArray[i] = GetDecay( fIVArray[i] , EvolutionTime); + } + } +#pragma omp critical(DeleteCoolingIVPB) + {sort (fCoolingEndOfCycle.begin(), fCoolingEndOfCycle.end());} + +DBGL +} + + +//________________________________________________________________________ +void Pool::Evolution(cSecond t) +{ + + // Check if the Pool has been created ... + if(t == fInternalTime && t != 0) return; + // Make the evolution for the Cooling IV ... + CoolingEvolution(t); + // Update Inside IV + UpdateInsideIV(); + // ... And Finaly update the AbsoluteInternalTime + fInternalTime = t; + + + +} + + +//________________________________________________________________________ +void Pool::Dump() +{ +DBGL +//------ Cooling ------// + for(int i = (int)fCoolingEndOfCycle.size()-1; i >= 0 ; i--) // IV End Of Cooling + { + + int idx = fCoolingEndOfCycle[i]; // Get Index number + + if(!fPutToWaste) + fOutBackEndFacility->AddIV(fIVArray[idx]); + else + GetParc()->AddWaste(fIVArray[idx]); + + fCoolingEndOfCycle.erase(fCoolingEndOfCycle.begin()+i); // Remove index entry + RemoveIVCooling(idx); // Remove IVcooling + } + + if((int)fCoolingEndOfCycle.size() != 0 )// Control + { + ERROR << "Problem while Dumping Cooling" << endl; + exit (1); + } +DBGL +} + + diff --git a/source/branches/BaM/src/Reactor.cxx b/source/branches/BaM/src/Reactor.cxx new file mode 100755 index 000000000..a37839c42 --- /dev/null +++ b/source/branches/BaM/src/Reactor.cxx @@ -0,0 +1,640 @@ +#include "Reactor.hxx" + +#include "EvolutionData.hxx" +#include "Pool.hxx" +#include "FabricationPlant.hxx" +#include "Storage.hxx" +#include "Scenario.hxx" +#include "CLASSConstante.hxx" + +#include <iostream> +#include <cmath> +#include "../../config/config.hxx" +#include <typeinfo> + +//________________________________________________________________________ +// +// Reactor +// +// +// +// +//________________________________________________________________________ + + + +ClassImp(Reactor) + + +Reactor::Reactor():CLASSFacility(4) +{ + + SetName("R_Reactor."); + + fOutBackEndFacility = 0; + fStorage = 0; + fFabricationPlant = 0; + fFuelPlan = 0; + +} + +Reactor::Reactor(CLASSLogger* log):CLASSFacility(log, 4) +{ + DBGL + + fOutBackEndFacility = 0; + fStorage = 0; + fFabricationPlant = 0; + fFuelPlan = 0; + SetName("R_Reactor."); + + DBGL +} + +Reactor::Reactor(CLASSLogger* log, + CLASSBackEnd* Pool, + cSecond creationtime, + cSecond lifetime, + double power, double HMMass, double CapacityFactor ):CLASSFacility(log, creationtime, lifetime, 4) +{ + DBGL + (*this).SetName("R_Reactor."); + + + fIsStarted = false; + fIsShutDown = false; + fIsAtEndOfCycle = false; + + fStorage = 0; + fFabricationPlant = 0; + + fFixedFuel = true; + fIsStorage = false; + + fOutBackEndFacility = Pool; + + fPower = power * CapacityFactor; + fEfficiencyFactor = 0.33; + fElectricPower = fEfficiencyFactor*fPower; + + + fHeavyMetalMass = HMMass; + + fBurnUp = -1; + fCycleTime = (-1); + + fIVBeginCycle = fEvolutionDB.GetIsotopicVectorAt(0); + fIVInCycle = fEvolutionDB.GetIsotopicVectorAt(0); + fIVOutCycle = fEvolutionDB.GetIsotopicVectorAt( (cSecond)(fCycleTime/fEvolutionDB.GetPower()*fPower) ); + + + fFuelPlan = 0; + + INFO << " A Reactor has been define :" << endl; + INFO << "\t Fuel Composition is fixed (for now)! " << endl; + INFO << "\t Creation time set at \t " << ((double)GetCreationTime())/((double)cYear) << " year" << endl; + INFO << "\t Life time (Operating's Duration) set at \t " << ((double)GetLifeTime())/((double)cYear) << " year" << endl; + INFO << "\t The Effective Thermal Power is \t " << (double)(fPower *1e-6) << " MW (with Full Power " << power << " and " << CapacityFactor << " capacity factor)" << endl; + INFO << "\t The Heavy Metal Mass in the Core set at " << (double)(fHeavyMetalMass) << " tons" << endl << endl; + + DBGL + +} + +Reactor::Reactor(CLASSLogger* log, + FabricationPlant* fabricationplant, CLASSBackEnd* Pool, + cSecond creationtime, cSecond lifetime, + double Power, double HMMass, double CapacityFactor):CLASSFacility(log, creationtime, lifetime, 4) +{ + DBGL + (*this).SetName("R_Reactor."); + + + fStorage = 0; + fIsStarted = false; + fIsShutDown = false; + fIsAtEndOfCycle = false; + + fFabricationPlant = fabricationplant; + fFixedFuel = false; + + fOutBackEndFacility = Pool; + + fBurnUp = -1; + fHeavyMetalMass = HMMass; + fPower = Power*CapacityFactor; + fEfficiencyFactor = 0.33; + fElectricPower = fEfficiencyFactor*fPower; + + fCycleTime = -1; //BU in GWd/t + + fFuelPlan = 0; + + + + INFO << " A Reactor has been define :" << endl; + INFO << "\t Fuel Composition is not fixed (for now)! " << endl; + INFO << "\t Creation time set at \t " << ((double)GetCreationTime())/((double)cYear) << " year" << endl; + INFO << "\t Life time (Operating's Duration) set at \t " << ((double)GetLifeTime())/((double)cYear) << " year" << endl; + INFO << "\t The Effective Thermal Power is \t " << (double)(fPower *1e-6) << " MW (with Full Power " << Power << " and " << CapacityFactor << " capacity factor)" << endl; + INFO << "\t The Heavy Metal Mass in the Core set at " << (double)(fHeavyMetalMass) << " tons" << endl << endl; + + + DBGL + +} + + +Reactor::Reactor(CLASSLogger* log, PhysicsModels* fueltypeDB, FabricationPlant* fabricationplant, CLASSBackEnd* Pool, + cSecond creationtime, cSecond lifetime, + double Power, double HMMass, double BurnUp, double CapacityFactor):CLASSFacility(log, creationtime, lifetime, 4) +{ + DBGL + (*this).SetName("R_Reactor."); + + + fStorage = 0; + fIsStarted = false; + fIsShutDown = false; + fIsAtEndOfCycle = false; + + fFabricationPlant = fabricationplant; + + fFixedFuel = false; + + fOutBackEndFacility = Pool; + + fBurnUp = BurnUp; + fHeavyMetalMass = HMMass; + fPower = Power*CapacityFactor; + fEfficiencyFactor = 0.33; + fElectricPower = fEfficiencyFactor*fPower; + fCycleTime = (cSecond) (fBurnUp*1e9 / (fPower) * fHeavyMetalMass *3600*24); //BU in GWd/t + + fFuelPlan = new CLASSFuelPlan(log); + fFuelPlan->AddFuel(creationtime, CLASSFuel(fueltypeDB), fBurnUp); + + + + INFO << " A Reactor has been define :" << endl; + INFO << "\t Fuel Composition is not fixed ! " << endl; + INFO << "\t Creation time set at \t " << (double)(GetCreationTime()/cYear) << " year" << endl; + INFO << "\t Life time (Operating's Duration) set at \t " << ((double)GetLifeTime())/((double)cYear) << " year" << endl; + INFO << "\t The Effective Thermal Power is \t " << (double)(fPower *1e-6) << " MW (with Full Power " << Power << " and " << CapacityFactor << " capacity factor)" << endl; + INFO << "\t Burn-Up at end of Cycle set at \t " << (double)(fBurnUp) << " GWj/t" << endl; + INFO << "\t The corresponding Cycle Time is\t " << ((double)fCycleTime)/((double)cYear) << " year" << endl; + INFO << "\t The Heavy Metal Mass in the Core set at " << (double)(fHeavyMetalMass) << " tons" << endl << endl; + + + DBGL + +} + +Reactor::Reactor(CLASSLogger* log, PhysicsModels* fueltypeDB, + FabricationPlant* fabricationplant, + CLASSBackEnd* Pool, + cSecond creationtime, cSecond lifetime, cSecond cycletime, + double HMMass, double BurnUp):CLASSFacility(log, creationtime, lifetime, cycletime, 4) +{ + DBGL + (*this).SetName("R_Reactor."); + + + fIsStarted = false; + fIsShutDown = false; + fIsAtEndOfCycle = false; + + fStorage = 0; + + fFabricationPlant = fabricationplant; + fFixedFuel = false; + fBurnUp = BurnUp; + fHeavyMetalMass = HMMass; + + fOutBackEndFacility = Pool; + fPower = BurnUp*3600.*24. / (fCycleTime) * HMMass *1e9; //BU in GWd/t + fEfficiencyFactor = 0.33; + fElectricPower = fEfficiencyFactor*fPower; + + fFuelPlan = new CLASSFuelPlan(log); + fFuelPlan->AddFuel(creationtime, CLASSFuel(fueltypeDB), fBurnUp); + + + INFO << " A Reactor has been define :" << endl; + INFO << "\t Fuel Composition is not fixed ! " << endl; + INFO << "\t Creation time set at \t " << ((double)GetCreationTime())/((double)cYear) << " year" << endl; + INFO << "\t Life time (Operating's Duration) set at \t " << ((double)GetCreationTime())/((double)cYear) << " year" << endl; + INFO << "\t The Cycle Time set at\t " << ((double)fCycleTime)/((double)cYear) << " year" << endl; + INFO << "\t Burn-Up at end of Cycle set at \t " << (double)(fBurnUp) << " GWj/t" << endl; + INFO << "\t The corresponding Effective Thermal Power is \t " << (double)(fPower *1e-6) << " MW" << endl; + INFO << "\t The Heavy Metal Mass in the Core set at " << (double)(fHeavyMetalMass) << " tons" << endl << endl; + + + DBGL + +} + + +Reactor::Reactor(CLASSLogger* log, EvolutionData* evolutivedb, + CLASSBackEnd* Pool, + cSecond creationtime, + cSecond lifetime, + double power, double HMMass, double BurnUp, double CapacityFactor ):CLASSFacility(log, creationtime, lifetime, 4) +{ + DBGL + (*this).SetName("R_Reactor."); + + + fIsStarted = false; + fIsShutDown = false; + fIsAtEndOfCycle = false; + + fStorage = 0; + fFabricationPlant = 0; + + fFixedFuel = true; + fIsStorage = false; + + fOutBackEndFacility = Pool; + + fPower = power * CapacityFactor; + fEfficiencyFactor = 0.33; + fElectricPower = fEfficiencyFactor*fPower; + + fHeavyMetalMass = HMMass; + + double M0 = cZAIMass.GetMass( evolutivedb->GetIsotopicVectorAt(0.).GetActinidesComposition() ); + + fEvolutionDB = (*evolutivedb) * (fHeavyMetalMass/M0); + + fBurnUp = BurnUp; + fCycleTime = (cSecond) (fBurnUp*1e9 / (fPower) * fHeavyMetalMass *3600*24); + + fIVBeginCycle = fEvolutionDB.GetIsotopicVectorAt(0); + fIVInCycle = fEvolutionDB.GetIsotopicVectorAt(0); + fIVOutCycle = fEvolutionDB.GetIsotopicVectorAt( (cSecond)(fCycleTime/fEvolutionDB.GetPower()*fPower) ); + + fFuelPlan = new CLASSFuelPlan(log); + fFuelPlan->AddFuel(creationtime, CLASSFuel(evolutivedb), fBurnUp); + + INFO << " A Reactor has been define :" << endl; + INFO << "\t Fuel Composition is fixed ! " << endl; + INFO << "\t Creation time set at \t " << (double)(GetCreationTime()/cYear) << " year" << endl; + INFO << "\t Life time (Operating's Duration) set at \t " << ((double)GetLifeTime())/((double)cYear) << " year" << endl; + INFO << "\t The Cycle Time set at\t " << ((double)fCycleTime)/((double)cYear) << " year" << endl; + INFO << "\t The Effective Thermal Power is \t " << (double)(fPower *1e-6) << " MW (with Full Power " << power << " and " << CapacityFactor << " capacity factor)" << endl; + INFO << "\t The Heavy Metal Mass in the Core set at " << (double)(fHeavyMetalMass) << " tons" << endl << endl; + + DBGL +} + +Reactor::Reactor(CLASSLogger* log, EvolutionData* evolutivedb, + CLASSBackEnd* Pool, + cSecond creationtime, cSecond lifetime, cSecond cycletime, + double HMMass, double BurnUp ):CLASSFacility(log, creationtime, lifetime, cycletime, 4) +{ + DBGL + (*this).SetName("R_Reactor."); + + + fIsStarted = false; + fIsShutDown = false; + fIsAtEndOfCycle = false; + + fStorage = 0; + fFabricationPlant = 0; + + fFixedFuel = true; + fIsStorage = false; + + fOutBackEndFacility = Pool; + + fPower = BurnUp*3600.*24. / (fCycleTime) * HMMass *1e9; //BU in GWd/t + fEfficiencyFactor = 0.33; + fElectricPower = fEfficiencyFactor*fPower; + + fHeavyMetalMass = HMMass; + + double M0 = cZAIMass.GetMass( evolutivedb->GetIsotopicVectorAt(0.).GetActinidesComposition() ); + + fEvolutionDB = (*evolutivedb) * (fHeavyMetalMass/M0); + + fBurnUp = BurnUp; + + fIVBeginCycle = fEvolutionDB.GetIsotopicVectorAt(0); + fIVInCycle = fEvolutionDB.GetIsotopicVectorAt(0); + fIVOutCycle = fEvolutionDB.GetIsotopicVectorAt( (cSecond)(fCycleTime/fEvolutionDB.GetPower()*fPower) ); + + + fFuelPlan = new CLASSFuelPlan(log); + fFuelPlan->AddFuel(creationtime, CLASSFuel(evolutivedb), fBurnUp); + + INFO << " A Reactor has been define :" << endl; + INFO << "\t Fuel Composition is fixed ! " << endl; + INFO << "\t Creation time set at \t " << ((double)GetCreationTime())/((double)cYear) << " year" << endl; + INFO << "\t Life time (Operating's Duration) set at \t " << ((double)GetLifeTime())/((double)cYear) << " year" << endl; + INFO << "\t The Cycle Time set at\t " << ((double)fCycleTime)/((double)cYear) << " year" << endl; + INFO << "\t The Effective Thermal Power is \t " << (double)(fPower *1e-6) << " MW (with Full Power " << fPower << endl; + INFO << "\t The Heavy Metal Mass in the Core set at " << (double)(fHeavyMetalMass) << " tons" << endl << endl; + + DBGL +} + + +//________________________________________________________________________ +Reactor::~Reactor() +{ + + +} + +//________________________________________________________________________ +void Reactor::SetCycleTime(double cycletime) +{ + fCycleTime = (cSecond)cycletime; + + if(fFixedFuel == true) + { + fIVOutCycle = fEvolutionDB.GetIsotopicVectorAt(fCycleTime/fEvolutionDB.GetPower()*fPower); + fBurnUp = fPower*fCycleTime/3600./24./fHeavyMetalMass; + } + else + { + fBurnUp = fPower*fCycleTime/3600./24./fHeavyMetalMass; + } +} +//________________________________________________________________________ +void Reactor::SetPower(double Power) +{ + fPower = Power; + + if(fFixedFuel == true) + { + fCycleTime = (cSecond) (fBurnUp*1e9 / (fPower) * fHeavyMetalMass *3600*24); + fIVOutCycle = fEvolutionDB.GetIsotopicVectorAt( (cSecond)(fCycleTime/fEvolutionDB.GetPower()*fPower) ); + } + else + fCycleTime = (cSecond)(fBurnUp*1e9 / (fPower) * fHeavyMetalMass *3600*24); //BU in GWd/t + + +} +//________________________________________________________________________ +void Reactor::SetBurnUp(double BU) +{ + + fBurnUp = BU; + + if(fFixedFuel == true) + { + fCycleTime = (cSecond) (fBurnUp*1e9 / (fPower) * fHeavyMetalMass *3600*24); + fIVOutCycle = fEvolutionDB.GetIsotopicVectorAt( (cSecond)(fCycleTime/fEvolutionDB.GetPower()*fPower) ); + } + else + fCycleTime = (cSecond) (fBurnUp*1e9 / (fPower) * fHeavyMetalMass *3600*24); + +} + +//________________________________________________________________________ +void Reactor::SetEvolutionDB(EvolutionData evolutionDB) +{ + DBGL + + //fEvolutionDB.DeleteEvolutionDataCopy(); + + double M0 = cZAIMass.GetMass( evolutionDB.GetIsotopicVectorAt(0.).GetActinidesComposition() ); + fEvolutionDB = evolutionDB * (fHeavyMetalMass/M0); + + fIVOutCycle = fEvolutionDB.GetIsotopicVectorAt( (cSecond)(fCycleTime/fEvolutionDB.GetPower()*fPower) ); + fIVBeginCycle = fEvolutionDB.GetIsotopicVectorAt(0); + + DBGL + +} + +//________________________________________________________________________ +void Reactor::SetNewFuel(EvolutionData ivdb) +{ + DBGL + SetEvolutionDB(ivdb); + DBGL +} + +//________________________________________________________________________ +void Reactor::Evolution(cSecond t) +{ + DBGL + + + if( fIsShutDown || t < GetCreationTime() ) return; // Reactor stop or not started... + + if(Norme(fInsideIV) != 0 && fIsStarted) + { +#pragma omp critical(ParcPowerUpdate) + {GetParc()->AddToPower(fPower, fElectricPower);} + } + else if(fIsStarted) + { + WARNING << " Reactor should be working but have no Heavy Nucleus Inside. It's not working so have a zero power..." + << " Time : " << t/cYear << " years" << endl; + } + + + if( t < fInternalTime ) return; + if( t == fInternalTime && t != GetCreationTime() ) return; + + + + if( t == GetCreationTime() && !fIsStarted) // Start of the Reactor + { + fIsAtEndOfCycle = true; + fInsideIV = fIVBeginCycle; + fInternalTime = t; + fInCycleTime = 0; + + } + + // Check if the Reactor if started ... + if(!fIsStarted) return; // If the reactor just start don't need to make Fuel evolution + + + cSecond EvolutionTime = t - fInternalTime; // Calculation of the evolution time (relativ) + + + if( EvolutionTime + fInCycleTime == fCycleTime ) //End of Cycle + { + fIsAtEndOfCycle = true; + fInternalTime += EvolutionTime; // Update Internal Time + fInCycleTime += EvolutionTime; // Update InCycleTime + + if(t >= GetCreationTime() + GetLifeTime()) // if the Next Cycle don't 'Exist... + fIsShutDown = true; + + + } + else if(EvolutionTime + fInCycleTime < fCycleTime ) // During Cycle + { + + fInternalTime += EvolutionTime; // Update Internal Time + fInCycleTime += EvolutionTime; // Update InCycleTime + + fInsideIV = fEvolutionDB.GetIsotopicVectorAt( (cSecond)(fInCycleTime/fEvolutionDB.GetPower()*fPower) ); // update the fuel composition + if(t>= GetCreationTime() + GetLifeTime()) fIsShutDown = true; + } + else + { + // Evolution goes after the end of cycle.... check it + ERROR << " " << (*this).GetName() << endl; + ERROR << " Evolution Time is " << t << endl; + ERROR << " Evolution is too long! There is a problem in Reactor evolution at " << t/cYear << endl; + ERROR << " This is too long of : " << EvolutionTime + fInCycleTime - fCycleTime << endl; + ERROR << " I have spend " << fInCycleTime +EvolutionTime << " and should have been " << fCycleTime << endl; + exit(1); + } + + DBGL +} + +//________________________________________________________________________ +void Reactor::Dump() +{ + DBGL + + + if(fInternalTime < GetCreationTime()) return; + if(fIsShutDown && !fIsStarted) return; // Reactor stopped... + if(!fIsAtEndOfCycle && !fIsShutDown) return; + + // First trash the irradiated fuel + if(fIsAtEndOfCycle && !fIsShutDown ) + { + if(fIsStarted ) // A Cycle has already been done + { + fOutBackEndFacility->AddIV(fInsideIV); + AddCumulativeIVOut(fInsideIV); + } + else fIsStarted = true; // Just start the first cycle + + } + else if (fIsAtEndOfCycle && fIsShutDown ) //shutdown at end of Cycle + { + + fOutBackEndFacility->AddIV(fIVOutCycle); + AddCumulativeIVOut(fIVOutCycle); + fInsideIV.Clear(); + fInCycleTime = 0; + fIsStarted = false; // shut down the Reactor + } + else if (!fIsAtEndOfCycle && fIsShutDown ) //shutdown during Cycle + { + fOutBackEndFacility->AddIV(fInsideIV); + AddCumulativeIVOut(fInsideIV); + fInsideIV.Clear(); + fInCycleTime = 0; + fIsStarted = false; // shut down the Reactor + } + + + DBGL + + + // Get the new Fuel ! + pair<CLASSFuel, double> NextFuel = fFuelPlan->GetFuelAt(fInternalTime); + SetBurnUp((NextFuel).second); + + if( NextFuel.first.GetPhysicsModels() ) + fFixedFuel = false; + else if( NextFuel.first.GetEvolutionData() ) + fFixedFuel = true; + else + { + ERROR << typeid(NextFuel.first).name() << endl; + ERROR << "WRONG Fuel Format Correct it !! " << endl; + exit(1); + } + DBGL + + if(fFixedFuel ) + { + DBGL + if(fIsAtEndOfCycle && !fIsShutDown ) + { + SetEvolutionDB( *(NextFuel.first.GetEvolutionData()) ); + fIsAtEndOfCycle = false; + + + if(!GetParc()->GetStockManagement() && fIsStorage ) + { + IsotopicVector BuildIVtmp ; + IsotopicVector OutIncomePart; + + //Get The Storage Compostion + BuildIVtmp.Add(fStorage->GetInsideIV().GetIsotopicQuantity()); + //Get the rest after IVIn creation + BuildIVtmp -= fIVInCycle; + //Get the OutIncome part form this rest + OutIncomePart.Add(BuildIVtmp.GetIsotopicQuantityNeeded()) ; + //Take what you can from Storage... + fStorage->TakeFromStock( fIVInCycle - OutIncomePart); + //And Get the rest from OutIncome + GetParc()->AddOutIncome(OutIncomePart); + + } + else GetParc()->AddOutIncome(fIVInCycle); + + + fInsideIV = fIVBeginCycle; + AddCumulativeIVIn(fIVBeginCycle); + + fInCycleTime = 0; + } + DBGL + + } + else + { + DBGL + if(!GetParc()->GetStockManagement()) + { + ERROR << " Can't have unfixedFuel without stock management" << endl; + exit(1); + } + + if(fIsAtEndOfCycle && !fIsShutDown ) + { + fIsAtEndOfCycle = false; + SetNewFuel(fFabricationPlant->GetReactorEvolutionDB(GetId())); + fFabricationPlant->TakeReactorFuel(GetId()); + + fInsideIV = fIVBeginCycle; + AddCumulativeIVIn(fIVBeginCycle); + + fInCycleTime = 0; + } + + DBGL + + + + } + + DBGL +} + + + +//________________________________________________________________________ +cSecond Reactor::GetNextCycleTime(cSecond time) +{ + DBGL + cSecond LastCycle = fInternalTime - fInCycleTime; + + while ( LastCycle < time) + { + cSecond cycletime = (cSecond)(fFuelPlan->GetFuelAt(LastCycle).second*1e9 / (fPower) * fHeavyMetalMass *3600*24); + LastCycle += cycletime; + } + + DBGL + return LastCycle; +} + diff --git a/source/branches/BaM/src/Scenario.cxx b/source/branches/BaM/src/Scenario.cxx new file mode 100755 index 000000000..780e07c34 --- /dev/null +++ b/source/branches/BaM/src/Scenario.cxx @@ -0,0 +1,1051 @@ +#include "Scenario.hxx" +#include "CLASSMethod.hxx" + +#include <ctime> +#include "time.h" +#include <cmath> +#include <iomanip> +#include <fstream> +#include <sstream> +#include <algorithm> +#include "../../config/config.hxx" +#include "stdlib.h" + +#include "Storage.hxx" +#include "Reactor.hxx" +#include "CLASSBackEnd.hxx" +#include "Pool.hxx" +#include "FabricationPlant.hxx" +#include "SeparationPlant.hxx" +#include "CLASSLogger.hxx" + + +//________________________________________________________________________ +// +// CLASS +// +// +// +// +//________________________________________________________________________ + + + + +//________________________________________________________________________ +Scenario::Scenario(CLASSLogger* log, cSecond abstime):CLASSObject(log) +{ + + + fNewTtree = true; + fPrintStep = (cSecond)(cYear); // One Step per Year + fAbsoluteTime = abstime; + fStartingTime = fAbsoluteTime; + + fStockManagement = true; + fLogTimeStep = false; + + fOutputFileName = "CLASS_Default.root"; + fOutputTreeName = "Data"; + fOutFile = 0; + fOutT = 0; + + fParcPower = 0; + + fZAIThreshold = -1; + fOldProgressBar = false; + + // Warning + + + INFO << " Parc has been define :" << endl; + INFO << " Print set at : " << (double)(fPrintStep/cYear) << " year" << endl; + INFO << " StockManagement set at : true" << endl; + INFO << " OutPut will be in \"" << fOutputFileName << "\" File and \"" << fOutputTreeName << "\" TTree" << endl; + INFO << " Log will be in " << GetLog()->GetCLASSLoggerName() << endl; + + + +} +//________________________________________________________________________ +Scenario::Scenario( cSecond abstime, CLASSLogger* log):CLASSObject(log) +{ + + + fNewTtree = true; + fPrintStep = (cSecond)(cYear); // One Step per Year + fAbsoluteTime = abstime; + fStartingTime = fAbsoluteTime; + + fStockManagement = true; + fLogTimeStep = false; + + fOutputFileName = "CLASS_Default.root"; + fOutputTreeName = "Data"; + fOutFile = 0; + fOutT = 0; + + fParcPower = 0; + + fZAIThreshold = -1; + fOldProgressBar = false; + + // Warning + + + INFO << " Parc has been define :" << endl; + INFO << " Print set at : " << (double)(fPrintStep/cYear) << " year" << endl; + INFO << " StockManagement set at : true" << endl; + INFO << " OutPut will be in \"" << fOutputFileName << "\" File and \"" << fOutputTreeName << "\" TTree" << endl; + INFO << " Log will be in " << GetLog()->GetCLASSLoggerName() << endl; + + + +} +//________________________________________________________________________ +Scenario::Scenario( cSecond abstime):CLASSObject(new CLASSLogger("CLASS_OUTPUT.log")) +{ + + + fNewTtree = true; + fPrintStep = (cSecond)(cYear); // One Step per Year + fAbsoluteTime = abstime; + fStartingTime = fAbsoluteTime; + + fStockManagement = true; + fLogTimeStep = false; + + fOutputFileName = "CLASS_Default.root"; + fOutputTreeName = "Data"; + fOutFile = 0; + fOutT = 0; + + fParcPower = 0; + + fZAIThreshold = -1; + fOldProgressBar = false; + + // Warning + + + INFO << " Parc has been define :" << endl; + INFO << " Print set at : " << (double)(fPrintStep/cYear) << " year" << endl; + INFO << " StockManagement set at : true" << endl; + INFO << " OutPut will be in \"" << fOutputFileName << "\" File and \"" << fOutputTreeName << "\" TTree" << endl; + INFO << " Log will be in " << GetLog()->GetCLASSLoggerName() << endl; + + + +} +//________________________________________________________________________ +Scenario::~Scenario() +{ + +#pragma omp single + {CloseOutputTree();} + + +} +//________________________________________________________________________ +void Scenario::AddPool(Pool* Pool) +{ + + + fPool.push_back(Pool); + fPool.back()->SetParc(this); + fPool.back()->SetDecayDataBank( (*this).GetDecayDataBase() ); + fPool.back()->SetId((int)fPool.size()-1); + fPool.back()->SetInternalTime(fAbsoluteTime); + + + string Pool_name = fPool.back()->GetName(); + if(Pool_name == "P_Pool.") + { + Pool_name = "P_Pool"; + Pool_name += dtoa(fPool.back()->GetId()); + Pool_name += "."; + fPool.back()->SetName(Pool_name.c_str()); + } + else + { + string name_tmp = Pool_name; + Pool_name = "P_"; + Pool_name += name_tmp; + Pool_name += "."; + fPool.back()->SetName(Pool_name.c_str()); + } + + if(!fNewTtree) + fOutT->Branch(fPool.back()->GetName(), "Pool", &fPool.back()); + + +} +//________________________________________________________________________ +void Scenario::AddReactor(Reactor* reactor) +{ + + fReactor.push_back(reactor); + fReactor.back()->SetParc(this); + fReactor.back()->SetId((int)fReactor.size()-1); + fReactor.back()->SetInternalTime(fAbsoluteTime); + + + string Reactor_name = fReactor.back()->GetName(); + if(Reactor_name == "R_Reactor.") + { + Reactor_name = "R_Reactor"; + Reactor_name += dtoa(fReactor.back()->GetId()); + Reactor_name += "."; + fReactor.back()->SetName(Reactor_name.c_str()); + } + else + { + string name_tmp = Reactor_name; + Reactor_name = "R_"; + Reactor_name += name_tmp; + Reactor_name += "."; + fReactor.back()->SetName(Reactor_name.c_str()); + } + + if(!fNewTtree) + fOutT->Branch(fReactor.back()->GetName(), "Reactor", &fReactor.back()); + + +} +//________________________________________________________________________ +void Scenario::AddStorage(Storage* storage) +{ + + fStorage.push_back(storage); + fStorage.back()->SetParc(this); + fStorage.back()->SetDecayDataBank( (*this).GetDecayDataBase() ); + fStorage.back()->SetId((int)fStorage.size()-1); + fStorage.back()->SetInternalTime(fAbsoluteTime); + + string Storage_name = fStorage.back()->GetName(); + + if(Storage_name == "S_Storage.") + { + Storage_name = "S_Storage"; + Storage_name += dtoa(fStorage.back()->GetId()); + Storage_name += "."; + fStorage.back()->SetName(Storage_name.c_str()); + } + else + { + string name_tmp = Storage_name; + Storage_name = "S_"; + Storage_name += name_tmp; + Storage_name += "."; + fStorage.back()->SetName(Storage_name.c_str()); + } + + if(!fNewTtree) + fOutT->Branch(fStorage.back()->GetName(), "Storage", &fStorage.back()); + + +} +//________________________________________________________________________ +void Scenario::AddFabricationPlant(FabricationPlant* fabricationplant) +{ + + fFabricationPlant.push_back(fabricationplant); + fFabricationPlant.back()->SetParc(this); + fFabricationPlant.back()->SetDecayDataBank( (*this).GetDecayDataBase() ); + fFabricationPlant.back()->SetId((int)fStorage.size()-1); + fFabricationPlant.back()->SetInternalTime(fAbsoluteTime); + + + string FP_name = fFabricationPlant.back()->GetName(); + if(FP_name == "F_FabricationPlant.") + { + FP_name = "F_FabricationPlant"; + FP_name += dtoa(fFabricationPlant.back()->GetId()); + FP_name += "."; + fFabricationPlant.back()->SetName(FP_name.c_str()); + } + else + { + string name_tmp = FP_name; + FP_name = "F_"; + FP_name += name_tmp; + FP_name += "."; + fFabricationPlant.back()->SetName(FP_name.c_str()); + } + + if(!fNewTtree) + fOutT->Branch(fFabricationPlant.back()->GetName(), "FabricationPlant", &fFabricationPlant.back()); +} +//________________________________________________________________________ +void Scenario::AddSeparationPlant(SeparationPlant* SeparationPlant) +{ + + + fSeparationPlant.push_back(SeparationPlant); + fSeparationPlant.back()->SetParc(this); + fSeparationPlant.back()->SetDecayDataBank( (*this).GetDecayDataBase() ); + fSeparationPlant.back()->SetId((int)fSeparationPlant.size()-1); + fSeparationPlant.back()->SetInternalTime(fAbsoluteTime); + + + string SeparationPlant_name = fSeparationPlant.back()->GetName(); + if(SeparationPlant_name == "C_SepPlant.") + { + SeparationPlant_name = "C_SepPlant"; + SeparationPlant_name += dtoa(fSeparationPlant.back()->GetId()); + SeparationPlant_name += "."; + fSeparationPlant.back()->SetName(SeparationPlant_name.c_str()); + } + else + { + string name_tmp = SeparationPlant_name; + SeparationPlant_name = "C_"; + SeparationPlant_name += name_tmp; + SeparationPlant_name += "."; + fSeparationPlant.back()->SetName(SeparationPlant_name.c_str()); + } + + if(!fNewTtree) + fOutT->Branch(fSeparationPlant.back()->GetName(), "SeparationPlant", &fSeparationPlant.back()); + + +} + + +//________________________________________________________________________ + + +//________________________________________________________________________ +void Scenario::BuildTimeVector(cSecond t) +{ + DBGL + + fTimeStep.clear(); + fTimeStep.insert( pair<cSecond ,int>(t,1) ); + //********* Printing Step *********// + { + DBGL + cSecond step = fStartingTime; + + if(step >= fAbsoluteTime ) + fTimeStep.insert( pair<cSecond ,int>(step,1) ); + step += fPrintStep; + cSecond timescale = 1; + + do + { + + if(step >= fAbsoluteTime ) + fTimeStep.insert( pair<cSecond ,int>(step,1) ); + + if(fLogTimeStep) + { + timescale *= 10; + step = fPrintStep*timescale; + } + else + step += fPrintStep; + + } + while( step < t ); + DBGL + } + + + for(int i = 0; i < (int)fReactor.size();i++) + { + DBGL + cSecond R_StartingTime = fReactor[i]->GetCreationTime(); + cSecond R_ShutDownTime = fReactor[i]->GetCreationTime() + fReactor[i]->GetLifeTime(); + + double R_Power = fReactor[i]->GetPower(); + double R_HMMass = fReactor[i]->GetHeavyMetalMass(); + pair<CLASSFuel, double> R_Fuel = fReactor[i]->GetFuelPlan()->GetFuelAt(R_StartingTime); + + double R_BU = R_Fuel.second; + cSecond R_CycleTime = (cSecond) (R_BU*1e9 / R_Power * R_HMMass *3600*24); + if(R_CycleTime == 0) + { + ERROR << " Be carefull a reactor cycletime is set to 0 second....\"\n" << endl; + exit(1); + } + + int R_FacilityType = fReactor[i]->GetFacilityType(); + + + cSecond F_CycleTime = 0; + + + cSecond step = R_StartingTime; + + map< cSecond, int > R_BackEndTimePath = fReactor[i]->GetOutBackEndFacility()->GetTheBackEndTimePath(); + + if( R_Fuel.first.GetPhysicsModels() ) + F_CycleTime = fReactor[i]->GetFabricationPlant()->GetCycleTime(); + + + //********* Reactor Evolution Step *********// + // ShutDown of a reactor + + // Test if the shutdown of the reactor is after the actual time (AbsolutreTime) and before the end of the evolution (t) + if( R_ShutDownTime < t ) + { + // Shutdown + if( R_ShutDownTime > fAbsoluteTime) + { + pair< map<cSecond, int>::iterator, bool > IResult; + IResult = fTimeStep.insert( pair<cSecond ,int>(R_ShutDownTime, 2) ); + if( !IResult.second ) + IResult.first->second |= 2; + } + + // BackEnd fuel Cycle after reactor Shutdown + + map< cSecond, int >::iterator TV_it; // the time vector iterator + + // Loop on the BackEnd fuel Cycle Time path + for(TV_it = R_BackEndTimePath.begin(); TV_it != R_BackEndTimePath.end(); TV_it++) + { + // Test if each step of the Fuel Cycle BackEnd is after the actual time (AbsolutreTime) and before the end of the evolution (t) + if( R_ShutDownTime + (*TV_it).first >= fAbsoluteTime && R_ShutDownTime + (*TV_it).first <= t) + { + pair< map<cSecond, int>::iterator, bool > IResult; + IResult = fTimeStep.insert( pair<cSecond ,int>(R_ShutDownTime + (*TV_it).first, (*TV_it).second) ); + if( !IResult.second ) + IResult.first->second |= (*TV_it).second; + } + } + + + } + + // Start the reactor and the Fuel Fabrication + if(step >= fAbsoluteTime && step <= t && step < R_ShutDownTime) + { + pair< map<cSecond, int>::iterator, bool > IResult; + IResult = fTimeStep.insert( pair<cSecond ,int>(step, R_FacilityType) ); + if( !IResult.second ) + IResult.first->second |= R_FacilityType; + } + + + //********* FabricationPlant Evolution Step *********// + + + if( R_Fuel.first.GetPhysicsModels() ) + { + + fReactor[i]->GetFabricationPlant()->AddReactor( i, step ); + + + F_CycleTime = fReactor[i]->GetFabricationPlant()->GetCycleTime(); + + if(step - F_CycleTime >= fAbsoluteTime && step - F_CycleTime <= t && step < R_ShutDownTime) + { // Set End of reactor cycle + pair< map<cSecond, int>::iterator, bool > IResult; + IResult = fTimeStep.insert( pair<cSecond ,int>(step - F_CycleTime,16) ); + if( !IResult.second ) IResult.first->second |= 16; + } + else if( step - F_CycleTime < fStartingTime ) + { + ERROR << " Can't Build Fuel before Scenario's start\"\n" << endl; + exit(1); + } + } + + step += R_CycleTime; + //Prepare the first Cycle + R_Fuel = fReactor[i]->GetFuelPlan()->GetFuelAt(step); + + R_BU = fReactor[i]->GetFuelPlan()->GetFuelAt(step).second; + R_CycleTime = (cSecond) (R_BU*1e9 / R_Power * R_HMMass *3600*24); + + if(R_CycleTime == 0) + { + ERROR << " Be carefull a reactor cycletime is set to 0 second....\"\n" << endl; + exit(1); + } + + + while( step <= t && step <= R_ShutDownTime ) + { + DBGL + + // FabricationPlant Evolution Step + if( R_Fuel.first.GetPhysicsModels() ) + { + fReactor[i]->GetFabricationPlant()->AddReactor( i, step ); + + F_CycleTime = fReactor[i]->GetFabricationPlant()->GetCycleTime(); + + if(step - F_CycleTime >= fAbsoluteTime && step - F_CycleTime <= t && step < R_ShutDownTime) + { // Set End of reactor cycle + pair< map<cSecond, int>::iterator, bool > IResult; + IResult = fTimeStep.insert( pair<cSecond ,int>(step - F_CycleTime,16) ); + if( !IResult.second ) IResult.first->second |= 16; + } + } + + + if(step >= fAbsoluteTime && step <= t && step < R_ShutDownTime) + { // Set End of reactor cycle + pair< map<cSecond, int>::iterator, bool > IResult = fTimeStep.insert( pair<cSecond ,int>(step,4) ); + if( !IResult.second ) IResult.first->second |= 4; + } + + // End/Start Of Reactor Cycle Step // + + + map< cSecond, int >::iterator TV_it; // the time vector iterator + // BackEnd fuel Cycle + // Loop on the BackEnd fuel Cycle Time path + for(TV_it = R_BackEndTimePath.begin(); TV_it != R_BackEndTimePath.end(); TV_it++) + { + + if(step + (*TV_it).first >= fAbsoluteTime && + step + (*TV_it).first <= t) + { // Test if each step of the Fuel Cycle BackEnd is after the actual time (AbsolutreTime) and before the end of the evolution (t) + pair< map<cSecond, int>::iterator, bool > IResult; + + IResult = fTimeStep.insert( pair<cSecond ,int>(step + (*TV_it).first, (*TV_it).second) ); + if( !IResult.second ) + IResult.first->second |= (*TV_it).second; + } + } + + + step += R_CycleTime; + + // Update to the next fuel + R_Fuel = fReactor[i]->GetFuelPlan()->GetFuelAt(step); + + R_BU = fReactor[i]->GetFuelPlan()->GetFuelAt(step).second; + R_CycleTime = (cSecond) (R_BU*1e9 / R_Power * R_HMMass *3600*24); + if(R_CycleTime == 0) + { + ERROR << " Be carefull a reactor cycletime is set to 0 second....\"\n" << endl; + exit(1); + } + + DBGL + } + + + + DBGL + } + //****** Print the Time Index ******// + ofstream TimeStepfile("CLASS_TimeStep", ios_base::app); // Open the File + + if(!TimeStepfile) + WARNING << " Can't open \" CLASS_TimeStep \"\n" << endl; + + map<cSecond ,int >::iterator it; + for( it = fTimeStep.begin(); it != fTimeStep.end(); it++) + TimeStepfile << (*it).first << " " << (*it).second << endl; + + DBGL +} + + +//________________________________________________________________________ +//___________________________ Evolution Method ___________________________ +//________________________________________________________________________ + +void Scenario::BackEndEvolution() +{ + DBGL + StorageEvolution(); + PoolEvolution(); + + PoolDump(); + DBGL +} +//________________________________________________________________________ +void Scenario::PoolEvolution() +{ + DBGL +#pragma omp parallel for + for(int i = 0; i < (int) fPool.size();i++) + fPool[i]->Evolution(fAbsoluteTime); + + DBGL +} +//________________________________________________________________________ +void Scenario::StorageEvolution() +{ + DBGL +#pragma omp parallel for + for(int i = 0; i < (int) fStorage.size();i++) + fStorage[i]->Evolution(fAbsoluteTime); + + DBGL +} +//________________________________________________________________________ +void Scenario::FabricationPlantEvolution() +{ + DBGL + //#pragma omp parallel for + for(int i = 0; i < (int) fFabricationPlant.size();i++) + fFabricationPlant[i]->Evolution(fAbsoluteTime); + + DBGL +} +//________________________________________________________________________ +void Scenario::PoolDump() +{ + DBGL + for(int i = 0; i < (int) fPool.size();i++) + fPool[i]->Dump(); + DBGL +} + +//________________________________________________________________________ +void Scenario::ReactorEvolution() +{ + DBGL + fParcPower = 0; + fParcElectricPower = 0; +#pragma omp parallel for + for(int i = 0; i < (int)fReactor.size(); i++) + fReactor[i]->Evolution(fAbsoluteTime); + + + for(int i = 0; i < (int)fReactor.size(); i++) + fReactor[i]->Dump(); + + DBGL +} + +//________________________________________________________________________ +void Scenario::Evolution(cSecond t) +{ + DBGL + fCloverCount = 0; + PrintCLASSPresentation(); + + BuildTimeVector(t); + + if(fNewTtree) + { + OpenOutputTree(); + OutAttach(); + UpdateParc(); + fOutT->Fill(); + } + + map<cSecond ,int >::iterator it; + for(it = fTimeStep.begin(); it != fTimeStep.end(); it++) + { + + fWaste = fDecayDataBase->GetDecay(fWaste, (*it).first - fAbsoluteTime); + fAbsoluteTime = (*it).first; + + if( (*it).second & 1 || (*it).second & 2 || (*it).second & 4 || (*it).second & 8 || (*it).second & 16 ) + BackEndEvolution(); + + if( (*it).second & 1 || (*it).second & 2 || (*it).second & 4 || (*it).second & 16 ) + FabricationPlantEvolution(); + + if( (*it).second & 1 || (*it).second & 2 || (*it).second & 4 ) + ReactorEvolution(); + + if( (*it).second & 1 || it == fTimeStep.begin() ) + { +#pragma omp single + { + if(fZAIThreshold != -1) + ApplyZAIThreshold(); + + UpdateParc(); + fOutT->Fill(); + ProgressPrintout( (cSecond)t); + } + } + + } + cout<<"Calculation complete successfully "<<endl<<endl; + + DBGL +} + +//_______________________________________________________________________ +//______________________________ Out Method ______________________________ +//________________________________________________________________________ + +//________________________________________________________________________ +void Scenario::OldProgressPrintout(cSecond t) +{ + double Time = (fAbsoluteTime-fStartingTime)/cYear ; + double Total = (t-fStartingTime)/cYear; + + // Reset the line + for(int i = 0; i < 10; i++) + cout << " "; + cout << flush ; + + cout << "\r["; + for(int i = 0; i < (int)(Time/Total*20.0); i++) + cout << "|"; + for(int i = 20; i >= (int)(Time/Total*20.0); i--) + cout << "-"; + cout << "] "; + + //cout << " Processed "; + if (Time < 10) cout << " "; + if (Time < 100) cout << " "; + cout << (int)Time << " / " << (int)Total << " Years \r"; + if( fLog->GetVerboseLVL() < 2) cout << flush; + else cout << endl; + +} +//________________________________________________________________________ +void Scenario::ProgressPrintout(cSecond t) +{ + double Time = (fAbsoluteTime-fStartingTime)/cYear ; + double Total = (t-fStartingTime)/cYear; + + if(fOldProgressBar) + OldProgressPrintout(t); + + else + { + system("clear"); + /****Printing CLASS info + nuclear clover****/ + if(fCloverCount>3) + fCloverCount=0; + PrintClover(fCloverCount); + fCloverCount++; + + /****Printing Progression bar r****/ + static int ProgressBarlength = 47; + cout << "â•"; + for(int i = 0; i < ProgressBarlength; i++) + cout <<"─" ; + + cout << "â•®"<<endl; + cout<<"│"; + + stringstream Completed ; Completed << "\033[42m"; + for(int i = 0; i < (int)(Time/Total*ProgressBarlength); i++) + Completed<< " "; + + Completed << "\033[0m"; + + for(int i = ProgressBarlength; i >= (int)(Time/Total*ProgressBarlength); i--) + Completed << " "; + + cout<<Completed.str(); + cout<<"│"<<endl; + + cout << "â•°"; + for(int i = 0; i < ProgressBarlength; i++) + cout <<"─" ; + cout << "╯"<<endl; + + + if (Time < 10) cout << " "; + if (Time < 100) cout << " "; + cout << (int)Time << " / " << (int)Total << " Years"; + cout << endl<<endl; + } + + INFO << " Proccessed " << (int)Time << " / " << (int)Total << " Years \r" << endl; + +} +//________________________________________________________________________ +void Scenario::PrintCLASSPresentation() +{ + cout<<endl; + cout<<"â•â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â•®"<<endl; + cout<<"│ ██████╗██╗ █████╗ ███████╗███████╗ │"<<endl; + cout<<"│ ██╔â•â•â•â•â•â–ˆâ–ˆâ•‘ ██╔â•â•â–ˆâ–ˆâ•—██╔â•â•â•â•â•â–ˆâ–ˆâ•”â•â•â•â•â• │"<<endl; + cout<<"│ ██║ ██║ ███████║███████╗███████╗ │"<<endl; + cout<<"│ ██║ ██║ ██╔â•â•â–ˆâ–ˆâ•‘â•šâ•â•â•â•â–ˆâ–ˆâ•‘â•šâ•â•â•â•â–ˆâ–ˆâ•‘ │"<<endl; + cout<<"│ ╚██████╗███████╗██║ ██║███████║███████║ │"<<endl; + cout<<"│ â•šâ•â•â•â•â•â•â•šâ•â•â•â•â•â•â•â•šâ•â• â•šâ•â•â•šâ•â•â•â•â•â•â•â•šâ•â•â•â•â•â•â• │"<<endl; + cout<<"│ Version 4.1 │"<<endl; + cout<<"├───────────────────────────────────────────────┤"<<endl; + cout<<"│ Core Lybrary for Advance Scenario Simulation │"<<endl; + cout<<"│ │"<<endl; + cout<<"│ A dynamical nuclear fuel cycle code developed │"<<endl; + cout<<"│ by the CNRS/IN2P3 & IRSN │"<<endl; + cout<<"│ https://forge.in2p3.fr/projects/classforge │"<<endl; + cout<<"├───────────────────────────────────────────────┤"<<endl; + cout<<"│ Authors : │"<<endl; + cout<<"│ B. MOUGINOT (@BaM) B. LENIAU (@BLG) │"<<endl; + cout<<"│ F. COURTIN (@FaC) N. THIOLIERE (@NT) │"<<endl; + cout<<"╰───────────────────────────────────────────────╯"<<endl; + cout<<" "<<endl; + cout<<" BEGINING FUEL CYCLE EVOLUTION "<<endl; + cout<<" "<<endl; + cout<<"Evolution progression : "<<endl; +} +//________________________________________________________________________ +void Scenario::PrintClover(int i) +{ + + if(i == 0) + { cout<<"â•â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â•® "<<endl; + cout<<"│ ██████╗██╗ █████╗ ███████╗███████╗ │ @@ "<<endl; + cout<<"│ ██╔â•â•â•â•â•â–ˆâ–ˆâ•‘ ██╔â•â•â–ˆâ–ˆâ•—██╔â•â•â•â•â•â–ˆâ–ˆâ•”â•â•â•â•â• │ @@@@@ "<<endl; + cout<<"│ ██║ ██║ ███████║███████╗███████╗ │ @@@@@@ "<<endl; + cout<<"│ ██║ ██║ ██╔â•â•â–ˆâ–ˆâ•‘â•šâ•â•â•â•â–ˆâ–ˆâ•‘â•šâ•â•â•â•â–ˆâ–ˆâ•‘ │ @@@@@@@ "<<endl; + cout<<"│ ╚██████╗███████╗██║ ██║███████║███████║ │ @@@@@@@ "<<endl; + cout<<"│ â•šâ•â•â•â•â•â•â•šâ•â•â•â•â•â•â•â•šâ•â• â•šâ•â•â•šâ•â•â•â•â•â•â•â•šâ•â•â•â•â•â•â• │ @@@@@@ @ "<<endl; + cout<<"│ Version 4.1 │ @@@@ @@@@ "<<endl; + cout<<"├───────────────────────────────────────────────┤ @@ @@@@@@ "<<endl; + cout<<"│ Core Lybrary for Advance Scenario Simulation │ @ @@@@@@@ "<<endl; + cout<<"│ │ @@ @@@@@@@ "<<endl; + cout<<"│ A dynamical nuclear fuel cycle code developed │ @ @@@@@@ "<<endl; + cout<<"│ by the CNRS/IN2P3 & IRSN │ @@@@ @@@@@ "<<endl; + cout<<"│ https://forge.in2p3.fr/projects/classforge │ @@@@@ @@@@ "<<endl; + cout<<"├───────────────────────────────────────────────┤ @@@@@@@ "<<endl; + cout<<"│ Authors : │ @@@@@@@ "<<endl; + cout<<"│ B. MOUGINOT (@BaM) B. LENIAU (@BLG) │ @@@@@@ "<<endl; + cout<<"│ F. COURTIN (@FaC) N. THIOLIERE (@NT) │ @@@@@ "<<endl; + cout<<"╰───────────────────────────────────────────────╯ @@@ "<<endl; + cout<<" "<<endl; + } + if(i == 1) + { cout<<"â•â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â•® "<<endl; + cout<<"│ ██████╗██╗ █████╗ ███████╗███████╗ │ @ @@@@@@@@ "<<endl; + cout<<"│ ██╔â•â•â•â•â•â–ˆâ–ˆâ•‘ ██╔â•â•â–ˆâ–ˆâ•—██╔â•â•â•â•â•â–ˆâ–ˆâ•”â•â•â•â•â• │ @@@@@@@@ "<<endl; + cout<<"│ ██║ ██║ ███████║███████╗███████╗ │ @@@@@@@ "<<endl; + cout<<"│ ██║ ██║ ██╔â•â•â–ˆâ–ˆâ•‘â•šâ•â•â•â•â–ˆâ–ˆâ•‘â•šâ•â•â•â•â–ˆâ–ˆâ•‘ │ @@@@@@ "<<endl; + cout<<"│ ╚██████╗███████╗██║ ██║███████║███████║ │ @@@@@ "<<endl; + cout<<"│ â•šâ•â•â•â•â•â•â•šâ•â•â•â•â•â•â•â•šâ•â• â•šâ•â•â•šâ•â•â•â•â•â•â•â•šâ•â•â•â•â•â•â• │ @@@@ "<<endl; + cout<<"│ Version 4.1 │ @@ "<<endl; + cout<<"├───────────────────────────────────────────────┤ @ "<<endl; + cout<<"│ Core Lybrary for Advance Scenario Simulation │ @ "<<endl; + cout<<"│ │ @@@@@@@ @@ @@@@@@@ "<<endl; + cout<<"│ A dynamical nuclear fuel cycle code developed │ @@@@@@@@ @@@@@@@@ "<<endl; + cout<<"│ by the CNRS/IN2P3 & IRSN │ @@@@@@@@ @@@@@@@ "<<endl; + cout<<"│ https://forge.in2p3.fr/projects/classforge │ @@@@@@ @@@@@@ "<<endl; + cout<<"├───────────────────────────────────────────────┤ @@@@@ @@@@@ "<<endl; + cout<<"│ Authors : │ @@@@ @@@@ "<<endl; + cout<<"│ B. MOUGINOT (@BaM) B. LENIAU (@BLG) │ @@ @@@ "<<endl; + cout<<"│ F. COURTIN (@FaC) N. THIOLIERE (@NT) │ @ @ "<<endl; + cout<<"╰───────────────────────────────────────────────╯ "<<endl; + cout<<" "<<endl; + } + + if(i == 2) + { cout<<"â•â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â•® "<<endl; + cout<<"│ ██████╗██╗ █████╗ ███████╗███████╗ │ @@@ "<<endl; + cout<<"│ ██╔â•â•â•â•â•â–ˆâ–ˆâ•‘ ██╔â•â•â–ˆâ–ˆâ•—██╔â•â•â•â•â•â–ˆâ–ˆâ•”â•â•â•â•â• │ @@@@@ "<<endl; + cout<<"│ ██║ ██║ ███████║███████╗███████╗ │ @@@@@@ "<<endl; + cout<<"│ ██║ ██║ ██╔â•â•â–ˆâ–ˆâ•‘â•šâ•â•â•â•â–ˆâ–ˆâ•‘â•šâ•â•â•â•â–ˆâ–ˆâ•‘ │ @@@@@@@ "<<endl; + cout<<"│ ╚██████╗███████╗██║ ██║███████║███████║ │ @@@@@@@@ "<<endl; + cout<<"│ â•šâ•â•â•â•â•â•â•šâ•â•â•â•â•â•â•â•šâ•â• â•šâ•â•â•šâ•â•â•â•â•â•â•â•šâ•â•â•â•â•â•â• │ @@ @@@@@@ "<<endl; + cout<<"│ Version 4.1 │ @@@ @@@@ "<<endl; + cout<<"├───────────────────────────────────────────────┤ @@@@@@ @@ "<<endl; + cout<<"│ Core Lybrary for Advance Scenario Simulation │ @@@@@@@@ @ "<<endl; + cout<<"│ │ @@@@@@@ @@ "<<endl; + cout<<"│ A dynamical nuclear fuel cycle code developed │ @@@@@@ @ "<<endl; + cout<<"│ by the CNRS/IN2P3 & IRSN │ @@@@@ @@@@ "<<endl; + cout<<"│ https://forge.in2p3.fr/projects/classforge │ @@ @@@@@@ "<<endl; + cout<<"├───────────────────────────────────────────────┤ @@@@@@@ "<<endl; + cout<<"│ Authors : │ @@@@@@@ "<<endl; + cout<<"│ B. MOUGINOT (@BaM) B. LENIAU (@BLG) │ @@@@@@@ "<<endl; + cout<<"│ F. COURTIN (@FaC) N. THIOLIERE (@NT) │ @@@@@ "<<endl; + cout<<"╰───────────────────────────────────────────────╯ @@@@ "<<endl; + cout<<" "<<endl; + + } + + if(i == 3) + { cout<<"â•â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â•® "<<endl; + cout<<"│ ██████╗██╗ █████╗ ███████╗███████╗ │ "<<endl; + cout<<"│ ██╔â•â•â•â•â•â–ˆâ–ˆâ•‘ ██╔â•â•â–ˆâ–ˆâ•—██╔â•â•â•â•â•â–ˆâ–ˆâ•”â•â•â•â•â• │ "<<endl; + cout<<"│ ██║ ██║ ███████║███████╗███████╗ │ @@ @@ "<<endl; + cout<<"│ ██║ ██║ ██╔â•â•â–ˆâ–ˆâ•‘â•šâ•â•â•â•â–ˆâ–ˆâ•‘â•šâ•â•â•â•â–ˆâ–ˆâ•‘ │ @@@@ @@@ "<<endl; + cout<<"│ ╚██████╗███████╗██║ ██║███████║███████║ │ @@@@@ @@@@@ "<<endl; + cout<<"│ â•šâ•â•â•â•â•â•â•šâ•â•â•â•â•â•â•â•šâ•â• â•šâ•â•â•šâ•â•â•â•â•â•â•â•šâ•â•â•â•â•â•â• │ @@@@@@ @@@@@@ "<<endl; + cout<<"│ Version 4.1 │ @@@@@@ @@@@@@@ "<<endl; + cout<<"├───────────────────────────────────────────────┤ @@@@@@@@ @@@@@@@@ "<<endl; + cout<<"│ Core Lybrary for Advance Scenario Simulation │ @@@@@@@@ @ @@@@@@@ "<<endl; + cout<<"│ │ @@ "<<endl; + cout<<"│ A dynamical nuclear fuel cycle code developed │ @@ "<<endl; + cout<<"│ by the CNRS/IN2P3 & IRSN │ @@@@ "<<endl; + cout<<"│ https://forge.in2p3.fr/projects/classforge │ @@@@@ "<<endl; + cout<<"├───────────────────────────────────────────────┤ @@@@@@ "<<endl; + cout<<"│ Authors : │ @@@@@@@ "<<endl; + cout<<"│ B. MOUGINOT (@BaM) B. LENIAU (@BLG) │ @@@@@@@@ "<<endl; + cout<<"│ F. COURTIN (@FaC) N. THIOLIERE (@NT) │ "<<endl; + cout<<"╰───────────────────────────────────────────────╯ "<<endl; + cout<<" "<<endl; + + } + +} +//________________________________________________________________________ +void Scenario::ApplyZAIThreshold() +{ + for(int i = 0; i < (int)fFabricationPlant.size(); i++) + fFabricationPlant[i]->ApplyZAIThreshold(fZAIThreshold); + + for(int i = 0; i < (int) fPool.size();i++) + fPool[i]->ApplyZAIThreshold(fZAIThreshold); + + for(int i = 0; i < (int)fStorage.size(); i++) + fStorage[i]->ApplyZAIThreshold(fZAIThreshold); + + for(int i = 0; i < (int)fReactor.size(); i++) + fReactor[i]->ApplyZAIThreshold(fZAIThreshold); + + + fWaste.ApplyZAIThreshold(fZAIThreshold); + + +} +//________________________________________________________________________ +void Scenario::UpdateParc() +{ + + ResetQuantity(); + + for(int i = 0; i < (int)fFabricationPlant.size(); i++) + fFuelFabrication += fFabricationPlant[i]->GetInsideIV(); + + for(int i = 0; i < (int) fPool.size();i++) + fTotalCooling += fPool[i]->GetInsideIV(); + + for(int i = 0; i < (int)fStorage.size(); i++) + fTotalStorage += fStorage[i]->GetInsideIV(); + + for(int i = 0; i < (int)fReactor.size(); i++) + fTotalInReactor += fReactor[i]->GetIVReactor(); + + fIVTotal = fWaste + fTotalStorage + fTotalCooling + fFuelFabrication + fTotalInReactor; + fIVInCycleTotal = fTotalStorage + fTotalCooling + fFuelFabrication + fTotalInReactor; +} +//________________________________________________________________________ +void Scenario::ResetQuantity() +{ + + fTotalInReactor.Clear(); + fTotalStorage.Clear(); + fTotalCooling.Clear(); + fFuelFabrication.Clear(); + fIVInCycleTotal.Clear(); + fIVTotal.Clear(); + +} +//________________________________________________________________________ +void Scenario::OpenOutputTree() +{ + + + INFO << "Opening : " << fOutputFileName << " ...\t"; + fOutFile = new TFile(fOutputFileName.c_str(),"UPDATE"); + + if(!fOutFile) + { + ERROR << "\nCould not open " << fOutputFileName << endl; + exit(-1); + } + INFO << "\t ...OK!" << endl; + + + fOutT = new TTree(fOutputTreeName.c_str(), "Data Tree"); + INFO << "Creating Data Tree ...\t"; + if(!fOutT) + { + ERROR << "\nCould not create Data Tree in " << fOutputFileName << endl; + exit(-1); + } + fNewTtree = false; + INFO << "\t ...OK!" << endl; + +} +//________________________________________________________________________ +void Scenario::CloseOutputTree() +{ + + + fOutFile->ls(); + INFO << "Writing outTree " << fOutputFileName << endl; + fOutFile->Write("",TObject::kOverwrite); + + if(fOutFile->IsOpen()) { + INFO << "Deleting outTree : " << endl; + delete fOutT; + INFO << "Closing file : " << fOutputFileName << endl; + fOutFile-> Close(); + delete fOutFile; + } else { + ERROR << "File was not opened " << fOutputFileName << endl; + exit(-1); + } +} +//________________________________________________________________________ +void Scenario::OutAttach() +{ + + ResetQuantity(); + //Branch Absolut Time + fOutT->Branch("AbsTime",&fAbsoluteTime,"AbsoluteTime/L"); + //Branch The Power installed in the Parc + fOutT->Branch("ParcPower",&fParcPower,"ParcPower/D"); + + + + // Branch the Sum IV + + + fOutT->Branch("STOCK.", "IsotopicVector", &fTotalStorage); + fOutT->Branch("FUELFABRICATION.", "IsotopicVector", &fFuelFabrication); + fOutT->Branch("COOLING.", "IsotopicVector", &fTotalCooling); + fOutT->Branch("REACTOR.", "IsotopicVector", &fTotalInReactor); + fOutT->Branch("INCYCLE.", "IsotopicVector", &fIVInCycleTotal); + fOutT->Branch("TOTAL.", "IsotopicVector", &fIVTotal); + + fOutT->Branch("OUTINCOME.", "IsotopicVector", &fOutIncome); + fOutT->Branch("WASTE.", "IsotopicVector", &fWaste); + + // Branch the separate object + + for(int i = 0; i < (int)fStorage.size(); i++) + fOutT->Branch(fStorage[i]->GetName(), "Storage", &fStorage[i]); + + for(int i = 0; i < (int)fPool.size(); i++) + + fOutT->Branch(fPool[i]->GetName(), "Pool", &fPool[i]); + + for(int i = 0; i < (int)fReactor.size(); i++) + + fOutT->Branch(fReactor[i]->GetName(), "Reactor", &fReactor[i]); + + for(int i = 0; i < (int)fFabricationPlant.size(); i++) + fOutT->Branch(fFabricationPlant[i]->GetName(), "FabricationPlant", &fFabricationPlant[i]); + + +} +//________________________________________________________________________ +void Scenario::Write() +{ + + + + +} +//________________________________________________________________________ +void Scenario::Print() +{ + + for(int i = 0; i < (int) fPool.size();i++) + { + INFO << "!!!!!!!!!STEP : " << fAbsoluteTime/(int)(cYear) << endl; + INFO << "Pool : " << endl; + INFO << "Cooling "; + INFO << fPool[i]->GetIVArray().size() << endl; + } + + for(int i = 0; i < (int)fReactor.size(); i++) + { + INFO << "Reactor" << endl; + fReactor[i]->GetIVReactor().Print(); + } + +} diff --git a/source/branches/BaM/src/SeparationPlant.cxx b/source/branches/BaM/src/SeparationPlant.cxx new file mode 100644 index 000000000..c2e9ed352 --- /dev/null +++ b/source/branches/BaM/src/SeparationPlant.cxx @@ -0,0 +1,137 @@ +#include "SeparationPlant.hxx" + +#include "Scenario.hxx" +#include "CLASSLogger.hxx" + +#include <sstream> +#include <string> +#include <iostream> +#include <cmath> +#include <algorithm> + +//________________________________________________________________________ +// +// SeparationPlant +// +// +// +// +//________________________________________________________________________ +ClassImp(SeparationPlant) + + +SeparationPlant::SeparationPlant():CLASSBackEnd(-2) +{ + fOutBackEndFacility = 0; + SetName("C_SeparationPlant."); + SetIsStorageType(); +} + +//________________________________________________________________________ +SeparationPlant::SeparationPlant(CLASSLogger* log):CLASSBackEnd(log, -2) +{ + + + fCycleTime = 0; + fIsStarted = false; + fPutToWaste = true; + + fOutBackEndFacility = 0; + SetName("C_SeparationPlant."); + + SetIsStorageType(); + + INFO << " A new SeparationPlant has been define :" << endl; + INFO << "\t The Separation Time set at\t " << (double)(fCycleTime/cYear) << " year" << endl; + WARNING << " All Separated Fuel go directly to WASTE after cooling !! " << endl; + + +} + + +//________________________________________________________________________ +SeparationPlant::~SeparationPlant() +{ + + +} + +//________________________________________________________________________ + +//________________________________________________________________________ +void SeparationPlant::SetBackEndDestination(CLASSBackEnd* storagedestination, IsotopicVector isotopicvector, cSecond destinationstartingtime) +{ + DBGL + + fDestinationStorageStartingTime.push_back(destinationstartingtime); + fDestinationStorage.push_back(storagedestination); + fDestinationStorageIV.push_back(isotopicvector); + + if (fDestinationStorage.size() != fDestinationStorageIV.size()) + ERROR << " fDestinationStorage.size() != fDestinationStorageIV.size() !! " << endl; + + DBGL + +} + + +//________________________________________________________________________ +void SeparationPlant::AddIV(IsotopicVector IV) +{ +DBGL + for(int fds = 0; fds<(int)fDestinationStorage.size(); fds++) + { + cSecond CurrentTime = GetParc()->GetAbsoluteTime(); + + DBGV( "Separation..." << endl); + DBGV( "Current Time : " << CurrentTime << endl); + DBGV( "IV Separation Time : " << fDestinationStorageStartingTime[fds] << endl); + + if(CurrentTime >= fDestinationStorageStartingTime[fds]) + { + IsotopicVector IVtmp; + IVtmp = IV*fDestinationStorageIV[fds]; + fDestinationStorage[fds]->AddIV(IVtmp); + IV -= IVtmp; + } + + } + + GetParc()->AddWaste(IV); + + DBGL +} + + + +//________________________________________________________________________ +map<cSecond,int> SeparationPlant::GetTheBackEndTimePath() +{ + DBGL + + map<cSecond, int> TheBackEndTimePath; + for( int i = 0; i < (int)fDestinationStorage.size(); i++ ) + { + map<cSecond, int> TheBackEndTimePath_tmp = fDestinationStorage[i]->GetTheBackEndTimePath(); + map<cSecond, int>::iterator it; + for (it = TheBackEndTimePath_tmp.begin(); it != TheBackEndTimePath_tmp.end(); it++) + { + pair< map<cSecond, int>::iterator, bool > IResult; + IResult = TheBackEndTimePath.insert( pair<cSecond ,int>((*it).first, (*it).second) ); + if( !IResult.second ) + IResult.first->second |= (*it).second; + + } + } + + DBGL + return TheBackEndTimePath; +} + + + + + +//________________________________________________________________________ + + diff --git a/source/branches/BaM/src/Storage.cxx b/source/branches/BaM/src/Storage.cxx new file mode 100644 index 000000000..b139970bd --- /dev/null +++ b/source/branches/BaM/src/Storage.cxx @@ -0,0 +1,215 @@ +#include "Storage.hxx" + +#include "Scenario.hxx" +#include "CLASSLogger.hxx" + + +#include <sstream> +#include <string> +#include <iostream> +#include <cmath> +#include <algorithm> + +//________________________________________________________________________ +// +// Storage +// +// +// +// +//________________________________________________________________________ +ClassImp(Storage) + + + + +Storage::Storage():CLASSBackEnd(-1) +{ + DBGL + SetIsStorageType(); + SetName("S_Storage."); + + DBGL +} + +Storage::Storage(CLASSLogger* log):CLASSBackEnd(log, -1) +{ + DBGL + SetIsStorageType(); + + SetName("S_Storage."); + + INFO << " A new Storage has been define." << endl; + +} +//________________________________________________________________________ +Storage::Storage(CLASSLogger* log, DecayDataBank* evolutivedb):CLASSBackEnd(log, -1) +{ + DBGL + SetIsStorageType(); + + SetDecayDataBank(evolutivedb); + + SetName("S_Storage."); + + INFO << " A new Storage has been define." << endl; + + + DBGL +} + +//________________________________________________________________________ +Storage::~Storage() +{ + + +} + +//________________________________________________________________________ +void Storage::AddIV(IsotopicVector isotopicvector) +{ + + AddCumulativeIVIn(isotopicvector); + + if(GetParc()) + { + if(GetParc()->GetStockManagement() ) + { + fIVArray.push_back(isotopicvector); + fIVArrayArrivalTime.push_back(fInternalTime); + } + } + else + { + fIVArray.push_back(isotopicvector); + fIVArrayArrivalTime.push_back(fInternalTime); + } + UpdateInsideIV(); +} + +//________________________________________________________________________ +void Storage::TakeFractionFromStock(int IVId,double fraction) +{ +DBGL + if(GetParc()) + { + if(GetParc()->GetStockManagement() ) + { + if(fraction > 1 || fraction < 0) + { + WARNING << " You try to remove fraction superior than 1 or a negative one..." << endl; + } + else + { + AddCumulativeIVOut(fIVArray[IVId]*fraction); + fIVArray[IVId] -= fIVArray[IVId] * fraction; + } + + } + else + { + ERROR << " TakeFractionFromStock can't be DEFINE without REAL stock management" << endl; + exit(1); + + } + } + else + { + if(fraction > 1 || fraction < 0) + { + WARNING << " You try to remove fraction superior than 1 or a negative one..." << endl; + } + else + { + AddCumulativeIVOut(fIVArray[IVId]*fraction); + fIVArray[IVId] -= fIVArray[IVId] * fraction; + } + + } + UpdateInsideIV(); + DBGL +} + +void Storage::TakeFromStock(IsotopicVector isotopicvector) +{ + + if(GetParc()) + { + if(!GetParc()->GetStockManagement()) + { + + AddCumulativeIVOut(isotopicvector); + fInsideIV -= isotopicvector; + } + else + { + ERROR << " TakeFromStock can't be DEFINE WITH REAL stock management" << endl; + exit(1); + } + } + else + { + AddCumulativeIVOut(isotopicvector); + fInsideIV -= isotopicvector; + + } + +} + +//________________________________________________________________________ +void Storage::StorageEvolution(cSecond t) +{ +DBGL + + if(t == fInternalTime && t != 0 ) return; + + RemoveEmptyStocks(); + + cSecond EvolutionTime = t - fInternalTime; + +#pragma omp parallel for + for (int i = 0; i <(int) fIVArray.size() ; i++) + { + fIVArray[i] = GetDecay(fIVArray[i] , EvolutionTime); + } +DBGL +} + +//________________________________________________________________________ +void Storage::Evolution(cSecond t) +{ + + // Check if the Storage has been created ... + if(t == fInternalTime && t != 0) return; + // Make the evolution for the Storage ... + + StorageEvolution(t); + // Update Inside IV; + UpdateInsideIV(); + + // ... And Finaly update the AbsoluteInternalTime + fInternalTime = t; + +} + +void Storage::Write(string filename, cSecond date) +{ + + for(int i = 0;i < (int)fIVArray.size(); i++) + { + + fIVArray[i].Write(filename, date); + } + +} +//________________________________________________________________________ +void Storage::RemoveEmptyStocks() +{ + for(int i = (int)fIVArray.size()-1 ; i >= 0; i--) //Removing empty Stock + if(fIVArray[i].GetSumOfAll() == 0) + { + fIVArray.erase(fIVArray.begin()+i); + fIVArrayArrivalTime.erase(fIVArrayArrivalTime.begin()+i); + + } +} diff --git a/source/branches/BaM/src/XSModel.cxx b/source/branches/BaM/src/XSModel.cxx new file mode 100644 index 000000000..cb6707c07 --- /dev/null +++ b/source/branches/BaM/src/XSModel.cxx @@ -0,0 +1,203 @@ +// +// XSModel.cxx +// CLASSSource +// +// Created by BaM on 04/05/2014. +// Copyright (c) 2014 BLG. All rights reserved. +// + +#include "XSModel.hxx" +#include "StringLine.hxx" +#include "CLASSMethod.hxx" +#include "ZAI.hxx" + + +using namespace std; + + + +XSModel::XSModel():CLASSObject() +{ + XSModel::LoadKeyword(); + freaded = false; + +} + +//________________________________________________________________________ + +XSModel::XSModel(CLASSLogger* log):CLASSObject(log) +{ + + XSModel::LoadKeyword(); + freaded = false; +} + +//________________________________________________________________________ +void XSModel::ReadNFO() +{ + DBGL + ifstream NFO(fInformationFile.c_str()); + + if(!NFO) + { + ERROR << "Can't find/open file " << fInformationFile << endl; + exit(0); + } + + do + { + string line; + getline(NFO,line); + + XSModel::ReadLine(line); + + } while(!NFO.eof()); + + DBGL +} + +//________________________________________________________________________ +void XSModel::ReadLine(string line) +{ + DBGL + + if (!freaded) + { + int pos = 0; + string keyword = tlc(StringLine::NextWord(line, pos, ' ')); + + map<string, XSM_MthPtr>::iterator it = fKeyword.find(keyword); + + if(it != fKeyword.end()) + (this->*(it->second))( line ); + + freaded = true; + ReadLine(line); + + } + + freaded = false; + + DBGL +} + +//________________________________________________________________________ +void XSModel::LoadKeyword() +{ + DBGL + fKeyword.insert( pair<string, XSM_MthPtr>( "k_zail", & XSModel::ReadZAIlimits)); + fKeyword.insert( pair<string, XSM_MthPtr>( "k_reactor", & XSModel::ReadType) ); + fKeyword.insert( pair<string, XSM_MthPtr>( "k_fuel", & XSModel::ReadType) ); + fKeyword.insert( pair<string, XSM_MthPtr>( "k_mass", & XSModel::ReadRParam) ); + fKeyword.insert( pair<string, XSM_MthPtr>( "k_power", & XSModel::ReadRParam) ); + DBGL +} + +//________________________________________________________________________ +void XSModel::ReadRParam(const string &line) +{ + DBGL + int pos = 0; + string keyword = tlc(StringLine::NextWord(line, pos, ' ')); + if( keyword != "k_power" && keyword != "k_mass" ) // Check the keyword + { + ERROR << " Bad keyword : " << keyword << " Not found !" << endl; + exit(1); + } + if( keyword == "k_mass" ) + fDBHMMass = atof(StringLine::NextWord(line, pos, ' ').c_str()); + else if( keyword == "k_power" ) + fDBPower = atof(StringLine::NextWord(line, pos, ' ').c_str()); + + DBGL +} + +//________________________________________________________________________ + +void XSModel::ReadType(const string &line) +{ + DBGL + int pos = 0; + string keyword = tlc(StringLine::NextWord(line, pos, ' ')); + if( keyword != "k_fuel" && keyword != "k_reactor" ) // Check the keyword + { + ERROR << " Bad keyword : " << keyword << " Not found !" << endl; + exit(1); + } + if( keyword == "k_fuel" ) + fDBFType = StringLine::NextWord(line, pos, ' '); + else if( keyword == "k_reactor" ) + fDBRType = StringLine::NextWord(line, pos, ' '); + + DBGL +} + +//________________________________________________________________________ +void XSModel::ReadZAIlimits(const string &line) +{ + DBGL + int pos = 0; + string keyword = tlc(StringLine::NextWord(line, pos, ' ')); + if( keyword != "k_zail" ) // Check the keyword + { + ERROR << " Bad keyword : \"k_zail\" not found !" << endl; + exit(1); + } + + int Z = atoi(StringLine::NextWord(line, pos, ' ').c_str()); + int A = atoi(StringLine::NextWord(line, pos, ' ').c_str()); + int I = atoi(StringLine::NextWord(line, pos, ' ').c_str()); + + double downLimit = atof(StringLine::NextWord(line, pos, ' ').c_str()); + double upLimit = atof(StringLine::NextWord(line, pos, ' ').c_str()); + + if (upLimit < downLimit) + { + double tmp = upLimit; + upLimit = downLimit; + downLimit = tmp; + } + fZAILimits.insert(pair<ZAI, pair<double, double> >(ZAI(Z,A,I), pair<double,double>(downLimit, upLimit))); + DBGL +} + +//________________________________________________________________________ +bool XSModel::isIVInDomain(IsotopicVector IV) +{ + DBGL + bool IsInDomain = true; + + if(fZAILimits.empty()) + { + WARNING << "Fresh Fuel variation domain is not set" << endl; + WARNING << "CLASS has no clue if the computed evolution for this fresh fuel is correct" << endl; + WARNING << "Proceed finger crossed !!" << endl; + return true; + } + + else + { + IsotopicVector IVNorm = IV /IV.GetSumOfAll(); + for (map< ZAI,pair<double,double> >::iterator Domain_it = fZAILimits.begin(); Domain_it != fZAILimits.end(); Domain_it++) + { + double ThatZAIProp = IVNorm.GetIsotopicQuantity()[Domain_it->first] ; + double ThatZAIMin = Domain_it->second.first; + double ThatZAIMax = Domain_it->second.second; + if( (ThatZAIProp > ThatZAIMax) || (ThatZAIProp < ThatZAIMin) ) + { + IsInDomain = false; + + WARNING << "Fresh fuel out of model range" << endl; + WARNING << "\t AT LEAST this ZAI is accused to be outrange :" << endl; + WARNING << "\t\t" << Domain_it->first.Z() << " " << Domain_it->first.A() << " " << Domain_it->first.I() << endl; + WARNING << "\t\t min = " << ThatZAIMin << " value = " << ThatZAIProp << " max = " << ThatZAIMax << endl; + WARNING << "\t IV accused :" << endl << endl; + WARNING << IVNorm.sPrint() << endl; + break; + } + } + } + DBGL + return IsInDomain; + +} \ No newline at end of file diff --git a/source/branches/BaM/src/ZAI.cxx b/source/branches/BaM/src/ZAI.cxx new file mode 100755 index 000000000..945d5e355 --- /dev/null +++ b/source/branches/BaM/src/ZAI.cxx @@ -0,0 +1,62 @@ +#include "ZAI.hxx" +#include "stdlib.h" + + +//const string DEFAULTDATABASE = "DecayBase.dat"; +//________________________________________________________________________ +// +// ZAI +// +// +// +// +//________________________________________________________________________ +//____________________________InClass Operator____________________________ +//________________________________________________________________________ +ClassImp(ZAI) + +ZAI ZAI::operator = (ZAI IVa) +{ + fZ = IVa.Z(); + fA = IVa.A(); + fI = IVa.I(); + return *this; +} + + + +ZAI::ZAI() +{ + + fZ = 0; + fA = 0; + fI = 0; + +} + + +//________________________________________________________________________ +ZAI::ZAI(int Z, int A, int I) +{ + + if( Z > A ) + { + cout << "!!!ERROR!!! " << "[" << __FILE__ << ":" << __FUNCTION__ << "]" << endl; + cout << "!!!ERROR!!! Z:" << Z << " is higher than A: " << A << endl; + cout << "!!!ERROR!!! CLASS did not manage yet anti-mater!!! Update comming soon !!!" << endl; + exit(1); + } + + fZ = Z; + fA = A; + fI = I; + +} + + +ZAI::~ZAI() +{ + +} + + diff --git a/source/branches/BaM/src/ZAIHeat.cxx b/source/branches/BaM/src/ZAIHeat.cxx new file mode 100644 index 000000000..c51335af1 --- /dev/null +++ b/source/branches/BaM/src/ZAIHeat.cxx @@ -0,0 +1,99 @@ +#include "ZAIHeat.hxx" + +//#include "CLASSConstante.hxx" + +#include "stdlib.h" +#include <fstream> +#include <string> + +#include "IsotopicVector.hxx" +#include "StringLine.hxx" + +#include "IrradiationModel.hxx" + + //________________________________________________________________________ + // + // ZAI + // + // + // + // + //________________________________________________________________________ + //____________________________InClass Operator____________________________ + //________________________________________________________________________ + +//________________________________________________________________________ +ZAIHeat::ZAIHeat() +{ + string CLASSPATH = getenv("CLASS_PATH"); + string HeatToxFile = CLASSPATH + "/data/HeatTox.dat"; + + ifstream infile(HeatToxFile.c_str()); + + if(!infile.good()) + { + cout << "Error in ZAIHeat : can't find/open file " << HeatToxFile << endl; + exit(1); + } + + IrradiationModel* IM = new IrradiationModel(); + IM->SetZAIThreshold(0); + IM->LoadDecay(); + + int Z,A,I; + string Name; + double WperBq,SvperBq; + while (!infile.eof()) + { + string line; + stringstream ossline; + getline(infile, line); + ossline << line; + + if(StringLine::IsDouble(line.substr(0,1))) //else is a comment + { ossline>>Z>>A>>I>>WperBq>>SvperBq; + fZAIHeat.insert( pair< ZAI,double >( ZAI(Z,A,I),IM->GetDecayConstant(ZAI(Z,A,I))*WperBq) ); + } + } + + delete IM; + infile.close(); +} +//________________________________________________________________________ +ZAIHeat::~ZAIHeat() +{ + fZAIHeat.clear(); +} +//________________________________________________________________________ +double ZAIHeat::GetHeat(ZAI zai ) const +{ + + map<ZAI ,double> ZAIHeat = fZAIHeat; + map<ZAI ,double>::iterator it; + it = ZAIHeat.find(zai); + + if ( it != ZAIHeat.end() ) + { + return it->second; + } + else + { + return 0; + } + +} +//________________________________________________________________________ +double ZAIHeat::GetHeat(const IsotopicVector IV) const +{ + double TotalHeat = 0; + + map<ZAI ,double >::iterator it; + map<ZAI ,double > isotopicquantity = IV.GetIsotopicQuantity(); + + for( it = isotopicquantity.begin(); it != isotopicquantity.end(); it++) + TotalHeat += (*it).second * GetHeat( (*it).first ) ; + + + return TotalHeat; + +} diff --git a/source/branches/BaM/src/ZAIMass.cxx b/source/branches/BaM/src/ZAIMass.cxx new file mode 100644 index 000000000..ed0841392 --- /dev/null +++ b/source/branches/BaM/src/ZAIMass.cxx @@ -0,0 +1,81 @@ +#include "ZAIMass.hxx" + +//#include "CLASSConstante.hxx" + +#include "stdlib.h" +#include <fstream> +#include <string> + +#include "IsotopicVector.hxx" + //________________________________________________________________________ + // + // ZAI + // + // + // + // + //________________________________________________________________________ + //____________________________InClass Operator____________________________ + //________________________________________________________________________ + + +ZAIMass::ZAIMass() +{ + string CLASSPATH = getenv("CLASS_PATH"); + string MassDataFile = CLASSPATH + "/data/Mass.dat"; + + ifstream infile(MassDataFile.c_str()); + + if(!infile.good()) + { + cout << " ZAIMass Error.\n can't find/open file " << MassDataFile << endl; + exit(1); + } + + int Z,A; + string Name; + double MassUnity,MassDec,error; + while (infile>>Z>>A>>Name>>MassUnity>>MassDec>>error) + { + double Masse = MassUnity + MassDec * 1e-6; + fZAIMass.insert( pair< ZAI,double >( ZAI(Z,A,0), Masse ) ); + } + + infile.close(); +} + + +ZAIMass::~ZAIMass() +{ + fZAIMass.clear(); +} + + +double ZAIMass::GetMass(ZAI zai ) const +{ + map<ZAI,double> ZAIMasscpy = fZAIMass ; + map<ZAI,double>::iterator MassIT = ZAIMasscpy.find( ZAI(zai.Z(), zai.A(), 0) ); + + if(MassIT == fZAIMass.end()) + return zai.A(); + else + return MassIT->second; + +} + + +double ZAIMass::GetMass(const IsotopicVector IV) const +{ + double AVOGADRO = 6.02214129e23; + double TotalMass = 0; + + map<ZAI ,double >::iterator it; + map<ZAI ,double > isotopicquantity = IV.GetIsotopicQuantity(); + for( it = isotopicquantity.begin(); it != isotopicquantity.end(); it++) + { + TotalMass += (*it).second/AVOGADRO * GetMass( (*it).first ) ; + } + + return TotalMass*1e-6; + +} \ No newline at end of file diff --git a/source/branches/BaM/src/ZAITox.cxx b/source/branches/BaM/src/ZAITox.cxx new file mode 100644 index 000000000..dc90c1f21 --- /dev/null +++ b/source/branches/BaM/src/ZAITox.cxx @@ -0,0 +1,99 @@ +#include "ZAITox.hxx" + +//#include "CLASSConstante.hxx" + +#include "stdlib.h" +#include <fstream> +#include <string> + +#include "IsotopicVector.hxx" +#include "StringLine.hxx" + +#include "IrradiationModel.hxx" + + //________________________________________________________________________ + // + // ZAI + // + // + // + // + //________________________________________________________________________ + //____________________________InClass Operator____________________________ + //________________________________________________________________________ + +//________________________________________________________________________ +ZAITox::ZAITox() +{ + string CLASSPATH = getenv("CLASS_PATH"); + string HeatToxFile = CLASSPATH + "/data/HeatTox.dat"; + + ifstream infile(HeatToxFile.c_str()); + + if(!infile.good()) + { + cout << "Error in ZAITox : can't find/open file " << HeatToxFile << endl; + exit(1); + } + + IrradiationModel* IM = new IrradiationModel(); + IM->SetZAIThreshold(1); + IM->LoadDecay(); + + int Z,A,I; + string Name; + double WperBq,SvperBq; + while (!infile.eof()) + { + string line; + stringstream ossline; + getline(infile, line); + ossline << line; + + if(StringLine::IsDouble(line.substr(0,1))) //else is a comment + { ossline>>Z>>A>>I>>WperBq>>SvperBq; + fZAITox.insert( pair< ZAI,double >( ZAI(Z,A,I),IM->GetDecayConstant(ZAI(Z,A,I))*SvperBq) ); + } + } + + delete IM; + infile.close(); +} +//________________________________________________________________________ +ZAITox::~ZAITox() +{ + fZAITox.clear(); +} +//________________________________________________________________________ +double ZAITox::GetRadioTox(ZAI zai ) const +{ + + map<ZAI ,double> ZAITox = fZAITox; + map<ZAI ,double>::iterator it; + it = ZAITox.find(zai); + + if ( it != ZAITox.end() ) + { + return it->second; + } + else + { + return 0; + } + +} +//________________________________________________________________________ +double ZAITox::GetRadioTox(const IsotopicVector IV) const +{ + double TotalTox = 0; + + map<ZAI ,double >::iterator it; + map<ZAI ,double > isotopicquantity = IV.GetIsotopicQuantity(); + + for( it = isotopicquantity.begin(); it != isotopicquantity.end(); it++) + TotalTox += (*it).second * GetRadioTox( (*it).first ) ; + + + return TotalTox; + +} -- GitLab