14#include "libmesh/utility.h"
23 "Fluid properties for carbon dioxide (CO2) using the Span & Wagner EOS");
80 throw MooseException(
"Temperature is below the triple point temperature in " +
name() +
81 ": meltingPressure()");
86 (1.0 + 1955.539 * (Tstar - 1.0) + 2055.4593 * Utility::pow<2>(Tstar - 1.0));
93 throw MooseException(
"Temperature is above the triple point temperature in " +
name() +
94 ": sublimationPressure()");
99 std::exp((-14.740846 * (1.0 - Tstar) + 2.4327015 * std::pow(1.0 - Tstar, 1.9) -
100 5.3061778 * std::pow(1.0 - Tstar, 2.9)) /
110 throw MooseException(
"Temperature is out of range in " +
name() +
": vaporPressure()");
115 (-7.0602087 * (1.0 - Tstar) + 1.9391218 * std::pow(1.0 - Tstar, 1.5) -
116 1.6463597 * Utility::pow<2>(1.0 - Tstar) - 3.2995634 * Utility::pow<4>(1.0 - Tstar)) /
125 mooseError(
"vaporPressure() is not implemented");
132 throw MooseException(
"Temperature is out of range in " +
name() +
": saturatedLiquiDensity()");
136 Real logdensity = 1.9245108 * std::pow(1.0 - Tstar, 0.34) -
137 0.62385555 * std::pow(1.0 - Tstar, 0.5) -
138 0.32731127 * std::pow(1.0 - Tstar, 10.0 / 6.0) +
139 0.39245142 * std::pow(1.0 - Tstar, 11.0 / 6.0);
148 throw MooseException(
"Temperature is out of range in " +
name() +
": saturatedVaporDensity()");
153 (-1.7074879 * std::pow(1.0 - Tstar, 0.34) - 0.82274670 * std::pow(1.0 - Tstar, 0.5) -
154 4.6008549 * (1.0 - Tstar) - 10.111178 * std::pow(1.0 - Tstar, 7.0 / 3.0) -
155 29.742252 * std::pow(1.0 - Tstar, 14.0 / 3.0));
165 for (std::size_t i = 0; i <
_a0.size(); ++i)
166 sum0 +=
_a0[i] * std::log(1.0 - std::exp(-
_theta0[i] * tau));
168 Real phi0 = std::log(delta) + 8.37304456 - 3.70454304 * tau + 2.5 * std::log(tau) + sum0;
171 Real theta, Delta, Psi;
173 for (std::size_t i = 0; i <
_n1.size(); ++i)
176 for (std::size_t i = 0; i <
_n2.size(); ++i)
180 for (std::size_t i = 0; i <
_n3.size(); ++i)
182 std::exp(-
_alpha3[i] * Utility::pow<2>(delta -
_eps3[i]) -
185 for (std::size_t i = 0; i <
_n4.size(); ++i)
187 theta = 1.0 - tau +
_A4[i] * std::pow(Utility::pow<2>(delta - 1.0), 1.0 / (2.0 *
_beta4[i]));
188 Delta = Utility::pow<2>(theta) +
_B4[i] * std::pow(Utility::pow<2>(delta - 1.0),
_a4[i]);
189 Psi = std::exp(-
_C4[i] * Utility::pow<2>(delta - 1.0) -
_D4[i] * Utility::pow<2>(tau - 1.0));
190 phir +=
_n4[i] * std::pow(Delta,
_b4[i]) * delta * Psi;
201 Real dphi0dd = 1.0 / delta;
204 Real theta, Delta, Psi, dDelta_dd, dPsi_dd;
207 for (std::size_t i = 0; i <
_n1.size(); ++i)
210 for (std::size_t i = 0; i <
_n2.size(); ++i)
215 for (std::size_t i = 0; i <
_n3.size(); ++i)
217 std::exp(-
_alpha3[i] * Utility::pow<2>(delta -
_eps3[i]) -
221 for (std::size_t i = 0; i <
_n4.size(); ++i)
223 theta = 1.0 - tau +
_A4[i] * std::pow(Utility::pow<2>(delta - 1.0), 1.0 / (2.0 *
_beta4[i]));
224 Delta = Utility::pow<2>(theta) +
_B4[i] * std::pow(Utility::pow<2>(delta - 1.0),
_a4[i]);
225 Psi = std::exp(-
_C4[i] * Utility::pow<2>(delta - 1.0) -
_D4[i] * Utility::pow<2>(tau - 1.0));
226 dPsi_dd = -2.0 *
_C4[i] * (delta - 1.0) * Psi;
227 dDelta_dd = (delta - 1.0) *
229 std::pow(Utility::pow<2>(delta - 1.0), 1.0 / (2.0 *
_beta4[i]) - 1.0) +
230 2.0 *
_B4[i] *
_a4[i] * std::pow(Utility::pow<2>(delta - 1.0),
_a4[i] - 1.0));
232 dphirdd +=
_n4[i] * (std::pow(Delta,
_b4[i]) * (Psi + delta * dPsi_dd) +
233 _b4[i] * std::pow(Delta,
_b4[i] - 1.0) * dDelta_dd * delta * Psi);
237 return dphi0dd + dphirdd;
245 for (std::size_t i = 0; i <
_a0.size(); ++i)
248 Real dphi0dt = -3.70454304 + 2.5 / tau + sum0;
251 Real theta, Delta, Psi, dDelta_dt, dPsi_dt;
253 for (std::size_t i = 0; i <
_n1.size(); ++i)
256 for (std::size_t i = 0; i <
_n2.size(); ++i)
260 for (std::size_t i = 0; i <
_n3.size(); ++i)
262 std::exp(-
_alpha3[i] * Utility::pow<2>(delta -
_eps3[i]) -
266 for (std::size_t i = 0; i <
_n4.size(); ++i)
268 theta = 1.0 - tau +
_A4[i] * std::pow(Utility::pow<2>(delta - 1.0), 1.0 / (2.0 *
_beta4[i]));
269 Delta = Utility::pow<2>(theta) +
_B4[i] * std::pow(Utility::pow<2>(delta - 1.0),
_a4[i]);
270 Psi = std::exp(-
_C4[i] * Utility::pow<2>(delta - 1.0) -
_D4[i] * Utility::pow<2>(tau - 1.0));
271 dDelta_dt = -2.0 * theta *
_b4[i] * std::pow(Delta,
_b4[i] - 1.0);
272 dPsi_dt = -2.0 *
_D4[i] * (tau - 1.0) * Psi;
274 dphirdt +=
_n4[i] * delta * (Psi * dDelta_dt + std::pow(Delta,
_b4[i]) * dPsi_dt);
278 return dphi0dt + dphirdt;
285 Real d2phi0dd2 = -1.0 / delta / delta;
288 Real d2phirdd2 = 0.0;
289 Real theta, Delta, Psi, dDelta_dd, dPsi_dd, d2Delta_dd2, d2Psi_dd2;
291 for (std::size_t i = 0; i <
_n1.size(); ++i)
293 std::pow(tau,
_t1[i]);
295 for (std::size_t i = 0; i <
_n2.size(); ++i)
302 for (std::size_t i = 0; i <
_n3.size(); ++i)
305 std::exp(-
_alpha3[i] * Utility::pow<2>(delta -
_eps3[i]) -
309 Utility::pow<2>(delta -
_eps3[i]) -
313 for (std::size_t i = 0; i <
_n4.size(); ++i)
315 theta = 1.0 - tau +
_A4[i] * std::pow(Utility::pow<2>(delta - 1.0), 1.0 / (2.0 *
_beta4[i]));
316 Delta = Utility::pow<2>(theta) +
_B4[i] * std::pow(Utility::pow<2>(delta - 1.0),
_a4[i]);
317 Psi = std::exp(-
_C4[i] * Utility::pow<2>(delta - 1.0) -
_D4[i] * Utility::pow<2>(tau - 1.0));
318 dPsi_dd = -2.0 *
_C4[i] * (delta - 1.0) * Psi;
319 dDelta_dd = (delta - 1.0) *
321 std::pow(Utility::pow<2>(delta - 1.0), 1.0 / (2.0 *
_beta4[i]) - 1.0) +
322 2.0 *
_B4[i] *
_a4[i] * std::pow(Utility::pow<2>(delta - 1.0),
_a4[i] - 1.0));
323 d2Psi_dd2 = 3.0 *
_D4[i] * Psi * (2.0 *
_C4[i] * Utility::pow<2>(delta - 1.0) - 1.0);
324 d2Delta_dd2 = 1.0 / (delta - 1.0) * dDelta_dd +
325 (delta - 1.0) * (delta - 1.0) *
326 (4.0 *
_B4[i] *
_a4[i] * (
_a4[i] - 1.0) *
327 std::pow(Utility::pow<2>(delta - 1.0),
_a4[i] - 2.0) +
329 Utility::pow<2>(std::pow(Utility::pow<2>(delta - 1.0),
330 1.0 / (2.0 *
_beta4[i]) - 1.0)) /
333 std::pow(Utility::pow<2>(delta - 1.0), 1.0 / (2.0 *
_beta4[i]) - 2.0));
336 (std::pow(Delta,
_b4[i]) * (2.0 * dPsi_dd + delta * d2Psi_dd2) +
337 2.0 *
_b4[i] * std::pow(Delta,
_b4[i] - 1.0) * dDelta_dd * (Psi + delta * dPsi_dd) +
339 (std::pow(Delta,
_b4[i] - 1.0) * d2Delta_dd2 +
340 (
_b4[i] - 1.0) * std::pow(Delta,
_b4[i] - 2.0) * Utility::pow<2>(dDelta_dd)) *
344 return d2phi0dd2 + d2phirdd2;
352 for (std::size_t i = 0; i <
_a0.size(); ++i)
354 Utility::pow<2>(1.0 - std::exp(-
_theta0[i] * tau));
356 Real d2phi0dt2 = -2.5 / tau / tau - sum0;
359 Real d2phirdt2 = 0.0;
360 Real theta, Delta, Psi, dPsi_dt, dDelta_dt, d2Delta_dt2, d2Psi_dt2;
362 for (std::size_t i = 0; i <
_n1.size(); ++i)
364 std::pow(tau,
_t1[i] - 2.0);
366 for (std::size_t i = 0; i <
_n2.size(); ++i)
370 for (std::size_t i = 0; i <
_n3.size(); ++i)
372 std::exp(-
_alpha3[i] * Utility::pow<2>(delta -
_eps3[i]) -
377 for (std::size_t i = 0; i <
_n4.size(); ++i)
379 theta = 1.0 - tau +
_A4[i] * std::pow(Utility::pow<2>(delta - 1.0), 1.0 / (2.0 *
_beta4[i]));
380 Delta = Utility::pow<2>(theta) +
_B4[i] * std::pow(Utility::pow<2>(delta - 1.0),
_a4[i]);
381 Psi = std::exp(-
_C4[i] * Utility::pow<2>(delta - 1.0) -
_D4[i] * Utility::pow<2>(tau - 1.0));
382 dDelta_dt = -2.0 * theta *
_b4[i] * std::pow(Delta,
_b4[i] - 1.0);
383 d2Delta_dt2 = 2.0 *
_b4[i] * std::pow(Delta,
_b4[i] - 1.0) +
384 4.0 * theta * theta *
_b4[i] * (
_b4[i] - 1.0) * std::pow(Delta,
_b4[i] - 2.0);
385 dPsi_dt = -2.0 *
_D4[i] * (tau - 1.0) * Psi;
386 d2Psi_dt2 = 2.0 *
_D4[i] * (2.0 *
_D4[i] * (tau - 1.0) * (tau - 1.0) - 1.0) * Psi;
389 (Psi * d2Delta_dt2 + 2.0 * dDelta_dt * dPsi_dt + std::pow(Delta,
_b4[i]) * d2Psi_dt2);
393 return d2phi0dt2 + d2phirdt2;
401 Real theta, Delta, Psi, dDelta_dd, dPsi_dd, dDelta_dt, dPsi_dt, d2Delta_ddt, d2Psi_ddt;
402 Real d2phirddt = 0.0;
403 for (std::size_t i = 0; i <
_n1.size(); ++i)
405 std::pow(tau,
_t1[i] - 1.0);
407 for (std::size_t i = 0; i <
_n2.size(); ++i)
412 for (std::size_t i = 0; i <
_n3.size(); ++i)
414 std::exp(-
_alpha3[i] * Utility::pow<2>(delta -
_eps3[i]) -
419 for (std::size_t i = 0; i <
_n4.size(); ++i)
421 theta = 1.0 - tau +
_A4[i] * std::pow(Utility::pow<2>(delta - 1.0), 1.0 / (2.0 *
_beta4[i]));
422 Delta = Utility::pow<2>(theta) +
_B4[i] * std::pow(Utility::pow<2>(delta - 1.0),
_a4[i]);
423 Psi = std::exp(-
_C4[i] * Utility::pow<2>(delta - 1.0) -
_D4[i] * Utility::pow<2>(tau - 1.0));
424 dPsi_dd = -2.0 *
_C4[i] * (delta - 1.0) * Psi;
425 dPsi_dt = -2.0 *
_D4[i] * (tau - 1.0) * Psi;
426 d2Psi_ddt = 4.0 *
_C4[i] *
_D4[i] * (delta - 1.0) * (tau - 1.0) * Psi;
427 dDelta_dd = (delta - 1.0) *
429 std::pow(Utility::pow<2>(delta - 1.0), 1.0 / (2.0 *
_beta4[i]) - 1.0) +
430 2.0 *
_B4[i] *
_a4[i] * std::pow(Utility::pow<2>(delta - 1.0),
_a4[i] - 1.0));
431 dDelta_dt = -2.0 * theta *
_b4[i] * std::pow(Delta,
_b4[i] - 1.0);
432 d2Delta_ddt = -2.0 *
_A4[i] *
_b4[i] /
_beta4[i] * std::pow(Delta,
_b4[i] - 1.0) *
434 std::pow(Utility::pow<2>(delta - 1.0), 1.0 / (2.0 *
_beta4[i]) - 1.0) -
435 2.0 * theta *
_b4[i] * (
_b4[i] - 1.0) * std::pow(Delta,
_b4[i] - 2.0) * dDelta_dd;
437 d2phirddt +=
_n4[i] * (std::pow(Delta,
_b4[i]) * (dPsi_dt + delta * d2Psi_ddt) +
438 delta *
_b4[i] * std::pow(Delta,
_b4[i] - 1.0) * dDelta_dd * dPsi_dt +
439 dDelta_dt * (Psi + delta * dPsi_dd) + d2Delta_ddt * delta * Psi);
449 if (temperature < 216.0 || temperature > 1100.0 || density <= 0.0)
459 if (density < gas_density || density > liquid_density)
474 if (temperature < 216.0 || temperature > 1100.0 || pressure <= 0.0)
481 ": rho_from_p_T() correspond to solid CO2 phase");
485 Real lower_density = 100.0;
486 Real upper_density = 1000.0;
490 auto pressure_diff = [&pressure, &temperature,
this](Real
x)
501 Real pressure, Real temperature, Real &
rho, Real & drho_dp, Real & drho_dT)
const
515 Real pressure, Real temperature, Real &
mu, Real & dmu_dp, Real & dmu_dT)
const
517 Real
rho, drho_dp, drho_dT;
522 dmu_dp = dmu_drho * drho_dp;
529 if (temperature < 216.0 || temperature > 1000.0 || density > 1400.0)
532 Real Tstar = temperature / 251.196;
537 for (std::size_t i = 0; i <
_mu_a.size(); ++i)
540 Real mu0 = 1.00697 * std::sqrt(temperature) / std::exp(sum);
543 Real mue =
_mu_d[0] * density +
_mu_d[1] * Utility::pow<2>(density) +
544 _mu_d[2] * Utility::pow<6>(density) / Utility::pow<3>(Tstar) +
545 _mu_d[3] * Utility::pow<8>(density) +
_mu_d[4] * Utility::pow<8>(density) / Tstar;
547 return (mu0 + mue) * 1.0e-6;
559 if (temperature < 216.0 || temperature > 1000.0 || density > 1400.0)
562 Real Tstar = temperature / 251.196;
563 Real dTstar_dT = 1.0 / 251.196;
567 Real sum0 =
_mu_a[0], dsum0_dTstar = 0.0;
569 for (std::size_t i = 1; i <
_mu_a.size(); ++i)
575 Real mu0 = 1.00697 * std::sqrt(temperature) / std::exp(sum0);
576 Real dmu0_dT = (0.5 * 1.00697 / std::sqrt(temperature) -
577 1.00697 * std::sqrt(temperature) * dsum0_dTstar * dTstar_dT) /
581 Real mue =
_mu_d[0] * density +
_mu_d[1] * Utility::pow<2>(density) +
582 _mu_d[2] * Utility::pow<6>(density) / Utility::pow<3>(Tstar) +
583 _mu_d[3] * Utility::pow<8>(density) +
_mu_d[4] * Utility::pow<8>(density) / Tstar;
585 Real dmue_drho =
_mu_d[0] + 2.0 *
_mu_d[1] * density +
586 6.0 *
_mu_d[2] * Utility::pow<5>(density) / Utility::pow<3>(Tstar) +
587 8.0 *
_mu_d[3] * Utility::pow<7>(density) +
588 8.0 *
_mu_d[4] * Utility::pow<7>(density) / Tstar;
590 Real dmue_dT = (-3.0 *
_mu_d[2] * Utility::pow<6>(density) / Utility::pow<4>(Tstar) -
591 _mu_d[4] * Utility::pow<8>(density) / Tstar / Tstar) *
595 mu = (mu0 + mue) * 1.0e-6;
596 dmu_drho = dmue_drho * 1.0e-6;
597 dmu_dT = (dmu0_dT + dmue_dT) * 1.0e-6 + dmu_drho * ddensity_dT;
620 dmu_dp = dmu_drho * drho_dp;
627 Real Tc = temperature -
_T_c2k;
629 Real V = 37.51 - 9.585e-2 * Tc + 8.74e-4 * Tc * Tc - 5.044e-7 * Tc * Tc * Tc;
631 return 1.0e6 *
_Mco2 / V;
637 return {-8.55445, 4.01195, 9.52345};
650 Real pressure, Real temperature, Real & k, Real & dk_dp, Real & dk_dT)
const
655 const Real
eps = 1.0e-6;
656 const Real peps = pressure *
eps;
657 const Real Teps = temperature *
eps;
659 dk_dp = (this->
k_from_p_T(pressure + peps, temperature) - k) / peps;
660 dk_dT = (this->
k_from_p_T(pressure, temperature + Teps) - k) / Teps;
667 if (temperature <= _triple_point_temperature || temperature >= 1000.0)
669 "K out of range (200K, 1000K) in " +
name() +
": k()");
676 for (std::size_t i = 0; i <
_k_n1.size(); ++i)
680 for (std::size_t i = 0; i <
_k_n2.size(); ++i)
685 1.0 -
_k_a[9] * std::acosh(1.0 +
_k_a[10] * std::pow(Utility::pow<2>(1.0 - Tr),
_k_a[11]));
688 std::exp(-std::pow(rhor,
_k_a[0]) /
_k_a[0] - Utility::pow<2>(
_k_a[1] * (Tr - 1.0)) -
689 Utility::pow<2>(
_k_a[2] * (rhor - 1.0))) /
690 std::pow(std::pow(Utility::pow<2>(
692 _k_a[3] * std::pow(Utility::pow<2>(rhor - 1.0), 1.0 / (2.0 *
_k_a[4]))),
694 std::pow(Utility::pow<2>(
_k_a[6] * (rhor -
alpha)),
_k_a[7]),
697 return 4.81384 * (sum1 + std::exp(-5.0 * rhor * rhor) * sum2 + 0.775547504 * lambdac) / 1000.0;
registerMooseObject("FluidPropertiesApp", CO2FluidProperties)
const std::vector< double > x
CO2 fluid properties Most thermophysical properties taken from: Span and Wagner, "A New Equation of S...
virtual Real p_from_rho_T(Real density, Real temperature) const override
Pressure as a function of density and temperature.
virtual Real rho_from_p_T(Real pressure, Real temperature) const override
virtual Real criticalDensity() const override
Critical density.
virtual Real molarMass() const override
Molar mass [kg/mol].
Real meltingPressure(Real temperature) const
Melting pressure.
const std::array< unsigned int, 5 > _d3
virtual Real k_from_p_T(Real pressure, Real temperature) const override
const std::array< Real, 3 > _b4
const std::array< Real, 7 > _k_g2
const std::array< Real, 3 > _n4
virtual Real alpha(Real delta, Real tau) const override
Helmholtz free energy.
const std::array< Real, 3 > _D4
const Real _critical_pressure
Critical pressure (Pa)
virtual Real triplePointPressure() const override
Triple point pressure.
Real saturatedLiquidDensity(Real temperature) const
Saturated liquid density of CO2 Valid for temperatures between the triple point temperature and criti...
virtual Real d2alpha_ddeltatau(Real delta, Real tau) const override
Second derivative of Helmholtz free energy wrt delta and tau.
const std::array< unsigned int, 7 > _k_h2
virtual void rho_mu_from_p_T(Real pressure, Real temperature, Real &rho, Real &mu) const override
Combined methods.
const std::array< Real, 7 > _k_n2
const std::array< Real, 27 > _n2
const std::array< unsigned int, 27 > _c2
virtual Real d2alpha_ddelta2(Real delta, Real tau) const override
Second derivative of Helmholtz free energy wrt delta.
const std::array< Real, 3 > _k_n1
virtual Real mu_from_rho_T(Real density, Real temperature) const override
const std::array< Real, 3 > _a4
const std::array< Real, 12 > _k_a
const std::array< unsigned int, 27 > _d2
const std::array< Real, 5 > _beta3
virtual Real mu_from_p_T(Real pressure, Real temperature) const override
virtual Real criticalTemperature() const override
Critical temperature.
CO2FluidProperties(const InputParameters ¶meters)
const std::array< Real, 3 > _A4
const std::array< Real, 5 > _theta0
virtual std::vector< Real > henryCoefficients() const override
Henry's law coefficients for dissolution in water.
const std::array< Real, 7 > _t1
virtual Real dalpha_ddelta(Real delta, Real tau) const override
Derivative of Helmholtz free energy wrt delta.
const std::array< unsigned int, 3 > _k_h1
virtual Real vaporPressure(Real temperature) const override
Vapor pressure.
const std::array< Real, 5 > _eps3
Real sublimationPressure(Real temperature) const
Sublimation pressure.
virtual Real k_from_rho_T(Real density, Real temperature) const override
const std::array< Real, 7 > _n1
Coefficients for the residual component of the Helmholtz free energy.
const std::array< Real, 5 > _n3
const std::array< Real, 3 > _beta4
const std::array< Real, 5 > _mu_d
virtual Real triplePointTemperature() const override
Triple point temperature.
virtual Real criticalPressure() const override
Critical pressure.
const Real _critical_density
Critical density (kg/m^3)
const Real _triple_point_temperature
Triple point temperature (K)
virtual Real dalpha_dtau(Real delta, Real tau) const override
Derivative of Helmholtz free energy wrt tau.
Real partialDensity(Real temperature) const
Partial density of dissolved CO2 From Garcia, Density of aqueous solutions of CO2,...
const std::array< Real, 3 > _C4
virtual std::string fluidName() const override
Fluid name.
const Real _Mco2
Molar mass of CO2 (kg/mol)
const Real _critical_temperature
Critical temperature (K)
const std::array< Real, 5 > _mu_a
Coefficients for viscosity.
virtual Real d2alpha_dtau2(Real delta, Real tau) const override
Second derivative of Helmholtz free energy wrt tau.
const std::array< unsigned int, 7 > _d1
static InputParameters validParams()
const std::array< Real, 5 > _alpha3
const std::array< unsigned int, 5 > _t3
virtual ~CO2FluidProperties()
const std::array< Real, 5 > _a0
Coefficients for the ideal gas component of the Helmholtz free energy.
const std::array< Real, 3 > _k_g1
Coefficients for the thermal conductivity.
Real saturatedVaporDensity(Real temperature) const
Saturated vapor density of CO2 Valid for temperatures between the triple point temperature and critic...
const std::array< Real, 3 > _B4
const std::array< Real, 27 > _t2
const std::array< Real, 5 > _gamma3
const Real _triple_point_pressure
Triple point pressure (Pa)
const Real _T_c2k
Conversion of temperature from Celsius to Kelvin.
Base class equation of state for fluids that use a Helmholtz free energy alpha(delta,...
static InputParameters validParams()
virtual Real rho_from_p_T(Real pressure, Real temperature) const override
virtual Real p_from_rho_T(Real rho, Real T) const
Pressure as a function of density and temperature.
void mooseError(Args &&... args) const
Real root(std::function< Real(Real)> const &f, Real x1, Real x2, Real tol=1.0e-12)
Finds the root of a function using Brent's method.
void bracket(std::function< Real(Real)> const &f, Real &x1, Real &x2)
Function to bracket a root of a given function.
std::string stringify(const T &t)