330{
331
332
333
334
335
336#if defined(LIBMESH_HAVE_EIGEN) && defined(LIBMESH_ENABLE_SECOND_DERIVATIVES)
337
338
339 libmesh_assert_equal_to (system_name, "Shell");
340
341
344
345
347
348
353 const bool distributed_load = es.
parameters.
get<
bool> (
"distributed load");
354
355
357 Hm <<
358 1., nu, 0.,
359 nu, 1., 0.,
360 0., 0., 0.5 * (1-nu);
361 Hm *= h * E/(1-nu*nu);
362
363
365 Hf <<
366 1., nu, 0.,
367 nu, 1., 0.,
368 0., 0., 0.5 * (1-nu);
369 Hf *= h*h*h/12 * E/(1-nu*nu);
370
371
373 Hc0 *= h * 5./6*E/(2*(1+nu));
374
376 Hc1 *= h*h*h/12 * 5./6*E/(2*(1+nu));
377
378
379
381
384 fe->attach_quadrature_rule (&qrule);
385
386
387 const std::vector<Real> & JxW = fe->get_JxW();
388
389
390
391 const std::vector<RealGradient> & dxyzdxi = fe->get_dxyzdxi();
392 const std::vector<RealGradient> & dxyzdeta = fe->get_dxyzdeta();
393
394 const std::vector<RealGradient> & d2xyzdxi2 = fe->get_d2xyzdxi2();
395 const std::vector<RealGradient> & d2xyzdeta2 = fe->get_d2xyzdeta2();
396 const std::vector<RealGradient> & d2xyzdxideta = fe->get_d2xyzdxideta();
397 const std::vector<std::vector<Real>> & dphidxi = fe->get_dphidxi();
398 const std::vector<std::vector<Real>> & dphideta = fe->get_dphideta();
399 const std::vector<std::vector<Real>> & phi = fe->get_phi();
400
401
402
403
405
406
408
409
412 {
425 };
426
427
430
431 std::vector<dof_id_type> dof_indices;
432 std::vector<std::vector<dof_id_type>> dof_indices_var(6);
433
434
435
436 for (
const auto & elem :
mesh.active_local_element_ptr_range())
437 {
439 for (unsigned int var=0; var<6; var++)
440 dof_map.
dof_indices (elem, dof_indices_var[var], var);
441
442 const unsigned int n_dofs = dof_indices.size();
443 const unsigned int n_var_dofs = dof_indices_var[0].size();
444
445
446 std::vector<Point> nodes;
447 for (auto i : elem->node_index_range())
448 nodes.push_back(elem->reference_elem()->node_ref(i));
449 fe->reinit (elem, &nodes);
450
451
452 MyVector3d X1(elem->node_ref(0)(0), elem->node_ref(0)(1), elem->node_ref(0)(2));
453 MyVector3d X2(elem->node_ref(1)(0), elem->node_ref(1)(1), elem->node_ref(1)(2));
454 MyVector3d X3(elem->node_ref(2)(0), elem->node_ref(2)(1), elem->node_ref(2)(2));
455 MyVector3d X4(elem->node_ref(3)(0), elem->node_ref(3)(1), elem->node_ref(3)(2));
456
457
458 std::vector<MyMatrix3d> F0node;
459 std::vector<MyMatrix3d> Qnode;
460 for (auto i : elem->node_index_range())
461 {
463 a1 << dxyzdxi[i](0), dxyzdxi[i](1), dxyzdxi[i](2);
465 a2 << dxyzdeta[i](0), dxyzdeta[i](1), dxyzdeta[i](2);
467 n = a1.cross(a2);
468 n /= n.norm();
471 a1(0), a2(0), n(0),
472 a1(1), a2(1), n(1),
473 a1(2), a2(2), n(2);
474 F0node.push_back(
F0);
475
479 if (std::abs(1.+C)<1e-6)
480 {
482 Q <<
483 1, 0, 0,
484 0, -1, 0,
485 0, 0, -1;
486 Qnode.push_back(Q);
487 }
488 else
489 {
491 Q <<
492 C+1./(1+C)*ny*ny, -1./(1+C)*nx*ny, nx,
493 -1./(1+C)*nx*ny, C+1./(1+C)*nx*nx, ny,
494 -nx, -ny, C;
495 Qnode.push_back(Q);
496 }
497 }
498
499 Ke.
resize (n_dofs, n_dofs);
500 for (unsigned int var_i=0; var_i<6; var_i++)
501 for (unsigned int var_j=0; var_j<6; var_j++)
502 Ke_var[var_i][var_j].reposition (var_i*n_var_dofs, var_j*n_var_dofs, n_var_dofs, n_var_dofs);
503
505 Fe_w.reposition(2*n_var_dofs,n_var_dofs);
506
507
508 fe->reinit (elem);
509
510
511 for (unsigned int qp=0; qp<qrule.n_points(); ++qp)
512 {
513
514
516 a1 << dxyzdxi[qp](0), dxyzdxi[qp](1), dxyzdxi[qp](2);
518 a2 << dxyzdeta[qp](0), dxyzdeta[qp](1), dxyzdeta[qp](2);
520 n = a1.cross(a2);
521 n /= n.norm();
524 a1(0), a2(0), n(0),
525 a1(1), a2(1), n(1),
526 a1(2), a2(2), n(2);
527
528
530 F0it =
F0.inverse().transpose();
531
532
537 if (std::abs(1.+C) < 1e-6)
538 {
539 Q <<
540 1, 0, 0,
541 0, -1, 0,
542 0, 0, -1;
543 }
544 else
545 {
546 Q <<
547 C+1./(1+C)*ny*ny, -1./(1+C)*nx*ny, nx,
548 -1./(1+C)*nx*ny, C+1./(1+C)*nx*nx, ny,
549 -nx, -ny, C;
550 }
551
553 C0 = F0it.block<3,2>(0,0).transpose()*Q.block<3,2>(0,0);
554
555
556 MyVector3d d2Xdxi2(d2xyzdxi2[qp](0), d2xyzdxi2[qp](1), d2xyzdxi2[qp](2));
557 MyVector3d d2Xdeta2(d2xyzdeta2[qp](0), d2xyzdeta2[qp](1), d2xyzdeta2[qp](2));
558 MyVector3d d2Xdxideta(d2xyzdxideta[qp](0), d2xyzdxideta[qp](1), d2xyzdxideta[qp](2));
559
560
563 n.dot(d2Xdxi2), n.dot(d2Xdxideta),
564 n.dot(d2Xdxideta), n.dot(d2Xdeta2);
565
566 MyVector3d dndxi = -
b(0,0)*F0it.col(0) -
b(0,1)*F0it.col(1);
567 MyVector3d dndeta = -
b(1,0)*F0it.col(0) -
b(1,1)*F0it.col(1);
568
570 bhat <<
571 F0it.col(1).dot(dndeta), -F0it.col(0).dot(dndeta),
572 -F0it.col(1).dot(dndxi), F0it.col(0).dot(dndxi);
573
575 bc = bhat*C0;
576
577
578 Real H = 0.5*(dndxi.dot(F0it.col(0))+dndeta.dot(F0it.col(1)));
579
580
581 Real xi = qrule.qp(qp)(0);
582 Real eta = qrule.qp(qp)(1);
583
584
585
586
587
588
589
590
591
592 MyVector3d nA1 = 0.5*(Qnode[0].col(2)+Qnode[1].col(2));
593 nA1 /= nA1.norm();
594 nA1 *= (1-eta)/4;
595 MyVector3d nB2 = 0.5*(Qnode[1].col(2)+Qnode[2].col(2));
596 nB2 /= nB2.norm();
597 nB2 *= (1+xi)/4;
598 MyVector3d nA2 = 0.5*(Qnode[2].col(2)+Qnode[3].col(2));
599 nA2 /= nA2.norm();
600 nA2 *= (1+eta)/4;
601 MyVector3d nB1 = 0.5*(Qnode[3].col(2)+Qnode[0].col(2));
602 nB1 /= nB1.norm();
603 nB1 *= (1-xi)/4;
604
605
610
611
612 MyVector2d AS1A1(-aA1.dot(Qnode[0].col(1)), aA1.dot(Qnode[0].col(0)));
613 MyVector2d AS2A1(-aA1.dot(Qnode[1].col(1)), aA1.dot(Qnode[1].col(0)));
614 AS1A1 *= (1-eta)/4;
615 AS2A1 *= (1-eta)/4;
616
617 MyVector2d AS1A2(-aA2.dot(Qnode[3].col(1)), aA2.dot(Qnode[3].col(0)));
618 MyVector2d AS2A2(-aA2.dot(Qnode[2].col(1)), aA2.dot(Qnode[2].col(0)));
619 AS1A2 *= (1+eta)/4;
620 AS2A2 *= (1+eta)/4;
621
622 MyVector2d AS1B1(-aB1.dot(Qnode[0].col(1)), aB1.dot(Qnode[0].col(0)));
623 MyVector2d AS2B1(-aB1.dot(Qnode[3].col(1)), aB1.dot(Qnode[3].col(0)));
624 AS1B1 *= (1-xi)/4;
625 AS2B1 *= (1-xi)/4;
626
627 MyVector2d AS1B2(-aB2.dot(Qnode[1].col(1)), aB2.dot(Qnode[1].col(0)));
628 MyVector2d AS2B2(-aB2.dot(Qnode[2].col(1)), aB2.dot(Qnode[2].col(0)));
629 AS1B2 *= (1+xi)/4;
630 AS2B2 *= (1+xi)/4;
631
632
633 std::vector<MyMatrixXd> Bcnode;
635
636 Bc.block<1,3>(0,0) = -nA1.transpose();
637 Bc.block<1,2>(0,3) = AS1A1.transpose();
638 Bc.block<1,3>(1,0) = -nB1.transpose();
639 Bc.block<1,2>(1,3) = AS1B1.transpose();
640 Bcnode.push_back(Bc);
641
642 Bc.block<1,3>(0,0) = nA1.transpose();
643 Bc.block<1,2>(0,3) = AS2A1.transpose();
644 Bc.block<1,3>(1,0) = -nB2.transpose();
645 Bc.block<1,2>(1,3) = AS1B2.transpose();
646 Bcnode.push_back(Bc);
647
648 Bc.block<1,3>(0,0) = nA2.transpose();
649 Bc.block<1,2>(0,3) = AS2A2.transpose();
650 Bc.block<1,3>(1,0) = nB2.transpose();
651 Bc.block<1,2>(1,3) = AS2B2.transpose();
652 Bcnode.push_back(Bc);
653
654 Bc.block<1,3>(0,0) = -nA2.transpose();
655 Bc.block<1,2>(0,3) = AS1A2.transpose();
656 Bc.block<1,3>(1,0) = nB1.transpose();
657 Bc.block<1,2>(1,3) = AS2B1.transpose();
658 Bcnode.push_back(Bc);
659
660
661 for (unsigned int i=0; i<n_var_dofs; ++i)
662 {
663
664 Real C1i = dphidxi[i][qp]*C0(0,0) + dphideta[i][qp]*C0(1,0);
665 Real C2i = dphidxi[i][qp]*C0(0,1) + dphideta[i][qp]*C0(1,1);
666
668 B0I = MyMatrixXd::Zero(3, 5);
669 B0I.block<1,3>(0,0) = C1i*Q.col(0).transpose();
670 B0I.block<1,3>(1,0) = C2i*Q.col(1).transpose();
671 B0I.block<1,3>(2,0) = C2i*Q.col(0).transpose()+C1i*Q.col(1).transpose();
672
673
674 Real bc1i = dphidxi[i][qp]*bc(0,0) + dphideta[i][qp]*bc(1,0);
675 Real bc2i = dphidxi[i][qp]*bc(0,1) + dphideta[i][qp]*bc(1,1);
676
677 MyVector2d V1i(-Q.col(0).dot(Qnode[i].col(1)),
678 Q.col(0).dot(Qnode[i].col(0)));
679
680 MyVector2d V2i(-Q.col(1).dot(Qnode[i].col(1)),
681 Q.col(1).dot(Qnode[i].col(0)));
682
684 B1I = MyMatrixXd::Zero(3,5);
685 B1I.block<1,3>(0,0) = bc1i*Q.col(0).transpose();
686 B1I.block<1,3>(1,0) = bc2i*Q.col(1).transpose();
687 B1I.block<1,3>(2,0) = bc2i*Q.col(0).transpose()+bc1i*Q.col(1).transpose();
688
689 B1I.block<1,2>(0,3) = C1i*V1i.transpose();
690 B1I.block<1,2>(1,3) = C2i*V2i.transpose();
691 B1I.block<1,2>(2,3) = C2i*V1i.transpose()+C1i*V2i.transpose();
692
693
695 B2I = MyMatrixXd::Zero(3,5);
696
697 B2I.block<1,2>(0,3) = bc1i*V1i.transpose();
698 B2I.block<1,2>(1,3) = bc2i*V2i.transpose();
699 B2I.block<1,2>(2,3) = bc2i*V1i.transpose()+bc1i*V2i.transpose();
700
701
703 Bc0I = C0.transpose()*Bcnode[i];
704
705
707 Bc1I = bc.transpose()*Bcnode[i];
708
709
710 MyVector2d BdxiI(dphidxi[i][qp],dphideta[i][qp]);
712
713 for (unsigned int j=0; j<n_var_dofs; ++j)
714 {
715
716
717 Real C1j = dphidxi[j][qp]*C0(0,0) + dphideta[j][qp]*C0(1,0);
718 Real C2j = dphidxi[j][qp]*C0(0,1) + dphideta[j][qp]*C0(1,1);
719
721 B0J = MyMatrixXd::Zero(3,5);
722 B0J.block<1,3>(0,0) = C1j*Q.col(0).transpose();
723 B0J.block<1,3>(1,0) = C2j*Q.col(1).transpose();
724 B0J.block<1,3>(2,0) = C2j*Q.col(0).transpose()+C1j*Q.col(1).transpose();
725
726
727 Real bc1j = dphidxi[j][qp]*bc(0,0) + dphideta[j][qp]*bc(1,0);
728 Real bc2j = dphidxi[j][qp]*bc(0,1) + dphideta[j][qp]*bc(1,1);
729
730 MyVector2d V1j(-Q.col(0).dot(Qnode[j].col(1)),
731 Q.col(0).dot(Qnode[j].col(0)));
732
733 MyVector2d V2j(-Q.col(1).dot(Qnode[j].col(1)),
734 Q.col(1).dot(Qnode[j].col(0)));
735
737 B1J = MyMatrixXd::Zero(3,5);
738 B1J.block<1,3>(0,0) = bc1j*Q.col(0).transpose();
739 B1J.block<1,3>(1,0) = bc2j*Q.col(1).transpose();
740 B1J.block<1,3>(2,0) = bc2j*Q.col(0).transpose()+bc1j*Q.col(1).transpose();
741
742 B1J.block<1,2>(0,3) = C1j*V1j.transpose();
743 B1J.block<1,2>(1,3) = C2j*V2j.transpose();
744 B1J.block<1,2>(2,3) = C2j*V1j.transpose()+C1j*V2j.transpose();
745
746
748 B2J = MyMatrixXd::Zero(3,5);
749
750 B2J.block<1,2>(0,3) = bc1j*V1j.transpose();
751 B2J.block<1,2>(1,3) = bc2j*V2j.transpose();
752 B2J.block<1,2>(2,3) = bc2j*V1j.transpose()+bc1j*V2j.transpose();
753
754
756 Bc0J = C0.transpose()*Bcnode[j];
757
758
760 Bc1J = bc.transpose()*Bcnode[j];
761
762
763 MyVector2d BdxiJ(dphidxi[j][qp], dphideta[j][qp]);
765
766
767
769 local_KIJ = JxW[qp] * (
770 B0I.transpose() * Hm * B0J
771 + B2I.transpose() * Hf * B0J
772 + B0I.transpose() * Hf * B2J
773 + B1I.transpose() * Hf * B1J
774 + 2*H * B0I.transpose() * Hf * B1J
775 + 2*H * B1I.transpose() * Hf * B0J
776 + Bc0I.transpose() * Hc0 * Bc0J
777 + Bc1I.transpose() * Hc1 * Bc1J
778 + 2*H * Bc0I.transpose() * Hc1 * Bc1J
779 + 2*H * Bc1I.transpose() * Hc1 * Bc0J
780 );
781
782
784 full_local_KIJ = MyMatrixXd::Zero(6, 6);
785 full_local_KIJ.block<5,5>(0,0)=local_KIJ;
786
787
788
789
790
791
792
793
794
795
796 full_local_KIJ(5,5) =
Real(Hf(0,0)*JxW[qp]*BdI.transpose()*BdJ);
797
798
801 TI = MyMatrixXd::Identity(6,6);
802 TI.block<3,3>(3,3) = Qnode[i].transpose();
804 TJ = MyMatrixXd::Identity(6,6);
805 TJ.block<3,3>(3,3) = Qnode[j].transpose();
806 global_KIJ = TI.transpose()*full_local_KIJ*TJ;
807
808
809
810
811 for (unsigned int k=0;k<6;k++)
812 for (unsigned int l=0;l<6;l++)
813 Ke_var[k][l](i,j) += global_KIJ(k,l);
814 }
815 }
816
817 }
818
819 if (distributed_load)
820 {
821
822 for (unsigned int shellface=0; shellface<2; shellface++)
823 {
824 std::vector<boundary_id_type> bids;
826
827 for (std::size_t k=0; k<bids.size(); k++)
828 if (bids[k]==11)
829 for (unsigned int qp=0; qp<qrule.n_points(); ++qp)
830 for (unsigned int i=0; i<n_var_dofs; ++i)
831 Fe_w(i) -= JxW[qp] * phi[i][qp];
832 }
833 }
834
835
836
837
839
842
843 }
844
845 if (!distributed_load)
846 {
847
848
849
851
852
854
855 for (
const auto & node :
mesh.node_ptr_range())
856 if (((*node) - C).
norm() < 1e-3)
857 system.rhs->set(node->dof_number(0, 2, 0), -q/4);
858 }
859
860#else
861
863#endif
864}
void shellface_boundary_ids(const Elem *const elem, const unsigned short int shellface, std::vector< boundary_id_type > &vec_to_fill) const
void constrain_element_matrix_and_vector(DenseMatrix< Number > &matrix, DenseVector< Number > &rhs, std::vector< dof_id_type > &elem_dofs, bool asymmetric_constraint_rows=true) const
Constrains the element matrix and vector.
Order default_quadrature_order() const
const BoundaryInfo & get_boundary_info() const
The information about boundary ids on the mesh.
unsigned int mesh_dimension() const
virtual void close()=0
Calls the NumericVector's internal assembly routines, ensuring that the values are consistent across ...
A Point defines a location in LIBMESH_DIM dimensional Real space.
This class implements specific orders of Gauss quadrature.
Eigen::Matrix< libMesh::Real, 3, 1 > MyVector3d
Eigen::Matrix< libMesh::Real, 3, 3 > MyMatrix3d
Eigen::Matrix< libMesh::Real, 2, 2 > MyMatrix2d
Eigen::Matrix< libMesh::Real, Eigen::Dynamic, Eigen::Dynamic > MyMatrixXd
Eigen::Matrix< libMesh::Real, 2, 1 > MyVector2d
void libmesh_ignore(const Args &...)