CoolProp  6.6.0
An open-source fluid property and humid air property database
HelmholtzEOSMixtureBackend.h
Go to the documentation of this file.
1 
2 #ifndef HELMHOLTZEOSMIXTUREBACKEND_H_
3 #define HELMHOLTZEOSMIXTUREBACKEND_H_
4 
5 #include "AbstractState.h"
6 #include "CoolPropFluid.h"
7 #include "ReducingFunctions.h"
8 #include "ExcessHEFunction.h"
9 #include "Solvers.h"
10 #include "PhaseEnvelope.h"
11 #include "DataStructures.h"
12 #include "Configuration.h"
13 
14 #include <vector>
15 
16 namespace CoolProp {
17 
18 class FlashRoutines;
19 
20 class ResidualHelmholtz;
21 
22 // This class contains the mole fractions for a given mixture.
24  private:
25  std::vector<CoolPropDbl> mole_fractions;
26  template <typename T>
27  bool verify_mole_fractions_set(T i) const {
28  if (i >= mole_fractions.size()){
29  throw CoolProp::ValueError("mole fractions are not set for all components");
30  }
31  return true;
32  }
33  public:
34  template <typename T>
35  void resize(T N){
36  return mole_fractions.resize(N);
37  }
38  std::size_t size() const {
39  return mole_fractions.size();
40  }
41  void clear() {
42  mole_fractions.clear();
43  }
44  // operator overloads
45  template<typename T>
46  MoleFractions& operator=(const std::vector<T>& values){
47  mole_fractions = values;
48  return *this;
49  }
50  template <typename T>
51  CoolPropDbl operator[](T i) const {
52  verify_mole_fractions_set(i);
53  return mole_fractions[i];
54  }
55  operator std::vector<CoolPropDbl>& () { return mole_fractions; }
56 };
57 
59 {
60 
61  protected:
62  void pre_update(CoolProp::input_pairs& input_pair, CoolPropDbl& value1, CoolPropDbl& value2);
63  void post_update(bool optional_checks = true);
64  std::vector<shared_ptr<HelmholtzEOSMixtureBackend>>
66  shared_ptr<HelmholtzEOSMixtureBackend> transient_pure_state;
67  shared_ptr<HelmholtzEOSMixtureBackend> TPD_state;
68  shared_ptr<HelmholtzEOSMixtureBackend> critical_state;
70  virtual void add_TPD_state() {
71  if (TPD_state.get() == NULL) {
72  bool sat_states = false;
73  TPD_state.reset(get_copy(sat_states));
74  linked_states.push_back(TPD_state);
75  }
76  };
78  virtual void add_critical_state() {
79  if (critical_state.get() == NULL) {
80  bool sat_states = true;
81  critical_state.reset(get_copy(sat_states));
82  linked_states.push_back(critical_state);
83  }
84  };
86  virtual void add_transient_pure_state() {
87  if (transient_pure_state.get() == NULL) {
88  bool sat_states = true;
89  transient_pure_state.reset(get_copy(sat_states));
91  }
92  };
93 
94  std::vector<CoolPropFluid> components;
97  std::vector<CoolPropDbl> K,
98  lnK;
99 
101  std::size_t N;
102 
104  std::vector<CoolProp::CriticalState> _calc_all_critical_points(bool find_critical_points = true);
105 
106  static void set_fluid_enthalpy_entropy_offset(CoolPropFluid& component, double delta_a1, double delta_a2, const std::string& ref);
107 
108  public:
110  HelmholtzEOSMixtureBackend(const std::vector<CoolPropFluid>& components, bool generate_SatL_and_SatV = true);
111  HelmholtzEOSMixtureBackend(const std::vector<std::string>& component_names, bool generate_SatL_and_SatV = true);
112  virtual HelmholtzEOSMixtureBackend* get_copy(bool generate_SatL_and_SatV = true);
113 
114  // Copy over the reducing and departure terms to all linked states (recursively)
116 
118  std::string backend_name(void) {
120  }
121  shared_ptr<ReducingFunction> Reducing;
122  shared_ptr<ResidualHelmholtz> residual_helmholtz;
127 
128  bool clear() {
129  // Clear the locally cached values for the derivatives of the Helmholtz energy
130  // in each component
131  for (std::vector<CoolPropFluid>::iterator it = components.begin(); it != components.end(); ++it) {
132  (*it).EOS().alphar.clear();
133  (*it).EOS().alpha0.clear();
134  }
135  return AbstractState::clear();
136  };
137 
138  friend class
139  FlashRoutines; // Allows the static methods in the FlashRoutines class to have access to all the protected members and methods of this class
140  friend class
141  TransportRoutines; // Allows the static methods in the TransportRoutines class to have access to all the protected members and methods of this class
142  friend class
143  MixtureDerivatives; // Allows the static methods in the MixtureDerivatives class to have access to all the protected members and methods of this class
144  friend class
145  PhaseEnvelopeRoutines; // Allows the static methods in the PhaseEnvelopeRoutines class to have access to all the protected members and methods of this class
146  friend class
147  MixtureParameters; // Allows the static methods in the MixtureParameters class to have access to all the protected members and methods of this class
148  friend class
149  CorrespondingStatesTerm; // // Allows the methods in the CorrespondingStatesTerm class to have access to all the protected members and methods of this class
150 
151  // Helmholtz EOS backend uses mole fractions
153  return true;
154  }
156  return false;
157  }
159  return false;
160  }
161  bool is_pure() {
162  return components.size() == 1 && !components[0].EOS().pseudo_pure;
163  }
164  bool has_melting_line() {
165  return is_pure_or_pseudopure && components[0].ancillaries.melting_line.enabled();
166  };
167  CoolPropDbl calc_melting_line(int param, int given, CoolPropDbl value);
169  std::string fluid_param_string(const std::string&);
170 
172  virtual void set_reference_stateS(const std::string& reference_state);
173 
175  virtual void set_reference_stateD(double T, double rhomolar, double hmolar0, double smolar0);
176 
178  virtual void set_binary_interaction_double(const std::size_t i, const std::size_t j, const std::string& parameter, const double value);
180  virtual double get_binary_interaction_double(const std::size_t i, const std::size_t j, const std::string& parameter);
182  //virtual std::string get_binary_interaction_string(const std::size_t &i, const std::size_t &j, const std::string &parameter);
184  void set_binary_interaction_string(const std::size_t i, const std::size_t j, const std::string& parameter, const std::string& value);
186  void apply_simple_mixing_rule(std::size_t i, std::size_t j, const std::string& model);
187 
188  // Set the cubic alpha function's constants:
189  virtual void set_cubic_alpha_C(const size_t i, const std::string& parameter, const double c1, const double c2, const double c3) {
190  throw ValueError("set_cubic_alpha_C only defined for cubic backends");
191  };
192 
193  // Set fluid parameter (currently the volume translation parameter for cubic)
194  virtual void set_fluid_parameter_double(const size_t i, const std::string& parameter, const double value) {
195  throw ValueError("set_fluid_parameter_double only defined for cubic backends");
196  };
197 
198  phases calc_phase(void) {
199  return _phase;
200  };
201 
206  void calc_specify_phase(phases phase_index) {
207  imposed_phase_index = phase_index;
208  _phase = phase_index;
209  }
212  void calc_unspecify_phase() {
214  }
215  CoolPropDbl calc_saturation_ancillary(parameters param, int Q, parameters given, double value);
216  void calc_ssat_max(void);
217  void calc_hsat_max(void);
222 
229 
230  CriticalState calc_critical_point(double rho0, double T0);
232  std::vector<CoolProp::CriticalState> calc_all_critical_points() {
233  bool find_critical_points = true;
234  return _calc_all_critical_points(find_critical_points);
235  };
236 
237  virtual void get_critical_point_starting_values(double& delta0, double& tau0) {
238  delta0 = get_config_double(SPINODAL_MINIMUM_DELTA); // The value of delta where we start searching for crossing with Lstar=0 contour
239  tau0 = 0.66; // The value of tau where we start searching at delta=delta0
240  }
242  virtual void get_critical_point_search_radii(double& R_delta, double& R_tau);
244  virtual bool get_critical_is_terminated(double& delta, double& tau) {
245  return delta > 5 || tau > 5;
246  }
247 
249  virtual void calc_build_spinodal();
250 
253  return spinodal_values;
254  };
255 
257  void calc_criticality_contour_values(double& L1star, double& M1star);
258 
260  double calc_tangent_plane_distance(const double T, const double p, const std::vector<double>& w, const double rhomolar_guess);
261 
264 
266  void calc_change_EOS(const std::size_t i, const std::string& EOS_name);
267 
268  const CoolProp::SimpleState& calc_state(const std::string& state);
269 
270  virtual const double get_fluid_constant(std::size_t i, parameters param) const {
271  const CoolPropFluid& fld = components[i];
272  switch (param) {
273  case iP_critical:
274  return fld.crit.p;
275  case iT_critical:
276  return fld.crit.T;
277  case iT_reducing:
278  return fld.EOS().reduce.T;
279  case irhomolar_reducing:
280  return fld.EOS().reduce.rhomolar;
281  case irhomolar_critical:
282  return fld.crit.rhomolar;
283  case iacentric_factor:
284  return fld.EOS().acentric;
285  case imolar_mass:
286  return fld.EOS().molar_mass;
287  case iT_triple:
288  return fld.EOS().sat_min_liquid.T;
289  case iP_triple:
290  return fld.EOS().sat_min_liquid.p;
291  case igas_constant:
292  return fld.EOS().R_u;
293  default:
294  throw ValueError(format("I don't know what to do with this fluid constant: %s", get_parameter_information(param, "short").c_str()));
295  }
296  }
297 
298  const std::vector<CoolPropFluid>& get_components() const {
299  return components;
300  }
301  std::vector<CoolPropFluid>& get_components() {
302  return components;
303  }
304  std::vector<CoolPropDbl>& get_K() {
305  return K;
306  };
307  std::vector<CoolPropDbl>& get_lnK() {
308  return lnK;
309  };
311  return *SatL;
312  };
314  return *SatV;
315  };
316 
317  std::vector<CoolPropDbl> calc_mole_fractions_liquid(void) {
318  return SatL->get_mole_fractions();
319  };
320  std::vector<CoolPropDbl> calc_mole_fractions_vapor(void) {
321  return SatV->get_mole_fractions();
322  };
323 
324  const std::vector<CoolPropDbl> calc_mass_fractions(void);
325 
327  return PhaseEnvelope;
328  };
329 
331  void calc_conformal_state(const std::string& reference_fluid, CoolPropDbl& T, CoolPropDbl& rhomolar);
332 
333  void resize(std::size_t N);
334  shared_ptr<HelmholtzEOSMixtureBackend> SatL, SatV;
335 
341  virtual void update(CoolProp::input_pairs input_pair, double value1, double value2);
342 
346  void update_with_guesses(CoolProp::input_pairs input_pair, double Value1, double Value2, const GuessesStructure& guesses);
347 
351 
360 
366  virtual void set_components(const std::vector<CoolPropFluid>& components, bool generate_SatL_and_SatV = true);
367 
370  void set_mixture_parameters();
371 
376  void set_mole_fractions(const std::vector<CoolPropDbl>& mf);
377 
378  const std::vector<CoolPropDbl>& get_mole_fractions() {
379  return mole_fractions;
380  };
381  std::vector<CoolPropDbl>& get_mole_fractions_ref() {
382  return mole_fractions;
383  };
384  std::vector<double>& get_mole_fractions_doubleref(void) {
385  return mole_fractions;
386  }
387 
392  void set_mass_fractions(const std::vector<CoolPropDbl>& mass_fractions);
393 
394  void calc_ideal_curve(const std::string& type, std::vector<double>& T, std::vector<double>& p);
395 
399 
404 
410  return gas_constant() * _T * (alphar() + delta() * dalphar_dDelta());
411  }
413 
417  CoolPropDbl calc_smolar(void);
419  return gas_constant() * (tau() * dalphar_dTau() - alphar());
420  }
422 
423  CoolPropDbl calc_hmolar(void);
425  return gas_constant() * _T * (tau() * dalphar_dTau() + delta() * dalphar_dDelta());
426  }
428 
430  CoolPropDbl calc_umolar(void);
432 
433  void calc_excess_properties();
434 
441  CoolPropDbl calc_fugacity(std::size_t i);
442  virtual CoolPropDbl calc_fugacity_coefficient(std::size_t i);
443  CoolPropDbl calc_chemical_potential(std::size_t i);
444 
447  return components[0].environment.FH;
448  };
451  return components[0].environment.HH;
452  };
455  return components[0].environment.PH;
456  };
457 
459  CoolPropDbl calc_alphar(void);
488 
489  CoolPropDbl calc_alpha0(void);
499 
504  CoolPropDbl calc_viscosity_background(CoolPropDbl eta_dilute, CoolPropDbl& initial_density, CoolPropDbl& residual);
507 
513  void calc_viscosity_contributions(CoolPropDbl& dilute, CoolPropDbl& initial_density, CoolPropDbl& residual, CoolPropDbl& critical);
519  void calc_conductivity_contributions(CoolPropDbl& dilute, CoolPropDbl& initial_density, CoolPropDbl& residual, CoolPropDbl& critical);
520 
523 
524  CoolPropDbl calc_Tmin(void);
525  CoolPropDbl calc_Tmax(void);
526  CoolPropDbl calc_pmax(void);
531  void calc_Tmin_sat(CoolPropDbl& Tmin_satL, CoolPropDbl& Tmin_satV);
532  void calc_pmin_sat(CoolPropDbl& pmin_satL, CoolPropDbl& pmin_satV);
533 
534  virtual CoolPropDbl calc_T_critical(void);
536  virtual CoolPropDbl calc_rhomolar_critical(void);
537 
539  return get_reducing_state().T;
540  };
542  return get_reducing_state().rhomolar;
543  };
545  return get_reducing_state().p;
546  };
547 
548  // Calculate the phase identification parameter of Venkatarathnam et al, Fluid Phase Equilibria
549  CoolPropDbl calc_PIP(void) {
550  return 2
551  - rhomolar()
554  };
555 
556  std::string calc_name(void);
557  std::vector<std::string> calc_fluid_names(void);
558 
559  void calc_all_alphar_deriv_cache(const std::vector<CoolPropDbl>& mole_fractions, const CoolPropDbl& tau, const CoolPropDbl& delta);
560  virtual CoolPropDbl calc_alphar_deriv_nocache(const int nTau, const int nDelta, const std::vector<CoolPropDbl>& mole_fractions,
561  const CoolPropDbl& tau, const CoolPropDbl& delta);
562 
587  CoolPropDbl calc_alpha0_deriv_nocache(const int nTau, const int nDelta, const std::vector<CoolPropDbl>& mole_fractions, const CoolPropDbl& tau,
588  const CoolPropDbl& delta, const CoolPropDbl& Tr, const CoolPropDbl& rhor);
589 
590  virtual void calc_reducing_state(void);
591  virtual SimpleState calc_reducing_state_nocache(const std::vector<CoolPropDbl>& mole_fractions);
592 
595  return _reducing;
596  };
597 
598  void update_states();
599 
601  return 1 + delta() * dalphar_dDelta();
602  };
603 
604  void calc_phase_envelope(const std::string& type);
605 
607 
608  // ***************************************************************
609  // ***************************************************************
610  // ************* PHASE DETERMINATION ROUTINES ******************
611  // ***************************************************************
612  // ***************************************************************
614  void p_phase_determination_pure_or_pseudopure(int other, CoolPropDbl value, bool& saturation_called);
616 
617  // ***************************************************************
618  // ***************************************************************
619  // ******************* SOLVER ROUTINES *************************
620  // ***************************************************************
621  // ***************************************************************
622 
623  virtual CoolPropDbl solver_rho_Tp(CoolPropDbl T, CoolPropDbl p, CoolPropDbl rho_guess = -1);
626  {
630  };
633 };
634 
636 {
637  public:
639  virtual HelmholtzDerivatives all(HelmholtzEOSMixtureBackend& HEOS, double tau, double delta, const std::vector<CoolPropDbl>& x,
640  bool cache_values = false) {
641  HelmholtzDerivatives summer;
642  std::size_t N = x.size();
643  for (std::size_t i = 0; i < N; ++i) {
644  HelmholtzDerivatives derivs = HEOS.components[i].EOS().alphar.all(tau, delta, cache_values);
645  summer = summer + derivs * x[i];
646  }
647  return summer;
648  }
649  CoolPropDbl dalphar_dxi(HelmholtzEOSMixtureBackend& HEOS, std::vector<CoolPropDbl>& x, std::size_t i, x_N_dependency_flag xN_flag) {
650  if (xN_flag == XN_INDEPENDENT) {
651  return HEOS.components[i].EOS().baser(HEOS.tau(), HEOS.delta());
652  } else if (xN_flag == XN_DEPENDENT) {
653  std::size_t N = x.size();
654  if (i == N - 1) return 0;
655  return HEOS.components[i].EOS().baser(HEOS.tau(), HEOS.delta()) - HEOS.components[N - 1].EOS().baser(HEOS.tau(), HEOS.delta());
656  } else {
657  throw ValueError(format("xN_flag is invalid"));
658  }
659  }
660  CoolPropDbl d2alphar_dxi_dTau(HelmholtzEOSMixtureBackend& HEOS, std::vector<CoolPropDbl>& x, std::size_t i, x_N_dependency_flag xN_flag) {
661  if (xN_flag == XN_INDEPENDENT) {
662  return HEOS.components[i].EOS().dalphar_dTau(HEOS._tau, HEOS._delta);
663  } else if (xN_flag == XN_DEPENDENT) {
664  std::size_t N = x.size();
665  if (i == N - 1) return 0;
666  return HEOS.components[i].EOS().dalphar_dTau(HEOS._tau, HEOS._delta) - HEOS.components[N - 1].EOS().dalphar_dTau(HEOS._tau, HEOS._delta);
667  } else {
668  throw ValueError(format("xN_flag is invalid"));
669  }
670  }
671  CoolPropDbl d2alphar_dxi_dDelta(HelmholtzEOSMixtureBackend& HEOS, std::vector<CoolPropDbl>& x, std::size_t i, x_N_dependency_flag xN_flag) {
672  if (xN_flag == XN_INDEPENDENT) {
673  return HEOS.components[i].EOS().dalphar_dDelta(HEOS.tau(), HEOS.delta());
674  } else if (xN_flag == XN_DEPENDENT) {
675  std::size_t N = x.size();
676  if (i == N - 1) return 0;
677  return HEOS.components[i].EOS().dalphar_dDelta(HEOS.tau(), HEOS.delta())
678  - HEOS.components[N - 1].EOS().dalphar_dDelta(HEOS._tau, HEOS._delta);
679  } else {
680  throw ValueError(format("xN_flag is invalid"));
681  }
682  }
683  CoolPropDbl d3alphar_dxi_dDelta2(HelmholtzEOSMixtureBackend& HEOS, std::vector<CoolPropDbl>& x, std::size_t i, x_N_dependency_flag xN_flag) {
684  if (xN_flag == XN_INDEPENDENT) {
685  return HEOS.components[i].EOS().d2alphar_dDelta2(HEOS.tau(), HEOS.delta());
686  } else if (xN_flag == XN_DEPENDENT) {
687  std::size_t N = x.size();
688  if (i == N - 1) return 0;
689  return HEOS.components[i].EOS().d2alphar_dDelta2(HEOS.tau(), HEOS.delta())
690  - HEOS.components[N - 1].EOS().d2alphar_dDelta2(HEOS.tau(), HEOS.delta());
691  } else {
692  throw ValueError(format("xN_flag is invalid"));
693  }
694  }
695  CoolPropDbl d3alphar_dxi_dTau2(HelmholtzEOSMixtureBackend& HEOS, std::vector<CoolPropDbl>& x, std::size_t i, x_N_dependency_flag xN_flag) {
696  if (xN_flag == XN_INDEPENDENT) {
697  return HEOS.components[i].EOS().d2alphar_dTau2(HEOS.tau(), HEOS.delta());
698  } else if (xN_flag == XN_DEPENDENT) {
699  std::size_t N = x.size();
700  if (i == N - 1) return 0;
701  return HEOS.components[i].EOS().d2alphar_dTau2(HEOS.tau(), HEOS.delta())
702  - HEOS.components[N - 1].EOS().d2alphar_dTau2(HEOS.tau(), HEOS.delta());
703  } else {
704  throw ValueError(format("xN_flag is invalid"));
705  }
706  }
707  CoolPropDbl d3alphar_dxi_dDelta_dTau(HelmholtzEOSMixtureBackend& HEOS, std::vector<CoolPropDbl>& x, std::size_t i, x_N_dependency_flag xN_flag) {
708  if (xN_flag == XN_INDEPENDENT) {
709  return HEOS.components[i].EOS().d2alphar_dDelta_dTau(HEOS.tau(), HEOS.delta());
710  } else if (xN_flag == XN_DEPENDENT) {
711  std::size_t N = x.size();
712  if (i == N - 1) return 0;
713  return HEOS.components[i].EOS().d2alphar_dDelta_dTau(HEOS.tau(), HEOS.delta())
714  - HEOS.components[N - 1].EOS().d2alphar_dDelta_dTau(HEOS.tau(), HEOS.delta());
715  } else {
716  throw ValueError(format("xN_flag is invalid"));
717  }
718  }
719 
720  CoolPropDbl d2alphardxidxj(HelmholtzEOSMixtureBackend& HEOS, std::vector<CoolPropDbl>& x, std::size_t i, std::size_t j,
721  x_N_dependency_flag xN_flag) {
722  if (xN_flag == XN_INDEPENDENT) {
723  return 0;
724  } else if (xN_flag == XN_DEPENDENT) {
725  return 0;
726  } else {
727  throw ValueError(format("xN_flag is invalid"));
728  }
729  }
730 
731  CoolPropDbl d4alphar_dxi_dDelta3(HelmholtzEOSMixtureBackend& HEOS, std::vector<CoolPropDbl>& x, std::size_t i, x_N_dependency_flag xN_flag) {
732  if (xN_flag == XN_INDEPENDENT) {
733  return HEOS.components[i].EOS().d3alphar_dDelta3(HEOS.tau(), HEOS.delta());
734  } else {
735  throw ValueError(format("xN_flag is invalid"));
736  }
737  }
738  CoolPropDbl d4alphar_dxi_dTau3(HelmholtzEOSMixtureBackend& HEOS, std::vector<CoolPropDbl>& x, std::size_t i, x_N_dependency_flag xN_flag) {
739  if (xN_flag == XN_INDEPENDENT) {
740  return HEOS.components[i].EOS().d3alphar_dTau3(HEOS.tau(), HEOS.delta());
741  } else {
742  throw ValueError(format("xN_flag is invalid"));
743  }
744  }
745  CoolPropDbl d4alphar_dxi_dDelta_dTau2(HelmholtzEOSMixtureBackend& HEOS, std::vector<CoolPropDbl>& x, std::size_t i, x_N_dependency_flag xN_flag) {
746  if (xN_flag == XN_INDEPENDENT) {
747  return HEOS.components[i].EOS().d3alphar_dDelta_dTau2(HEOS.tau(), HEOS.delta());
748  } else {
749  throw ValueError(format("xN_flag is invalid"));
750  }
751  }
752  CoolPropDbl d4alphar_dxi_dDelta2_dTau(HelmholtzEOSMixtureBackend& HEOS, std::vector<CoolPropDbl>& x, std::size_t i, x_N_dependency_flag xN_flag) {
753  if (xN_flag == XN_INDEPENDENT) {
754  return HEOS.components[i].EOS().d3alphar_dDelta2_dTau(HEOS.tau(), HEOS.delta());
755  } else {
756  throw ValueError(format("xN_flag is invalid"));
757  }
758  }
759 
760  CoolPropDbl d3alphardxidxjdxk(HelmholtzEOSMixtureBackend& HEOS, std::vector<CoolPropDbl>& x, std::size_t i, std::size_t j, std::size_t k,
761  x_N_dependency_flag xN_flag) {
762  return 0;
763  }
764  CoolPropDbl d3alphar_dxi_dxj_dDelta(HelmholtzEOSMixtureBackend& HEOS, std::vector<CoolPropDbl>& x, std::size_t i, std::size_t j,
765  x_N_dependency_flag xN_flag) {
766  return 0;
767  }
768  CoolPropDbl d3alphar_dxi_dxj_dTau(HelmholtzEOSMixtureBackend& HEOS, std::vector<CoolPropDbl>& x, std::size_t i, std::size_t j,
769  x_N_dependency_flag xN_flag) {
770  return 0;
771  }
772  CoolPropDbl d4alphar_dxi_dxj_dDelta2(HelmholtzEOSMixtureBackend& HEOS, std::vector<CoolPropDbl>& x, std::size_t i, std::size_t j,
773  x_N_dependency_flag xN_flag) {
774  return 0;
775  }
776  CoolPropDbl d4alphar_dxi_dxj_dDelta_dTau(HelmholtzEOSMixtureBackend& HEOS, std::vector<CoolPropDbl>& x, std::size_t i, std::size_t j,
777  x_N_dependency_flag xN_flag) {
778  return 0;
779  }
780  CoolPropDbl d4alphar_dxi_dxj_dTau2(HelmholtzEOSMixtureBackend& HEOS, std::vector<CoolPropDbl>& x, std::size_t i, std::size_t j,
781  x_N_dependency_flag xN_flag) {
782  return 0;
783  }
784 };
785 
792 {
793  public:
796 
799 
801  return ResidualHelmholtz(Excess.copy(), CS);
802  }
804  return new ResidualHelmholtz(Excess.copy(), CS);
805  }
806 
807  virtual HelmholtzDerivatives all(HelmholtzEOSMixtureBackend& HEOS, const std::vector<CoolPropDbl>& mole_fractions, double tau, double delta,
808  bool cache_values = false) {
809  HelmholtzDerivatives a = CS.all(HEOS, tau, delta, mole_fractions, cache_values) + Excess.all(tau, delta, mole_fractions, cache_values);
810  a.delta_x_dalphar_ddelta = delta * a.dalphar_ddelta;
811  a.tau_x_dalphar_dtau = tau * a.dalphar_dtau;
812 
813  a.delta2_x_d2alphar_ddelta2 = POW2(delta) * a.d2alphar_ddelta2;
814  a.deltatau_x_d2alphar_ddelta_dtau = delta * tau * a.d2alphar_ddelta_dtau;
815  a.tau2_x_d2alphar_dtau2 = POW2(tau) * a.d2alphar_dtau2;
816 
817  return a;
818  }
820  std::vector<CoolPropDbl>& mole_fractions = HEOS.get_mole_fractions_ref();
821  return CS.dalphar_dxi(HEOS, mole_fractions, i, xN_flag) + Excess.dalphar_dxi(mole_fractions, i, xN_flag);
822  }
823  virtual CoolPropDbl d2alphardxidxj(HelmholtzEOSMixtureBackend& HEOS, std::size_t i, std::size_t j, x_N_dependency_flag xN_flag) {
824  std::vector<CoolPropDbl>& mole_fractions = HEOS.get_mole_fractions_ref();
825  return CS.d2alphardxidxj(HEOS, mole_fractions, i, j, xN_flag) + Excess.d2alphardxidxj(mole_fractions, i, j, xN_flag);
826  }
828  std::vector<CoolPropDbl>& mole_fractions = HEOS.get_mole_fractions_ref();
829  return CS.d2alphar_dxi_dTau(HEOS, mole_fractions, i, xN_flag) + Excess.d2alphar_dxi_dTau(mole_fractions, i, xN_flag);
830  }
832  std::vector<CoolPropDbl>& mole_fractions = HEOS.get_mole_fractions_ref();
833  return CS.d2alphar_dxi_dDelta(HEOS, mole_fractions, i, xN_flag) + Excess.d2alphar_dxi_dDelta(mole_fractions, i, xN_flag);
834  }
836  std::vector<CoolPropDbl>& mole_fractions = HEOS.get_mole_fractions_ref();
837  return CS.d3alphar_dxi_dTau2(HEOS, mole_fractions, i, xN_flag) + Excess.d3alphar_dxi_dTau2(mole_fractions, i, xN_flag);
838  }
840  std::vector<CoolPropDbl>& mole_fractions = HEOS.get_mole_fractions_ref();
841  return CS.d3alphar_dxi_dDelta_dTau(HEOS, mole_fractions, i, xN_flag) + Excess.d3alphar_dxi_dDelta_dTau(mole_fractions, i, xN_flag);
842  }
844  std::vector<CoolPropDbl>& mole_fractions = HEOS.get_mole_fractions_ref();
845  return CS.d3alphar_dxi_dDelta2(HEOS, mole_fractions, i, xN_flag) + Excess.d3alphar_dxi_dDelta2(mole_fractions, i, xN_flag);
846  }
847  virtual CoolPropDbl d3alphar_dxi_dxj_dTau(HelmholtzEOSMixtureBackend& HEOS, std::size_t i, std::size_t j, x_N_dependency_flag xN_flag) {
848  std::vector<CoolPropDbl>& mole_fractions = HEOS.get_mole_fractions_ref();
849  return CS.d3alphar_dxi_dxj_dTau(HEOS, mole_fractions, i, j, xN_flag) + Excess.d3alphar_dxi_dxj_dTau(mole_fractions, i, j, xN_flag);
850  }
851  virtual CoolPropDbl d3alphar_dxi_dxj_dDelta(HelmholtzEOSMixtureBackend& HEOS, std::size_t i, std::size_t j, x_N_dependency_flag xN_flag) {
852  std::vector<CoolPropDbl>& mole_fractions = HEOS.get_mole_fractions_ref();
853  return CS.d3alphar_dxi_dxj_dDelta(HEOS, mole_fractions, i, j, xN_flag) + Excess.d3alphar_dxi_dxj_dDelta(mole_fractions, i, j, xN_flag);
854  }
855  virtual CoolPropDbl d3alphardxidxjdxk(HelmholtzEOSMixtureBackend& HEOS, std::size_t i, std::size_t j, std::size_t k,
856  x_N_dependency_flag xN_flag) {
857  std::vector<CoolPropDbl>& mole_fractions = HEOS.get_mole_fractions_ref();
858  return CS.d3alphardxidxjdxk(HEOS, mole_fractions, i, j, k, xN_flag) + Excess.d3alphardxidxjdxk(mole_fractions, i, j, k, xN_flag);
859  }
860 
862  std::vector<CoolPropDbl>& mole_fractions = HEOS.get_mole_fractions_ref();
863  return CS.d4alphar_dxi_dTau3(HEOS, mole_fractions, i, xN_flag) + Excess.d4alphar_dxi_dTau3(mole_fractions, i, xN_flag);
864  }
866  std::vector<CoolPropDbl>& mole_fractions = HEOS.get_mole_fractions_ref();
867  return CS.d4alphar_dxi_dDelta2_dTau(HEOS, mole_fractions, i, xN_flag) + Excess.d4alphar_dxi_dDelta2_dTau(mole_fractions, i, xN_flag);
868  }
870  std::vector<CoolPropDbl>& mole_fractions = HEOS.get_mole_fractions_ref();
871  return CS.d4alphar_dxi_dDelta_dTau2(HEOS, mole_fractions, i, xN_flag) + Excess.d4alphar_dxi_dDelta_dTau2(mole_fractions, i, xN_flag);
872  }
874  std::vector<CoolPropDbl>& mole_fractions = HEOS.get_mole_fractions_ref();
875  return CS.d4alphar_dxi_dDelta3(HEOS, mole_fractions, i, xN_flag) + Excess.d4alphar_dxi_dDelta3(mole_fractions, i, xN_flag);
876  }
877  virtual CoolPropDbl d4alphar_dxi_dxj_dTau2(HelmholtzEOSMixtureBackend& HEOS, std::size_t i, std::size_t j, x_N_dependency_flag xN_flag) {
878  std::vector<CoolPropDbl>& mole_fractions = HEOS.get_mole_fractions_ref();
879  return CS.d4alphar_dxi_dxj_dTau2(HEOS, mole_fractions, i, j, xN_flag) + Excess.d4alphar_dxi_dxj_dTau2(mole_fractions, i, j, xN_flag);
880  }
881  virtual CoolPropDbl d4alphar_dxi_dxj_dDelta_dTau(HelmholtzEOSMixtureBackend& HEOS, std::size_t i, std::size_t j, x_N_dependency_flag xN_flag) {
882  std::vector<CoolPropDbl>& mole_fractions = HEOS.get_mole_fractions_ref();
883  return CS.d4alphar_dxi_dxj_dDelta_dTau(HEOS, mole_fractions, i, j, xN_flag)
884  + Excess.d4alphar_dxi_dxj_dDelta_dTau(mole_fractions, i, j, xN_flag);
885  }
886  virtual CoolPropDbl d4alphar_dxi_dxj_dDelta2(HelmholtzEOSMixtureBackend& HEOS, std::size_t i, std::size_t j, x_N_dependency_flag xN_flag) {
887  std::vector<CoolPropDbl>& mole_fractions = HEOS.get_mole_fractions_ref();
888  return CS.d4alphar_dxi_dxj_dDelta2(HEOS, mole_fractions, i, j, xN_flag) + Excess.d4alphar_dxi_dxj_dDelta2(mole_fractions, i, j, xN_flag);
889  }
890  virtual CoolPropDbl d4alphar_dxi_dxj_dxk_dDelta(HelmholtzEOSMixtureBackend& HEOS, std::size_t i, std::size_t j, std::size_t k,
891  x_N_dependency_flag xN_flag) {
892  return 0;
893  }
894  virtual CoolPropDbl d4alphar_dxi_dxj_dxk_dTau(HelmholtzEOSMixtureBackend& HEOS, std::size_t i, std::size_t j, std::size_t k,
895  x_N_dependency_flag xN_flag) {
896  return 0;
897  }
898 };
899 
900 } /* namespace CoolProp */
901 #endif /* HELMHOLTZEOSMIXTUREBACKEND_H_ */