Esempio n. 1
0
  void H1FETransformation<OutputShape>::map_phi( const unsigned int dim,
						 const Elem* const elem,
						 const std::vector<Point>& qp,
						 const FEGenericBase<OutputShape>& fe,
						 std::vector<std::vector<OutputShape> >& phi ) const
  {
    switch(dim)
      {
      case 0:
	{
	  for (unsigned int i=0; i<phi.size(); i++)
	    {
	      libmesh_assert_equal_to ( qp.size(), phi[i].size() );
	      for (unsigned int p=0; p<phi[i].size(); p++)
		FEInterface::shape<OutputShape>(0, fe.get_fe_type(), elem, i, qp[p], phi[i][p]);
	    }
	  break;
	}
      case 1:
	{
	  for (unsigned int i=0; i<phi.size(); i++)
	    {
	      libmesh_assert_equal_to ( qp.size(), phi[i].size() );
	      for (unsigned int p=0; p<phi[i].size(); p++)
		FEInterface::shape<OutputShape>(1, fe.get_fe_type(), elem, i, qp[p], phi[i][p]);
	    }
	  break;
	}
      case 2:
	{
	  for (unsigned int i=0; i<phi.size(); i++)
	    {
	      libmesh_assert_equal_to ( qp.size(), phi[i].size() );
	      for (unsigned int p=0; p<phi[i].size(); p++)
		FEInterface::shape<OutputShape>(2, fe.get_fe_type(), elem, i, qp[p], phi[i][p]);
	    }
	  break;
	}
      case 3:
	{
	  for (unsigned int i=0; i<phi.size(); i++)
	    {
	      libmesh_assert_equal_to ( qp.size(), phi[i].size() );
	      for (unsigned int p=0; p<phi[i].size(); p++)
		FEInterface::shape<OutputShape>(3, fe.get_fe_type(), elem, i, qp[p], phi[i][p]);
	    }
	  break;
	}
      default:
	libmesh_error();
      }

    return;
  }
Esempio n. 2
0
  void HCurlFETransformation<OutputShape>::map_phi( const unsigned int dim,
						    const Elem* const elem,
						    const std::vector<Point>& qp,
						    const FEGenericBase<OutputShape>& fe,
						    std::vector<std::vector<OutputShape> >& phi ) const
  {
    switch(dim)
      {
	// These element transformations only make sense in 2D and 3D
      case 0: 
      case 1:
	{
	  libmesh_error();
	}
	
      case 2:
	{
	  const std::vector<Real>& dxidx_map = fe.get_fe_map().get_dxidx();
	  const std::vector<Real>& dxidy_map = fe.get_fe_map().get_dxidy();

	  const std::vector<Real>& detadx_map = fe.get_fe_map().get_detadx();
	  const std::vector<Real>& detady_map = fe.get_fe_map().get_detady();

	  // FIXME: Need to update for 2D elements in 3D space
	  /* phi = (dx/dxi)^-T * \hat{phi} 
	     In 2D:
	             (dx/dxi)^{-1} = [  dxi/dx   dxi/dy 
		                        deta/dx  deta/dy ]

	         so: dxi/dx^{-T} * \hat{phi} = [ dxi/dx  deta/dx   [ \hat{phi}_xi
                                                 dxi/dy  deta/dy ]   \hat{phi}_eta ]

	      or in indicial notation:  phi_j = xi_{i,j}*\hat{phi}_i */

	  for (unsigned int i=0; i<phi.size(); i++)
	    for (unsigned int p=0; p<phi[i].size(); p++)
	      {
		// Need to temporarily cache reference shape functions
		// TODO: PB: Might be worth trying to build phi_ref separately to see
		//           if we can get vectorization
		OutputShape phi_ref;
		FEInterface::shape<OutputShape>(2, fe.get_fe_type(), elem, i, qp[p], phi_ref);

		phi[i][p](0) = dxidx_map[p]*phi_ref.slice(0) + detadx_map[p]*phi_ref.slice(1);

		phi[i][p](1) = dxidy_map[p]*phi_ref.slice(0) + detady_map[p]*phi_ref.slice(1);
	      }

	  break;
	}

      case 3:
	{
	  const std::vector<Real>& dxidx_map = fe.get_fe_map().get_dxidx();
	  const std::vector<Real>& dxidy_map = fe.get_fe_map().get_dxidy();
	  const std::vector<Real>& dxidz_map = fe.get_fe_map().get_dxidz();

	  const std::vector<Real>& detadx_map = fe.get_fe_map().get_detadx();
	  const std::vector<Real>& detady_map = fe.get_fe_map().get_detady();
	  const std::vector<Real>& detadz_map = fe.get_fe_map().get_detadz();

	  const std::vector<Real>& dzetadx_map = fe.get_fe_map().get_dzetadx();
	  const std::vector<Real>& dzetady_map = fe.get_fe_map().get_dzetady();
	  const std::vector<Real>& dzetadz_map = fe.get_fe_map().get_dzetadz();

	  /* phi = (dx/dxi)^-T * \hat{phi} 
	     In 3D:
	          dx/dxi^-1 = [  dxi/dx    dxi/dy    dxi/dz
                                 deta/dx   deta/dy   deta/dz
                                 dzeta/dx  dzeta/dy  dzeta/dz]

	         so: dxi/dx^-T * \hat{phi} = [ dxi/dx  deta/dx  dzeta/dx   [ \hat{phi}_xi
                                               dxi/dy  deta/dy  dzeta/dy     \hat{phi}_eta 
                                               dxi/dz  deta/dz  dzeta/dz ]   \hat{phi}_zeta ]

	      or in indicial notation:  phi_j = xi_{i,j}*\hat{phi}_i */

	  for (unsigned int i=0; i<phi.size(); i++)
	    for (unsigned int p=0; p<phi[i].size(); p++)
	      {
		// Need to temporarily cache reference shape functions
		// TODO: PB: Might be worth trying to build phi_ref separately to see
		//           if we can get vectorization
		OutputShape phi_ref;
		FEInterface::shape<OutputShape>(3, fe.get_fe_type(), elem, i, qp[p], phi_ref);

		phi[i][p].slice(0) = dxidx_map[p]*phi_ref.slice(0) + detadx_map[p]*phi_ref.slice(1)
		  + dzetadx_map[p]*phi_ref.slice(2);

		phi[i][p].slice(1) = dxidy_map[p]*phi_ref.slice(0) + detady_map[p]*phi_ref.slice(1)
		  + dzetady_map[p]*phi_ref.slice(2);

		phi[i][p].slice(2) = dxidz_map[p]*phi_ref.slice(0) + detadz_map[p]*phi_ref.slice(1)
		  + dzetadz_map[p]*phi_ref.slice(2);
	      }
	  break;
	}
	
      default:
	libmesh_error();

      } // switch(dim)

    return;
  }