Thermal-FIST 1.6
Package for hadron resonance gas model applications
Loading...
Searching...
No Matches
ThermalModelEVDiagonal.cpp
Go to the documentation of this file.
1/*
2 * Thermal-FIST package
3 *
4 * Copyright (c) 2014-2019 Volodymyr Vovchenko
5 *
6 * GNU General Public License (GPLv3 or later)
7 */
9
10#ifdef USE_OPENMP
11#include <omp.h>
12#endif
13
14#include <vector>
15#include <cmath>
16#include <cassert>
17#include <iostream>
18#include <iomanip>
19#include <fstream>
20#include <sstream>
21
22#include "HRGBase/xMath.h"
24
25#include <Eigen/Dense>
26
27using namespace Eigen;
28
29using namespace std;
30
31namespace thermalfist {
32
35 {
36 m_densitiesid.resize(m_TPS->Particles().size());
37 m_v.resize(m_TPS->Particles().size());
38 m_Volume = params.V;
39 m_TAG = "ThermalModelEVDiagonal";
40
41 m_Ensemble = GCE;
42 m_InteractionModel = DiagonalEV;
43 }
44
45
49
50
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) {
55 m_v[i] = CuteHRGHelper::vr(rad);
56 }
57 }
58
59 void ThermalModelEVDiagonal::FillVirial(const std::vector<double>& ri)
60 {
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;
63 return;
64 }
65 m_v.resize(m_TPS->Particles().size());
66 for (int i = 0; i < m_TPS->ComponentsNumber(); ++i)
67 m_v[i] = CuteHRGHelper::vr(ri[i]);
68 }
69
70 void ThermalModelEVDiagonal::FillVirialEV(const std::vector<double>& vi)
71 {
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;
74 return;
75 }
76 m_v = vi;
77 }
78
79 void ThermalModelEVDiagonal::ReadInteractionParameters(const std::string & filename)
80 {
81 m_v = std::vector<double>(m_TPS->Particles().size(), 0.);
82
83 ifstream fin(filename.c_str());
84 char cc[2000];
85 while (!fin.eof()) {
86 fin.getline(cc, 2000);
87 string tmp = string(cc);
88 vector<string> elems = CuteHRGHelper::split(tmp, '#');
89 if (elems.size() < 1)
90 continue;
91 istringstream iss(elems[0]);
92 long long pdgid;
93 double b;
94 if (iss >> pdgid >> b) {
95 int ind = m_TPS->PdgToId(pdgid);
96 if (ind != -1)
97 m_v[ind] = b;
98 }
99 }
100 fin.close();
101 }
102
103 void ThermalModelEVDiagonal::WriteInteractionParameters(const std::string & filename)
104 {
105 ofstream fout(filename.c_str());
106 fout << "# List of eigenvolume parameters to be used in the Diagonal excluded-volume HRG model"
107 << std::endl;
108 fout << "# Only particles with a non-zero eigenvolume parameter are listed here"
109 << std::endl;
110 fout << "#" << std::setw(14) << "pdg"
111 << std::setw(15) << "v_i[fm^3]"
112 << std::endl;
113 for (int i = 0; i < m_TPS->ComponentsNumber(); ++i) {
114 if (m_v[i] != 0.) {
115 fout << std::setw(15) << m_TPS->Particle(i).PdgId();
116 fout << std::setw(15) << m_v[i];
117 fout << std::endl;
118 }
119 }
120 fout.close();
121 }
122
124 {
125 if (i < 0 || i >= static_cast<int>(m_v.size()))
126 return 0.;
127 return m_v[i];
128 }
129
130
133 m_densitiesid.resize(m_TPS->Particles().size());
134 }
135
136
138 double dMu = -m_v[i] * Pressure;
139
140 return m_TPS->Particles()[i].Density(m_Parameters, IdealGasFunctions::ParticleDensity, m_UseWidth, m_Chem[i] + dMu);
141 }
142
144 double dMu = -m_v[i] * Pressure;
145
146 return m_TPS->Particles()[i].Density(m_Parameters, IdealGasFunctions::Pressure, m_UseWidth, m_Chem[i] + dMu);
147 }
148
150 double dMu = -m_v[i] * Pressure;
151
152 return m_TPS->Particles()[i].ScaledVariance(m_Parameters, m_UseWidth, m_Chem[i] + dMu);
153 }
154
156 double ret = 0.;
157
158 for (int i = 0; i < m_TPS->ComponentsNumber(); ++i) {
159 double dMu = -m_v[i] * P;
160 ret += m_TPS->Particles()[i].Density(m_Parameters, IdealGasFunctions::Pressure, m_UseWidth, m_Chem[i] + dMu);
161 }
162
163 return ret;
164 }
165
167 BroydenEquationsDEV eqs(this);
168 BroydenJacobianDEV jac(this);
169 Broyden broydn(&eqs, &jac);
170 BroydenSolutionCriteriumDEV crit(this, 1.0E-8);
171
172 m_Pressure = Pressure(0.);
173 double mnc = pow(m_Parameters.T, 4.) * pow(xMath::GeVtoifm(), 3.);
174 if (m_Parameters.T == 0.0)
175 mnc = pow(xMath::mnucleon(), 4.) * pow(xMath::GeVtoifm(), 3.);
176 eqs.SetMnc(mnc);
177 jac.SetMnc(mnc);
178 double x0 = log(m_Pressure / mnc);
179 std::vector<double> x(1, x0);
180
181 x = broydn.Solve(x, &crit);
182
183
184
185 double PressureNew = mnc * exp(x[0]);
186
187 // UPDATE: Currently not used
188 //double current_precision = Broyden::TOL;
190 //while (abs(PressureNew) < current_precision && current_precision > 1.e-50 && abs(PressureNew /m_Pressure) < 1.e-5) {
191 // current_precision *= 1.e-10;
192 // x = broydn.Solve(x, &Broyden::BroydenSolutionCriterium(current_precision));
193 // PressureNew = mnc * exp(x[0]);
194 //}
195
196 m_Pressure = PressureNew;
197
198 if (broydn.Iterations() == broydn.MaxIterations())
199 m_LastCalculationSuccessFlag = false;
200 else m_LastCalculationSuccessFlag = true;
201
202 m_MaxDiff = broydn.MaxDifference();
203 }
204
206 m_FluctuationsCalculated = false;
207
209
210 m_wnSum = 0.;
211 m_Densityid = 0.;
212 m_TotalDensity = 0.;
213 m_Suppression = 0.;
214 double densityid = 0., suppression = 0.;
215
217
218#pragma omp parallel for reduction(+:densityid) reduction(+:suppression) if(useOpenMP)
219 for (int i = 0; i < m_TPS->ComponentsNumber(); ++i) {
220 double dMu = -m_v[i] * m_Pressure;
221 m_densitiesid[i] = m_TPS->Particles()[i].Density(m_Parameters, IdealGasFunctions::ParticleDensity, m_UseWidth, m_Chem[i] + dMu);
222 densityid += m_densitiesid[i];
223 suppression += m_v[i] * m_densitiesid[i];
224
225 m_densitiesidnoshift[i] = m_TPS->Particles()[i].Density(m_Parameters, IdealGasFunctions::ParticleDensity, m_UseWidth, m_Chem[i]);
226 }
227
228 m_Densityid = densityid;
229 m_Suppression = suppression;
230
231 m_Suppression = 1. / (1. + m_Suppression);
232
233 for (int i = 0; i < m_TPS->ComponentsNumber(); ++i) {
234 m_densities[i] = m_densitiesid[i] * m_Suppression;
235 m_TotalDensity += m_densities[i];
236 m_wnSum += m_densities[i] * m_TPS->Particles()[i].ScaledVariance(m_Parameters, m_UseWidth, m_Chem[i] - m_v[i] * m_Pressure);
237 }
238
240
241 m_Calculated = true;
243 }
244
246 int NN = m_densities.size();
247 vector<double> tN(NN);
248 for (int i = 0; i < NN; ++i) tN[i] = DensityId(i, m_Pressure);
249
250 vector<double> chi2id(NN);
251 for (int i = 0; i < NN; ++i) {
252 chi2id[i] = m_TPS->Particles()[i].chiDimensionfull(2, m_Parameters, m_UseWidth, m_Chem[i] - m_v[i] * m_Pressure) * xMath::GeVtoifm3();
253 if (tN[i] > 0.0)
254 chi2id[i] *= m_densities[i] / tN[i];
255 }
256
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;
261
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];
268 double tmp = 0.;
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;
272
273 m_dmusdmu[i][j] = (i == j ? 1. : 0.) - m_v[i] * m_densities[j];
274 }
275 }
276
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.;
282 }
283
284 m_TwoParticleCorrelationsCalculated = true;
285 }
286
288 if (!IsTemperatureDerivativesCalculated())
290
291 // Compute dE/dT
292 double ret = 0.;
293
294 double eid = 0., dTbn = 0., bn = 0., dTeidterm = 0., dmueidterm = 0.;
295 for (int i = 0; i < m_TPS->ComponentsNumber(); ++i) {
296 const ThermalParticle &part = m_TPS->Particles()[i];
297 eid += part.Density(m_Parameters, IdealGasFunctions::EnergyDensity, m_UseWidth, m_Chem[i] - m_v[i] * m_Pressure);
298 dTbn += m_v[i] * m_dndT[i];
299 bn += m_v[i] * m_densities[i];
300 dTeidterm += part.Density(m_Parameters, IdealGasFunctions::dedT, m_UseWidth, m_Chem[i] - m_v[i] * m_Pressure);
301 dmueidterm += -m_v[i] * EntropyDensity() * part.Density(m_Parameters, IdealGasFunctions::dedmu, m_UseWidth, m_Chem[i] - m_v[i] * m_Pressure);
302 }
303
304 ret = -dTbn * eid + (1. - bn) * (dTeidterm + dmueidterm);
305
306 return ret;
307 }
308
310 if (!IsTemperatureDerivativesCalculated())
312
313 // Compute ds/dT
314 double ret = 0.;
315
316 double sid = 0., dTbn = 0., bn = 0., dTsidterm = 0., dmusidterm = 0.;
317 for (int i = 0; i < m_TPS->ComponentsNumber(); ++i) {
318 const ThermalParticle &part = m_TPS->Particles()[i];
319 sid += part.Density(m_Parameters, IdealGasFunctions::EntropyDensity, m_UseWidth, m_Chem[i] - m_v[i] * m_Pressure);
320 dTbn += m_v[i] * m_dndT[i];
321 bn += m_v[i] * m_densities[i];
322 dTsidterm += part.Density(m_Parameters, IdealGasFunctions::dsdT, m_UseWidth, m_Chem[i] - m_v[i] * m_Pressure);
323 // ds/dmu = dn/dT (Maxwell relation), dmu*/dT = -b_i * s
324 dmusidterm += -m_v[i] * EntropyDensity() * part.Density(m_Parameters, IdealGasFunctions::dndT, m_UseWidth, m_Chem[i] - m_v[i] * m_Pressure);
325 }
326
327 ret = -dTbn * sid + (1. - bn) * (dTsidterm + dmusidterm);
328
329 return ret;
330 }
331
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.));
337
338 double T = m_Parameters.T;
339
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) {
342 nids[i] = m_TPS->Particles()[i].Density(m_Parameters, IdealGasFunctions::ParticleDensity, m_UseWidth, m_Chem[i] - m_v[i] * m_Pressure);
343 dniddTs[i] = m_TPS->Particles()[i].Density(m_Parameters, IdealGasFunctions::dndT, m_UseWidth, m_Chem[i] - m_v[i] * m_Pressure);
344 chi2ids[i] = m_TPS->Particles()[i].chiDimensionfull(2, m_Parameters, m_UseWidth, m_Chem[i] - m_v[i] * m_Pressure) * xMath::GeVtoifm3();
345 // dchi2idsdT = d(dn^id/dmu*)/dT = T^2 * dchi2/dT + 2 * chi2ids / T
346 // The two terms individually diverge as 1/T but their sum is O(T).
347 // At T=0 the result is exactly zero (Sommerfeld: dn/dmu = const + O(T^2)).
348 if (T > 0.)
349 dchi2idsdT[i] = (T * T * m_TPS->Particles()[i].Density(m_Parameters, IdealGasFunctions::dchi2dT, m_UseWidth, m_Chem[i] - m_v[i] * m_Pressure) * xMath::GeVtoifm3() + 2. * chi2ids[i] / T);
350 else
351 dchi2idsdT[i] = 0.;
352 chi3ids[i] = m_TPS->Particles()[i].chiDimensionfull(3, m_Parameters, m_UseWidth, m_Chem[i] - m_v[i] * m_Pressure) * xMath::GeVtoifm3();
353 }
354
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];
365 }
366
367 double sum_dbndT = (1. - sum_bn) * (1. - sum_bn) * (sum_dTbns - sum_chi2idb2 * s);
368
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]);
371 }
372
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.;
377
378 double tval = 0.;
379 tval += -chi2ids[j] * m_densities[i] * m_v[j];
380 tval += sum_chi2idb2 * m_densities[j] * m_densities[i];
381 if (i == j)
382 tval += chi2ids[i];
383 tval += -chi2ids[i] * m_densities[j] * m_v[i];
384 m_PrimChi2sdT[i][j] += -sum_dbndT * tval;
385
386 tval = 0.;
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]);
393 if (i == j) {
394 tval += dchi2idsdT[i];
395 tval += chi3ids[i] * m_dmusdT[i];
396 }
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];
400
401 m_PrimChi2sdT[i][j] += (1. - sum_bn) * tval;
402
403 // dchi2/dT = dchi2til/dT / T^2 - 2 * chi2til / T^3
404 // Both terms diverge as T -> 0; guard against division by zero.
405 if (T > 0.)
406 m_PrimChi2sdT[i][j] = m_PrimChi2sdT[i][j] / (xMath::GeVtoifm3() * T * T) - 2. * m_PrimCorrel[i][j] / T / T / T / xMath::GeVtoifm3();
407 else
408 m_PrimChi2sdT[i][j] = 0.;
409 }
410 }
411
412 m_TemperatureDerivativesCalculated = true;
414 }
415
416 m_TemperatureDerivativesCalculated = true;
417 }
418
419 // TODO include correlations
426
427 m_FluctuationsCalculated = true;
428
429 for (size_t i = 0; i < m_wprim.size(); ++i) {
430 m_skewprim[i] = ParticleSkewness(i);
431 m_kurtprim[i] = ParticleKurtosis(i);
432 }
433
434 for (size_t i = 0; i < m_wprim.size(); ++i) {
435 m_skewtot[i] = 1.;
436 m_kurttot[i] = 1.;
437 }
438
439 if (IsTemperatureDerivativesCalculated()) {
440 m_TemperatureDerivativesCalculated = false;
442 }
443 }
444
445
446 std::vector<double> ThermalModelEVDiagonal::CalculateChargeFluctuations(const std::vector<double>& chgs, int order, bool dimensionfull)
447 {
448 vector<double> ret(order + 1, 0.);
449
450 // chi1
451 for (size_t i = 0; i < m_densities.size(); ++i)
452 ret[0] += chgs[i] * m_densities[i];
453
454 if (!dimensionfull)
455 ret[0] /= pow(m_Parameters.T * xMath::GeVtoifm(), 3);
456 else
457 ret[0] /= pow(xMath::GeVtoifm(), 3);
458
459 if (order < 2) return ret;
460
461
462
463 // Preparing matrix for system of linear equations
464 int NN = m_densities.size();
465
466 vector<double> MuStar(NN, 0.);
467 for (int i = 0; i < NN; ++i) {
468 MuStar[i] = m_Chem[i] + MuShift(i);
469 }
470
471
472 MatrixXd densMatrix(2 * NN, 2 * NN);
473 VectorXd solVector(2 * NN), xVector(2 * NN);
474
475 vector<double> DensitiesId(m_densities.size()), chi2id(m_densities.size());
476 for (int i = 0; i < NN; ++i) {
477 DensitiesId[i] = m_TPS->Particles()[i].Density(m_Parameters, IdealGasFunctions::ParticleDensity, m_UseWidth, MuStar[i]);
478 chi2id[i] = m_TPS->Particles()[i].chiDimensionfull(2, m_Parameters, m_UseWidth, MuStar[i]) * pow(xMath::GeVtoifm(), 3);
479 }
480
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.;
485 }
486
487 for (int i = 0; i < NN; ++i)
488 for (int j = 0; j < NN; ++j)
489 densMatrix(i, NN + j) = 0.;
490
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];
495 }
496 densMatrix(i, NN + i) = (densMatrix(i, NN + i) - 1.) * chi2id[i];
497 }
498
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.;
504 }
505
506
507 PartialPivLU<MatrixXd> decomp(densMatrix);
508
509 // chi2
510 vector<double> dni(NN, 0.), dmus(NN, 0.);
511
512 for (int i = 0; i < NN; ++i) {
513 xVector[i] = 0.;
514 xVector[NN + i] = chgs[i];
515 }
516
517 solVector = decomp.solve(xVector);
518
519 for (int i = 0; i < NN; ++i) {
520 dni[i] = solVector[i];
521 dmus[i] = solVector[NN + i];
522 }
523
524 for (int i = 0; i < NN; ++i)
525 ret[1] += chgs[i] * dni[i];
526
527 if (!dimensionfull)
528 ret[1] /= pow(m_Parameters.T, 2) * pow(xMath::GeVtoifm(), 3);
529 else
530 ret[1] /= pow(xMath::GeVtoifm(), 3);
531
532 if (order < 3) return ret;
533 // chi3
534 vector<double> d2ni(NN, 0.), d2mus(NN, 0.);
535
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);
539
540 for (int i = 0; i < NN; ++i) {
541 xVector[i] = 0.;
542
543 double tmp = 0.;
544 for (int j = 0; j < NN; ++j) tmp += m_v[j] * dni[j];
545 tmp = -2. * tmp * chi2id[i] * dmus[i];
546 xVector[i] += tmp;
547
548 tmp = 0.;
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];
551 xVector[i] += tmp;
552 }
553 for (int i = 0; i < NN; ++i) {
554 xVector[NN + i] = 0.;
555
556 double tmp = 0.;
557 for (int j = 0; j < NN; ++j) tmp += -m_v[i] * dmus[j] * chi2id[j] * dmus[j];
558
559 xVector[NN + i] = tmp;
560 }
561
562 solVector = decomp.solve(xVector);
563
564 for (int i = 0; i < NN; ++i) {
565 d2ni[i] = solVector[i];
566 d2mus[i] = solVector[NN + i];
567 }
568
569 for (int i = 0; i < NN; ++i)
570 ret[2] += chgs[i] * d2ni[i];
571
572 if (!dimensionfull)
573 ret[2] /= m_Parameters.T * pow(xMath::GeVtoifm(), 3);
574 else
575 ret[2] /= pow(xMath::GeVtoifm(), 3);
576
577
578 if (order < 4) return ret;
579
580 // chi4
581 vector<double> d3ni(NN, 0.), d3mus(NN, 0.);
582
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);
586
587 vector<double> dnis(NN, 0.);
588 for (int i = 0; i < NN; ++i) {
589 dnis[i] = chi2id[i] * dmus[i];
590 }
591
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];
596 }
597
598 for (int i = 0; i < NN; ++i) {
599 xVector[i] = 0.;
600
601 double tmp = 0.;
602 for (int j = 0; j < NN; ++j) tmp += m_v[j] * dni[j];
603 tmp = -3. * tmp * d2nis[i];
604 xVector[i] += tmp;
605
606 tmp = 0.;
607 for (int j = 0; j < NN; ++j) tmp += m_v[j] * d2ni[j];
608 tmp = -3. * tmp * dnis[i];
609 xVector[i] += tmp;
610
611 double tmps = 0.;
612 for (int j = 0; j < NN; ++j) tmps += m_v[j] * m_densities[j];
613
614 tmp = -(tmps - 1.) * chi3id[i] * d2mus[i] * 3. * dmus[i];
615 xVector[i] += tmp;
616
617 tmp = -(tmps - 1.) * chi4id[i] * dmus[i] * dmus[i] * dmus[i];
618 xVector[i] += tmp;
619 }
620 for (int i = 0; i < NN; ++i) {
621 xVector[NN + i] = 0.;
622
623 double tmp = 0.;
624 for (int j = 0; j < NN; ++j) tmp += -2. * m_v[i] * d2mus[j] * dnis[j];
625 xVector[NN + i] += tmp;
626
627 tmp = 0.;
628 for (int j = 0; j < NN; ++j) tmp += -m_v[i] * dmus[j] * d2nis[j];
629 xVector[NN + i] += tmp;
630 }
631
632 solVector = decomp.solve(xVector);
633
634 for (int i = 0; i < NN; ++i) {
635 d3ni[i] = solVector[i];
636 d3mus[i] = solVector[NN + i];
637 }
638
639 for (int i = 0; i < NN; ++i)
640 ret[3] += chgs[i] * d3ni[i];
641
642 ret[3] /= pow(xMath::GeVtoifm(), 3);
643
644 return ret;
645 }
646
647
649 if (!m_Calculated) CalculateDensities();
650 double ret = 0.;
651 double dMu = 0.;
652 for (int i = 0; i < m_TPS->ComponentsNumber(); ++i) {
653 dMu = -m_v[i] * m_Pressure;
654 ret += m_TPS->Particles()[i].Density(m_Parameters, IdealGasFunctions::EnergyDensity, m_UseWidth, m_Chem[i] + dMu);
655 }
656 return ret * m_Suppression;
657 }
658
660 if (!m_Calculated) CalculateDensities();
661 double ret = 0.;
662 double dMu = 0.;
663 for (int i = 0; i < m_TPS->ComponentsNumber(); ++i) {
664 dMu = -m_v[i] * m_Pressure;
665 ret += m_TPS->Particles()[i].Density(m_Parameters, IdealGasFunctions::EntropyDensity, m_UseWidth, m_Chem[i] + dMu);
666 }
667 return ret * m_Suppression;
668 }
669
671 if (!m_Calculated) CalculateDensities();
672 return m_Pressure;
673 }
674
676 if (!m_Calculated) CalculateDensities();
677
678 double dMu = -m_v[part] * m_Pressure;
679 double ret = m_TPS->Particles()[part].Density(m_Parameters, IdealGasFunctions::ScalarDensity, m_UseWidth, m_Chem[part] + dMu);
680 return ret * m_Suppression;
681 }
682
684 {
685 if (!m_Calculated)
687 return m_Suppression;
688 }
689
691 {
692 if (id >= 0. && id < static_cast<int>(m_v.size()))
693 return -m_v[id] * m_Pressure;
694 else
695 return 0.0;
696 }
697
699 double tEV = 0.;
700 for (int i = 0; i < m_TPS->ComponentsNumber(); ++i) {
701 tEV += m_v[i] * m_densities[i] / 4.;
702 }
703 return tEV;
704 }
705
706 void ThermalModelEVDiagonal::SetRadius(int i, double rad)
707 {
708 if (i >= 0 && i < static_cast<int>(m_v.size()))
709 m_v[i] = CuteHRGHelper::vr(rad);
710 }
711
712 double ThermalModelEVDiagonal::VirialCoefficient(int i, int /*j*/) const
713 {
714 return m_v[i];
715 }
716
717 void ThermalModelEVDiagonal::SetVirial(int i, int j, double b)
718 {
719 if (i == j)
720 m_v[i] = b;
721 }
722
723 std::vector<double> ThermalModelEVDiagonal::BroydenEquationsDEV::Equations(const std::vector<double>& x)
724 {
725 std::vector<double> ret(1);
726 double pressure = m_mnc * exp(x[0]);
727
728 ret[0] = pressure - m_THM->Pressure(pressure);
729
730 return ret;
731 }
732
733 std::vector<double> ThermalModelEVDiagonal::BroydenJacobianDEV::Jacobian(const std::vector<double>& x)
734 {
735 double pressure = m_mnc * exp(x[0]);
736
737 double ret = 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);
740 ret += 1.;
741 ret *= pressure;
742
743 return std::vector<double>(1, ret);
744 }
745
746 std::vector<double> ThermalModelEVDiagonal::BroydenEquationsDEVOrig::Equations(const std::vector<double>& x)
747 {
748 std::vector<double> ret(1);
749 ret[0] = x[0] - m_THM->Pressure(x[0]);
750 return ret;
751 }
752
753 std::vector<double> ThermalModelEVDiagonal::BroydenJacobianDEVOrig::Jacobian(const std::vector<double>& x)
754 {
755 const double &pressure = x[0];
756
757 double ret = 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);
760 ret += 1.;
761
762 return std::vector<double>(1, ret);
763 }
764
765 bool ThermalModelEVDiagonal::BroydenSolutionCriteriumDEV::IsSolved(const std::vector<double>& x, const std::vector<double>& f, const std::vector<double>& /*xdelta*/) const
766 {
767 double maxdiff = 0.;
768 for (size_t i = 0; i < x.size(); ++i) {
769 maxdiff = std::max(maxdiff, fabs(f[i]) / m_THM->m_Pressure);
770 }
771 return (maxdiff < m_MaximumError);
772 }
773} // namespace thermalfist
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.
Definition Broyden.h:132
double MaxDifference() const
Definition Broyden.h:239
virtual std::vector< double > Solve(const std::vector< double > &x0, BroydenSolutionCriterium *solcrit=NULL, int max_iterations=MAX_ITERS)
Definition Broyden.cpp:83
int Iterations() const
Definition Broyden.h:229
int MaxIterations() const
Definition Broyden.h:234
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 &params=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.
void FillVirial(const std::vector< double > &ri=std::vector< double >(0))
Fills the vector of particle eigenvolume parameters.
ThermalModelEVDiagonal(ThermalParticleSystem *TPS, const ThermalModelParameters &params=ThermalModelParameters())
Construct a new ThermalModelEVDiagonal object.
virtual void CalculateFluctuations()
Computes the fluctuation observables.
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...
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.
virtual double MuShift(int i) const
The shift in the chemical potential of particle species i due to the excluded volume interactions.
virtual void SolvePressure()
Solves the transcdental equation for the pressure.
virtual void CalculatePrimordialDensities()
Calculates the primordial densities of all species.
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 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 &params, 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 .
Definition xMath.h:25
constexpr double GeVtoifm3()
A constant to transform GeV into fm .
Definition xMath.h:31
constexpr double mnucleon()
Nucleon's mass. Value as in UrQMD.
Definition xMath.h:34
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.
Contains some extra mathematical functions used in the code.