4#include <dune/geometry/type.hh>
5#include <dune/geometry/referenceelements.hh>
6#include <dune/geometry/quadraturerules.hh>
11 template<
typename GV,
typename PROBLEM,
typename DGF,
int dofel>
12 class getStressLinear :
21 public NumericalJacobianApplyVolume<getStressLinear<GV,PROBLEM,DGF,dofel> >,
22 public FullVolumePattern,
23 public LocalOperatorDefaultFlags,
24 public InstationaryLocalOperatorDefaultMethods<double>,
25 public NumericalJacobianVolume<getStressLinear<GV,PROBLEM,DGF, dofel> >
29 enum { doPatternVolume =
false };
32 enum { doAlphaVolume =
true };
35 getStressLinear (
const GV& gv_,
const PROBLEM& prob_,
const DGF& dgf_,
double& maxDisp_) : gv(gv_), problem(prob_) , maxDisp(maxDisp_), dgf(dgf_){}
40 template<
typename EG,
typename LFSU,
typename X,
typename LFSV,
typename R>
41 void alpha_volume (
const EG& eg,
const LFSU& lfsu,
const X& x,
const LFSV& lfsv, R& r)
const
46 typedef typename LFSU::template Child<0>::Type LFS1;
47 typedef typename LFS1::Traits::FiniteElementType::Traits::LocalBasisType::Traits::JacobianType JacobianType;
49 const auto& lfs1 = lfsu.template child<0>();
50 const auto& lfs2 = lfsu.template child<1>();
51 const auto& lfs3 = lfsu.template child<2>();
53 const auto& lfsv1 = lfsv.template child<0>();
54 const auto& lfsv2 = lfsv.template child<1>();
55 const auto& lfsv3 = lfsv.template child<2>();
56 const auto& lfsv4 = lfsv.template child<3>();
57 const auto& lfsv5 = lfsv.template child<4>();
58 const auto& lfsv6 = lfsv.template child<5>();
61 Dune::FieldMatrix<double,6,6> C(0.0),Cthermal(0.0);
62 problem.evaluate(eg.entity(),C);
63 problem.evaluate_strain(eg.entity(),Cthermal);
66 Dune::FieldVector<double,6> delta(0.0);
67 if(problem.getMaterialType(eg.entity()) == 0)
68 problem.evaluateHeat(delta,
true);
70 problem.evaluateHeat(delta,
false);
73 Dune::FieldVector<double,6> appliedStress(0.0);
74 Cthermal.mv(delta, appliedStress);
76 int nodes_per_element = lfsv1.size();
77 int dof = lfs1.size();
80 for (
int iter = 0; iter < nodes_per_element; iter++){
81 Dune::FieldVector<double,1> num_elem(1.0);
82 Dune::FieldVector<double,dim> pt = eg.geometry().local(eg.geometry().corner(iter));
83 Dune::FieldVector<double,dim> pt_cen = eg.geometry().local(eg.geometry().center());
85 auto theta = problem.getThetaFct(eg.entity(),pt);
86 auto Cijkl = getMatrix(C,theta);
89 std::vector<JacobianType> js(dof);
90 lfs1.finiteElement().localBasis().evaluateJacobian(pt,js);
93 const auto jac = eg.geometry().jacobianInverseTransposed(pt);
94 std::vector<Dune::FieldVector<double,dim> > gradphi(dof);
95 for (
int i=0; i < dof; i++){
97 jac.umv(js[i][0],gradphi[i]);
99 Dune::FieldMatrix<double,6,dofel> B(0.0);
100 for (
int i = 0; i < dof; i++)
102 B[0][i] = gradphi[i][0];
103 B[1][i + dof] = gradphi[i][1];
104 B[2][i + 2 * dof] = gradphi[i][2];
105 B[3][i + dof] = gradphi[i][2]; B[3][i + 2 * dof] = gradphi[i][1];
106 B[4][i] = gradphi[i][2]; B[4][i + 2 * dof] = gradphi[i][0];
107 B[5][i] = gradphi[i][1]; B[5][i + dof] = gradphi[i][0];
110 Dune::FieldVector<double,6> e(0.0),s(0.0);
111 Dune::FieldVector<double,dofel> xlc(0.0);
112 for(
int i = 0; i < dof; i++){
114 xlc[i+dof] = x(lfs2,i);
115 xlc[i+2*dof] = x(lfs3,i);
124 std::vector<JacobianType> js_cen(dof);
125 lfs1.finiteElement().localBasis().evaluateJacobian(pt_cen,js_cen);
128 const auto jac_cen = eg.geometry().jacobianInverseTransposed(pt_cen);
129 std::vector<Dune::FieldVector<double,dim> > gradphi_cen(dof);
130 for (
int i=0; i < dof; i++){
131 gradphi_cen[i] = 0.0;
132 jac_cen.umv(js_cen[i][0],gradphi_cen[i]);
134 Dune::FieldMatrix<double,6,dofel> B_cen(0.0);
135 for (
int i = 0; i < dof; i++)
137 B_cen[0][i] = gradphi_cen[i][0];
138 B_cen[1][i + dof] = gradphi_cen[i][1];
139 B_cen[2][i + 2 * dof] = gradphi_cen[i][2];
140 B_cen[3][i + dof] = gradphi_cen[i][2]; B_cen[3][i + 2 * dof] = gradphi_cen[i][1];
141 B_cen[4][i] = gradphi_cen[i][2]; B_cen[4][i + 2 * dof] = gradphi_cen[i][0];
142 B_cen[5][i] = gradphi_cen[i][1]; B_cen[5][i + dof] = gradphi_cen[i][0];
145 Dune::FieldVector<double,6> e_cen(0.0),s_cen(0.0);
147 Cijkl.mv(e_cen,s_cen);
149 s_cen -= appliedStress;
151 for(
int i = 0; i < dof; i++){
152 double maxUpdate = sqrt(xlc[i]*xlc[i]+xlc[i+dof]*xlc[i+dof]+xlc[i+2*dof]*xlc[i+2*dof]);
153 if(maxUpdate > maxDisp){ maxDisp = maxUpdate; }
157 dgf.evaluate(eg.entity(),pt,num_elem);
158 r.accumulate(lfsv1, iter, s[0]);
159 r.accumulate(lfsv2, iter, s[1] /num_elem[0]);
160 r.accumulate(lfsv3, iter, s_cen[2]/num_elem[0]);
161 r.accumulate(lfsv4, iter, s[3]);
162 r.accumulate(lfsv5, iter, s[4] /num_elem[0]);
163 r.accumulate(lfsv6, iter, s[5]);
170 Dune::FieldMatrix<double,6,6> getR(Dune::FieldMatrix<double,3,3> A)
const{
171 Dune::FieldMatrix<double,6,6> R;
172 R[0][0] = A[0][0]*A[0][0]; R[0][1] = A[0][1]*A[0][1]; R[0][2] = A[0][2]*A[0][2];
173 R[1][0] = A[1][0]*A[1][0]; R[1][1] = A[1][1]*A[1][1]; R[1][2] = A[1][2]*A[1][2];
174 R[2][0] = A[2][0]*A[2][0]; R[2][1] = A[2][1]*A[2][1]; R[2][2] = A[2][2]*A[2][2];
176 R[0][3] = 2.0*A[0][1]*A[0][2]; R[0][4] = 2.0*A[0][0]*A[0][2]; R[0][5] = 2.0*A[0][0]*A[0][1];
177 R[1][3] = 2.0*A[1][1]*A[1][2]; R[1][4] = 2.0*A[1][0]*A[1][2]; R[1][5] = 2.0*A[1][0]*A[1][1];
178 R[2][3] = 2.0*A[2][1]*A[2][2]; R[2][4] = 2.0*A[2][0]*A[2][2]; R[2][5] = 2.0*A[2][0]*A[2][1];
180 R[3][0] = A[1][0]*A[2][0]; R[3][1] = A[1][1]*A[2][1]; R[3][2] = A[1][2]*A[2][2];
181 R[4][0] = A[0][0]*A[2][0]; R[4][1] = A[0][1]*A[2][1]; R[4][2] = A[0][2]*A[2][2];
182 R[5][0] = A[0][0]*A[1][0]; R[5][1] = A[0][1]*A[1][1]; R[5][2] = A[0][2]*A[1][2];
184 R[3][3] = A[1][1]*A[2][2]+A[1][2]*A[2][1]; R[3][4] = A[1][0]*A[2][2]+A[1][2]*A[2][0]; R[3][5] = A[1][0]*A[2][1]+A[1][1]*A[2][0];
185 R[4][3] = A[0][1]*A[2][2]+A[2][1]*A[0][2]; R[4][4] = A[0][0]*A[2][2]+A[2][0]*A[0][2]; R[4][5] = A[2][0]*A[0][1]+A[2][1]*A[0][0];
186 R[5][3] = A[0][1]*A[1][2]+A[0][2]*A[1][1]; R[5][4] = A[0][0]*A[1][2]+A[0][2]*A[1][0]; R[5][5] = A[0][0]*A[1][1]+A[0][1]*A[1][0];
190 Dune::FieldMatrix<double,6,6> getMatrix(Dune::FieldMatrix<double,6,6> C, std::vector<double> theta)
const{
191 double c = cos(theta[1]*M_PI/180.0);
192 double s = sin(theta[1]*M_PI/180.0);
193 Dune::FieldMatrix<double,3,3> A = {{c,0,-s},{0,1,0},{s,0,c}};
195 Dune::FieldMatrix<double,6,6> R = getR(A);
198 Dune::FieldMatrix<double,6,6> RT(0.0);
199 Composites::transpose<Dune::FieldMatrix<double,6,6>,6>(R,RT);
200 Ch.rightmultiply(RT);
205 const PROBLEM& problem;
211 template<
typename GV,
typename MODEL,
int dofel>
213 public NumericalJacobianApplyVolume<getStress<GV,MODEL,dofel> >,
214 public FullVolumePattern,
215 public LocalOperatorDefaultFlags,
216 public InstationaryLocalOperatorDefaultMethods<double>,
217 public NumericalJacobianVolume<getStress<GV,MODEL, dofel> >
221 enum { doPatternVolume =
false };
224 enum { doAlphaVolume =
true };
227 getStress (
const GV& gv_,
const MODEL& model_) : gv(gv_), model(model_) {}
232 template<
typename EG,
typename LFSU,
typename X,
typename LFSV,
typename R>
233 void alpha_volume (
const EG& eg,
const LFSU& lfsu,
const X& x,
const LFSV& lfsv, R& r)
const
238 typedef typename LFSU::template Child<0>::Type LFS1;
239 typedef typename LFS1::Traits::FiniteElementType::Traits::LocalBasisType::Traits::DomainFieldType DF;
240 typedef typename LFS1::Traits::FiniteElementType::Traits::LocalBasisType::Traits::JacobianType JacobianType;
242 const auto& lfs1 = lfsu.template child<0>();
243 const auto& lfs2 = lfsu.template child<1>();
244 const auto& lfs3 = lfsu.template child<2>();
246 const auto& lfsv1 = lfsv.template child<0>();
247 const auto& lfsv2 = lfsv.template child<1>();
248 const auto& lfsv3 = lfsv.template child<2>();
249 const auto& lfsv4 = lfsv.template child<3>();
250 const auto& lfsv5 = lfsv.template child<4>();
251 const auto& lfsv6 = lfsv.template child<5>();
254 int id = gv.indexSet().index(eg.entity());
257 Dune::FieldMatrix<double,6,6> C = model.getElasticTensor(
id);
258 auto theta = model.returnTheta(eg.geometry().center());
259 auto Cthermal = model.TensorRotationRight(C,-theta[2],2);
261 int nodes_per_element = lfsv1.size();
262 int dof = lfs1.size();
265 Dune::FieldVector<double,6> delta(0.0);
266 model.evaluateHeat(delta,
id);
269 Dune::FieldVector<double,6> appliedStress(0.0);
270 Cthermal.mv(delta, appliedStress);
273 GeometryType gt = eg.geometry().type();
274 const QuadratureRule<DF,dim>& rule = QuadratureRules<DF,dim>::rule(gt,1);
275 for (
typename Dune::QuadratureRule<DF,dim>::const_iterator it = rule.begin(),endit = rule.end(); it != endit; ++it){
276 Dune::FieldVector<double,dim> pt = it->position();
277 Dune::FieldVector<DF,dim> local = eg.geometry().global(pt);
279 auto theta = model.returnTheta(local);
280 auto Cijkl = model.TensorRotationRight(C,theta[1],1);
283 std::vector<JacobianType> js(dof);
284 lfs1.finiteElement().localBasis().evaluateJacobian(pt,js);
287 const auto jac = eg.geometry().jacobianInverseTransposed(pt);
288 std::vector<Dune::FieldVector<double,dim> > gradphi(dof);
289 for (
int i=0; i < dof; i++){
291 jac.umv(js[i][0],gradphi[i]);
293 Dune::FieldMatrix<double,6,dofel> B(0.0);
294 for (
int i = 0; i < dof; i++)
296 B[0][i] = gradphi[i][0];
297 B[1][i + dof] = gradphi[i][1];
298 B[2][i + 2 * dof] = gradphi[i][2];
299 B[3][i + dof] = gradphi[i][2]; B[3][i + 2 * dof] = gradphi[i][1];
300 B[4][i] = gradphi[i][2]; B[4][i + 2 * dof] = gradphi[i][0];
301 B[5][i] = gradphi[i][1]; B[5][i + dof] = gradphi[i][0];
304 Dune::FieldVector<double,6> e(0.0),s(0.0);
305 Dune::FieldVector<double,dofel> xlc(0.0);
306 for(
int i = 0; i < dof; i++){
308 xlc[i+dof] = x(lfs2,i);
309 xlc[i+2*dof] = x(lfs3,i);
317 for (
int i = 0; i < nodes_per_element; i++){
318 r.accumulate(lfsv1, i, s[0] * it->weight());
319 r.accumulate(lfsv2, i, s[1] * it->weight());
320 r.accumulate(lfsv3, i, s[2] * it->weight());
321 r.accumulate(lfsv4, i, s[3] * it->weight());
322 r.accumulate(lfsv5, i, s[4] * it->weight());
323 r.accumulate(lfsv6, i, s[5] * it->weight());
333 public NumericalJacobianApplyVolume<countElem >,
334 public FullVolumePattern,
335 public LocalOperatorDefaultFlags,
336 public InstationaryLocalOperatorDefaultMethods<double>,
337 public NumericalJacobianVolume<countElem >
341 enum { doPatternVolume =
false };
344 enum { doLambdaVolume =
true };
350 template<
typename EG,
typename LFSV,
typename R>
351 void lambda_volume (
const EG& eg,
const LFSV& lfsv, R& r)
const
353 for (
int i = 0; i < lfsv.size(); i++){
354 r.accumulate(lfsv, i, 1.);
360 template<
typename GV,
typename PROBLEM,
typename DGF,
int dofel>
362 public NumericalJacobianApplyVolume<getStressUG<GV,PROBLEM,DGF,dofel> >,
363 public FullVolumePattern,
364 public LocalOperatorDefaultFlags,
365 public InstationaryLocalOperatorDefaultMethods<double>,
366 public NumericalJacobianVolume<getStressUG<GV,PROBLEM,DGF, dofel> >
370 enum { doPatternVolume =
false };
373 enum { doAlphaVolume =
true };
376 getStressUG (
const GV& gv_,
const PROBLEM& prob_,
const DGF& dgf_,
double& maxDisp_) : gv(gv_), problem(prob_) , maxDisp(maxDisp_), dgf(dgf_){}
381 template<
typename EG,
typename LFSU,
typename X,
typename LFSV,
typename R>
382 void alpha_volume (
const EG& eg,
const LFSU& lfsu,
const X& x,
const LFSV& lfsv, R& r)
const
387 typedef typename LFSU::template Child<0>::Type LFS1;
388 typedef typename LFS1::Traits::FiniteElementType::Traits::LocalBasisType::Traits::JacobianType JacobianType;
390 const auto& lfs1 = lfsu.template child<0>();
391 const auto& lfs2 = lfsu.template child<1>();
392 const auto& lfs3 = lfsu.template child<2>();
394 const auto& lfsv1 = lfsv.template child<0>();
395 const auto& lfsv2 = lfsv.template child<1>();
396 const auto& lfsv3 = lfsv.template child<2>();
397 const auto& lfsv4 = lfsv.template child<3>();
398 const auto& lfsv5 = lfsv.template child<4>();
399 const auto& lfsv6 = lfsv.template child<5>();
402 Dune::FieldMatrix<double,6,6> C(0.0),Cthermal(0.0);
403 problem.evaluate(eg.entity(),C);
404 problem.evaluate_strain(eg.entity(),Cthermal);
407 Dune::FieldVector<double,6> delta(0.0);
408 if(problem.getMaterialType(eg.entity()) == 0)
409 problem.evaluateHeat(delta,
true);
411 problem.evaluateHeat(delta,
false);
414 Dune::FieldVector<double,6> appliedStress(0.0);
415 Cthermal.mv(delta, appliedStress);
417 int nodes_per_element = lfsv1.size();
418 int dof = lfs1.size();
421 for (
int iter = 0; iter < nodes_per_element; iter++){
422 Dune::FieldVector<double,1> num_elem(1.0);
423 Dune::FieldVector<double,dim> pt = eg.geometry().local(eg.geometry().corner(iter));
425 auto theta = problem.getThetaFct(eg.entity(),pt);
426 auto Cijkl = getMatrix(C,theta);
429 std::vector<JacobianType> js(dof);
430 lfs1.finiteElement().localBasis().evaluateJacobian(pt,js);
433 const auto jac = eg.geometry().jacobianInverseTransposed(pt);
434 std::vector<Dune::FieldVector<double,dim> > gradphi(dof);
435 for (
int i=0; i < dof; i++){
437 jac.umv(js[i][0],gradphi[i]);
439 Dune::FieldMatrix<double,6,dofel> B(0.0);
440 for (
int i = 0; i < dof; i++)
442 B[0][i] = gradphi[i][0];
443 B[1][i + dof] = gradphi[i][1];
444 B[2][i + 2 * dof] = gradphi[i][2];
445 B[3][i + dof] = gradphi[i][2]; B[3][i + 2 * dof] = gradphi[i][1];
446 B[4][i] = gradphi[i][2]; B[4][i + 2 * dof] = gradphi[i][0];
447 B[5][i] = gradphi[i][1]; B[5][i + dof] = gradphi[i][0];
450 Dune::FieldVector<double,6> e(0.0),s(0.0);
451 Dune::FieldVector<double,dofel> xlc(0.0);
452 for(
int i = 0; i < dof; i++){
454 xlc[i+dof] = x(lfs2,i);
455 xlc[i+2*dof] = x(lfs3,i);
463 for(
int i = 0; i < dof; i++){
464 double maxUpdate = sqrt(xlc[i]*xlc[i]+xlc[i+dof]*xlc[i+dof]+xlc[i+2*dof]*xlc[i+2*dof]);
465 if(maxUpdate > maxDisp){ maxDisp = maxUpdate; }
469 dgf.evaluate(eg.entity(),pt,num_elem);
470 r.accumulate(lfsv1, iter, s[0]/num_elem[0]);
471 r.accumulate(lfsv2, iter, s[1]/num_elem[0]);
472 r.accumulate(lfsv3, iter, s[2]/num_elem[0]);
473 r.accumulate(lfsv4, iter, s[3]/num_elem[0]);
474 r.accumulate(lfsv5, iter, s[4]/num_elem[0]);
475 r.accumulate(lfsv6, iter, s[5]/num_elem[0]);
482 Dune::FieldMatrix<double,6,6> getR(Dune::FieldMatrix<double,3,3> A)
const{
483 Dune::FieldMatrix<double,6,6> R;
484 R[0][0] = A[0][0]*A[0][0]; R[0][1] = A[0][1]*A[0][1]; R[0][2] = A[0][2]*A[0][2];
485 R[1][0] = A[1][0]*A[1][0]; R[1][1] = A[1][1]*A[1][1]; R[1][2] = A[1][2]*A[1][2];
486 R[2][0] = A[2][0]*A[2][0]; R[2][1] = A[2][1]*A[2][1]; R[2][2] = A[2][2]*A[2][2];
488 R[0][3] = 2.0*A[0][1]*A[0][2]; R[0][4] = 2.0*A[0][0]*A[0][2]; R[0][5] = 2.0*A[0][0]*A[0][1];
489 R[1][3] = 2.0*A[1][1]*A[1][2]; R[1][4] = 2.0*A[1][0]*A[1][2]; R[1][5] = 2.0*A[1][0]*A[1][1];
490 R[2][3] = 2.0*A[2][1]*A[2][2]; R[2][4] = 2.0*A[2][0]*A[2][2]; R[2][5] = 2.0*A[2][0]*A[2][1];
492 R[3][0] = A[1][0]*A[2][0]; R[3][1] = A[1][1]*A[2][1]; R[3][2] = A[1][2]*A[2][2];
493 R[4][0] = A[0][0]*A[2][0]; R[4][1] = A[0][1]*A[2][1]; R[4][2] = A[0][2]*A[2][2];
494 R[5][0] = A[0][0]*A[1][0]; R[5][1] = A[0][1]*A[1][1]; R[5][2] = A[0][2]*A[1][2];
496 R[3][3] = A[1][1]*A[2][2]+A[1][2]*A[2][1]; R[3][4] = A[1][0]*A[2][2]+A[1][2]*A[2][0]; R[3][5] = A[1][0]*A[2][1]+A[1][1]*A[2][0];
497 R[4][3] = A[0][1]*A[2][2]+A[2][1]*A[0][2]; R[4][4] = A[0][0]*A[2][2]+A[2][0]*A[0][2]; R[4][5] = A[2][0]*A[0][1]+A[2][1]*A[0][0];
498 R[5][3] = A[0][1]*A[1][2]+A[0][2]*A[1][1]; R[5][4] = A[0][0]*A[1][2]+A[0][2]*A[1][0]; R[5][5] = A[0][0]*A[1][1]+A[0][1]*A[1][0];
502 Dune::FieldMatrix<double,6,6> getMatrix(Dune::FieldMatrix<double,6,6> C, std::vector<double> theta)
const{
503 double c = cos(theta[1]*M_PI/180.0);
504 double s = sin(theta[1]*M_PI/180.0);
505 Dune::FieldMatrix<double,3,3> A = {{c,0,-s},{0,1,0},{s,0,c}};
507 Dune::FieldMatrix<double,6,6> R = getR(A);
510 Dune::FieldMatrix<double,6,6> RT(0.0);
511 Composites::transpose<Dune::FieldMatrix<double,6,6>,6>(R,RT);
512 Ch.rightmultiply(RT);
517 const PROBLEM& problem;