Branch data Line data Source code
1 : : // *****************************************************************************
2 : : /*!
3 : : \file src/PDE/EoS/WilkinsAluminum.cpp
4 : : \copyright 2012-2015 J. Bakosi,
5 : : 2016-2018 Los Alamos National Security, LLC.,
6 : : 2019-2021 Triad National Security, LLC.
7 : : All rights reserved. See the LICENSE file for details.
8 : : \brief Wilkins equation of state for aluminum
9 : : \details This file defines functions for the Wilkins equation of
10 : : state for solids and a hydro EoS for aluminum. These functions were
11 : : taken from Example 4 of Barton, Philip T. "An interface-capturing
12 : : Godunov method for the simulation of compressible solid-fluid
13 : : problems." Journal of Computational Physics 390 (2019): 25-50.
14 : : */
15 : : // *****************************************************************************
16 : :
17 : : #include <cmath>
18 : : #include <iostream>
19 : : #include "Vector.hpp"
20 : : #include "EoS/WilkinsAluminum.hpp"
21 : : #include "EoS/GetMatProp.hpp"
22 : :
23 : : // // Lapacke forward declarations
24 : : // extern "C" {
25 : :
26 : : // using lapack_int = long;
27 : :
28 : : // #define LAPACK_ROW_MAJOR 101
29 : :
30 : : // lapack_int LAPACKE_dgeev(int, char, char, lapack_int, double*, lapack_int,
31 : : // double*, double*, double*, lapack_int, double*, lapack_int );
32 : :
33 : : // }
34 : :
35 : : static const tk::real e1 = -13.0e+09;
36 : : static const tk::real e2 = 20.0e+09;
37 : : static const tk::real e3 = 52.0e+09;
38 : : static const tk::real e4 = -59.0e+09;
39 : : static const tk::real e5 = 151.0e+09;
40 : :
41 : : using inciter::WilkinsAluminum;
42 : :
43 : 0 : WilkinsAluminum::WilkinsAluminum(
44 : : tk::real gamma,
45 : : tk::real cv,
46 : 0 : tk::real mu ) :
47 : : m_gamma(gamma),
48 : : m_cv(cv),
49 : 0 : m_mu(mu)
50 : : // *************************************************************************
51 : : // Constructor
52 : : //! \param[in] gamma Ratio of specific heats
53 : : //! \param[in] cv Specific heat at constant volume
54 : : //! \param[in] mu Constant shear modulus
55 : : // *************************************************************************
56 : : {
57 : : // Since this is only for aluminum we hard set rho0
58 : 0 : m_rho0 = 2700.0;
59 : 0 : }
60 : :
61 : : void
62 : 0 : WilkinsAluminum::setRho0( tk::real rho0 )
63 : : // *************************************************************************
64 : : // Set rho0 EOS parameter; i.e. the initial density
65 : : //! \param[in] rho0 Initial material density that needs to be stored
66 : : // *************************************************************************
67 : : {
68 : 0 : m_rho0 = rho0;
69 : 0 : }
70 : :
71 : : tk::real
72 : 0 : WilkinsAluminum::density(
73 : : tk::real pr,
74 : : tk::real ) const
75 : : // *************************************************************************
76 : : //! \brief Calculate density from the material pressure and temperature
77 : : //! using the WilkinsAluminum equation of state
78 : : //! \param[in] pr Material pressure
79 : : // //! \param[in] temp Material temperature
80 : : //! \return Material density calculated using the WilkinsAluminum EoS
81 : : // *************************************************************************
82 : : {
83 : 0 : tk::real rho0 = m_rho0;
84 : : // Quick Newton
85 : 0 : tk::real rho = rho0;
86 : 0 : std::size_t maxiter = 50;
87 : 0 : tk::real tol = 1.0e-04;
88 : 0 : tk::real err = tol + 1;
89 [ - - ]: 0 : for (std::size_t iter=0; iter<maxiter; ++iter)
90 : : {
91 : 0 : tk::real p = 2*e2*std::pow(rho/rho0,3.0)
92 : 0 : + e3*std::pow(rho/rho0,2.0)
93 : 0 : - e5*rho/rho0 - e4 - pr;
94 : 0 : tk::real dpdrho = 6*e2*std::pow(rho/rho0,2.0)/rho0
95 : 0 : + 2*e3*rho/(rho0*rho0) - e5/rho0;
96 : 0 : tk::real delta = p/dpdrho;
97 : 0 : rho -= delta;
98 : 0 : err = std::sqrt(std::pow(p,2.0));
99 [ - - ]: 0 : if (err < tol) break;
100 : : }
101 : 0 : return rho;
102 : : }
103 : :
104 : : tk::real
105 : 0 : WilkinsAluminum::pressure(
106 : : tk::real arho,
107 : : tk::real,
108 : : tk::real,
109 : : tk::real,
110 : : tk::real,
111 : : tk::real alpha,
112 : : std::size_t /*imat*/,
113 : : const std::array< std::array< tk::real, 3 >, 3 >& ) const
114 : : // *************************************************************************
115 : : //! \brief Calculate pressure from the material density, momentum, total energy
116 : : //! and the inverse deformation gradient tensor using the WilkinsAluminum
117 : : //! equation of state
118 : : //! \param[in] arho Material partial density (alpha_k * rho_k)
119 : : // //! \param[in] u X-velocity
120 : : // //! \param[in] v Y-velocity
121 : : // //! \param[in] w Z-velocity
122 : : // //! \param[in] arhoE Material total energy (alpha_k * rho_k * E_k)
123 : : //! \param[in] alpha Material volume fraction. Default is 1.0, so that for
124 : : //! the single-material system, this argument can be left unspecified by
125 : : //! the calling code
126 : : // //! \param[in] imat Material-id who's EoS is required. Default is 0, so that
127 : : // //! for the single-material system, this argument can be left unspecified
128 : : // //! by the calling code
129 : : // //! \param[in] defgrad Material inverse deformation gradient tensor
130 : : // //! (g_k). Default is 0, so that for the single-material system,
131 : : // //! this argument can be left unspecified by the calling code
132 : : //! \return Material partial pressure (alpha_k * p_k) calculated using the
133 : : //! WilkinsAluminum EoS
134 : : // *************************************************************************
135 : : {
136 : 0 : tk::real rho0 = m_rho0;
137 : 0 : tk::real rho = arho/alpha;
138 : 0 : tk::real partpressure = alpha*(2*e2*std::pow(rho/rho0,3.0)
139 : 0 : + e3*std::pow(rho/rho0,2.0)
140 : 0 : - e5*rho/rho0 - e4 );
141 : :
142 [ - - ]: 0 : partpressure = std::max(min_eff_pressure(1e-10, arho, alpha), partpressure);
143 : :
144 : : //// check partial pressure divergence
145 : : //if (!std::isfinite(partpressure)) {
146 : : // std::cout << "Material-id: " << imat << std::endl;
147 : : // std::cout << "Volume-fraction: " << alpha << std::endl;
148 : : // std::cout << "Partial density: " << arho << std::endl;
149 : : // Throw("Material-" + std::to_string(imat) +
150 : : // " has nan/inf partial pressure: " + std::to_string(partpressure) +
151 : : // ", material volume fraction: " + std::to_string(alpha));
152 : : //}
153 : :
154 : 0 : return partpressure;
155 : : }
156 : :
157 : : std::array< std::array< tk::real, 3 >, 3 >
158 : 0 : WilkinsAluminum::CauchyStress(
159 : : tk::real alpha,
160 : : std::size_t /*imat*/,
161 : : const std::array< std::array< tk::real, 3 >, 3 >& defgrad ) const
162 : : // *************************************************************************
163 : : //! \brief Calculate the elastic Cauchy stress tensor from the material
164 : : //! inverse deformation gradient tensor using the WilkinsAluminum EOS
165 : : //! \param[in] alpha Material volume fraction. Default is 1.0, so that for
166 : : //! the single-material system, this argument can be left unspecified by
167 : : //! the calling code
168 : : // //! \param[in] imat Material-id who's EoS is required. Default is 0, so that
169 : : // //! for the single-material system, this argument can be left unspecified
170 : : // //! by the calling code
171 : : //! \param[in] defgrad Material inverse deformation gradient tensor (g_k).
172 : : //! \return Material Cauchy stress tensor (alpha_k * sigma_k) calculated using
173 : : //! the WilkinsAluminum EoS
174 : : // *************************************************************************
175 : : {
176 : 0 : std::array< std::array< tk::real, 3 >, 3 > asig{{{0,0,0}, {0,0,0}, {0,0,0}}};
177 : :
178 : : // obtain elastic contribution to energy and substract it from pmean
179 : : std::array< std::array< tk::real, 3 >, 3 > devH;
180 : :
181 : : // p_mean
182 [ - - ]: 0 : auto pmean = - alpha * elasticEnergy(defgrad, devH);
183 : :
184 : : // Pressure due to shear
185 : 0 : asig[0][0] = -pmean;
186 : 0 : asig[1][1] = -pmean;
187 : 0 : asig[2][2] = -pmean;
188 : :
189 : : // Add deviatoric component of Cauchy stress tensor
190 [ - - ]: 0 : for (std::size_t i=0; i<3; ++i) {
191 [ - - ]: 0 : for (std::size_t j=0; j<3; ++j)
192 : 0 : asig[i][j] += 2.0*m_mu*alpha*devH[i][j];
193 : : }
194 : :
195 : 0 : return asig;
196 : : }
197 : :
198 : : tk::real
199 : 0 : WilkinsAluminum::soundspeed(
200 : : tk::real arho,
201 : : tk::real apr,
202 : : tk::real alpha,
203 : : std::size_t imat,
204 : : const std::array< std::array< tk::real, 3 >, 3 >& /*defgrad*/ ) const
205 : : // *************************************************************************
206 : : //! Calculate speed of sound from the material density and material pressure
207 : : //! \param[in] arho Material partial density (alpha_k * rho_k)
208 : : //! \param[in] apr Material partial pressure (alpha_k * p_k)
209 : : //! \param[in] alpha Material volume fraction. Default is 1.0, so that for
210 : : //! the single-material system, this argument can be left unspecified by
211 : : //! the calling code
212 : : //! \param[in] imat Material-id who's EoS is required. Default is 0, so that
213 : : //! for the single-material system, this argument can be left unspecified
214 : : //! by the calling code
215 : : //! (alpha * sigma_ij * n_j) projected onto the normal vector. Default is 0,
216 : : //! so that for the single-material system, this argument can be left
217 : : //! unspecified by the calling code
218 : : // //! \param[in] defgrad Material inverse deformation gradient tensor
219 : : // //! (g_k) with the first dimension aligned to direction in which
220 : : // //! wave speeds are required. Default is 0, so that for the single-material
221 : : // //! system, this argument can be left unspecified by the calling code
222 : : //! \return Material speed of sound using the WilkinsAluminum EoS
223 : : // *************************************************************************
224 : : {
225 : 0 : tk::real a = 0.0;
226 : :
227 : : // Hydro contribution
228 : 0 : tk::real rho0 = m_rho0;
229 : 0 : tk::real rho = arho/alpha;
230 : 0 : a += std::max( 1.0e-15, 6*e2*std::pow(rho/rho0,2.0)/rho0
231 : 0 : + 2*e3*rho/(rho0*rho0) - e5/rho0 );
232 : :
233 : : // Shear contribution
234 : 0 : a += (4.0/3.0) * m_mu / (arho/alpha);
235 : :
236 : : // Compute square root
237 : 0 : a = std::sqrt(a);
238 : :
239 : : // check sound speed divergence
240 [ - - ]: 0 : if (!std::isfinite(a)) {
241 : 0 : std::cout << "Material-id: " << imat << std::endl;
242 : 0 : std::cout << "Volume-fraction: " << alpha << std::endl;
243 : 0 : std::cout << "Partial density: " << arho << std::endl;
244 : 0 : std::cout << "Partial pressure: " << apr << std::endl;
245 [ - - ][ - - ]: 0 : Throw("Material-" + std::to_string(imat) + " has nan/inf sound speed: "
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ][ - - ]
246 : : + std::to_string(a) + ", material volume fraction: " +
247 : : std::to_string(alpha));
248 : : }
249 : :
250 : 0 : return a;
251 : : }
252 : :
253 : : tk::real
254 : 0 : WilkinsAluminum::shearspeed(
255 : : tk::real arho,
256 : : tk::real alpha,
257 : : std::size_t imat ) const
258 : : // *************************************************************************
259 : : //! Calculate speed of sound from the material density and material pressure
260 : : //! \param[in] arho Material partial density (alpha_k * rho_k)
261 : : //! \param[in] alpha Material volume fraction. Default is 1.0, so that for
262 : : //! the single-material system, this argument can be left unspecified by
263 : : //! the calling code
264 : : //! \param[in] imat Material-id who's EoS is required. Default is 0, so that
265 : : //! for the single-material system, this argument can be left unspecified
266 : : //! by the calling code
267 : : //! \return Material shear-wave speed speed using the SmallShearSolid EoS
268 : : // *************************************************************************
269 : : {
270 : : // Approximate shear-wave speed. Ref. Barton, P. T. (2019).
271 : : // An interface-capturing Godunov method for the simulation of compressible
272 : : // solid-fluid problems. Journal of Computational Physics, 390, 25-50.
273 : 0 : tk::real a = std::sqrt(alpha*m_mu/arho);
274 : :
275 : : // check shear-wave speed divergence
276 [ - - ]: 0 : if (!std::isfinite(a)) {
277 : 0 : std::cout << "Material-id: " << imat << std::endl;
278 : 0 : std::cout << "Volume-fraction: " << alpha << std::endl;
279 : 0 : std::cout << "Partial density: " << arho << std::endl;
280 [ - - ][ - - ]: 0 : Throw("Material-" + std::to_string(imat) + " has nan/inf shear-wave speed: "
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ][ - - ]
281 : : + std::to_string(a) + ", material volume fraction: " +
282 : : std::to_string(alpha));
283 : : }
284 : :
285 : 0 : return a;
286 : : }
287 : :
288 : : tk::real
289 : 0 : WilkinsAluminum::totalenergy(
290 : : tk::real arho,
291 : : tk::real u,
292 : : tk::real v,
293 : : tk::real w,
294 : : tk::real,
295 : : tk::real alpha,
296 : : const std::array< std::array< tk::real, 3 >, 3 >& defgrad ) const
297 : : // *************************************************************************
298 : : //! \brief Calculate material specific total energy from the material
299 : : //! density, momentum and material pressure
300 : : //! \param[in] arho Material partial density
301 : : //! \param[in] u X-velocity
302 : : //! \param[in] v Y-velocity
303 : : //! \param[in] w Z-velocity
304 : : // //! \param[in] apr Material partial pressure
305 : : //! \param[in] alpha Material volume fraction. Default is 1.0, so that for
306 : : //! the single-material system, this argument can be left unspecified by
307 : : //! the calling code
308 : : //! \param[in] defgrad Material inverse deformation gradient tensor
309 : : //! g_k. Default is 0, so that for the single-material system,
310 : : //! this argument can be left unspecified by the calling code
311 : : //! \return Material specific total energy using the WilkinsAluminum EoS
312 : : // *************************************************************************
313 : : {
314 : : // obtain hydro contribution to energy
315 : 0 : tk::real rho0 = m_rho0;
316 : 0 : tk::real rho = arho/alpha;
317 : 0 : tk::real rhoEh = (e1+e2*std::pow(rho/rho0,2.0)+e3*(rho/rho0)
318 : 0 : +e4*std::pow(rho/rho0,-1.0)-e5*std::log(rho/rho0))/rho0
319 : 0 : + 0.5*rho*(u*u + v*v + w*w);
320 : : // obtain elastic contribution to energy
321 : : std::array< std::array< tk::real, 3 >, 3 > devH;
322 [ - - ]: 0 : tk::real rhoEe = elasticEnergy(defgrad, devH);
323 : :
324 : 0 : return alpha*(rhoEh + rhoEe);
325 : : }
326 : :
327 : : tk::real
328 : 0 : WilkinsAluminum::temperature(
329 : : tk::real,
330 : : tk::real,
331 : : tk::real,
332 : : tk::real,
333 : : tk::real,
334 : : tk::real,
335 : : const std::array< std::array< tk::real, 3 >, 3 >& ) const
336 : : // *************************************************************************
337 : : //! \brief Calculate material temperature from the material density, and
338 : : //! material specific total energy
339 : : // //! \param[in] arho Material partial density (alpha_k * rho_k)
340 : : // //! \param[in] u X-velocity
341 : : // //! \param[in] v Y-velocity
342 : : // //! \param[in] w Z-velocity
343 : : // //! \param[in] arhoE Material total energy (alpha_k * rho_k * E_k)
344 : : // //! \param[in] alpha Material volume fraction. Default is 1.0, so that for
345 : : // //! the single-material system, this argument can be left unspecified by
346 : : // //! the calling code
347 : : // //! \param[in] defgrad Material inverse deformation gradient tensor
348 : : // //! (g_k). Default is 0, so that for the single-material system,
349 : : // //! this argument can be left unspecified by the calling code
350 : : //! \return Material temperature using the WilkinsAluminum EoS
351 : : // *************************************************************************
352 : : {
353 : : // Temperature does not directly contribute to energy
354 : : // So we just set a value.
355 : 0 : tk::real t = 300.0;
356 : :
357 : 0 : return t;
358 : : }
359 : :
360 : : tk::real
361 : 0 : WilkinsAluminum::min_eff_pressure(
362 : : tk::real min,
363 : : tk::real,
364 : : tk::real ) const
365 : : // *************************************************************************
366 : : //! Compute the minimum allowed pressure
367 : : //! \param[in] min Numerical threshold above which pressure needs to be limited
368 : : //! \return Minimum pressure allowed by physical constraints
369 : : // *************************************************************************
370 : : {
371 : : // minimum pressure is constrained by zero soundspeed.
372 : 0 : return min;
373 : : }
374 : :
375 : : tk::real
376 : 0 : WilkinsAluminum::elasticEnergy(
377 : : const std::array< std::array< tk::real, 3 >, 3 >& defgrad,
378 : : std::array< std::array< tk::real, 3 >, 3 >& devH ) const
379 : : // *************************************************************************
380 : : //! \brief Calculate elastic contribution to material energy from the material
381 : : //! density, and deformation gradient tensor
382 : : //! \param[in] defgrad Material inverse deformation gradient tensor
383 : : //! \param[in/out] devH Deviatoric part of the Hensky tensor
384 : : //! \return Material elastic energy using the WilkinsAluminum EoS
385 : : //! \details This function returns the material elastic energy, and also stores
386 : : //! the elastic shear distortion for further use
387 : : // *************************************************************************
388 : : {
389 : : // Compute deviatoric part of Hencky tensor
390 : 0 : devH = tk::getDevHencky(defgrad);
391 : :
392 : : // Compute elastic energy
393 : 0 : tk::real rhoEe = 0.0;
394 [ - - ]: 0 : for (std::size_t i=0; i<3; ++i)
395 [ - - ]: 0 : for (std::size_t j=0; j<3; ++j)
396 : 0 : rhoEe += m_mu*devH[i][j]*devH[i][j];
397 : :
398 : 0 : return rhoEe;
399 : : }
|