b2api
B2000++ API Reference Manual, VERSION 4.6
 
Loading...
Searching...
No Matches
b2element_klt_compute_shape_t.H
1//------------------------------------------------------------------------
2// b2element_klt_compute_shape_t.H --
3//
4// Compute shape functions and derivatives for Bezier triangles.
5//
6// Copyright (c) 2015,2016,2017
7// SMR Engineering & Development SA
8// 2502 Bienne, Switzerland
9//
10// All Rights Reserved. Proprietary source code. The contents of
11// this file may not be disclosed to third parties, copied or
12// duplicated in any form, in whole or in part, without the prior
13// written permission of SMR.
14//------------------------------------------------------------------------
15
16#ifndef _B2ELEMENT_KLT_COMPUTE_SHAPE_T_H_
17#define _B2ELEMENT_KLT_COMPUTE_SHAPE_T_H_
18
19#include <algorithm>
20#include <cassert>
21
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"
27#include "model/b2domain.H"
28#include "model/b2element.H"
29#include "model_imp/b2hnode.H"
31
32namespace b2000::klt {
33
34template <int ORDER, typename DATA>
35class TriangleBezier : public GenericShape {
36public:
37 static const int order = ORDER;
38
39 static const size_t num_nodes = (ORDER + 2) * (ORDER + 1) / 2;
40
41 static const size_t num_nodes_edge_c0 = ORDER + 1;
42
43 static const size_t num_nodes_edge_c1 = ORDER * 2 + 1;
44
45 static const size_t num_nodes_edge_c2 = ORDER * 3;
46
47 TriangleBezier() : GenericShape((ORDER + 2) * (ORDER + 1) / 2, 3) {}
48
49 IntegrationScheme create_ischeme() const {
50 IS_T orig_ischeme;
51 orig_ischeme.set_order((ORDER - 1) * 2); // XXX change
52 IntegrationScheme ischeme;
53 for (int i = 0; i != orig_ischeme.get_num(); ++i) {
54 double xi[2];
55 double weight;
56 orig_ischeme.get_point(i, xi, weight);
57 ischeme.points.push_back(IntegrationScheme::Point(xi, weight));
58 }
59 return ischeme;
60 }
61
62 int get_edge_order(const int edge) const {
63 assert(edge >= 0 && edge < 3);
64 return 2 * ORDER; // XXX change
65 }
66
67 int get_edge_shape_order(const int edge) const {
68 assert(edge >= 0 && edge < 3);
69 return ORDER;
70 }
71
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];
77 }
78
79 IntegrationScheme create_ischeme_edge(const int edge) const {
80 assert(edge >= 0 && edge < 3);
81 IS_L orig_ischeme;
82 orig_ischeme.set_order(get_edge_order(edge));
83
84 IntegrationScheme ischeme;
85 for (int i = 0; i != orig_ischeme.get_num(); ++i) {
86 double xi;
87 double weight;
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));
93 }
94 return ischeme;
95 }
96
97 void get_edge_direction(const int edge, double edge_dir[2]) const {
98 assert(edge >= 0 && edge < 3);
99 switch (edge) {
100 case 0:
101 edge_dir[0] = 1;
102 edge_dir[1] = 0;
103 break;
104 case 1:
105 edge_dir[0] = -1;
106 edge_dir[1] = 1;
107 break;
108 case 2:
109 edge_dir[0] = 0;
110 edge_dir[1] = -1;
111 break;
112 }
113 }
114
115 void get_node_indices(const int sub_type, const int sub_index, b2linalg::Index& indices) const {
116 indices.clear();
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));
125 const size_t n =
126 (continuity == 0 ? num_nodes_edge_c0
127 : (continuity == 1 ? num_nodes_edge_c1 : num_nodes_edge_c2));
128 indices.reserve(n);
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);
132 }
133 } else if (
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));
140 indices.reserve(n);
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);
144 }
145 }
146 }
147
148 void compute_nodes_interpolation_straight_d0(
149 const double xi[2], b2linalg::Vector<double, b2linalg::Vdense>& N) const {
150 N.resize(3);
151 N[0] = 1 - xi[0] - xi[1];
152 N[1] = xi[0];
153 N[2] = xi[1];
154 }
155
156 void compute_nodes_interpolation_straight_d1(
157 const double xi[2], b2linalg::Matrix<double, b2linalg::Mrectangle>& N) const {
158 N.resize(3, 3);
159
160 N[d00][0] = 1 - xi[0] - xi[1];
161 N[d00][1] = xi[0];
162 N[d00][2] = xi[1];
163
164 N[d10][0] = -1;
165 N[d10][1] = 1;
166 N[d10][2] = 0;
167
168 N[d01][0] = -1;
169 N[d01][1] = 0;
170 N[d01][2] = 1;
171 }
172
173 void compute_nodes_interpolation_straight_d2(
174 const double xi[2], b2linalg::Matrix<double, b2linalg::Mrectangle>& N) const {
175 N.resize(3, 6);
176
177 N[d00][0] = 1 - xi[0] - xi[1];
178 N[d00][1] = xi[0];
179 N[d00][2] = xi[1];
180
181 N[d10][0] = -1;
182 N[d10][1] = 1;
183 N[d10][2] = 0;
184
185 N[d01][0] = -1;
186 N[d01][1] = 0;
187 N[d01][2] = 1;
188
189 N[d20][0] = 0;
190 N[d20][1] = 0;
191 N[d20][2] = 0;
192
193 N[d11][0] = 0;
194 N[d11][1] = 0;
195 N[d11][2] = 0;
196
197 N[d02][0] = 0;
198 N[d02][1] = 0;
199 N[d02][2] = 0;
200 }
201};
202
203template <int ORDER, typename DATA>
204const size_t TriangleBezier<ORDER, DATA>::num_nodes_edge_c0;
205
206template <int ORDER, typename DATA>
207const size_t TriangleBezier<ORDER, DATA>::num_nodes_edge_c1;
208
209template <int ORDER, typename DATA>
210const size_t TriangleBezier<ORDER, DATA>::num_nodes_edge_c2;
211
212} // namespace b2000::klt
213
214#endif // B2ELEMENT_KLT_COMPUTE_SHAPE_T_H_