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;