//********************************************************************** void Element_Linear2D::print(std::ostream& os) const { os << "Element: gid = " << m_global_element_index << ", lid = " << m_local_element_index << std::endl; os << " coords: " << std::endl; for (size_type i=0; i < this->numNodes(); ++i) os << " node[" << i << "]: gid = " << m_global_node_ids[i] << " coords = (" << m_coords(i,0) << "," << m_coords(i,1) << "), owns = " << m_owns_node[i] << std::endl; if (false) { os << "\n m_grad_phi_xy(QP,Node,Dim):" << std::endl; for (size_type qp=0; qp < this->numQuadraturePoints(); ++qp) for (size_type node=0; node < this->numNodes(); ++node) for (size_type dim=0; dim < 2; ++dim) { os << " m_grad_phi_xy(" << qp << "," << node << "," << dim << ") = " << m_grad_phi_xy(qp,node,dim) << std::endl; } } }
//********************************************************************** CellData::CellData() { m_coords = Kokkos::View<double***,PHX::Device>("coords",4,4,3); m_phi = Kokkos::View<double**,PHX::Device>("phi",4,4); m_grad_phi = Kokkos::View<double***,PHX::Device>("grad_phi",4,4,3); // just some garbage values for unit testing for (PHX::Device::size_type i=0; i < m_phi.dimension(0); ++i) { for (PHX::Device::size_type j=0; j < m_phi.dimension(1); ++j) { m_phi(i,j) = 0.25; for (PHX::Device::size_type k=0; k < m_phi.dimension(2); ++k) { m_coords(i,j,k) = 0.25; m_grad_phi(i,j,k) = 0.25; } } } }
//********************************************************************** Element_Linear2D::Element_Linear2D(std::vector<size_type> global_node_ids, size_type global_element_index, size_type local_element_index, std::vector<double> x_node_coords, std::vector<double> y_node_coords) : m_global_element_index(global_element_index), m_local_element_index(local_element_index), m_global_node_ids(global_node_ids), m_owns_node(4, false), m_coords_mem(Teuchos::arcp<double>(4*2)), m_phi_mem(Teuchos::arcp<double>(4*4)), m_grad_phi_mem(Teuchos::arcp<double>(4*4*2)), m_grad_phi_xy_mem(Teuchos::arcp<double>(4*4*2)), m_det_jacobian_mem(Teuchos::arcp<double>(4)), m_weights_mem(Teuchos::arcp<double>(4)), m_coords(&(m_coords_mem[0]),4,2), m_phi(&(m_phi_mem[0]),4,4), m_grad_phi(&(m_grad_phi_mem[0]),4,4,2), m_grad_phi_xy(&(m_grad_phi_xy_mem[0]),4,4,2), m_det_jacobian(&(m_det_jacobian_mem[0]),4), m_weights(&(m_weights_mem[0]),4) { // Set node coordinatates m_coords(0,0) = x_node_coords[0]; m_coords(0,1) = y_node_coords[0]; m_coords(1,0) = x_node_coords[1]; m_coords(1,1) = y_node_coords[1]; m_coords(2,0) = x_node_coords[2]; m_coords(2,1) = y_node_coords[2]; m_coords(3,0) = x_node_coords[3]; m_coords(3,1) = y_node_coords[3]; // Quadrature rule defines number of quadrature points - 4 std::vector<double> chi(4); std::vector<double> eta(4); chi[0] = -1.0 / std::sqrt(3); chi[1] = 1.0 / std::sqrt(3); chi[2] = 1.0 / std::sqrt(3); chi[3] = -1.0 / std::sqrt(3); eta[0] = -1.0 / std::sqrt(3); eta[1] = -1.0 / std::sqrt(3); eta[2] = 1.0 / std::sqrt(3); eta[3] = 1.0 / std::sqrt(3); m_weights[0] = 1.0; m_weights[1] = 1.0; m_weights[2] = 1.0; m_weights[3] = 1.0; for (size_type qp=0; qp < this->numQuadraturePoints(); ++qp) { // Phi shards::Array<double,shards::NaturalOrder,Node> phi_qp = m_phi.truncate(qp); evaluatePhi(chi[qp], eta[qp], phi_qp); // Grad Phi in local element coordinates shards::Array<double,shards::NaturalOrder,Node,Dim> grad_phi_qp = m_grad_phi.truncate(qp); evaluateGradPhi(chi[qp], eta[qp], grad_phi_qp); // Determinant of Jacobian and basis function gradients in // real space shards::Array<double,shards::NaturalOrder,Node,Dim> grad_phi_xy_qp = m_grad_phi_xy.truncate(qp); evaluateDetJacobianAndGradients(chi[qp], eta[qp], m_det_jacobian(qp), grad_phi_qp, grad_phi_xy_qp); } // for (std::size_t i=0; i < m_grad_phi_xy.size(); ++i) // m_grad_phi_xy[i] = 0.0; // for (std::size_t qp=0; qp < this->numQuadraturePoints(); ++qp) // for (std::size_t node=0; node < this->numNodes(); ++node) // for (std::size_t dim=0; dim < 2; ++dim) // m_grad_phi_xy(qp,node,dim) = // (1.0 / m_det_jacobian(qp)) * m_grad_phi(qp,node,dim); }
//********************************************************************** void Element_Linear2D:: evaluateDetJacobianAndGradients(double chi, double eta, double& det_jac, const shards::Array<double,shards::NaturalOrder,Node,Dim>& grad_phi, shards::Array<double,shards::NaturalOrder,Node,Dim>& grad_phi_xy) { double dx_dchi = 0.25 * ( ( m_coords(1,0) - m_coords(0,0) ) * (1.0 - eta) + ( m_coords(2,0) - m_coords(3,0) ) * (1.0 + eta) ); double dx_deta = 0.25 * ( ( m_coords(1,1) - m_coords(0,1) ) * (1.0 - eta) + ( m_coords(2,1) - m_coords(3,1) ) * (1.0 + eta) ); double dy_dchi = 0.25 * ( ( m_coords(3,0) - m_coords(0,0) ) * (1.0 - chi) + ( m_coords(2,0) - m_coords(1,0) ) * (1.0 + chi) ); double dy_deta = 0.25 * ( ( m_coords(3,1) - m_coords(0,1) ) * (1.0 - chi) + ( m_coords(2,1) - m_coords(1,1) ) * (1.0 + chi) ); det_jac = dx_dchi * dy_deta - dx_deta * dy_dchi; double inv_det_jac = 1.0 / det_jac; for (size_type node = 0; node < this->numNodes(); ++node) { grad_phi_xy(node,0) = inv_det_jac * (dy_deta * grad_phi(node, 0) - dy_dchi * grad_phi(node, 1)); grad_phi_xy(node,1) = inv_det_jac * (-dx_deta * grad_phi(node, 0) + dx_dchi * grad_phi(node, 1)); } }