13 #include <Eigen/Dense> 18 using namespace Eigen;
30 m_FeeddownCalculated(false),
31 m_FluctuationsCalculated(false),
32 m_GCECalculated(false),
60 for (
int i = 0; i < 4; ++i)
m_Susc[i].resize(4);
66 for (
size_t j = 0; j < tpart.
Decays().size(); ++j) {
126 void ThermalModelBase::ResetChemicalPotentials() {
346 printf(
"**WARNING** ThermalModelBase::SetResonanceWidthIntegrationType: Using resonance widths is switched off!\n");
362 printf(
"**WARNING** %s::SetChemicalPotentials(const std::vector<double> & chem): size of chem does not match number of hadrons in the list",
m_TAG.c_str());
370 if (i < 0 || i >= static_cast<int>(
m_Chem.size())) {
371 printf(
"**ERROR** ThermalModelBase::ChemicalPotential(int i): i is out of bounds!");
379 if (i < 0 || i >= static_cast<int>(
m_Chem.size())) {
380 printf(
"**ERROR** ThermalModelBase::FullIdealChemicalPotential(int i): i is out of bounds!");
414 for (
size_t j = 0; j < decayContributions.size(); ++j)
415 if (i != decayContributions[j].second)
427 for (
size_t j = 0; j < decayContributions.size(); ++j)
428 if (i != decayContributions[j].second)
439 if (resetInitialValues)
491 vector<double> x22(4);
496 vector<double> x2(4), xinit(4);
501 int iter = 0, iterMAX = 2;
502 while (iter < iterMAX) {
503 BroydenEquationsChem eqs(
this);
504 BroydenJacobianChem jaco(
this);
505 BroydenChem broydn(
this, &eqs, &jaco);
507 broydn.Solve(x22, &crit);
513 double muBinit,
double muQinit,
double muSinit,
double muCinit,
514 bool ConstrMuB,
bool ConstrMuQ,
bool ConstrMuS,
bool ConstrMuC) {
516 printf(
"**WARNING** PCE enabled, cannot assume chemical equilibrium to do optimization...");
525 allzero &= (totB == 0.0 && ConstrMuB) || (muBinit == 0 && !ConstrMuB);
526 allzero &= (totQ == 0.0 && ConstrMuQ) || (muQinit == 0 && !ConstrMuQ);
527 allzero &= (totS == 0.0 && ConstrMuS) || (muSinit == 0 && !ConstrMuS);
528 allzero &= (totC == 0.0 && ConstrMuC) || (muCinit == 0 && !ConstrMuC);
538 vector<int> vConstr(4, 1);
539 vector<int> vType(4, 0);
546 vType[0] = (int)(totB == 0.0);
547 vType[1] = (int)(totQ == 0.0);
548 vType[2] = (int)(totS == 0.0);
549 vType[3] = (int)(totC == 0.0);
551 vector<double> vTotals(4);
557 vector<double> xin(4, 0.);
563 vector<double> xinactual;
564 for (
int i = 0; i < 4; ++i) {
566 xinactual.push_back(xin[i]);
570 BroydenEquationsChemTotals eqs(vConstr, vType, vTotals,
this);
571 BroydenJacobianChemTotals jaco(vConstr, vType, vTotals,
this);
574 broydn.
Solve(xinactual, &crit);
608 printf(
"**WARNING** %s::CalculateChargeFluctuations(const std::vector<double>& chgs, int order) not implemented!\n",
m_TAG.c_str());
609 return std::vector<double>();
706 if (PDGID == 310 || PDGID == 130)
711 if (PDGID % 10 == 0) {
712 long long tpdgid = PDGID / 10;
721 printf(
"**WARNING** %s: Density with PDG ID %lld not found!\n",
m_TAG.c_str(), PDGID);
728 std::vector<double> *dens = NULL;
736 printf(
"**WARNING** %s: GetDensity: Unknown feeddown: %d\n",
m_TAG.c_str(),
static_cast<int>(feeddown));
786 if (type == 0 && tQ != 0)
788 if (type == 1 && tQ > 0)
790 if (type == -1 && tQ < 0)
801 printf(
"**WARNING** %s: ChargedScaledVariance(int): Fluctuations were not calculated\n",
m_TAG.c_str());
808 if (type == 0 && tQ != 0)
810 if (type == 1 && tQ > 0)
812 if (type == -1 && tQ < 0)
818 if (type == 0 && tQ2 != 0)
820 if (type == 1 && tQ2 > 0)
822 if (type == -1 && tQ2 < 0)
852 printf(
"**WARNING** %s: ChargedScaledVarianceFinal(int): Fluctuations were not calculated\n",
m_TAG.c_str());
869 printf(
"**WARNING** %s: Calculation of two-particle correlations and fluctuations is not implemented\n",
m_TAG.c_str());
880 for (
int i = 0; i < NN; ++i)
886 for (
size_t r = 0; r < decayContributions.size(); ++r) {
887 int rr = decayContributions[r].second;
894 for (
size_t r2 = 0; r2 < decayContributions.size(); ++r2) {
895 int rr2 = decayContributions[r2].second;
903 for (
int i = 0; i < NN; ++i) {
905 for (
int j = 0; j < NN; ++j) {
912 for (
size_t r = 0; r < decayContributionsJ.size(); ++r) {
913 int rr = decayContributionsJ[r].second;
917 for (
size_t r = 0; r < decayContributionsI.size(); ++r) {
918 int rr = decayContributionsI[r].second;
922 for (
size_t r = 0; r < decayContributionsI.size(); ++r) {
923 int rr = decayContributionsI[r].second;
925 for (
size_t r2 = 0; r2 < decayContributionsJ.size(); ++r2) {
926 int rr2 = decayContributionsJ[r2].second;
933 if (r != i && r != j) {
934 double nij = 0., ni = 0., nj = 0., dnij = 0.;
937 for (
size_t br = 0; br < decayDistributions.size(); ++br) {
938 nij += decayDistributions[br].first * decayDistributions[br].second[i] * decayDistributions[br].second[j];
939 ni += decayDistributions[br].first * decayDistributions[br].second[i];
940 nj += decayDistributions[br].first * decayDistributions[br].second[j];
942 dnij = nij - ni * nj;
952 for (
int i = 0; i < NN; ++i) {
962 printf(
"**ERROR** ThermalModelBase::TwoParticleSusceptibilityPrimordial: fluctuations were not computed beforehand! Quitting...\n");
975 printf(
"**WARNING** ThermalModelBase::TwoParticleSusceptibilityPrimordialByPdg: unknown pdg code %lld", id1);
979 printf(
"**WARNING** ThermalModelBase::TwoParticleSusceptibilityPrimordialByPdg: unknown pdg code %lld", id2);
992 printf(
"**WARNING** ThermalModelBase::NetParticleSusceptibilityPrimordialByPdg: unknown pdg code %lld", id1);
996 printf(
"**WARNING** ThermalModelBase::NetParticleSusceptibilityPrimordialByPdg: unknown pdg code %lld", id2);
1004 if (i2 == -1 && j2 == -1) {
1025 printf(
"**ERROR** ThermalModelBase::TwoParticleSusceptibilityFinal: fluctuations were not computed beforehand! Quitting...\n");
1033 printf(
"**ERROR** ThermalModelBase::TwoParticleSusceptibilityFinal: Particle %d is not stable! Final correlations not computed for unstable particles. Quitting...\n", tid);
1046 printf(
"**WARNING** ThermalModelBase::TwoParticleSusceptibilityFinalByPdg: unknown pdg code %lld", id1);
1050 printf(
"**WARNING** ThermalModelBase::TwoParticleSusceptibilityFinalByPdg: unknown pdg code %lld", id2);
1063 printf(
"**WARNING** ThermalModelBase::NetParticleSusceptibilityFinalByPdg: unknown pdg code %lld", id1);
1067 printf(
"**WARNING** ThermalModelBase::NetParticleSusceptibilityFinalByPdg: unknown pdg code %lld", id2);
1075 if (i2 == -1 && j2 == -1) {
1096 printf(
"**ERROR** ThermalModelBase::PrimordialParticleChargeSusceptibility: fluctuations were not computed beforehand! Quitting...\n");
1107 printf(
"**WARNING** ThermalModelBase::PrimordialParticleChargeSusceptibilityByPdg: unknown pdg code %lld", id1);
1118 printf(
"**WARNING** ThermalModelBase::PrimordialNetParticleChargeSusceptibilityByPdg: unknown pdg code %lld", id1);
1132 printf(
"**ERROR** ThermalModelBase::FinalParticleChargeSusceptibility: fluctuations were not computed beforehand! Quitting...\n");
1143 printf(
"**WARNING** ThermalModelBase::FinalParticleChargeSusceptibilityByPdg: unknown pdg code %lld", id1);
1154 printf(
"**WARNING** ThermalModelBase::FinalNetParticleChargeSusceptibilityByPdg: unknown pdg code %lld", id1);
1168 for (
int i = 0; i < 4; ++i)
m_Susc[i].resize(4);
1170 for (
int i = 0; i < 4; ++i) {
1171 for (
int j = 0; j < 4; ++j) {
1196 for (
int i = 0; i < 4; ++i)
1200 for (
int i = 0; i < 3; ++i) {
1201 for (
int j = 0; j < 3; ++j) {
1241 for (
int chg = 0; chg < 4; ++chg) {
1252 for (
int chg = 0; chg < 4; ++chg) {
1256 m_FinalChargesCorrel[i][chg] += c1 * c2 *
m_TotalCorrel[i][j];
1265 printf(
"**WARNING** %s: Calculation of fluctuations is not implemented\n",
m_TAG.c_str());
1268 std::vector<double> ThermalModelBase::BroydenEquationsChem::Equations(
const std::vector<double>& x)
1270 std::vector<double> ret(m_N, 0.);
1273 if (m_THM->ConstrainMuB()) { m_THM->SetBaryonChemicalPotential(x[i1]); i1++; }
1274 if (m_THM->ConstrainMuQ()) { m_THM->SetElectricChemicalPotential(x[i1]); i1++; }
1275 if (m_THM->ConstrainMuS()) { m_THM->SetStrangenessChemicalPotential(x[i1]); i1++; }
1276 if (m_THM->ConstrainMuC()) { m_THM->SetCharmChemicalPotential(x[i1]); i1++; }
1277 m_THM->FillChemicalPotentials();
1278 m_THM->CalculatePrimordialDensities();
1283 if (m_THM->ConstrainMuB()) {
1284 double fBd = m_THM->CalculateBaryonDensity();
1285 double fSd = m_THM->CalculateEntropyDensity();
1287 ret[i1] = (fBd / fSd - 1. / m_THM->SoverB()) * m_THM->SoverB();
1293 if (m_THM->ConstrainMuQ()) {
1294 double fBd = m_THM->CalculateBaryonDensity();
1295 double fQd = m_THM->CalculateChargeDensity();
1298 ret[i1] = (fQd / fBd - m_THM->QoverB());
1306 if (m_THM->ConstrainMuS()) {
1307 double fSd = m_THM->CalculateStrangenessDensity();
1308 double fASd = m_THM->CalculateAbsoluteStrangenessDensity();
1310 ret[i1] = fSd / fASd;
1317 if (m_THM->ConstrainMuC()) {
1318 double fCd = m_THM->CalculateCharmDensity();
1319 double fACd = m_THM->CalculateAbsoluteCharmDensity();
1321 ret[i1] = fCd / fACd;
1329 std::vector<double> ThermalModelBase::BroydenJacobianChem::Jacobian(
const std::vector<double>& x)
1333 if (m_THM->ConstrainMuB()) {
1334 printf(
"**ERROR** Constraining chemical potentials: analytic calculation of the Jacobian not supported if muB is constrained\n");
1338 if (m_THM->ConstrainMuQ()) { m_THM->SetElectricChemicalPotential(x[i1]); i1++; }
1339 if (m_THM->ConstrainMuS()) { m_THM->SetStrangenessChemicalPotential(x[i1]); i1++; }
1340 if (m_THM->ConstrainMuC()) { m_THM->SetCharmChemicalPotential(x[i1]); i1++; }
1341 m_THM->FillChemicalPotentials();
1342 m_THM->CalculatePrimordialDensities();
1344 double fBd = m_THM->CalculateBaryonDensity();
1345 double fQd = m_THM->CalculateChargeDensity();
1346 double fSd = m_THM->CalculateStrangenessDensity();
1347 double fASd = m_THM->CalculateAbsoluteStrangenessDensity();
1348 double fCd = m_THM->CalculateCharmDensity();
1349 double fACd = m_THM->CalculateAbsoluteCharmDensity();
1351 vector<double> wprim;
1352 wprim.resize(m_THM->Densities().size());
1353 for (
size_t i = 0; i < wprim.size(); ++i)
1354 wprim[i] = m_THM->ParticleScaledVariance(i);
1357 if (m_THM->ConstrainMuQ()) NNN++;
1358 if (m_THM->ConstrainMuS()) NNN++;
1359 if (m_THM->ConstrainMuC()) NNN++;
1360 MatrixXd ret(NNN, NNN);
1364 if (m_THM->ConstrainMuQ()) {
1367 double d1 = 0., d2 = 0.;
1369 if (m_THM->ConstrainMuQ()) {
1371 for (
size_t i = 0; i < wprim.size(); ++i)
1372 d1 += m_THM->TPS()->Particle(i).ElectricCharge() * m_THM->TPS()->Particle(i).ElectricCharge() * m_THM->Densities()[i] * wprim[i];
1373 d1 /= m_THM->Parameters().T;
1376 for (
size_t i = 0; i < wprim.size(); ++i)
1377 d2 += m_THM->TPS()->Particle(i).BaryonCharge() * m_THM->TPS()->Particle(i).ElectricCharge() * m_THM->Densities()[i] * wprim[i];
1378 d2 /= m_THM->Parameters().T;
1381 ret(i1, i2) = (d1 / fBd - fQd / fBd / fBd * d2);
1388 if (m_THM->ConstrainMuS()) {
1390 for (
size_t i = 0; i < wprim.size(); ++i)
1391 d1 += m_THM->TPS()->Particle(i).ElectricCharge() * m_THM->TPS()->Particle(i).Strangeness() * m_THM->Densities()[i] * wprim[i];
1392 d1 /= m_THM->Parameters().T;
1395 for (
size_t i = 0; i < wprim.size(); ++i)
1396 d2 += m_THM->TPS()->Particle(i).BaryonCharge() * m_THM->TPS()->Particle(i).Strangeness() * m_THM->Densities()[i] * wprim[i];
1397 d2 /= m_THM->Parameters().T;
1400 ret(i1, i2) = (d1 / fBd - fQd / fBd / fBd * d2);
1407 if (m_THM->ConstrainMuC()) {
1409 for (
size_t i = 0; i < wprim.size(); ++i)
1410 d1 += m_THM->TPS()->Particle(i).ElectricCharge() * m_THM->TPS()->Particle(i).Charm() * m_THM->Densities()[i] * wprim[i];
1411 d1 /= m_THM->Parameters().T;
1414 for (
size_t i = 0; i < wprim.size(); ++i)
1415 d2 += m_THM->TPS()->Particle(i).BaryonCharge() * m_THM->TPS()->Particle(i).Charm() * m_THM->Densities()[i] * wprim[i];
1416 d2 /= m_THM->Parameters().T;
1419 ret(i1, i2) = (d1 / fBd - fQd / fBd / fBd * d2);
1430 if (m_THM->ConstrainMuS()) {
1433 double d1 = 0., d2 = 0.;
1435 if (m_THM->ConstrainMuQ()) {
1437 for (
size_t i = 0; i < wprim.size(); ++i)
1438 d1 += m_THM->TPS()->Particle(i).Strangeness() * m_THM->TPS()->Particle(i).ElectricCharge() * m_THM->Densities()[i] * wprim[i];
1439 d1 /= m_THM->Parameters().T;
1442 for (
size_t i = 0; i < wprim.size(); ++i)
1443 d2 += m_THM->TPS()->Particle(i).AbsoluteStrangeness() * m_THM->TPS()->Particle(i).ElectricCharge() * m_THM->Densities()[i] * wprim[i];
1444 d2 /= m_THM->Parameters().T;
1446 ret(i1, i2) = d1 / fASd - fSd / fASd / fASd * d2;
1452 if (m_THM->ConstrainMuS()) {
1454 for (
size_t i = 0; i < wprim.size(); ++i)
1455 d1 += m_THM->TPS()->Particle(i).Strangeness() * m_THM->TPS()->Particle(i).Strangeness() * m_THM->Densities()[i] * wprim[i];
1456 d1 /= m_THM->Parameters().T;
1459 for (
size_t i = 0; i < wprim.size(); ++i)
1460 d2 += m_THM->TPS()->Particle(i).AbsoluteStrangeness() * m_THM->TPS()->Particle(i).Strangeness() * m_THM->Densities()[i] * wprim[i];
1461 d2 /= m_THM->Parameters().T;
1463 ret(i1, i2) = d1 / fASd - fSd / fASd / fASd * d2;
1469 if (m_THM->ConstrainMuC()) {
1471 for (
size_t i = 0; i < wprim.size(); ++i)
1472 d1 += m_THM->TPS()->Particle(i).Strangeness() * m_THM->TPS()->Particle(i).Charm() * m_THM->Densities()[i] * wprim[i];
1473 d1 /= m_THM->Parameters().T;
1476 for (
size_t i = 0; i < wprim.size(); ++i)
1477 d2 += m_THM->TPS()->Particle(i).AbsoluteStrangeness() * m_THM->TPS()->Particle(i).Charm() * m_THM->Densities()[i] * wprim[i];
1478 d2 /= m_THM->Parameters().T;
1480 ret(i1, i2) = d1 / fASd - fSd / fASd / fASd * d2;
1490 if (m_THM->ConstrainMuC()) {
1493 double d1 = 0., d2 = 0.;
1495 if (m_THM->ConstrainMuQ()) {
1497 for (
size_t i = 0; i < wprim.size(); ++i)
1498 d1 += m_THM->TPS()->Particle(i).Charm() * m_THM->TPS()->Particle(i).ElectricCharge() * m_THM->Densities()[i] * wprim[i];
1499 d1 /= m_THM->Parameters().T;
1502 for (
size_t i = 0; i < wprim.size(); ++i)
1503 d2 += m_THM->TPS()->Particle(i).AbsoluteCharm() * m_THM->TPS()->Particle(i).ElectricCharge() * m_THM->Densities()[i] * wprim[i];
1504 d2 /= m_THM->Parameters().T;
1506 ret(i1, i2) = d1 / fACd - fCd / fACd / fACd * d2;
1512 if (m_THM->ConstrainMuS()) {
1514 for (
size_t i = 0; i < wprim.size(); ++i)
1515 d1 += m_THM->TPS()->Particle(i).Charm() * m_THM->TPS()->Particle(i).Strangeness() * m_THM->Densities()[i] * wprim[i];
1516 d1 /= m_THM->Parameters().T;
1519 for (
size_t i = 0; i < wprim.size(); ++i)
1520 d2 += m_THM->TPS()->Particle(i).AbsoluteCharm() * m_THM->TPS()->Particle(i).Strangeness() * m_THM->Densities()[i] * wprim[i];
1521 d2 /= m_THM->Parameters().T;
1523 ret(i1, i2) = d1 / fACd - fCd / fACd / fACd * d2;
1529 if (m_THM->ConstrainMuC()) {
1531 for (
size_t i = 0; i < wprim.size(); ++i)
1532 d1 += m_THM->TPS()->Particle(i).Charm() * m_THM->TPS()->Particle(i).Charm() * m_THM->Densities()[i] * wprim[i];
1533 d1 /= m_THM->Parameters().T;
1536 for (
size_t i = 0; i < wprim.size(); ++i)
1537 d2 += m_THM->TPS()->Particle(i).AbsoluteCharm() * m_THM->TPS()->Particle(i).Charm() * m_THM->Densities()[i] * wprim[i];
1538 d2 /= m_THM->Parameters().T;
1540 ret(i1, i2) = d1 / fACd - fCd / fACd / fACd * d2;
1548 std::vector<double> retVec(NNN*NNN, 0);
1549 for (
int i = 0; i < NNN; ++i)
1550 for (
int j = 0; j < NNN; ++j)
1551 retVec[i*NNN + j] = ret(i, j);
1557 std::vector<double> ThermalModelBase::BroydenChem::Solve(
const std::vector<double>& x0, BroydenSolutionCriterium * solcrit,
int max_iterations)
1559 if (m_Equations == NULL) {
1560 printf(
"**ERROR** Broyden::Solve: Equations to solve not specified!\n");
1565 std::vector<double> xcur;
1566 if (m_THM->ConstrainMuB()) { xcur.push_back(x0[0]); NNN++; }
1567 if (m_THM->ConstrainMuQ()) { xcur.push_back(x0[1]); NNN++; }
1568 if (m_THM->ConstrainMuS()) { xcur.push_back(x0[2]); NNN++; }
1569 if (m_THM->ConstrainMuC()) { xcur.push_back(x0[3]); NNN++; }
1571 m_THM->FillChemicalPotentials();
1575 m_Equations->SetDimension(NNN);
1577 m_MaxIterations = max_iterations;
1579 BroydenSolutionCriterium *SolutionCriterium = solcrit;
1580 bool UseDefaultSolutionCriterium =
false;
1581 if (SolutionCriterium == NULL) {
1582 SolutionCriterium =
new BroydenSolutionCriterium(TOL);
1583 UseDefaultSolutionCriterium =
true;
1587 bool UseDefaultJacobian =
false;
1588 if (JacobianInUse == NULL || m_THM->ConstrainMuB()) {
1590 UseDefaultJacobian =
true;
1593 double &maxdiff = m_MaxDifference;
1594 int N = m_Equations->Dimension();
1598 std::vector<double> tmpvec, xdeltavec = xcur;
1599 VectorXd xold(N), xnew(N), xdelta(N);
1600 VectorXd fold(N), fnew(N), fdelta(N);
1602 xold = VectorXd::Map(&xcur[0], xcur.size());
1604 MatrixXd Jac = Eigen::Map< Matrix<double, Dynamic, Dynamic, RowMajor> >(&JacobianInUse->
Jacobian(xcur)[0], N, N);
1606 bool constrmuB = m_THM->ConstrainMuB();
1607 bool constrmuQ = m_THM->ConstrainMuQ();
1608 bool constrmuS = m_THM->ConstrainMuS();
1609 bool constrmuC = m_THM->ConstrainMuC();
1610 bool repeat =
false;
1612 if (m_THM->ConstrainMuB()) {
1613 for (
int j = 0; j < Jac.rows(); ++j)
1614 if (Jac(NNN, j) > 1.e8) { repeat =
true; m_THM->ConstrainMuB(
false); }
1615 double S = m_THM->CalculateEntropyDensity();
1616 double nB = m_THM->CalculateBaryonDensity();
1617 if (abs(S) < 1.e-25 || abs(nB) < 1.e-25) { repeat =
true; m_THM->ConstrainMuB(
false); }
1620 if (m_THM->ConstrainMuQ()) {
1621 for (
int j = 0; j < Jac.rows(); ++j)
1622 if (Jac(NNN, j) > 1.e8) { repeat =
true; m_THM->ConstrainMuQ(
false); }
1623 double nQ = m_THM->CalculateChargeDensity();
1624 double nB = m_THM->CalculateBaryonDensity();
1625 if (abs(nQ) < 1.e-25 || abs(nB) < 1.e-25) { repeat =
true; m_THM->ConstrainMuQ(
false); }
1628 if (m_THM->ConstrainMuS()) {
1629 for (
int j = 0; j < Jac.rows(); ++j)
1630 if (Jac(NNN, j) > 1.e8) { repeat =
true; m_THM->ConstrainMuS(
false); }
1632 double nS = m_THM->CalculateAbsoluteStrangenessDensity();
1633 if (abs(nS) < 1.e-25) { repeat =
true; m_THM->ConstrainMuS(
false); }
1636 if (m_THM->ConstrainMuC()) {
1637 for (
int j = 0; j < Jac.rows(); ++j)
1638 if (Jac(NNN, j) > 1.e8) { repeat =
true; m_THM->ConstrainMuC(
false); }
1639 double nC = m_THM->CalculateAbsoluteCharmDensity();
1640 if (abs(nC) < 1.e-25) { repeat =
true; m_THM->ConstrainMuC(
false); }
1644 std::vector<double> ret = Solve(x0, solcrit, max_iterations);
1645 m_THM->ConstrainMuQ(constrmuB);
1646 m_THM->ConstrainMuQ(constrmuQ);
1647 m_THM->ConstrainMuS(constrmuS);
1648 m_THM->ConstrainMuC(constrmuC);
1652 if (Jac.determinant() == 0.0)
1654 printf(
"**WARNING** Singular Jacobian in Broyden::Solve\n");
1658 MatrixXd Jinv = Jac.inverse();
1659 tmpvec = m_Equations->Equations(xcur);
1660 fold = VectorXd::Map(&tmpvec[0], tmpvec.size());
1662 for (m_Iterations = 1; m_Iterations < max_iterations; ++m_Iterations) {
1663 xnew = xold - Jinv * fold;
1665 VectorXd::Map(&xcur[0], xcur.size()) = xnew;
1667 tmpvec = m_Equations->Equations(xcur);
1668 fnew = VectorXd::Map(&tmpvec[0], tmpvec.size());
1672 for (
size_t i = 0; i < xcur.size(); ++i) {
1673 maxdiff = std::max(maxdiff, fabs(fnew[i]));
1676 xdelta = xnew - xold;
1677 fdelta = fnew - fold;
1679 VectorXd::Map(&xdeltavec[0], xdeltavec.size()) = xdelta;
1681 if (SolutionCriterium->IsSolved(xcur, tmpvec, xdeltavec))
1688 for (
int i = 0; i < N; ++i)
1689 for (
int j = 0; j < N; ++j)
1690 norm += xdelta[i] * Jinv(i, j) * fdelta[j];
1692 p1 = (xdelta - Jinv * fdelta);
1693 for (
int i = 0; i < N; ++i) p1[i] *= 1. / norm;
1694 Jinv = Jinv + (p1 * xdelta.transpose()) * Jinv;
1698 Jac = Eigen::Map< Matrix<double, Dynamic, Dynamic, RowMajor> >(&JacobianInUse->
Jacobian(xcur)[0], N, N);
1699 Jinv = Jac.inverse();
1706 if (m_Iterations == max_iterations) {
1707 printf(
"**WARNING** Reached maximum number of iterations in Broyden procedure\n");
1710 if (UseDefaultSolutionCriterium) {
1711 delete SolutionCriterium;
1712 SolutionCriterium = NULL;
1714 if (UseDefaultJacobian) {
1715 delete JacobianInUse;
1716 JacobianInUse = NULL;
1722 ThermalModelBase::BroydenEquationsChemTotals::BroydenEquationsChemTotals(
const std::vector<int>& vConstr,
const std::vector<int>& vType,
const std::vector<double>& vTotals,
ThermalModelBase * model) :
1723 BroydenEquations(), m_Constr(vConstr), m_Type(vType), m_Totals(vTotals), m_THM(model)
1726 for (
size_t i = 0; i < m_Constr.size(); ++i)
1730 std::vector<double> ThermalModelBase::BroydenEquationsChemTotals::Equations(
const std::vector<double>& x)
1732 std::vector<double> ret(m_N, 0.);
1735 for (
int i = 0; i < 4; ++i) {
1737 if (i == 0) m_THM->SetBaryonChemicalPotential(x[i1]);
1738 if (i == 1) m_THM->SetElectricChemicalPotential(x[i1]);
1739 if (i == 2) m_THM->SetStrangenessChemicalPotential(x[i1]);
1740 if (i == 3) m_THM->SetCharmChemicalPotential(x[i1]);
1744 m_THM->FillChemicalPotentials();
1745 m_THM->CalculatePrimordialDensities();
1747 vector<double> dens(4, 0.), absdens(4, 0.);
1749 dens[0] = m_THM->CalculateBaryonDensity();
1750 absdens[0] = m_THM->CalculateAbsoluteBaryonDensity();
1753 dens[1] = m_THM->CalculateChargeDensity();
1754 absdens[1] = m_THM->CalculateAbsoluteChargeDensity();
1757 dens[2] = m_THM->CalculateStrangenessDensity();
1758 absdens[2] = m_THM->CalculateAbsoluteStrangenessDensity();
1761 dens[3] = m_THM->CalculateCharmDensity();
1762 absdens[3] = m_THM->CalculateAbsoluteCharmDensity();
1767 for (
int i = 0; i < 4; ++i) {
1770 ret[i1] = (dens[i] * m_THM->Parameters().V - m_Totals[i]) / m_Totals[i];
1772 ret[i1] = dens[i] / absdens[i];
1780 std::vector<double> ThermalModelBase::BroydenJacobianChemTotals::Jacobian(
const std::vector<double>& x)
1783 for (
int i = 0; i < 4; ++i) NNN += m_Constr[i];
1787 for (
int i = 0; i < 4; ++i) {
1789 if (i == 0) m_THM->SetBaryonChemicalPotential(x[i1]);
1790 if (i == 1) m_THM->SetElectricChemicalPotential(x[i1]);
1791 if (i == 2) m_THM->SetStrangenessChemicalPotential(x[i1]);
1792 if (i == 3) m_THM->SetCharmChemicalPotential(x[i1]);
1797 vector<double> tfug(4, 0.);
1798 tfug[0] = exp(m_THM->Parameters().muB / m_THM->Parameters().T);
1799 tfug[1] = exp(m_THM->Parameters().muQ / m_THM->Parameters().T);
1800 tfug[2] = exp(m_THM->Parameters().muS / m_THM->Parameters().T);
1801 tfug[3] = exp(m_THM->Parameters().muC / m_THM->Parameters().T);
1803 m_THM->FillChemicalPotentials();
1804 m_THM->CalculatePrimordialDensities();
1806 vector<double> dens(4, 0.), absdens(4, 0.);
1808 dens[0] = m_THM->CalculateBaryonDensity();
1809 absdens[0] = m_THM->CalculateAbsoluteBaryonDensity();
1812 dens[1] = m_THM->CalculateChargeDensity();
1813 absdens[1] = m_THM->CalculateAbsoluteChargeDensity();
1816 dens[2] = m_THM->CalculateStrangenessDensity();
1817 absdens[2] = m_THM->CalculateAbsoluteStrangenessDensity();
1820 dens[3] = m_THM->CalculateCharmDensity();
1821 absdens[3] = m_THM->CalculateAbsoluteCharmDensity();
1824 vector<double> wprim;
1825 wprim.resize(m_THM->Densities().size());
1826 for (
size_t i = 0; i < wprim.size(); ++i) wprim[i] = m_THM->ParticleScaledVariance(i);
1828 vector< vector<double> > deriv(4, vector<double>(4)), derivabs(4, vector<double>(4));
1829 for (
int i = 0; i < 4; ++i)
1830 for (
int j = 0; j < 4; ++j) {
1832 for (
size_t part = 0; part < wprim.size(); ++part)
1833 deriv[i][j] += m_THM->TPS()->Particles()[part].GetCharge(i) * m_THM->TPS()->Particles()[part].GetCharge(j) * m_THM->Densities()[part] * wprim[part];
1834 deriv[i][j] /= m_THM->Parameters().T;
1836 derivabs[i][j] = 0.;
1837 for (
size_t part = 0; part < wprim.size(); ++part)
1838 derivabs[i][j] += m_THM->TPS()->Particles()[part].GetAbsCharge(i) * m_THM->TPS()->Particles()[part].GetCharge(j) * m_THM->Densities()[part] * wprim[part];
1839 derivabs[i][j] /= m_THM->Parameters().T;
1843 MatrixXd ret(NNN, NNN);
1847 for (
int i = 0; i < 4; ++i) {
1850 for (
int j = 0; j < 4; ++j)
1854 ret(i1, i2) = deriv[i][j] * m_THM->Parameters().V / m_Totals[i];
1856 ret(i1, i2) = deriv[i][j] / absdens[i] - dens[i] / absdens[i] / absdens[i] * derivabs[i][j];
1863 std::vector<double> retVec(NNN*NNN, 0);
1864 for (
int i = 0; i < NNN; ++i)
1865 for (
int j = 0; j < NNN; ++j)
1866 retVec[i*NNN + j] = ret(i, j);
Feeddown from strong, electromagnetic, and weak decays.
void ConstrainChemicalPotentials(bool resetInitialValues=true)
Constrains the chemical potentials by the conservation laws imposed.
virtual void DisableMesonBaryonAttraction()
const ParticleDecaysVector & DecaysOriginal() const
A backup copy of particle's decays.
Abstract base class for an HRG model implementation.
virtual double PrimordialParticleChargeSusceptibility(int i, ConservedCharge::Name chg) const
Returns the computed primordial particle vs conserved charge (cross-)susceptibility for particle wit...
virtual double CalculateArbitraryChargeDensity()
Computes the density of the auxiliary ArbitraryCharge()
virtual void CalculateTwoParticleFluctuationsDecays()
Computes particle number correlations and fluctuations for all final-state particles which are marked...
virtual double PrimordialNetParticleChargeSusceptibilityByPdg(long long id1, ConservedCharge::Name chg)
Returns the computed primordial net particle vs conserved charge (cross-)susceptibility for particle...
virtual void SetStrangenessChemicalPotential(double muS)
Set the strangeness chemical potential.
std::vector< double > m_Chem
virtual double FinalParticleChargeSusceptibilityByPdg(long long id1, ConservedCharge::Name chg)
Returns the computed final (after decays) particle vs conserved charge (cross-)susceptibility for pa...
virtual double FinalNetParticleChargeSusceptibilityByPdg(long long id1, ConservedCharge::Name chg)
Returns the computed final (after decays) net particle vs conserved charge (cross-)susceptibility fo...
virtual double NetParticleSusceptibilityFinalByPdg(long long id1, long long id2)
Returns the computed (cross-)susceptibility between final net-particle numbers for pdg codes id1 and...
double AbsoluteStrangeness() const
Absolute strange quark content |s|.
virtual void SetGammaS(double gammaS)
Set the strange quark fugacity factor.
Class implementing the Broyden method to solve a system of non-linear equations.
static bool PrintDisclaimer()
double GeVtoifm()
A constant to transform GeV into fm .
virtual void SetElectricChemicalPotential(double muQ)
Set the electric chemical potential.
virtual void SetElectricCharge(int Q)
Set the total electric charge (for canonical ensemble only)
std::vector< double > m_kurttot
std::vector< double > m_wprim
virtual void SetBaryonCharge(int B)
Set the total baryon number (for canonical ensemble only)
virtual double CalculateAbsoluteCharmDensity()
virtual void SetBaryonChemicalPotential(double muB)
Set the baryon chemical potential.
std::vector< std::vector< double > > m_FinalChargesCorrel
const ThermalParticle & Particle(int id) const
ThermalParticle object corresponding to particle species with a provided 0-based index.
std::vector< double > m_skewprim
virtual void SetStatistics(bool stats)
virtual void FixParameters()
Method which actually implements ConstrainChemicalPotentials() (for backward compatibility).
Contains some helper functions.
bool m_FluctuationsCalculated
virtual void SetStrangeness(int S)
Set the total strangeness (for canonical ensemble only)
std::vector< std::vector< double > > m_ProxySusc
bool m_FeeddownCalculated
virtual void DisableBaryonAntiBaryonAttraction()
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.
static bool DisclaimerPrinted
std::vector< std::vector< double > > m_Susc
virtual double TwoParticleSusceptibilityPrimordial(int i, int j) const
Returns the computed primordial particle number (cross-)susceptibility for particles with ids i and ...
Energy-independent Breit-Wigner in +-2 interval.
Feeddown from strong decays.
long long PdgId() const
Particle's Particle Data Group (PDG) ID number.
double ChargedMultiplicity(int type=0)
Multiplicity of charged particles.
virtual double CalculateAbsoluteChargeDensity()
virtual void SetGammaC(double gammaC)
Set the charm quark fugacity factor.
Class containing the particle list.
virtual void CalculatePrimordialDensities()=0
Calculates the primordial densities of all species.
virtual std::vector< double > Jacobian(const std::vector< double > &x)
Evaluates the Jacobian for given values of the variables.
Grand canonical ensemble.
Energy-dependent Breit-Wigner scheme (eBW)
virtual void SetParameters(const ThermalModelParameters ¶ms)
The thermal parameters.
virtual void DisableMesonMesonVirial()
ThermalModelParameters m_Parameters
Structure containing all thermal parameters of the model.
virtual double CalculateStrangenessDensity()
Abstract class which defines the system of non-linear equations to be solved by the Broyden's method...
int ComponentsNumber() const
Number of different particle species in the list.
virtual void SetTemperature(double T)
Set the temperature.
virtual double MuShift(int) const
Shift in chemical potential of particle species id due to interactions.
void NormalizeBranchingRatios()
Normalize branching ratios for all particles such that they add up to 100%.
virtual void SetGammaq(double gammaq)
Set the light quark fugacity factor.
virtual double CalculateHadronDensity()
void SetNormBratio(bool normBratio)
Whether branching ratios are renormalized to 100%.
virtual double CalculateBaryonDensity()
virtual void DisableBaryonBaryonVirial()
static const int NumberOfDecayTypes
virtual double CalculateCharmDensity()
virtual void SetVirial(int, int, double)
Set the excluded volume coefficient .
virtual double FullIdealChemicalPotential(int i) const
Chemical potential entering the ideal gas expressions of particle species i.
virtual void CalculateSusceptibilityMatrix()
Calculates the conserved charges susceptibility matrix.
ThermalParticleSystem * m_TPS
std::vector< double > m_wtot
std::string m_ValidityLog
double ChargedMultiplicityFinal(int type=0)
Multiplicity of charged particles including the feeddown contributions in accordance with the stabili...
virtual void DisableBaryonBaryonAttraction()
Zero-width approximation.
virtual void FillChemicalPotentials()
Sets the chemical potentials of all particles.
std::vector< std::pair< double, std::vector< int > > > ResonanceFinalStatesDistribution
void ResetCalculatedFlags()
Reset all flags which correspond to a calculation status.
virtual void FixParametersNoReset()
Method which actually implements ConstrainChemicalPotentialsNoReset() (for backward compatibility)...
int BaryonCharge() const
Particle's baryon number.
int MaxIterations() const
double ChemicalPotential(int i) const
Chemical potential of particle species i.
ResonanceWidthIntegration
Treatment of finite resonance widths.
Class containing all information about a particle specie.
double ChargedScaledVarianceFinal(int type=0)
Scaled variance of charged particles including the feeddown contributions in accordance with the stab...
std::vector< SingleDecayContribution > DecayContributionsToParticle
A vector of SingleDecayContribution where each element corresponds to a certain resonance species...
virtual void CalculateProxySusceptibilityMatrix()
Calculates the susceptibility matrix of conserved charges proxies.
virtual std::vector< double > Solve(const std::vector< double > &x0, BroydenSolutionCriterium *solcrit=NULL, int max_iterations=MAX_ITERS)
virtual double PrimordialParticleChargeSusceptibilityByPdg(long long id1, ConservedCharge::Name chg)
Returns the computed primordial particle vs conserved charge (cross-)susceptibility for particle wit...
virtual double CalculateChargeDensity()
Sub-class where it is determined whether the required accuracy is achieved in the Broyden's method...
virtual void CalculateTwoParticleCorrelations()
Computes the fluctuations and correlations of the primordial particle numbers.
void SetResonanceWidthIntegrationType(ThermalParticle::ResonanceWidthIntegration type)
Set the ThermalParticle::ResonanceWidthIntegration scheme for all particles. Calls the corresponding ...
double GetDensity(long long PDGID, int feeddown)
Same as GetDensity(int,Feeddown::Type)
const std::string & Name() const
Particle's name.
std::vector< double > m_kurtprim
const std::vector< ThermalParticle > & Particles() const
Returns the vector of all particle species.
std::vector< std::vector< double > > m_TotalCorrel
double ConservedChargeDensity(ConservedCharge::Name chg)
A density of a conserved charge (in fm^-3)
double ChargedScaledVariance(int type=0)
Scaled variance of charged particles.
ThermalModelInteraction m_InteractionModel
virtual void ValidateCalculation()
Checks whether issues have occured during the calculation of particle densities in the CalculateDensi...
const std::vector< ResonanceFinalStatesDistribution > & ResonanceFinalStatesDistributions() const
Final state particle number distributions for resonance decays.
virtual double CalculateAbsoluteStrangenessDensity()
virtual bool SolveChemicalPotentials(double totB=0., double totQ=0., double totS=0., double totC=0., double muBinit=0., double muQinit=0., double muSinit=0., double muCinit=0., bool ConstrMuB=true, bool ConstrMuQ=true, bool ConstrMuS=true, bool ConstrMuC=true)
The procedure which calculates the chemical potentials which reproduce the specified total baryon...
virtual void SetCharmChemicalPotential(double muC)
Set the charm chemical potential.
virtual 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...
void UseStatistics(bool enable)
Use quantum statistics.
virtual double TwoParticleSusceptibilityPrimordialByPdg(long long id1, long long id2)
Returns the computed primordial particle number (cross-)susceptibility for particles with pdg codes ...
void CalculateThermalBranchingRatios(const ThermalModelParameters ¶ms, bool useWidth=0, double mu=0.)
Computes average decay branching ratios by integrating over the thermal mass distribution.
virtual double TwoParticleSusceptibilityFinal(int i, int j) const
Returns the computed final particle number (cross-)susceptibility for particles with ids i and j...
Name
Set of all conserved charges considered.
double ElectricChargeDensity()
Electric charge density (fm )
virtual void DisableMesonBaryonVirial()
virtual void CalculateDensities()
Calculates the primordial and total (after decays) densities of all species.
double BaryonDensity()
Net baryon density (fm )
virtual void SetCharm(int C)
Set the total charm (for canonical ensemble only)
virtual void DisableMesonMesonAttraction()
const DecayCumulantsContributionsToAllParticles & DecayCumulants() const
Cumulants of particle number distributions of from decays.
double CharmDensity()
Net charm density (fm )
std::vector< double > m_densities
virtual double FinalParticleChargeSusceptibility(int i, ConservedCharge::Name chg) const
Returns the computed final (after decays) particle vs conserved charge (cross-)susceptibility for pa...
Class which implements calculation of the Jacobian needed for the Broyden's method.
virtual double NetParticleSusceptibilityPrimordialByPdg(long long id1, long long id2)
Returns the computed (cross-)susceptibility between primordial net-particle numbers for pdg codes id...
virtual void CalculateFluctuations()
Computes the fluctuation observables.
double AbsoluteQuark() const
Absolute light quark content |u,d|.
virtual void ChangeTPS(ThermalParticleSystem *TPS)
Change the particle list.
std::vector< std::vector< double > > m_PrimCorrel
bool UsePartialChemicalEquilibrium()
Whether partial chemical equilibrium with additional chemical potentials is used. ...
virtual std::vector< double > CalculateChargeFluctuations(const std::vector< double > &chgs, int order=4)
Calculates fluctuations (diagonal susceptibilities) of an arbitrary "conserved" charge.
ThermalModelEnsemble m_Ensemble
bool IsStable() const
Return particle stability flag.
virtual void SetAttraction(int, int, double)
Set the vdW mean field attraction coefficient .
std::vector< double > GetIdealGasDensities() const
std::vector< std::vector< double > > m_densitiesbyfeeddown
virtual void CalculateFeeddown()
Calculates the total densities which include feeddown contributions.
std::vector< double > m_skewtot
virtual void CalculateParticleChargeCorrelationMatrix()
Calculates the matrix of correlators between primordial (and also final) particle numbers and conserv...
virtual double TwoParticleSusceptibilityFinalByPdg(long long id1, long long id2)
Returns the computed final particle number (cross-)susceptibility for particles with pdg codes id1 a...
const std::vector< DecayContributionsToAllParticles > & DecayContributionsByFeeddown() const
virtual void DisableBaryonAntiBaryonVirial()
std::vector< double > m_densitiestotal
ThermalParticle::ResonanceWidthIntegration ResonanceWidthIntegrationType() const
void ProcessDecays()
Computes the decay contributions of decaying resonances to all particle yields.
int ConservedCharge(ConservedCharge::Name chg) const
One of the four QCD conserved charges.
virtual double CalculateAbsoluteBaryonDensity()
const ParticleDecaysVector & Decays() const
A vector of particle's decays.
double mnucleon()
Nucleon's mass. Value as in UrQMD.
double AbsoluteCharm() const
Absolute charm quark content |s|.
bool m_LastCalculationSuccessFlag
void SetResonanceWidthIntegrationType(ThermalParticle::ResonanceWidthIntegration type)
Set (or get) the ThermalParticle::ResonanceWidthIntegration scheme for all particles.
The main namespace where all classes and functions of the Thermal-FIST library reside.
virtual void SetChemicalPotentials(const std::vector< double > &chem=std::vector< double >(0))
Sets the chemical potentials of all particles.
bool IsFluctuationsCalculated() const
Feeddown from all particles marked as unstable.
double StrangenessDensity()
Net strangeness density (fm )
double Volume() const
System volume (fm )
ThermalParticleSystem * TPS()
void RestoreBranchingRatios()
Restore the original values of all the branching ratios.
std::vector< std::vector< double > > m_PrimChargesCorrel