PolyFEM
Loading...
Searching...
No Matches
prism_bases.cpp
Go to the documentation of this file.
1#include "prism_bases.hpp"
2
3#include "auto_p_bases.hpp"
4#include "auto_q_bases.hpp"
5
6namespace polyfem
7{
8 namespace autogen
9 {
10 namespace
11 {
12 int index_mapping(const int p, const int q, const int i)
13 {
14 // base vertices
15 if (i < 3)
16 return i;
17 const int npe = (p - 1) * 3;
18 const int npf = std::max(0, (p - 1) * (p - 2) / 2);
19 const int nl = 3 + npe + npf;
20 const int nqe = q - 1;
21
22 // top vertices
23 if (i >= nl * q && i < nl * q + 3)
24 return i - nl * q + 3;
25
26 // base edges
27 if (i >= 3 && i < 3 + npe)
28 return i - 3 + 6;
29
30 // top edges
31 if (i >= nl * q + 3 && i < nl * q + 3 + npe)
32 return i - nl * q - 3 + 6 + npe;
33
34 // first vertical edge
35 if (i % nl == 0)
36 return 6 + 2 * npe + i / nl - 1;
37
38 // second vertical edge
39 if (i % nl == 1)
40 return 6 + 2 * npe + i / nl - 1 + nqe;
41
42 // third vertical edge
43 if (i % nl == 2)
44 return 6 + 2 * npe + i / nl - 1 + 2 * nqe;
45
46 // base face
47 if (i >= 3 + npe && i < 3 + npe + npf)
48 return 6 + 2 * npe + 3 * nqe + i - (3 + npe);
49
50 // top face
51 if (i >= nl * q + 3 + npe && i < nl * q + 3 + npe + npf)
52 return 6 + 2 * npe + 3 * nqe + i - (nl * q + 3 + npe) + npf;
53
54 int mod = i % nl - 3;
55 const int div = i / nl - 1;
56
57 // quad faces
58 if (mod < npe)
59 return 2 * nl + nqe * 3 + (mod % (npe / 3)) + (mod / (npe / 3)) * npe / 3 * nqe + div * npe / 3;
60 mod -= npe;
61 // volume
62 if (mod < npf)
63 return 2 * nl + nqe * 3 + npe * nqe + mod + npf * div;
64
65 // assert false
66 return -1;
67 }
68
69 int inverse_index_mapping(const int p, const int q, const int li)
70 {
71 Eigen::MatrixXd tmpp, tmpq;
72
73 p_nodes_2d(p, tmpp);
74 q_nodes_1d(q, tmpq);
75
76 int index = 0;
77
78 for (int i = 0; i < tmpq.rows(); ++i)
79 {
80 for (int j = 0; j < tmpp.rows(); ++j)
81 {
82 if (index_mapping(p, q, index) == li)
83 return index;
84 ++index;
85 }
86 }
87 assert(false);
88 return -1;
89 }
90 } // namespace
91
92 void prism_nodes_3d(const int p, const int q, Eigen::MatrixXd &val)
93 {
94 Eigen::MatrixXd tmpp, tmpq;
95
96 p_nodes_2d(p, tmpp);
97 q_nodes_1d(q, tmpq);
98
99 val.resize(tmpp.rows() * tmpq.rows(), 3);
100 int index = 0;
101
102 for (int i = 0; i < tmpq.rows(); ++i)
103 {
104 for (int j = 0; j < tmpp.rows(); ++j)
105 {
106 val.row(index_mapping(p, q, index)) << tmpp(j, 0), tmpp(j, 1), tmpq(i, 0);
107 ++index;
108 }
109 }
110 }
111
112 void prism_basis_value_3d(const int p, const int q, const int li, const Eigen::MatrixXd &uv, Eigen::MatrixXd &val)
113 {
114 assert(uv.cols() == 3);
115
116 Eigen::MatrixXd tmpp, tmpq;
117
118 Eigen::MatrixXd nn;
119 p_nodes_2d(p, nn);
120 const int n_p = nn.rows();
121
122 const int local_index = inverse_index_mapping(p, q, li);
123
124 p_basis_value_2d(false, p, local_index % n_p, uv.leftCols(2), tmpp);
125 q_basis_value_1d(q, local_index / n_p, uv.col(2), tmpq);
126
127 val = tmpp.array() * tmpq.array();
128 }
129
130 void prism_grad_basis_value_3d(const int p, const int q, const int li, const Eigen::MatrixXd &uv, Eigen::MatrixXd &val)
131 {
132 assert(uv.cols() == 3);
133
134 Eigen::MatrixXd nn;
135 p_nodes_2d(p, nn);
136 const int n_p = nn.rows();
137
138 Eigen::MatrixXd tmpp, tmpq, tmpgp, tmpgq;
139
140 const int local_index = inverse_index_mapping(p, q, li);
141
142 p_basis_value_2d(false, p, local_index % n_p, uv.leftCols(2), tmpp);
143 q_basis_value_1d(q, local_index / n_p, uv.col(2), tmpq);
144
145 p_grad_basis_value_2d(false, p, local_index % n_p, uv.leftCols(2), tmpgp);
146 q_grad_basis_value_1d(q, local_index / n_p, uv.col(2), tmpgq);
147
148 val.resize(uv.rows(), 3);
149 val.col(0) = tmpgp.col(0).array() * tmpq.array();
150 val.col(1) = tmpgp.col(1).array() * tmpq.array();
151 val.col(2) = tmpp.array() * tmpgq.array();
152 }
153 } // namespace autogen
154} // namespace polyfem
double val
Definition Assembler.cpp:86
void p_grad_basis_value_2d(const bool bernstein, const int p, const int local_index, const Eigen::MatrixXd &uv, Eigen::MatrixXd &val)
void prism_basis_value_3d(const int p, const int q, const int li, const Eigen::MatrixXd &uv, Eigen::MatrixXd &val)
void prism_grad_basis_value_3d(const int p, const int q, const int li, const Eigen::MatrixXd &uv, Eigen::MatrixXd &val)
void prism_nodes_3d(const int p, const int q, Eigen::MatrixXd &val)
void q_basis_value_1d(const int q, const int local_index, const Eigen::MatrixXd &uv, Eigen::MatrixXd &val)
void p_nodes_2d(const int p, Eigen::MatrixXd &val)
void q_grad_basis_value_1d(const int q, const int local_index, const Eigen::MatrixXd &uv, Eigen::MatrixXd &val)
void p_basis_value_2d(const bool bernstein, const int p, const int local_index, const Eigen::MatrixXd &uv, Eigen::MatrixXd &val)
void q_nodes_1d(const int q, Eigen::MatrixXd &val)