11 #include "RankFourTensor.h"
14 #include "MooseRandom.h"
17 #include <petscblaslapack.h>
25 params.addRangeCheckedParam<Real>(
"linear_dependent",
27 "linear_dependent>=0 & linear_dependent<1",
28 "Flow directions are considered linearly dependent if the "
29 "smallest singular value is less than linear_dependent times "
30 "the largest singular value");
36 _svd_tol(_params.get<Real>(
"linear_dependent")),
39 for (
unsigned model = 0; model <
_num_models; ++model)
48 std::vector<Real> & s)
53 s.resize(std::min(bm, bn));
64 std::vector<double> a(bm * 6);
67 for (
int col = 0; col < 3; ++col)
68 for (
int row = 0; row < bm; ++row)
69 a[ind++] = r[row](0, col);
70 for (
int col = 3; col < 5; ++col)
71 for (
int row = 0; row < bm; ++row)
72 a[ind++] = r[row](1, col - 2);
73 for (
int row = 0; row < bm; ++row)
74 a[ind++] = r[row](2, 2);
79 std::vector<double> u(sizeu);
81 std::vector<double> vt(sizevt);
83 int sizework = 16 * (bm + 6);
84 std::vector<double> work(sizework);
108 const std::vector<Real> & intnl,
109 const std::vector<Real> & f,
110 const std::vector<RankTwoTensor> & r,
111 const std::vector<bool> & active,
112 std::vector<bool> & deactivated_due_to_ld)
116 unsigned num_active = r.size();
121 std::vector<double> s;
124 mooseError(
"In finding the SVD in the return-map algorithm, the PETSC LAPACK gesvd routine "
125 "returned with error code ",
130 unsigned int num_lin_dep = 0;
132 unsigned i = s.size();
139 if (num_lin_dep == 0 && num_active <= 6)
148 std::vector<RankTwoTensor> df_dstress;
151 typedef std::pair<Real, unsigned> pair_for_sorting;
152 std::vector<pair_for_sorting> dist(num_active);
153 for (
unsigned i = 0; i < num_active; ++i)
155 dist[i].first = f[i] / df_dstress[i].L2norm();
158 std::sort(dist.begin(), dist.end());
161 bool equals_detected =
false;
162 for (
unsigned i = 0; i < num_active - 1; ++i)
163 if (std::abs(dist[i].first - dist[i + 1].first) <
_min_f_tol)
165 equals_detected =
true;
166 dist[i].first +=
_min_f_tol * (MooseRandom::rand() - 0.5);
169 std::sort(dist.begin(), dist.end());
171 std::vector<bool> scheduled_for_deactivation;
172 scheduled_for_deactivation.assign(num_active,
false);
181 current_yf = dist[num_active - 1].second;
183 std::vector<RankTwoTensor> r_tmp = {r[current_yf]};
185 unsigned num_kept_active = 1;
186 for (
unsigned yf_to_try = 2; yf_to_try <= num_active; ++yf_to_try)
188 current_yf = dist[num_active - yf_to_try].second;
190 scheduled_for_deactivation[current_yf] =
true;
191 else if (num_kept_active >= 6)
193 scheduled_for_deactivation[current_yf] =
true;
196 r_tmp.push_back(r[current_yf]);
199 mooseError(
"In finding the SVD in the return-map algorithm, the PETSC LAPACK gesvd routine "
200 "returned with error code ",
202 if (s[s.size() - 1] <
_svd_tol * s[0])
204 scheduled_for_deactivation[current_yf] =
true;
210 if (num_lin_dep == 0 && num_active <= 6)
217 unsigned int old_active_number = 0;
218 for (
unsigned surface = 0; surface <
_num_surfaces; ++surface)
221 if (scheduled_for_deactivation[old_active_number])
222 deactivated_due_to_ld[surface] =
true;
229 const std::vector<Real> & intnl_old,
230 const std::vector<Real> & intnl,
231 const std::vector<Real> & pm,
233 std::vector<Real> & f,
234 std::vector<RankTwoTensor> & r,
236 std::vector<Real> & ic,
237 const std::vector<bool> & active)
242 "Size of intnl_old is " << intnl_old.size()
243 <<
" which is incorrect in calculateConstraints");
245 "Size of intnl is " << intnl.size() <<
" which is incorrect in calculateConstraints");
247 "Size of pm is " << pm.size() <<
" which is incorrect in calculateConstraints");
249 "Size of active is " << active.size()
250 <<
" which is incorrect in calculateConstraints");
259 for (
unsigned surface = 0; surface <
_num_surfaces; ++surface)
261 epp += pm[surface] * r[ind++];
269 std::vector<unsigned int> active_surfaces;
270 std::vector<unsigned int>::iterator active_surface;
271 for (
unsigned model = 0; model <
_num_models; ++model)
274 if (active_surfaces.size() > 0)
277 ic.push_back(intnl[model] - intnl_old[model]);
278 for (active_surface = active_surfaces.begin(); active_surface != active_surfaces.end();
280 ic[ic.size() - 1] += pm[*active_surface] * h[ind++];
289 const std::vector<Real> & intnl_old,
290 const std::vector<Real> & intnl,
291 const std::vector<Real> & pm,
293 std::vector<Real> & rhs,
294 const std::vector<bool> & active,
296 std::vector<bool> & deactivated_due_to_ld)
301 "Size of intnl_old is " << intnl_old.size() <<
" which is incorrect in calculateRHS");
303 "Size of intnl is " << intnl.size() <<
" which is incorrect in calculateRHS");
305 "Size of pm is " << pm.size() <<
" which is incorrect in calculateRHS");
307 "Size of active is " << active.size() <<
" which is incorrect in calculateRHS");
311 std::vector<Real> ic;
313 std::vector<RankTwoTensor> r;
322 for (
unsigned surface = 0; surface <
_num_surfaces; ++surface)
323 active_not_deact[surface] = (active[surface] && !deactivated_due_to_ld[surface]);
325 unsigned num_active_f = 0;
326 for (
unsigned surface = 0; surface <
_num_surfaces; ++surface)
327 if (active_not_deact[surface])
330 unsigned num_active_ic = 0;
331 for (
unsigned model = 0; model <
_num_models; ++model)
335 unsigned int dim = 3;
336 unsigned int system_size = 6 + num_active_f + num_active_ic;
340 rhs.resize(system_size);
343 for (
unsigned i = 0; i < dim; ++i)
344 for (
unsigned j = 0; j <= i; ++j)
345 rhs[ind++] = -epp(i, j);
346 unsigned active_surface = 0;
347 for (
unsigned surface = 0; surface <
_num_surfaces; ++surface)
350 if (!deactivated_due_to_ld[surface])
351 rhs[ind++] = -f[active_surface];
354 unsigned active_model = 0;
355 for (
unsigned model = 0; model <
_num_models; ++model)
359 rhs[ind++] = -ic[active_model];
363 mooseAssert(ind == system_size,
"Incorrect filling of the rhs in calculateRHS");
368 const std::vector<Real> & intnl,
369 const std::vector<Real> & pm,
371 const std::vector<bool> & active,
372 const std::vector<bool> & deactivated_due_to_ld,
373 std::vector<std::vector<Real>> & jac)
378 "Size of intnl is " << intnl.size() <<
" which is incorrect in calculateJacobian");
380 "Size of pm is " << pm.size() <<
" which is incorrect in calculateJacobian");
382 "Size of active is " << active.size() <<
" which is incorrect in calculateJacobian");
384 "Size of deactivated_due_to_ld is " << deactivated_due_to_ld.size()
385 <<
" which is incorrect in calculateJacobian");
388 unsigned active_surface_ind = 0;
391 for (
unsigned surface = 0; surface <
_num_surfaces; ++surface)
392 active_surface[surface] = (active[surface] && !deactivated_due_to_ld[surface]);
393 unsigned num_active_surface = 0;
394 for (
unsigned surface = 0; surface <
_num_surfaces; ++surface)
395 if (active_surface[surface])
396 num_active_surface++;
398 std::vector<bool> active_model(
400 for (
unsigned model = 0; model <
_num_models; ++model)
403 unsigned num_active_model = 0;
404 for (
unsigned model = 0; model <
_num_models; ++model)
405 if (active_model[model])
409 std::vector<unsigned int> active_model_index(
_num_models);
410 for (
unsigned model = 0; model <
_num_models; ++model)
411 if (active_model[model])
412 active_model_index[model] = ind++;
414 active_model_index[model] =
417 std::vector<RankTwoTensor> df_dstress;
420 std::vector<Real> df_dintnl;
423 std::vector<RankTwoTensor> r;
426 std::vector<RankFourTensor> dr_dstress;
429 std::vector<RankTwoTensor> dr_dintnl;
435 std::vector<RankTwoTensor> dh_dstress;
438 std::vector<Real> dh_dintnl;
444 for (
unsigned surface = 0; surface <
_num_surfaces; ++surface)
446 depp_dstress += pm[surface] * dr_dstress[ind++];
447 depp_dstress += E_inv;
450 std::vector<RankTwoTensor> depp_dpm;
451 depp_dpm.resize(num_active_surface);
453 active_surface_ind = 0;
454 for (
unsigned surface = 0; surface <
_num_surfaces; ++surface)
458 if (active_surface[surface])
460 depp_dpm[active_surface_ind++] = r[ind];
466 std::vector<RankTwoTensor> depp_dintnl;
469 for (
unsigned surface = 0; surface <
_num_surfaces; ++surface)
474 if (active_model[model_num])
476 depp_dintnl[active_model_index[model_num]] += pm[surface] * dr_dintnl[ind];
486 std::vector<RankTwoTensor> dic_dstress;
489 for (
unsigned surface = 0; surface <
_num_surfaces; ++surface)
494 if (active_model[model_num])
496 dic_dstress[active_model_index[model_num]] += pm[surface] * dh_dstress[ind];
501 std::vector<std::vector<Real>> dic_dpm;
502 dic_dpm.resize(num_active_model);
504 active_surface_ind = 0;
505 for (
unsigned model = 0; model < num_active_model; ++model)
506 dic_dpm[model].assign(num_active_surface, 0);
507 for (
unsigned surface = 0; surface <
_num_surfaces; ++surface)
511 if (active_surface[surface])
516 dic_dpm[active_model_index[model_num]][active_surface_ind] = h[ind];
517 active_surface_ind++;
523 std::vector<std::vector<Real>> dic_dintnl;
524 dic_dintnl.resize(num_active_model);
525 for (
unsigned model = 0; model < num_active_model; ++model)
527 dic_dintnl[model].assign(num_active_model, 0);
528 dic_dintnl[model][model] = 1;
531 for (
unsigned surface = 0; surface <
_num_surfaces; ++surface)
536 if (active_model[model_num])
538 dic_dintnl[active_model_index[model_num]][active_model_index[model_num]] +=
539 pm[surface] * dh_dintnl[ind];
544 unsigned int dim = 3;
545 unsigned int system_size =
546 6 + num_active_surface + num_active_model;
547 jac.resize(system_size);
548 for (
unsigned i = 0; i < system_size; ++i)
549 jac[i].assign(system_size, 0);
551 unsigned int row_num = 0;
552 unsigned int col_num = 0;
553 for (
unsigned i = 0; i < dim; ++i)
554 for (
unsigned j = 0; j <= i; ++j)
556 for (
unsigned k = 0; k < dim; ++k)
557 for (
unsigned l = 0; l <= k; ++l)
558 jac[col_num][row_num++] =
559 depp_dstress(i, j, k, l) +
560 (k != l ? depp_dstress(i, j, l, k)
562 for (
unsigned surface = 0; surface < num_active_surface; ++surface)
563 jac[col_num][row_num++] = depp_dpm[surface](i, j);
564 for (
unsigned a = 0; a < num_active_model; ++a)
565 jac[col_num][row_num++] = depp_dintnl[a](i, j);
571 for (
unsigned surface = 0; surface <
_num_surfaces; ++surface)
572 if (active_surface[surface])
574 for (
unsigned k = 0; k < dim; ++k)
575 for (
unsigned l = 0; l <= k; ++l)
576 jac[col_num][row_num++] =
577 df_dstress[ind](k, l) +
578 (k != l ? df_dstress[ind](l, k)
580 for (
unsigned beta = 0; beta < num_active_surface; ++beta)
581 jac[col_num][row_num++] = 0;
582 for (
unsigned model = 0; model <
_num_models; ++model)
583 if (active_model[model])
586 jac[col_num][row_num++] = df_dintnl[ind];
588 jac[col_num][row_num++] = 0;
595 for (
unsigned a = 0; a < num_active_model; ++a)
597 for (
unsigned k = 0; k < dim; ++k)
598 for (
unsigned l = 0; l <= k; ++l)
599 jac[col_num][row_num++] =
600 dic_dstress[a](k, l) +
601 (k != l ? dic_dstress[a](l, k)
603 for (
unsigned alpha = 0; alpha < num_active_surface; ++alpha)
604 jac[col_num][row_num++] = dic_dpm[a][alpha];
605 for (
unsigned b = 0; b < num_active_model; ++b)
606 jac[col_num][row_num++] = dic_dintnl[a][b];
611 mooseAssert(col_num == system_size,
"Incorrect filling of cols in Jacobian");
616 const std::vector<Real> & intnl_old,
617 const std::vector<Real> & intnl,
618 const std::vector<Real> & pm,
622 std::vector<Real> & dpm,
623 std::vector<Real> & dintnl,
624 const std::vector<bool> & active,
625 std::vector<bool> & deactivated_due_to_ld)
628 std::vector<Real> rhs;
629 calculateRHS(stress, intnl_old, intnl, pm, delta_dp, rhs, active,
true, deactivated_due_to_ld);
631 std::vector<std::vector<Real>> jac;
635 int system_size = rhs.size();
637 std::vector<double> a(system_size * system_size);
640 for (
int col = 0; col < system_size; ++col)
641 for (
int row = 0; row < system_size; ++row)
642 a[ind++] = jac[row][col];
645 std::vector<int> ipiv(system_size);
647 LAPACKgesv_(&system_size, &nrhs, &a[0], &system_size, &ipiv[0], &rhs[0], &system_size, &info);
650 mooseError(
"In solving the linear system in a Newton-Raphson process, the PETSC LAPACK gsev "
651 "routine returned with error code ",
656 for (
unsigned surface = 0; surface <
_num_surfaces; ++surface)
657 active_not_deact[surface] = (active[surface] && !deactivated_due_to_ld[surface]);
659 unsigned int dim = 3;
662 for (
unsigned i = 0; i < dim; ++i)
663 for (
unsigned j = 0; j <= i; ++j)
664 dstress(i, j) = dstress(j, i) = rhs[ind++];
666 for (
unsigned surface = 0; surface <
_num_surfaces; ++surface)
667 if (active_not_deact[surface])
668 dpm[surface] = rhs[ind++];
670 for (
unsigned model = 0; model <
_num_models; ++model)
672 dintnl[model] = rhs[ind++];
674 mooseAssert(static_cast<int>(ind) == system_size,
675 "Incorrect extracting of changes from NR solution in nrStep");