16#ifndef _B2ELEMENT_KLT_COMPUTE_SHAPE_T_H_ 
   17#define _B2ELEMENT_KLT_COMPUTE_SHAPE_T_H_ 
   22#include "elements/klt_shells/b2element_klt_generic_shape.H" 
   23#include "elements/klt_shells/b2element_klt_util.H" 
   24#include "elements/smr/b2element_continuum_integrate.H" 
   25#include "elements/smr/b2element_continuum_shape.H" 
   26#include "elements/smr/b2element_continuum_util.H" 
   28#include "model/b2element.H" 
   29#include "model_imp/b2hnode.H" 
   34template <
int ORDER, 
typename DATA>
 
   35class TriangleBezier : 
public GenericShape {
 
   37    static const int order = ORDER;
 
   39    static const size_t num_nodes = (ORDER + 2) * (ORDER + 1) / 2;
 
   41    static const size_t num_nodes_edge_c0 = ORDER + 1;
 
   43    static const size_t num_nodes_edge_c1 = ORDER * 2 + 1;
 
   45    static const size_t num_nodes_edge_c2 = ORDER * 3;
 
   47    TriangleBezier() : GenericShape((ORDER + 2) * (ORDER + 1) / 2, 3) {}
 
   49    IntegrationScheme create_ischeme()
 const {
 
   51        orig_ischeme.set_order((ORDER - 1) * 2);  
 
   52        IntegrationScheme ischeme;
 
   53        for (
int i = 0; i != orig_ischeme.get_num(); ++i) {
 
   56            orig_ischeme.get_point(i, xi, weight);
 
   57            ischeme.points.push_back(IntegrationScheme::Point(xi, weight));
 
   62    int get_edge_order(
const int edge)
 const {
 
   63        assert(edge >= 0 && edge < 3);
 
   67    int get_edge_shape_order(
const int edge)
 const {
 
   68        assert(edge >= 0 && edge < 3);
 
   72    void get_xi_all_from_xi_edge(
const int edge, 
const double xi, 
double xi_all[2])
 const {
 
   73        assert(edge >= 0 && edge < 3);
 
   74        const double mapping[3][2] = {{xi, 0.}, {1. - xi, xi}, {0, 1. - xi}};
 
   75        xi_all[0] = mapping[edge][0];
 
   76        xi_all[1] = mapping[edge][1];
 
   79    IntegrationScheme create_ischeme_edge(
const int edge)
 const {
 
   80        assert(edge >= 0 && edge < 3);
 
   82        orig_ischeme.set_order(get_edge_order(edge));
 
   84        IntegrationScheme ischeme;
 
   85        for (
int i = 0; i != orig_ischeme.get_num(); ++i) {
 
   88            orig_ischeme.get_point(i, xi, weight);
 
   89            const double er = .5 * (1 + xi);
 
   90            const double mapping[3][2] = {{er, 0}, {1 - er, er}, {0, 1 - er}};
 
   91            ischeme.points.push_back(
 
   92                  IntegrationScheme::Point(mapping[edge][0], mapping[edge][1], .5 * weight));
 
   97    void get_edge_direction(
const int edge, 
double edge_dir[2])
 const {
 
   98        assert(edge >= 0 && edge < 3);
 
  115    void get_node_indices(
const int sub_type, 
const int sub_index, b2linalg::Index& indices)
 const {
 
  117        if (sub_type == SUB_ALL) {
 
  118            indices.reserve(num_nodes);
 
  119            for (
size_t i = 0; i != num_nodes; ++i) { indices.push_back(i); }
 
  120        } 
else if (sub_type == SUB_EDGE_C0 || sub_type == SUB_EDGE_C1 || sub_type == SUB_EDGE_C2) {
 
  121            const int edge = sub_index;
 
  122            assert(edge >= 0 && edge < 3);
 
  123            const int continuity =
 
  124                  (sub_type == SUB_EDGE_C0 ? 0 : (sub_type == SUB_EDGE_C1 ? 1 : 2));
 
  126                  (continuity == 0 ? num_nodes_edge_c0
 
  127                                   : (continuity == 1 ? num_nodes_edge_c1 : num_nodes_edge_c2));
 
  129            for (
size_t i = 0; i != n; ++i) {
 
  130                const size_t ii = DATA::node_indices_edge_c2[edge][i];
 
  131                indices.push_back(ii);
 
  134              sub_type == SUB_VERTEX_C0 || sub_type == SUB_VERTEX_C1 || sub_type == SUB_VERTEX_C2) {
 
  135            const int vertex = sub_index;
 
  136            assert(vertex >= 0 && vertex < 3);
 
  137            const int continuity =
 
  138                  (sub_type == SUB_VERTEX_C0 ? 0 : (sub_type == SUB_VERTEX_C1 ? 1 : 2));
 
  139            const size_t n = (continuity == 0 ? 1 : (continuity == 1 ? 3 : 6));
 
  141            for (
size_t i = 0; i != n; ++i) {
 
  142                const size_t ii = DATA::node_indices_vertex_c2[vertex][i];
 
  143                indices.push_back(ii);
 
  148    void compute_nodes_interpolation_straight_d0(
 
  149          const double xi[2], b2linalg::Vector<double, b2linalg::Vdense>& N)
 const {
 
  151        N[0] = 1 - xi[0] - xi[1];
 
  156    void compute_nodes_interpolation_straight_d1(
 
  157          const double xi[2], b2linalg::Matrix<double, b2linalg::Mrectangle>& N)
 const {
 
  160        N[d00][0] = 1 - xi[0] - xi[1];
 
  173    void compute_nodes_interpolation_straight_d2(
 
  174          const double xi[2], b2linalg::Matrix<double, b2linalg::Mrectangle>& N)
 const {
 
  177        N[d00][0] = 1 - xi[0] - xi[1];
 
  203template <
int ORDER, 
typename DATA>
 
  204const size_t TriangleBezier<ORDER, DATA>::num_nodes_edge_c0;
 
  206template <
int ORDER, 
typename DATA>
 
  207const size_t TriangleBezier<ORDER, DATA>::num_nodes_edge_c1;
 
  209template <
int ORDER, 
typename DATA>
 
  210const size_t TriangleBezier<ORDER, DATA>::num_nodes_edge_c2;