58 const unsigned int &num_basis_functions,
59 const unsigned int &num_virtual_basis_functions,
60 const std::vector<Polydim::FEM::PCC::FEM_Triangle_PCC_2D_LocalSpace_Data> &fem_local_space_data,
61 const Eigen::MatrixXi &local_to_global)
const
64 const unsigned int num_quadrature =
66 const unsigned int num_triangles = fem_local_space_data.size();
68 Eigen::MatrixXd total_fem_basis_functions_values =
69 Eigen::MatrixXd::Zero(num_quadrature * num_triangles, num_basis_functions + num_virtual_basis_functions);
71 unsigned int offeset_quadrature_points = 0;
72 for (
unsigned int t = 0; t < num_triangles; t++)
74 const Eigen::MatrixXd fem_basis_function_values =
76 fem_local_space_data[t]);
78 for (
unsigned int p = 0; p < local_to_global.cols(); p++)
79 total_fem_basis_functions_values.block(offeset_quadrature_points, local_to_global(t, p), num_quadrature, 1) =
80 fem_basis_function_values.col(p);
82 offeset_quadrature_points += num_quadrature;
85 return total_fem_basis_functions_values;
89 const unsigned int &num_basis_functions,
90 const unsigned int &num_virtual_basis_functions,
91 const std::vector<Polydim::FEM::PCC::FEM_Triangle_PCC_2D_LocalSpace_Data> &fem_local_space_data,
92 const Eigen::MatrixXi &local_to_global,
93 const std::vector<Eigen::MatrixXd> &points)
const
96 unsigned int num_quadrature = 0;
98 for (
unsigned int t = 0; t < points.size(); t++)
99 num_quadrature += points[t].cols();
101 Eigen::MatrixXd total_fem_basis_functions_values =
102 Eigen::MatrixXd::Zero(num_quadrature, num_basis_functions + num_virtual_basis_functions);
104 unsigned int offeset_quadrature_points = 0;
105 for (
unsigned int t = 0; t < points.size(); t++)
107 if (points[t].size() > 0)
110 const unsigned int num_ref_quadrature = points[t].cols();
112 const Eigen::MatrixXd fem_basis_function_values =
114 fem_local_space_data[t],
117 for (
unsigned int p = 0; p < local_to_global.cols(); p++)
118 total_fem_basis_functions_values.block(offeset_quadrature_points, local_to_global(t, p), num_ref_quadrature, 1) =
119 fem_basis_function_values.col(p);
121 offeset_quadrature_points += num_ref_quadrature;
125 return total_fem_basis_functions_values;
129 unsigned int dimension,
131 const unsigned int &num_basis_functions,
132 const unsigned int &num_virtual_basis_functions,
133 const std::vector<Polydim::FEM::PCC::FEM_Triangle_PCC_2D_LocalSpace_Data> &fem_local_space_data,
134 const Eigen::MatrixXi &local_to_global)
const
137 const unsigned int num_quadrature =
139 const unsigned int num_triangles = fem_local_space_data.size();
141 std::vector<Eigen::MatrixXd> total_fem_basis_functions_derivative_values(
143 Eigen::MatrixXd::Zero(num_quadrature * num_triangles, num_basis_functions + num_virtual_basis_functions));
145 unsigned int offeset_quadrature_points = 0;
146 for (
unsigned int t = 0; t < num_triangles; t++)
149 const std::vector<Eigen::MatrixXd> fem_basis_function_derivatives_values =
151 fem_local_space_data[t]);
153 for (
unsigned int d = 0; d < dimension; d++)
155 for (
unsigned int p = 0; p < local_to_global.cols(); p++)
156 total_fem_basis_functions_derivative_values[d].block(offeset_quadrature_points, local_to_global(t, p), num_quadrature, 1) =
157 fem_basis_function_derivatives_values[d].col(p);
160 offeset_quadrature_points += num_quadrature;
163 return total_fem_basis_functions_derivative_values;
167 unsigned int dimension,
169 const unsigned int &num_basis_functions,
170 const unsigned int &num_virtual_basis_functions,
171 const std::vector<Polydim::FEM::PCC::FEM_Triangle_PCC_2D_LocalSpace_Data> &fem_local_space_data,
172 const Eigen::MatrixXi &local_to_global,
173 const std::vector<Eigen::MatrixXd> &points)
const
176 unsigned int num_quadrature = 0;
178 for (
unsigned int t = 0; t < points.size(); t++)
179 num_quadrature += points[t].cols();
181 std::vector<Eigen::MatrixXd> total_fem_basis_functions_derivative_values(
183 Eigen::MatrixXd::Zero(num_quadrature, num_basis_functions + num_virtual_basis_functions));
185 unsigned int offeset_quadrature_points = 0;
186 for (
unsigned int t = 0; t < points.size(); t++)
188 if (points[t].size() > 0)
191 const unsigned int num_ref_quadrature = points[t].cols();
193 const std::vector<Eigen::MatrixXd> fem_basis_function_derivatives_values =
195 fem_local_space_data[t],
198 for (
unsigned int d = 0; d < dimension; d++)
200 for (
unsigned int p = 0; p < local_to_global.cols(); p++)
201 total_fem_basis_functions_derivative_values[d].block(offeset_quadrature_points,
202 local_to_global(t, p),
205 fem_basis_function_derivatives_values[d].col(p);
208 offeset_quadrature_points += num_ref_quadrature;
212 return total_fem_basis_functions_derivative_values;
216 const unsigned int &NumBasisFunctions,
217 const unsigned int &NumVirtualBasisFunctions,
218 const std::vector<Eigen::MatrixXd> &fem_basis_functions_derivative_values,
219 const Eigen::MatrixXd &VirtualWeights)
const
221 std::vector<Eigen::MatrixXd> ZFEM_basis_functions_derivative_values(Dimension);
223 for (
unsigned int d = 0; d < Dimension; d++)
225 ZFEM_basis_functions_derivative_values[d] =
226 fem_basis_functions_derivative_values[d].leftCols(NumBasisFunctions) +
227 fem_basis_functions_derivative_values[d].rightCols(NumVirtualBasisFunctions) * VirtualWeights.transpose();
230 return ZFEM_basis_functions_derivative_values;
234 const unsigned int num_vertices,
235 const unsigned int NumDOFs1D,
236 const unsigned int NumDOFs2D,
237 const unsigned int NumBasisFunctions)
const
239 Eigen::MatrixXi local_to_total(num_vertices, 3 * (1 + NumDOFs1D) + NumDOFs2D);
241 const Eigen::ArrayXi edge_reference_id_dofs = Eigen::VectorXi::LinSpaced(NumDOFs1D, 0, NumDOFs1D - 1);
244 for (
unsigned int t = 0; t < num_vertices; t++)
246 const unsigned int next_t = (t + 1) % num_vertices;
248 local_to_total(t, 1) = t;
249 local_to_total(t, 2) = next_t;
250 local_to_total.row(t).segment(3 + NumDOFs1D, NumDOFs1D) = edge_reference_id_dofs + t * NumDOFs1D + num_vertices;
255 local_to_total.col(0) = Eigen::VectorXi::Constant(num_vertices, NumBasisFunctions);
257 for (
unsigned int t = 0; t < num_vertices; t++)
259 const unsigned int next_t = (t + 1) % num_vertices;
261 local_to_total.row(t).segment(3, NumDOFs1D) = edge_reference_id_dofs + NumBasisFunctions + 1 + t * NumDOFs1D;
262 local_to_total.row(t).segment(3 + 2 * NumDOFs1D, NumDOFs1D) =
263 edge_reference_id_dofs + NumBasisFunctions + 1 + next_t * NumDOFs1D;
268 local_to_total.col(0) = Eigen::VectorXi::Constant(num_vertices, NumBasisFunctions - 1);
270 for (
unsigned int t = 0; t < num_vertices; t++)
272 const unsigned int next_t = (t + 1) % num_vertices;
274 local_to_total.row(t).segment(3, NumDOFs1D) = edge_reference_id_dofs + NumBasisFunctions + t * NumDOFs1D;
275 local_to_total.row(t).segment(3 + 2 * NumDOFs1D, NumDOFs1D) =
276 edge_reference_id_dofs + NumBasisFunctions + next_t * NumDOFs1D;
277 local_to_total(t, 3 + 3 * NumDOFs1D) = NumBasisFunctions + num_vertices * NumDOFs1D + t;
282 local_to_total.col(0) = Eigen::VectorXi::Constant(num_vertices, NumBasisFunctions - NumDOFs2D);
284 const unsigned int base = (NumDOFs2D - 1) / num_vertices;
285 const unsigned int other = (NumDOFs2D - 1) % num_vertices;
287 std::vector<unsigned int> num_pt_triangle(num_vertices, 0);
289 const unsigned int num_selected_triangles = NumDOFs2D - 1;
291 unsigned int count = 0;
292 const unsigned int repeat_times = ceil(num_vertices / ((
double)num_selected_triangles));
293 for (
unsigned int i = 0; i < repeat_times; i++)
295 for (
unsigned int j = 0; j < num_selected_triangles; j++)
297 if (i + j * repeat_times < num_vertices && count < num_vertices)
299 num_pt_triangle[i + j * repeat_times] = base + (count < other ? 1 : 0);
305 unsigned int offset_internal = NumBasisFunctions + num_vertices * NumDOFs1D;
306 unsigned int offset_internal_dof = NumBasisFunctions - NumDOFs2D + 1;
308 std::vector<unsigned int> copy_ordered(NumDOFs2D);
309 std::iota(copy_ordered.begin(), copy_ordered.end(), 0);
311 std::vector<unsigned int> p_mod(NumDOFs2D);
312 for (
unsigned int t = 0; t < num_vertices; t++)
314 const unsigned int next_t = (t + 1) % num_vertices;
316 local_to_total.row(t).segment(3, NumDOFs1D) = edge_reference_id_dofs + NumBasisFunctions + t * NumDOFs1D;
317 local_to_total.row(t).segment(3 + 2 * NumDOFs1D, NumDOFs1D) =
318 edge_reference_id_dofs + NumBasisFunctions + next_t * NumDOFs1D;
320 if (NumDOFs2D > 1 && num_pt_triangle[t] > 0)
322 unsigned int count = 0;
323 const unsigned int repeat_times = ceil(((
double)NumDOFs2D) / num_pt_triangle[t]);
324 for (
unsigned int i = 0; i < repeat_times; i++)
326 for (
unsigned int j = 0; j < num_pt_triangle[t]; j++)
328 if (i + j * repeat_times < NumDOFs2D && count < NumDOFs2D)
329 p_mod[count++] = (i + j * repeat_times + t + 1) % NumDOFs2D;
334 p_mod = copy_ordered;
336 for (
unsigned int p = 0; p < num_pt_triangle[t]; p++)
338 local_to_total(t, 3 * (NumDOFs1D + 1) + p_mod[p]) = offset_internal_dof;
339 offset_internal_dof += 1;
342 for (
unsigned int p = num_pt_triangle[t]; p < NumDOFs2D; p++)
344 local_to_total(t, 3 * (NumDOFs1D + 1) + p_mod[p]) = offset_internal;
345 offset_internal += 1;
350 return local_to_total;