39 static void ga_init_scalar(bgeot::multi_index &mi) { mi.resize(0); }
40 static void ga_init_vector(bgeot::multi_index &mi,
size_type N)
41 { mi.resize(1); mi[0] = N; }
43 { mi.resize(2); mi[0] = M; mi[1] = N; }
44 static void ga_init_square_matrix(bgeot::multi_index &mi,
size_type N)
45 { mi.resize(2); mi[0] = mi[1] = N; }
48 bool expm(
const base_matrix &a_, base_matrix &aexp, scalar_type tol=1e-15) {
54 frexp(gmm::mat_norminf(a), &e);
55 e = std::max(0, std::min(1023, e));
56 gmm::scale(a, pow(scalar_type(2),-scalar_type(e)));
58 base_matrix atmp(a), an(a);
60 gmm::add(gmm::identity_matrix(), aexp);
64 factn /= scalar_type(n);
67 gmm::scale(atmp, factn);
69 if (gmm::mat_euclidean_norm(atmp) < tol) {
75 for (
int i=0; i < e; ++i) {
82 bool expm_deriv(
const base_matrix &a_, base_tensor &daexp,
83 base_matrix *paexp=NULL, scalar_type tol=1e-15) {
92 frexp(gmm::mat_norminf(a), &e);
93 e = std::max(0, std::min(1023, e));
94 scalar_type scale = pow(scalar_type(2),-scalar_type(e));
97 base_vector factnn(itmax);
98 base_matrix atmp(a), an(a), aexp(a);
99 base_tensor ann(bgeot::multi_index(N,N,itmax));
100 gmm::add(gmm::identity_matrix(), aexp);
102 std::copy(atmp.begin(), atmp.end(), ann.begin());
104 std::copy(a.begin(), a.end(), ann.begin()+N2);
107 for (n=2; n < itmax; ++n) {
108 factnn[n] = factnn[n-1]/scalar_type(n);
111 std::copy(an.begin(), an.end(), ann.begin()+n*N2);
112 gmm::scale(atmp, factnn[n]);
114 if (gmm::mat_euclidean_norm(atmp) < tol) {
124 gmm::scale(factnn, scale);
125 for (--n; n >= 1; --n) {
126 scalar_type factn = factnn[n];
132 daexp(i,j,k,l) += factn*ann(i,k,m-1)*ann(l,j,n-m);
136 base_matrix atmp1(a), atmp2(a);
137 for (
int i=0; i < e; ++i) {
140 std::copy(&daexp(0,0,k,l), &daexp(0,0,k,l)+N*N, atmp.begin());
144 std::copy(atmp.begin(), atmp.end(), &daexp(0,0,k,l));
157 bool logm_deriv(
const base_matrix &a, base_tensor &dalog,
158 base_matrix *palog=NULL) {
161 base_matrix a1(a), alog1(a), alog(a);
163 scalar_type eps(1e-8);
171 dalog(i,j,k,l) = (alog1(i,j) - alog(i,j))/eps;
179 struct matrix_exponential_operator :
public ga_nonlinear_operator {
180 bool result_size(
const arg_list &args, bgeot::multi_index &sizes)
const {
181 if (args.size() != 1 || args[0]->sizes().size() != 2
182 || args[0]->sizes()[0] != args[0]->sizes()[1])
return false;
183 ga_init_matrix(sizes, args[0]->sizes()[0], args[0]->sizes()[1]);
188 void value(
const arg_list &args, base_tensor &result)
const {
190 base_matrix inpmat(N,N), outmat(N,N);
191 gmm::copy(args[0]->as_vector(), inpmat.as_vector());
192 bool info = expm(inpmat, outmat);
193 GMM_ASSERT1(info,
"Matrix exponential calculation "
194 "failed to converge");
195 gmm::copy(outmat.as_vector(), result.as_vector());
199 void derivative(
const arg_list &args,
size_type ,
200 base_tensor &result)
const {
202 base_matrix inpmat(N,N);
203 gmm::copy(args[0]->as_vector(), inpmat.as_vector());
204 bool info = expm_deriv(inpmat, result);
205 GMM_ASSERT1(info,
"Matrix exponential derivative calculation "
206 "failed to converge");
211 base_tensor &)
const {
212 GMM_ASSERT1(
false,
"Sorry, second derivative not implemented");
218 struct matrix_logarithm_operator :
public ga_nonlinear_operator {
219 bool result_size(
const arg_list &args, bgeot::multi_index &sizes)
const {
220 if (args.size() != 1 || args[0]->sizes().size() != 2
221 || args[0]->sizes()[0] != args[0]->sizes()[1])
return false;
222 ga_init_matrix(sizes, args[0]->sizes()[0], args[0]->sizes()[1]);
227 void value(
const arg_list &args, base_tensor &result)
const {
229 base_matrix inpmat(N,N), outmat(N,N);
230 gmm::copy(args[0]->as_vector(), inpmat.as_vector());
232 gmm::copy(outmat.as_vector(), result.as_vector());
236 void derivative(
const arg_list &args,
size_type ,
237 base_tensor &result)
const {
239 base_matrix inpmat(N,N), outmat(N,N), tmpmat(N*N,N*N);
240 gmm::copy(args[0]->as_vector(), inpmat.as_vector());
242 bool info = expm_deriv(outmat, result);
244 gmm::copy(result.as_vector(), tmpmat.as_vector());
246 if (det <= 0)
gmm::copy(gmm::identity_matrix(), tmpmat);
247 gmm::copy(tmpmat.as_vector(), result.as_vector());
249 GMM_ASSERT1(info,
"Matrix logarithm derivative calculation "
250 "failed to converge");
255 base_tensor &)
const {
256 GMM_ASSERT1(
false,
"Sorry, second derivative not implemented");
262 struct normalized_operator :
public ga_nonlinear_operator {
263 bool result_size(
const arg_list &args, bgeot::multi_index &sizes)
const {
264 if (args.size() != 1 || args[0]->sizes().size() > 2
265 || args[0]->sizes().size() < 1)
return false;
266 if (args[0]->sizes().size() == 1)
267 ga_init_vector(sizes, args[0]->sizes()[0]);
269 ga_init_matrix(sizes, args[0]->sizes()[0], args[0]->sizes()[1]);
274 void value(
const arg_list &args, base_tensor &result)
const {
276 const base_tensor &t = *args[0];
277 scalar_type eps = 1E-25;
278 scalar_type no = ::sqrt(gmm::vect_norm2_sqr(t.as_vector())+gmm::sqr(eps));
279 gmm::copy(gmm::scaled(t.as_vector(), scalar_type(1)/no),
286 gmm::copy(gmm::scaled(args[0]->as_vector(), scalar_type(1)/no),
292 void derivative(
const arg_list &args,
size_type,
293 base_tensor &result)
const {
294 const base_tensor &t = *args[0];
297 scalar_type eps = 1E-25;
298 scalar_type no = ::sqrt(gmm::vect_norm2_sqr(t.as_vector())+gmm::sqr(eps));
299 scalar_type no3 = no*no*no;
303 result[i*N+i] += scalar_type(1)/no;
305 result[j*N+i] -= t[i]*t[j] / no3;
312 scalar_type no3 = no*no*no;
314 result[i*N+i] += scalar_type(1)/no;
316 result[j*N+i] -= t[i]*t[j] / no3;
324 base_tensor &)
const {
325 GMM_ASSERT1(
false,
"Sorry, second derivative not implemented");
331 struct Ball_projection_operator :
public ga_nonlinear_operator {
332 bool result_size(
const arg_list &args, bgeot::multi_index &sizes)
const {
333 if (args.size() != 2 || args[0]->sizes().size() > 2
334 || (args[0]->sizes().size() < 1 && args[0]->size() != 1)
335 || args[1]->size() != 1)
return false;
336 if (args[0]->sizes().size() < 1)
337 ga_init_scalar(sizes);
338 else if (args[0]->sizes().size() == 1)
339 ga_init_vector(sizes, args[0]->sizes()[0]);
341 ga_init_matrix(sizes, args[0]->sizes()[0], args[0]->sizes()[1]);
346 void value(
const arg_list &args, base_tensor &result)
const {
347 const base_tensor &t = *args[0];
348 scalar_type r = (*args[1])[0];
351 gmm::copy(gmm::scaled(t.as_vector(), r/no), result.as_vector());
353 gmm::copy(t.as_vector(), result.as_vector());
357 void derivative(
const arg_list &args,
size_type n,
358 base_tensor &result)
const {
359 const base_tensor &t = *args[0];
361 scalar_type r = (*args[1])[0];
372 result[i*N+i] += scalar_type(1);
375 result[i*N+i] += r/no;
377 result[j*N+i] -= t[i]*t[j]*rno3;
383 if (r > 0 && no > r) {
388 default : GMM_ASSERT1(
false,
"Wrong derivative number");
394 base_tensor &)
const {
395 GMM_ASSERT1(
false,
"Sorry, second derivative not implemented");
401 struct normalized_reg_operator :
public ga_nonlinear_operator {
402 bool result_size(
const arg_list &args, bgeot::multi_index &sizes)
const {
403 if (args.size() != 2 || args[0]->sizes().size() > 2
404 || args[0]->sizes().size() < 1 || args[1]->size() != 1)
return false;
405 if (args[0]->sizes().size() == 1)
406 ga_init_vector(sizes, args[0]->sizes()[0]);
408 ga_init_matrix(sizes, args[0]->sizes()[0], args[0]->sizes()[1]);
413 void value(
const arg_list &args, base_tensor &result)
const {
414 const base_tensor &t = *args[0];
415 scalar_type eps = (*args[1])[0];
416 scalar_type no = ::sqrt(gmm::vect_norm2_sqr(t.as_vector())+gmm::sqr(eps));
417 gmm::copy(gmm::scaled(t.as_vector(), scalar_type(1)/no),
423 void derivative(
const arg_list &args,
size_type nder,
424 base_tensor &result)
const {
425 const base_tensor &t = *args[0];
426 scalar_type eps = (*args[1])[0];
429 scalar_type no = ::sqrt(gmm::vect_norm2_sqr(t.as_vector())+gmm::sqr(eps));
430 scalar_type no3 = no*no*no;
436 result[i*N+i] += scalar_type(1)/no;
438 result[j*N+i] -= t[i]*t[j] / no3;
443 gmm::copy(gmm::scaled(t.as_vector(), -scalar_type(eps)/no3),
451 base_tensor &)
const {
452 GMM_ASSERT1(
false,
"Sorry, second derivative not implemented");
462 struct Von_Mises_projection_operator :
public ga_nonlinear_operator {
463 bool result_size(
const arg_list &args, bgeot::multi_index &sizes)
const {
464 if (args.size() != 2 || args[0]->sizes().size() > 2
465 || args[1]->size() != 1)
return false;
466 size_type N = (args[0]->sizes().size() == 2) ? args[0]->sizes()[0] : 1;
467 if (args[0]->sizes().size() == 2 && args[0]->sizes()[1] != N)
return false;
468 if (args[0]->sizes().size() != 2 && args[0]->size() != 1)
return false;
469 if (N > 1) ga_init_square_matrix(sizes, N);
else ga_init_scalar(sizes);
474 void value(
const arg_list &args, base_tensor &result)
const {
475 size_type N = (args[0]->sizes().size() == 2) ? args[0]->sizes()[0] : 1;
476 base_matrix tau(N, N), tau_D(N, N);
477 gmm::copy(args[0]->as_vector(), tau.as_vector());
478 scalar_type s = (*(args[1]))[0];
482 for (
size_type i = 0; i < N; ++i) tau_D(i,i) -= tau_m;
486 if (norm_tau_D > s) gmm::scale(tau_D, s / norm_tau_D);
488 for (
size_type i = 0; i < N; ++i) tau_D(i,i) += tau_m;
490 gmm::copy(tau_D.as_vector(), result.as_vector());
494 void derivative(
const arg_list &args,
size_type nder,
495 base_tensor &result)
const {
496 size_type N = (args[0]->sizes().size() == 2) ? args[0]->sizes()[0] : 1;
497 base_matrix tau(N, N), tau_D(N, N);
498 gmm::copy(args[0]->as_vector(), tau.as_vector());
499 scalar_type s = (*(args[1]))[0];
502 for (
size_type i = 0; i < N; ++i) tau_D(i,i) -= tau_m;
505 if (norm_tau_D != scalar_type(0))
506 gmm::scale(tau_D, scalar_type(1)/norm_tau_D);
510 if (norm_tau_D <= s) {
514 result(i,j,i,j) = scalar_type(1);
521 = s * (-tau_D(i,j) * tau_D(m,n)
522 + ((i == m && j == n) ? scalar_type(1) : scalar_type(0))
523 - ((i == j && m == n) ? scalar_type(1)/scalar_type(N)
524 : scalar_type(0))) / norm_tau_D;
527 result(i,i,j,j) += scalar_type(1)/scalar_type(N);
534 gmm::copy(tau_D.as_vector(), result.as_vector());
541 base_tensor &)
const {
542 GMM_ASSERT1(
false,
"Sorry, second derivative not implemented");
546 static bool init_predef_operators(
void) {
548 ga_predef_operator_tab &PREDEF_OPERATORS
551 PREDEF_OPERATORS.add_method(
"Expm",
552 std::make_shared<matrix_exponential_operator>());
553 PREDEF_OPERATORS.add_method(
"Logm",
554 std::make_shared<matrix_logarithm_operator>());
555 PREDEF_OPERATORS.add_method(
"Normalized",
556 std::make_shared<normalized_operator>());
557 PREDEF_OPERATORS.add_method(
"Normalized_reg",
558 std::make_shared<normalized_reg_operator>());
559 PREDEF_OPERATORS.add_method(
"Ball_projection",
560 std::make_shared<Ball_projection_operator>());
561 PREDEF_OPERATORS.add_method(
"Von_Mises_projection",
562 std::make_shared<Von_Mises_projection_operator>());
567 bool predef_operators_plasticity_initialized
568 = init_predef_operators();
580 void build_isotropic_perfect_elastoplasticity_expressions_mult
581 (model &md,
const std::string &dispname,
const std::string &xi,
582 const std::string &Previous_Ep,
const std::string &lambda,
583 const std::string &mu,
const std::string &sigma_y,
584 const std::string &theta,
const std::string &dt,
585 std::string &sigma_np1, std::string &Epnp1, std::string &compcond,
586 std::string &sigma_after, std::string &von_mises) {
588 const mesh_fem *mfu = md.pmesh_fem_of_variable(dispname);
590 GMM_ASSERT1(mfu && mfu->get_qdim() == N,
"The small strain "
591 "elastoplasticity brick can only be applied on a fem "
592 "variable of the same dimension as the mesh");
594 GMM_ASSERT1(!(md.is_data(xi)) && md.pmesh_fem_of_variable(xi),
595 "The provided name '" << xi <<
"' for the plastic multiplier, "
596 "should be defined as a fem variable");
598 GMM_ASSERT1(md.is_data(Previous_Ep) &&
599 (md.pim_data_of_variable(Previous_Ep) ||
600 md.pmesh_fem_of_variable(Previous_Ep)),
601 "The provided name '" << Previous_Ep <<
"' for the plastic "
602 "strain tensor at the previous timestep, should be defined "
603 "either as fem or as im data");
605 bgeot::multi_index Ep_size(N, N);
606 GMM_ASSERT1((md.pim_data_of_variable(Previous_Ep) &&
607 md.pim_data_of_variable(Previous_Ep)->tensor_size() == Ep_size)
609 (md.pmesh_fem_of_variable(Previous_Ep) &&
610 md.pmesh_fem_of_variable(Previous_Ep)->get_qdims() == Ep_size),
611 "Wrong size of " << Previous_Ep);
613 std::map<std::string, std::string> dict;
614 dict[
"Grad_u"] =
"Grad_"+dispname; dict[
"xi"] = xi;
615 dict[
"Previous_xi"] =
"Previous_"+xi;
616 dict[
"Grad_Previous_u"] =
"Grad_Previous_"+dispname;
617 dict[
"theta"] = theta; dict[
"dt"] = dt; dict[
"Epn"] = Previous_Ep;
618 dict[
"lambda"] = lambda; dict[
"mu"] = mu; dict[
"sigma_y"] = sigma_y;
620 dict[
"Enp1"] = ga_substitute(
"Sym(Grad_u)", dict);
621 dict[
"En"] = ga_substitute(
"Sym(Grad_Previous_u)", dict);
622 dict[
"zetan"] = ga_substitute
623 (
"((Epn)+(1-(theta))*(2*(mu)*(dt)*(Previous_xi))*(Deviator(En)-(Epn)))",
625 Epnp1 = ga_substitute
626 (
"((zetan)+(1-1/(1+(theta)*2*(mu)*(dt)*(xi)))*(Deviator(Enp1)-(zetan)))",
628 dict[
"Epnp1"] = Epnp1;
629 sigma_np1 = ga_substitute
630 (
"((lambda)*Trace(Enp1)*Id(meshdim)+2*(mu)*((Enp1)-(Epnp1)))", dict);
631 dict[
"fbound"] = ga_substitute
632 (
"(2*(mu)*Norm(Deviator(Enp1)-(Epnp1))-sqrt(2/3)*(sigma_y))", dict);
633 dict[
"sigma_after"] = sigma_after = ga_substitute
634 (
"((lambda)*Trace(Enp1)*Id(meshdim)+2*(mu)*((Enp1)-(Epn)))", dict);
635 compcond = ga_substitute
636 (
"((mu)*xi-pos_part((mu)*xi+100*(fbound)/(mu)))", dict);
637 von_mises = ga_substitute
638 (
"sqrt(3/2)*Norm(Deviator(sigma_after))", dict);
644 void build_isotropic_perfect_elastoplasticity_expressions_no_mult
645 (model &md,
const std::string &dispname,
const std::string &xi,
646 const std::string &Previous_Ep,
const std::string &lambda,
647 const std::string &mu,
const std::string &sigma_y,
648 const std::string &theta,
const std::string &dt,
649 std::string &sigma_np1, std::string &Epnp1, std::string &xi_np1,
650 std::string &sigma_after, std::string &von_mises) {
652 const mesh_fem *mfu = md.pmesh_fem_of_variable(dispname);
654 GMM_ASSERT1(mfu && mfu->get_qdim() == N,
"The small strain "
655 "elastoplasticity brick can only be applied on a fem "
656 "variable of the same dimension as the mesh");
658 GMM_ASSERT1(md.is_data(xi) &&
659 (md.pim_data_of_variable(xi) ||
660 md.pmesh_fem_of_variable(xi)),
661 "The provided name '" << xi <<
"' for the plastic multiplier, "
662 "should be defined either as fem data or as im data");
664 GMM_ASSERT1(md.is_data(Previous_Ep) &&
665 (md.pim_data_of_variable(Previous_Ep) ||
666 md.pmesh_fem_of_variable(Previous_Ep)),
667 "The provided name '" << Previous_Ep <<
"' for the plastic "
668 "strain tensor at the previous timestep, should be defined "
669 "either as fem or as im data");
671 bgeot::multi_index Ep_size(N, N);
672 GMM_ASSERT1((md.pim_data_of_variable(Previous_Ep) &&
673 md.pim_data_of_variable(Previous_Ep)->tensor_size() == Ep_size)
675 (md.pmesh_fem_of_variable(Previous_Ep) &&
676 md.pmesh_fem_of_variable(Previous_Ep)->get_qdims() == Ep_size),
677 "Wrong size of " << Previous_Ep);
679 std::map<std::string, std::string> dict;
680 dict[
"Grad_u"] =
"Grad_"+dispname; dict[
"xi"] = xi;
681 dict[
"Previous_xi"] =
"Previous_"+xi;
682 dict[
"Grad_Previous_u"] =
"Grad_Previous_"+dispname;
683 dict[
"theta"] = theta; dict[
"dt"] = dt; dict[
"Epn"] = Previous_Ep;
684 dict[
"lambda"] = lambda; dict[
"mu"] = mu; dict[
"sigma_y"] = sigma_y;
686 dict[
"Enp1"] = ga_substitute(
"Sym(Grad_u)", dict);
687 dict[
"En"] = ga_substitute(
"Sym(Grad_Previous_u)", dict) ;
690 dict[
"zetan"] = ga_substitute
691 (
"(Epn)+(1-(theta))*(2*(mu)*(dt)*(Previous_xi))*(Deviator(En)-(Epn))",
693 dict[
"B"] = ga_substitute(
"Deviator(Enp1)-(zetan)", dict);
694 Epnp1 = ga_substitute
695 (
"(zetan)+pos_part(1-sqrt(2/3)*(sigma_y)/(2*(mu)*Norm(B)+1e-40))*(B)",
697 dict[
"Epnp1"] = Epnp1;
699 sigma_np1 = ga_substitute
700 (
"(lambda)*Trace(Enp1)*Id(meshdim)+2*(mu)*((Enp1)-(Epnp1))", dict);
701 dict[
"sigma_after"] = sigma_after = ga_substitute
702 (
"(lambda)*Trace(Enp1)*Id(meshdim)+2*(mu)*((Enp1)-(Epn))", dict);
703 xi_np1 = ga_substitute
704 (
"pos_part(sqrt(3/2)*Norm(B)/(sigma_y)-1/(2*(mu)))/((theta)*(dt))", dict);
705 von_mises = ga_substitute
706 (
"sqrt(3/2)*Norm(Deviator(sigma_after))", dict);
712 void build_isotropic_perfect_elastoplasticity_expressions_mult_ps
713 (model &md,
const std::string &dispname,
const std::string &xi,
714 const std::string &Previous_Ep,
const std::string &lambda,
715 const std::string &mu,
const std::string &sigma_y,
716 const std::string &theta,
const std::string &dt,
717 std::string &sigma_np1, std::string &Epnp1, std::string &compcond,
718 std::string &sigma_after, std::string &von_mises) {
720 const mesh_fem *mfu = md.pmesh_fem_of_variable(dispname);
722 GMM_ASSERT1(N == 2,
"This plastic law is restricted to 2D");
724 GMM_ASSERT1(mfu && mfu->get_qdim() == N,
"The small strain "
725 "elastoplasticity brick can only be applied on a fem "
726 "variable of the same dimension as the mesh");
728 GMM_ASSERT1(!(md.is_data(xi)) && md.pmesh_fem_of_variable(xi),
729 "The provided name '" << xi <<
"' for the plastic multiplier, "
730 "should be defined as a fem variable");
732 GMM_ASSERT1(md.is_data(Previous_Ep) &&
733 (md.pim_data_of_variable(Previous_Ep) ||
734 md.pmesh_fem_of_variable(Previous_Ep)),
735 "The provided name '" << Previous_Ep <<
"' for the plastic "
736 "strain tensor at the previous timestep, should be defined "
737 "either as fem or as im data");
739 bgeot::multi_index Ep_size(N, N);
740 GMM_ASSERT1((md.pim_data_of_variable(Previous_Ep) &&
741 md.pim_data_of_variable(Previous_Ep)->tensor_size() == Ep_size)
743 (md.pmesh_fem_of_variable(Previous_Ep) &&
744 md.pmesh_fem_of_variable(Previous_Ep)->get_qdims() == Ep_size),
745 "Wrong size of " << Previous_Ep);
747 std::map<std::string, std::string> dict;
748 dict[
"Grad_u"] =
"Grad_"+dispname; dict[
"xi"] = xi;
749 dict[
"Previous_xi"] =
"Previous_"+xi;
750 dict[
"Grad_Previous_u"] =
"Grad_Previous_"+dispname;
751 dict[
"theta"] = theta; dict[
"dt"] = dt; dict[
"Epn"] = Previous_Ep;
752 dict[
"lambda"] = lambda; dict[
"mu"] = mu; dict[
"sigma_y"] = sigma_y;
754 dict[
"Enp1"] = ga_substitute(
"Sym(Grad_u)", dict);
755 dict[
"En"] = ga_substitute(
"Sym(Grad_Previous_u)", dict);
756 dict[
"Dev_En"]= ga_substitute(
"(En-(Trace(En)/3)*Id(meshdim))", dict);
757 dict[
"Dev_Enp1"]= ga_substitute(
"(Enp1-(Trace(Enp1)/3)*Id(meshdim))", dict);
758 dict[
"zetan"] = ga_substitute
759 (
"((Epn)+(1-(theta))*(2*(mu)*(dt)*(Previous_xi))*((Dev_En)-(Epn)))",
761 Epnp1 = ga_substitute
762 (
"((zetan)+(1-1/(1+(theta)*2*(mu)*(dt)*(xi)))*((Dev_Enp1)-(zetan)))",
764 dict[
"Epnp1"] = Epnp1;
765 sigma_np1 = ga_substitute
766 (
"((lambda)*Trace(Enp1)*Id(meshdim)+2*(mu)*((Enp1)-(Epnp1)))", dict);
767 dict[
"fbound"] = ga_substitute
768 (
"(2*(mu)*sqrt(Norm_sqr(Dev_Enp1-(Epnp1))"
769 "+sqr(Trace(Enp1)/3-Trace(Epnp1)))-sqrt(2/3)*(sigma_y))", dict);
771 sigma_after = ga_substitute
772 (
"((lambda)*Trace(Enp1)*Id(meshdim)+2*(mu)*((Enp1)-(Epn)))", dict);
773 compcond = ga_substitute
774 (
"((mu)*xi-pos_part((mu)*xi+100*(fbound)/(mu)))", dict);
775 von_mises = ga_substitute
776 (
"sqrt(3/2)*sqrt(Norm_sqr((2*(mu))*(Dev_En)-(2*(mu))*(Epn))"
777 "+sqr(2*(mu)*Trace(En)/3-(2*(mu))*Trace(Epn)))", dict);
784 void build_isotropic_perfect_elastoplasticity_expressions_no_mult_ps
785 (model &md,
const std::string &dispname,
const std::string &xi,
786 const std::string &Previous_Ep,
const std::string &lambda,
787 const std::string &mu,
const std::string &sigma_y,
788 const std::string &theta,
const std::string &dt,
789 std::string &sigma_np1, std::string &Epnp1,
790 std::string &xi_np1, std::string &sigma_after, std::string &von_mises) {
792 const mesh_fem *mfu = md.pmesh_fem_of_variable(dispname);
794 GMM_ASSERT1(N == 2,
"This plastic law is restricted to 2D");
796 GMM_ASSERT1(mfu && mfu->get_qdim() == N,
"The small strain "
797 "elastoplasticity brick can only be applied on a fem "
798 "variable of the same dimension as the mesh");
800 GMM_ASSERT1(md.is_data(xi) &&
801 (md.pim_data_of_variable(xi) ||
802 md.pmesh_fem_of_variable(xi)),
803 "The provided name '" << xi <<
"' for the plastic multiplier, "
804 "should be defined either as fem data or as im data");
806 GMM_ASSERT1(md.is_data(Previous_Ep) &&
807 (md.pim_data_of_variable(Previous_Ep) ||
808 md.pmesh_fem_of_variable(Previous_Ep)),
809 "The provided name '" << Previous_Ep <<
"' for the plastic "
810 "strain tensor at the previous timestep, should be defined "
811 "either as fem or as im data");
813 bgeot::multi_index Ep_size(N, N);
814 GMM_ASSERT1((md.pim_data_of_variable(Previous_Ep) &&
815 md.pim_data_of_variable(Previous_Ep)->tensor_size() == Ep_size)
817 (md.pmesh_fem_of_variable(Previous_Ep) &&
818 md.pmesh_fem_of_variable(Previous_Ep)->get_qdims() == Ep_size),
819 "Wrong size of " << Previous_Ep);
821 std::map<std::string, std::string> dict;
822 dict[
"Grad_u"] =
"Grad_"+dispname; dict[
"xi"] = xi;
823 dict[
"Previous_xi"] =
"Previous_"+xi;
824 dict[
"Grad_Previous_u"] =
"Grad_Previous_"+dispname;
825 dict[
"theta"] = theta; dict[
"dt"] = dt; dict[
"Epn"] = Previous_Ep;
826 dict[
"lambda"] = lambda; dict[
"mu"] = mu; dict[
"sigma_y"] = sigma_y;
828 dict[
"Enp1"] = ga_substitute(
"Sym(Grad_u)", dict);
829 dict[
"En"] = ga_substitute(
"Sym(Grad_Previous_u)", dict) ;
830 dict[
"Dev_En"]= ga_substitute(
"(En-(Trace(En)/3)*Id(meshdim))", dict);
831 dict[
"Dev_Enp1"]= ga_substitute(
"(Enp1-(Trace(Enp1)/3)*Id(meshdim))", dict);
832 dict[
"zetan"] = ga_substitute
833 (
"((Epn)+(1-(theta))*(2*(mu)*(dt)*(Previous_xi))*(Dev_En-(Epn)))",
835 dict[
"B"] = ga_substitute(
"(Dev_Enp1)-(zetan)", dict);
836 Epnp1 = ga_substitute
837 (
"(zetan)+pos_part(1-sqrt(2/3)*(sigma_y)/(2*(mu)*(sqrt(Norm_sqr(B)+"
838 "sqr(Trace(Enp1)/3-Trace(zetan))))+1e-25))*(B)", dict);
839 dict[
"Epnp1"] = Epnp1;
841 sigma_np1 = ga_substitute
842 (
"(lambda)*Trace(Enp1)*Id(meshdim)+2*(mu)*((Enp1)-(Epnp1))", dict);
843 sigma_after = ga_substitute
844 (
"(lambda)*Trace(Enp1)*Id(meshdim)+2*(mu)*((Enp1)-(Epn))", dict);
845 xi_np1 = ga_substitute
846 (
"pos_part(sqrt(3/2)*Norm(B)/(sigma_y)-1/(2*(mu)))/((theta)*(dt))", dict);
847 von_mises = ga_substitute
848 (
"sqrt(3/2)*sqrt(Norm_sqr((2*(mu))*(Dev_En)-(2*(mu))*(Epn))"
849 "+sqr(2*(mu)*Trace(En)/3-(2*(mu))*Trace(Epn)))", dict);
855 void build_isotropic_perfect_elastoplasticity_expressions_hard_mult
856 (model &md,
const std::string &dispname,
const std::string &xi,
857 const std::string &Previous_Ep,
const std::string &alpha,
858 const std::string &lambda,
const std::string &mu,
859 const std::string &sigma_y,
const std::string &Hk,
const std::string &Hi,
860 const std::string &theta,
const std::string &dt,
861 std::string &sigma_np1, std::string &Epnp1, std::string &compcond,
862 std::string &sigma_after, std::string &von_mises, std::string &alphanp1) {
864 const mesh_fem *mfu = md.pmesh_fem_of_variable(dispname);
866 GMM_ASSERT1(mfu && mfu->get_qdim() == N,
"The small strain "
867 "elastoplasticity brick can only be applied on a fem "
868 "variable of the same dimension as the mesh");
870 GMM_ASSERT1(!(md.is_data(xi)) && md.pmesh_fem_of_variable(xi),
871 "The provided name '" << xi <<
"' for the plastic multiplier, "
872 "should be defined as a fem variable");
874 GMM_ASSERT1(md.is_data(Previous_Ep) &&
875 (md.pim_data_of_variable(Previous_Ep) ||
876 md.pmesh_fem_of_variable(Previous_Ep)),
877 "The provided name '" << Previous_Ep <<
"' for the plastic "
878 "strain tensor at the previous timestep, should be defined "
879 "either as fem or as im data");
881 bgeot::multi_index Ep_size(N, N);
882 GMM_ASSERT1((md.pim_data_of_variable(Previous_Ep) &&
883 md.pim_data_of_variable(Previous_Ep)->tensor_size() == Ep_size)
885 (md.pmesh_fem_of_variable(Previous_Ep) &&
886 md.pmesh_fem_of_variable(Previous_Ep)->get_qdims() == Ep_size),
887 "Wrong size of " << Previous_Ep);
889 std::map<std::string, std::string> dict;
890 dict[
"Hk"] = Hk; dict[
"Hi"] = Hi; dict[
"alphan"] =
alpha;
891 dict[
"Grad_u"] =
"Grad_"+dispname; dict[
"xi"] = xi;
892 dict[
"Previous_xi"] =
"Previous_"+xi;
893 dict[
"Grad_Previous_u"] =
"Grad_Previous_"+dispname;
894 dict[
"theta"] = theta; dict[
"dt"] = dt; dict[
"Epn"] = Previous_Ep;
895 dict[
"lambda"] = lambda; dict[
"mu"] = mu; dict[
"sigma_y"] = sigma_y;
897 dict[
"Enp1"] = ga_substitute(
"Sym(Grad_u)", dict);
898 dict[
"En"] = ga_substitute(
"Sym(Grad_Previous_u)", dict);
899 dict[
"zetan"] = ga_substitute
900 (
"((Epn)+(1-(theta))*((dt)*(Previous_xi))*((2*(mu))*Deviator(En)"
901 "-(2*(mu)+2/3*(Hk))*(Epn)))", dict);
902 dict[
"etan"] = ga_substitute
903 (
"((alphan)+sqrt(2/3)*(1-(theta))*((dt)*(Previous_xi))*"
904 "Norm((2*(mu))*Deviator(En)-(2*(mu)+2/3*(Hk))*(Epn)))", dict);
905 dict[
"B"] = ga_substitute
906 (
"((2*(mu))*Deviator(Enp1)-(2*(mu)+2/3*(Hk))*(zetan))", dict);
907 dict[
"beta"] = ga_substitute
908 (
"((theta)*(dt)*(xi)/(1+(2*(mu)+2/3*(Hk))*(theta)*(dt)*(xi)))", dict);
909 dict[
"Epnp1"] = Epnp1 = ga_substitute(
"((zetan)+(beta)*(B))", dict);
910 alphanp1 = ga_substitute(
"((etan)+sqrt(2/3)*(beta)*Norm(B))", dict);
911 dict[
"alphanp1"] = alphanp1;
912 sigma_np1 = ga_substitute
913 (
"((lambda)*Trace(Enp1)*Id(meshdim)+2*(mu)*((Enp1)-(Epnp1)))", dict);
914 dict[
"fbound"] = ga_substitute
915 (
"(Norm((2*(mu))*Deviator(Enp1)-(2*(mu)+2/3*(Hk))*(Epnp1))"
916 "-sqrt(2/3)*(sigma_y+(Hi)*(alphanp1)))", dict);
917 dict[
"sigma_after"] = sigma_after = ga_substitute
918 (
"((lambda)*Trace(Enp1)*Id(meshdim)+2*(mu)*((Enp1)-(Epn)))", dict);
919 compcond = ga_substitute
920 (
"((mu)*xi-pos_part((mu)*xi+100*(fbound)/(mu)))", dict);
921 von_mises = ga_substitute
922 (
"sqrt(3/2)*Norm(Deviator(sigma_after))", dict);
928 void build_isotropic_perfect_elastoplasticity_expressions_hard_no_mult
929 (model &md,
const std::string &dispname,
const std::string &xi,
930 const std::string &Previous_Ep,
const std::string &alpha,
931 const std::string &lambda,
const std::string &mu,
932 const std::string &sigma_y,
const std::string &Hk,
const std::string &Hi,
933 const std::string &theta,
const std::string &dt,
934 std::string &sigma_np1, std::string &Epnp1, std::string &xi_np1,
935 std::string &sigma_after, std::string &von_mises, std::string &alphanp1) {
937 const mesh_fem *mfu = md.pmesh_fem_of_variable(dispname);
939 GMM_ASSERT1(mfu && mfu->get_qdim() == N,
"The small strain "
940 "elastoplasticity brick can only be applied on a fem "
941 "variable of the same dimension as the mesh");
943 GMM_ASSERT1(md.is_data(xi) &&
944 (md.pim_data_of_variable(xi) ||
945 md.pmesh_fem_of_variable(xi)),
946 "The provided name '" << xi <<
"' for the plastic multiplier, "
947 "should be defined either as fem data or as im data");
949 GMM_ASSERT1(md.is_data(Previous_Ep) &&
950 (md.pim_data_of_variable(Previous_Ep) ||
951 md.pmesh_fem_of_variable(Previous_Ep)),
952 "The provided name '" << Previous_Ep <<
"' for the plastic "
953 "strain tensor at the previous timestep, should be defined "
954 "either as fem or as im data");
956 bgeot::multi_index Ep_size(N, N);
957 GMM_ASSERT1((md.pim_data_of_variable(Previous_Ep) &&
958 md.pim_data_of_variable(Previous_Ep)->tensor_size() == Ep_size)
960 (md.pmesh_fem_of_variable(Previous_Ep) &&
961 md.pmesh_fem_of_variable(Previous_Ep)->get_qdims() == Ep_size),
962 "Wrong size of " << Previous_Ep);
964 std::map<std::string, std::string> dict;
965 dict[
"Hk"] = Hk; dict[
"Hi"] = Hi; dict[
"alphan"] =
alpha;
966 dict[
"Grad_u"] =
"Grad_"+dispname; dict[
"xi"] = xi;
967 dict[
"Previous_xi"] =
"Previous_"+xi;
968 dict[
"Grad_Previous_u"] =
"Grad_Previous_"+dispname;
969 dict[
"theta"] = theta; dict[
"dt"] = dt; dict[
"Epn"] = Previous_Ep;
970 dict[
"lambda"] = lambda; dict[
"mu"] = mu; dict[
"sigma_y"] = sigma_y;
972 dict[
"Enp1"] = ga_substitute(
"Sym(Grad_u)", dict);
973 dict[
"En"] = ga_substitute(
"Sym(Grad_Previous_u)", dict);
974 dict[
"zetan"] = ga_substitute
975 (
"((Epn)+(1-(theta))*((dt)*(Previous_xi))*((2*(mu))*Deviator(En)"
976 "-(2*(mu)+2/3*(Hk))*(Epn)))", dict);
977 dict[
"etan"] = ga_substitute
978 (
"((alphan)+sqrt(2/3)*(1-(theta))*((dt)*(Previous_xi))*"
979 "Norm((2*(mu))*Deviator(En)-(2*(mu)+2/3*(Hk))*(Epn)))", dict);
981 dict[
"B"] = ga_substitute
982 (
"((2*(mu))*Deviator(Enp1)-(2*(mu)+2/3*(Hk))*(zetan))", dict);
984 ga_substitute(
"(1/((Norm(B)+1e-40)*(2*(mu)+2/3*(Hk)+(2/3)*(Hi))))"
985 "*pos_part(Norm(B)-sqrt(2/3)*((sigma_y)+(Hi)*(etan)))", dict);
986 dict[
"Epnp1"] = Epnp1 = ga_substitute(
"((zetan)+(beta)*(B))", dict);
987 alphanp1 = ga_substitute(
"((etan)+sqrt(2/3)*(beta)*Norm(B))", dict);
988 dict[
"alphanp1"] = alphanp1;
990 sigma_np1 = ga_substitute
991 (
"(lambda)*Trace(Enp1)*Id(meshdim)+2*(mu)*((Enp1)-(Epnp1))", dict);
992 dict[
"sigma_after"] = sigma_after = ga_substitute
993 (
"(lambda)*Trace(Enp1)*Id(meshdim)+2*(mu)*((Enp1)-(Epn))", dict);
994 xi_np1 = ga_substitute
995 (
"(((beta)/(1-(2*(mu)+2/3*(Hk))*(beta)))/((theta)*(dt)))", dict);
996 von_mises = ga_substitute
997 (
"sqrt(3/2)*Norm(Deviator(sigma_after))", dict);
1003 void build_isotropic_perfect_elastoplasticity_expressions_hard_mult_ps
1004 (model &md,
const std::string &dispname,
const std::string &xi,
1005 const std::string &Previous_Ep,
const std::string &alpha,
1006 const std::string &lambda,
const std::string &mu,
1007 const std::string &sigma_y,
const std::string &Hk,
const std::string &Hi,
1008 const std::string &theta,
const std::string &dt,
1009 std::string &sigma_np1, std::string &Epnp1, std::string &compcond,
1010 std::string &sigma_after, std::string &von_mises, std::string &alphanp1) {
1012 const mesh_fem *mfu = md.pmesh_fem_of_variable(dispname);
1014 GMM_ASSERT1(N == 2,
"This plastic law is restricted to 2D");
1016 GMM_ASSERT1(mfu && mfu->get_qdim() == N,
"The small strain "
1017 "elastoplasticity brick can only be applied on a fem "
1018 "variable of the same dimension as the mesh");
1020 GMM_ASSERT1(!(md.is_data(xi)) && md.pmesh_fem_of_variable(xi),
1021 "The provided name '" << xi <<
"' for the plastic multiplier, "
1022 "should be defined as a fem variable");
1024 GMM_ASSERT1(md.is_data(Previous_Ep) &&
1025 (md.pim_data_of_variable(Previous_Ep) ||
1026 md.pmesh_fem_of_variable(Previous_Ep)),
1027 "The provided name '" << Previous_Ep <<
"' for the plastic "
1028 "strain tensor at the previous timestep, should be defined "
1029 "either as fem or as im data");
1031 bgeot::multi_index Ep_size(N, N);
1032 GMM_ASSERT1((md.pim_data_of_variable(Previous_Ep) &&
1033 md.pim_data_of_variable(Previous_Ep)->tensor_size() == Ep_size)
1035 (md.pmesh_fem_of_variable(Previous_Ep) &&
1036 md.pmesh_fem_of_variable(Previous_Ep)->get_qdims() == Ep_size),
1037 "Wrong size of " << Previous_Ep);
1039 std::map<std::string, std::string> dict;
1040 dict[
"Hk"] = Hk; dict[
"Hi"] = Hi; dict[
"alphan"] =
alpha;
1041 dict[
"Grad_u"] =
"Grad_"+dispname; dict[
"xi"] = xi;
1042 dict[
"Previous_xi"] =
"Previous_"+xi;
1043 dict[
"Grad_Previous_u"] =
"Grad_Previous_"+dispname;
1044 dict[
"theta"] = theta; dict[
"dt"] = dt; dict[
"Epn"] = Previous_Ep;
1045 dict[
"lambda"] = lambda; dict[
"mu"] = mu; dict[
"sigma_y"] = sigma_y;
1047 dict[
"Enp1"] = ga_substitute(
"Sym(Grad_u)", dict);
1048 dict[
"En"] = ga_substitute(
"Sym(Grad_Previous_u)", dict);
1049 dict[
"Dev_En"]= ga_substitute(
"(En-(Trace(En)/3)*Id(meshdim))", dict);
1050 dict[
"Dev_Enp1"]= ga_substitute(
"(Enp1-(Trace(Enp1)/3)*Id(meshdim))", dict);
1051 dict[
"zetan"] = ga_substitute
1052 (
"((Epn)+(1-(theta))*((dt)*(Previous_xi))*((2*(mu))*(Dev_En)"
1053 "-(2*(mu)+2/3*(Hk))*(Epn)))", dict);
1054 dict[
"etan"] = ga_substitute
1055 (
"((alphan)+sqrt(2/3)*(1-(theta))*((dt)*(Previous_xi))*"
1056 "sqrt(Norm_sqr((2*(mu))*(Dev_En)-(2*(mu)+2/3*(Hk))*(Epn))"
1057 "+sqr(2*(mu)*Trace(En)/3-(2*(mu)+2/3*(Hk))*Trace(Epn))))", dict);
1058 dict[
"B"] = ga_substitute(
"((2*(mu))*(Dev_Enp1)-(2*(mu)+2/3*(Hk))*(zetan))",
1060 dict[
"Norm_B"] = ga_substitute(
"sqrt(Norm_sqr(B)+sqr(2*(mu)*Trace(Enp1)/3"
1061 "-(2*(mu)+2/3*(Hk))*Trace(zetan)))", dict);
1063 dict[
"beta"] = ga_substitute
1064 (
"((theta)*(dt)*(xi)/(1+(2*(mu)+2/3*(Hk))*(theta)*(dt)*(xi)))", dict);
1065 dict[
"Epnp1"] = Epnp1 = ga_substitute(
"((zetan)+(beta)*(B))", dict);
1066 alphanp1 = ga_substitute(
"((etan)+sqrt(2/3)*(beta)*(Norm_B))", dict);
1067 dict[
"alphanp1"] = alphanp1;
1068 sigma_np1 = ga_substitute
1069 (
"((lambda)*Trace(Enp1)*Id(meshdim)+2*(mu)*((Enp1)-(Epnp1)))", dict);
1070 dict[
"fbound"] = ga_substitute
1071 (
"(sqrt(Norm_sqr((2*(mu))*(Dev_Enp1)-(2*(mu)+2/3*(Hk))*(Epnp1))"
1072 "+sqr(2*(mu)*Trace(Enp1)/3-(2*(mu)+2/3*(Hk))*Trace(Epnp1)))"
1073 "-sqrt(2/3)*(sigma_y+(Hi)*(alphanp1)))", dict);
1074 sigma_after = ga_substitute
1075 (
"((lambda)*Trace(Enp1)*Id(meshdim)+2*(mu)*((Enp1)-(Epn)))", dict);
1076 compcond = ga_substitute
1077 (
"((mu)*xi-pos_part((mu)*xi+100*(fbound)/(mu)))", dict);
1078 von_mises = ga_substitute
1079 (
"sqrt(3/2)*sqrt(Norm_sqr((2*(mu))*(Dev_En)-(2*(mu)+2/3*(Hk))*(Epn))"
1080 "+sqr(2*(mu)*Trace(En)/3-(2*(mu)+2/3*(Hk))*Trace(Epn)))", dict);
1087 void build_isotropic_perfect_elastoplasticity_expressions_hard_no_mult_ps
1088 (model &md,
const std::string &dispname,
const std::string &xi,
1089 const std::string &Previous_Ep,
const std::string &alpha,
1090 const std::string &lambda,
const std::string &mu,
1091 const std::string &sigma_y,
const std::string &Hk,
const std::string &Hi,
1092 const std::string &theta,
const std::string &dt,
1093 std::string &sigma_np1, std::string &Epnp1, std::string &xi_np1,
1094 std::string &sigma_after, std::string &von_mises, std::string &alphanp1) {
1096 const mesh_fem *mfu = md.pmesh_fem_of_variable(dispname);
1098 GMM_ASSERT1(N == 2,
"This plastic law is restricted to 2D");
1100 GMM_ASSERT1(mfu && mfu->get_qdim() == N,
"The small strain "
1101 "elastoplasticity brick can only be applied on a fem "
1102 "variable of the same dimension as the mesh");
1104 GMM_ASSERT1(md.is_data(xi) &&
1105 (md.pim_data_of_variable(xi) ||
1106 md.pmesh_fem_of_variable(xi)),
1107 "The provided name '" << xi <<
"' for the plastic multiplier, "
1108 "should be defined either as fem data or as im data");
1110 GMM_ASSERT1(md.is_data(Previous_Ep) &&
1111 (md.pim_data_of_variable(Previous_Ep) ||
1112 md.pmesh_fem_of_variable(Previous_Ep)),
1113 "The provided name '" << Previous_Ep <<
"' for the plastic "
1114 "strain tensor at the previous timestep, should be defined "
1115 "either as fem or as im data");
1117 bgeot::multi_index Ep_size(N, N);
1118 GMM_ASSERT1((md.pim_data_of_variable(Previous_Ep) &&
1119 md.pim_data_of_variable(Previous_Ep)->tensor_size() == Ep_size)
1121 (md.pmesh_fem_of_variable(Previous_Ep) &&
1122 md.pmesh_fem_of_variable(Previous_Ep)->get_qdims() == Ep_size),
1123 "Wrong size of " << Previous_Ep);
1125 std::map<std::string, std::string> dict;
1126 dict[
"Hk"] = Hk; dict[
"Hi"] = Hi; dict[
"alphan"] =
alpha;
1127 dict[
"Grad_u"] =
"Grad_"+dispname; dict[
"xi"] = xi;
1128 dict[
"Previous_xi"] =
"Previous_"+xi;
1129 dict[
"Grad_Previous_u"] =
"Grad_Previous_"+dispname;
1130 dict[
"theta"] = theta; dict[
"dt"] = dt; dict[
"Epn"] = Previous_Ep;
1131 dict[
"lambda"] = lambda; dict[
"mu"] = mu; dict[
"sigma_y"] = sigma_y;
1133 dict[
"Enp1"] = ga_substitute(
"Sym(Grad_u)", dict);
1134 dict[
"En"] = ga_substitute(
"Sym(Grad_Previous_u)", dict);
1135 dict[
"Dev_En"]= ga_substitute(
"(En-(Trace(En)/3)*Id(meshdim))", dict);
1136 dict[
"Dev_Enp1"]= ga_substitute(
"(Enp1-(Trace(Enp1)/3)*Id(meshdim))", dict);
1137 dict[
"zetan"] = ga_substitute
1138 (
"((Epn)+(1-(theta))*((dt)*(Previous_xi))*((2*(mu))*(Dev_En)"
1139 "-(2*(mu)+2/3*(Hk))*(Epn)))", dict);
1140 dict[
"etan"] = ga_substitute
1141 (
"((alphan)+sqrt(2/3)*(1-(theta))*((dt)*(Previous_xi))*"
1142 "sqrt(Norm_sqr((2*(mu))*(Dev_En)-(2*(mu)+2/3*(Hk))*(Epn))"
1143 "+sqr(2*(mu)*Trace(En)/3-(2*(mu)+2/3*(Hk))*Trace(Epn))))", dict);
1145 dict[
"B"] = ga_substitute
1146 (
"((2*(mu))*(Dev_Enp1)-(2*(mu)+2/3*(Hk))*(zetan))", dict);
1147 dict[
"Norm_B"] = ga_substitute(
"sqrt(Norm_sqr(B)+sqr(2*(mu)*Trace(Enp1)/3"
1148 "-(2*(mu)+2/3*(Hk))*Trace(zetan)))", dict);
1150 ga_substitute(
"(1/(((Norm_B)+1e-40)*(2*(mu)+2/3*(Hk)+(2/3)*(Hi))))"
1151 "*pos_part((Norm_B)-sqrt(2/3)*((sigma_y)+(Hi)*(etan)))", dict);
1152 dict[
"Epnp1"] = Epnp1 = ga_substitute(
"((zetan)+(beta)*(B))", dict);
1153 alphanp1 = ga_substitute(
"((etan)+sqrt(2/3)*(beta)*(Norm_B))", dict);
1154 dict[
"alphanp1"] = alphanp1;
1156 sigma_np1 = ga_substitute
1157 (
"(lambda)*Trace(Enp1)*Id(meshdim)+2*(mu)*((Enp1)-(Epnp1))", dict);
1158 sigma_after = ga_substitute
1159 (
"(lambda)*Trace(Enp1)*Id(meshdim)+2*(mu)*((Enp1)-(Epn))", dict);
1160 xi_np1 = ga_substitute
1161 (
"(((beta)/(1-(2*(mu)+2/3*(Hk))*(beta)))/((theta)*(dt)))", dict);
1162 von_mises = ga_substitute
1163 (
"sqrt(3/2)*sqrt(Norm_sqr((2*(mu))*(Dev_En)-(2*(mu)+2/3*(Hk))*(Epn))"
1164 "+sqr(2*(mu)*Trace(En)/3-(2*(mu)+2/3*(Hk))*Trace(Epn)))", dict);
1167 void build_isotropic_perfect_elastoplasticity_expressions_generic
1168 (model &md,
const std::string &lawname,
1169 plasticity_unknowns_type unknowns_type,
1170 const std::vector<std::string> &varnames,
1171 const std::vector<std::string> ¶ms,
1172 std::string &sigma_np1, std::string &Epnp1,
1173 std::string &compcond, std::string &xi_np1,
1174 std::string &sigma_after, std::string &von_mises,
1175 std::string &alphanp1) {
1177 GMM_ASSERT1(unknowns_type == DISPLACEMENT_ONLY ||
1178 unknowns_type == DISPLACEMENT_AND_PLASTIC_MULTIPLIER,
1179 "Not supported type of unknowns");
1180 bool plastic_multiplier_is_var
1181 = (unknowns_type == DISPLACEMENT_AND_PLASTIC_MULTIPLIER);
1183 bool hardening = (lawname.find(
"_hardening") != std::string::npos);
1186 GMM_ASSERT1(varnames.size() == (hardening ? 4 : 3),
1187 "Incorrect number of variables: " << varnames.size());
1188 GMM_ASSERT1(params.size() >= 3+nhard &&
1189 params.size() <= 5+nhard,
1190 "Incorrect number of parameters: " << params.size());
1191 const std::string &dispname = sup_previous_and_dot_to_varname(varnames[0]);
1192 const std::string &xi = sup_previous_and_dot_to_varname(varnames[1]);
1193 const std::string &Previous_Ep = varnames[2];
1194 const std::string &
alpha = hardening ? varnames[3] :
"";
1195 const std::string &lambda = params[0];
1196 const std::string &mu = params[1];
1197 const std::string &sigma_y = params[2];
1198 const std::string &Hk = hardening ? params[3] :
"";
1199 const std::string &Hi = hardening ? params[4] :
"";
1200 const std::string &theta = (params.size() >= 4+nhard)
1201 ? params[3+nhard] :
"1";
1202 const std::string &dt = (params.size() >= 5+nhard)
1203 ? params[4+nhard] :
"timestep";
1205 sigma_np1 = Epnp1 = compcond = xi_np1 =
"";;
1206 sigma_after = von_mises = alphanp1 =
"";
1208 if (lawname.compare(
"isotropic_perfect_plasticity") == 0 ||
1209 lawname.compare(
"prandtl_reuss") == 0) {
1210 if (plastic_multiplier_is_var) {
1211 build_isotropic_perfect_elastoplasticity_expressions_mult
1212 (md, dispname, xi, Previous_Ep, lambda, mu, sigma_y, theta, dt,
1213 sigma_np1, Epnp1, compcond, sigma_after, von_mises);
1215 build_isotropic_perfect_elastoplasticity_expressions_no_mult
1216 (md, dispname, xi, Previous_Ep, lambda, mu, sigma_y, theta, dt,
1217 sigma_np1, Epnp1, xi_np1, sigma_after, von_mises);
1219 }
else if (lawname.compare(
"plane_strain_isotropic_perfect_plasticity")
1221 lawname.compare(
"plane_strain_prandtl_reuss") == 0) {
1222 if (plastic_multiplier_is_var) {
1223 build_isotropic_perfect_elastoplasticity_expressions_mult_ps
1224 (md, dispname, xi, Previous_Ep, lambda, mu, sigma_y, theta, dt,
1225 sigma_np1, Epnp1, compcond, sigma_after, von_mises);
1227 build_isotropic_perfect_elastoplasticity_expressions_no_mult_ps
1228 (md, dispname, xi, Previous_Ep, lambda, mu, sigma_y, theta, dt,
1229 sigma_np1, Epnp1, xi_np1, sigma_after, von_mises);
1231 }
else if (lawname.compare(
"isotropic_plasticity_linear_hardening") == 0 ||
1232 lawname.compare(
"prandtl_reuss_linear_hardening") == 0) {
1233 if (plastic_multiplier_is_var) {
1234 build_isotropic_perfect_elastoplasticity_expressions_hard_mult
1235 (md, dispname, xi, Previous_Ep, alpha,
1236 lambda, mu, sigma_y, Hk, Hi, theta, dt,
1237 sigma_np1, Epnp1, compcond, sigma_after, von_mises, alphanp1);
1239 build_isotropic_perfect_elastoplasticity_expressions_hard_no_mult
1240 (md, dispname, xi, Previous_Ep, alpha,
1241 lambda, mu, sigma_y, Hk, Hi, theta, dt,
1242 sigma_np1, Epnp1, xi_np1, sigma_after, von_mises, alphanp1);
1245 (lawname.compare(
"plane_strain_isotropic_plasticity_linear_hardening")
1247 lawname.compare(
"plane_strain_prandtl_reuss_linear_hardening") == 0) {
1248 if (plastic_multiplier_is_var) {
1249 build_isotropic_perfect_elastoplasticity_expressions_hard_mult_ps
1250 (md, dispname, xi, Previous_Ep, alpha,
1251 lambda, mu, sigma_y, Hk, Hi, theta, dt,
1252 sigma_np1, Epnp1, compcond, sigma_after, von_mises, alphanp1);
1254 build_isotropic_perfect_elastoplasticity_expressions_hard_no_mult_ps
1255 (md, dispname, xi, Previous_Ep, alpha,
1256 lambda, mu, sigma_y, Hk, Hi, theta, dt,
1257 sigma_np1, Epnp1, xi_np1, sigma_after, von_mises, alphanp1);
1260 GMM_ASSERT1(
false, lawname <<
" is not an implemented elastoplastic law");
1263 static void filter_lawname(std::string &lawname) {
1264 for (
auto &c : lawname)
1265 {
if (c ==
' ') c =
'_';
if (c >=
'A' && c <=
'Z') c = char(c+
'a'-
'A'); }
1270 std::string lawname, plasticity_unknowns_type unknowns_type,
1271 const std::vector<std::string> &varnames,
1272 const std::vector<std::string> ¶ms,
size_type region) {
1274 filter_lawname(lawname);
1275 std::string sigma_np1, compcond;
1277 std::string dum2, dum4, dum5, dum6, dum7;
1278 build_isotropic_perfect_elastoplasticity_expressions_generic
1279 (md, lawname, unknowns_type, varnames, params,
1280 sigma_np1, dum2, compcond, dum4, dum5, dum6, dum7);
1283 const std::string dispname=sup_previous_and_dot_to_varname(varnames[0]);
1284 const std::string xi =sup_previous_and_dot_to_varname(varnames[1]);
1286 if (unknowns_type == DISPLACEMENT_AND_PLASTIC_MULTIPLIER) {
1287 std::string expr = (
"("+sigma_np1+
"):Grad_Test_"+dispname
1288 +
"+("+compcond+
")*Test_"+xi);
1290 (md, mim, expr, region,
false,
false,
1291 "Small strain isotropic perfect elastoplasticity brick");
1294 (md, mim,
"("+sigma_np1+
"):Grad_Test_"+dispname, region,
true,
false,
1295 "Small strain isotropic perfect elastoplasticity brick");
1301 std::string lawname, plasticity_unknowns_type unknowns_type,
1302 const std::vector<std::string> &varnames,
1303 const std::vector<std::string> ¶ms,
size_type region) {
1305 filter_lawname(lawname);
1306 std::string Epnp1, xi_np1, alphanp1;
1308 std::string dum1, dum3, dum5, dum6;
1309 build_isotropic_perfect_elastoplasticity_expressions_generic
1310 (md, lawname, unknowns_type, varnames, params,
1311 dum1, Epnp1, dum3, xi_np1, dum5, dum6, alphanp1);
1314 std::string disp = sup_previous_and_dot_to_varname(varnames[0]);
1315 std::string xi = sup_previous_and_dot_to_varname(varnames[1]);
1316 std::string Previous_Ep = varnames[2];
1318 std::string Previous_alpha;
1319 base_vector tmpv_alpha;
1320 if (alphanp1.size()) {
1321 Previous_alpha = varnames[3];
1322 tmpv_alpha.resize(gmm::vect_size(md.
real_variable(Previous_alpha)));
1323 const im_data *pimd = md.pim_data_of_variable(Previous_alpha);
1325 ga_interpolation_im_data(md, alphanp1, *pimd, tmpv_alpha, region);
1328 GMM_ASSERT1(pmf,
"Provided data " << Previous_alpha
1329 <<
" should be defined on a im_data or a mesh_fem object");
1334 base_vector tmpv_xi;
1335 if (xi_np1.size()) {
1339 const im_data *pimd = md.pim_data_of_variable(xi);
1341 ga_interpolation_im_data(md, xi_np1, *pimd, tmpv_xi, region);
1344 GMM_ASSERT1(pmf,
"Provided data " << xi
1345 <<
" should be defined on a im_data or a mesh_fem object");
1350 base_vector tmpv_ep(gmm::vect_size(md.
real_variable(Previous_Ep)));
1351 const im_data *pimd = md.pim_data_of_variable(Previous_Ep);
1353 ga_interpolation_im_data(md, Epnp1, *pimd, tmpv_ep, region);
1356 GMM_ASSERT1(pmf,
"Provided data " << Previous_Ep
1357 <<
" should be defined on a im_data or a mesh_fem object");
1363 if (alphanp1.size())
1373 std::string lawname, plasticity_unknowns_type unknowns_type,
1374 const std::vector<std::string> &varnames,
1375 const std::vector<std::string> ¶ms,
1379 "Von mises stress can only be approximated on a scalar fem");
1380 VM.resize(mf_vm.
nb_dof());
1382 filter_lawname(lawname);
1384 std::string sigma_after, von_mises;
1386 std::string dum1, dum2, dum3, dum4, dum7;
1387 build_isotropic_perfect_elastoplasticity_expressions_generic
1388 (md, lawname, unknowns_type, varnames, params,
1389 dum1, dum2, dum3, dum4, sigma_after, von_mises, dum7);
1394 const im_data *pimd = md.pim_data_of_variable(varnames[n_ep]);
1400 GMM_ASSERT1(pmf,
"Provided data " << varnames[n_ep]
1401 <<
" should be defined on a im_data or a mesh_fem object");
1402 ga_interpolation_Lagrange_fem(md, von_mises, mf_vm, VM, region);
1414 const std::string _TWOTHIRD_(
"0.6666666666666666667");
1415 const std::string _FIVETHIRD_(
"1.6666666666666666667");
1416 const std::string _SQRTTHREEHALF_(
"1.2247448713915889407");
1419 (
const std::string &name, scalar_type sigma_y0, scalar_type H,
bool frobenius)
1422 sigma_y0 *= sqrt(2./3.);
1425 std::stringstream expr, der;
1426 expr << std::setprecision(17) << sigma_y0 <<
"+" << H <<
"*t";
1427 der << std::setprecision(17) << H;
1428 ga_define_function(name, 1, expr.str(), der.str());
1432 (
const std::string &name,
1433 scalar_type sigma_ref, scalar_type eps_ref, scalar_type n,
bool frobenius)
1435 scalar_type coef = sigma_ref / pow(eps_ref, 1./n);
1437 coef *= pow(2./3., 0.5 + 0.5/n);
1439 std::stringstream expr, der;
1440 expr << std::setprecision(17) << coef <<
"*pow(t+1e-12," << 1./n <<
")";
1441 der << std::setprecision(17) << coef/n <<
"*pow(t+1e-12," << 1./n-1 <<
")";
1442 ga_define_function(name, 1, expr.str(), der.str());
1446 void build_Simo_Miehe_elastoplasticity_expressions
1447 (model &md, plasticity_unknowns_type unknowns_type,
1448 const std::vector<std::string> &varnames,
1449 const std::vector<std::string> ¶ms,
1450 std::string &expr, std::string &plaststrain, std::string &invCp, std::string &vm)
1452 GMM_ASSERT1(unknowns_type == DISPLACEMENT_AND_PLASTIC_MULTIPLIER ||
1453 unknowns_type == DISPLACEMENT_AND_PLASTIC_MULTIPLIER_AND_PRESSURE,
1454 "Not supported type of unknowns for this type of plasticity law");
1455 bool has_pressure_var(unknowns_type ==
1456 DISPLACEMENT_AND_PLASTIC_MULTIPLIER_AND_PRESSURE);
1457 GMM_ASSERT1(varnames.size() == (has_pressure_var ? 5 : 4),
1458 "Wrong number of variables.");
1459 GMM_ASSERT1(params.size() == 3,
"Wrong number of parameters, "
1460 << params.size() <<
" != 3.");
1461 const std::string &dispname = sup_previous_and_dot_to_varname(varnames[0]);
1462 const std::string &multname = sup_previous_and_dot_to_varname(varnames[1]);
1463 const std::string &pressname = has_pressure_var ? varnames[2] :
"";
1464 const std::string &plaststrain0 = varnames[has_pressure_var ? 3 : 2];
1465 const std::string &invCp0 = varnames[has_pressure_var ? 4 : 3];
1466 const std::string &K = params[0];
1467 const std::string &G = params[1];
1468 const std::string &sigma_y = params[2];
1470 const mesh_fem *mfu = md.pmesh_fem_of_variable(dispname);
1471 GMM_ASSERT1(mfu,
"The provided displacement variable " << dispname <<
1472 " has to be defined on a mesh_fem");
1474 GMM_ASSERT1(N >= 2 && N <= 3,
1475 "Finite strain elastoplasticity brick works only in 2D or 3D");
1476 GMM_ASSERT1(mfu && mfu->get_qdim() == N,
"The finite strain "
1477 "elastoplasticity brick can only be applied on a fem "
1478 "variable of the same dimension as the mesh");
1479 const mesh_fem *mfmult = md.pmesh_fem_of_variable(multname);
1480 GMM_ASSERT1(mfmult && mfmult->get_qdim() == 1,
"The plastic multiplier "
1481 "for the finite strain elastoplasticity brick has to be a "
1482 "scalar fem variable");
1483 bool mixed(!pressname.empty());
1484 const mesh_fem *mfpress = mixed ? md.pmesh_fem_of_variable(pressname) : 0;
1485 GMM_ASSERT1(!mixed || (mfpress && mfpress->get_qdim() == 1),
1486 "The hydrostatic pressure multiplier for the finite strain "
1487 "elastoplasticity brick has to be a scalar fem variable");
1489 GMM_ASSERT1(ga_function_exists(sigma_y),
"The provided isotropic "
1490 "hardening function name '" << sigma_y <<
"' is not defined");
1492 GMM_ASSERT1(md.is_data(plaststrain0) &&
1493 (md.pim_data_of_variable(plaststrain0) ||
1494 md.pmesh_fem_of_variable(plaststrain0)),
1495 "The provided name '" << plaststrain0 <<
"' for the plastic "
1496 "strain field at the previous timestep, should be defined "
1497 "either as fem or as im data");
1498 GMM_ASSERT1((md.pim_data_of_variable(plaststrain0) &&
1499 md.pim_data_of_variable(plaststrain0)->nb_tensor_elem() == 1) ||
1500 (md.pmesh_fem_of_variable(plaststrain0) &&
1501 md.pmesh_fem_of_variable(plaststrain0)->get_qdim() == 1),
1502 "Wrong size of " << plaststrain0);
1503 GMM_ASSERT1(md.is_data(invCp0) &&
1504 (md.pim_data_of_variable(invCp0) ||
1505 md.pmesh_fem_of_variable(invCp0)),
1506 "The provided name '" << invCp0 <<
"' for the inverse of the "
1507 "plastic right Cauchy-Green tensor field at the previous "
1508 "timestep, should be defined either as fem or as im data");
1509 bgeot::multi_index Cp_size(1);
1510 Cp_size[0] = 4 + (N==3)*2;
1511 GMM_ASSERT1((md.pim_data_of_variable(invCp0) &&
1512 md.pim_data_of_variable(invCp0)->tensor_size() == Cp_size) ||
1513 (md.pmesh_fem_of_variable(invCp0) &&
1514 md.pmesh_fem_of_variable(invCp0)->get_qdims() == Cp_size),
1515 "Wrong size of " << invCp0);
1517 const std::string _U_ = sup_previous_and_dot_to_varname(dispname);
1518 const std::string _KSI_ = sup_previous_and_dot_to_varname(multname);
1519 const std::string _I_(N == 2 ?
"Id(2)" :
"Id(3)");
1520 const std::string _F_(
"("+_I_+
"+Grad_"+_U_+
")");
1521 const std::string _J_(
"Det"+_F_);
1525 _P_ =
"-"+pressname+
"*"+_J_;
1527 _P_ =
"("+K+
")*log("+_J_+
")";
1529 std::string _INVCP0_, _F3d_, _DEVLOGBETR_, _DEVLOGBETR_3D_;
1531 _INVCP0_ =
"([[[1,0,0],[0,0,0],[0,0,0]],"
1532 "[[0,0,0],[0,1,0],[0,0,0]],"
1533 "[[0,0,0],[0,0,0],[0,0,1]],"
1534 "[[0,1,0],[1,0,0],[0,0,0]]]."+invCp0+
")";
1535 _F3d_ =
"(Id(3)+[[1,0,0],[0,1,0]]*Grad_"+_U_+
"*[[1,0,0],[0,1,0]]')";
1536 _DEVLOGBETR_3D_ =
"(Deviator(Logm("+_F3d_+
"*"+_INVCP0_+
"*"+_F3d_+
"')))";
1537 _DEVLOGBETR_ =
"([[[[1,0],[0,0]],[[0,1],[0,0]],[[0,0],[0,0]]],"
1538 "[[[0,0],[1,0]],[[0,0],[0,1]],[[0,0],[0,0]]],"
1539 "[[[0,0],[0,0]],[[0,0],[0,0]],[[0,0],[0,0]]]]"
1540 ":"+_DEVLOGBETR_3D_+
")";
1542 _INVCP0_ =
"([[[1,0,0],[0,0,0],[0,0,0]],"
1543 "[[0,0,0],[0,1,0],[0,0,0]],"
1544 "[[0,0,0],[0,0,0],[0,0,1]],"
1545 "[[0,1,0],[1,0,0],[0,0,0]],"
1546 "[[0,0,1],[0,0,0],[1,0,0]],"
1547 "[[0,0,0],[0,0,1],[0,1,0]]]."+invCp0+
")";
1550 _DEVLOGBETR_ =
"(Deviator(Logm("+_F_+
"*"+_INVCP0_+
"*"+_F_+
"')))";
1552 const std::string _DEVTAUTR_(
"("+G+
"*"+_DEVLOGBETR_+
")");
1553 const std::string _DEVTAUTR_3D_(
"("+G+
"*"+_DEVLOGBETR_3D_+
")");
1554 const std::string _DEVTAU_(
"((1-2*"+_KSI_+
")*"+_DEVTAUTR_+
")");
1555 const std::string _DEVTAU_3D_(
"((1-2*"+_KSI_+
")*"+_DEVTAUTR_3D_+
")");
1556 const std::string _TAU_(
"("+_P_+
"*"+_I_+
"+"+_DEVTAU_+
")");
1558 const std::string _PLASTSTRAIN_(
"("+plaststrain0+
"+"+_KSI_+
"*Norm"+_DEVLOGBETR_3D_+
")");
1559 const std::string _SIGMA_Y_(sigma_y+
"("+_PLASTSTRAIN_+
")");
1562 expr = _TAU_+
":(Grad_Test_"+_U_+
"*Inv"+_F_+
")";
1564 expr +=
"+("+pressname+
"/("+K+
")+log("+_J_+
")/"+_J_+
")*Test_"+pressname;
1565 expr +=
"+(Norm"+_DEVTAU_+
1566 "-min("+_SIGMA_Y_+
",Norm"+_DEVTAUTR_+
"+1e-12*"+_KSI_+
"))*Test_"+_KSI_;
1568 plaststrain = _PLASTSTRAIN_;
1570 if (N==2) invCp =
"[[[1,0,0,0.0],[0,0,0,0.5],[0,0,0,0]],"
1571 "[[0,0,0,0.5],[0,1,0,0.0],[0,0,0,0]],"
1572 "[[0,0,0,0.0],[0,0,0,0.0],[0,0,1,0]]]";
1573 else invCp =
"[[[1.0,0,0,0,0,0],[0,0,0,0.5,0,0],[0,0,0,0,0.5,0]],"
1574 "[[0,0,0,0.5,0,0],[0,1.0,0,0,0,0],[0,0,0,0,0,0.5]],"
1575 "[[0,0,0,0,0.5,0],[0,0,0,0,0,0.5],[0,0,1.0,0,0,0]]]";
1576 invCp +=
":((Inv"+_F3d_+
"*Expm(-"+_KSI_+
"*"+_DEVLOGBETR_3D_+
")*"+_F3d_+
")*"+_INVCP0_+
1577 "*(Inv"+_F3d_+
"*Expm(-"+_KSI_+
"*"+_DEVLOGBETR_3D_+
")*"+_F3d_+
")')";
1579 vm = _SQRTTHREEHALF_+
"*Norm("+_DEVTAU_+
")/"+_J_;
1583 (model &md,
const mesh_im &mim,
1584 std::string lawname, plasticity_unknowns_type unknowns_type,
1585 const std::vector<std::string> &varnames,
1586 const std::vector<std::string> ¶ms,
size_type region)
1588 filter_lawname(lawname);
1589 if (lawname.compare(
"simo_miehe") == 0 ||
1590 lawname.compare(
"eterovic_bathe") == 0) {
1591 std::string expr, dummy1, dummy2, dummy3;
1592 build_Simo_Miehe_elastoplasticity_expressions
1593 (md, unknowns_type, varnames, params, expr, dummy1, dummy2, dummy3);
1595 (md, mim, expr, region,
true,
false,
"Simo Miehe elastoplasticity brick");
1597 GMM_ASSERT1(
false, lawname <<
" is not a known elastoplastic law");
1602 (model &md,
const mesh_im &mim,
1603 std::string lawname, plasticity_unknowns_type unknowns_type,
1604 const std::vector<std::string> &varnames,
1605 const std::vector<std::string> ¶ms,
size_type region) {
1607 filter_lawname(lawname);
1608 if (lawname.compare(
"simo_miehe") == 0 ||
1609 lawname.compare(
"eterovic_bathe") == 0) {
1610 std::string dummy1, dummy2, plaststrain, invCp;
1611 build_Simo_Miehe_elastoplasticity_expressions
1612 (md, unknowns_type, varnames, params, dummy1, plaststrain, invCp, dummy2);
1614 bool has_pressure_var(unknowns_type ==
1615 DISPLACEMENT_AND_PLASTIC_MULTIPLIER_AND_PRESSURE);
1616 const std::string &multname = sup_previous_and_dot_to_varname(varnames[1]);
1617 const std::string &plaststrain0 = varnames[has_pressure_var ? 3 : 2];
1618 const std::string &invCp0 = varnames[has_pressure_var ? 4 : 3];
1620 model_real_plain_vector tmpvec(gmm::vect_size(md.real_variable(plaststrain0)));
1621 const im_data *pimd = md.pim_data_of_variable(plaststrain0);
1623 ga_interpolation_im_data(md, plaststrain, *pimd, tmpvec, region);
1625 const mesh_fem *pmf = md.pmesh_fem_of_variable(plaststrain0);
1626 GMM_ASSERT1(pmf,
"Provided data " << plaststrain0 <<
" should be defined "
1627 "either on a im_data or a mesh_fem object");
1631 gmm::copy(tmpvec, md.set_real_variable(plaststrain0));
1635 model_real_plain_vector tmpvec(gmm::vect_size(md.real_variable(invCp0)));
1636 const im_data *pimd = md.pim_data_of_variable(invCp0);
1638 ga_interpolation_im_data(md, invCp, *pimd, tmpvec, region);
1640 const mesh_fem *pmf = md.pmesh_fem_of_variable(invCp0);
1641 GMM_ASSERT1(pmf,
"Provided data " << invCp0 <<
" should be defined "
1642 "either on a im_data or a mesh_fem object");
1646 gmm::copy(tmpvec, md.set_real_variable(invCp0));
1652 GMM_ASSERT1(
false, lawname <<
" is not a known elastoplastic law");
1656 (model &md,
const mesh_im &mim,
1657 std::string lawname, plasticity_unknowns_type unknowns_type,
1658 const std::vector<std::string> &varnames,
1659 const std::vector<std::string> ¶ms,
1660 const mesh_fem &mf_vm, model_real_plain_vector &VM,
1663 filter_lawname(lawname);
1664 if (lawname.compare(
"simo_miehe") == 0 ||
1665 lawname.compare(
"eterovic_bathe") == 0) {
1666 std::string dummy1, dummy2, dummy3, von_mises;
1667 build_Simo_Miehe_elastoplasticity_expressions
1668 (md, unknowns_type, varnames, params, dummy1, dummy2, dummy3, von_mises);
1669 VM.resize(mf_vm.nb_dof());
1671 bool has_pressure_var(unknowns_type ==
1672 DISPLACEMENT_AND_PLASTIC_MULTIPLIER_AND_PRESSURE);
1673 const std::string &plaststrain0 = varnames[has_pressure_var ? 3 : 2];
1674 const std::string &invCp0 = varnames[has_pressure_var ? 4 : 3];
1675 bool im_data1 = md.pim_data_of_variable(plaststrain0) != 0;
1676 bool im_data2 = md.pim_data_of_variable(invCp0) != 0;
1677 bool fem_data1 = md.pmesh_fem_of_variable(plaststrain0) != 0;
1678 bool fem_data2 = md.pmesh_fem_of_variable(invCp0) != 0;
1679 GMM_ASSERT1(im_data1 || fem_data1,
1680 "Provided data " << plaststrain0 <<
1681 " should be defined on a im_data or a mesh_fem object");
1682 GMM_ASSERT1(im_data2 || fem_data2,
1683 "Provided data " << invCp0 <<
1684 " should be defined on a im_data or a mesh_fem object");
1685 if (im_data1 || im_data2) {
1688 ga_interpolation_Lagrange_fem(md, von_mises, mf_vm, VM, region);
1692 GMM_ASSERT1(
false, lawname <<
" is not a known elastoplastic law");
1721 enum elastoplasticity_nonlinear_term_version { PROJ,
1728 class elastoplasticity_nonlinear_term :
public nonlinear_elem_term {
1732 const mesh_fem &mf_u;
1733 const mesh_fem &mf_sigma;
1734 const mesh_fem *pmf_data;
1735 model_real_plain_vector U_n, U_np1;
1736 model_real_plain_vector Sigma_n;
1737 model_real_plain_vector threshold, lambda, mu;
1738 const abstract_constraints_projection &t_proj;
1741 const bool store_sigma;
1743 bgeot::multi_index sizes_;
1750 model_real_plain_vector convex_coeffs, interpolated_val;
1753 model_real_plain_vector cumulated_sigma;
1755 model_real_plain_vector cumulated_count;
1757 fem_precomp_pool fppool;
1761 void compute_convex_coeffs(
size_type cv) {
1765 pfem pf_sigma = mf_sigma.fem_of_element(cv);
1766 size_type nbd_sigma = pf_sigma->nb_dof(cv);
1767 size_type qdim_sigma = mf_sigma.get_qdim();
1772 bgeot::vectors_to_base_matrix
1773 (G, mf_u.linked_mesh().points_of_convex(cv));
1775 mf_u.linked_mesh().trans_of_convex(cv);
1778 base_vector coeff_data;
1780 fem_interpolation_context ctx_data;
1782 pf_data = pmf_data->fem_of_element(cv);
1783 size_type nbd_data = pf_data->nb_dof(cv);
1784 coeff_data.resize(nbd_data*3);
1787 mesh_fem::ind_dof_ct::const_iterator itdof
1788 = pmf_data->ind_basic_dof_of_element(cv).begin();
1789 for (
size_type k = 0; k < nbd_data; ++k, ++itdof) {
1790 coeff_data[k*3] = lambda[*itdof];
1791 coeff_data[k*3+1] = mu[*itdof];
1792 coeff_data[k*3+2] = threshold[*itdof];
1794 GMM_ASSERT1(pf_data->target_dim() == 1,
1795 "won't interpolate on a vector FEM... ");
1797 pfem_precomp pfp_data = fppool(pf_data, pf_sigma->node_tab(cv));
1798 ctx_data = fem_interpolation_context
1803 size_type cvnbdof_u = mf_u.nb_basic_dof_of_element(cv);
1804 model_real_plain_vector coeff_du(cvnbdof_u);
1805 model_real_plain_vector coeff_u_np1(cvnbdof_u);
1806 mesh_fem::ind_dof_ct::const_iterator itdof
1807 = mf_u.ind_basic_dof_of_element(cv).begin();
1808 for (
size_type k = 0; k < cvnbdof_u; ++k, ++itdof) {
1809 coeff_du[k] = U_np1[*itdof] - U_n[*itdof];
1810 coeff_u_np1[k] = U_np1[*itdof];
1813 pfem pf_u = mf_u.fem_of_element(cv);
1814 pfem_precomp pfp_u = fppool(pf_u, pf_sigma->node_tab(cv));
1815 fem_interpolation_context
1819 base_matrix G_du(qdim, qdim), G_u_np1(qdim, qdim);
1821 for (
size_type ii = 0; ii < nbd_sigma; ++ii) {
1825 ctx_data.set_ii(ii);
1826 pf_data->interpolation(ctx_data, coeff_data, params, 3);
1831 pf_u->interpolation_grad(ctx_u, coeff_du, G_du, dim_type(qdim));
1832 if (option == PLAST)
1833 pf_u->interpolation_grad(ctx_u, coeff_u_np1, G_u_np1, dim_type(qdim));
1837 scalar_type ltrace_eps_np1 = (option == PLAST) ?
1838 params[0]*gmm::mat_trace(G_u_np1) : 0.;
1842 base_matrix sigma_hat(qdim, qdim);
1843 size_type sigma_dof = mf_sigma.ind_basic_dof_of_element(cv)[ii*qdim_sigma];
1844 for (dim_type j = 0; j < qdim; ++j) {
1845 for (dim_type i = 0; i < qdim; ++i)
1846 sigma_hat(i,j) = Sigma_n[sigma_dof++]
1847 + params[1]*(G_du(i,j) + G_du(j,i));
1848 sigma_hat(j,j) += ltrace_deps;
1853 t_proj.do_projection(sigma_hat, params[2], proj, flag_proj);
1856 if (option == PLAST)
1857 for (dim_type i = 0; i < qdim; ++i) {
1858 for (dim_type j = 0; j < qdim; ++j)
1859 proj(i,j) -= params[1]*(G_u_np1(i,j) + G_u_np1(j,i));
1860 proj(i,i) -= ltrace_eps_np1;
1864 std::copy(proj.begin(), proj.end(),
1865 convex_coeffs.begin() + proj.size() * ii);
1869 sigma_dof = mf_sigma.ind_basic_dof_of_element(cv)[ii*qdim_sigma];
1870 for (dim_type j = 0; j < qdim; ++j) {
1871 for (dim_type i = 0; i < qdim; ++i) {
1872 cumulated_count[sigma_dof] += 1;
1873 cumulated_sigma[sigma_dof++] += proj(i,j);
1885 elastoplasticity_nonlinear_term
1886 (
const mesh_im &mim_,
1887 const mesh_fem &mf_u_,
1888 const mesh_fem &mf_sigma_,
1889 const mesh_fem *pmf_data_,
1890 const model_real_plain_vector &U_n_,
1891 const model_real_plain_vector &U_np1_,
1892 const model_real_plain_vector &Sigma_n_,
1893 const model_real_plain_vector &threshold_,
1894 const model_real_plain_vector &lambda_,
1895 const model_real_plain_vector &mu_,
1896 const abstract_constraints_projection &t_proj_,
1898 bool store_sigma_) :
1899 mim(mim_), mf_u(mf_u_), mf_sigma(mf_sigma_), pmf_data(pmf_data_),
1900 Sigma_n(Sigma_n_), t_proj(t_proj_), option(option_),
1901 flag_proj(option == GRADPROJ ? 1 : 0),
1902 store_sigma(option == GRADPROJ ? false : store_sigma_) {
1905 N = mf_u.linked_mesh().dim();
1907 sizes_ = (flag_proj == 0 ? bgeot::multi_index(N,N)
1908 :
bgeot::multi_index(N,N,N,N));
1912 size_proj = (flag_proj == 0 ? N*N : N*N*N*N);
1917 mf_u.extend_vector(gmm::sub_vector(U_n_,
1918 gmm::sub_interval(0,mf_u.nb_dof())),
1920 mf_u.extend_vector(gmm::sub_vector(U_np1_,
1921 gmm::sub_interval(0,mf_u.nb_dof())),
1923 mf_sigma.extend_vector(gmm::sub_vector(Sigma_n_,
1924 gmm::sub_interval(0,mf_sigma.nb_dof())),
1931 pmf_data->extend_vector(threshold_, threshold);
1932 pmf_data->extend_vector(lambda_, lambda);
1933 pmf_data->extend_vector(mu_, mu);
1937 gmm::resize(threshold, 1); threshold[0] = threshold_[0];
1938 params[0] = lambda[0];
1940 params[2] = threshold[0];
1942 GMM_ASSERT1(mf_u.get_qdim() == N,
1943 "wrong qdim for the mesh_fem");
1948 cumulated_sigma.resize(mf_sigma.nb_dof());
1949 cumulated_count.resize(mf_sigma.nb_dof());
1960 const bgeot::multi_index &sizes(
size_type)
const {
return sizes_; }
1964 virtual void compute(fem_interpolation_context& ctx,
1965 bgeot::base_tensor &t) {
1967 pfem pf_sigma = ctx.pf();
1968 GMM_ASSERT1(pf_sigma->is_lagrange(),
1969 "Sorry, works only for Lagrange fems");
1972 if (cv != current_cv)
1973 compute_convex_coeffs(cv);
1976 pf_sigma->interpolation(ctx, convex_coeffs, interpolated_val, dim_type(size_proj));
1979 t.adjust_sizes(sizes_);
1980 std::copy(interpolated_val.begin(), interpolated_val.end(), t.begin());
1985 void get_averaged_sigmas(model_real_plain_vector &sigma) {
1986 model_real_plain_vector glob_cumulated_count(mf_sigma.nb_dof());
1987 MPI_SUM_VECTOR(cumulated_sigma, sigma);
1988 MPI_SUM_VECTOR(cumulated_count, glob_cumulated_count);
1991 sigma[i] /= glob_cumulated_count[i];
2002 void asm_elastoplasticity_rhs
2003 (model_real_plain_vector &V,
2004 model_real_plain_vector *saved_sigma,
2006 const mesh_fem &mf_u,
2007 const mesh_fem &mf_sigma,
2008 const mesh_fem &mf_data,
2009 const model_real_plain_vector &u_n,
2010 const model_real_plain_vector &u_np1,
2011 const model_real_plain_vector &sigma_n,
2012 const model_real_plain_vector &lambda,
2013 const model_real_plain_vector &mu,
2014 const model_real_plain_vector &threshold,
2015 const abstract_constraints_projection &t_proj,
2019 GMM_ASSERT1(mf_u.get_qdim() == mf_u.linked_mesh().dim(),
2020 "wrong qdim for the mesh_fem");
2021 GMM_ASSERT1(option_sigma == PROJ || option_sigma == PLAST,
2022 "wrong option parameter");
2024 elastoplasticity_nonlinear_term plast(mim, mf_u, mf_sigma, &mf_data,
2025 u_n, u_np1, sigma_n,
2026 threshold, lambda, mu,
2027 t_proj, option_sigma, (saved_sigma != NULL));
2029 generic_assembly assem(
"V(#1) + =comp(NonLin(#2).vGrad(#1))(i,j,:,i,j);");
2032 assem.push_mf(mf_u);
2033 assem.push_mf(mf_sigma);
2034 assem.push_nonlinear_term(&plast);
2039 plast.get_averaged_sigmas(*saved_sigma);
2047 void asm_elastoplasticity_tangent_matrix
2048 (model_real_sparse_matrix &H,
2050 const mesh_fem &mf_u,
2051 const mesh_fem &mf_sigma,
2052 const mesh_fem *pmf_data,
2053 const model_real_plain_vector &u_n,
2054 const model_real_plain_vector &u_np1,
2055 const model_real_plain_vector &sigma_n,
2056 const model_real_plain_vector &lambda,
2057 const model_real_plain_vector &mu,
2058 const model_real_plain_vector &threshold,
2059 const abstract_constraints_projection &t_proj,
2062 GMM_ASSERT1(mf_u.get_qdim() == mf_u.linked_mesh().dim(),
2063 "wrong qdim for the mesh_fem");
2065 elastoplasticity_nonlinear_term gradplast(mim, mf_u, mf_sigma, pmf_data,
2066 u_n, u_np1, sigma_n,
2067 threshold, lambda, mu,
2068 t_proj, GRADPROJ,
false);
2070 generic_assembly assem;
2073 assem.set(
"lambda=data$1(#3); mu=data$2(#3);"
2074 "t=comp(NonLin(#2).vGrad(#1).vGrad(#1).Base(#3))(i,j,:,:,:,:,:,:,i,j,:);"
2075 "M(#1,#1)+= sym(t(k,l,:,l,k,:,m).mu(m)+t(k,l,:,k,l,:,m).mu(m)+t(k,k,:,l,l,:,m).lambda(m))");
2077 assem.set(
"lambda=data$1(1); mu=data$2(1);"
2078 "t=comp(NonLin(#2).vGrad(#1).vGrad(#1))(i,j,:,:,:,:,:,:,i,j);"
2079 "M(#1,#1)+= sym(t(k,l,:,l,k,:).mu(1)+t(k,l,:,k,l,:).mu(1)+t(k,k,:,l,l,:).lambda(1))");
2082 assem.push_mf(mf_u);
2083 assem.push_mf(mf_sigma);
2085 assem.push_mf(*pmf_data);
2086 assem.push_data(lambda);
2087 assem.push_data(mu);
2088 assem.push_nonlinear_term(&gradplast);
2100 struct elastoplasticity_brick :
public virtual_brick {
2102 pconstraints_projection t_proj;
2104 virtual void asm_real_tangent_terms(
const model &md,
2106 const model::varnamelist &vl,
2107 const model::varnamelist &dl,
2108 const model::mimlist &mims,
2109 model::real_matlist &matl,
2110 model::real_veclist &vecl,
2111 model::real_veclist &,
2113 build_version version)
const {
2115 GMM_ASSERT1(mims.size() == 1,
2116 "Elastoplasticity brick need a single mesh_im");
2117 GMM_ASSERT1(vl.size() == 1,
2118 "Elastoplasticity brick need one variable");
2121 GMM_ASSERT1(dl.size() == 5,
2122 "Wrong number of data for elastoplasticity brick, "
2123 << dl.size() <<
" should be 4.");
2124 GMM_ASSERT1(matl.size() == 1,
"Wrong number of terms for "
2125 "elastoplasticity brick");
2127 const model_real_plain_vector &u_np1 = md.real_variable(vl[0]);
2128 const model_real_plain_vector &u_n = md.real_variable(dl[4]);
2129 const mesh_fem &mf_u = *(md.pmesh_fem_of_variable(vl[0]));
2130 GMM_ASSERT1(&mf_u == md.pmesh_fem_of_variable(dl[4]),
2131 "The previous displacement data have to be defined on the "
2132 "same mesh_fem as the displacement variable");
2134 const model_real_plain_vector &lambda = md.real_variable(dl[0]);
2135 const model_real_plain_vector &mu = md.real_variable(dl[1]);
2136 const model_real_plain_vector &threshold = md.real_variable(dl[2]);
2137 const mesh_fem *mf_data = md.pmesh_fem_of_variable(dl[0]);
2139 const model_real_plain_vector &sigma_n = md.real_variable(dl[3]);
2140 const mesh_fem &mf_sigma = *(md.pmesh_fem_of_variable(dl[3]));
2141 GMM_ASSERT1(!(mf_sigma.is_reduced()),
2142 "Works only for pure Lagrange fems");
2144 const mesh_im &mim = *mims[0];
2145 mesh_region rg(region);
2146 mim.linked_mesh().intersect_with_mpi_region(rg);
2148 if (version & model::BUILD_MATRIX) {
2150 asm_elastoplasticity_tangent_matrix
2151 (matl[0], mim, mf_u, mf_sigma, mf_data, u_n,
2152 u_np1, sigma_n, lambda, mu, threshold, *t_proj, rg);
2155 if (version & model::BUILD_RHS) {
2156 model_real_plain_vector *dummy = 0;
2157 asm_elastoplasticity_rhs(vecl[0], dummy,
2158 mim, mf_u, mf_sigma, *mf_data,
2159 u_n, u_np1, sigma_n,
2160 lambda, mu, threshold, *t_proj, PROJ, rg);
2161 gmm::scale(vecl[0], scalar_type(-1));
2167 elastoplasticity_brick(
const pconstraints_projection &t_proj_)
2169 set_flags(
"Elastoplasticity brick",
false ,
2184 const pconstraints_projection &ACP,
2185 const std::string &varname,
2186 const std::string &data_previous_disp,
2187 const std::string &datalambda,
2188 const std::string &datamu,
2189 const std::string &datathreshold,
2190 const std::string &datasigma,
2193 pbrick pbr = std::make_shared<elastoplasticity_brick>(ACP);
2195 model::termlist tl{model::term_description(varname, varname,
true)};
2197 dl{datalambda, datamu, datathreshold, datasigma, data_previous_disp},
2200 return md.add_brick(pbr, vl, dl, tl,
2201 model::mimlist(1,&mim), region);
2213 const std::string &varname,
2214 const std::string &data_previous_disp,
2215 const pconstraints_projection &ACP,
2216 const std::string &datalambda,
2217 const std::string &datamu,
2218 const std::string &datathreshold,
2219 const std::string &datasigma) {
2221 const model_real_plain_vector &u_np1 = md.real_variable(varname);
2222 model_real_plain_vector &u_n = md.set_real_variable(data_previous_disp);
2223 const mesh_fem &mf_u = *(md.pmesh_fem_of_variable(varname));
2225 const model_real_plain_vector &lambda = md.real_variable(datalambda);
2226 const model_real_plain_vector &mu = md.real_variable(datamu);
2227 const model_real_plain_vector &threshold = md.real_variable(datathreshold);
2228 const mesh_fem *mf_data = md.pmesh_fem_of_variable(datalambda);
2230 const model_real_plain_vector &sigma_n = md.real_variable(datasigma);
2231 const mesh_fem &mf_sigma = *(md.pmesh_fem_of_variable(datasigma));
2235 mesh_region rg = mim.linked_mesh().get_mpi_region();
2237 model_real_plain_vector sigma_np1(mf_sigma.nb_dof());
2238 model_real_plain_vector dummyV(mf_u.nb_dof());
2239 asm_elastoplasticity_rhs(dummyV, &sigma_np1,
2240 mim, mf_u, mf_sigma, *mf_data,
2241 u_n, u_np1, sigma_n,
2242 lambda, mu, threshold, *ACP, PROJ, rg);
2247 gmm::copy(sigma_np1, md.set_real_variable(datasigma));
2260 const std::string &datasigma,
2261 const mesh_fem &mf_vm,
2262 model_real_plain_vector &VM,
2265 GMM_ASSERT1(gmm::vect_size(VM) == mf_vm.nb_dof(),
2266 "The vector has not the right size");
2268 const model_real_plain_vector &sigma_np1 = md.real_variable(datasigma);
2269 const mesh_fem &mf_sigma = md.mesh_fem_of_variable(datasigma);
2272 dim_type N = mf_sigma.linked_mesh().dim();
2274 GMM_ASSERT1(mf_vm.get_qdim() == 1,
2275 "Target dimension of mf_vm should be 1");
2277 base_matrix sigma(N, N), Id(N, N);
2279 base_vector sigma_vm(mf_vm.nb_dof()*N*N);
2286 for (
size_type ii = 0; ii < mf_vm.nb_dof(); ++ii) {
2289 std::copy(sigma_vm.begin()+ii*N*N, sigma_vm.begin()+(ii+1)*N*N,
2294 gmm::add(gmm::scaled(Id, -gmm::mat_trace(sigma) / N), sigma);
2300 gmm::symmetric_qr_algorithm(sigma, eig);
2301 std::sort(eig.begin(), eig.end());
2302 VM[ii] = eig.back() - eig.front();
2315 const mesh_fem &mf_pl,
2316 const std::string &varname,
2317 const std::string &data_previous_disp,
2318 const pconstraints_projection &ACP,
2319 const std::string &datalambda,
2320 const std::string &datamu,
2321 const std::string &datathreshold,
2322 const std::string &datasigma,
2323 model_real_plain_vector &plast) {
2325 const model_real_plain_vector &u_np1 = md.real_variable(varname);
2326 const model_real_plain_vector &u_n = md.real_variable(data_previous_disp);
2327 const mesh_fem &mf_u = *(md.pmesh_fem_of_variable(varname));
2329 const model_real_plain_vector &lambda = md.real_variable(datalambda);
2330 const model_real_plain_vector &mu = md.real_variable(datamu);
2331 const model_real_plain_vector &threshold = md.real_variable(datathreshold);
2332 const mesh_fem *pmf_data = md.pmesh_fem_of_variable(datalambda);
2334 const model_real_plain_vector &sigma_n = md.real_variable(datasigma);
2335 const mesh_fem &mf_sigma = *(md.pmesh_fem_of_variable(datasigma));
2337 dim_type N = mf_sigma.linked_mesh().dim();
2339 mesh_region rg = mim.linked_mesh().get_mpi_region();
2341 model_real_plain_vector dummyV(mf_u.nb_dof());
2342 model_real_plain_vector saved_plast(mf_sigma.nb_dof());
2343 asm_elastoplasticity_rhs(dummyV, &saved_plast,
2344 mim, mf_u, mf_sigma, *pmf_data,
2345 u_n, u_np1, sigma_n,
2346 lambda, mu, threshold, *ACP, PLAST, rg);
2349 GMM_ASSERT1(gmm::vect_size(plast) == mf_pl.nb_dof(),
2350 "The vector has not the right size");
2351 GMM_ASSERT1(mf_pl.get_qdim() == 1,
2352 "Target dimension of mf_pl should be 1");
2354 base_vector saved_pl(mf_pl.nb_dof()*N*N);
2358 base_matrix plast_tmp(N, N);
2359 for (
size_type ii = 0; ii < mf_pl.nb_dof(); ++ii) {
2362 std::copy(saved_pl.begin()+ii*N*N, saved_pl.begin()+(ii+1)*N*N,
static T & instance()
Instance from the current thread.
im_data provides indexing to the integration points of a mesh im object.
Describe a finite element method linked to a mesh.
virtual dim_type get_qdim() const
Return the Q dimension.
virtual size_type nb_dof() const
Return the total number of degrees of freedom.
Describe an integration method linked to a mesh.
static mesh_region all_convexes()
provide a default value for the mesh_region parameters of assembly procedures etc.
`‘Model’' variables store the variables, the data and the description of a model.
const mesh_fem * pmesh_fem_of_variable(const std::string &name) const
Gives a pointer to the mesh_fem of a variable if any.
model_real_plain_vector & set_real_variable(const std::string &name, size_type niter) const
Gives the write access to the vector value of a variable.
const model_real_plain_vector & real_variable(const std::string &name, size_type niter) const
Gives the access to the vector value of a variable.
A language for generic assembly of pde boundary value problems.
Interpolation of fields from a mesh_fem onto another.
Model representation in Getfem.
void copy(const L1 &l1, L2 &l2)
*/
number_traits< typename linalg_traits< V >::value_type >::magnitude_type vect_norm2(const V &v)
Euclidean norm of a vector.
linalg_traits< M >::value_type mat_trace(const M &m)
Trace of a matrix.
number_traits< typename linalg_traits< M >::value_type >::magnitude_type mat_euclidean_norm(const M &m)
Euclidean norm of a matrix.
void clear(L &l)
clear (fill with zeros) a vector or matrix.
void resize(V &v, size_type n)
*/
void mult(const L1 &l1, const L2 &l2, L3 &l3)
*/
void add(const L1 &l1, L2 &l2)
*/
void lu_inverse(const DenseMatrixLU &LU, const Pvector &pvector, const DenseMatrix &AInv_)
Given an LU factored matrix, build the inverse of the matrix.
Common matrix functions for dense matrices.
void logm(const dense_matrix< T > &A, dense_matrix< T > &LOGMA)
Matrix logarithm (from GNU/Octave)
std::shared_ptr< const getfem::virtual_fem > pfem
type of pointer on a fem description
gmm::uint16_type short_type
used as the common short type integer in the library
size_t size_type
used as the common size type in the library
std::shared_ptr< const bgeot::geometric_trans > pgeometric_trans
pointer type for a geometric transformation
size_type alpha(short_type n, short_type d)
Return the value of which is the number of monomials of a polynomial of variables and degree .
GEneric Tool for Finite Element Methods.
size_type APIDECL add_nonlinear_term(model &md, const mesh_im &mim, const std::string &expr, size_type region=size_type(-1), bool is_sym=false, bool is_coercive=false, const std::string &brickname="")
Add a nonlinear term given by the weak form language expression expr which will be assembled in regio...
void ga_define_linear_hardening_function(const std::string &name, scalar_type sigma_y0, scalar_type H, bool frobenius=true)
Add a linear function with the name specified by name to represent linear isotropoc hardening in plas...
void compute_plastic_part(model &md, const mesh_im &mim, const mesh_fem &mf_pl, const std::string &varname, const std::string &previous_dep_name, const pconstraints_projection &ACP, const std::string &datalambda, const std::string &datamu, const std::string &datathreshold, const std::string &datasigma, model_real_plain_vector &plast)
This function computes on mf_pl the plastic part, that could appear after a load and an unload,...
void compute_small_strain_elastoplasticity_Von_Mises(model &md, const mesh_im &mim, std::string lawname, plasticity_unknowns_type unknowns_type, const std::vector< std::string > &varnames, const std::vector< std::string > ¶ms, const mesh_fem &mf_vm, model_real_plain_vector &VM, size_type region=size_type(-1))
This function computes the Von Mises stress field with respect to a small strain elastoplasticity ter...
void finite_strain_elastoplasticity_next_iter(model &md, const mesh_im &mim, std::string lawname, plasticity_unknowns_type unknowns_type, const std::vector< std::string > &varnames, const std::vector< std::string > ¶ms, size_type region=size_type(-1))
This function permits to update the state variables for a finite strain elastoplasticity brick,...
size_type add_finite_strain_elastoplasticity_brick(model &md, const mesh_im &mim, std::string lawname, plasticity_unknowns_type unknowns_type, const std::vector< std::string > &varnames, const std::vector< std::string > ¶ms, size_type region=size_type(-1))
Add a finite strain elastoplasticity brick to the model.
void elastoplasticity_next_iter(model &md, const mesh_im &mim, const std::string &varname, const std::string &previous_dep_name, const pconstraints_projection &ACP, const std::string &datalambda, const std::string &datamu, const std::string &datathreshold, const std::string &datasigma)
This function permits to compute the new stress constraints values supported by the material after a ...
void interpolation(const mesh_fem &mf_source, const mesh_fem &mf_target, const VECTU &U, VECTV &V, int extrapolation=0, double EPS=1E-10, mesh_region rg_source=mesh_region::all_convexes(), mesh_region rg_target=mesh_region::all_convexes())
interpolation/extrapolation of (mf_source, U) on mf_target.
void compute_elastoplasticity_Von_Mises_or_Tresca(model &md, const std::string &datasigma, const mesh_fem &mf_vm, model_real_plain_vector &VM, bool tresca)
This function computes on mf_vm the Von Mises or Tresca stress of a field for elastoplasticity and re...
std::shared_ptr< const virtual_brick > pbrick
type of pointer on a brick
void ga_define_Ramberg_Osgood_hardening_function(const std::string &name, scalar_type sigma_ref, scalar_type eps_ref, scalar_type n, bool frobenius=false)
Add a Ramberg-Osgood hardening function with the name specified by name, for reference stress and str...
size_type add_small_strain_elastoplasticity_brick(model &md, const mesh_im &mim, std::string lawname, plasticity_unknowns_type unknowns_type, const std::vector< std::string > &varnames, const std::vector< std::string > ¶ms, size_type region=size_type(-1))
Adds a small strain plasticity term to the model md.
void ga_local_projection(const getfem::model &md, const mesh_im &mim, const std::string &expr, const mesh_fem &mf, base_vector &result, const mesh_region &rg=mesh_region::all_convexes())
Make an elementwise L2 projection of an expression with respect to the mesh_fem mf.
void compute_finite_strain_elastoplasticity_Von_Mises(model &md, const mesh_im &mim, std::string lawname, plasticity_unknowns_type unknowns_type, const std::vector< std::string > &varnames, const std::vector< std::string > ¶ms, const mesh_fem &mf_vm, model_real_plain_vector &VM, size_type region=size_type(-1))
This function computes the Von Mises stress field with respect to a finite strain elastoplasticity te...
void small_strain_elastoplasticity_next_iter(model &md, const mesh_im &mim, std::string lawname, plasticity_unknowns_type unknowns_type, const std::vector< std::string > &varnames, const std::vector< std::string > ¶ms, size_type region=size_type(-1))
Function that allows to pass from a time step to another for the small strain plastic brick.
size_type add_elastoplasticity_brick(model &md, const mesh_im &mim, const pconstraints_projection &ACP, const std::string &varname, const std::string &previous_dep_name, const std::string &datalambda, const std::string &datamu, const std::string &datathreshold, const std::string &datasigma, size_type region=size_type(-1))
Add a nonlinear elastoplasticity term to the model for small deformations and an isotropic material,...