MFEM v4.8.0
Finite element discretization library
Loading...
Searching...
No Matches
nonlininteg.cpp
Go to the documentation of this file.
1// Copyright (c) 2010-2025, Lawrence Livermore National Security, LLC. Produced
2// at the Lawrence Livermore National Laboratory. All Rights reserved. See files
3// LICENSE and NOTICE for details. LLNL-CODE-806117.
4//
5// This file is part of the MFEM library. For more information and source code
6// availability visit https://mfem.org.
7//
8// MFEM is free software; you can redistribute it and/or modify it under the
9// terms of the BSD-3 license. We welcome feedback and contributions, see file
10// CONTRIBUTING.md for details.
11
12#include "fem.hpp"
13#include "../general/forall.hpp"
14
15namespace mfem
16{
17
19{
20 mfem_error ("NonlinearFormIntegrator::GetLocalStateEnergyPA(...)\n"
21 " is not implemented for this class.");
22 return 0.0;
23}
24
26{
27 mfem_error ("NonlinearFormIntegrator::AssemblePA(...)\n"
28 " is not implemented for this class.");
29}
30
32 const FiniteElementSpace &)
33{
34 mfem_error ("NonlinearFormIntegrator::AssemblePA(...)\n"
35 " is not implemented for this class.");
36}
37
39 const FiniteElementSpace &fes)
40{
41 mfem_error ("NonlinearFormIntegrator::AssembleGradPA(...)\n"
42 " is not implemented for this class.");
43}
44
46{
47 mfem_error ("NonlinearFormIntegrator::AddMultPA(...)\n"
48 " is not implemented for this class.");
49}
50
52{
53 mfem_error ("NonlinearFormIntegrator::AddMultGradPA(...)\n"
54 " is not implemented for this class.");
55}
56
58{
59 mfem_error ("NonlinearFormIntegrator::AssembleGradDiagonalPA(...)\n"
60 " is not implemented for this class.");
61}
62
64{
65 mfem_error ("NonlinearFormIntegrator::AssembleMF(...)\n"
66 " is not implemented for this class.");
67}
68
70{
71 mfem_error ("NonlinearFormIntegrator::AddMultMF(...)\n"
72 " is not implemented for this class.");
73}
74
77 const Vector &elfun, Vector &elvect)
78{
79 mfem_error("NonlinearFormIntegrator::AssembleElementVector"
80 " is not overloaded!");
81}
82
84 const FiniteElement &el1, const FiniteElement &el2,
85 FaceElementTransformations &Tr, const Vector &elfun, Vector &elvect)
86{
87 mfem_error("NonlinearFormIntegrator::AssembleFaceVector"
88 " is not overloaded!");
89}
90
92 const FiniteElement &el, ElementTransformation &Tr, const Vector &elfun,
93 DenseMatrix &elmat)
94{
95 mfem_error("NonlinearFormIntegrator::AssembleElementGrad"
96 " is not overloaded!");
97}
98
100 const FiniteElement &el1, const FiniteElement &el2,
101 FaceElementTransformations &Tr, const Vector &elfun,
102 DenseMatrix &elmat)
103{
104 mfem_error("NonlinearFormIntegrator::AssembleFaceGrad"
105 " is not overloaded!");
106}
107
109 const FiniteElement &el, ElementTransformation &Tr, const Vector &elfun)
110{
111 mfem_error("NonlinearFormIntegrator::GetElementEnergy"
112 " is not overloaded!");
113 return 0.0;
114}
115
116
120 const Array<const Vector *> &elfun,
121 const Array<Vector *> &elvec)
122{
123 mfem_error("BlockNonlinearFormIntegrator::AssembleElementVector"
124 " is not overloaded!");
125}
126
131 const Array<const Vector *> &elfun,
132 const Array<Vector *> &elvect)
133{
134 mfem_error("BlockNonlinearFormIntegrator::AssembleFaceVector"
135 " is not overloaded!");
136}
137
141 const Array<const Vector *> &elfun,
142 const Array2D<DenseMatrix *> &elmats)
143{
144 mfem_error("BlockNonlinearFormIntegrator::AssembleElementGrad"
145 " is not overloaded!");
146}
147
152 const Array<const Vector *> &elfun,
153 const Array2D<DenseMatrix *> &elmats)
154{
155 mfem_error("BlockNonlinearFormIntegrator::AssembleFaceGrad"
156 " is not overloaded!");
157}
158
162 const Array<const Vector *>&elfun)
163{
164 mfem_error("BlockNonlinearFormIntegrator::GetElementEnergy"
165 " is not overloaded!");
166 return 0.0;
167}
168
169
171{
172 Z.SetSize(J.Width());
174 return 0.5*(Z*Z)/J.Det();
175}
176
178{
179 int dim = J.Width();
180 real_t t;
181
182 Z.SetSize(dim);
183 S.SetSize(dim);
185 MultAAt(Z, S);
186 t = 0.5*S.Trace();
187 for (int i = 0; i < dim; i++)
188 {
189 S(i,i) -= t;
190 }
191 t = J.Det();
192 S *= -1.0/(t*t);
193 Mult(S, Z, P);
194}
195
197 const DenseMatrix &J, const DenseMatrix &DS, const real_t weight,
198 DenseMatrix &A) const
199{
200 int dof = DS.Height(), dim = DS.Width();
201 real_t t;
202
203 Z.SetSize(dim);
204 S.SetSize(dim);
205 G.SetSize(dof, dim);
206 C.SetSize(dof, dim);
207
209 MultAAt(Z, S);
210
211 t = 1.0/J.Det();
212 Z *= t; // Z = J^{-t}
213 S *= t; // S = |J| (J.J^t)^{-1}
214 t = 0.5*S.Trace();
215
216 MultABt(DS, Z, G); // G = DS.J^{-1}
217 Mult(G, S, C);
218
219 // 1.
220 for (int i = 0; i < dof; i++)
221 for (int j = 0; j <= i; j++)
222 {
223 real_t a = 0.0;
224 for (int d = 0; d < dim; d++)
225 {
226 a += G(i,d)*G(j,d);
227 }
228 a *= weight;
229 for (int k = 0; k < dim; k++)
230 for (int l = 0; l <= k; l++)
231 {
232 real_t b = a*S(k,l);
233 A(i+k*dof,j+l*dof) += b;
234 if (i != j)
235 {
236 A(j+k*dof,i+l*dof) += b;
237 }
238 if (k != l)
239 {
240 A(i+l*dof,j+k*dof) += b;
241 if (i != j)
242 {
243 A(j+l*dof,i+k*dof) += b;
244 }
245 }
246 }
247 }
248
249 // 2.
250 for (int i = 1; i < dof; i++)
251 for (int j = 0; j < i; j++)
252 {
253 for (int k = 1; k < dim; k++)
254 for (int l = 0; l < k; l++)
255 {
256 real_t a =
257 weight*(C(i,l)*G(j,k) - C(i,k)*G(j,l) +
258 C(j,k)*G(i,l) - C(j,l)*G(i,k) +
259 t*(G(i,k)*G(j,l) - G(i,l)*G(j,k)));
260
261 A(i+k*dof,j+l*dof) += a;
262 A(j+l*dof,i+k*dof) += a;
263
264 A(i+l*dof,j+k*dof) -= a;
265 A(j+k*dof,i+l*dof) -= a;
266 }
267 }
268}
269
270
272{
273 mu = c_mu->Eval(*Ttr, Ttr->GetIntPoint());
274 K = c_K->Eval(*Ttr, Ttr->GetIntPoint());
275 if (c_g)
276 {
277 g = c_g->Eval(*Ttr, Ttr->GetIntPoint());
278 }
279}
280
282{
283 int dim = J.Width();
284
285 if (have_coeffs)
286 {
287 EvalCoeffs();
288 }
289
290 real_t dJ = J.Det();
291 real_t sJ = dJ/g;
292 real_t bI1 = pow(dJ, -2.0/dim)*(J*J); // \bar{I}_1
293
294 return 0.5*(mu*(bI1 - dim) + K*(sJ - 1.0)*(sJ - 1.0));
295}
296
298{
299 int dim = J.Width();
300
301 if (have_coeffs)
302 {
303 EvalCoeffs();
304 }
305
306 Z.SetSize(dim);
308
309 real_t dJ = J.Det();
310 real_t a = mu*pow(dJ, -2.0/dim);
311 real_t b = K*(dJ/g - 1.0)/g - a*(J*J)/(dim*dJ);
312
313 P = 0.0;
314 P.Add(a, J);
315 P.Add(b, Z);
316}
317
319 const real_t weight, DenseMatrix &A) const
320{
321 int dof = DS.Height(), dim = DS.Width();
322
323 if (have_coeffs)
324 {
325 EvalCoeffs();
326 }
327
328 Z.SetSize(dim);
329 G.SetSize(dof, dim);
330 C.SetSize(dof, dim);
331
332 real_t dJ = J.Det();
333 real_t sJ = dJ/g;
334 real_t a = mu*pow(dJ, -2.0/dim);
335 real_t bc = a*(J*J)/dim;
336 real_t b = bc - K*sJ*(sJ - 1.0);
337 real_t c = 2.0*bc/dim + K*sJ*(2.0*sJ - 1.0);
338
340 Z *= (1.0/dJ); // Z = J^{-t}
341
342 MultABt(DS, J, C); // C = DS J^t
343 MultABt(DS, Z, G); // G = DS J^{-1}
344
345 a *= weight;
346 b *= weight;
347 c *= weight;
348
349 // 1.
350 for (int i = 0; i < dof; i++)
351 for (int k = 0; k <= i; k++)
352 {
353 real_t s = 0.0;
354 for (int d = 0; d < dim; d++)
355 {
356 s += DS(i,d)*DS(k,d);
357 }
358 s *= a;
359
360 for (int d = 0; d < dim; d++)
361 {
362 A(i+d*dof,k+d*dof) += s;
363 }
364
365 if (k != i)
366 for (int d = 0; d < dim; d++)
367 {
368 A(k+d*dof,i+d*dof) += s;
369 }
370 }
371
372 a *= (-2.0/dim);
373
374 // 2.
375 for (int i = 0; i < dof; i++)
376 for (int j = 0; j < dim; j++)
377 for (int k = 0; k < dof; k++)
378 for (int l = 0; l < dim; l++)
379 {
380 A(i+j*dof,k+l*dof) +=
381 a*(C(i,j)*G(k,l) + G(i,j)*C(k,l)) +
382 b*G(i,l)*G(k,j) + c*G(i,j)*G(k,l);
383 }
384}
385
387 const FiniteElement& trial_fe, const FiniteElement& test_fe,
388 const ElementTransformation& trans) const
389{
390 return &(IntRules.Get(test_fe.GetGeomType(), 2*test_fe.GetOrder() + 3));
391}
392
395 const Vector &elfun)
396{
397 int dof = el.GetDof(), dim = el.GetDim();
398 real_t energy;
399
400 DSh.SetSize(dof, dim);
401 Jrt.SetSize(dim);
402 Jpr.SetSize(dim);
403 Jpt.SetSize(dim);
404 PMatI.UseExternalData(elfun.GetData(), dof, dim);
405
406 const IntegrationRule *ir = GetIntegrationRule(el, Ttr);
407
408 energy = 0.0;
409 model->SetTransformation(Ttr);
410 for (int i = 0; i < ir->GetNPoints(); i++)
411 {
412 const IntegrationPoint &ip = ir->IntPoint(i);
413 Ttr.SetIntPoint(&ip);
414 CalcInverse(Ttr.Jacobian(), Jrt);
415
416 el.CalcDShape(ip, DSh);
417 MultAtB(PMatI, DSh, Jpr);
418 Mult(Jpr, Jrt, Jpt);
419
420 energy += ip.weight * Ttr.Weight() * model->EvalW(Jpt);
421 }
422
423 return energy;
424}
425
427 const FiniteElement &el, ElementTransformation &Ttr,
428 const Vector &elfun, Vector &elvect)
429{
430 int dof = el.GetDof(), dim = el.GetDim();
431
432 DSh.SetSize(dof, dim);
433 DS.SetSize(dof, dim);
434 Jrt.SetSize(dim);
435 Jpt.SetSize(dim);
436 P.SetSize(dim);
437 PMatI.UseExternalData(elfun.GetData(), dof, dim);
438 elvect.SetSize(dof*dim);
439 PMatO.UseExternalData(elvect.GetData(), dof, dim);
440
441 const IntegrationRule *ir = GetIntegrationRule(el, Ttr);
442 if (!ir)
443 {
444 ir = &(IntRules.Get(el.GetGeomType(), 2*el.GetOrder() + 3)); // <---
445 }
446
447 elvect = 0.0;
448 model->SetTransformation(Ttr);
449 for (int i = 0; i < ir->GetNPoints(); i++)
450 {
451 const IntegrationPoint &ip = ir->IntPoint(i);
452 Ttr.SetIntPoint(&ip);
453 CalcInverse(Ttr.Jacobian(), Jrt);
454
455 el.CalcDShape(ip, DSh);
456 Mult(DSh, Jrt, DS);
457 MultAtB(PMatI, DS, Jpt);
458
459 model->EvalP(Jpt, P);
460
461 P *= ip.weight * Ttr.Weight();
462 AddMultABt(DS, P, PMatO);
463 }
464}
465
468 const Vector &elfun,
469 DenseMatrix &elmat)
470{
471 int dof = el.GetDof(), dim = el.GetDim();
472
473 DSh.SetSize(dof, dim);
474 DS.SetSize(dof, dim);
475 Jrt.SetSize(dim);
476 Jpt.SetSize(dim);
477 PMatI.UseExternalData(elfun.GetData(), dof, dim);
478 elmat.SetSize(dof*dim);
479
480 const IntegrationRule *ir = GetIntegrationRule(el, Ttr);
481 if (!ir)
482 {
483 ir = &(IntRules.Get(el.GetGeomType(), 2*el.GetOrder() + 3)); // <---
484 }
485
486 elmat = 0.0;
487 model->SetTransformation(Ttr);
488 for (int i = 0; i < ir->GetNPoints(); i++)
489 {
490 const IntegrationPoint &ip = ir->IntPoint(i);
491 Ttr.SetIntPoint(&ip);
492 CalcInverse(Ttr.Jacobian(), Jrt);
493
494 el.CalcDShape(ip, DSh);
495 Mult(DSh, Jrt, DS);
496 MultAtB(PMatI, DS, Jpt);
497
498 model->AssembleH(Jpt, DS, ip.weight * Ttr.Weight(), elmat);
499 }
500}
501
505 const Array<const Vector *>&elfun)
506{
507 if (el.Size() != 2)
508 {
509 mfem_error("IncompressibleNeoHookeanIntegrator::GetElementEnergy"
510 " has incorrect block finite element space size!");
511 }
512
513 int dof_u = el[0]->GetDof();
514 int dim = el[0]->GetDim();
515
516 DSh_u.SetSize(dof_u, dim);
517 J0i.SetSize(dim);
518 J1.SetSize(dim);
519 J.SetSize(dim);
520 PMatI_u.UseExternalData(elfun[0]->GetData(), dof_u, dim);
521
522 int intorder = 2*el[0]->GetOrder() + 3; // <---
523 const IntegrationRule &ir = IntRules.Get(el[0]->GetGeomType(), intorder);
524
525 real_t energy = 0.0;
526 real_t mu = 0.0;
527
528 for (int i = 0; i < ir.GetNPoints(); ++i)
529 {
530 const IntegrationPoint &ip = ir.IntPoint(i);
531 Tr.SetIntPoint(&ip);
532 CalcInverse(Tr.Jacobian(), J0i);
533
534 el[0]->CalcDShape(ip, DSh_u);
535 MultAtB(PMatI_u, DSh_u, J1);
536 Mult(J1, J0i, J);
537
538 mu = c_mu->Eval(Tr, ip);
539
540 energy += ip.weight*Tr.Weight()*(mu/2.0)*(J*J - 3);
541 }
542
543 return energy;
544}
545
549 const Array<const Vector *> &elfun,
550 const Array<Vector *> &elvec)
551{
552 if (el.Size() != 2)
553 {
554 mfem_error("IncompressibleNeoHookeanIntegrator::AssembleElementVector"
555 " has finite element space of incorrect block number");
556 }
557
558 int dof_u = el[0]->GetDof();
559 int dof_p = el[1]->GetDof();
560
561 int dim = el[0]->GetDim();
562 int spaceDim = Tr.GetSpaceDim();
563
564 if (dim != spaceDim)
565 {
566 mfem_error("IncompressibleNeoHookeanIntegrator::AssembleElementVector"
567 " is not defined on manifold meshes");
568 }
569
570
571 DSh_u.SetSize(dof_u, dim);
572 DS_u.SetSize(dof_u, dim);
573 J0i.SetSize(dim);
574 F.SetSize(dim);
575 FinvT.SetSize(dim);
576 P.SetSize(dim);
577 PMatI_u.UseExternalData(elfun[0]->GetData(), dof_u, dim);
578 elvec[0]->SetSize(dof_u*dim);
579 PMatO_u.UseExternalData(elvec[0]->GetData(), dof_u, dim);
580
581 Sh_p.SetSize(dof_p);
582 elvec[1]->SetSize(dof_p);
583
584 int intorder = 2*el[0]->GetOrder() + 3; // <---
585 const IntegrationRule &ir = IntRules.Get(el[0]->GetGeomType(), intorder);
586
587 *elvec[0] = 0.0;
588 *elvec[1] = 0.0;
589
590 for (int i = 0; i < ir.GetNPoints(); ++i)
591 {
592 const IntegrationPoint &ip = ir.IntPoint(i);
593 Tr.SetIntPoint(&ip);
594 CalcInverse(Tr.Jacobian(), J0i);
595
596 el[0]->CalcDShape(ip, DSh_u);
597 Mult(DSh_u, J0i, DS_u);
598 MultAtB(PMatI_u, DS_u, F);
599
600 el[1]->CalcShape(ip, Sh_p);
601
602 real_t pres = Sh_p * *elfun[1];
603 real_t mu = c_mu->Eval(Tr, ip);
604 real_t dJ = F.Det();
605
606 CalcInverseTranspose(F, FinvT);
607
608 P = 0.0;
609 P.Add(mu * dJ, F);
610 P.Add(-1.0 * pres * dJ, FinvT);
611 P *= ip.weight*Tr.Weight();
612
613 AddMultABt(DS_u, P, PMatO_u);
614
615 elvec[1]->Add(ip.weight * Tr.Weight() * (dJ - 1.0), Sh_p);
616 }
617
618}
619
623 const Array<const Vector *> &elfun,
624 const Array2D<DenseMatrix *> &elmats)
625{
626 int dof_u = el[0]->GetDof();
627 int dof_p = el[1]->GetDof();
628
629 int dim = el[0]->GetDim();
630
631 elmats(0,0)->SetSize(dof_u*dim, dof_u*dim);
632 elmats(0,1)->SetSize(dof_u*dim, dof_p);
633 elmats(1,0)->SetSize(dof_p, dof_u*dim);
634 elmats(1,1)->SetSize(dof_p, dof_p);
635
636 *elmats(0,0) = 0.0;
637 *elmats(0,1) = 0.0;
638 *elmats(1,0) = 0.0;
639 *elmats(1,1) = 0.0;
640
641 DSh_u.SetSize(dof_u, dim);
642 DS_u.SetSize(dof_u, dim);
643 J0i.SetSize(dim);
644 F.SetSize(dim);
645 FinvT.SetSize(dim);
646 Finv.SetSize(dim);
647 P.SetSize(dim);
648 PMatI_u.UseExternalData(elfun[0]->GetData(), dof_u, dim);
649 Sh_p.SetSize(dof_p);
650
651 int intorder = 2*el[0]->GetOrder() + 3; // <---
652 const IntegrationRule &ir = IntRules.Get(el[0]->GetGeomType(), intorder);
653
654 for (int i = 0; i < ir.GetNPoints(); ++i)
655 {
656 const IntegrationPoint &ip = ir.IntPoint(i);
657 Tr.SetIntPoint(&ip);
658 CalcInverse(Tr.Jacobian(), J0i);
659
660 el[0]->CalcDShape(ip, DSh_u);
661 Mult(DSh_u, J0i, DS_u);
662 MultAtB(PMatI_u, DS_u, F);
663
664 el[1]->CalcShape(ip, Sh_p);
665 real_t pres = Sh_p * *elfun[1];
666 real_t mu = c_mu->Eval(Tr, ip);
667 real_t dJ = F.Det();
668 real_t dJ_FinvT_DS;
669
670 CalcInverseTranspose(F, FinvT);
671
672 // u,u block
673 for (int i_u = 0; i_u < dof_u; ++i_u)
674 {
675 for (int i_dim = 0; i_dim < dim; ++i_dim)
676 {
677 for (int j_u = 0; j_u < dof_u; ++j_u)
678 {
679 for (int j_dim = 0; j_dim < dim; ++j_dim)
680 {
681
682 // m = j_dim;
683 // k = i_dim;
684
685 for (int n=0; n<dim; ++n)
686 {
687 for (int l=0; l<dim; ++l)
688 {
689 (*elmats(0,0))(i_u + i_dim*dof_u, j_u + j_dim*dof_u) +=
690 dJ * (mu * F(i_dim, l) - pres * FinvT(i_dim,l)) *
691 FinvT(j_dim,n) * DS_u(i_u,l) * DS_u(j_u, n) *
692 ip.weight * Tr.Weight();
693
694 if (j_dim == i_dim && n==l)
695 {
696 (*elmats(0,0))(i_u + i_dim*dof_u, j_u + j_dim*dof_u) +=
697 dJ * mu * DS_u(i_u, l) * DS_u(j_u,n) *
698 ip.weight * Tr.Weight();
699 }
700
701 // a = n;
702 // b = m;
703 (*elmats(0,0))(i_u + i_dim*dof_u, j_u + j_dim*dof_u) +=
704 dJ * pres * FinvT(i_dim, n) *
705 FinvT(j_dim,l) * DS_u(i_u,l) * DS_u(j_u,n) *
706 ip.weight * Tr.Weight();
707 }
708 }
709 }
710 }
711 }
712 }
713
714 // u,p and p,u blocks
715 for (int i_p = 0; i_p < dof_p; ++i_p)
716 {
717 for (int j_u = 0; j_u < dof_u; ++j_u)
718 {
719 for (int dim_u = 0; dim_u < dim; ++dim_u)
720 {
721 for (int l=0; l<dim; ++l)
722 {
723 dJ_FinvT_DS = dJ * FinvT(dim_u,l) * DS_u(j_u, l) * Sh_p(i_p) *
724 ip.weight * Tr.Weight();
725 (*elmats(1,0))(i_p, j_u + dof_u * dim_u) += dJ_FinvT_DS;
726 (*elmats(0,1))(j_u + dof_u * dim_u, i_p) -= dJ_FinvT_DS;
727
728 }
729 }
730 }
731 }
732 }
733
734}
735
736const IntegrationRule&
738 const ElementTransformation &T)
739{
740 const int order = 2 * fe.GetOrder() + T.OrderGrad(&fe);
741 return IntRules.Get(fe.GetGeomType(), order);
742}
743
745 const FiniteElement &el,
747 const Vector &elfun,
748 Vector &elvect)
749{
750 const int nd = el.GetDof();
751 dim = el.GetDim();
752
753 shape.SetSize(nd);
754 dshape.SetSize(nd, dim);
755 elvect.SetSize(nd * dim);
756 gradEF.SetSize(dim);
757
758 EF.UseExternalData(elfun.GetData(), nd, dim);
759 ELV.UseExternalData(elvect.GetData(), nd, dim);
760
761 Vector vec1(dim), vec2(dim);
762 const IntegrationRule *ir = GetIntegrationRule(el, T);
763 ELV = 0.0;
764 for (int i = 0; i < ir->GetNPoints(); i++)
765 {
766 const IntegrationPoint &ip = ir->IntPoint(i);
767 T.SetIntPoint(&ip);
768 el.CalcShape(ip, shape);
769 el.CalcPhysDShape(T, dshape);
770 real_t w = ip.weight * T.Weight();
771 if (Q) { w *= Q->Eval(T, ip); }
772
773 MultAtB(EF, dshape, gradEF);
774 EF.MultTranspose(shape, vec1);
775 gradEF.Mult(vec1, vec2);
776 vec2 *= w;
777 AddMultVWt(shape, vec2, ELV);
778 }
779}
780
782 const FiniteElement &el,
784 const Vector &elfun,
785 DenseMatrix &elmat)
786{
787 const int nd = el.GetDof();
788 dim = el.GetDim();
789
790 shape.SetSize(nd);
791 dshape.SetSize(nd, dim);
792 dshapex.SetSize(nd, dim);
793 elmat.SetSize(nd * dim);
794 elmat_comp.SetSize(nd);
795 gradEF.SetSize(dim);
796
797 EF.UseExternalData(elfun.GetData(), nd, dim);
798
799 real_t w;
800 Vector vec1(dim), vec2(dim), vec3(nd);
801
803
804 elmat = 0.0;
805 for (int i = 0; i < ir->GetNPoints(); i++)
806 {
807 const IntegrationPoint &ip = ir->IntPoint(i);
808 trans.SetIntPoint(&ip);
809
810 el.CalcShape(ip, shape);
811 el.CalcDShape(ip, dshape);
812
813 Mult(dshape, trans.InverseJacobian(), dshapex);
814
815 w = ip.weight;
816
817 if (Q)
818 {
819 w *= Q->Eval(trans, ip);
820 }
821
822 MultAtB(EF, dshapex, gradEF);
823 EF.MultTranspose(shape, vec1);
824
825 trans.AdjugateJacobian().Mult(vec1, vec2);
826
827 vec2 *= w;
828 dshape.Mult(vec2, vec3);
829 MultVWt(shape, vec3, elmat_comp);
830
831 for (int ii = 0; ii < dim; ii++)
832 {
833 elmat.AddMatrix(elmat_comp, ii * nd, ii * nd);
834 }
835
836 MultVVt(shape, elmat_comp);
837 w = ip.weight * trans.Weight();
838 if (Q)
839 {
840 w *= Q->Eval(trans, ip);
841 }
842 for (int ii = 0; ii < dim; ii++)
843 {
844 for (int jj = 0; jj < dim; jj++)
845 {
846 elmat.AddMatrix(w * gradEF(ii, jj), elmat_comp, ii * nd, jj * nd);
847 }
848 }
849 }
850}
851
852
854 const FiniteElement &el,
856 const Vector &elfun,
857 DenseMatrix &elmat)
858{
859 const int nd = el.GetDof();
860 const int dim = el.GetDim();
861
862 shape.SetSize(nd);
863 dshape.SetSize(nd, dim);
864 dshapex.SetSize(nd, dim);
865 elmat.SetSize(nd * dim);
866 elmat_comp.SetSize(nd);
867 gradEF.SetSize(dim);
868
869 EF.UseExternalData(elfun.GetData(), nd, dim);
870
871 Vector vec1(dim), vec2(dim), vec3(nd);
872
874
875 elmat = 0.0;
876 for (int i = 0; i < ir->GetNPoints(); i++)
877 {
878 const IntegrationPoint &ip = ir->IntPoint(i);
879 trans.SetIntPoint(&ip);
880
881 el.CalcShape(ip, shape);
882 el.CalcDShape(ip, dshape);
883
884 const real_t w = Q ? Q->Eval(trans, ip) * ip.weight : ip.weight;
885
886 EF.MultTranspose(shape, vec1); // u^n
887
888 trans.AdjugateJacobian().Mult(vec1, vec2);
889
890 vec2 *= w;
891 dshape.Mult(vec2, vec3); // (u^n \cdot grad u^{n+1})
892 MultVWt(shape, vec3, elmat_comp); // (u^n \cdot grad u^{n+1},v)
893
894 for (int ii = 0; ii < dim; ii++)
895 {
896 elmat.AddMatrix(elmat_comp, ii * nd, ii * nd);
897 }
898 }
899}
900
901
903 const FiniteElement &el,
905 const Vector &elfun,
906 DenseMatrix &elmat)
907{
908 const int nd = el.GetDof();
909 const int dim = el.GetDim();
910
911 shape.SetSize(nd);
912 dshape.SetSize(nd, dim);
913 dshapex.SetSize(nd, dim);
914 elmat.SetSize(nd * dim);
915 elmat_comp.SetSize(nd);
916 gradEF.SetSize(dim);
917
918 DenseMatrix elmat_comp_T(nd);
919
920 EF.UseExternalData(elfun.GetData(), nd, dim);
921
922 Vector vec1(dim), vec2(dim), vec3(nd), vec4(dim), vec5(nd);
923
925
926 elmat = 0.0;
927 elmat_comp_T = 0.0;
928 for (int i = 0; i < ir->GetNPoints(); i++)
929 {
930 const IntegrationPoint &ip = ir->IntPoint(i);
931 trans.SetIntPoint(&ip);
932
933 el.CalcShape(ip, shape);
934 el.CalcDShape(ip, dshape);
935
936 Mult(dshape, trans.InverseJacobian(), dshapex);
937
938 const real_t w = Q ? Q->Eval(trans, ip) * ip.weight : ip.weight;
939
940 EF.MultTranspose(shape, vec1); // u^n
941
942 trans.AdjugateJacobian().Mult(vec1, vec2);
943
944 vec2 *= w;
945 dshape.Mult(vec2, vec3); // (u^n \cdot grad u^{n+1})
946 MultVWt(shape, vec3, elmat_comp); // (u^n \cdot grad u^{n+1},v)
947 elmat_comp_T.Transpose(elmat_comp);
948
949 for (int ii = 0; ii < dim; ii++)
950 {
951 elmat.AddMatrix(.5, elmat_comp, ii * nd, ii * nd);
952 elmat.AddMatrix(-.5, elmat_comp_T, ii * nd, ii * nd);
953 }
954 }
955}
956
957}
Dynamic 2D array using row-major layout.
Definition array.hpp:392
void SetSize(int m, int n)
Definition array.hpp:405
void SetSize(int nsize)
Change the logical size of the array, keep existing entries.
Definition array.hpp:758
int Size() const
Return the logical size of the array.
Definition array.hpp:147
virtual real_t GetElementEnergy(const Array< const FiniteElement * > &el, ElementTransformation &Tr, const Array< const Vector * > &elfun)
Compute the local energy.
virtual void AssembleFaceVector(const Array< const FiniteElement * > &el1, const Array< const FiniteElement * > &el2, FaceElementTransformations &Tr, const Array< const Vector * > &elfun, const Array< Vector * > &elvect)
virtual void AssembleElementVector(const Array< const FiniteElement * > &el, ElementTransformation &Tr, const Array< const Vector * > &elfun, const Array< Vector * > &elvec)
Perform the local action of the BlockNonlinearFormIntegrator.
virtual void AssembleFaceGrad(const Array< const FiniteElement * > &el1, const Array< const FiniteElement * > &el2, FaceElementTransformations &Tr, const Array< const Vector * > &elfun, const Array2D< DenseMatrix * > &elmats)
virtual void AssembleElementGrad(const Array< const FiniteElement * > &el, ElementTransformation &Tr, const Array< const Vector * > &elfun, const Array2D< DenseMatrix * > &elmats)
Assemble the local gradient matrix.
virtual real_t Eval(ElementTransformation &T, const IntegrationPoint &ip)=0
Evaluate the coefficient in the element described by T at the point ip.
void AssembleElementGrad(const FiniteElement &el, ElementTransformation &trans, const Vector &elfun, DenseMatrix &elmat) override
Assemble the local gradient matrix.
Data type dense matrix using column-major storage.
Definition densemat.hpp:24
void Mult(const real_t *x, real_t *y) const
Matrix vector multiplication.
Definition densemat.cpp:125
void MultTranspose(const real_t *x, real_t *y) const
Multiply a vector with the transpose matrix.
Definition densemat.cpp:172
void Transpose()
(*this) = (*this)^t
void SetSize(int s)
Change the size of the DenseMatrix to s x s.
Definition densemat.hpp:108
real_t Trace() const
Trace of a square matrix.
Definition densemat.cpp:429
void AddMatrix(DenseMatrix &A, int ro, int co)
Perform (ro+i,co+j)+=A(i,j) for 0<=i.
void UseExternalData(real_t *d, int h, int w)
Change the data array and the size of the DenseMatrix.
Definition densemat.hpp:80
void Add(const real_t c, const DenseMatrix &A)
Adds the matrix A multiplied by the number c to the matrix.
Definition densemat.cpp:609
real_t Det() const
Definition densemat.cpp:516
virtual int OrderGrad(const FiniteElement *fe) const =0
Return the order of .
const IntegrationPoint & GetIntPoint()
Get a const reference to the currently set integration point. This will return NULL if no integration...
Definition eltrans.hpp:111
virtual int GetSpaceDim() const =0
Get the dimension of the target (physical) space.
real_t Weight()
Return the weight of the Jacobian matrix of the transformation at the currently set IntegrationPoint....
Definition eltrans.hpp:144
const DenseMatrix & Jacobian()
Return the Jacobian matrix of the transformation at the currently set IntegrationPoint,...
Definition eltrans.hpp:132
void SetIntPoint(const IntegrationPoint *ip)
Set the integration point ip that weights and Jacobians will be evaluated at.
Definition eltrans.hpp:106
A specialized ElementTransformation class representing a face and its two neighboring elements.
Definition eltrans.hpp:750
Class FiniteElementSpace - responsible for providing FEM view of the mesh, mainly managing the set of...
Definition fespace.hpp:244
Abstract class for all finite elements.
Definition fe_base.hpp:244
int GetOrder() const
Returns the order of the finite element. In the case of anisotropic orders, returns the maximum order...
Definition fe_base.hpp:338
void CalcPhysDShape(ElementTransformation &Trans, DenseMatrix &dshape) const
Evaluate the gradients of all shape functions of a scalar finite element in physical space at the poi...
Definition fe_base.cpp:192
int GetDim() const
Returns the reference space dimension for the finite element.
Definition fe_base.hpp:321
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const =0
Evaluate the gradients of all shape functions of a scalar finite element in reference space at the gi...
Geometry::Type GetGeomType() const
Returns the Geometry::Type of the reference element.
Definition fe_base.hpp:331
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const =0
Evaluate the values of all shape functions of a scalar finite element in reference space at the given...
int GetDof() const
Returns the number of degrees of freedom in the finite element.
Definition fe_base.hpp:334
virtual void AssembleH(const DenseMatrix &Jpt, const DenseMatrix &DS, const real_t weight, DenseMatrix &A) const =0
Evaluate the derivative of the 1st Piola-Kirchhoff stress tensor and assemble its contribution to the...
virtual real_t EvalW(const DenseMatrix &Jpt) const =0
Evaluate the strain energy density function, W = W(Jpt).
ElementTransformation * Ttr
virtual void EvalP(const DenseMatrix &Jpt, DenseMatrix &P) const =0
Evaluate the 1st Piola-Kirchhoff stress tensor, P = P(Jpt).
void SetTransformation(ElementTransformation &Ttr_)
void AssembleElementVector(const FiniteElement &el, ElementTransformation &Ttr, const Vector &elfun, Vector &elvect) override
Perform the local action of the NonlinearFormIntegrator.
real_t GetElementEnergy(const FiniteElement &el, ElementTransformation &Ttr, const Vector &elfun) override
Computes the integral of W(Jacobian(Trt)) over a target zone.
const IntegrationRule * GetDefaultIntegrationRule(const FiniteElement &trial_fe, const FiniteElement &test_fe, const ElementTransformation &trans) const override
Subclasses should override to choose a default integration rule.
void AssembleElementGrad(const FiniteElement &el, ElementTransformation &Ttr, const Vector &elfun, DenseMatrix &elmat) override
Assemble the local gradient matrix.
real_t GetElementEnergy(const Array< const FiniteElement * > &el, ElementTransformation &Tr, const Array< const Vector * > &elfun) override
Compute the local energy.
void AssembleElementVector(const Array< const FiniteElement * > &el, ElementTransformation &Tr, const Array< const Vector * > &elfun, const Array< Vector * > &elvec) override
Perform the local action of the NonlinearFormIntegrator.
void AssembleElementGrad(const Array< const FiniteElement * > &el, ElementTransformation &Tr, const Array< const Vector * > &elfun, const Array2D< DenseMatrix * > &elmats) override
Assemble the local gradient matrix.
Class for integration point with weight.
Definition intrules.hpp:35
Class for an integration rule - an Array of IntegrationPoint.
Definition intrules.hpp:100
int GetNPoints() const
Returns the number of the points in the integration rule.
Definition intrules.hpp:256
IntegrationPoint & IntPoint(int i)
Returns a reference to the i-th integration point.
Definition intrules.hpp:259
const IntegrationRule & Get(int GeomType, int Order)
Returns an integration rule for given GeomType and Order.
const IntegrationRule * GetIntegrationRule() const
Equivalent to GetIntRule, but retained for backward compatibility with applications.
void EvalP(const DenseMatrix &J, DenseMatrix &P) const override
Evaluate the 1st Piola-Kirchhoff stress tensor, P = P(Jpt).
void AssembleH(const DenseMatrix &J, const DenseMatrix &DS, const real_t weight, DenseMatrix &A) const override
Evaluate the derivative of the 1st Piola-Kirchhoff stress tensor and assemble its contribution to the...
real_t EvalW(const DenseMatrix &J) const override
Evaluate the strain energy density function, W = W(Jpt).
void AssembleH(const DenseMatrix &J, const DenseMatrix &DS, const real_t weight, DenseMatrix &A) const override
Evaluate the derivative of the 1st Piola-Kirchhoff stress tensor and assemble its contribution to the...
real_t EvalW(const DenseMatrix &J) const override
Evaluate the strain energy density function, W = W(Jpt).
void EvalP(const DenseMatrix &J, DenseMatrix &P) const override
Evaluate the 1st Piola-Kirchhoff stress tensor, P = P(Jpt).
virtual void AssembleElementVector(const FiniteElement &el, ElementTransformation &Tr, const Vector &elfun, Vector &elvect)
Perform the local action of the NonlinearFormIntegrator.
virtual real_t GetLocalStateEnergyPA(const Vector &x) const
Compute the local (to the MPI rank) energy with partial assembly.
virtual void AddMultMF(const Vector &x, Vector &y) const
virtual void AssembleMF(const FiniteElementSpace &fes)
Method defining fully unassembled operator.
virtual void AssembleGradPA(const Vector &x, const FiniteElementSpace &fes)
Prepare the integrator for partial assembly (PA) gradient evaluations on the given FE space fes at th...
virtual void AssemblePA(const FiniteElementSpace &fes)
Method defining partial assembly.
virtual void AssembleFaceGrad(const FiniteElement &el1, const FiniteElement &el2, FaceElementTransformations &Tr, const Vector &elfun, DenseMatrix &elmat)
Assemble the local action of the gradient of the NonlinearFormIntegrator resulting from a face integr...
virtual void AssembleGradDiagonalPA(Vector &diag) const
Method for computing the diagonal of the gradient with partial assembly.
virtual void AssembleElementGrad(const FiniteElement &el, ElementTransformation &Tr, const Vector &elfun, DenseMatrix &elmat)
Assemble the local gradient matrix.
virtual void AssembleFaceVector(const FiniteElement &el1, const FiniteElement &el2, FaceElementTransformations &Tr, const Vector &elfun, Vector &elvect)
Perform the local action of the NonlinearFormIntegrator resulting from a face integral term.
virtual void AddMultPA(const Vector &x, Vector &y) const
Method for partially assembled action.
virtual void AddMultGradPA(const Vector &x, Vector &y) const
Method for partially assembled gradient action.
virtual real_t GetElementEnergy(const FiniteElement &el, ElementTransformation &Tr, const Vector &elfun)
Compute the local energy.
int Height() const
Get the height (size of output) of the Operator. Synonym with NumRows().
Definition operator.hpp:66
int Width() const
Get the width (size of input) of the Operator. Synonym with NumCols().
Definition operator.hpp:72
void AssembleElementGrad(const FiniteElement &el, ElementTransformation &trans, const Vector &elfun, DenseMatrix &elmat) override
Assemble the local gradient matrix.
void AssembleElementVector(const FiniteElement &el, ElementTransformation &trans, const Vector &elfun, Vector &elvect) override
Perform the local action of the NonlinearFormIntegrator.
void AssembleElementGrad(const FiniteElement &el, ElementTransformation &trans, const Vector &elfun, DenseMatrix &elmat) override
Assemble the local gradient matrix.
static const IntegrationRule & GetRule(const FiniteElement &fe, const ElementTransformation &T)
Vector data type.
Definition vector.hpp:82
void SetSize(int s)
Resize the vector to size s.
Definition vector.hpp:558
real_t * GetData() const
Return a pointer to the beginning of the Vector data.
Definition vector.hpp:235
int dim
Definition ex24.cpp:53
real_t mu
Definition ex25.cpp:140
void trans(const Vector &u, Vector &x)
Definition ex27.cpp:412
real_t b
Definition lissajous.cpp:42
real_t a
Definition lissajous.cpp:41
void mfem_error(const char *msg)
Definition error.cpp:154
void Mult(const Table &A, const Table &B, Table &C)
C = A * B (as boolean matrices)
Definition table.cpp:548
void CalcAdjugateTranspose(const DenseMatrix &a, DenseMatrix &adjat)
Calculate the transposed adjugate of a matrix (for NxN matrices, N=1,2,3)
void MultVWt(const Vector &v, const Vector &w, DenseMatrix &VWt)
void MultABt(const DenseMatrix &A, const DenseMatrix &B, DenseMatrix &ABt)
Multiply a matrix A with the transpose of a matrix B: A*Bt.
void CalcInverse(const DenseMatrix &a, DenseMatrix &inva)
void AddMultVWt(const Vector &v, const Vector &w, DenseMatrix &VWt)
VWt += v w^t.
void MultVVt(const Vector &v, DenseMatrix &vvt)
Make a matrix from a vector V.Vt.
void AddMultABt(const DenseMatrix &A, const DenseMatrix &B, DenseMatrix &ABt)
ABt += A * B^t.
void MultAAt(const DenseMatrix &a, DenseMatrix &aat)
Calculate the matrix A.At.
void CalcInverseTranspose(const DenseMatrix &a, DenseMatrix &inva)
Calculate the inverse transpose of a matrix (for NxN matrices, N=1,2,3)
ComplexDenseMatrix * MultAtB(const ComplexDenseMatrix &A, const ComplexDenseMatrix &B)
Multiply the complex conjugate transpose of a matrix A with a matrix B. A^H*B.
float real_t
Definition config.hpp:43
IntegrationRules IntRules(0, Quadrature1D::GaussLegendre)
A global object with all integration rules (defined in intrules.cpp)
Definition intrules.hpp:492