34 #include "libmesh/libmesh.h" 
   35 #include "libmesh/mesh.h" 
   36 #include "libmesh/linear_implicit_system.h" 
   37 #include "libmesh/equation_systems.h" 
   38 #include "libmesh/fe.h" 
   39 #include "libmesh/quadrature.h" 
   40 #include "libmesh/node.h" 
   41 #include "libmesh/elem.h" 
   42 #include "libmesh/dof_map.h" 
   43 #include "libmesh/quadrature_gauss.h" 
   44 #include "libmesh/vector_value.h" 
   45 #include "libmesh/tensor_value.h" 
   46 #include "libmesh/dense_matrix.h" 
   47 #include "libmesh/dense_submatrix.h" 
   48 #include "libmesh/dense_vector.h" 
   49 #include "libmesh/dense_subvector.h" 
   50 #include "libmesh/sparse_matrix.h" 
   51 #include "libmesh/numeric_vector.h" 
   52 #include "libmesh/exodusII_io.h" 
   53 #include "libmesh/dirichlet_boundaries.h" 
   54 #include "libmesh/zero_function.h" 
   55 #include "libmesh/linear_solver.h" 
   56 #include "libmesh/getpot.h" 
   57 #include "libmesh/enum_solver_package.h" 
   58 #include "libmesh/enum_solver_type.h" 
   59 #include "libmesh/parallel.h" 
   62 #ifdef LIBMESH_HAVE_EIGEN 
   63 #include "libmesh/ignore_warnings.h" 
   64 # include <Eigen/Dense> 
   65 #include "libmesh/restore_warnings.h" 
   72 typedef Eigen::Matrix<libMesh::Real, Eigen::Dynamic, Eigen::Dynamic> 
MyMatrixXd;
 
   82                      const std::string & system_name);
 
   85 int main (
int argc, 
char ** argv)
 
   91   libmesh_example_requires (3 == LIBMESH_DIM, 
"3D support");
 
   94 #ifndef LIBMESH_ENABLE_DIRICHLET 
   95   libmesh_example_requires(
false, 
"--enable-dirichlet");
 
   99 #ifndef LIBMESH_HAVE_EXODUS_API 
  100   libmesh_example_requires (
false, 
"ExodusII support");
 
  103 #ifndef LIBMESH_ENABLE_SECOND_DERIVATIVES 
  104   libmesh_example_requires (
false, 
"second derivatives enabled");
 
  109 #ifndef LIBMESH_HAVE_EIGEN 
  110   libmesh_example_requires(
false, 
"--enable-eigen");
 
  115 #ifndef LIBMESH_HAVE_XDR 
  116   libmesh_example_requires (
false, 
"XDR support");
 
  121 #ifdef LIBMESH_DEFAULT_QUADRUPLE_PRECISION 
  122   libmesh_example_requires (
false, 
"--disable-quadruple-precision");
 
  126   GetPot command_line (argc, argv);
 
  127   int distributed_load = 0;
 
  128   if (command_line.search(1, 
"-distributed_load"))
 
  129     distributed_load = command_line.next(distributed_load);
 
  179   equation_systems.
parameters.
set<
bool>(
"distributed load")  = (distributed_load != 0);
 
  189 #ifdef LIBMESH_ENABLE_DIRICHLET 
  192     std::set<boundary_id_type> boundary_ids;
 
  193     boundary_ids.insert(7);
 
  194     unsigned int variables[] = {2, 3, 4};
 
  201        std::vector<unsigned int>(variables, variables+3), zf,
 
  207     std::set<boundary_id_type> boundary_ids;
 
  208     boundary_ids.insert(8);
 
  209     unsigned int variables[] = {1, 3, 5};
 
  214        std::vector<unsigned int>(variables, variables+3), zf,
 
  220     std::set<boundary_id_type> boundary_ids;
 
  221     boundary_ids.insert(9);
 
  222     unsigned int variables[] = {0, 4, 5};
 
  227        std::vector<unsigned int>(variables, variables+3), zf,
 
  233     std::set<boundary_id_type> boundary_ids;
 
  234     boundary_ids.insert(10);
 
  235     unsigned int variables[] = {0, 2, 4};
 
  240        std::vector<unsigned int>(variables, variables+3), zf,
 
  244 #endif // LIBMESH_ENABLE_DIRICHLET 
  247   equation_systems.
init();
 
  267   if (distributed_load==0)
 
  270       Node * node_C = 
