Reaktoro  v2.11.0
A unified framework for modeling chemically reactive systems
MolalityUtils.hpp
1 // Reaktoro is a unified framework for modeling chemically reactive systems.
2 //
3 // Copyright © 2014-2024 Allan Leal
4 //
5 // This library is free software; you can redistribute it and/or
6 // modify it under the terms of the GNU Lesser General Public
7 // License as published by the Free Software Foundation; either
8 // version 2.1 of the License, or (at your option) any later version.
9 //
10 // This library is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 // Lesser General Public License for more details.
14 //
15 // You should have received a copy of the GNU Lesser General Public License
16 // along with this library. If not, see <http://www.gnu.org/licenses/>.
17 
18 #pragma once
19 
20 // Reaktoro includes
21 #include <Reaktoro/Common/TraitsUtils.hpp>
22 #include <Reaktoro/Common/Matrix.hpp>
23 #include <Reaktoro/Water/WaterConstants.hpp>
24 
25 namespace Reaktoro {
26 
31 template<typename ArrayConstRef, typename ArrayRef>
32 auto molalities(ArrayConstRef&& n, Index iH2O, ArrayRef&& m)
33 {
34  const auto N = n.size();
35  assert(iH2O < N);
36  const auto kgH2O = n[iH2O] * waterMolarMass;
37  const auto nsum = n.sum();
38  if(N == 1) {
39  m[iH2O] = 1.0 / waterMolarMass;
40  return;
41  }
42  if(kgH2O == 0.0 || nsum == 0.0) {
43  m.fill(0.0);
44  m[iH2O] = 1.0 / waterMolarMass;
45  return;
46  }
47  m = n/kgH2O;
48 }
49 
53 template<typename ArrayConstRef>
54 auto molalities(ArrayConstRef&& n, Index iH2O)
55 {
56  using T = Decay<decltype(n[0])>;
57  const auto N = n.size();
58  ArrayX<T> m(N);
59  molalities(n, iH2O, m);
60  return m;
61 }
62 
67 template<typename ArrayConstRef, typename MatrixRef>
68 auto molalitiesJacobian(ArrayConstRef&& n, Index iH2O, MatrixRef&& J)
69 {
70  //-----------------------------------------------------------------------------------------------------
71  // == LATEX ==
72  //-----------------------------------------------------------------------------------------------------
73  // \frac{\partial m_{i}}{\partial n_{j}}=m_{i}\left(\frac{\delta_{ij}}{n_{i}}-\frac{\delta_{jw}}{n_{w}}\right)
74  // \frac{\partial x_{w}}{\partial n_{j}}=\frac{1}{n_{\Sigma}}\left(\delta_{wj}-x_{w}\right)
75  //-----------------------------------------------------------------------------------------------------
76  using T = Decay<decltype(J(0, 0))>;
77  const auto N = n.size();
78  assert(iH2O < N);
79  assert(J.rows() == N);
80  assert(J.cols() == N);
81  J.fill(0.0);
82  const T nH2O = n[iH2O];
83  const T nsum = n.sum();
84  if(nH2O == 0.0 || nsum == 0.0)
85  return;
86  const T kgH2O = nH2O * waterMolarMass;
87  const T xH2O = nH2O/nsum;
88  const T kgH2Oinv = 1.0/kgH2O;
89  for(auto i = 0; i < N; ++i)
90  {
91  const T ni = n[i];
92  const T mi = ni/kgH2O;
93  J(i, i) = kgH2Oinv;
94  J(i, iH2O) -= mi/nH2O;
95  }
96  J.row(iH2O).array() = 0.0;
97 }
98 
102 template<typename ArrayConstRef>
103 auto molalitiesJacobian(ArrayConstRef&& n, Index iH2O)
104 {
105  using T = Decay<decltype(n[0])>;
106  const auto N = n.size();
107  MatrixX<T> J(N, N);
108  molalitiesJacobian(n, iH2O, J);
109  return J;
110 }
111 
116 template<typename ArrayConstRef, typename MatrixRef>
117 auto lnMolalitiesJacobian(ArrayConstRef&& n, Index iH2O, MatrixRef&& J) -> void
118 {
119  //-----------------------------------------------------------------------------------------------------
120  // == LATEX ==
121  //-----------------------------------------------------------------------------------------------------
122  // \frac{\partial\ln m_{i}}{\partial n_{j}}=\frac{1}{m_{i}}\frac{\partial m_{i}}{\partial n_{j}}=\left(\frac{\delta_{ij}}{n_{i}}-\frac{\delta_{jw}}{n_{w}}\right)
123  // \frac{\partial\ln x_{w}}{\partial n_{j}}=\frac{\delta_{wj}}{n_{w}}-\frac{1}{n_{\Sigma}}
124  //-----------------------------------------------------------------------------------------------------
125  using T = Decay<decltype(J(0, 0))>;
126  const auto N = n.size();
127  assert(iH2O < N);
128  assert(J.rows() == N);
129  assert(J.cols() == N);
130  J.fill(0.0);
131  const T nH2O = n[iH2O];
132  const T nsum = n.sum();
133  if(nH2O == 0.0 || nsum == 0.0)
134  return;
135  for(auto i = 0; i < N; ++i)
136  {
137  const T ni = n[i];
138  J(i, i) = 1.0/ni;
139  J(i, iH2O) -= 1.0/nH2O;
140  }
141  J.row(iH2O).array() = 0.0;
142 }
143 
147 template<typename ArrayConstRef>
148 auto lnMolalitiesJacobian(ArrayConstRef&& n, Index iH2O)
149 {
150  using T = Decay<decltype(n[0])>;
151  const auto N = n.size();
152  MatrixX<T> J(N, N);
153  lnMolalitiesJacobian(n, iH2O, J);
154  return J;
155 }
156 
161 template<typename ArrayConstRef, typename VectorRef>
162 auto lnMolalitiesJacobianDiagonal(ArrayConstRef&& n, Index iH2O, VectorRef&& D) -> void
163 {
164  //-----------------------------------------------------------------------------------------------------
165  // == LATEX ==
166  //-----------------------------------------------------------------------------------------------------
167  // \frac{\partial\ln m_{i}}{\partial n_{i}}=\frac{1}{n_{i}}-\frac{\delta_{iw}}{n_{w}}
168  // \ln a_{w}=-\dfrac{1-x_{w}}{x_{w}}=-\dfrac{n_{\Sigma}-n_{w}}{n_{w}}
169  // \dfrac{\partial\ln a_{w}}{\partial n_{i}}=\begin{cases}-\dfrac{1}{n_{w}} & i\neq w\\\dfrac{n_{\Sigma}-n_{w}}{n_{w}^{2}} & i=w\end{cases}
170  //-----------------------------------------------------------------------------------------------------
171  using T = Decay<decltype(D[0])>;
172  const auto N = n.size();
173  assert(iH2O < N);
174  assert(D.rows() == N);
175  const T nH2O = n[iH2O];
176  const T nsum = n.sum();
177  if(nH2O == 0.0 || nsum == 0.0) {
178  D.fill(0.0);
179  return;
180  }
181  for(auto i = 0; i < N; ++i)
182  D[i] = 1.0/n[i];
183  D[iH2O] = 0.0;
184 }
185 
189 template<typename ArrayConstRef>
190 auto lnMolalitiesJacobianDiagonal(ArrayConstRef&& n, Index iH2O)
191 {
192  using T = Decay<decltype(n[0])>;
193  const auto N = n.size();
194  ArrayX<T> D(N);
195  lnMolalitiesJacobianDiagonal(n, iH2O, D);
196  return D;
197 }
198 
199 } // namespace Reaktoro
The namespace containing all components of the Reaktoro library.
Definition: Algorithms.hpp:29
auto lnMolalitiesJacobian(ArrayConstRef &&n, Index iH2O, MatrixRef &&J) -> void
Compute the Jacobian matrix of the species molalities in natural log ( ).
Definition: MolalityUtils.hpp:117
auto molalitiesJacobian(ArrayConstRef &&n, Index iH2O, MatrixRef &&J)
Compute the Jacobian matrix of the species molalities ( ).
Definition: MolalityUtils.hpp:68
std::size_t Index
Define a type that represents an index.
Definition: Index.hpp:26
Eigen::Matrix< T, -1, -1, 0, -1, -1 > MatrixX
Convenient alias to Eigen type.
Definition: Matrix.hpp:42
auto molalities(ArrayConstRef &&n, Index iH2O, ArrayRef &&m)
Compute the molalities of the species with given species amounts.
Definition: MolalityUtils.hpp:32
const double waterMolarMass
The molar mass of water in units of kg/mol.
Definition: WaterConstants.hpp:23
Eigen::Array< T, -1, 1, 0, -1, 1 > ArrayX
Convenient alias to Eigen type.
Definition: Matrix.hpp:46
auto lnMolalitiesJacobianDiagonal(ArrayConstRef &&n, Index iH2O, VectorRef &&D) -> void
Compute the diagonal only of the Jacobian matrix of the species molalities in natural log ( ).
Definition: MolalityUtils.hpp:162