PolyDiM
C++ library for POLYtopal DIscretization Methods
Loading...
Searching...
No Matches
DOFsManager.hpp
Go to the documentation of this file.
1// _LICENSE_HEADER_
2//
3// Copyright (C) 2019 - 2025.
4// Terms register on the GPL-3.0 license.
5//
6// This file can be redistributed and/or modified under the license terms.
7//
8// See top level LICENSE file for more details.
9//
10// This file can be used citing references in CITATION.cff file.
11
12#ifndef __PDETOOLS_DOFS_DOFsManager_HPP
13#define __PDETOOLS_DOFS_DOFsManager_HPP
14
15#include "Eigen/Eigen"
16#include "Gedim_Macro.hpp"
17#include <array>
18#include <concepts>
19
21#define DOFSMANAGER_MAX_DIMENSION 3
22
23namespace Polydim
24{
25namespace PDETools
26{
27namespace DOFs
28{
29#if PYBIND == 1
30
31#else
32template <class mesh_connectivity_class>
33concept is_mesh_connectivity_class_0D = requires(mesh_connectivity_class mesh) {
34 { mesh.Cell0Ds_number() } -> std::same_as<unsigned int>;
35 { mesh.Cell0D_marker(0) } -> std::same_as<unsigned int>;
36};
37
38template <class mesh_connectivity_class>
39concept is_mesh_connectivity_class_1D = requires(mesh_connectivity_class mesh) {
40 { mesh.Cell1Ds_number() } -> std::same_as<unsigned int>;
41 { mesh.Cell1D_marker(0) } -> std::same_as<unsigned int>;
42 { mesh.Cell1D_vertices(0) } -> std::same_as<std::array<unsigned int, 2>>;
43};
44
45template <class mesh_connectivity_class>
46concept is_mesh_connectivity_class_2D = requires(mesh_connectivity_class mesh) {
47 { mesh.Cell2Ds_number() } -> std::same_as<unsigned int>;
48 { mesh.Cell2D_marker(0) } -> std::same_as<unsigned int>;
49 { mesh.Cell2D_vertices(0) } -> std::same_as<std::vector<unsigned int>>;
50 { mesh.Cell2D_edges(0) } -> std::same_as<std::vector<unsigned int>>;
51};
52
53template <class mesh_connectivity_class>
54concept is_mesh_connectivity_class_3D = requires(mesh_connectivity_class mesh) {
55 { mesh.Cell3Ds_number() } -> std::same_as<unsigned int>;
56 { mesh.Cell3D_marker(0) } -> std::same_as<unsigned int>;
57 { mesh.Cell3D_vertices(0) } -> std::same_as<std::vector<unsigned int>>;
58 { mesh.Cell3D_edges(0) } -> std::same_as<std::vector<unsigned int>>;
59 { mesh.Cell3D_faces(0) } -> std::same_as<std::vector<unsigned int>>;
60};
61#endif
62
73{
74 public:
75 struct MeshDOFsInfo final
76 {
77
80 {
81 enum struct BoundaryTypes
82 {
83 Unknwon = 0,
84 Strong = 1,
85 Weak = 2,
86 Robin = 4,
87 None = 3
88 };
89
91 unsigned int Marker;
92 };
93
95 std::array<std::vector<unsigned int>, DOFSMANAGER_MAX_DIMENSION + 1> CellsNumDOFs;
97 std::array<std::vector<Polydim::PDETools::DOFs::DOFsManager::MeshDOFsInfo::BoundaryInfo>, DOFSMANAGER_MAX_DIMENSION + 1> CellsBoundaryInfo;
98
99 using BoundaryMap = std::map<unsigned int, Polydim::PDETools::DOFs::DOFsManager::MeshDOFsInfo::BoundaryInfo>;
100 };
101
103
108 struct ConstantDOFsInfo final
109 {
110 std::array<unsigned int, DOFSMANAGER_MAX_DIMENSION + 1> NumDOFs;
111 std::map<unsigned int, Polydim::PDETools::DOFs::DOFsManager::MeshDOFsInfo::BoundaryInfo> BoundaryInfo;
112 };
113
115 struct DOFsData final
116 {
117 struct DOF final
118 {
119 enum struct Types
120 {
121 Unknwon = 0,
122 Strong = 1,
123 DOF = 2
124 };
125
127 unsigned int Global_Index;
128 };
129
131 {
132 unsigned int Dimension;
133 unsigned int CellIndex;
134 unsigned int DOFIndex;
135 };
136
137 unsigned int NumberDOFs;
138 unsigned int NumberInternalDOFs;
139 unsigned int NumberBoundaryDOFs;
140 unsigned int NumberStrongs;
141 std::array<std::vector<std::vector<Polydim::PDETools::DOFs::DOFsManager::DOFsData::DOF>>, DOFSMANAGER_MAX_DIMENSION + 1> CellsDOFs;
142 std::array<std::vector<std::vector<Polydim::PDETools::DOFs::DOFsManager::DOFsData::GlobalCell_DOF>>, DOFSMANAGER_MAX_DIMENSION + 1> CellsGlobalDOFs;
143
144 std::array<std::vector<unsigned int>, DOFSMANAGER_MAX_DIMENSION + 1> CellsNumberDOFs;
145 std::array<std::vector<bool>, DOFSMANAGER_MAX_DIMENSION + 1> CellsHasInternalDOFs;
146 std::array<std::vector<bool>, DOFSMANAGER_MAX_DIMENSION + 1> CellsHasBoundaryDOFs;
147 std::array<std::vector<unsigned int>, DOFSMANAGER_MAX_DIMENSION + 1> CellsNumberStrongs;
148
149 std::array<std::vector<unsigned int>, DOFSMANAGER_MAX_DIMENSION + 1> CellsGlobalNumberDOFs;
150 std::array<std::vector<bool>, DOFSMANAGER_MAX_DIMENSION + 1> CellsGlobalHasInternalDOFs;
151 std::array<std::vector<bool>, DOFSMANAGER_MAX_DIMENSION + 1> CellsGlobalHasBoundaryDOFs;
152 std::array<std::vector<unsigned int>, DOFSMANAGER_MAX_DIMENSION + 1> CellsGlobalNumberStrongs;
153 };
154
157 {
158 std::vector<std::vector<unsigned int>> Cells_DOFs_LocalIndex;
159 std::vector<std::vector<unsigned int>> Cells_Strongs_LocalIndex;
160 std::vector<std::vector<unsigned int>> Cells_DOFs_GlobalIndex;
161 std::vector<std::vector<unsigned int>> Cells_Strongs_GlobalIndex;
162 };
163
164 private:
165 void ConcatenateGlobalDOFs(const unsigned int local_cell_dimension,
166 const unsigned int local_cell_index,
167 const std::vector<typename DOFsData::DOF> &local_cell_DOFs,
168 std::vector<typename DOFsData::GlobalCell_DOF> &global_cell_DOFs,
169 unsigned int &globalDOF_counter) const;
170
176 void CreateCellDOFs(const MeshDOFsInfo &meshDOFsInfo, DOFsData &dofs, const unsigned int dim) const;
177
178 template <class mesh_connectivity_data_class>
179 void Create_Constant_DOFsInfo_0D(const mesh_connectivity_data_class &mesh,
180 const ConstantDOFsInfo &boundary_info,
181 MeshDOFsInfo &mesh_dof_info) const
182#if PYBIND == 1
183#else
185#endif
186 {
187 mesh_dof_info.CellsNumDOFs[0].resize(mesh.Cell0Ds_number(), boundary_info.NumDOFs[0]);
188 mesh_dof_info.CellsBoundaryInfo[0].resize(mesh.Cell0Ds_number());
189
190 for (unsigned int c = 0; c < mesh.Cell0Ds_number(); ++c)
191 {
192 mesh_dof_info.CellsBoundaryInfo[0][c] = boundary_info.BoundaryInfo.at(mesh.Cell0D_marker(c));
193 }
194 }
195
196 template <class mesh_connectivity_data_class>
197 void Create_Constant_DOFsInfo_1D(const mesh_connectivity_data_class &mesh,
198 const ConstantDOFsInfo &boundary_info,
199 MeshDOFsInfo &mesh_dof_info) const
200#if PYBIND == 1
201#else
202 requires(is_mesh_connectivity_class_1D<mesh_connectivity_data_class>)
203#endif
204 {
205 mesh_dof_info.CellsNumDOFs[1].resize(mesh.Cell1Ds_number(), boundary_info.NumDOFs[1]);
206 mesh_dof_info.CellsBoundaryInfo[1].resize(mesh.Cell1Ds_number());
207
208 for (unsigned int c = 0; c < mesh.Cell1Ds_number(); ++c)
209 {
210 mesh_dof_info.CellsBoundaryInfo[1][c] = boundary_info.BoundaryInfo.at(mesh.Cell1D_marker(c));
211 }
212 }
213
214 template <class mesh_connectivity_data_class>
215 void Create_Constant_DOFsInfo_2D(const mesh_connectivity_data_class &mesh,
216 const ConstantDOFsInfo &boundary_info,
217 MeshDOFsInfo &mesh_dof_info) const
218#if PYBIND == 1
219#else
220 requires(is_mesh_connectivity_class_2D<mesh_connectivity_data_class>)
221#endif
222 {
223 mesh_dof_info.CellsNumDOFs[2].resize(mesh.Cell2Ds_number(), boundary_info.NumDOFs[2]);
224 mesh_dof_info.CellsBoundaryInfo[2].resize(mesh.Cell2Ds_number());
225
226 for (unsigned int c = 0; c < mesh.Cell2Ds_number(); ++c)
227 {
228 mesh_dof_info.CellsBoundaryInfo[2][c] = boundary_info.BoundaryInfo.at(mesh.Cell2D_marker(c));
229 }
230 }
231
232 template <class mesh_connectivity_data_class>
233 void Create_Constant_DOFsInfo_3D(const mesh_connectivity_data_class &mesh,
234 const ConstantDOFsInfo &boundary_info,
235 MeshDOFsInfo &mesh_dof_info) const
236#if PYBIND == 1
237#else
238 requires(is_mesh_connectivity_class_3D<mesh_connectivity_data_class>)
239#endif
240 {
241 mesh_dof_info.CellsNumDOFs[3].resize(mesh.Cell3Ds_number(), boundary_info.NumDOFs[3]);
242 mesh_dof_info.CellsBoundaryInfo[3].resize(mesh.Cell3Ds_number());
243
244 for (unsigned int c = 0; c < mesh.Cell3Ds_number(); ++c)
245 {
246 mesh_dof_info.CellsBoundaryInfo[3][c] = boundary_info.BoundaryInfo.at(mesh.Cell3D_marker(c));
247 }
248 }
249
250#if PYBIND == 1
251#else
252 template <unsigned int dimension>
253#endif
254 void CreateCell0DDOFs(const MeshDOFsInfo &meshDOFsInfo, DOFsData &dofs) const
255 {
256#if PYBIND == 1
257#else
258 if (dimension < 0)
259 return;
260#endif
261
262 CreateCellDOFs(meshDOFsInfo, dofs, 0);
263
264 const unsigned int numCells = meshDOFsInfo.CellsNumDOFs.at(0).size();
265
266 auto &cellsGlobalDOFs = dofs.CellsGlobalDOFs.at(0);
267 auto &cellsGlobalNumberDOFs = dofs.CellsGlobalNumberDOFs.at(0);
268 auto &cellsGlobalNumberStrongs = dofs.CellsGlobalNumberStrongs.at(0);
269
270 cellsGlobalDOFs.resize(numCells);
271 cellsGlobalNumberDOFs.resize(numCells, 0);
272 cellsGlobalNumberStrongs.resize(numCells, 0);
273
274 for (unsigned int cell0DIndex = 0; cell0DIndex < numCells; cell0DIndex++)
275 {
276 const auto &cell0D_DOFs = dofs.CellsDOFs.at(0).at(cell0DIndex);
277
278 const unsigned int cellNumGlobalDOFs = cell0D_DOFs.size();
279 cellsGlobalDOFs[cell0DIndex].resize(cellNumGlobalDOFs);
280
281 cellsGlobalNumberDOFs[cell0DIndex] += dofs.CellsNumberDOFs.at(0).at(cell0DIndex);
282 cellsGlobalNumberStrongs[cell0DIndex] += dofs.CellsNumberStrongs.at(0).at(cell0DIndex);
283
284 unsigned int globalDOF_counter = 0;
285
286 ConcatenateGlobalDOFs(0, cell0DIndex, cell0D_DOFs, cellsGlobalDOFs[cell0DIndex], globalDOF_counter);
287 }
288 }
289
290#if PYBIND == 1
291 template <class mesh_connectivity_data_class>
292#else
293 template <unsigned int dimension, class mesh_connectivity_data_class>
294#endif
295 void CreateCell1DDOFs(const MeshDOFsInfo &meshDOFsInfo, const mesh_connectivity_data_class &mesh, DOFsData &dofs) const
296#if PYBIND == 1
297#else
298 requires(is_mesh_connectivity_class_1D<mesh_connectivity_data_class>)
299#endif
300 {
301#if PYBIND == 1
302#else
303 if (dimension < 1)
304 return;
305#endif
306
307 CreateCellDOFs(meshDOFsInfo, dofs, 1);
308
309 const unsigned int numCells = meshDOFsInfo.CellsNumDOFs.at(1).size();
310
311 auto &cellsGlobalDOFs = dofs.CellsGlobalDOFs.at(1);
312 auto &cellsGlobalNumberDOFs = dofs.CellsGlobalNumberDOFs.at(1);
313 auto &cellsGlobalNumberStrongs = dofs.CellsGlobalNumberStrongs.at(1);
314 auto &cellsGlobalHasInternalDOFs = dofs.CellsGlobalHasInternalDOFs.at(1);
315 auto &cellsGlobalHasBoundaryDOFs = dofs.CellsGlobalHasBoundaryDOFs.at(1);
316
317 cellsGlobalDOFs.resize(numCells);
318 cellsGlobalNumberDOFs.resize(numCells, 0);
319 cellsGlobalNumberStrongs.resize(numCells, 0);
320 cellsGlobalHasInternalDOFs.resize(numCells, false);
321 cellsGlobalHasBoundaryDOFs.resize(numCells, false);
322
323 for (unsigned int cell1DIndex = 0; cell1DIndex < numCells; cell1DIndex++)
324 {
325 const auto cell1D_vertices = mesh.Cell1D_vertices(cell1DIndex);
326
327 const unsigned int cell1D_origin_cell0DIndex = cell1D_vertices.at(0);
328 const unsigned int cell1D_end_cell0DIndex = cell1D_vertices.at(1);
329
330 const auto &origin_cell0D_DOFs = dofs.CellsDOFs.at(0).at(cell1D_origin_cell0DIndex);
331 const auto &end_cell0D_DOFs = dofs.CellsDOFs.at(0).at(cell1D_end_cell0DIndex);
332 const auto &cell1D_DOFs = dofs.CellsDOFs.at(1).at(cell1DIndex);
333
334 const unsigned int cellNumGlobalDOFs = origin_cell0D_DOFs.size() + end_cell0D_DOFs.size() + cell1D_DOFs.size();
335 cellsGlobalDOFs[cell1DIndex].resize(cellNumGlobalDOFs);
336
337 unsigned int globalDOF_counter = 0;
338
339 cellsGlobalNumberDOFs[cell1DIndex] += dofs.CellsNumberDOFs.at(0).at(cell1D_origin_cell0DIndex);
340 cellsGlobalNumberStrongs[cell1DIndex] += dofs.CellsNumberStrongs.at(0).at(cell1D_origin_cell0DIndex);
341
342 if (dofs.CellsHasInternalDOFs.at(0).at(cell1D_origin_cell0DIndex))
343 cellsGlobalHasInternalDOFs[cell1DIndex] = true;
344
345 if (dofs.CellsHasBoundaryDOFs.at(0).at(cell1D_origin_cell0DIndex))
346 cellsGlobalHasBoundaryDOFs[cell1DIndex] = true;
347
348 cellsGlobalNumberDOFs[cell1DIndex] += dofs.CellsNumberDOFs.at(0).at(cell1D_end_cell0DIndex);
349 cellsGlobalNumberStrongs[cell1DIndex] += dofs.CellsNumberStrongs.at(0).at(cell1D_end_cell0DIndex);
350
351 if (dofs.CellsHasInternalDOFs.at(0).at(cell1D_end_cell0DIndex))
352 cellsGlobalHasInternalDOFs[cell1DIndex] = true;
353
354 if (dofs.CellsHasBoundaryDOFs.at(0).at(cell1D_end_cell0DIndex))
355 cellsGlobalHasBoundaryDOFs[cell1DIndex] = true;
356
357 cellsGlobalNumberDOFs[cell1DIndex] += dofs.CellsNumberDOFs.at(1).at(cell1DIndex);
358 cellsGlobalNumberStrongs[cell1DIndex] += dofs.CellsNumberStrongs.at(1).at(cell1DIndex);
359
360 ConcatenateGlobalDOFs(0, cell1D_origin_cell0DIndex, origin_cell0D_DOFs, cellsGlobalDOFs[cell1DIndex], globalDOF_counter);
361 ConcatenateGlobalDOFs(0, cell1D_end_cell0DIndex, end_cell0D_DOFs, cellsGlobalDOFs[cell1DIndex], globalDOF_counter);
362 ConcatenateGlobalDOFs(1, cell1DIndex, cell1D_DOFs, cellsGlobalDOFs[cell1DIndex], globalDOF_counter);
363 }
364 }
365
366#if PYBIND == 1
367 template <class mesh_connectivity_data_class>
368#else
369 template <unsigned int dimension, class mesh_connectivity_data_class>
370#endif
371 void CreateCell2DDOFs(const MeshDOFsInfo &meshDOFsInfo, const mesh_connectivity_data_class &mesh, DOFsData &dofs) const
372#if PYBIND == 1
373#else
374 requires(is_mesh_connectivity_class_2D<mesh_connectivity_data_class>)
375#endif
376 {
377#if PYBIND == 1
378#else
379 if (dimension < 2)
380 return;
381#endif
382
383 CreateCellDOFs(meshDOFsInfo, dofs, 2);
384
385 const unsigned int numCells = meshDOFsInfo.CellsNumDOFs.at(2).size();
386
387 auto &cellsGlobalDOFs = dofs.CellsGlobalDOFs.at(2);
388 auto &cellsGlobalNumberDOFs = dofs.CellsGlobalNumberDOFs.at(2);
389 auto &cellsGlobalNumberStrongs = dofs.CellsGlobalNumberStrongs.at(2);
390 auto &cellsGlobalHasInternalDOFs = dofs.CellsGlobalHasInternalDOFs.at(2);
391 auto &cellsGlobalHasBoundaryDOFs = dofs.CellsGlobalHasBoundaryDOFs.at(2);
392
393 cellsGlobalDOFs.resize(numCells);
394 cellsGlobalNumberDOFs.resize(numCells, 0);
395 cellsGlobalNumberStrongs.resize(numCells, 0);
396 cellsGlobalHasInternalDOFs.resize(numCells, false);
397 cellsGlobalHasBoundaryDOFs.resize(numCells, false);
398
399 for (unsigned int cell2DIndex = 0; cell2DIndex < numCells; cell2DIndex++)
400 {
401 unsigned int cellNumGlobalDOFs = dofs.CellsDOFs.at(2).at(cell2DIndex).size();
402
403 const auto cell2D_vertices = mesh.Cell2D_vertices(cell2DIndex);
404
405 for (unsigned int v = 0; v < cell2D_vertices.size(); v++)
406 {
407 const unsigned int vertex_cell0DIndex = cell2D_vertices.at(v);
408 cellNumGlobalDOFs += dofs.CellsDOFs.at(0).at(vertex_cell0DIndex).size();
409 }
410
411 const auto cell2D_edges = mesh.Cell2D_edges(cell2DIndex);
412
413 for (unsigned int e = 0; e < cell2D_edges.size(); e++)
414 {
415 const unsigned int edge_cell1DIndex = cell2D_edges.at(e);
416 cellNumGlobalDOFs += dofs.CellsDOFs.at(1).at(edge_cell1DIndex).size();
417 }
418
419 cellsGlobalDOFs[cell2DIndex].resize(cellNumGlobalDOFs);
420
421 unsigned int globalDOF_counter = 0;
422
423 for (unsigned int v = 0; v < cell2D_vertices.size(); v++)
424 {
425 const unsigned int vertex_cell0DIndex = cell2D_vertices.at(v);
426 ConcatenateGlobalDOFs(0, vertex_cell0DIndex, dofs.CellsDOFs.at(0).at(vertex_cell0DIndex), cellsGlobalDOFs[cell2DIndex], globalDOF_counter);
427
428 cellsGlobalNumberDOFs[cell2DIndex] += dofs.CellsNumberDOFs.at(0).at(vertex_cell0DIndex);
429 cellsGlobalNumberStrongs[cell2DIndex] += dofs.CellsNumberStrongs.at(0).at(vertex_cell0DIndex);
430 }
431
432 for (unsigned int e = 0; e < cell2D_edges.size(); e++)
433 {
434 const unsigned int edge_cell1DIndex = cell2D_edges.at(e);
435 ConcatenateGlobalDOFs(1, edge_cell1DIndex, dofs.CellsDOFs.at(1).at(edge_cell1DIndex), cellsGlobalDOFs[cell2DIndex], globalDOF_counter);
436
437 cellsGlobalNumberDOFs[cell2DIndex] += dofs.CellsNumberDOFs.at(1).at(edge_cell1DIndex);
438 cellsGlobalNumberStrongs[cell2DIndex] += dofs.CellsNumberStrongs.at(1).at(edge_cell1DIndex);
439
440 if (dofs.CellsHasInternalDOFs.at(1).at(edge_cell1DIndex))
441 cellsGlobalHasInternalDOFs[cell2DIndex] = true;
442
443 if (dofs.CellsHasBoundaryDOFs.at(1).at(edge_cell1DIndex))
444 cellsGlobalHasBoundaryDOFs[cell2DIndex] = true;
445 }
446
447 ConcatenateGlobalDOFs(2, cell2DIndex, dofs.CellsDOFs.at(2).at(cell2DIndex), cellsGlobalDOFs[cell2DIndex], globalDOF_counter);
448
449 cellsGlobalNumberDOFs[cell2DIndex] += dofs.CellsNumberDOFs.at(2).at(cell2DIndex);
450 cellsGlobalNumberStrongs[cell2DIndex] += dofs.CellsNumberStrongs.at(2).at(cell2DIndex);
451 }
452 }
453
454#if PYBIND == 1
455 template <class mesh_connectivity_data_class>
456#else
457 template <unsigned int dimension, class mesh_connectivity_data_class>
458#endif
459 void CreateCell3DDOFs(const MeshDOFsInfo &meshDOFsInfo, const mesh_connectivity_data_class &mesh, DOFsData &dofs) const
460#if PYBIND == 1
461#else
462 requires(is_mesh_connectivity_class_3D<mesh_connectivity_data_class>)
463#endif
464 {
465#if PYBIND == 1
466#else
467 if (dimension < 3)
468 return;
469#endif
470
471 CreateCellDOFs(meshDOFsInfo, dofs, 3);
472
473 const unsigned int numCells = meshDOFsInfo.CellsNumDOFs.at(3).size();
474
475 auto &cellsGlobalDOFs = dofs.CellsGlobalDOFs.at(3);
476 auto &cellsGlobalNumberDOFs = dofs.CellsGlobalNumberDOFs.at(3);
477 auto &cellsGlobalNumberStrongs = dofs.CellsGlobalNumberStrongs.at(3);
478 auto &cellsGlobalHasInternalDOFs = dofs.CellsGlobalHasInternalDOFs.at(3);
479 auto &cellsGlobalHasBoundaryDOFs = dofs.CellsGlobalHasBoundaryDOFs.at(3);
480
481 cellsGlobalDOFs.resize(numCells);
482 cellsGlobalNumberDOFs.resize(numCells, 0);
483 cellsGlobalNumberStrongs.resize(numCells, 0);
484 cellsGlobalHasInternalDOFs.resize(numCells, false);
485 cellsGlobalHasBoundaryDOFs.resize(numCells, false);
486
487 for (unsigned int cell3DIndex = 0; cell3DIndex < numCells; cell3DIndex++)
488 {
489 unsigned int cellNumGlobalDOFs = dofs.CellsDOFs.at(3).at(cell3DIndex).size();
490 const auto cell3D_vertices = mesh.Cell3D_vertices(cell3DIndex);
491 const auto cell3D_edges = mesh.Cell3D_edges(cell3DIndex);
492 const auto cell3D_faces = mesh.Cell3D_faces(cell3DIndex);
493
494 for (unsigned int v = 0; v < cell3D_vertices.size(); v++)
495 {
496 const unsigned int vertex_cell0DIndex = cell3D_vertices.at(v);
497 cellNumGlobalDOFs += dofs.CellsDOFs.at(0).at(vertex_cell0DIndex).size();
498 }
499
500 for (unsigned int e = 0; e < cell3D_edges.size(); e++)
501 {
502 const unsigned int edge_cell1DIndex = cell3D_edges.at(e);
503 cellNumGlobalDOFs += dofs.CellsDOFs.at(1).at(edge_cell1DIndex).size();
504 }
505
506 for (unsigned int f = 0; f < cell3D_faces.size(); f++)
507 {
508 const unsigned int face_cell2DIndex = cell3D_faces.at(f);
509 cellNumGlobalDOFs += dofs.CellsDOFs.at(2).at(face_cell2DIndex).size();
510 }
511
512 cellsGlobalDOFs[cell3DIndex].resize(cellNumGlobalDOFs);
513
514 unsigned int globalDOF_counter = 0;
515
516 for (unsigned int v = 0; v < cell3D_vertices.size(); v++)
517 {
518 const unsigned int vertex_cell0DIndex = cell3D_vertices.at(v);
519 ConcatenateGlobalDOFs(0, vertex_cell0DIndex, dofs.CellsDOFs.at(0).at(vertex_cell0DIndex), cellsGlobalDOFs[cell3DIndex], globalDOF_counter);
520
521 cellsGlobalNumberDOFs[cell3DIndex] += dofs.CellsNumberDOFs.at(0).at(vertex_cell0DIndex);
522 cellsGlobalNumberStrongs[cell3DIndex] += dofs.CellsNumberStrongs.at(0).at(vertex_cell0DIndex);
523 }
524
525 for (unsigned int e = 0; e < cell3D_edges.size(); e++)
526 {
527 const unsigned int edge_cell1DIndex = cell3D_edges.at(e);
528 ConcatenateGlobalDOFs(1, edge_cell1DIndex, dofs.CellsDOFs.at(1).at(edge_cell1DIndex), cellsGlobalDOFs[cell3DIndex], globalDOF_counter);
529
530 cellsGlobalNumberDOFs[cell3DIndex] += dofs.CellsNumberDOFs.at(1).at(edge_cell1DIndex);
531 cellsGlobalNumberStrongs[cell3DIndex] += dofs.CellsNumberStrongs.at(1).at(edge_cell1DIndex);
532 }
533
534 for (unsigned int f = 0; f < cell3D_faces.size(); f++)
535 {
536 const unsigned int face_cell2DIndex = cell3D_faces.at(f);
537 ConcatenateGlobalDOFs(2, face_cell2DIndex, dofs.CellsDOFs.at(2).at(face_cell2DIndex), cellsGlobalDOFs[cell3DIndex], globalDOF_counter);
538
539 cellsGlobalNumberDOFs[cell3DIndex] += dofs.CellsNumberDOFs.at(2).at(face_cell2DIndex);
540 cellsGlobalNumberStrongs[cell3DIndex] += dofs.CellsNumberStrongs.at(2).at(face_cell2DIndex);
541
542 if (dofs.CellsHasInternalDOFs.at(2).at(face_cell2DIndex))
543 cellsGlobalHasInternalDOFs[cell3DIndex] = true;
544
545 if (dofs.CellsHasBoundaryDOFs.at(2).at(face_cell2DIndex))
546 cellsGlobalHasBoundaryDOFs[cell3DIndex] = true;
547 }
548
549 ConcatenateGlobalDOFs(3, cell3DIndex, dofs.CellsDOFs.at(3).at(cell3DIndex), cellsGlobalDOFs[cell3DIndex], globalDOF_counter);
550
551 cellsGlobalNumberDOFs[cell3DIndex] += dofs.CellsNumberDOFs.at(3).at(cell3DIndex);
552 cellsGlobalNumberStrongs[cell3DIndex] += dofs.CellsNumberStrongs.at(3).at(cell3DIndex);
553 }
554 }
555
556 public:
557 template <class mesh_connectivity_data_class>
558 MeshDOFsInfo Create_Constant_DOFsInfo_0D(const mesh_connectivity_data_class &mesh, const ConstantDOFsInfo &boundary_info) const
559 {
561
562#if PYBIND == 1
563 Create_Constant_DOFsInfo_0D(mesh, boundary_info, meshDOFsInfo);
564#else
565 Create_Constant_DOFsInfo_0D(mesh, boundary_info, meshDOFsInfo);
566#endif
567
568 return meshDOFsInfo;
569 }
570
571 template <class mesh_connectivity_data_class>
572 MeshDOFsInfo Create_Constant_DOFsInfo_1D(const mesh_connectivity_data_class &mesh, const ConstantDOFsInfo &boundary_info) const
573 {
575
576#if PYBIND == 1
577 Create_Constant_DOFsInfo_0D(mesh, boundary_info, meshDOFsInfo);
578 Create_Constant_DOFsInfo_1D(mesh, boundary_info, meshDOFsInfo);
579#else
580 Create_Constant_DOFsInfo_0D(mesh, boundary_info, meshDOFsInfo);
581 Create_Constant_DOFsInfo_1D(mesh, boundary_info, meshDOFsInfo);
582#endif
583
584 return meshDOFsInfo;
585 }
586
587 template <class mesh_connectivity_data_class>
588 MeshDOFsInfo Create_Constant_DOFsInfo_2D(const mesh_connectivity_data_class &mesh, const ConstantDOFsInfo &boundary_info) const
589 {
591#if PYBIND == 1
592 Create_Constant_DOFsInfo_0D(mesh, boundary_info, meshDOFsInfo);
593 Create_Constant_DOFsInfo_1D(mesh, boundary_info, meshDOFsInfo);
594 Create_Constant_DOFsInfo_2D(mesh, boundary_info, meshDOFsInfo);
595#else
596 Create_Constant_DOFsInfo_0D(mesh, boundary_info, meshDOFsInfo);
597 Create_Constant_DOFsInfo_1D(mesh, boundary_info, meshDOFsInfo);
598 Create_Constant_DOFsInfo_2D(mesh, boundary_info, meshDOFsInfo);
599#endif
600 return meshDOFsInfo;
601 }
602
603 template <class mesh_connectivity_data_class>
604 MeshDOFsInfo Create_Constant_DOFsInfo_3D(const mesh_connectivity_data_class &mesh, const ConstantDOFsInfo &boundary_info) const
605 {
607#if PYBIND == 1
608 Create_Constant_DOFsInfo_0D(mesh, boundary_info, meshDOFsInfo);
609 Create_Constant_DOFsInfo_1D(mesh, boundary_info, meshDOFsInfo);
610 Create_Constant_DOFsInfo_2D(mesh, boundary_info, meshDOFsInfo);
611 Create_Constant_DOFsInfo_3D(mesh, boundary_info, meshDOFsInfo);
612#else
613 Create_Constant_DOFsInfo_0D(mesh, boundary_info, meshDOFsInfo);
614 Create_Constant_DOFsInfo_1D(mesh, boundary_info, meshDOFsInfo);
615 Create_Constant_DOFsInfo_2D(mesh, boundary_info, meshDOFsInfo);
616 Create_Constant_DOFsInfo_3D(mesh, boundary_info, meshDOFsInfo);
617#endif
618
619 return meshDOFsInfo;
620 }
621
625 DOFsData CreateDOFs_0D(const MeshDOFsInfo &meshDOFsInfo) const
626 {
627 DOFsData result;
628
629 result.NumberDOFs = 0;
630 result.NumberStrongs = 0;
631 result.NumberBoundaryDOFs = 0;
632 result.NumberInternalDOFs = 0;
633
634#if PYBIND == 1
635 CreateCell0DDOFs(meshDOFsInfo, result);
636#else
637 CreateCell0DDOFs<0>(meshDOFsInfo, result);
638#endif
639
640 return result;
641 }
642
647 template <class mesh_connectivity_data_class>
648 DOFsData CreateDOFs_1D(const MeshDOFsInfo &meshDOFsInfo, const mesh_connectivity_data_class &mesh) const
649 {
650 DOFsData result;
651
652 result.NumberDOFs = 0;
653 result.NumberStrongs = 0;
654 result.NumberBoundaryDOFs = 0;
655 result.NumberInternalDOFs = 0;
656
657#if PYBIND == 1
658 CreateCell0DDOFs(meshDOFsInfo, result);
659 CreateCell1DDOFs(meshDOFsInfo, mesh, result);
660#else
661 CreateCell0DDOFs<1>(meshDOFsInfo, result);
662 CreateCell1DDOFs<1>(meshDOFsInfo, mesh, result);
663#endif
664
665 return result;
666 }
667
672 template <class mesh_connectivity_data_class>
673 DOFsData CreateDOFs_2D(const MeshDOFsInfo &meshDOFsInfo, const mesh_connectivity_data_class &mesh) const
674 {
675 DOFsData result;
676
677 result.NumberDOFs = 0;
678 result.NumberStrongs = 0;
679 result.NumberBoundaryDOFs = 0;
680 result.NumberInternalDOFs = 0;
681
682#if PYBIND == 1
683 CreateCell0DDOFs(meshDOFsInfo, result);
684 CreateCell1DDOFs(meshDOFsInfo, mesh, result);
685 CreateCell2DDOFs(meshDOFsInfo, mesh, result);
686#else
687 CreateCell0DDOFs<2>(meshDOFsInfo, result);
688 CreateCell1DDOFs<2>(meshDOFsInfo, mesh, result);
689 CreateCell2DDOFs<2>(meshDOFsInfo, mesh, result);
690#endif
691
692 return result;
693 }
694
699 template <class mesh_connectivity_data_class>
700 DOFsData CreateDOFs_3D(const MeshDOFsInfo &meshDOFsInfo, const mesh_connectivity_data_class &mesh) const
701 {
702 DOFsData result;
703
704 result.NumberDOFs = 0;
705 result.NumberStrongs = 0;
706 result.NumberBoundaryDOFs = 0;
707 result.NumberInternalDOFs = 0;
708
709#if PYBIND == 1
710 CreateCell0DDOFs(meshDOFsInfo, result);
711 CreateCell1DDOFs(meshDOFsInfo, mesh, result);
712 CreateCell2DDOFs(meshDOFsInfo, mesh, result);
713 CreateCell3DDOFs(meshDOFsInfo, mesh, result);
714#else
715 CreateCell0DDOFs<3>(meshDOFsInfo, result);
716 CreateCell1DDOFs<3>(meshDOFsInfo, mesh, result);
717 CreateCell2DDOFs<3>(meshDOFsInfo, mesh, result);
718 CreateCell3DDOFs<3>(meshDOFsInfo, mesh, result);
719#endif
720
721 return result;
722 }
723
733 CellsDOFsIndicesData ComputeCellsDOFsIndices(const DOFsData &dofs, const unsigned int dim) const;
734};
735} // namespace DOFs
736} // namespace PDETools
737} // namespace Polydim
738
739#endif
#define DOFSMANAGER_MAX_DIMENSION
Maximum spatial dimension handled by the DOFsManager (arrays are sized as this plus one).
Definition DOFsManager.hpp:21
Builds and manages the degrees of freedom (DOFs) of a discrete space over a mesh.
Definition DOFsManager.hpp:73
DOFsData CreateDOFs_0D(const MeshDOFsInfo &meshDOFsInfo) const
Build the DOF numbering for a 0D problem.
Definition DOFsManager.hpp:625
MeshDOFsInfo Create_Constant_DOFsInfo_2D(const mesh_connectivity_data_class &mesh, const ConstantDOFsInfo &boundary_info) const
Definition DOFsManager.hpp:588
DOFsData CreateDOFs_3D(const MeshDOFsInfo &meshDOFsInfo, const mesh_connectivity_data_class &mesh) const
Build the DOF numbering for a 3D problem (vertices, edges, faces and cells).
Definition DOFsManager.hpp:700
CellsDOFsIndicesData ComputeCellsDOFsIndices(const DOFsData &dofs, const unsigned int dim) const
Extract per-cell local/global index lists for free DOFs and strongs.
Definition DOFsManager.cpp:109
DOFsData CreateDOFs_2D(const MeshDOFsInfo &meshDOFsInfo, const mesh_connectivity_data_class &mesh) const
Build the DOF numbering for a 2D problem (vertices, edges and cells).
Definition DOFsManager.hpp:673
MeshDOFsInfo Create_Constant_DOFsInfo_3D(const mesh_connectivity_data_class &mesh, const ConstantDOFsInfo &boundary_info) const
Definition DOFsManager.hpp:604
MeshDOFsInfo Create_Constant_DOFsInfo_0D(const mesh_connectivity_data_class &mesh, const ConstantDOFsInfo &boundary_info) const
Definition DOFsManager.hpp:558
MeshDOFsInfo Create_Constant_DOFsInfo_1D(const mesh_connectivity_data_class &mesh, const ConstantDOFsInfo &boundary_info) const
Definition DOFsManager.hpp:572
typename MeshDOFsInfo::BoundaryInfo::BoundaryTypes BoundaryTypes
Definition DOFsManager.hpp:102
DOFsData CreateDOFs_1D(const MeshDOFsInfo &meshDOFsInfo, const mesh_connectivity_data_class &mesh) const
Build the DOF numbering for a 1D problem (vertices and edges).
Definition DOFsManager.hpp:648
Definition FEM_MCC_2D_LocalSpace.cpp:17
Flattened local/global index lists (free DOFs and strongs) for each cell.
Definition DOFsManager.hpp:157
std::vector< std::vector< unsigned int > > Cells_Strongs_GlobalIndex
Definition DOFsManager.hpp:161
std::vector< std::vector< unsigned int > > Cells_DOFs_LocalIndex
Definition DOFsManager.hpp:158
std::vector< std::vector< unsigned int > > Cells_Strongs_LocalIndex
Definition DOFsManager.hpp:159
std::vector< std::vector< unsigned int > > Cells_DOFs_GlobalIndex
Definition DOFsManager.hpp:160
DOF specification that is constant across all entities of each dimension.
Definition DOFsManager.hpp:109
std::map< unsigned int, Polydim::PDETools::DOFs::DOFsManager::MeshDOFsInfo::BoundaryInfo > BoundaryInfo
Definition DOFsManager.hpp:111
std::array< unsigned int, DOFSMANAGER_MAX_DIMENSION+1 > NumDOFs
Definition DOFsManager.hpp:110
Polydim::PDETools::DOFs::DOFsManager::DOFsData::DOF::Types Type
Definition DOFsManager.hpp:126
unsigned int Global_Index
Global index within the free or strong numbering.
Definition DOFsManager.hpp:127
unsigned int Dimension
Entity dimension (0..3) hosting the DOF.
Definition DOFsManager.hpp:132
unsigned int DOFIndex
Local DOF index within that entity.
Definition DOFsManager.hpp:134
unsigned int CellIndex
Index of the hosting entity.
Definition DOFsManager.hpp:133
Full DOF numbering produced for a mesh: local/global indices and aggregate counts.
Definition DOFsManager.hpp:116
std::array< std::vector< std::vector< Polydim::PDETools::DOFs::DOFsManager::DOFsData::DOF > >, DOFSMANAGER_MAX_DIMENSION+1 > CellsDOFs
Definition DOFsManager.hpp:141
unsigned int NumberDOFs
Definition DOFsManager.hpp:137
std::array< std::vector< bool >, DOFSMANAGER_MAX_DIMENSION+1 > CellsHasInternalDOFs
Definition DOFsManager.hpp:145
std::array< std::vector< bool >, DOFSMANAGER_MAX_DIMENSION+1 > CellsGlobalHasBoundaryDOFs
Definition DOFsManager.hpp:151
std::array< std::vector< bool >, DOFSMANAGER_MAX_DIMENSION+1 > CellsGlobalHasInternalDOFs
Definition DOFsManager.hpp:150
std::array< std::vector< std::vector< Polydim::PDETools::DOFs::DOFsManager::DOFsData::GlobalCell_DOF > >, DOFSMANAGER_MAX_DIMENSION+1 > CellsGlobalDOFs
Definition DOFsManager.hpp:142
unsigned int NumberStrongs
Definition DOFsManager.hpp:140
unsigned int NumberBoundaryDOFs
Definition DOFsManager.hpp:139
std::array< std::vector< unsigned int >, DOFSMANAGER_MAX_DIMENSION+1 > CellsGlobalNumberStrongs
Definition DOFsManager.hpp:152
std::array< std::vector< bool >, DOFSMANAGER_MAX_DIMENSION+1 > CellsHasBoundaryDOFs
Definition DOFsManager.hpp:146
std::array< std::vector< unsigned int >, DOFSMANAGER_MAX_DIMENSION+1 > CellsGlobalNumberDOFs
Definition DOFsManager.hpp:149
std::array< std::vector< unsigned int >, DOFSMANAGER_MAX_DIMENSION+1 > CellsNumberStrongs
Definition DOFsManager.hpp:147
std::array< std::vector< unsigned int >, DOFSMANAGER_MAX_DIMENSION+1 > CellsNumberDOFs
Definition DOFsManager.hpp:144
unsigned int NumberInternalDOFs
Number of interior free DOFs.
Definition DOFsManager.hpp:138
Boundary classification attached to a mesh entity.
Definition DOFsManager.hpp:80
unsigned int Marker
Mesh marker the classification was derived from.
Definition DOFsManager.hpp:91
Polydim::PDETools::DOFs::DOFsManager::MeshDOFsInfo::BoundaryInfo::BoundaryTypes Type
Definition DOFsManager.hpp:90
std::array< std::vector< unsigned int >, DOFSMANAGER_MAX_DIMENSION+1 > CellsNumDOFs
Number of DOFs on each cell, per entity dimension (index 0..3).
Definition DOFsManager.hpp:95
std::array< std::vector< Polydim::PDETools::DOFs::DOFsManager::MeshDOFsInfo::BoundaryInfo >, DOFSMANAGER_MAX_DIMENSION+1 > CellsBoundaryInfo
Boundary classification of each cell, per entity dimension (index 0..3).
Definition DOFsManager.hpp:97
std::map< unsigned int, Polydim::PDETools::DOFs::DOFsManager::MeshDOFsInfo::BoundaryInfo > BoundaryMap
Definition DOFsManager.hpp:99