#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(); 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(); D = Distance( IV_ActinidesComposition, ActinidesCompositionAtT / NormalisationFactor, fDistanceType, fDistanceParameter); if (D< distance) { distance = D; N_BestEvolutionData = i; } } 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); } }