OpenBeam
C++ library for static analysis of mechanical structures
CFiniteElementProblem.h
1 /* +---------------------------------------------------------------------------+
2  | OpenBeam - C++ Finite Element Analysis library |
3  | |
4  | Copyright (C) 2010-2021 Jose Luis Blanco Claraco |
5  | University of Malaga |
6  | |
7  | OpenBeam is free software: you can redistribute it and/or modify |
8  | it under the terms of the GNU General Public License as published by |
9  | the Free Software Foundation, either version 3 of the License, or |
10  | (at your option) any later version. |
11  | |
12  | OpenBeam is distributed in the hope that it will be useful, |
13  | but WITHOUT ANY WARRANTY; without even the implied warranty of |
14  | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
15  | GNU General Public License for more details. |
16  | |
17  | You should have received a copy of the GNU General Public License |
18  | along with OpenBeam. If not, see <http://www.gnu.org/licenses/>. |
19  | |
20  +---------------------------------------------------------------------------+
21  */
22 
23 #pragma once
24 
25 #include <mrpt/containers/yaml.h>
26 #include <mrpt/core/optional_ref.h>
27 #include <mrpt/opengl/CSetOfObjects.h>
28 #include <mrpt/system/CTimeLogger.h>
29 #include <openbeam/CElement.h>
30 #include <openbeam/types.h>
31 
32 #include <Eigen/Sparse>
33 #include <cstdint>
34 #include <fstream>
35 #include <iostream>
36 
37 namespace openbeam
38 {
39 struct RenderInitData; // Fwd. decl. (defined in
40  // CFiniteElementProblem::saveAsImage)
41 
43 enum class DoF_index : uint8_t
44 {
45  DX = 0,
46  DY,
47  DZ,
48  RX,
49  RY,
50  RZ
51 };
52 
53 struct NodeDoF
54 {
55  NodeDoF(node_index_t _node_id, DoF_index _dof) : nodeId(_node_id), dof(_dof)
56  {
57  }
58  NodeDoF(node_index_t _node_id, uint8_t _dof)
59  : nodeId(_node_id), dof(static_cast<DoF_index>(_dof))
60  {
61  }
62 
63  node_index_t nodeId;
64  DoF_index dof;
65 
66  uint8_t dofAsInt() const { return static_cast<uint8_t>(dof); }
67 };
68 
69 enum class StaticSolverAlgorithm : uint8_t
70 {
71  Dense_LLT = 0,
72  Sparse_LLT
73 };
74 
77 {
78  struct TDoFType
79  {
80  size_t bounded_index;
82  size_t free_index;
84  };
85 
86  Eigen::SparseMatrix<num_t> K_bb;
87  Eigen::SparseMatrix<num_t> K_ff;
88  Eigen::SparseMatrix<num_t> K_bf;
89 
90  std::vector<size_t> free_dof_indices;
91  std::vector<size_t> bounded_dof_indices;
92  std::vector<TDoFType> dof_types;
93 
97  Eigen::Matrix<num_t, Eigen::Dynamic, 1> U_b;
98 
101  Eigen::Matrix<num_t, Eigen::Dynamic, 1> F_f;
102 };
103 
106 {
109 
112  Eigen::Matrix<num_t, Eigen::Dynamic, 1> F_b;
113 
116  Eigen::Matrix<num_t, Eigen::Dynamic, 1> U_f;
117 
119  Eigen::Matrix<num_t, Eigen::Dynamic, 1> F;
120 
122  Eigen::Matrix<num_t, Eigen::Dynamic, 1> U;
123 };
124 
128 {
129  MeshParams();
130 
132 };
133 
138 {
139  MeshOutputInfo() = default;
140 
143  size_t num_original_nodes = 0;
144 
148 
151  std::deque<std::vector<node_index_t>> element2nodes;
152 
154  std::deque<std::vector<element_index_t>> element2elements;
155 };
156 
158 {
159  ImageSaveOutputInfo() = default;
160 
161  unsigned int img_width = 0, img_height = 0;
162 };
163 
166 {
167  StaticSolverOptions() = default;
168 
169  StaticSolverAlgorithm algorithm = StaticSolverAlgorithm::Dense_LLT;
170  bool nonLinearIterative = false;
171 };
172 
174 {
175  StressInfo() {}
176 
182  std::vector<ElementStress> element_stress;
183 };
184 
196 {
197  public:
198  using constraint_list_t = std::map<size_t, num_t>;
199  using load_list_t = std::map<size_t, num_t>;
200 
201  CFiniteElementProblem() = default;
202  virtual ~CFiniteElementProblem();
203 
204  // ----------------------------------------------------------------------------
208  virtual void clear();
210 
221  std::istream& is,
222  const mrpt::optional_ref<vector_string_t>& errMsg = std::nullopt,
223  const mrpt::optional_ref<vector_string_t>& warnMsg = std::nullopt);
224 
235  const std::string& file,
236  const mrpt::optional_ref<vector_string_t>& errMsg = std::nullopt,
237  const mrpt::optional_ref<vector_string_t>& warnMsg = std::nullopt);
238 
244  const std::string& file, const DrawStructureOptions& options,
245  const StaticSolveProblemInfo* solver_info = nullptr,
246  const MeshOutputInfo* meshing_info = nullptr,
247  ImageSaveOutputInfo* out_img_info = nullptr) const;
248  bool saveAsImagePNG(
249  const std::string& file, const DrawStructureOptions& options,
250  const StaticSolveProblemInfo* solver_info = nullptr,
251  const MeshOutputInfo* meshing_info = nullptr,
252  ImageSaveOutputInfo* out_img_info = nullptr) const;
253  bool saveAsImage(
254  const std::string& file, const bool is_svg,
255  const DrawStructureOptions& options,
256  const StaticSolveProblemInfo* solver_info = nullptr,
257  const MeshOutputInfo* meshing_info = nullptr,
258  ImageSaveOutputInfo* out_img_info = nullptr) const;
259 
260  bool renderToCairoContext(
261  void* _cairo_context, const RenderInitData& ri,
262  const DrawStructureOptions& options,
263  const StaticSolveProblemInfo* solver_info,
264  const MeshOutputInfo* meshing_info) const;
265 
266  mrpt::opengl::CSetOfObjects::Ptr getVisualization(
267  const DrawStructureOptions& options,
268  const StaticSolveProblemInfo& solver_info,
269  const MeshOutputInfo* meshing_info = nullptr,
270  const StressInfo* stressInfo = nullptr) const;
271 
273  // ----------------------------------------------------------------------------
279  size_t insertElement(CElement::Ptr el);
280 
283  template <typename ElementClass, typename... _Args>
284  size_t createElement(_Args&&... __args)
285  {
286  return insertElement(
287  std::make_shared<ElementClass>(std::forward<_Args>(__args)...));
288  }
289 
291  CElement::ConstPtr getElement(size_t i) const;
292 
294  const CElement::Ptr& getElement(size_t i);
295 
297  size_t getNumberOfElements() const { return m_elements.size(); }
298 
300  // ----------------------------------------------------------------------------
307  void insertConstraint(const size_t dof_index, const num_t value = 0);
308 
309  const constraint_list_t& getAllConstraints() const
310  {
311  return m_DoF_constraints;
312  }
313 
316  void setLoadAtDOF(const size_t dof_index, const num_t f);
317 
320  void addLoadAtDOF(const size_t dof_index, const num_t f);
321 
322  const load_list_t& getOverallLoadsOnDOFs() const
323  {
324  return m_loads_at_each_dof;
325  }
326 
328  // ----------------------------------------------------------------------------
334  void setNumberOfNodes(size_t N);
335 
337  size_t getNumberOfNodes() const { return m_node_poses.size(); }
338 
341  node_index_t insertNode(const TRotationTrans3D& p);
342 
344  void setNodePose(size_t idx, const TRotationTrans3D& p);
345 
347  void setNodePose(size_t idx, const num_t x, const num_t y, const num_t z);
348 
352  {
353  ASSERT_(i < m_node_poses.size());
354  return m_node_poses[i];
355  }
358  const TRotationTrans3D& getNodePose(size_t i) const
359  {
360  ASSERT_(i < m_node_poses.size());
361  return m_node_poses[i];
362  }
363 
367  size_t i, Vector3& out_final_point,
368  const StaticSolveProblemInfo& solver_info,
369  const num_t exageration_factor = 1) const;
370 
374  const StaticSolveProblemInfo& solver_info) const;
375 
378  num_t& min_x, num_t& max_x, num_t& min_y, num_t& max_y,
379  bool deformed = false,
380  const StaticSolveProblemInfo* solver_info = nullptr,
381  num_t deformed_scale_factor = 1.0) const;
382 
384  // ----------------------------------------------------------------------------
391  const std::vector<NodeDoF>& getProblemDoFs()
392  {
393  updateListDoFs();
394  return m_problem_DoFs;
395  }
396 
400 
404  static std::vector<size_t> complementaryDoFs(
405  const std::vector<size_t>& ds, const size_t nTotalDOFs);
406 
412  size_t getDOFIndex(const size_t nNode, const DoF_index n) const;
413 
415  // ----------------------------------------------------------------------------
425  virtual void updateAll();
426 
436 
445  StaticSolveProblemInfo& out_info,
446  const StaticSolverOptions& opts = StaticSolverOptions());
447 
454  StressInfo& out_stress, const StaticSolveProblemInfo& solver_info);
455 
456  std::string getNodeLabel(
457  const size_t idx) const;
458 
460  // ----------------------------------------------------------------------------
461  protected:
465  struct node_used_t
466  {
467  node_used_t() = default;
468 
469  bool used = false;
470  };
471 
472  std::deque<node_used_t> m_node_defined;
473  std::deque<TRotationTrans3D> m_node_poses;
474  std::vector<std::string> m_node_labels;
475  std::deque<CElement::Ptr> m_elements;
476 
482  constraint_list_t m_DoF_constraints;
483 
486  load_list_t m_loads_at_each_dof;
487 
493 
498  std::map<size_t, ElementStress> m_extra_stress_for_each_element;
499 
506 
509  const mrpt::containers::yaml& f,
510  const mrpt::optional_ref<vector_string_t>& errMsg,
511  const mrpt::optional_ref<vector_string_t>& warnMsg);
512 
513  void internal_parser1_Parameters(
514  const mrpt::containers::yaml& f, EvaluationContext& ctx) const;
515 
516  void internal_parser2_BeamSections(
517  const mrpt::containers::yaml& f, EvaluationContext& ctx) const;
518 
519  void internal_parser3_nodes(
520  const mrpt::containers::yaml& f, EvaluationContext& ctx);
521  void internal_parser4_elements(
522  const mrpt::containers::yaml& f, EvaluationContext& ctx);
523  void internal_parser5_constraints(
524  const mrpt::containers::yaml& f, EvaluationContext& ctx);
525 
526  void internal_parser6_node_loads(
527  const mrpt::containers::yaml& f, EvaluationContext& ctx);
528  void internal_parser7_element_loads(
529  const mrpt::containers::yaml& f, EvaluationContext& ctx);
530 
535 
538 
542 
545 
548  {
549  TProblemDOFIndicesForNode() = default;
550 
553  std::array<int, 6> dof_index = {-1, -1, -1, -1, -1, -1};
554  };
555 
560  std::vector<NodeDoF> m_problem_DoFs;
561 
566  std::vector<TProblemDOFIndicesForNode> m_problem_DoFs_inverse_list;
567 
569  {
570  unsigned char elementFaceId;
571  used_DoFs_t dofs;
572  };
573 
576  using TNodeConnections = std::map<element_index_t, TNodeElementConnection>;
577 
582  std::vector<TNodeConnections> m_node_connections;
583 
587  std::vector<TRotation3D> m_nodeMainDirection;
588 
589  // Visualization subroutines:
590  void internal_getVisualization_nodeLoads(
591  mrpt::opengl::CSetOfObjects& gl, const DrawStructureOptions& options,
592  const StaticSolveProblemInfo& solver_info,
593  const MeshOutputInfo* meshing_info, num_t DEFORMED_SCALE_FACTOR) const;
594 
595  void internal_getVisualization_constraints(
596  mrpt::opengl::CSetOfObjects& gl, const DrawStructureOptions& options,
597  const StaticSolveProblemInfo& solver_info,
598  const MeshOutputInfo* meshing_info, num_t DEFORMED_SCALE_FACTOR) const;
599 
600  void internal_getVisualization_distributedLoads(
601  const CStructureProblem& str, mrpt::opengl::CSetOfObjects& gl,
602  const DrawStructureOptions& options,
603  const StaticSolveProblemInfo& solver_info,
604  const MeshOutputInfo* meshing_info, num_t DEFORMED_SCALE_FACTOR) const;
605 
606  void internal_getVisualization_stressDiagrams(
607  mrpt::opengl::CSetOfObjects& gl, const DrawStructureOptions& options,
608  const StaticSolveProblemInfo& solverInfo,
609  const MeshOutputInfo* meshingInfo, num_t DEFORMED_SCALE_FACTOR,
610  const StressInfo& stressInfo) const;
611 };
612 } // namespace openbeam
Definition: CFiniteElementProblem.h:196
void getNodeDeformedPosition(size_t i, Vector3 &out_final_point, const StaticSolveProblemInfo &solver_info, const num_t exageration_factor=1) const
std::vector< TRotation3D > m_nodeMainDirection
Definition: CFiniteElementProblem.h:587
std::vector< NodeDoF > m_problem_DoFs
Definition: CFiniteElementProblem.h:560
size_t getNumberOfElements() const
Definition: CFiniteElementProblem.h:297
std::string getNodeLabel(const size_t idx) const
"N%i" or custom label
std::vector< TProblemDOFIndicesForNode > m_problem_DoFs_inverse_list
Definition: CFiniteElementProblem.h:566
TRotationTrans3D & getNodePose(size_t i)
Definition: CFiniteElementProblem.h:351
bool internal_loadFromYaml(const mrpt::containers::yaml &f, const mrpt::optional_ref< vector_string_t > &errMsg, const mrpt::optional_ref< vector_string_t > &warnMsg)
std::vector< std::string > m_node_labels
node custom label
Definition: CFiniteElementProblem.h:474
void solveStatic(StaticSolveProblemInfo &out_info, const StaticSolverOptions &opts=StaticSolverOptions())
load_list_t m_loads_at_each_dof_equivs
Definition: CFiniteElementProblem.h:492
static std::vector< size_t > complementaryDoFs(const std::vector< size_t > &ds, const size_t nTotalDOFs)
virtual void internalComputeStressAndEquivalentLoads()
Definition: CFiniteElementProblem.h:505
constraint_list_t m_DoF_constraints
Definition: CFiniteElementProblem.h:482
size_t createElement(_Args &&... __args)
Definition: CFiniteElementProblem.h:284
void insertConstraint(const size_t dof_index, const num_t value=0)
bool saveAsImageSVG(const std::string &file, const DrawStructureOptions &options, const StaticSolveProblemInfo *solver_info=nullptr, const MeshOutputInfo *meshing_info=nullptr, ImageSaveOutputInfo *out_img_info=nullptr) const
node_index_t insertNode(const TRotationTrans3D &p)
num_t getMaximumDeformedDisplacement(const StaticSolveProblemInfo &solver_info) const
std::map< element_index_t, TNodeElementConnection > TNodeConnections
Definition: CFiniteElementProblem.h:576
const std::vector< NodeDoF > & getProblemDoFs()
Definition: CFiniteElementProblem.h:391
bool loadFromStream(std::istream &is, const mrpt::optional_ref< vector_string_t > &errMsg=std::nullopt, const mrpt::optional_ref< vector_string_t > &warnMsg=std::nullopt)
size_t getDOFIndex(const size_t nNode, const DoF_index n) const
size_t getNumberOfNodes() const
Definition: CFiniteElementProblem.h:337
std::string getProblemDoFsDescription()
void addLoadAtDOF(const size_t dof_index, const num_t f)
size_t insertElement(CElement::Ptr el)
void getBoundingBox(num_t &min_x, num_t &max_x, num_t &min_y, num_t &max_y, bool deformed=false, const StaticSolveProblemInfo *solver_info=nullptr, num_t deformed_scale_factor=1.0) const
CElement::ConstPtr getElement(size_t i) const
void setNodePose(size_t idx, const num_t x, const num_t y, const num_t z)
const TRotationTrans3D & getNodePose(size_t i) const
Definition: CFiniteElementProblem.h:358
std::vector< TNodeConnections > m_node_connections
Definition: CFiniteElementProblem.h:582
bool loadFromFile(const std::string &file, const mrpt::optional_ref< vector_string_t > &errMsg=std::nullopt, const mrpt::optional_ref< vector_string_t > &warnMsg=std::nullopt)
void postProcCalcStress(StressInfo &out_stress, const StaticSolveProblemInfo &solver_info)
void assembleProblem(BuildProblemInfo &out_info)
std::map< size_t, ElementStress > m_extra_stress_for_each_element
Definition: CFiniteElementProblem.h:498
load_list_t m_loads_at_each_dof
Definition: CFiniteElementProblem.h:486
const CElement::Ptr & getElement(size_t i)
void setNodePose(size_t idx, const TRotationTrans3D &p)
void setLoadAtDOF(const size_t dof_index, const num_t f)
Definition: CStructureProblem.h:36
Definition: CFiniteElementProblem.h:79
size_t free_index
Definition: CFiniteElementProblem.h:82
size_t bounded_index
Definition: CFiniteElementProblem.h:80
Definition: CFiniteElementProblem.h:77
Eigen::Matrix< num_t, Eigen::Dynamic, 1 > U_b
Definition: CFiniteElementProblem.h:97
Eigen::Matrix< num_t, Eigen::Dynamic, 1 > F_f
Definition: CFiniteElementProblem.h:101
Definition: CFiniteElementProblem.h:569
unsigned char elementFaceId
To which face in that element.
Definition: CFiniteElementProblem.h:570
used_DoFs_t dofs
DoFs used by that face in that element.
Definition: CFiniteElementProblem.h:571
Definition: CFiniteElementProblem.h:548
std::array< int, 6 > dof_index
Definition: CFiniteElementProblem.h:553
Definition: CFiniteElementProblem.h:466
Definition: DrawStructureOptions.h:34
Definition: types.h:161
Definition: CFiniteElementProblem.h:158
Definition: CFiniteElementProblem.h:138
std::deque< std::vector< element_index_t > > element2elements
List of smaller element IDs resulting from meshing the element [i].
Definition: CFiniteElementProblem.h:154
std::deque< std::vector< node_index_t > > element2nodes
Definition: CFiniteElementProblem.h:151
size_t num_original_elements
Definition: CFiniteElementProblem.h:147
size_t num_original_nodes
Definition: CFiniteElementProblem.h:143
Definition: CFiniteElementProblem.h:128
double max_element_length
In meters (m)
Definition: CFiniteElementProblem.h:131
Definition: CFiniteElementProblem.h:54
DoF_index dof
In the range [0-5].
Definition: CFiniteElementProblem.h:64
Definition: DrawStructureOptions.h:115
Definition: CFiniteElementProblem.h:106
Eigen::Matrix< num_t, Eigen::Dynamic, 1 > U_f
Definition: CFiniteElementProblem.h:116
Eigen::Matrix< num_t, Eigen::Dynamic, 1 > F_b
Definition: CFiniteElementProblem.h:112
BuildProblemInfo build_info
Information from the assembly of the problem.
Definition: CFiniteElementProblem.h:108
Eigen::Matrix< num_t, Eigen::Dynamic, 1 > F
The full F vector (bounded+free DOFs)
Definition: CFiniteElementProblem.h:119
Eigen::Matrix< num_t, Eigen::Dynamic, 1 > U
The full U vector (bounded+free DOFs)
Definition: CFiniteElementProblem.h:122
Definition: CFiniteElementProblem.h:166
Definition: CFiniteElementProblem.h:174
std::vector< ElementStress > element_stress
Definition: CFiniteElementProblem.h:182
Definition: types.h:214