21#ifndef B2ELEMENT_KLT_COMPUTE_SHAPE_Q_H_ 
   22#define B2ELEMENT_KLT_COMPUTE_SHAPE_Q_H_ 
   27#include "elements/klt_shells/b2element_klt_generic_shape.H" 
   28#include "elements/klt_shells/b2element_klt_util.H" 
   29#include "elements/smr/b2element_continuum_integrate.H" 
   30#include "elements/smr/b2element_continuum_shape.H" 
   31#include "elements/smr/b2element_continuum_util.H" 
   33#include "model/b2element.H" 
   34#include "model_imp/b2hnode.H" 
   39template <
int ORDER_R, 
int ORDER_S, 
typename DATA>
 
   40class QuadBezier : 
public GenericShape {
 
   42    static const int num_nodes = (ORDER_R + 1) * (ORDER_S + 1);
 
   44    static const int order_r = ORDER_R;
 
   46    static const int order_s = ORDER_S;
 
   48    static const size_t num_nodes_edge_r = ORDER_R + 1;
 
   50    static const size_t num_nodes_edge_c1_r = (ORDER_R + 1) * 2;
 
   52    static const size_t num_nodes_edge_c2_r = (ORDER_R + 1) * 3;
 
   54    static const size_t num_nodes_edge_s = ORDER_S + 1;
 
   56    static const size_t num_nodes_edge_c1_s = (ORDER_S + 1) * 2;
 
   58    static const size_t num_nodes_edge_c2_s = (ORDER_S + 1) * 3;
 
   60    QuadBezier() : GenericShape((ORDER_R + 1) * (ORDER_S + 1), 4) {}
 
   62    IntegrationScheme create_ischeme()
 const {
 
   64        orig_ischeme[0].set_order(2 * ORDER_R);
 
   65        orig_ischeme[1].set_order(2 * ORDER_S);
 
   68        IntegrationScheme ischeme;
 
   69        for (
int i = 0; i != orig_ischeme.get_num(); ++i) {
 
   72            orig_ischeme.get_point(i, xi, weight);
 
   73            xi[0] = .5 * (xi[0] + 1);
 
   74            xi[1] = .5 * (xi[1] + 1);
 
   76            ischeme.points.push_back(IntegrationScheme::Point(xi, weight));
 
   81    int get_edge_order(
const int edge)
 const {
 
   82        assert(edge >= 0 && edge < 4);
 
   83        return (edge % 2 == 0 ? 2 * ORDER_R : 2 * ORDER_S);  
 
   86    int get_edge_shape_order(
const int edge)
 const {
 
   87        assert(edge >= 0 && edge < 4);
 
   88        return (edge % 2 == 0 ? ORDER_R : ORDER_S);
 
   91    void get_xi_all_from_xi_edge(
const int edge, 
const double xi, 
double xi_all[2])
 const {
 
   92        assert(edge >= 0 && edge < 4);
 
   93        const double mapping[4][2] = {{xi, 0.}, {1., xi}, {1 - xi, 1.}, {0., 1 - xi}};
 
   94        xi_all[0] = mapping[edge][0];
 
   95        xi_all[1] = mapping[edge][1];
 
   98    IntegrationScheme create_ischeme_edge(
const int edge)
 const {
 
   99        assert(edge >= 0 && edge < 4);
 
  101        orig_ischeme.set_order(get_edge_order(edge));
 
  103        IntegrationScheme ischeme;
 
  104        for (
int i = 0; i != orig_ischeme.get_num(); ++i) {
 
  107            orig_ischeme.get_point(i, xi, weight);
 
  110            const double mapping[4][2] = {{xi, 0.}, {1., xi}, {1 - xi, 1.}, {0., 1 - xi}};
 
  111            ischeme.points.push_back(
 
  112                  IntegrationScheme::Point(mapping[edge][0], mapping[edge][1], weight));
 
  117    void get_edge_direction(
const int edge, 
double edge_dir[2])
 const {
 
  118        assert(edge >= 0 && edge < 4);
 
  139    void get_node_indices(
const int sub_type, 
const int sub_index, b2linalg::Index& indices)
 const {
 
  141        if (sub_type == SUB_ALL) {
 
  142            indices.reserve(num_nodes);
 
  143            for (
size_t i = 0; i != num_nodes; ++i) { indices.push_back(i); }
 
  144        } 
else if (sub_type == SUB_EDGE_C0 || sub_type == SUB_EDGE_C1 || sub_type == SUB_EDGE_C2) {
 
  145            const int edge = sub_index;
 
  146            assert(edge >= 0 && edge < 4);
 
  147            const int continuity =
 
  148                  (sub_type == SUB_EDGE_C0 ? 0 : (sub_type == SUB_EDGE_C1 ? 1 : 2));
 
  150                const size_t n = num_nodes_edge_r * (1 + continuity);
 
  152                for (
size_t i = 0; i != n; ++i) {
 
  153                    const size_t ii = DATA::node_indices_edge_c2_r[edge / 2][i];
 
  154                    indices.push_back(ii);
 
  157                const size_t n = num_nodes_edge_s * (1 + continuity);
 
  159                for (
size_t i = 0; i != n; ++i) {
 
  160                    const size_t ii = DATA::node_indices_edge_c2_s[edge / 2][i];
 
  161                    indices.push_back(ii);
 
  165              sub_type == SUB_VERTEX_C0 || sub_type == SUB_VERTEX_C1 || sub_type == SUB_VERTEX_C2) {
 
  166            const int vertex = sub_index;
 
  167            assert(vertex >= 0 && vertex < 4);
 
  168            const int continuity =
 
  169                  (sub_type == SUB_VERTEX_C0 ? 0 : (sub_type == SUB_VERTEX_C1 ? 1 : 2));
 
  170            const size_t n = (continuity == 0 ? 1 : (continuity == 1 ? 3 : 6));
 
  172            for (
size_t i = 0; i != n; ++i) {
 
  173                const size_t ii = DATA::node_indices_vertex_c2[vertex][i];
 
  174                indices.push_back(ii);
 
  179    void compute_nodes_interpolation_straight_d0(
 
  180          const double xi[2], b2linalg::Vector<double, b2linalg::Vdense>& N)
 const {
 
  182        N[0] = (1 - xi[0]) * (1 - xi[1]);
 
  183        N[1] = xi[0] * (1 - xi[1]);
 
  184        N[2] = xi[0] * xi[1];
 
  185        N[3] = (1 - xi[0]) * xi[1];
 
  188    void compute_nodes_interpolation_straight_d1(
 
  189          const double xi[2], b2linalg::Matrix<double, b2linalg::Mrectangle>& N)
 const {
 
  192        N[d00][0] = (1 - xi[0]) * (1 - xi[1]);
 
  193        N[d00][1] = xi[0] * (1 - xi[1]);
 
  194        N[d00][2] = xi[0] * xi[1];
 
  195        N[d00][3] = (1 - xi[0]) * xi[1];
 
  197        N[d10][0] = -(1 - xi[1]);
 
  198        N[d10][1] = (1 - xi[1]);
 
  202        N[d01][0] = -(1 - xi[0]);
 
  205        N[d01][3] = (1 - xi[0]);
 
  208    void compute_nodes_interpolation_straight_d2(
 
  209          const double xi[2], b2linalg::Matrix<double, b2linalg::Mrectangle>& N)
 const {
 
  212        N[d00][0] = (1 - xi[0]) * (1 - xi[1]);
 
  213        N[d00][1] = xi[0] * (1 - xi[1]);
 
  214        N[d00][2] = xi[0] * xi[1];
 
  215        N[d00][3] = (1 - xi[0]) * xi[1];
 
  217        N[d10][0] = -(1 - xi[1]);
 
  218        N[d10][1] = (1 - xi[1]);
 
  222        N[d01][0] = -(1 - xi[0]);
 
  225        N[d01][3] = (1 - xi[0]);
 
  244template <
int ORDER_R, 
int ORDER_S, 
typename DATA>
 
  245const size_t QuadBezier<ORDER_R, ORDER_S, DATA>::num_nodes_edge_c1_r;
 
  247template <
int ORDER_R, 
int ORDER_S, 
typename DATA>
 
  248const size_t QuadBezier<ORDER_R, ORDER_S, DATA>::num_nodes_edge_c2_r;
 
  250template <
int ORDER_R, 
int ORDER_S, 
typename DATA>
 
  251const size_t QuadBezier<ORDER_R, ORDER_S, DATA>::num_nodes_edge_c1_s;
 
  253template <
int ORDER_R, 
int ORDER_S, 
typename DATA>
 
  254const size_t QuadBezier<ORDER_R, ORDER_S, DATA>::num_nodes_edge_c2_s;