327{
328
329
330#if defined(LIBMESH_HAVE_EIGEN) && defined(LIBMESH_ENABLE_SECOND_DERIVATIVES)
331
332
333 libmesh_assert_equal_to (system_name, "Shell");
334
335
338
339
341
342
347 const bool distributed_load = es.
parameters.
get<
bool> (
"distributed load");
348
349
351 Hm <<
352 1., nu, 0.,
353 nu, 1., 0.,
354 0., 0., 0.5 * (1-nu);
355 Hm *= h * E/(1-nu*nu);
356
357
359 Hf <<
360 1., nu, 0.,
361 nu, 1., 0.,
362 0., 0., 0.5 * (1-nu);
363 Hf *= h*h*h/12 * E/(1-nu*nu);
364
365
367 Hc0 *= h * 5./6*E/(2*(1+nu));
368
370 Hc1 *= h*h*h/12 * 5./6*E/(2*(1+nu));
371
372
373
375
378 fe->attach_quadrature_rule (&qrule);
379
380
381 const std::vector<Real> & JxW = fe->get_JxW();
382
383
384
385 const std::vector<RealGradient> & dxyzdxi = fe->get_dxyzdxi();
386 const std::vector<RealGradient> & dxyzdeta = fe->get_dxyzdeta();
387 const std::vector<RealGradient> & d2xyzdxi2 = fe->get_d2xyzdxi2();
388 const std::vector<RealGradient> & d2xyzdeta2 = fe->get_d2xyzdeta2();
389 const std::vector<RealGradient> & d2xyzdxideta = fe->get_d2xyzdxideta();
390 const std::vector<std::vector<Real>> & dphidxi = fe->get_dphidxi();
391 const std::vector<std::vector<Real>> & dphideta = fe->get_dphideta();
392 const std::vector<std::vector<Real>> & phi = fe->get_phi();
393
394
395
396
398
399
401
402
405 {
418 };
419
420
423
424 std::vector<dof_id_type> dof_indices;
425 std::vector<std::vector<dof_id_type>> dof_indices_var(6);
426
427
428
429 for (
const auto & elem :
mesh.active_local_element_ptr_range())
430 {
432 for (unsigned int var=0; var<6; var++)
433 dof_map.
dof_indices (elem, dof_indices_var[var], var);
434
435 const unsigned int n_dofs = dof_indices.size();
436 const unsigned int n_var_dofs = dof_indices_var[0].size();
437
438
439 std::vector<Point> nodes;
440 for (unsigned int i=0; i<elem->n_nodes(); ++i)
441 nodes.push_back(elem->reference_elem()->node_ref(i));
442 fe->reinit (elem, &nodes);
443
444
445 std::vector<MyMatrix3d> Qnode;
446 for (unsigned int i=0; i<elem->n_nodes(); ++i)
447 {
449 a1 << dxyzdxi[i](0), dxyzdxi[i](1), dxyzdxi[i](2);
451 a2 << dxyzdeta[i](0), dxyzdeta[i](1), dxyzdeta[i](2);
453 n = a1.cross(a2);
454 n /= n.norm();
455
459 if (std::abs(1.+C)<1e-6)
460 {
462 Q <<
463 1, 0, 0,
464 0, -1, 0,
465 0, 0, -1;
466 Qnode.push_back(Q);
467 }
468 else
469 {
471 Q <<
472 C+1./(1+C)*ny*ny, -1./(1+C)*nx*ny, nx,
473 -1./(1+C)*nx*ny, C+1./(1+C)*nx*nx, ny,
474 -nx, -ny, C;
475 Qnode.push_back(Q);
476 }
477 }
478
479 Ke.
resize (n_dofs, n_dofs);
480 for (unsigned int var_i=0; var_i<6; var_i++)
481 for (unsigned int var_j=0; var_j<6; var_j++)
482 Ke_var[var_i][var_j].reposition (var_i*n_var_dofs, var_j*n_var_dofs, n_var_dofs, n_var_dofs);
483
485 Fe_w.reposition(2*n_var_dofs,n_var_dofs);
486
487
488 fe->reinit (elem);
489
490
491 for (unsigned int qp=0; qp<qrule.n_points(); ++qp)
492 {
493
494
496 a1 << dxyzdxi[qp](0), dxyzdxi[qp](1), dxyzdxi[qp](2);
498 a2 << dxyzdeta[qp](0), dxyzdeta[qp](1), dxyzdeta[qp](2);
500 n = a1.cross(a2);
501 n /= n.norm();
504 a1(0), a2(0), n(0),
505 a1(1), a2(1), n(1),
506 a1(2), a2(2), n(2);
507
508
510 F0it =
F0.inverse().transpose();
511
512
517 if (std::abs(1.+C) < 1e-6)
518 {
519 Q <<
520 1, 0, 0,
521 0, -1, 0,
522 0, 0, -1;
523 }
524 else
525 {
526 Q <<
527 C+1./(1+C)*ny*ny, -1./(1+C)*nx*ny, nx,
528 -1./(1+C)*nx*ny, C+1./(1+C)*nx*nx, ny,
529 -nx, -ny, C;
530 }
531
533 C0 = F0it.block<3,2>(0,0).transpose()*Q.block<3,2>(0,0);
534
535
536 MyVector3d d2Xdxi2(d2xyzdxi2[qp](0), d2xyzdxi2[qp](1), d2xyzdxi2[qp](2));
537 MyVector3d d2Xdeta2(d2xyzdeta2[qp](0), d2xyzdeta2[qp](1), d2xyzdeta2[qp](2));
538 MyVector3d d2Xdxideta(d2xyzdxideta[qp](0), d2xyzdxideta[qp](1), d2xyzdxideta[qp](2));
539
542 n.dot(d2Xdxi2), n.dot(d2Xdxideta),
543 n.dot(d2Xdxideta), n.dot(d2Xdeta2);
544
545 MyVector3d dndxi = -
b(0,0)*F0it.col(0) -
b(0,1)*F0it.col(1);
546 MyVector3d dndeta = -
b(1,0)*F0it.col(0) -
b(1,1)*F0it.col(1);
547
549 bhat <<
550 F0it.col(1).dot(dndeta), -F0it.col(0).dot(dndeta),
551 -F0it.col(1).dot(dndxi), F0it.col(0).dot(dndxi);
552
554 bc = bhat*C0;
555
556
557 Real H = 0.5*(dndxi.dot(F0it.col(0))+dndeta.dot(F0it.col(1)));
558
559
560 for (unsigned int i=0; i<n_var_dofs; ++i)
561 {
562
563 Real C1i = dphidxi[i][qp]*C0(0,0) + dphideta[i][qp]*C0(1,0);
564 Real C2i = dphidxi[i][qp]*C0(0,1) + dphideta[i][qp]*C0(1,1);
565
567 B0I = MyMatrixXd::Zero(3, 5);
568 B0I.block<1,3>(0,0) = C1i*Q.col(0).transpose();
569 B0I.block<1,3>(1,0) = C2i*Q.col(1).transpose();
570 B0I.block<1,3>(2,0) = C2i*Q.col(0).transpose()+C1i*Q.col(1).transpose();
571
572
573 Real bc1i = dphidxi[i][qp]*bc(0,0) + dphideta[i][qp]*bc(1,0);
574 Real bc2i = dphidxi[i][qp]*bc(0,1) + dphideta[i][qp]*bc(1,1);
575
576 MyVector2d V1i(-Q.col(0).dot(Qnode[i].col(1)),
577 Q.col(0).dot(Qnode[i].col(0)));
578
579 MyVector2d V2i(-Q.col(1).dot(Qnode[i].col(1)),
580 Q.col(1).dot(Qnode[i].col(0)));
581
583 B1I = MyMatrixXd::Zero(3,5);
584 B1I.block<1,3>(0,0) = bc1i*Q.col(0).transpose();
585 B1I.block<1,3>(1,0) = bc2i*Q.col(1).transpose();
586 B1I.block<1,3>(2,0) = bc2i*Q.col(0).transpose()+bc1i*Q.col(1).transpose();
587
588 B1I.block<1,2>(0,3) = C1i*V1i.transpose();
589 B1I.block<1,2>(1,3) = C2i*V2i.transpose();
590 B1I.block<1,2>(2,3) = C2i*V1i.transpose()+C1i*V2i.transpose();
591
592
594 B2I = MyMatrixXd::Zero(3,5);
595
596 B2I.block<1,2>(0,3) = bc1i*V1i.transpose();
597 B2I.block<1,2>(1,3) = bc2i*V2i.transpose();
598 B2I.block<1,2>(2,3) = bc2i*V1i.transpose()+bc1i*V2i.transpose();
599
600
602 Bc0I = MyMatrixXd::Zero(2,5);
603 Bc0I.block<1,3>(0,0) = C1i*Q.col(2).transpose();
604 Bc0I.block<1,3>(1,0) = C2i*Q.col(2).transpose();
605 Bc0I.block<1,2>(0,3) = phi[i][qp]*V1i.transpose();
606 Bc0I.block<1,2>(1,3) = phi[i][qp]*V2i.transpose();
607
608
610 Bc1I = MyMatrixXd::Zero(2,5);
611 Bc1I.block<1,3>(0,0) = bc1i*Q.col(2).transpose();
612 Bc1I.block<1,3>(1,0) = bc2i*Q.col(2).transpose();
613
614
615 MyVector2d BdxiI(dphidxi[i][qp],dphideta[i][qp]);
617
618 for (unsigned int j=0; j<n_var_dofs; ++j)
619 {
620
621
622 Real C1j = dphidxi[j][qp]*C0(0,0) + dphideta[j][qp]*C0(1,0);
623 Real C2j = dphidxi[j][qp]*C0(0,1) + dphideta[j][qp]*C0(1,1);
624
626 B0J = MyMatrixXd::Zero(3,5);
627 B0J.block<1,3>(0,0) = C1j*Q.col(0).transpose();
628 B0J.block<1,3>(1,0) = C2j*Q.col(1).transpose();
629 B0J.block<1,3>(2,0) = C2j*Q.col(0).transpose()+C1j*Q.col(1).transpose();
630
631
632 Real bc1j = dphidxi[j][qp]*bc(0,0) + dphideta[j][qp]*bc(1,0);
633 Real bc2j = dphidxi[j][qp]*bc(0,1) + dphideta[j][qp]*bc(1,1);
634
635 MyVector2d V1j(-Q.col(0).dot(Qnode[j].col(1)),
636 Q.col(0).dot(Qnode[j].col(0)));
637
638 MyVector2d V2j(-Q.col(1).dot(Qnode[j].col(1)),
639 Q.col(1).dot(Qnode[j].col(0)));
640
642 B1J = MyMatrixXd::Zero(3,5);
643 B1J.block<1,3>(0,0) = bc1j*Q.col(0).transpose();
644 B1J.block<1,3>(1,0) = bc2j*Q.col(1).transpose();
645 B1J.block<1,3>(2,0) = bc2j*Q.col(0).transpose()+bc1j*Q.col(1).transpose();
646
647 B1J.block<1,2>(0,3) = C1j*V1j.transpose();
648 B1J.block<1,2>(1,3) = C2j*V2j.transpose();
649 B1J.block<1,2>(2,3) = C2j*V1j.transpose()+C1j*V2j.transpose();
650
651
653 B2J = MyMatrixXd::Zero(3,5);
654
655 B2J.block<1,2>(0,3) = bc1j*V1j.transpose();
656 B2J.block<1,2>(1,3) = bc2j*V2j.transpose();
657 B2J.block<1,2>(2,3) = bc2j*V1j.transpose()+bc1j*V2j.transpose();
658
659
661 Bc0J = MyMatrixXd::Zero(2,5);
662 Bc0J.block<1,3>(0,0) = C1j*Q.col(2).transpose();
663 Bc0J.block<1,3>(1,0) = C2j*Q.col(2).transpose();
664 Bc0J.block<1,2>(0,3) = phi[j][qp]*V1j.transpose();
665 Bc0J.block<1,2>(1,3) = phi[j][qp]*V2j.transpose();
666
667
669 Bc1J = MyMatrixXd::Zero(2,5);
670 Bc1J.block<1,3>(0,0) = bc1j*Q.col(2).transpose();
671 Bc1J.block<1,3>(1,0) = bc2j*Q.col(2).transpose();
672
673
674 MyVector2d BdxiJ(dphidxi[j][qp], dphideta[j][qp]);
676
677
678
680 local_KIJ = JxW[qp] * (
681 B0I.transpose() * Hm * B0J
682 + B2I.transpose() * Hf * B0J
683 + B0I.transpose() * Hf * B2J
684 + B1I.transpose() * Hf * B1J
685 + 2*H * B0I.transpose() * Hf * B1J
686 + 2*H * B1I.transpose() * Hf * B0J
687 + Bc0I.transpose() * Hc0 * Bc0J
688 + Bc1I.transpose() * Hc1 * Bc1J
689 + 2*H * Bc0I.transpose() * Hc1 * Bc1J
690 + 2*H * Bc1I.transpose() * Hc1 * Bc0J
691 );
692
693
695 full_local_KIJ = MyMatrixXd::Zero(6, 6);
696 full_local_KIJ.block<5,5>(0,0)=local_KIJ;
697
698
699
700
701
702 full_local_KIJ(5,5) =
Real(Hf(0,0)*JxW[qp]*BdI.transpose()*BdJ);
703
704
707 TI = MyMatrixXd::Identity(6,6);
708 TI.block<3,3>(3,3) = Qnode[i].transpose();
710 TJ = MyMatrixXd::Identity(6,6);
711 TJ.block<3,3>(3,3) = Qnode[j].transpose();
712 global_KIJ = TI.transpose()*full_local_KIJ*TJ;
713
714
715
716
717 for (unsigned int k=0;k<6;k++)
718 for (unsigned int l=0;l<6;l++)
719 Ke_var[k][l](i,j) += global_KIJ(k,l);
720 }
721 }
722
723 }
724
725 if (distributed_load)
726 {
727
728 for (unsigned int shellface=0; shellface<2; shellface++)
729 {
730 std::vector<boundary_id_type> bids;
732
733 for (std::size_t k=0; k<bids.size(); k++)
734 if (bids[k]==11)
735 for (unsigned int qp=0; qp<qrule.n_points(); ++qp)
736 for (unsigned int i=0; i<n_var_dofs; ++i)
737 Fe_w(i) -= JxW[qp] * phi[i][qp];
738 }
739 }
740
741
742
743
745
748
749 }
750
751 if (!distributed_load)
752 {
753
754
755
757
758
760
761 for (
const auto & node :
mesh.node_ptr_range())
762 if (((*node) - C).
norm() < 1e-3)
763 system.rhs->set(node->dof_number(0, 2, 0), -q/4);
764 }
765
766#else
767
769#endif
770}
void shellface_boundary_ids(const Elem *const elem, const unsigned short int shellface, std::vector< boundary_id_type > &vec_to_fill) const
Defines a dense matrix for use in Finite Element-type computations.
void resize(const unsigned int new_m, const unsigned int new_n)
Resizes the matrix to the specified size and calls zero().
Defines a dense submatrix for use in Finite Element-type computations.
Defines a dense subvector for use in finite element computations.
Defines a dense vector for use in Finite Element-type computations.
void resize(const unsigned int n)
Resize the vector.
This class handles the numbering of degrees of freedom on a mesh.
void dof_indices(const Elem *const elem, std::vector< dof_id_type > &di) 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.
const MeshBase & get_mesh() const
Parameters parameters
Data structure holding arbitrary parameters.
const T_sys & get_system(std::string_view name) const
NumericVector< Number > * rhs
The system matrix.
static std::unique_ptr< FEGenericBase > build(const unsigned int dim, const FEType &type)
Builds a specific finite element type.
class FEType hides (possibly multiple) FEFamily and approximation orders, thereby enabling specialize...
const SparseMatrix< Number > & get_system_matrix() const
Manages consistently variables, degrees of freedom, coefficient vectors, matrices and linear solvers ...
This is the MeshBase class.
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 ...
virtual void add_vector(const T *v, const std::vector< numeric_index_type > &dof_indices)
Computes , where v is a pointer and each dof_indices[i] specifies where to add value v[i].
const T & get(std::string_view) const
A Point defines a location in LIBMESH_DIM dimensional Real space.
This class implements specific orders of Gauss quadrature.
virtual void add_matrix(const DenseMatrix< T > &dm, const std::vector< numeric_index_type > &rows, const std::vector< numeric_index_type > &cols)=0
Add the full matrix dm to the SparseMatrix.
const FEType & variable_type(const unsigned int i) const
const DofMap & get_dof_map() const
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 &...)
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real