//________________________________________________________________ Bool_t KVCaloBase::RootSquare(Double_t aa, Double_t bb, Double_t cc) { // protected method // // calcul les racines du polynome d'ordre 2 : aa*x*x + bb*xx + cc = 0 // les racines sont accessibles par les variables kracine_min et kracine_max // // kroot_status>=0 -> tout c'est bien passe la fonction retourne kTRUE // =0 2 racines reelles distinctes // =1 2 racines reelles egales (aa==0) // // kroot_status<0 les deux racines sont mises a zero la fonction retourne kFALSE // =-1 2 racines imaginaires (Delta<0) // =-2 aa=bb=0 // le calcul n'est alors pas poursuivi, la méthode Calculate() retournera kFALSE // la cause peut être discriminée en appelant la méthode GetValue("RootStatus") // kracine_max = 0, kracine_min = 0; Double_t x1, x2; kroot_status = 0; if (aa != 0) { Double_t Delta = TMath::Power(bb, 2.) - 4.*aa * cc; if (Delta < 0) { //Warning("RootSquare","Delta<0 - Solutions imaginaires"); kroot_status = -1; SetIngValue("RootStatus", kroot_status); } else { Double_t racDelta = TMath::Sqrt(Delta); x1 = (-1.*bb + racDelta) / (2.*aa); x2 = (-1.*(bb + racDelta)) / (2.*aa); kroot_status = 0; if (x1 > x2) { kracine_max = x1; kracine_min = x2; } else { kracine_max = x2; kracine_min = x1; } } } else { if (bb != 0) { kroot_status = 1; kracine_max = kracine_min = -1.*cc / bb; } else { kroot_status = -2; kracine_max = kracine_min = 0; SetIngValue("RootStatus", kroot_status); } } if (kroot_status < 0) { SetIngValue("RootStatus", kroot_status); return kFALSE; } else { return kTRUE; } }
//________________________________________________________________ void KVCaloBase::ComputeExcitationEnergy() { Double_t exci = GetIngValue("Qsum") + GetIngValue("Eksum") - GetIngValue("Qini"); SetIngValue("Exci",exci); }
//________________________________________________________________ void KVCalorimetry::ComputeTemperature() { Double_t exci = GetIngValue("Exci"); Double_t temp = TMath::Sqrt(GetParValue("LevelDensityParameter") * exci / GetIngValue("Asum")); SetIngValue("Temp", temp); }
//________________________________________________________________ void KVCaloBase::AddIngValue(KVString name,Double_t value) { // protected method, //increment the value of a name given ingredient //if it is not defined, it's created Double_t before = GetIngValue(name); before += value; SetIngValue(name,before); }
//________________________________________________________________ void KVCaloBase::SumUp() { // protected method // Appelé par Calculate pour mettre à jour les différents ingrédients // de la calorimétrie : // // Trois modes de sommes: //------------------ // // détermination de l excès de masse de la source recontruite, dernier ingrédient de l'équation : // Exci + Qini = \Sigma Ek + \Sigma Q -> Exci = \Sigma Ek + \Sigma Q - Qini // // defaut de masse de la source reconstruite SetIngValue("Qini",nn.GetMassExcess(TMath::Nint(GetIngValue("Zsum")),TMath::Nint(GetIngValue("Asum")))); }
//________________________________________________________________ Bool_t KVCalorimetry::Calculate(void) { //Réalisation de la calorimétrie //Calcul de l'énergie d'excitation, température (optionnel), de l'énergie moyenne des neutrons (optionnel) //appel de SumUp() //Cette méthore retourne kTRUE si tout s'est bien passée, kFALSE si il y a un problème dans la résolution //du polynome d'ordre 2 // // Deux modes de calcul: //------------------ // - mode normal (par defaut) // Résolution de l'équation // Exci + Qini = \Sigma Ek + \Sigma Q // -> Exci = \Sigma Ek + \Sigma Q - Qini // // Optionnel : // le calcul de la température peut être également fait si la méthode DeduceTemperature(Double_t LevelDensityParameter) a été appelée // elle est obtenue via la formule : Exci = Asum/[LevelDensityParameter] * T*T // // - mode avec prise en compte des neutrons libres, actif si la métode // IncludeFreeNeutrons(Double_t AsurZ,Double_t NeutronMeanEnergyFactor,Double_t LevelDensityParameter) // Résolution de l'équation (polynome deuxième degrée en T (température) ) // Asum/[LevelDensityParameter] * T*T + Qi - \Sigma Ek - [NeutronMeanEnergyFactor]*Mn*T - \Sigma Q = 0 // on y obtient directement la température // //Info("Calculate","Debut"); if (!kIsModified) return kTRUE; kIsModified = kFALSE; // premier calcul depuis le dernier remplissage par Fill SumUp(); if (kfree_neutrons_included) { Double_t coefA = GetIngValue("Asum") / GetParValue("LevelDensityParameter"); Double_t coefB = -1.*GetParValue("NeutronMeanEnergyFactor") * GetIngValue("Mneu"); Double_t coefC = GetIngValue("Qini") - GetIngValue("Qsum") - GetIngValue("Eksum"); // Resolution du polynome de degre 2 // Les champs ne sont remplis que si une solution reelle est trouvee if (RootSquare(coefA, coefB, coefC)) { // la solution max donne la temperature SetIngValue("Temp", kracine_max); SetIngValue("Exci", coefA * TMath::Power(GetIngValue("Temp"), 2.)); // ajout de l'energie des neutrons a l energie totale de la source SetIngValue("Ekneu", GetParValue("NeutronMeanEnergyFactor") * GetIngValue("Mneu")*GetIngValue("Temp")); AddIngValue("Eksum", GetIngValue("Ekneu")); //parametre additionnel //SetIngValue("Tmin",kracine_min); // la deuxieme solution de l'eq en T2 } else { return kFALSE; } } else { ComputeExcitationEnergy(); if (ktempdeduced) { ComputeTemperature(); } } return kTRUE; }
//________________________________________________________________ void KVCalorimetry::SumUp() { // protected method // Appelé par Calculate pour mettre à jour les différents ingrédients // de la calorimétrie : // // Trois modes de sommes: //------------------ // - mode normal (par defaut) // détermination de l excès de masse de la source recontruite, dernier ingrédient de l'équation : // Exci + Qini = \Sigma Ek + \Sigma Q -> Exci = \Sigma Ek + \Sigma Q - Qini // // - mode avec distinction particules / fragments, actif si la méthode // UseChargeDiff(Int_t FragmentMinimumCharge,Double_t ParticleFactor) a été appelée : // -> une distinction entre produits avec une charge strictement inférieur à FragmentMinimumCharge (particules) // et supérieur ou égale (fragments) est appliquée // Ainsi dans la méthode SumUp() pour les énergies cinétiques, par exemple // l'énergie cinétique de la source reconstruite sera // Eksum = Ekfrag(Z>=[FragmentMinimumCharge]) + [ParticleFactor]*Ekpart(Z<[FragmentMinimumCharge]) // Détermination ensuite de l excès de masse de la source // // - mode avec prise en compte des neutrons libres, actif si la métode // IncludeFreeNeutrons(Double_t AsurZ,Double_t NeutronMeanEnergyFactor,Double_t LevelDensityParameter) // L'estimation du nombre neutrons, est fait en utilisant un AsurZ (paramètre de la calorimétrie) // supposé de la source reconstruite : // le nombre de neutrons libres est alors égal : // Mn = [AsurZ]*Zsum - Asum // Pour un Zsou reconstruit, on rajoute des neutrons pour que le Asou corresponde à un AsurZ prédéfini // On en déduit ensuite l'exces de masse asscoié à ces neutrons // Détermination ensuite de l excès de masse de la source // Les proprietes de la source sont calculees if (kchargediff) { // somme des contributions fragments et particules AddIngValue("Zsum", GetIngValue("Zfrag") + GetParValue("ParticleFactor")*GetIngValue("Zpart")); AddIngValue("Asum", GetIngValue("Afrag") + GetParValue("ParticleFactor")*GetIngValue("Apart")); AddIngValue("Eksum", GetIngValue("Ekfrag") + GetParValue("ParticleFactor")*GetIngValue("Ekpart")); AddIngValue("Qsum", GetIngValue("Qfrag") + GetParValue("ParticleFactor")*GetIngValue("Qpart")); AddIngValue("Msum", GetIngValue("Mfrag") + GetParValue("ParticleFactor")*GetIngValue("Mpart")); } //printf("Eksum=%lf avant neutrons \n",GetIngValue("Eksum")); if (kfree_neutrons_included) { // conservation du AsurZ du systeme --> multiplicite moyenne des neutrons Double_t Mneutron = Double_t(TMath::Nint(GetParValue("AsurZ") * GetIngValue("Zsum") - GetIngValue("Asum"))); if (Mneutron < 0) { //Warning("SumUp","Nombre de neutrons déduits négatif : %1.0lf -> on le met à zéro",Mneutron); SetIngValue("Aexcess", TMath::Abs(Mneutron)); Mneutron = 0; } SetIngValue("Aneu", Mneutron); SetIngValue("Qneu", Mneutron * nn.GetMassExcess(0, 1)); SetIngValue("Mneu", Mneutron); // prise en compte des neutrons dans la source AddIngValue("Asum", GetIngValue("Mneu")); AddIngValue("Qsum", GetIngValue("Qneu")); AddIngValue("Msum", GetIngValue("Mneu")); } //printf("Eksum=%lf apres neutrons \n",GetIngValue("Eksum")); // defaut de masse de la source reconstruite KVCaloBase::SumUp(); }