Thermal-FIST 1.6
Package for hadron resonance gas model applications
Loading...
Searching...
No Matches
TestEMMDerivatives.cpp
Go to the documentation of this file.
1/*
2 * Thermal-FIST package
3 *
4 * Test: EMM temperature derivatives with differentiated EV/MF parameters
5 * r_meson = 0.15 fm, r_baryon = 0.4 fm, small mean-field attraction
6 * Tests thermodynamic identity (e+P = Ts + sum mu_i n_i)
7 * and temperature derivatives (ds/dT, de/dT) vs numerical FD
8 */
9#include <iostream>
10#include <iomanip>
11#include <cmath>
12#include <vector>
13#include <string>
14
15#include "HRGBase.h"
16#include "HRGRealGas.h"
17#include "HRGEV.h"
18#include "ThermalFISTConfig.h"
21
22using namespace std;
23using namespace thermalfist;
24
25// Helper: set up a RealGas model with given EV/MF and optionally EMM on pions
27 const vector<vector<double>>& bij, const vector<vector<double>>& aij,
28 bool useEMM,
29 double T, double muB, double muQ, double muS) {
32
33 if (useEMM) {
34 int pdgs[] = {211, 111, -211};
35 for (int pdg : pdgs) {
38 tps.ParticleByPDG(pdg),
39 new EMMFieldPressureChPT(tps.ParticleByPDG(pdg).Mass(), 0.133)));
40 }
41 }
42
44 params.T = T;
45 params.muB = muB;
46 params.muQ = muQ;
47 params.muS = muS;
48 params.muC = 0.;
49 model.SetParameters(params);
50 model.SetStatistics(true);
51 model.ConstrainMuB(false);
52 model.ConstrainMuQ(false);
53 model.ConstrainMuS(false);
54 model.ConstrainMuC(false);
55}
56
57int main() {
58 // Load particle list
59 string listpath = string(ThermalFIST_INPUT_FOLDER) + "/list/PDG2020/list.dat";
60 ThermalParticleSystem TPS(listpath);
61 int N = TPS.Particles().size();
62
63 // EV radii
64 double r_meson = 0.15; // fm
65 double r_baryon = 0.4; // fm
66
67 // Mean-field attraction parameter (GeV fm^3)
68 double a_meson = 0.05;
69 double a_baryon = 0.3;
70
71 // Build bij and aij matrices
72 vector<vector<double>> bij(N, vector<double>(N, 0.));
73 vector<vector<double>> aij(N, vector<double>(N, 0.));
74
75 for (int i = 0; i < N; ++i) {
76 int Bi = TPS.Particles()[i].BaryonCharge();
77 double ri = (Bi == 0) ? r_meson : r_baryon;
78 double ai_coeff = (Bi == 0) ? a_meson : a_baryon;
79 for (int j = 0; j < N; ++j) {
80 int Bj = TPS.Particles()[j].BaryonCharge();
81 double rj = (Bj == 0) ? r_meson : r_baryon;
82 double aj_coeff = (Bj == 0) ? a_meson : a_baryon;
83 bij[i][j] = CuteHRGHelper::brr(ri, rj);
84 aij[i][j] = sqrt(ai_coeff * aj_coeff); // geometric mean
85 }
86 }
87
88 // Helper lambda: run test at given T, muB, muQ, muS
89 auto runTest = [&](double T, double muB, double muQ, double muS, bool useEMM, const string& label) {
90 cout << "=== " << label << " ===" << endl;
91 cout << "T = " << T << " GeV, muB = " << muB << " GeV, muQ = " << muQ << " GeV, muS = " << muS << " GeV" << endl;
92 cout << "EMM on pions: " << (useEMM ? "YES" : "NO") << endl;
93
94 ThermalParticleSystem TPScopy(TPS);
95 ThermalModelRealGas model(&TPScopy);
96 setupModel(model, TPScopy, bij, aij, useEMM, T, muB, muQ, muS);
97 model.CalculateDensities();
98
99 // Check BEC status of pions
100 if (useEMM) {
101 int pdgs[] = {211, 111, -211};
102 const char* names[] = {"pi+", "pi0", "pi-"};
103 for (int ip = 0; ip < 3; ++ip) {
104 int idx = TPScopy.PdgToId(pdgs[ip]);
105 auto* gd = TPScopy.Particles()[idx].GetGeneralizedDensity();
106 if (gd) {
107 cout << " " << names[ip] << ": mu=" << model.ChemicalPotential(idx)
108 << " m*=" << gd->EffectiveMass() << " BEC=" << gd->IsBECPhase() << endl;
109 }
110 }
111 }
112
113 // --- Thermodynamic identity: e + P = T*s + sum(mu_i * n_i) ---
114 double P = model.CalculatePressure();
115 double e = model.CalculateEnergyDensity();
116 double s = model.CalculateEntropyDensity();
117
118 double sum_mu_n = 0.;
119 for (int i = 0; i < model.TPS()->Particles().size(); ++i) {
120 double mu_i = model.ChemicalPotential(i);
121 double n_i = model.Densities()[i]; // primordial
122 sum_mu_n += mu_i * n_i;
123 }
124
125 double lhs = e + P;
126 double rhs = T * s + sum_mu_n;
127 double rel_identity = (lhs != 0.) ? std::abs(lhs - rhs) / std::abs(lhs) : std::abs(lhs - rhs);
128 cout << fixed << setprecision(8);
129 cout << " e + P = " << lhs << endl;
130 cout << " T*s + sum(mu*n) = " << rhs << endl;
131 cout << " Rel. diff = " << scientific << rel_identity << endl;
132
133 // --- Temperature derivatives via CalculateTemperatureDerivatives ---
135 double dsdT_model = model.CalculateEntropyDensityDerivativeT();
136 double dedT_model = model.CalculateEnergyDensityDerivativeT();
137
138 // --- Numerical finite differences ---
139 double dT = 1.e-4 * T;
140
141 // s(T+dT/2)
142 ThermalParticleSystem TPSp(TPS);
143 ThermalModelRealGas model_p(&TPSp);
144 setupModel(model_p, TPSp, bij, aij, useEMM, T + 0.5 * dT, muB, muQ, muS);
145 model_p.CalculateDensities();
146 double s_p = model_p.CalculateEntropyDensity();
147 double e_p = model_p.CalculateEnergyDensity();
148
149 // s(T-dT/2)
150 ThermalParticleSystem TPSm(TPS);
151 ThermalModelRealGas model_m(&TPSm);
152 setupModel(model_m, TPSm, bij, aij, useEMM, T - 0.5 * dT, muB, muQ, muS);
153 model_m.CalculateDensities();
154 double s_m = model_m.CalculateEntropyDensity();
155 double e_m = model_m.CalculateEnergyDensity();
156
157 double dsdT_fd = (s_p - s_m) / dT;
158 double dedT_fd = (e_p - e_m) / dT;
159
160 double rel_dsdT = (dsdT_fd != 0.) ? std::abs(dsdT_model - dsdT_fd) / std::abs(dsdT_fd) : std::abs(dsdT_model - dsdT_fd);
161 double rel_dedT = (dedT_fd != 0.) ? std::abs(dedT_model - dedT_fd) / std::abs(dedT_fd) : std::abs(dedT_model - dedT_fd);
162
163 cout << fixed << setprecision(8);
164 cout << " ds/dT (model) = " << dsdT_model << " (FD) = " << dsdT_fd
165 << " rel.diff = " << scientific << rel_dsdT << endl;
166 cout << " de/dT (model) = " << fixed << dedT_model << " (FD) = " << dedT_fd
167 << " rel.diff = " << scientific << rel_dedT << endl;
168
169 // --- Check dP/dmuB = nB and dP/dmuQ = nQ ---
170 double nB_model = model.CalculateBaryonDensity();
171 double nQ_model = model.CalculateChargeDensity();
172
173 double dmu = 1.e-4 * T; // small shift in chemical potential
174
175 // dP/dmuB via FD
176 {
177 ThermalParticleSystem TPS_Bp(TPS), TPS_Bm(TPS);
178 ThermalModelRealGas m_Bp(&TPS_Bp), m_Bm(&TPS_Bm);
179 setupModel(m_Bp, TPS_Bp, bij, aij, useEMM, T, muB + 0.5 * dmu, muQ, muS);
180 setupModel(m_Bm, TPS_Bm, bij, aij, useEMM, T, muB - 0.5 * dmu, muQ, muS);
181 m_Bp.CalculateDensities();
182 m_Bm.CalculateDensities();
183 double dPdmuB_fd = (m_Bp.CalculatePressure() - m_Bm.CalculatePressure()) / dmu;
184 double rel_nB = (std::abs(nB_model) > 1.e-20) ?
185 std::abs(nB_model - dPdmuB_fd) / std::abs(nB_model) : std::abs(nB_model - dPdmuB_fd);
186 cout << fixed << setprecision(8);
187 cout << " nB (model) = " << nB_model << " dP/dmuB (FD) = " << dPdmuB_fd
188 << " rel.diff = " << scientific << rel_nB << endl;
189 }
190
191 // dP/dmuQ via FD
192 {
193 ThermalParticleSystem TPS_Qp(TPS), TPS_Qm(TPS);
194 ThermalModelRealGas m_Qp(&TPS_Qp), m_Qm(&TPS_Qm);
195 setupModel(m_Qp, TPS_Qp, bij, aij, useEMM, T, muB, muQ + 0.5 * dmu, muS);
196 setupModel(m_Qm, TPS_Qm, bij, aij, useEMM, T, muB, muQ - 0.5 * dmu, muS);
197 m_Qp.CalculateDensities();
198 m_Qm.CalculateDensities();
199 double dPdmuQ_fd = (m_Qp.CalculatePressure() - m_Qm.CalculatePressure()) / dmu;
200 double rel_nQ = (std::abs(nQ_model) > 1.e-20) ?
201 std::abs(nQ_model - dPdmuQ_fd) / std::abs(nQ_model) : std::abs(nQ_model - dPdmuQ_fd);
202 cout << fixed << setprecision(8);
203 cout << " nQ (model) = " << nQ_model << " dP/dmuQ (FD) = " << dPdmuQ_fd
204 << " rel.diff = " << scientific << rel_nQ << endl;
205 }
206
207 cout << endl;
208 };
209
210 cout << "====================================================" << endl;
211 cout << " EMM T-derivative test with differentiated EV/MF" << endl;
212 cout << " r_meson = " << r_meson << " fm, r_baryon = " << r_baryon << " fm" << endl;
213 cout << " a_meson = " << a_meson << ", a_baryon = " << a_baryon << " GeV fm^3" << endl;
214 cout << "====================================================" << endl << endl;
215
216 // Normal phase tests
217 runTest(0.150, 0.0, 0.0, 0.0, false, "T=150 MeV, muB=0, no EMM");
218 runTest(0.150, 0.0, 0.0, 0.0, true, "T=150 MeV, muB=0, with EMM");
219 runTest(0.150, 0.300, 0.0, 0.0, false, "T=150 MeV, muB=300 MeV, no EMM");
220 runTest(0.150, 0.300, 0.0, 0.0, true, "T=150 MeV, muB=300 MeV, with EMM");
221 runTest(0.120, 0.0, 0.0, 0.0, false, "T=120 MeV, muB=0, no EMM");
222 runTest(0.120, 0.0, 0.0, 0.0, true, "T=120 MeV, muB=0, with EMM");
223 runTest(0.120, 0.200, 0.0, 0.0, true, "T=120 MeV, muB=200 MeV, with EMM");
224
225 // BEC phase tests: large muQ pushes pi+ into BEC (mu_pi+ = muQ > m_pi)
226 runTest(0.100, 0.0, 0.200, 0.0, true, "T=100 MeV, muQ=200 MeV, with EMM (BEC)");
227 runTest(0.080, 0.0, 0.200, 0.0, true, "T=80 MeV, muQ=200 MeV, with EMM (BEC)");
228 runTest(0.120, 0.0, 0.150, 0.0, true, "T=120 MeV, muQ=150 MeV, with EMM (near BEC)");
229 runTest(0.100, 0.300, 0.200, 0.0, true, "T=100 MeV, muB=300, muQ=200 MeV, with EMM (BEC)");
230
231 return 0;
232}
233
Header with effective mass model implementation, including the Bose-condensed phase.
Contains some functions to deal with excluded volumes.
map< string, double > params
void setupModel(ThermalModelRealGas &model, ThermalParticleSystem &tps, const vector< vector< double > > &bij, const vector< vector< double > > &aij, bool useEMM, double T, double muB, double muQ, double muS)
int main()
Effective mass model matched to chiral perturbation theory for pions at T = 0. See supplemental mater...
Class implementing an effective mass model for single particle species.
Implementation of the crossterms van der Waals excluded volume model.
Implementation of the van der Waals mean field model for multiple components.
double ChemicalPotential(int i) const
Chemical potential of particle species i.
virtual void SetParameters(const ThermalModelParameters &params)
The thermal parameters.
virtual void CalculateDensities()
Calculates the primordial and total (after decays) densities of all species.
virtual void SetStatistics(bool stats)
Class implementing the quantum real gas HRG model.
void SetExcludedVolumeModel(ExcludedVolumeModelMultiBase *exvolmod)
Set the excluded volume model for the real gas HRG model.
void SetMeanFieldModel(MeanFieldModelMultiBase *mfmod)
Set the mean field model for the real gas HRG model.
virtual double CalculateEnergyDensity()
Calculate the energy density of the system.
virtual void CalculateTemperatureDerivatives()
Calculate the temperature derivatives of the system.
virtual double CalculateEntropyDensity()
Calculate the entropy density of the system.
virtual double CalculateEntropyDensityDerivativeT()
Calculate the derivative of the entropy density with respect to temperature.
virtual double CalculateEnergyDensityDerivativeT()
Calculate the derivative of the energy density with respect to temperature.
virtual double CalculatePressure()
Calculate the pressure of the system.
double Mass() const
Particle's mass [GeV].
void SetGeneralizedDensity(GeneralizedDensity *density_model)
Class containing the particle list.
const std::vector< ThermalParticle > & Particles() const
Returns the vector of all particle species.
const ThermalParticle & ParticleByPDG(long long pdgid) const
ThermalParticle object corresponding to particle species with a provided PDG ID.
double brr(double r1, double r2)
Computes the symmetric 2nd virial coefficient of the classical hard spheres equation of state from t...
The main namespace where all classes and functions of the Thermal-FIST library reside.
Definition CosmicEoS.h:9
Structure containing all thermal parameters of the model.