blob: da38684603e381ae52e07f5d8d5adecaba7771e8 [file] [log] [blame]
#ifndef _Hex8_box_utils_hpp_
#define _Hex8_box_utils_hpp_
//@HEADER
// ************************************************************************
//
// MiniFE: Simple Finite Element Assembly and Solve
// Copyright (2006-2013) Sandia Corporation
//
// Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
// license for use of this work by or on behalf of the U.S. Government.
//
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as
// published by the Free Software Foundation; either version 2.1 of the
// License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
// USA
//
// ************************************************************************
//@HEADER
#include <stdexcept>
#include <box_utils.hpp>
#include <ElemData.hpp>
#include <simple_mesh_description.hpp>
#include <Hex8.hpp>
namespace miniFE {
template<typename GlobalOrdinal>
void get_hex8_node_ids(int nx, int ny,
GlobalOrdinal node0,
GlobalOrdinal* elem_node_ids)
{
//Given box dimensions nx and ny, and a starting node
//(local-node-0 for a hex8), compute the other nodes
//of the hex8 using the exodus ordering convention.
elem_node_ids[0] = node0;
elem_node_ids[1] = node0 + 1;
elem_node_ids[2] = node0 + nx + 1;
elem_node_ids[3] = node0 + nx;
elem_node_ids[4] = node0 + nx*ny;
elem_node_ids[5] = node0 + 1 + nx*ny;
elem_node_ids[6] = node0 + nx + nx*ny + 1;
elem_node_ids[7] = node0 + nx + nx*ny;
}
template<typename Scalar>
void get_hex8_node_coords_3d(Scalar x, Scalar y, Scalar z,
Scalar hx, Scalar hy, Scalar hz,
Scalar* elem_node_coords)
{
//Input: x,y,z are the coordinates of local-node 0 for a Hex8.
//'hx', 'hy', 'hz' are the lengths of the sides of the element
//in each direction.
elem_node_coords[0] = x;
elem_node_coords[1] = y;
elem_node_coords[2] = z;
elem_node_coords[3] = x + hx;
elem_node_coords[4] = y;
elem_node_coords[5] = z;
elem_node_coords[6] = x + hx;
elem_node_coords[7] = y + hy;
elem_node_coords[8] = z;
elem_node_coords[9] = x;
elem_node_coords[10] = y + hy;
elem_node_coords[11] = z;
elem_node_coords[12] = x;
elem_node_coords[13] = y;
elem_node_coords[14] = z + hz;
elem_node_coords[15] = x + hx;
elem_node_coords[16] = y;
elem_node_coords[17] = z + hz;
elem_node_coords[18] = x + hx;
elem_node_coords[19] = y + hy;
elem_node_coords[20] = z + hz;
elem_node_coords[21] = x;
elem_node_coords[22] = y + hy;
elem_node_coords[23] = z + hz;
}
template<typename GlobalOrdinal, typename Scalar>
void
get_elem_nodes_and_coords(const simple_mesh_description<GlobalOrdinal>& mesh,
GlobalOrdinal elemID,
GlobalOrdinal* node_ords, Scalar* node_coords)
{
int global_nodes_x = mesh.global_box[0][1]+1;
int global_nodes_y = mesh.global_box[1][1]+1;
int global_nodes_z = mesh.global_box[2][1]+1;
if (elemID < 0) {
//I don't think this can happen, but check for the sake of paranoia...
throw std::runtime_error("get_elem_nodes_and_coords ERROR, negative elemID");
}
int elem_int_x, elem_int_y, elem_int_z;
get_int_coords(elemID, global_nodes_x-1, global_nodes_y-1, global_nodes_z-1,
elem_int_x, elem_int_y, elem_int_z);
GlobalOrdinal nodeID = get_id<GlobalOrdinal>(global_nodes_x, global_nodes_y, global_nodes_z, elem_int_x, elem_int_y, elem_int_z);
#ifdef MINIFE_DEBUG_VERBOSE
std::cout<<"\nelemID: "<<elemID<<", nodeID: "<<nodeID<<std::endl;
#endif
get_hex8_node_ids(global_nodes_x, global_nodes_y, nodeID, node_ords);
//Map node-IDs to rows because each processor may have a non-contiguous block of
//node-ids, but needs a contiguous block of row-numbers:
#ifdef MINIFE_DEBUG_VERBOSE
std::cout<<"elem "<<elemID<<" nodes: ";
#endif
for(int i=0; i<Hex8::numNodesPerElem; ++i) {
#ifdef MINIFE_DEBUG_VERBOSE
std::cout<<node_ords[i]<<" ";
#endif
node_ords[i] = mesh.map_id_to_row(node_ords[i]);
}
#ifdef MINIFE_DEBUG_VERBOSE
std::cout << std::endl;
#endif
int global_elems_x = mesh.global_box[0][1];
int global_elems_y = mesh.global_box[1][1];
int global_elems_z = mesh.global_box[2][1];
Scalar ix,iy,iz;
get_coords<GlobalOrdinal,Scalar>(nodeID, global_nodes_x,global_nodes_y,global_nodes_z,
ix,iy,iz);
Scalar hx = 1.0/global_elems_x;
Scalar hy = 1.0/global_elems_y;
Scalar hz = 1.0/global_elems_z;
get_hex8_node_coords_3d(ix, iy, iz, hx, hy, hz, node_coords);
#ifdef MINIFE_DEBUG_VERBOSE
int offset = 0;
for(int i=0; i<Hex8::numNodesPerElem; ++i) {
std::cout << "("<<node_coords[offset++]<<","<<node_coords[offset++]<<","<<node_coords[offset++]<<")";
}
std::cout << std::endl;
#endif
}
template<typename GlobalOrdinal, typename Scalar>
void
get_elem_nodes_and_coords(const simple_mesh_description<GlobalOrdinal>& mesh,
GlobalOrdinal elemID,
ElemData<GlobalOrdinal,Scalar>& elem_data)
{
get_elem_nodes_and_coords(mesh, elemID, elem_data.elem_node_ids, elem_data.elem_node_coords);
}
}//namespace miniFE
#endif