Thermal-FIST  1.3
Package for hadron resonance gas model applications
ThermalModelVDWCanonicalStrangeness.cpp
Go to the documentation of this file.
1 /*
2  * Thermal-FIST package
3  *
4  * Copyright (c) 2018-2019 Volodymyr Vovchenko
5  *
6  * GNU General Public License (GPLv3 or later)
7  */
9 
10 #include <iostream>
11 #include <iomanip>
12 #include <fstream>
13 #include <sstream>
14 
15 #include "HRGBase/xMath.h"
17 
18 using namespace std;
19 
20 namespace thermalfist {
21 
22  ThermalModelVDWCanonicalStrangeness::ThermalModelVDWCanonicalStrangeness(ThermalParticleSystem *TPS_, const ThermalModelParameters& params) :
24  {
25  m_modelVDW = NULL;
26  m_MuStar.resize(m_densities.size());
27  m_Virial.resize(m_densities.size(), vector<double>(m_densities.size(), 0.));
28  m_Attr = m_Virial;
29  m_TAG = "ThermalModelVDWCanonicalStrangeness";
30 
31  m_Ensemble = SCE;
33  }
34 
36  {
37  ClearModelVDW();
38  }
39 
41  if (m_modelVDW == NULL)
43 
44  for (int i = 0; i < m_TPS->ComponentsNumber(); ++i) {
46  }
47 
48  m_GCECalculated = true;
49  }
50 
52  if (m_modelVDW == NULL)
54 
55  m_energydensitiesGCE.resize(m_densitiesGCE.size());
56  for (int i = 0; i < m_TPS->ComponentsNumber(); ++i) {
58  }
59  }
60 
62  {
63  if (m_modelVDW == NULL)
65 
66  m_pressuresGCE.resize(m_densitiesGCE.size());
67  for (int i = 0; i < m_TPS->ComponentsNumber(); ++i) {
69  }
70  }
71 
72  void ThermalModelVDWCanonicalStrangeness::CalculateSums(const std::vector<double>& Vcs)
73  {
74  if (!m_GCECalculated)
76 
77  m_Zsum.resize(m_StrVals.size());
78 
79  m_partialS.resize(m_StrVals.size());
80  vector<double> xi(3, 0.), yi(3, 0.);
81 
82  for (size_t i = 0; i < m_StrVals.size(); ++i) {
83  m_partialS[i] = 0.;
84  for (int j = 0; j < m_TPS->ComponentsNumber(); ++j)
85  if (m_StrVals[i] == m_TPS->Particles()[j].Strangeness())
86  m_partialS[i] += m_densitiesGCE[j] * Vcs[j];
87  }
88 
89  for (int i = 0; i < 3; ++i) {
90  xi[i] = 2. * sqrt(m_partialS[m_StrMap[i + 1]] * m_partialS[m_StrMap[-(i + 1)]]);
91  yi[i] = sqrt(m_partialS[m_StrMap[i + 1]] / m_partialS[m_StrMap[-(i + 1)]]);
92  }
93 
94  // TODO: Choose iters dynamically based on total strangeness
95  int iters = 20;
96 
97  for (unsigned int i = 0; i < m_StrVals.size(); ++i) {
98  double res = 0.;
99 
100  for (int m = -iters; m <= iters; ++m)
101  for (int n = -iters; n <= iters; ++n) {
102  double tmp = xMath::BesselI(abs(3 * m + 2 * n - m_StrVals[i]), xi[0]) *
103  xMath::BesselI(abs(n), xi[1]) *
104  xMath::BesselI(abs(m), xi[2]) *
105  pow(yi[0], m_StrVals[i] - 3 * m - 2 * n) *
106  pow(yi[1], n) *
107  pow(yi[2], m);
108  if (tmp != tmp) continue;
109  res += tmp;
110  }
111  m_Zsum[i] = res;
112  }
113  }
114 
115 
117  m_FluctuationsCalculated = false;
118 
119  m_energydensitiesGCE.resize(0);
120  m_pressuresGCE.resize(0);
121 
122  PrepareModelVDW();
123 
125 
126  std::vector<double> Vcs(m_TPS->Particles().size(), 0.);
127  for (int i = 0; i < m_TPS->ComponentsNumber(); ++i)
128  Vcs[i] = m_Parameters.SVc * m_Suppression[i];
129 
130  CalculateSums(Vcs);
131 
132  for (int i = 0; i < m_TPS->ComponentsNumber(); ++i) {
133  if (m_StrMap.count(-m_TPS->Particles()[i].Strangeness()))
134  m_densities[i] = m_Suppression[i] * (m_Zsum[m_StrMap[-m_TPS->Particles()[i].Strangeness()]] / m_Zsum[m_StrMap[0]]) * m_densitiesGCE[i];
135  }
136 
137  double tP = CalculatePressure();
138  //printf("VDW-SCE calculation: The following parameter must be much smaller than unity. Otherwise we are in trouble...\n");
139  printf("%s%lf\n", "PS/P = ", (tP - m_PNS) / tP);
140 
142 
143  m_Calculated = true;
145  }
146 
147 
148 
150  double ret = 0.;
151 
152  if (!m_Calculated)
154 
155  if (m_energydensitiesGCE.size() == 0)
157 
159 
160  for (int i = 0; i < m_TPS->ComponentsNumber(); ++i)
161  if (m_TPS->Particles()[i].Strangeness() != 0)
162  if (m_StrMap.count(-m_TPS->Particles()[i].Strangeness()))
163  ret += m_Suppression[i] * (m_Zsum[m_StrMap[-m_TPS->Particles()[i].Strangeness()]] / m_Zsum[m_StrMap[0]]) * m_energydensitiesGCE[i];
164  return ret;
165  }
166 
167 
169  double ret = 0.;
170 
171  if (m_energydensitiesGCE.size() == 0)
173 
175 
176  ret += log(m_Zsum[m_StrMap[0]]) / m_Parameters.SVc;
177 
178  for (int i = 0; i < m_TPS->ComponentsNumber(); ++i)
179  if (m_TPS->Particles()[i].Strangeness() != 0)
180  if (m_StrMap.count(-m_TPS->Particles()[i].Strangeness()))
181  ret += m_Suppression[i] * (m_Zsum[m_StrMap[-m_TPS->Particles()[i].Strangeness()]] / m_Zsum[m_StrMap[0]]) * ((m_energydensitiesGCE[i] - (m_MuStar[i]) * m_densitiesGCE[i]) / m_Parameters.T);
182 
183  return ret;
184  }
185 
186 
188  double ret = 0.;
189  if (m_pressuresGCE.size() == 0)
191 
192  ret += m_modelVDW->CalculatePressure();
193 
194  for (int i = 0; i < m_TPS->ComponentsNumber(); ++i)
195  if (m_TPS->Particles()[i].Strangeness() != 0)
196  if (m_StrMap.count(-m_TPS->Particles()[i].Strangeness()))
197  ret += (m_Zsum[m_StrMap[-m_TPS->Particles()[i].Strangeness()]] / m_Zsum[m_StrMap[0]]) * m_pressuresGCE[i];
198  return ret;
199  }
200 
202  {
203  if (id >= 0. && id < static_cast<int>(m_Virial.size()))
204  return m_MuStar[id] - m_Chem[id];
205  else
206  return 0.0;
207  }
208 
209 
211  {
212  ClearModelVDW();
213 
215 
216  // "Switch off" all strange particles
217  for (size_t i = 0; i < TPSnew->Particles().size(); ++i) {
218  ThermalParticle &part = TPSnew->Particle(i);
219  if (part.Strangeness() != 0)
220  part.SetDegeneracy(0.);
221  }
222 
223  m_modelVDW = new ThermalModelVDWFull(TPSnew);
230 
232 
233  std::vector<double> PidNS(m_modelVDW->Densities().size(), 0.);
234  for (size_t j = 0; j < m_modelVDW->Densities().size(); ++j) {
236  }
237 
239 
240  m_Suppression.resize(TPS()->Particles().size());
241  m_MuStar.resize(TPS()->Particles().size());
242  for (size_t i = 0; i < m_Suppression.size(); ++i) {
243  m_Suppression[i] = 1.0;
244  for (size_t j = 0; j < m_modelVDW->Densities().size(); ++j) {
245  m_Suppression[i] += -m_Virial[j][i] * m_modelVDW->Densities()[j];
246  }
247 
248  m_MuStar[i] = m_Chem[i];
249  for (size_t j = 0; j < m_modelVDW->Densities().size(); ++j) {
250  m_MuStar[i] += -m_Virial[i][j] * PidNS[j];
251  m_MuStar[i] += (m_Attr[i][j] + m_Attr[j][i]) * m_modelVDW->Densities()[j];
252  }
253  }
254  }
255 
257  {
258  if (m_modelVDW != NULL) {
259  ThermalParticleSystem *TPSold = m_modelVDW->TPS();
260  if (TPSold != NULL)
261  delete TPSold;
262  delete m_modelVDW;
263  m_modelVDW = NULL;
264  }
265  }
266 
267  void ThermalModelVDWCanonicalStrangeness::FillVirial(const std::vector<double>& ri)
268  {
269  if (ri.size() != m_TPS->Particles().size()) {
270  printf("**WARNING** %s::FillVirial(const std::vector<double> & ri): size of ri does not match number of hadrons in the list", m_TAG.c_str());
271  return;
272  }
273  m_Virial.resize(m_TPS->Particles().size());
274  for (int i = 0; i < m_TPS->ComponentsNumber(); ++i) {
275  m_Virial[i].resize(m_TPS->Particles().size());
276  for (int j = 0; j < m_TPS->ComponentsNumber(); ++j)
277  m_Virial[i][j] = CuteHRGHelper::brr(ri[i], ri[j]);
278  }
279 
280  // Correct R1=R2 and R2=0
281  std::vector< std::vector<double> > fVirialTmp = m_Virial;
282  for (int i = 0; i < m_TPS->ComponentsNumber(); ++i)
283  for (int j = 0; j < m_TPS->ComponentsNumber(); ++j) {
284  if (i == j) m_Virial[i][j] = fVirialTmp[i][j];
285  else if ((fVirialTmp[i][i] + fVirialTmp[j][j]) > 0.0) m_Virial[i][j] = 2. * fVirialTmp[i][j] * fVirialTmp[i][i] / (fVirialTmp[i][i] + fVirialTmp[j][j]);
286  }
287  }
288 
289  void ThermalModelVDWCanonicalStrangeness::FillVirialEV(const std::vector< std::vector<double> > & bij)
290  {
291  if (bij.size() != m_TPS->Particles().size()) {
292  printf("**WARNING** %s::FillVirialEV(const std::vector<double> & bij): size of bij does not match number of hadrons in the list", m_TAG.c_str());
293  return;
294  }
295  m_Virial = bij;
296  }
297 
298  void ThermalModelVDWCanonicalStrangeness::FillAttraction(const std::vector< std::vector<double> > & aij)
299  {
300  if (aij.size() != m_TPS->Particles().size()) {
301  printf("**WARNING** %s::FillAttraction(const std::vector<double> & aij): size of aij does not match number of hadrons in the list", m_TAG.c_str());
302  return;
303  }
304  m_Attr = aij;
305  }
306 
308  {
309  m_Virial = std::vector< std::vector<double> >(m_TPS->Particles().size(), std::vector<double>(m_TPS->Particles().size(), 0.));
310  m_Attr = std::vector< std::vector<double> >(m_TPS->Particles().size(), std::vector<double>(m_TPS->Particles().size(), 0.));
311 
312  ifstream fin(filename.c_str());
313  char cc[2000];
314  while (!fin.eof()) {
315  fin.getline(cc, 2000);
316  string tmp = string(cc);
317  vector<string> elems = CuteHRGHelper::split(tmp, '#');
318  if (elems.size() < 1)
319  continue;
320  istringstream iss(elems[0]);
321  int pdgid1, pdgid2;
322  double b, a;
323  if (iss >> pdgid1 >> pdgid2 >> b) {
324  if (!(iss >> a))
325  a = 0.;
326  int ind1 = m_TPS->PdgToId(pdgid1);
327  int ind2 = m_TPS->PdgToId(pdgid2);
328  if (ind1 != -1 && ind2 != -1) {
329  m_Virial[ind1][ind2] = b;
330  m_Attr[ind1][ind2] = a;
331  }
332  }
333  }
334  fin.close();
335  }
336 
338  {
339  ofstream fout(filename.c_str());
340  for (int i = 0; i < m_TPS->ComponentsNumber(); ++i) {
341  for (int j = 0; j < m_TPS->ComponentsNumber(); ++j) {
342  fout << std::setw(15) << m_TPS->Particle(i).PdgId();
343  fout << std::setw(15) << m_TPS->Particle(j).PdgId();
344  fout << std::setw(15) << m_Virial[i][j];
345  fout << std::setw(15) << m_Attr[i][j];
346  fout << std::endl;
347  }
348  }
349  fout.close();
350  }
351 
353  {
354  if (i < 0 || i >= static_cast<int>(m_Virial.size()) || j < 0 || j >= static_cast<int>(m_Virial.size()))
355  return 0.;
356  return m_Virial[i][j];
357  }
358 
360  {
361  if (i < 0 || i >= static_cast<int>(m_Attr.size()) || j < 0 || j >= static_cast<int>(m_Attr.size()))
362  return 0.;
363  return m_Attr[i][j];
364  }
365 
367  return (charge == ConservedCharge::StrangenessCharge);
368  }
369 
370 } // namespace thermalfist
std::vector< std::string > split(const std::string &s, char delim)
std::vector< double > m_Chem
Quantum van der Waals model.
const std::vector< double > & Densities() const
virtual void SetChemicalPotentials(const std::vector< double > &chem=std::vector< double >(0))
Sets the chemical potentials of all particles.
double VirialCoefficient(int i, int j) const
Excluded volume coefficient .
virtual void CalculateSums(const std::vector< double > &Vcs)
Calculates the necessary strangeness-canonical partition functions.
const ThermalParticle & Particle(int id) const
ThermalParticle object corresponding to particle species with a provided 0-based index.
virtual void CalculatePressuresGCE()
Calculates the grand-canonical pressures.
double AttractionCoefficient(int i, int j) const
QvdW mean field attraction coefficient .
void FillVirialEV(const std::vector< std::vector< double > > &bij=std::vector< std::vector< double > >(0))
Same as FillVirial() but uses the matrix of excluded-volume coefficients as input instead of radii...
void SetUseWidth(bool useWidth)
Sets whether finite resonance widths are used. Deprecated.
int PdgToId(long long pdgid)
Transforms PDG ID to a 0-based particle id number.
Class implementing the ideal HRG model with exact conservation of strangeness (strangeness-canonical ...
void FillAttraction(const std::vector< std::vector< double > > &aij=std::vector< std::vector< double > >(0))
long long PdgId() const
Particle&#39;s Particle Data Group (PDG) ID number.
Class containing the particle list.
virtual void SetParameters(const ThermalModelParameters &params)
The thermal parameters.
ThermalModelParameters m_Parameters
Structure containing all thermal parameters of the model.
int ComponentsNumber() const
Number of different particle species in the list.
virtual double MuShift(int id) const
The shift in the chemical potential of particle species i due to the QvdW interactions.
virtual void CalculatePrimordialDensities()
Calculates the primordial densities of all species.
virtual bool IsConservedChargeCanonical(ConservedCharge::Name charge) const
Whether the given conserved charge is treated canonically.
virtual void WriteInteractionParameters(const std::string &filename)
Write the QvdW interaction parameters to a file.
Contains some extra mathematical functions used in the code.
ThermalParticleSystem * m_TPS
double BesselI(int n, double x)
integer order modified Bessel function I_n(x)
Definition: xMath.cpp:191
virtual ~ThermalModelVDWCanonicalStrangeness(void)
Destroy the ThermalModelEVCanonicalStrangeness object.
virtual void CalculateEnergyDensitiesGCE()
Calculates the grand-canonical energy densities.
Class containing all information about a particle specie.
double brr(double r1, double r2)
Computes the symmetric 2nd virial coefficient of the classical hard spheres equation of state from t...
const std::vector< ThermalParticle > & Particles() const
Returns the vector of all particle species.
double MuStar(int i) const
The shifted chemical potential of particle species i.
ThermalModelInteraction m_InteractionModel
Contains some functions do deal with excluded volumes.
Name
Set of all conserved charges considered.
bool UseWidth() const
Whether finite resonance widths are considered.
virtual double CalculateEnergyDensity()
virtual double CalculateEntropyDensity()
virtual void CalculateDensities()
Calculates the primordial and total (after decays) densities of all species.
virtual double CalculatePressure()
Implementation of the equation of state functions.
std::vector< double > m_densities
virtual double CalculatePressure()
Implementation of the equation of state functions.
void SetDegeneracy(double deg)
Set particle&#39;s internal degeneracy factor.
Strangeness-canonical ensemble.
ThermalModelEnsemble m_Ensemble
virtual void CalculateFeeddown()
Calculates the total densities which include feeddown contributions.
ThermalModelVDW ThermalModelVDWFull
For backward compatibility.
void FillVirial(const std::vector< double > &ri=std::vector< double >(0))
Fills the excluded volume coefficients based on the provided radii parameters for all species...
virtual void ReadInteractionParameters(const std::string &filename)
Reads the QvdW interaction parameters from a file.
int Strangeness() const
Particle&#39;s strangeness.
const ThermalModelParameters & Parameters() const
virtual void CalculateDensitiesGCE()
Calculates the particle densities in a grand-canonical ensemble.
The main namespace where all classes and functions of the Thermal-FIST library reside.
ThermalParticleSystem * TPS()
void FillVirialEV(const std::vector< std::vector< double > > &bij=std::vector< std::vector< double > >(0))
Same as FillVirial() but uses the matrix of excluded-volume coefficients as input instead of radii...
void SetVolume(double Volume)
Sets the system volume.
void FillAttraction(const std::vector< std::vector< double > > &aij=std::vector< std::vector< double > >(0))