37 m_v.resize(m_TPS->Particles().size());
39 m_TAG =
"ThermalModelEVDiagonal";
52 if (
m_v.size() != m_TPS->Particles().size())
53 m_v.resize(m_TPS->Particles().size());
54 for (
int i = 0; i < m_TPS->ComponentsNumber(); ++i) {
61 if (ri.size() != m_TPS->Particles().size()) {
62 std::cerr <<
"**WARNING** " << m_TAG <<
"::FillVirial(const std::vector<double> & ri): size of ri does not match number of hadrons in the list" << std::endl;
65 m_v.resize(m_TPS->Particles().size());
66 for (
int i = 0; i < m_TPS->ComponentsNumber(); ++i)
72 if (vi.size() != m_TPS->Particles().size()) {
73 std::cerr <<
"**WARNING** " << m_TAG <<
"::FillVirialEV(const std::vector<double> & vi): size of vi does not match number of hadrons in the list" << std::endl;
81 m_v = std::vector<double>(m_TPS->Particles().size(), 0.);
83 ifstream fin(filename.c_str());
86 fin.getline(cc, 2000);
87 string tmp = string(cc);
91 istringstream iss(elems[0]);
94 if (iss >> pdgid >> b) {
95 int ind = m_TPS->PdgToId(pdgid);
105 ofstream fout(filename.c_str());
106 fout <<
"# List of eigenvolume parameters to be used in the Diagonal excluded-volume HRG model"
108 fout <<
"# Only particles with a non-zero eigenvolume parameter are listed here"
110 fout <<
"#" << std::setw(14) <<
"pdg"
111 << std::setw(15) <<
"v_i[fm^3]"
113 for (
int i = 0; i < m_TPS->ComponentsNumber(); ++i) {
115 fout << std::setw(15) << m_TPS->Particle(i).PdgId();
116 fout << std::setw(15) <<
m_v[i];
125 if (i < 0 || i >=
static_cast<int>(
m_v.size()))
152 return m_TPS->Particles()[i].ScaledVariance(m_Parameters, m_UseWidth, m_Chem[i] + dMu);
158 for (
int i = 0; i < m_TPS->ComponentsNumber(); ++i) {
159 double dMu = -
m_v[i] * P;
167 BroydenEquationsDEV eqs(
this);
168 BroydenJacobianDEV jac(
this);
170 BroydenSolutionCriteriumDEV crit(
this, 1.0E-8);
174 if (m_Parameters.T == 0.0)
179 std::vector<double> x(1, x0);
181 x = broydn.
Solve(x, &crit);
185 double PressureNew = mnc * exp(x[0]);
199 m_LastCalculationSuccessFlag =
false;
200 else m_LastCalculationSuccessFlag =
true;
206 m_FluctuationsCalculated =
false;
214 double densityid = 0., suppression = 0.;
218#pragma omp parallel for reduction(+:densityid) reduction(+:suppression) if(useOpenMP)
219 for (
int i = 0; i < m_TPS->ComponentsNumber(); ++i) {
233 for (
int i = 0; i < m_TPS->ComponentsNumber(); ++i) {
236 m_wnSum += m_densities[i] * m_TPS->Particles()[i].ScaledVariance(m_Parameters, m_UseWidth, m_Chem[i] -
m_v[i] *
m_Pressure);
246 int NN = m_densities.size();
247 vector<double> tN(NN);
250 vector<double> chi2id(NN);
251 for (
int i = 0; i < NN; ++i) {
254 chi2id[i] *= m_densities[i] / tN[i];
257 m_PrimCorrel.resize(NN);
258 for (
int i = 0; i < NN; ++i) m_PrimCorrel[i].resize(NN);
259 m_dmusdmu = m_PrimCorrel;
260 m_TotalCorrel = m_PrimCorrel;
262 for (
int i = 0; i < NN; ++i) {
263 for (
int j = 0; j < NN; ++j) {
264 m_PrimCorrel[i][j] = 0.;
265 if (i == j) m_PrimCorrel[i][j] += chi2id[i];
266 m_PrimCorrel[i][j] += -
m_v[i] * m_densities[j] * chi2id[i];
267 m_PrimCorrel[i][j] += -
m_v[j] * m_densities[i] * chi2id[j];
269 for (
size_t k = 0; k < m_densities.size(); ++k)
270 tmp +=
m_v[k] *
m_v[k] * chi2id[k];
271 m_PrimCorrel[i][j] += m_densities[i] * m_densities[j] * tmp;
273 m_dmusdmu[i][j] = (i == j ? 1. : 0.) -
m_v[i] * m_densities[j];
277 for (
int i = 0; i < NN; ++i) {
278 m_wprim[i] = m_PrimCorrel[i][i];
279 if (m_densities[i] > 0.) m_wprim[i] *= m_Parameters.T / m_densities[i];
280 else m_wprim[i] = 1.;
281 if (m_wprim[i] != m_wprim[i]) m_wprim[i] = 1.;
284 m_TwoParticleCorrelationsCalculated =
true;
288 if (!IsTemperatureDerivativesCalculated())
294 double eid = 0., dTbn = 0., bn = 0., dTeidterm = 0., dmueidterm = 0.;
295 for (
int i = 0; i < m_TPS->ComponentsNumber(); ++i) {
298 dTbn +=
m_v[i] * m_dndT[i];
299 bn +=
m_v[i] * m_densities[i];
304 ret = -dTbn * eid + (1. - bn) * (dTeidterm + dmueidterm);
310 if (!IsTemperatureDerivativesCalculated())
316 double sid = 0., dTbn = 0., bn = 0., dTsidterm = 0., dmusidterm = 0.;
317 for (
int i = 0; i < m_TPS->ComponentsNumber(); ++i) {
320 dTbn +=
m_v[i] * m_dndT[i];
321 bn +=
m_v[i] * m_densities[i];
327 ret = -dTbn * sid + (1. - bn) * (dTsidterm + dmusidterm);
333 int N = m_TPS->ComponentsNumber();
334 m_dndT = vector<double>(N, 0.);
335 m_dmusdT = vector<double>(N, 0.);
336 m_PrimChi2sdT = vector<vector<double>>(N, vector<double>(N, 0.));
338 double T = m_Parameters.T;
340 vector<double> nids(N, 0.), dniddTs(N, 0.), chi2ids(N, 0.), dchi2idsdT(N, 0.), chi3ids(N, 0.);
341 for (
int i = 0; i < N; ++i) {
355 double s = EntropyDensity();
356 double sum_chi2idb2 = 0., sum_bns= 0., sum_bn = 0., sum_dTbns = 0., sum_dchi2dTidb2 = 0., sum_chi3idb3 = 0.;
357 for (
int i = 0; i < N; ++i) {
358 m_dmusdT[i] = -
m_v[i] * s;
359 sum_chi2idb2 +=
m_v[i] *
m_v[i] * chi2ids[i];
360 sum_bns +=
m_v[i] * nids[i];
361 sum_bn +=
m_v[i] * m_densities[i];
362 sum_dTbns +=
m_v[i] * dniddTs[i];
363 sum_dchi2dTidb2 +=
m_v[i] *
m_v[i] * dchi2idsdT[i];
364 sum_chi3idb3 +=
m_v[i] *
m_v[i] *
m_v[i] * chi3ids[i];
367 double sum_dbndT = (1. - sum_bn) * (1. - sum_bn) * (sum_dTbns - sum_chi2idb2 * s);
369 for (
int i = 0; i < N; ++i) {
370 m_dndT[i] = -sum_dbndT * nids[i] + (1. - sum_bn) * (dniddTs[i] + chi2ids[i] * m_dmusdT[i]);
373 if (IsSusceptibilitiesCalculated()) {
374 for (
int i = 0; i < N; ++i) {
375 for (
int j = 0; j < N; ++j) {
376 m_PrimChi2sdT[i][j] = 0.;
379 tval += -chi2ids[j] * m_densities[i] *
m_v[j];
380 tval += sum_chi2idb2 * m_densities[j] * m_densities[i];
383 tval += -chi2ids[i] * m_densities[j] *
m_v[i];
384 m_PrimChi2sdT[i][j] += -sum_dbndT * tval;
387 tval += -dchi2idsdT[j] * m_densities[i] *
m_v[j];
388 tval += -chi3ids[j] * m_dmusdT[j] * m_densities[i] *
m_v[j];
389 tval += -chi2ids[j] * m_dndT[i] *
m_v[j];
390 tval += sum_dchi2dTidb2 * m_densities[j] * m_densities[i];
391 tval += -sum_chi3idb3 * s * m_densities[j] * m_densities[i];
392 tval += sum_chi2idb2 * (m_dndT[j] * m_densities[i] + m_densities[j] * m_dndT[i]);
394 tval += dchi2idsdT[i];
395 tval += chi3ids[i] * m_dmusdT[i];
397 tval += -dchi2idsdT[i] * m_densities[j] *
m_v[i];
398 tval += -chi3ids[i] * m_dmusdT[i] * m_densities[j] *
m_v[i];
399 tval += -chi2ids[i] * m_dndT[j] *
m_v[i];
401 m_PrimChi2sdT[i][j] += (1. - sum_bn) * tval;
408 m_PrimChi2sdT[i][j] = 0.;
412 m_TemperatureDerivativesCalculated =
true;
416 m_TemperatureDerivativesCalculated =
true;
427 m_FluctuationsCalculated =
true;
429 for (
size_t i = 0; i < m_wprim.size(); ++i) {
434 for (
size_t i = 0; i < m_wprim.size(); ++i) {
439 if (IsTemperatureDerivativesCalculated()) {
440 m_TemperatureDerivativesCalculated =
false;
448 vector<double> ret(order + 1, 0.);
451 for (
size_t i = 0; i < m_densities.size(); ++i)
452 ret[0] += chgs[i] * m_densities[i];
459 if (order < 2)
return ret;
464 int NN = m_densities.size();
466 vector<double> MuStar(NN, 0.);
467 for (
int i = 0; i < NN; ++i) {
468 MuStar[i] = m_Chem[i] +
MuShift(i);
472 MatrixXd densMatrix(2 * NN, 2 * NN);
473 VectorXd solVector(2 * NN), xVector(2 * NN);
475 vector<double> DensitiesId(m_densities.size()), chi2id(m_densities.size());
476 for (
int i = 0; i < NN; ++i) {
478 chi2id[i] = m_TPS->Particles()[i].chiDimensionfull(2, m_Parameters, m_UseWidth, MuStar[i]) * pow(
xMath::GeVtoifm(), 3);
481 for (
int i = 0; i < NN; ++i)
482 for (
int j = 0; j < NN; ++j) {
483 densMatrix(i, j) =
m_v[j] * DensitiesId[i];
484 if (i == j) densMatrix(i, j) += 1.;
487 for (
int i = 0; i < NN; ++i)
488 for (
int j = 0; j < NN; ++j)
489 densMatrix(i, NN + j) = 0.;
491 for (
int i = 0; i < NN; ++i) {
492 densMatrix(i, NN + i) = 0.;
493 for (
int k = 0; k < NN; ++k) {
494 densMatrix(i, NN + i) +=
m_v[k] * m_densities[k];
496 densMatrix(i, NN + i) = (densMatrix(i, NN + i) - 1.) * chi2id[i];
499 for (
int i = 0; i < NN; ++i)
500 for (
int j = 0; j < NN; ++j) {
501 densMatrix(NN + i, j) = 0.;
502 densMatrix(NN + i, NN + j) =
m_v[i] * DensitiesId[j];
503 if (i == j) densMatrix(NN + i, NN + j) += 1.;
507 PartialPivLU<MatrixXd> decomp(densMatrix);
510 vector<double> dni(NN, 0.), dmus(NN, 0.);
512 for (
int i = 0; i < NN; ++i) {
514 xVector[NN + i] = chgs[i];
517 solVector = decomp.solve(xVector);
519 for (
int i = 0; i < NN; ++i) {
520 dni[i] = solVector[i];
521 dmus[i] = solVector[NN + i];
524 for (
int i = 0; i < NN; ++i)
525 ret[1] += chgs[i] * dni[i];
532 if (order < 3)
return ret;
534 vector<double> d2ni(NN, 0.), d2mus(NN, 0.);
536 vector<double> chi3id(m_densities.size());
537 for (
int i = 0; i < NN; ++i)
538 chi3id[i] = m_TPS->Particles()[i].chiDimensionfull(3, m_Parameters, m_UseWidth, MuStar[i]) * pow(
xMath::GeVtoifm(), 3);
540 for (
int i = 0; i < NN; ++i) {
544 for (
int j = 0; j < NN; ++j) tmp +=
m_v[j] * dni[j];
545 tmp = -2. * tmp * chi2id[i] * dmus[i];
549 for (
int j = 0; j < NN; ++j) tmp +=
m_v[j] * m_densities[j];
550 tmp = -(tmp - 1.) * chi3id[i] * dmus[i] * dmus[i];
553 for (
int i = 0; i < NN; ++i) {
554 xVector[NN + i] = 0.;
557 for (
int j = 0; j < NN; ++j) tmp += -
m_v[i] * dmus[j] * chi2id[j] * dmus[j];
559 xVector[NN + i] = tmp;
562 solVector = decomp.solve(xVector);
564 for (
int i = 0; i < NN; ++i) {
565 d2ni[i] = solVector[i];
566 d2mus[i] = solVector[NN + i];
569 for (
int i = 0; i < NN; ++i)
570 ret[2] += chgs[i] * d2ni[i];
578 if (order < 4)
return ret;
581 vector<double> d3ni(NN, 0.), d3mus(NN, 0.);
583 vector<double> chi4id(m_densities.size());
584 for (
int i = 0; i < NN; ++i)
585 chi4id[i] = m_TPS->Particles()[i].chiDimensionfull(4, m_Parameters, m_UseWidth, MuStar[i]) * pow(
xMath::GeVtoifm(), 3);
587 vector<double> dnis(NN, 0.);
588 for (
int i = 0; i < NN; ++i) {
589 dnis[i] = chi2id[i] * dmus[i];
592 vector<double> d2nis(NN, 0.);
593 for (
int i = 0; i < NN; ++i) {
594 d2nis[i] = chi3id[i] * dmus[i] * dmus[i] +
595 chi2id[i] * d2mus[i];
598 for (
int i = 0; i < NN; ++i) {
602 for (
int j = 0; j < NN; ++j) tmp +=
m_v[j] * dni[j];
603 tmp = -3. * tmp * d2nis[i];
607 for (
int j = 0; j < NN; ++j) tmp +=
m_v[j] * d2ni[j];
608 tmp = -3. * tmp * dnis[i];
612 for (
int j = 0; j < NN; ++j) tmps +=
m_v[j] * m_densities[j];
614 tmp = -(tmps - 1.) * chi3id[i] * d2mus[i] * 3. * dmus[i];
617 tmp = -(tmps - 1.) * chi4id[i] * dmus[i] * dmus[i] * dmus[i];
620 for (
int i = 0; i < NN; ++i) {
621 xVector[NN + i] = 0.;
624 for (
int j = 0; j < NN; ++j) tmp += -2. *
m_v[i] * d2mus[j] * dnis[j];
625 xVector[NN + i] += tmp;
628 for (
int j = 0; j < NN; ++j) tmp += -
m_v[i] * dmus[j] * d2nis[j];
629 xVector[NN + i] += tmp;
632 solVector = decomp.solve(xVector);
634 for (
int i = 0; i < NN; ++i) {
635 d3ni[i] = solVector[i];
636 d3mus[i] = solVector[NN + i];
639 for (
int i = 0; i < NN; ++i)
640 ret[3] += chgs[i] * d3ni[i];
652 for (
int i = 0; i < m_TPS->ComponentsNumber(); ++i) {
663 for (
int i = 0; i < m_TPS->ComponentsNumber(); ++i) {
692 if (
id >= 0. &&
id <
static_cast<int>(
m_v.size()))
700 for (
int i = 0; i < m_TPS->ComponentsNumber(); ++i) {
701 tEV +=
m_v[i] * m_densities[i] / 4.;
708 if (i >= 0 && i <
static_cast<int>(
m_v.size()))
723 std::vector<double> ThermalModelEVDiagonal::BroydenEquationsDEV::Equations(
const std::vector<double>& x)
725 std::vector<double> ret(1);
726 double pressure = m_mnc * exp(x[0]);
728 ret[0] = pressure - m_THM->
Pressure(pressure);
733 std::vector<double> ThermalModelEVDiagonal::BroydenJacobianDEV::Jacobian(
const std::vector<double>& x)
735 double pressure = m_mnc * exp(x[0]);
738 for (
size_t i = 0; i < m_THM->Densities().size(); ++i)
739 ret += m_THM->VirialCoefficient(i, i) * m_THM->DensityId(i, pressure);
743 return std::vector<double>(1, ret);
746 std::vector<double> ThermalModelEVDiagonal::BroydenEquationsDEVOrig::Equations(
const std::vector<double>& x)
748 std::vector<double> ret(1);
749 ret[0] = x[0] - m_THM->Pressure(x[0]);
753 std::vector<double> ThermalModelEVDiagonal::BroydenJacobianDEVOrig::Jacobian(
const std::vector<double>& x)
755 const double &pressure = x[0];
758 for (
size_t i = 0; i < m_THM->Densities().size(); ++i)
759 ret += m_THM->VirialCoefficient(i, i) * m_THM->DensityId(i, pressure);
762 return std::vector<double>(1, ret);
765 bool ThermalModelEVDiagonal::BroydenSolutionCriteriumDEV::IsSolved(
const std::vector<double>& x,
const std::vector<double>& f,
const std::vector<double>& )
const
768 for (
size_t i = 0; i < x.size(); ++i) {
769 maxdiff = std::max(maxdiff, fabs(f[i]) / m_THM->m_Pressure);
771 return (maxdiff < m_MaximumError);
Contains some functions to deal with excluded volumes.
map< string, double > params
Class implementing the Broyden method to solve a system of non-linear equations.
double MaxDifference() const
virtual std::vector< double > Solve(const std::vector< double > &x0, BroydenSolutionCriterium *solcrit=NULL, int max_iterations=MAX_ITERS)
int MaxIterations() const
virtual void CalculateSusceptibilityMatrix()
Calculates the conserved charges susceptibility matrix.
virtual void ChangeTPS(ThermalParticleSystem *TPS)
Change the particle list.
virtual void CalculateParticleChargeCorrelationMatrix()
Calculates the matrix of correlators between primordial (and also final) particle numbers and conserv...
@ DiagonalEV
Diagonal excluded volume model.
virtual void CalculateFeeddown()
Calculates the total densities which include feeddown contributions.
virtual void ValidateCalculation()
Checks whether issues have occured during the calculation of particle densities in the CalculateDensi...
virtual void CalculateProxySusceptibilityMatrix()
Calculates the susceptibility matrix of conserved charges proxies.
ThermalModelBase(ThermalParticleSystem *TPS, const ThermalModelParameters ¶ms=ThermalModelParameters())
Construct a new ThermalModelBase object.
virtual void CalculateDensities()
Calculates the primordial and total (after decays) densities of all species.
@ GCE
Grand canonical ensemble.
virtual void CalculateTwoParticleFluctuationsDecays()
Computes particle number correlations and fluctuations for all final-state particles which are marked...
double DensityId(int i, double Pressure)
Calculate the ideal gas density of particle species i for the given pressure value.
double ExcludedVolume(int i) const
The excluded volume parameter of particle species i.
virtual double CalculateEntropyDensityDerivativeT()
std::vector< double > m_densitiesidnoshift
void FillVirial(const std::vector< double > &ri=std::vector< double >(0))
Fills the vector of particle eigenvolume parameters.
ThermalModelEVDiagonal(ThermalParticleSystem *TPS, const ThermalModelParameters ¶ms=ThermalModelParameters())
Construct a new ThermalModelEVDiagonal object.
virtual double ParticleScalarDensity(int part)
virtual void CalculateFluctuations()
Computes the fluctuation observables.
virtual double ParticleKurtosis(int)
void SetRadius(double rad)
Set the same excluded volume radius parameter for all species.
virtual void CalculateTemperatureDerivatives()
Computes the temperature derivatives of densities, shifted chemical potentials, and primordial hadron...
virtual double CalculateEnergyDensity()
void FillVirialEV(const std::vector< double > &vi=std::vector< double >(0))
Same as FillVirial() but uses the diagonal excluded-volume coefficients as input instead of radii.
virtual void WriteInteractionParameters(const std::string &filename)
Write the set of eigenvolume parameters for all particles to an external file.
void SetVirial(int i, int j, double b)
Sets the eigenvolume parameter of particle species i.
double CommonSuppressionFactor()
The density suppression factor , common for all species.
double PressureId(int i, double Pressure)
Calculate the ideal gas pressure of particle species i for the given pressure value.
std::vector< double > m_densitiesid
virtual double CalculatePressure()
virtual double MuShift(int i) const
The shift in the chemical potential of particle species i due to the excluded volume interactions.
virtual double CalculateEntropyDensity()
virtual void SolvePressure()
Solves the transcdental equation for the pressure.
std::vector< double > m_v
virtual void CalculatePrimordialDensities()
Calculates the primordial densities of all species.
virtual double ParticleSkewness(int)
virtual double CalculateEigenvolumeFraction()
double ScaledVarianceId(int i, double Pressure)
Calculate the ideal gas scaled variance of particle species i number fluctuations for the given press...
virtual void ReadInteractionParameters(const std::string &filename)
Read the set of eigenvolume parameters for all particles from an external file.
virtual double CalculateEnergyDensityDerivativeT()
virtual void CalculateTwoParticleCorrelations()
Computes the fluctuations and correlations of the primordial particle numbers.
virtual void ChangeTPS(ThermalParticleSystem *TPS)
Change the particle list.
virtual std::vector< double > CalculateChargeFluctuations(const std::vector< double > &chgs, int order=4, bool dimensionfull=false)
Calculates fluctuations (diagonal susceptibilities) of an arbitrary "conserved" charge.
double Pressure(double P)
Computes the l.h.s. of the transcdental equation for the pressure.
double VirialCoefficient(int i, int j) const
Return the eigenvolume parameter of particle species i.
virtual ~ThermalModelEVDiagonal(void)
Destroy the ThermalModelEVDiagonal object.
Class containing all information about a particle specie.
double Density(const ThermalModelParameters ¶ms, IdealGasFunctions::Quantity type=IdealGasFunctions::ParticleDensity, bool useWidth=0, double mu=0.) const
Computes a specified ideal gas thermodynamic function.
Class containing the particle list.
double vr(double r)
Computes the excluded volume parameter from a given radius parameter value.
std::vector< std::string > split(const std::string &s, char delim)
constexpr double GeVtoifm()
A constant to transform GeV into fm .
constexpr double GeVtoifm3()
A constant to transform GeV into fm .
constexpr double mnucleon()
Nucleon's mass. Value as in UrQMD.
The main namespace where all classes and functions of the Thermal-FIST library reside.
Structure containing all thermal parameters of the model.
Contains some extra mathematical functions used in the code.