nullptr;
 
  271       Point point_C(0, 3, 3);
 
  273         Real nearest_dist_sq = std::numeric_limits<Real>::max();
 
  281             if (dist_sq < nearest_dist_sq)
 
  283                 nearest_dist_sq = dist_sq;
 
  289         unsigned int minrank = 0;
 
  290         system.
comm().minloc(nearest_dist_sq, minrank);
 
  296           nearest_node_id = node_C->
id();
 
  297         system.
comm().broadcast(nearest_node_id, minrank);
 
  314       system.
comm().sum(w);
 
  317       Number w_C_bar = -E*h*w/q;
 
  318       const Real w_C_bar_analytic = 164.24;
 
  322       libMesh::out << 
"z-displacement of the point C: " << w_C_bar << std::endl;
 
  323       libMesh::out << 
"Analytic solution: " << w_C_bar_analytic << std::endl;
 
  327       Point point_D(0, 0, 3);
 
  332       const Real v_D_bar_analytic = 4.114;
 
  336       libMesh::out << 
"y-displacement of the point D: " << v_D_bar << std::endl;
 
  337       libMesh::out << 
"Analytic solution: " << v_D_bar_analytic << std::endl;
 
  349                      const std::string & system_name)
 
  356 #if defined(LIBMESH_HAVE_EIGEN) && defined(LIBMESH_ENABLE_SECOND_DERIVATIVES) 
  359   libmesh_assert_equal_to (system_name, 
"Shell");
 
  373   const bool distributed_load  = es.
parameters.
get<
bool> (
"distributed load");
 
  380     0., 0., 0.5 * (1-nu);
 
  381   Hm *= h * E/(1-nu*nu);
 
  388     0., 0., 0.5 * (1-nu);
 
  389   Hf *= h*h*h/12 * E/(1-nu*nu);
 
  393   Hc0 *= h * 5./6*E/(2*(1+nu));
 
  396   Hc1 *= h*h*h/12 * 5./6*E/(2*(1+nu));
 
  404   fe->attach_quadrature_rule (&qrule);
 
  407   const std::vector<Real> & JxW = fe->get_JxW();
 
  411   const std::vector<RealGradient> & dxyzdxi = fe->get_dxyzdxi();
 
  412   const std::vector<RealGradient> & dxyzdeta = fe->get_dxyzdeta();
 
  414   const std::vector<RealGradient> & d2xyzdxi2 = fe->get_d2xyzdxi2();
 
  415   const std::vector<RealGradient> & d2xyzdeta2 = fe->get_d2xyzdeta2();
 
  416   const std::vector<RealGradient> & d2xyzdxideta = fe->get_d2xyzdxideta();
 
  417   const std::vector<std::vector<Real>> & dphidxi = fe->get_dphidxi();
 
  418   const std::vector<std::vector<Real>> & dphideta = fe->get_dphideta();
 
  419   const std::vector<std::vector<Real>> & phi = fe->get_phi();
 
  448   std::vector<dof_id_type> dof_indices;
 
  449   std::vector<std::vector<dof_id_type>> dof_indices_var(6);
 
  456       for (
unsigned int var=0; var<6; var++)
 
  457         dof_map.
dof_indices (elem, dof_indices_var[var], var);
 
  459       const unsigned int n_dofs   = dof_indices.size();
 
  460       const unsigned int n_var_dofs = dof_indices_var[0].size();
 
  463       std::vector<Point> nodes;
 
  464       for (
auto i : elem->node_index_range())
 
  465         nodes.push_back(elem->reference_elem()->node_ref(i));
 
  466       fe->reinit (elem, &nodes);
 
  469       MyVector3d X1(elem->node_ref(0)(0), elem->node_ref(0)(1), elem->node_ref(0)(2));
 
  470       MyVector3d X2(elem->node_ref(1)(0), elem->node_ref(1)(1), elem->node_ref(1)(2));
 
  471       MyVector3d X3(elem->node_ref(2)(0), elem->node_ref(2)(1), elem->node_ref(2)(2));
 
  472       MyVector3d X4(elem->node_ref(3)(0), elem->node_ref(3)(1), elem->node_ref(3)(2));
 
  475       std::vector<MyMatrix3d> F0node;
 
  476       std::vector<MyMatrix3d> Qnode;
 
  477       for (
auto i : elem->node_index_range())
 
  480           a1 << dxyzdxi[i](0), dxyzdxi[i](1), dxyzdxi[i](2);
 
  482           a2 << dxyzdeta[i](0), dxyzdeta[i](1), dxyzdeta[i](2);
 
  491           F0node.push_back(
F0);
 
  509                 C+1./(1+C)*ny*ny, -1./(1+C)*nx*ny, nx,
 
  510                 -1./(1+C)*nx*ny, C+1./(1+C)*nx*nx, ny,
 
  516       Ke.
