12 double LonglivedResoWidthCut) :
15 m_PionAnnihilationNumber = 5.;
27 m_StableNormal.clear();
30 long long tpdgid =
ThermalModel()->TPS()->Particle(i).PdgId();
32 if (tpdgid == 211 || tpdgid == 111 || tpdgid == -211
36 m_StableNormal.push_back(i);
41 m_StableAnnihilate.clear();
42 m_StableAnnihilateAnti.clear();
45 m_StableAnnihilate.push_back(i);
46 long long tpdgid =
ThermalModel()->TPS()->Particle(i).PdgId();
49 throw std::runtime_error(
"ThermalModelPCEAnnihilation: No antibaryon with pdg code " + std::to_string(-tpdgid) +
" exists in the list!");
51 m_StableAnnihilateAnti.push_back(idanti);
58 long long tpdgid =
ThermalModel()->TPS()->Particle(i).PdgId();
59 if (tpdgid == 211 || tpdgid == -211 || tpdgid == 111) {
69 throw std::runtime_error(
"ThermalModelPCE::CalculatePCE: Tried to make a PCE calculation without setting the chemical freze-out! Call ThermalModelPCE::SetChemicalFreezeout() first.");
88 BroydenEquationsPCEAnnihilation eqs(
this, mode);
92 std::vector<double> PCEParams(m_StableNormal.size() + m_StableAnnihilate.size() + m_Pions.size(), 0.);
97 for (
int ind = 0; ind < m_StableNormal.size(); ++ind) {
98 int i = m_StableNormal[ind];
105 for (
int ind = 0; ind < m_StableAnnihilate.size(); ++ind) {
106 int i = m_StableAnnihilate[ind];
113 for (
int ind = 0; ind < m_Pions.size(); ++ind) {
114 int i = m_Pions[ind];
132 PCEParams = broydn.
Solve(PCEParams, &crit);
160 for (
int ind = 0; ind < m_StableNormal.size(); ++ind) {
161 int iglob = m_StableNormal[ind];
165 ret[istab] = x[stab_index];
171 for (
int ind = 0; ind < m_StableAnnihilate.size(); ++ind) {
172 int iglob = m_StableAnnihilate[ind];
176 ret[istab] = x[stab_index];
182 for (
int ind = 0; ind < m_Pions.size(); ++ind) {
183 int iglob = m_Pions[ind];
187 ret[istab] = x[stab_index];
193 for (
int ind = 0; ind < m_StableAnnihilate.size(); ++ind) {
194 int iglob = m_StableAnnihilate[ind];
195 int iglobanti = m_StableAnnihilateAnti[ind];
205 ret[istabanti] = -ret[istab] + m_PionAnnihilationNumber / 3. * (ret[istabpip] + ret[istabpiz] + ret[istabpim]);
215 for(
auto& tpdg: annihilationpdgs) {
219 stability_flags[id] = 2;
224 stability_flags[id] = 2;
226 return stability_flags;
231 std::vector<double> ThermalModelPCEAnnihilation::BroydenEquationsPCEAnnihilation::Equations(
const std::vector<double>& x)
233 std::vector<double> ret(x.size(), 0.);
239 std::vector<double> Chem(m_THM->
ThermalModel()->Densities().size(), 0.);
246 ThermalModelBase *model = m_THM->ThermalModel();
247 model->SetChemicalPotentials(Chem);
251 const double& Vtmp = x[x.size() - 1];
252 m_THM->m_ParametersCurrent.V = Vtmp;
255 const double& Ttmp = x[x.size() - 1];
256 m_THM->m_ParametersCurrent.T = Ttmp;
258 double V = m_THM->m_ParametersCurrent.V;
259 model->SetParameters(m_THM->m_ParametersCurrent);
262 model->CalculateDensities();
268 for (
int ind = 0; ind < m_THM->m_StableNormal.size(); ++ind) {
269 int iglob = m_THM->m_StableNormal[ind];
271 int istab = m_THM->StableHadronIndexByGlobalId(iglob);
274 for (
int i = 0; i < m_THM->m_EffectiveCharges.size(); ++i) {
275 totdens += m_THM->m_EffectiveCharges[i][istab] * model->Densities()[i];
278 ret[stab_index] = (totdens * V) / (m_THM->m_StableDensitiesInit[istab] * m_THM->m_ParametersInit.V) - 1.;
284 for (
int ind = 0; ind < m_THM->m_StableAnnihilate.size(); ++ind) {
285 int iglob = m_THM->m_StableAnnihilate[ind];
286 int iglobanti = m_THM->m_StableAnnihilateAnti[ind];
288 int istab = m_THM->StableHadronIndexByGlobalId(iglob);
289 int istabanti = m_THM->StableHadronIndexByGlobalId(iglobanti);
292 for (
int i = 0; i < m_THM->m_EffectiveCharges.size(); ++i) {
293 totdens += m_THM->m_EffectiveCharges[i][istab] * model->Densities()[i];
294 totdens -= m_THM->m_EffectiveCharges[i][istabanti] * model->Densities()[i];
297 double netInit = (m_THM->m_StableDensitiesInit[istab] - m_THM->m_StableDensitiesInit[istabanti]) * m_THM->m_ParametersInit.V;
298 if (abs(netInit) > 1.e-12) {
299 ret[stab_index] = (totdens * V) / netInit - 1.;
302 double sumInit = (m_THM->m_StableDensitiesInit[istab] + m_THM->m_StableDensitiesInit[istabanti]) * m_THM->m_ParametersInit.V;
303 ret[stab_index] = totdens * V / sumInit;
310 int istabpip = m_THM->StableHadronIndexByGlobalId(m_THM->ThermalModel()->TPS()->PdgToId(211));
311 int istabpim = m_THM->StableHadronIndexByGlobalId(m_THM->ThermalModel()->TPS()->PdgToId(-211));
312 int istabpiz = m_THM->StableHadronIndexByGlobalId(m_THM->ThermalModel()->TPS()->PdgToId(111));
315 double netpicurrent = 0.;
316 for (
int i = 0; i < m_THM->m_EffectiveCharges.size(); ++i) {
317 netpicurrent += m_THM->m_EffectiveCharges[i][istabpip] * model->Densities()[i];
318 netpicurrent -= m_THM->m_EffectiveCharges[i][istabpim] * model->Densities()[i];
322 double netpiinit = (m_THM->m_StableDensitiesInit[istabpip] - m_THM->m_StableDensitiesInit[istabpim]) * m_THM->m_ParametersInit.V;
324 if (abs(netpiinit) > 1.e-12) {
325 ret[stab_index] = netpicurrent / netpiinit - 1.;
328 double sumpiinit = (m_THM->m_StableDensitiesInit[istabpip] + m_THM->m_StableDensitiesInit[istabpim]) * m_THM->m_ParametersInit.V;
329 ret[stab_index] = netpicurrent / sumpiinit;
335 double pippi0current = 0.;
336 for (
int i = 0; i < m_THM->m_EffectiveCharges.size(); ++i) {
337 pippi0current += m_THM->m_EffectiveCharges[i][istabpip] * model->Densities()[i];
338 pippi0current -= m_THM->m_EffectiveCharges[i][istabpiz] * model->Densities()[i];
342 double pippi0init = (m_THM->m_StableDensitiesInit[istabpip] - m_THM->m_StableDensitiesInit[istabpiz]) * m_THM->m_ParametersInit.V;
344 if (abs(pippi0init) > 1.e-12) {
345 ret[stab_index] = pippi0current / pippi0init - 1.;
348 double sumpippi0init = (m_THM->m_StableDensitiesInit[istabpip] + m_THM->m_StableDensitiesInit[istabpiz]) * m_THM->m_ParametersInit.V;
349 ret[stab_index] = pippi0current / sumpippi0init;
358 double tretinit = 0.;
361 for (
int i = 0; i < m_THM->m_EffectiveCharges.size(); ++i) {
362 tret += m_THM->m_EffectiveCharges[i][istabpip] * model->Densities()[i] * 2. / m_THM->m_PionAnnihilationNumber;
363 tret += m_THM->m_EffectiveCharges[i][istabpiz] * model->Densities()[i] * 2. / m_THM->m_PionAnnihilationNumber;
364 tret += m_THM->m_EffectiveCharges[i][istabpim] * model->Densities()[i] * 2. / m_THM->m_PionAnnihilationNumber;
368 tretinit += (m_THM->m_StableDensitiesInit[istabpip] + m_THM->m_StableDensitiesInit[istabpiz] +
369 m_THM->m_StableDensitiesInit[istabpim]) * 2. / m_THM->m_PionAnnihilationNumber;
372 for (
int ind = 0; ind < m_THM->m_StableAnnihilate.size(); ++ind) {
373 int iglob = m_THM->m_StableAnnihilate[ind];
374 int iglobanti = m_THM->m_StableAnnihilateAnti[ind];
376 int istab = m_THM->StableHadronIndexByGlobalId(iglob);
377 int istabanti = m_THM->StableHadronIndexByGlobalId(iglobanti);
381 for (
int i = 0; i < m_THM->m_EffectiveCharges.size(); ++i) {
382 tret += m_THM->m_EffectiveCharges[i][istab] * model->Densities()[i];
383 tret += m_THM->m_EffectiveCharges[i][istabanti] * model->Densities()[i];
386 tretinit += m_THM->m_StableDensitiesInit[istab] + m_THM->m_StableDensitiesInit[istabanti];
389 ret[stab_index] = (tret * V) / (tretinit * m_THM->m_ParametersInit.V) - 1.;
395 ret[ret.size() - 1] = model->CalculateEntropyDensity() * V - m_THM->m_EntropyDensityInit * m_THM->m_ParametersInit.V;
396 ret[ret.size() - 1] /= m_THM->m_EntropyDensityInit * m_THM->m_ParametersInit.V;
Sub-class where it is determined whether the required accuracy is achieved in the Broyden's method.
Class implementing the Broyden method to solve a system of non-linear equations.
virtual std::vector< double > Solve(const std::vector< double > &x0, BroydenSolutionCriterium *solcrit=NULL, int max_iterations=MAX_ITERS)
Abstract base class for an HRG model implementation.
int StableHadronIndexByGlobalId(int globalid)
Returns the PCE-based index of the stable hadron based on its global (particle list) index.
std::vector< int > RecalculateStabilityFlags(const std::vector< long long > &annihilationpdgs={2212, 2112})
ThermalModelPCEAnnihilation(ThermalModelBase *THMbase, bool FreezeLonglived=false, double LonglivedResoWidthCut=0.015)
Construct a new ThermalModelPCEAnnihilation object.
std::vector< double > StableChemsFromBroydenInput(const std::vector< double > &x)
Chemical potentials of all PCE-based hadrons from the solution to PCE equations.
virtual void SetStabilityFlags(const std::vector< int > &StabilityFlags)
Manually set the PCE stability flags for all species.
virtual void CalculatePCE(double param, PCEMode mode=AtFixedTemperature)
Solves the equations of partial chemical equilibrium at a fixed temperature or a fixed volume.
bool FreezeLonglivedResonances() const
ThermalModelPCE(ThermalModelBase *THMbase, bool FreezeLonglived=false, double LonglivedResoWidthCut=0.015)
Construct a new ThermalModelPCE object.
double LonglivedResonanceWidthCut() const
int m_StableComponentsNumber
void SetChemicalFreezeout(const ThermalModelParameters ¶ms, const std::vector< double > &ChemInit=std::vector< double >(0))
Sets the chemical freeze-out conditions to be used as an initial condition for PCE calculations.
ThermalModelParameters m_ParametersCurrent
The current PCE thermal paratmeres and chemical potentials.
ThermalModelParameters m_ParametersInit
Parameters at the chemical freeze-out.
bool m_ChemicalFreezeoutSet
Whether the chemical freeze-out "initial" condition has been set.
virtual void SetStabilityFlags(const std::vector< int > &StabilityFlags)
Manually set the PCE stability flags for all species.
ThermalModelBase * m_model
bool UseSahaForNuclei() const
std::vector< int > m_StableMapTo
std::vector< double > m_ChemCurrent
bool m_IsCalculated
Whether PCE has been calculated.
std::vector< int > m_StabilityFlags
std::vector< double > m_ChemInit
static std::vector< int > ComputePCEStabilityFlags(const ThermalParticleSystem *TPS, bool SahaEquationForNuclei=true, bool FreezeLongLived=false, double WidthCut=0.015)
Computes the PCE stability flags based on the provided particle list and a number of parameters.
ThermalModelBase * ThermalModel() const
Pointer to the HRG model used in calculations.
PCEMode
Whether partial chemical equilibrium should be calculated at a fixed value of the temperature or a fi...
@ AtFixedVolume
Partial chemical equilibrium at fixed value of the volume.
@ AtFixedTemperature
Partial chemical equilibrium at fixed value of the temperature.
const std::vector< int > & StabilityFlags() const
std::vector< std::vector< double > > m_EffectiveCharges
bool m_StabilityFlagsSet
PCE configuration, list of stable species etc.
The main namespace where all classes and functions of the Thermal-FIST library reside.