PeriDEM 0.2.0
PeriDEM -- Peridynamics-based high-fidelity model for granular media
Loading...
Searching...
No Matches
quadElem.cpp
Go to the documentation of this file.
1/*
2 * -------------------------------------------
3 * Copyright (c) 2021 - 2024 Prashant K. Jha
4 * -------------------------------------------
5 * PeriDEM https://github.com/prashjha/PeriDEM
6 *
7 * Distributed under the Boost Software License, Version 1.0. (See accompanying
8 * file LICENSE)
9 */
10
11#include "quadElem.h"
12#include "util/feElementDefs.h" // global definition of elements
13
15 : fe::BaseElem(order, util::vtk_type_quad) {
16
17 // compute quad data
18 this->init();
19}
20
21double fe::QuadElem::elemSize(const std::vector<util::Point> &nodes) {
22 return 0.25 *
23 ((-nodes[0].d_x + nodes[1].d_x + nodes[2].d_x - nodes[3].d_x) *
24 (-nodes[0].d_y - nodes[1].d_y + nodes[2].d_y + nodes[3].d_y) -
25 (-nodes[0].d_x - nodes[1].d_x + nodes[2].d_x + nodes[3].d_x) *
26 (-nodes[0].d_y + nodes[1].d_y + nodes[2].d_y - nodes[3].d_y));
27}
28
29
30
31std::vector<fe::QuadData>
32fe::QuadElem::getQuadDatas(const std::vector<util::Point> &nodes) {
33
34 // copy quad data associated to reference element
35 auto qds = d_quads;
36
37 // modify data
38 for (auto &qd : qds) {
39
40 // get Jacobian and determinant
41 qd.d_detJ = getJacobian(qd.d_p, nodes, &(qd.d_J));
42
43 // transform quad weight
44 qd.d_w *= qd.d_detJ;
45
46 // map point to triangle
47 qd.d_p.d_x = qd.d_shapes[0] * nodes[0].d_x + qd.d_shapes[1] * nodes[1].d_x +
48 qd.d_shapes[2] * nodes[2].d_x + qd.d_shapes[3] * nodes[3].d_x;
49 qd.d_p.d_y = qd.d_shapes[0] * nodes[0].d_y + qd.d_shapes[1] * nodes[1].d_y +
50 qd.d_shapes[2] * nodes[2].d_y + qd.d_shapes[3] * nodes[3].d_y;
51
52 // derivatives of shape function
53 std::vector<std::vector<double>> ders;
54
55 for (size_t i=3; i<4; i++) {
56 // partial N_i/ partial x
57 auto d1 = (qd.d_derShapes[i][0] * qd.d_J[1][1] - qd.d_derShapes[i][1] *
58 qd.d_J[0][1]) / qd.d_detJ;
59 // partial N_i/ partial y
60 auto d2 = (-qd.d_derShapes[i][0] * qd.d_J[1][0] + qd.d_derShapes[i][1] *
61 qd.d_J[0][0]) / qd.d_detJ;
62
63 ders.push_back(std::vector<double>{d1, d2});
64 }
65 qd.d_derShapes = ders;
66 }
67
68 return qds;
69}
70
71std::vector<fe::QuadData>
72fe::QuadElem::getQuadPoints(const std::vector<util::Point> &nodes) {
73
74 // copy quad data associated to reference element
75 auto qds = d_quads;
76
77 // modify data
78 for (auto &qd : qds) {
79
80 // transform quad weight
81 qd.d_w *= getJacobian(qd.d_p, nodes, nullptr);
82
83 // map point to triangle
84 qd.d_p.d_x = qd.d_shapes[0] * nodes[0].d_x + qd.d_shapes[1] * nodes[1].d_x +
85 qd.d_shapes[2] * nodes[2].d_x + qd.d_shapes[3] * nodes[3].d_x;
86 qd.d_p.d_y = qd.d_shapes[0] * nodes[0].d_y + qd.d_shapes[1] * nodes[1].d_y +
87 qd.d_shapes[2] * nodes[2].d_y + qd.d_shapes[3] * nodes[3].d_y;
88 }
89
90 return qds;
91}
92
93std::vector<double> fe::QuadElem::getShapes(const util::Point &p) {
94
95 // N1 = (1 - xi)(1 - eta)/4
96 // N2 = (1 + xi)(1 - eta)/4
97 // N3 = (1 + xi)(1 + eta)/4
98 // N4 = (1 - xi)(1 + eta)/4
99 return std::vector<double>{
100 0.25 * (1. - p.d_x) * (1. - p.d_y), 0.25 * (1. + p.d_x) * (1. - p.d_y),
101 0.25 * (1. + p.d_x) * (1. + p.d_y), 0.25 * (1. - p.d_x) * (1. + p.d_y)};
102}
103
104std::vector<std::vector<double>>
106
107 // N1 = (1 - xi)(1 - eta)/4
108 // --> d N1/d xi = -(1 - eta)/4, d N1/d eta = -(1 - xi)/4
109 //
110 // N2 = (1 + xi)(1 - eta)/4
111 // --> d N2/d xi = (1 - eta)/4, d N2/d eta = -(1 + xi)/4
112 //
113 // N3 = (1 + xi)(1 + eta)/4
114 // --> d N3/d xi = (1 + eta)/4, d N3/d eta = (1 + xi)/4
115 //
116 // N4 = (1 - xi)(1 + eta)/4
117 // --> d N4/d xi = -(1 + eta)/4, d N4/d eta = (1 - xi)/4
118 std::vector<std::vector<double>> r;
119 r.push_back(std::vector<double>{-0.25 * (1. - p.d_y), -0.25 * (1. - p.d_x)});
120 r.push_back(std::vector<double>{0.25 * (1. - p.d_y), -0.25 * (1. + p.d_x)});
121 r.push_back(std::vector<double>{0.25 * (1. + p.d_y), 0.25 * (1. + p.d_x)});
122 r.push_back(std::vector<double>{-0.25 * (1. + p.d_y), 0.25 * (1. - p.d_x)});
123
124 return r;
125}
126
128 const std::vector<util::Point> &nodes,
129 std::vector<std::vector<double>> *J) {
130
131 auto der_shapes = getDerShapes(p);
132 if (J != nullptr) {
133 J->resize(2);
134 (*J)[0] = std::vector<double>{
135 der_shapes[0][0] * nodes[0].d_x + der_shapes[1][0] * nodes[1].d_x +
136 der_shapes[2][0] * nodes[2].d_x + der_shapes[3][0] * nodes[3].d_x,
137 der_shapes[0][0] * nodes[0].d_y + der_shapes[1][0] * nodes[1].d_y +
138 der_shapes[2][0] * nodes[2].d_y + der_shapes[3][0] * nodes[3].d_y};
139 (*J)[1] = std::vector<double>{
140 der_shapes[0][1] * nodes[0].d_x + der_shapes[1][1] * nodes[1].d_x +
141 der_shapes[2][1] * nodes[2].d_x + der_shapes[3][1] * nodes[3].d_x,
142 der_shapes[0][1] * nodes[0].d_y + der_shapes[1][1] * nodes[1].d_y +
143 der_shapes[2][1] * nodes[2].d_y + der_shapes[3][1] * nodes[3].d_y};
144
145 return (*J)[0][0] * (*J)[1][1] - (*J)[0][1] * (*J)[1][0];
146 }
147
148 return (der_shapes[0][0] * nodes[0].d_x + der_shapes[1][0] * nodes[1].d_x +
149 der_shapes[2][0] * nodes[2].d_x + der_shapes[3][0] * nodes[3].d_x) *
150 (der_shapes[0][1] * nodes[0].d_y +
151 der_shapes[1][1] * nodes[1].d_y +
152 der_shapes[2][1] * nodes[2].d_y +
153 der_shapes[3][1] * nodes[3].d_y) -
154 (der_shapes[0][0] * nodes[0].d_y + der_shapes[1][0] * nodes[1].d_y +
155 der_shapes[2][0] * nodes[2].d_y + der_shapes[3][0] * nodes[3].d_y) *
156 (der_shapes[0][1] * nodes[0].d_x +
157 der_shapes[1][1] * nodes[1].d_x +
158 der_shapes[2][1] * nodes[2].d_x +
159 der_shapes[3][1] * nodes[3].d_x);
160}
161
163
164 //
165 // compute quad data for reference quadrangle with vertex at
166 // p1 = (-1,-1), p2 = (1,-1), p3 = (1,1), p4 = (-1,1)
167 //
168 // Shape functions are
169 // N1 = (1 - xi)(1 - eta)/4
170 // N2 = (1 + xi)(1 - eta)/4
171 // N3 = (1 + xi)(1 + eta)/4
172 // N4 = (1 - xi)(1 + eta)/4
173 //
174 //
175 // Let [-1,1] is the 1-d reference element and {x1, x2, x3,.., xN} are N
176 // quad points for 1-d domain and {w1, w2, w3,..., wN} are respective
177 // weights. Then, the Nth order quad points in Quadrangle [-1,1]x[-1,1] is
178 // simply given by N^2 points and
179 //
180 // (i,j) point is (xi, xj) and weight is wi \times wj
181 //
182
183 if (!d_quads.empty())
184 return;
185
186 // no point in zeroth order
187 if (d_quadOrder == 0)
188 d_quads.resize(0);
189
190 // 2x2 identity matrix
191 std::vector<std::vector<double>> ident_mat;
192 ident_mat.push_back(std::vector<double>{1., 0.});
193 ident_mat.push_back(std::vector<double>{0., 1.});
194
195 //
196 // first order quad points
197 //
198 if (d_quadOrder == 1) {
199 d_quads.clear();
200 // 1-d points are: {0} and weights are: {2}
201 int npts = 1;
202 std::vector<double> x = std::vector<double>(1, 0.);
203 std::vector<double> w = std::vector<double>(1, 2.);
204 for (size_t i = 0; i < npts; i++)
205 for (size_t j = 0; j < npts; j++) {
206
207 fe::QuadData qd;
208 qd.d_w = w[i] * w[j];
209 qd.d_p = util::Point(x[i], x[j], 0.);
210 qd.d_shapes = getShapes(qd.d_p);
211 qd.d_derShapes = getDerShapes(qd.d_p);
212 qd.d_J = ident_mat;
213 qd.d_detJ = 1.;
214 d_quads.push_back(qd);
215 }
216 }
217
218 //
219 // second order quad points
220 //
221 if (d_quadOrder == 2) {
222 d_quads.clear();
223 // 1-d points are: {-1/sqrt{3], 1/sqrt{3}} and weights are: {1,1}
224 int npts = 2;
225 std::vector<double> x =
226 std::vector<double>{-1. / std::sqrt(3.), 1. / std::sqrt(3.)};
227 std::vector<double> w = std::vector<double>{1., 1.};
228 for (size_t i = 0; i < npts; i++)
229 for (size_t j = 0; j < npts; j++) {
230
231 fe::QuadData qd;
232 qd.d_w = w[i] * w[j];
233 qd.d_p = util::Point(x[i], x[j], 0.);
234 qd.d_shapes = getShapes(qd.d_p);
235 qd.d_derShapes = getDerShapes(qd.d_p);
236 qd.d_J = ident_mat;
237 qd.d_detJ = 1.;
238 d_quads.push_back(qd);
239 }
240 }
241
242 //
243 // third order quad points
244 //
245 if (d_quadOrder == 3) {
246 d_quads.clear();
247 // 1-d points are: {-sqrt{3}/sqrt{5}, 0, sqrt{3}/sqrt{5}}
248 // weights are: {5/9, 8/9, 5/9}
249 int npts = 3;
250 std::vector<double> x = std::vector<double>{
251 -std::sqrt(3.) / std::sqrt(5.), 0., std::sqrt(3.) / std::sqrt(5.)};
252 std::vector<double> w = std::vector<double>{5. / 9., 8. / 9., 5. / 9.};
253 for (size_t i = 0; i < npts; i++)
254 for (size_t j = 0; j < npts; j++) {
255
256 fe::QuadData qd;
257 qd.d_w = w[i] * w[j];
258 qd.d_p = util::Point(x[i], x[j], 0.);
259 qd.d_shapes = getShapes(qd.d_p);
260 qd.d_derShapes = getDerShapes(qd.d_p);
261 qd.d_J = ident_mat;
262 qd.d_detJ = 1.;
263 d_quads.push_back(qd);
264 }
265 }
266
267 //
268 // fourth order quad points
269 //
270 if (d_quadOrder == 4) {
271 d_quads.clear();
272 int npts = 4;
273 std::vector<double> x =
274 std::vector<double>{-0.3399810435848563, 0.3399810435848563,
275 -0.8611363115940526, 0.8611363115940526};
276 std::vector<double> w =
277 std::vector<double>{0.6521451548625461, 0.6521451548625461,
278 0.3478548451374538, 0.3478548451374538};
279 for (size_t i = 0; i < npts; i++)
280 for (size_t j = 0; j < npts; j++) {
281
282 fe::QuadData qd;
283 qd.d_w = w[i] * w[j];
284 qd.d_p = util::Point(x[i], x[j], 0.);
285 qd.d_shapes = getShapes(qd.d_p);
286 qd.d_derShapes = getDerShapes(qd.d_p);
287 qd.d_J = ident_mat;
288 qd.d_detJ = 1.;
289 d_quads.push_back(qd);
290 }
291 }
292
293 //
294 // fifth order quad points
295 //
296 if (d_quadOrder == 5) {
297 d_quads.clear();
298 int npts = 5;
299 std::vector<double> x =
300 std::vector<double>{0., -0.5384693101056831, 0.5384693101056831,
301 -0.9061798459386640, 0.9061798459386640};
302 std::vector<double> w = std::vector<double>{
303 0.5688888888888889, 0.4786286704993665, 0.4786286704993665,
304 0.2369268850561891, 0.2369268850561891};
305 for (size_t i = 0; i < npts; i++)
306 for (size_t j = 0; j < npts; j++) {
307
308 fe::QuadData qd;
309 qd.d_w = w[i] * w[j];
310 qd.d_p = util::Point(x[i], x[j], 0.);
311 qd.d_shapes = getShapes(qd.d_p);
312 qd.d_derShapes = getDerShapes(qd.d_p);
313 qd.d_J = ident_mat;
314 qd.d_detJ = 1.;
315 d_quads.push_back(qd);
316 }
317 }
318}
A base class which provides methods to map points to/from reference element and to compute quadrature...
Definition baseElem.h:84
double getJacobian(const util::Point &p, const std::vector< util::Point > &nodes, std::vector< std::vector< double > > *J) override
Computes the Jacobian of map .
Definition quadElem.cpp:127
std::vector< fe::QuadData > getQuadDatas(const std::vector< util::Point > &nodes) override
Get vector of quadrature data.
Definition quadElem.cpp:32
void init() override
Compute the quadrature points for quadrangle element.
Definition quadElem.cpp:162
std::vector< double > getShapes(const util::Point &p) override
Returns the values of shape function at point p on reference element.
Definition quadElem.cpp:93
std::vector< std::vector< double > > getDerShapes(const util::Point &p) override
Returns the values of derivative of shape function at point p on reference element.
Definition quadElem.cpp:105
double elemSize(const std::vector< util::Point > &nodes) override
Returns the area of element.
Definition quadElem.cpp:21
std::vector< fe::QuadData > getQuadPoints(const std::vector< util::Point > &nodes) override
Get vector of quadrature data.
Definition quadElem.cpp:72
QuadElem(size_t order)
Constructor for quadrangle element.
Definition quadElem.cpp:14
Collection of methods and data related to finite element and mesh.
Definition baseElem.h:17
Collection of methods useful in simulation.
A struct to store the quadrature data. List of data are.
Definition quadData.h:23
std::vector< double > d_shapes
Value of shape functions at quad point p.
Definition quadData.h:37
std::vector< std::vector< double > > d_derShapes
Value of derivative of shape functions at quad point p.
Definition quadData.h:50
double d_w
Quadrature weight.
Definition quadData.h:26
util::Point d_p
Quadrature point in 1-d, 2-d or 3-d.
Definition quadData.h:29
std::vector< std::vector< double > > d_J
Jacobian of the map from reference element to the element.
Definition quadData.h:58
double d_detJ
Determinant of the Jacobian of the map from reference element to the element.
Definition quadData.h:64
A structure to represent 3d vectors.
Definition point.h:30
double d_y
the y coordinate
Definition point.h:36
double d_x
the x coordinate
Definition point.h:33