resize (n_dofs, n_dofs);
 
  517       for (
unsigned int var_i=0; var_i<6; var_i++)
 
  518         for (
unsigned int var_j=0; var_j<6; var_j++)
 
  519           Ke_var[var_i][var_j].reposition (var_i*n_var_dofs, var_j*n_var_dofs, n_var_dofs, n_var_dofs);
 
  528       for (
unsigned int qp=0; qp<qrule.n_points(); ++qp)
 
  533           a1 << dxyzdxi[qp](0), dxyzdxi[qp](1), dxyzdxi[qp](2);
 
  535           a2 << dxyzdeta[qp](0), dxyzdeta[qp](1), dxyzdeta[qp](2);
 
  547           F0it = 
F0.inverse().transpose();
 
  564                 C+1./(1+C)*ny*ny, -1./(1+C)*nx*ny, nx,
 
  565                 -1./(1+C)*nx*ny, C+1./(1+C)*nx*nx, ny,
 
  570           C0 = F0it.block<3,2>(0,0).transpose()*Q.block<3,2>(0,0);
 
  573           MyVector3d d2Xdxi2(d2xyzdxi2[qp](0), d2xyzdxi2[qp](1), d2xyzdxi2[qp](2));
 
  574           MyVector3d d2Xdeta2(d2xyzdeta2[qp](0), d2xyzdeta2[qp](1), d2xyzdeta2[qp](2));
 
  575           MyVector3d d2Xdxideta(d2xyzdxideta[qp](0), d2xyzdxideta[qp](1), d2xyzdxideta[qp](2));
 
  580             n.dot(d2Xdxi2), n.dot(d2Xdxideta),
 
  581             n.dot(d2Xdxideta), n.dot(d2Xdeta2);
 
  583           MyVector3d dndxi = -b(0,0)*F0it.col(0) - b(0,1)*F0it.col(1);
 
  584           MyVector3d dndeta = -b(1,0)*F0it.col(0) - b(1,1)*F0it.col(1);
 
  588             F0it.col(1).dot(dndeta), -F0it.col(0).dot(dndeta),
 
  589             -F0it.col(1).dot(dndxi), F0it.col(0).dot(dndxi);
 
  595           Real H = 0.5*(dndxi.dot(F0it.col(0))+dndeta.dot(F0it.col(1)));
 
  598           Real xi = qrule.qp(qp)(0);
 
  599           Real eta = qrule.qp(qp)(1);
 
  609           MyVector3d nA1 = 0.5*(Qnode[0].col(2)+Qnode[1].col(2));
 
  612           MyVector3d nB2 = 0.5*(Qnode[1].col(2)+Qnode[2].col(2));
 
  615           MyVector3d nA2 = 0.5*(Qnode[2].col(2)+Qnode[3].col(2));
 
  618           MyVector3d nB1 = 0.5*(Qnode[3].col(2)+Qnode[0].col(2));
 
  629           MyVector2d AS1A1(-aA1.dot(Qnode[0].col(1)), aA1.dot(Qnode[0].col(0)));
 
  630           MyVector2d AS2A1(-aA1.dot(Qnode[1].col(1)), aA1.dot(Qnode[1].col(0)));
 
  634           MyVector2d AS1A2(-aA2.dot(Qnode[3].col(1)), aA2.dot(Qnode[3].col(0)));
 
  635           MyVector2d AS2A2(-aA2.dot(Qnode[2].col(1)), aA2.dot(Qnode[2].col(0)));
 
  639           MyVector2d AS1B1(-aB1.dot(Qnode[0].col(1)), aB1.dot(Qnode[0].col(0)));
 
  640           MyVector2d AS2B1(-aB1.dot(Qnode[3].col(1)), aB1.dot(Qnode[3].col(0)));
 
  644           MyVector2d AS1B2(-aB2.dot(Qnode[1].col(1)), aB2.dot(Qnode[1].col(0)));
 
  645           MyVector2d AS2B2(-aB2.dot(Qnode[2].col(1)), aB2.dot(Qnode[2].col(0)));
 
  650           std::vector<MyMatrixXd> Bcnode;
 
  653           Bc.block<1,3>(0,0) = -nA1.transpose();
 
  654           Bc.block<1,2>(0,3) = AS1A1.transpose();
 
  655           Bc.block<1,3>(1,0) = -nB1.transpose();
 
  656           Bc.block<1,2>(1,3) = AS1B1.transpose();
 
  657           Bcnode.push_back(Bc);
 
  659           Bc.block<1,3>(0,0) = nA1.transpose();
 
  660           Bc.block<1,2>(0,3) = AS2A1.transpose();
 
  661           Bc.block<1,3>(1,0) = -nB2.transpose();
 
  662           Bc.block<1,2>(1,3) = AS1B2.transpose();
 
  663           Bcnode.push_back(Bc);
 
  665           Bc.block<1,3>(0,0) = nA2.transpose();
 
  666           Bc.block<1,2>(0,3) = AS2A2.transpose();
 
  667           Bc.block<1,3>(1,0) = nB2.transpose();
 
  668           Bc.block<1,2>(1,3) = AS2B2.transpose();
 
  669           Bcnode.push_back(Bc);
 
  671           Bc.block<1,3>(0,0) = -nA2.transpose();
 
  672           Bc.block<1,2>(0,3) = AS1A2.transpose();
 
  673           Bc.block<1,3>(1,0) = nB1.transpose();
 
  674           Bc.block<1,2>(1,3) = AS2B1.transpose();
 
  675           Bcnode.push_back(Bc);
 
  678           for (
unsigned int i=0; i<n_var_dofs; ++i)
 
  681               Real C1i = dphidxi[i][qp]*C0(0,0) + dphideta[i][qp]*C0(1,0);
 
  682               Real C2i = dphidxi[i][qp]*C0(0,1) + dphideta[i][qp]*C0(1,1);
 
  685               B0I = MyMatrixXd::Zero(3, 5);
 
  686               B0I.block<1,3>(0,0) = C1i*Q.col(0).transpose();
 
  687               B0I.block<1,3>(1,0) = C2i*Q.col(1).transpose();
 
  688               B0I.block<1,3>(2,0) = C2i*Q.col(0).transpose()+C1i*Q.col(1).transpose();
 
  691               Real bc1i = dphidxi[i][qp]*bc(0,0) + dphideta[i][qp]*bc(1,0);
 
  692               Real bc2i = dphidxi[i][qp]*bc(0,1) + dphideta[i][qp]*bc(1,1);
 
  694               MyVector2d V1i(-Q.col(0).dot(Qnode[i].col(1)),
 
  695                              Q.col(0).dot(Qnode[i].col(0)));
 
  697               MyVector2d V2i(-Q.col(1).dot(Qnode[i].col(1)),
 
  698                              Q.col(1).dot(Qnode[i].col(0)));
 
  701               B1I = MyMatrixXd::Zero(3,5);
 
  702               B1I.block<1,3>(0,0) = bc1i*Q.col(0).transpose();
 
  703               B1I.block<1,3>(1,0) = bc2i*Q.col(1).transpose();
 
  704               B1I.block<1,3>(2,0) = bc2i*Q.col(0).transpose()+bc1i*Q.col(1).transpose();
 
  706               B1I.block<1,2>(0,3) = C1i*V1i.transpose();
 
  707               B1I.block<1,2>(1,3) = C2i*V2i.transpose();
 
  708               B1I.block<1,2>(2,3) = C2i*V1i.transpose()+C1i*V2i.transpose();
 
  712               B2I = MyMatrixXd::Zero(3,5);
 
  714               B2I.block<1,2>(0,3) = bc1i*V1i.transpose();
 
  715               B2I.block<1,2>(1,3) = bc2i*V2i.transpose();
 
  716               B2I.block<1,2>(2,3) = bc2i*V1i.transpose()+bc1i*V2i.transpose();
 
  720               Bc0I = C0.transpose()*Bcnode[i];
 
  724               Bc1I = bc.transpose()*Bcnode[i];
 
  727               MyVector2d BdxiI(dphidxi[i][qp],dphideta[i][qp]);
 
  730               for (
unsigned int j=0; j<n_var_dofs; ++j)
 
  734                   Real C1j = dphidxi[j][qp]*C0(0,0) + dphideta[j][qp]*C0(1,0);
 
  735                   Real C2j = dphidxi[j][qp]*C0(0,1) + dphideta[j][qp]*C0(1,1);
 
  738                   B0J = MyMatrixXd::Zero(3,5);
 
  739                   B0J.block<1,3>(0,0) = C1j*Q.col(0).transpose();
 
  740                   B0J.block<1,3>(1,0) = C2j*Q.col(1).transpose();
 
  741                   B0J.block<1,3>(2,0) = C2j*Q.col(0).transpose()+C1j*Q.col(1).transpose();
 
  744                   Real bc1j = dphidxi[j][qp]*bc(0,0) + dphideta[j][qp]*bc(1,0);
 
  745                   Real bc2j = dphidxi[j][qp]*bc(0,1) + dphideta[j][qp]*bc(1,1);
 
  747                   MyVector2d V1j(-Q.col(0).dot(Qnode[j].col(1)),
 
  748                                  Q.col(0).dot(Qnode[j].col(0)));
 
  750                   MyVector2d V2j(-Q.col(1).dot(Qnode[j].col(1)),
 
  751                                  Q.col(1).dot(Qnode[j].col(0)));
 
  754                   B1J = MyMatrixXd::Zero(3,5);
 
  755                   B1J.block<1,3>(0,0) = bc1j*Q.col(0).transpose();
 
  756                   B1J.block<1,3>(1,0) = bc2j*Q.col(1).transpose();
 
  757                   B1J.block<1,3>(2,0) = bc2j*Q.col(0).transpose()+bc1j*Q.col(1).transpose();
 
  759                   B1J.block<1,2>(0,3) = C1j*V1j.transpose();
 
  760                   B1J.block<1,2>(1,3) = C2j*V2j.transpose();
 
  761                   B1J.block<1,2>(2,3) = C2j*V1j.transpose()+C1j*V2j.transpose();
 
  765                   B2J = MyMatrixXd::Zero(3,5);
 
  767                   B2J.block<1,2>(0,3) = bc1j*V1j.transpose();
 
  768                   B2J.block<1,2>(1,3) = bc2j*V2j.transpose();
 
  769                   B2J.block<1,2>(2,3) = bc2j*V1j.transpose()+bc1j*V2j.transpose();
 
  773                   Bc0J = C0.transpose()*Bcnode[j];
 
  777                   Bc1J = bc.transpose()*Bcnode[j];
 
  780                   MyVector2d BdxiJ(dphidxi[j][qp], dphideta[j][qp]);
 
  786                   local_KIJ = JxW[qp] * (
 
  787                                          B0I.transpose() * Hm * B0J
 
  788                                          +  B2I.transpose() * Hf * B0J
 
  789                                          +  B0I.transpose() * Hf * B2J
 
  790                                          +  B1I.transpose() * Hf * B1J
 
  791                                          +  2*H * B0I.transpose() * Hf * B1J
 
  792                                          +  2*H * B1I.transpose() * Hf * B0J
 
  793                                          +  Bc0I.transpose() * Hc0 * Bc0J
 
  794                                          +  Bc1I.transpose() * Hc1 * Bc1J
 
  795                                          +  2*H * Bc0I.transpose() * Hc1 * Bc1J
 
  796                                          +  2*H * Bc1I.transpose() * Hc1 * Bc0J
 
  801                   full_local_KIJ = MyMatrixXd::Zero(6, 6);
 
  802                   full_local_KIJ.block<5,5>(0,0)=local_KIJ;
 
  813                   full_local_KIJ(5,5) = 
Real(Hf(0,0)*JxW[qp]*BdI.transpose()*BdJ);
 
  818                   TI = MyMatrixXd::Identity(6,6);
 
  819                   TI.block<3,3>(3,3) = Qnode[i].transpose();
 
  821                   TJ = MyMatrixXd::Identity(6,6);
 
  822                   TJ.block<3,3>(3,3) = Qnode[j].transpose();
 
  823                   global_KIJ = TI.transpose()*full_local_KIJ*TJ;
 
  828                   for (
unsigned int k=0;k<6;k++)
 
  829                     for (
unsigned int l=0;l<6;l++)
 
  830                       Ke_var[k][l](i,j) += global_KIJ(k,l);
 
  836       if (distributed_load)
 
  839           for (
unsigned int shellface=0; shellface<2; shellface++)
 
  841               std::vector<boundary_id_type> bids;
 
  844               for (std::size_t k=0; k<bids.size(); k++)
 
  846                   for (
unsigned int qp=0; qp<qrule.n_points(); ++qp)
 
  847                     for (
unsigned int i=0; i<n_var_dofs; ++i)
 
  848                       Fe_w(i) -= JxW[qp] * phi[i][qp];
 
  862   if (!distributed_load)
 
  873         if (((*node) - C).norm() < 1e-3)
 
  874           system.
rhs->
set(node->dof_number(0, 2, 0), -q/4);
 
  880 #endif // defined(LIBMESH_HAVE_EIGEN) && defined(LIBMESH_ENABLE_SECOND_DERIVATIVES)