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/system/CTimeLogger.h>
28 #include <mrpt/viz/CSetOfObjects.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  NodeDoF(node_index_t _node_id, uint8_t _dof) : nodeId(_node_id), dof(static_cast<DoF_index>(_dof))
57  {
58  }
59 
60  node_index_t nodeId;
61  DoF_index dof;
62 
63  uint8_t dofAsInt() const { return static_cast<uint8_t>(dof); }
64 };
65 
66 enum class StaticSolverAlgorithm : uint8_t
67 {
68  Dense_LLT = 0,
69  Sparse_LLT
70 };
71 
74 {
75  struct TDoFType
76  {
77  size_t bounded_index;
79  size_t free_index;
81  };
82 
83  Eigen::SparseMatrix<num_t> K_bb;
84  Eigen::SparseMatrix<num_t> K_ff;
85  Eigen::SparseMatrix<num_t> K_bf;
86 
87  std::vector<size_t> free_dof_indices;
88  std::vector<size_t> bounded_dof_indices;
89  std::vector<TDoFType> dof_types;
90 
94  Eigen::Matrix<num_t, Eigen::Dynamic, 1> U_b;
95 
98  Eigen::Matrix<num_t, Eigen::Dynamic, 1> F_f;
99 
102  Eigen::Matrix<num_t, Eigen::Dynamic, 1> F_b_applied;
103 };
104 
107 {
110 
113  Eigen::Matrix<num_t, Eigen::Dynamic, 1> F_b;
114 
117  Eigen::Matrix<num_t, Eigen::Dynamic, 1> U_f;
118 
123  Eigen::Matrix<num_t, Eigen::Dynamic, 1> F;
124 
128  Eigen::Matrix<num_t, Eigen::Dynamic, 1> U;
129 
133  num_t rcond = std::numeric_limits<num_t>::quiet_NaN();
134 
136  std::vector<std::string> warnings;
137 };
138 
142 {
143  MeshParams();
144 
146 };
147 
152 {
153  MeshOutputInfo() = default;
154 
157  size_t num_original_nodes = 0;
158 
162 
165  std::deque<std::vector<node_index_t>> element2nodes;
166 
168  std::deque<std::vector<element_index_t>> element2elements;
169 };
170 
172 {
173  ImageSaveOutputInfo() = default;
174 
175  unsigned int img_width = 0, img_height = 0;
176 };
177 
180 {
181  StaticSolverOptions() = default;
182 
185  StaticSolverAlgorithm algorithm = StaticSolverAlgorithm::Sparse_LLT;
186  bool nonLinearIterative = false;
187 };
188 
190 {
191  StressInfo() {}
192 
198  std::vector<ElementStress> element_stress;
199 };
200 
212 {
213  public:
214  using constraint_list_t = std::map<size_t, num_t>;
215  using load_list_t = std::map<size_t, num_t>;
216 
217  CFiniteElementProblem() = default;
218  virtual ~CFiniteElementProblem();
219 
220  // ----------------------------------------------------------------------------
224  virtual void clear();
226 
237  std::istream& is,
238  const mrpt::optional_ref<vector_string_t>& errMsg = std::nullopt,
239  const mrpt::optional_ref<vector_string_t>& warnMsg = std::nullopt);
240 
251  const std::string& file,
252  const mrpt::optional_ref<vector_string_t>& errMsg = std::nullopt,
253  const mrpt::optional_ref<vector_string_t>& warnMsg = std::nullopt);
254 
260  const std::string& file,
261  const DrawStructureOptions& options,
262  const StaticSolveProblemInfo* solver_info = nullptr,
263  const MeshOutputInfo* meshing_info = nullptr,
264  ImageSaveOutputInfo* out_img_info = nullptr) const;
265  bool saveAsImagePNG(
266  const std::string& file,
267  const DrawStructureOptions& options,
268  const StaticSolveProblemInfo* solver_info = nullptr,
269  const MeshOutputInfo* meshing_info = nullptr,
270  ImageSaveOutputInfo* out_img_info = nullptr) const;
271  bool saveAsImage(
272  const std::string& file,
273  const bool is_svg,
274  const DrawStructureOptions& options,
275  const StaticSolveProblemInfo* solver_info = nullptr,
276  const MeshOutputInfo* meshing_info = nullptr,
277  ImageSaveOutputInfo* out_img_info = nullptr) const;
278 
279  bool renderToCairoContext(
280  void* _cairo_context,
281  const RenderInitData& ri,
282  const DrawStructureOptions& options,
283  const StaticSolveProblemInfo* solver_info,
284  const MeshOutputInfo* meshing_info) const;
285 
286  mrpt::viz::CSetOfObjects::Ptr getVisualization(
287  const DrawStructureOptions& options,
288  const StaticSolveProblemInfo& solver_info,
289  const MeshOutputInfo* meshing_info = nullptr,
290  const StressInfo* stressInfo = nullptr) const;
291 
293  // ----------------------------------------------------------------------------
299  size_t insertElement(CElement::Ptr el);
300 
303  template <typename ElementClass, typename... _Args>
304  size_t createElement(_Args&&... __args)
305  {
306  return insertElement(std::make_shared<ElementClass>(std::forward<_Args>(__args)...));
307  }
308 
310  CElement::ConstPtr getElement(size_t i) const;
311 
313  const CElement::Ptr& getElement(size_t i);
314 
316  size_t getNumberOfElements() const { return m_elements.size(); }
317 
319  // ----------------------------------------------------------------------------
326  void insertConstraint(const size_t dof_index, const num_t value = 0);
327 
328  const constraint_list_t& getAllConstraints() const { return m_DoF_constraints; }
329 
336  bool addNodeConstraint(node_index_t node, DoF_index dof, num_t value = 0);
337 
339  const std::map<std::pair<node_index_t, DoF_index>, num_t>& getNodeConstraintRequests() const
340  {
342  }
343 
346  void setLoadAtDOF(const size_t dof_index, const num_t f);
347 
350  void addLoadAtDOF(const size_t dof_index, const num_t f);
351 
352  const load_list_t& getOverallLoadsOnDOFs() const { return m_loads_at_each_dof; }
353 
355  // ----------------------------------------------------------------------------
361  void setNumberOfNodes(size_t N);
362 
364  size_t getNumberOfNodes() const { return m_node_poses.size(); }
365 
368  node_index_t insertNode(const TRotationTrans3D& p);
369 
371  void setNodePose(size_t idx, const TRotationTrans3D& p);
372 
374  void setNodePose(size_t idx, const num_t x, const num_t y, const num_t z);
375 
379  {
380  ASSERT_(i < m_node_poses.size());
381  return m_node_poses[i];
382  }
385  const TRotationTrans3D& getNodePose(size_t i) const
386  {
387  ASSERT_(i < m_node_poses.size());
388  return m_node_poses[i];
389  }
390 
394  size_t i,
395  Vector3& out_final_point,
396  const StaticSolveProblemInfo& solver_info,
397  const num_t exageration_factor = 1) const;
398 
402 
405  num_t& min_x,
406  num_t& max_x,
407  num_t& min_y,
408  num_t& max_y,
409  bool deformed = false,
410  const StaticSolveProblemInfo* solver_info = nullptr,
411  num_t deformed_scale_factor = 1.0) const;
412 
414  // ----------------------------------------------------------------------------
421  const std::vector<NodeDoF>& getProblemDoFs()
422  {
423  updateListDoFs();
424  return m_problem_DoFs;
425  }
426 
430 
434  static std::vector<size_t> complementaryDoFs(
435  const std::vector<size_t>& ds, const size_t nTotalDOFs);
436 
442  size_t getDOFIndex(const size_t nNode, const DoF_index n) const;
443 
445  // ----------------------------------------------------------------------------
455  virtual void updateAll();
456 
466 
476 
482  void postProcCalcStress(StressInfo& out_stress, const StaticSolveProblemInfo& solver_info);
483 
484  std::string getNodeLabel(const size_t idx) const;
485 
487  // ----------------------------------------------------------------------------
488  protected:
492  struct node_used_t
493  {
494  node_used_t() = default;
495 
496  bool used = false;
497  };
498 
499  std::deque<node_used_t> m_node_defined;
500  std::deque<TRotationTrans3D> m_node_poses;
501  std::vector<std::string> m_node_labels;
502  std::deque<CElement::Ptr> m_elements;
503 
509  constraint_list_t m_DoF_constraints;
510 
512  std::map<std::pair<node_index_t, DoF_index>, num_t> m_node_constraint_requests;
513 
516  load_list_t m_loads_at_each_dof;
517 
523 
528  std::map<size_t, ElementStress> m_extra_stress_for_each_element;
529 
536 
539  const mrpt::containers::yaml& f,
540  const mrpt::optional_ref<vector_string_t>& errMsg,
541  const mrpt::optional_ref<vector_string_t>& warnMsg);
542 
543  void internal_parser1_Parameters(const mrpt::containers::yaml& f, EvaluationContext& ctx) const;
544 
545  void internal_parser2_BeamSections(const mrpt::containers::yaml& f, EvaluationContext& ctx) const;
546 
547  void internal_parser3_nodes(const mrpt::containers::yaml& f, EvaluationContext& ctx);
548  void internal_parser4_elements(const mrpt::containers::yaml& f, EvaluationContext& ctx);
549  void internal_parser5_constraints(const mrpt::containers::yaml& f, EvaluationContext& ctx);
550 
551  void internal_parser6_node_loads(const mrpt::containers::yaml& f, EvaluationContext& ctx);
552  void internal_parser7_element_loads(const mrpt::containers::yaml& f, EvaluationContext& ctx);
553 
558 
561 
565 
568 
572  const DynMatrix& Kff, const std::vector<size_t>& free_dof_indices) const;
573 
576  {
577  TProblemDOFIndicesForNode() = default;
578 
581  std::array<int, 6> dof_index = {-1, -1, -1, -1, -1, -1};
582  };
583 
588  std::vector<NodeDoF> m_problem_DoFs;
589 
594  std::vector<TProblemDOFIndicesForNode> m_problem_DoFs_inverse_list;
595 
597  {
598  unsigned char elementFaceId;
599  used_DoFs_t dofs;
600  };
601 
604  using TNodeConnections = std::map<element_index_t, TNodeElementConnection>;
605 
610  std::vector<TNodeConnections> m_node_connections;
611 
615  std::vector<TRotation3D> m_nodeMainDirection;
616 
617  // Visualization subroutines:
618  void internal_getVisualization_nodeLoads(
619  mrpt::viz::CSetOfObjects& gl,
620  const DrawStructureOptions& options,
621  const StaticSolveProblemInfo& solver_info,
622  const MeshOutputInfo* meshing_info,
623  num_t DEFORMED_SCALE_FACTOR) const;
624 
625  void internal_getVisualization_constraints(
626  mrpt::viz::CSetOfObjects& gl,
627  const DrawStructureOptions& options,
628  const StaticSolveProblemInfo& solver_info,
629  const MeshOutputInfo* meshing_info,
630  num_t DEFORMED_SCALE_FACTOR) const;
631 
632  void internal_getVisualization_distributedLoads(
633  const CStructureProblem& str,
634  mrpt::viz::CSetOfObjects& gl,
635  const DrawStructureOptions& options,
636  const StaticSolveProblemInfo& solver_info,
637  const MeshOutputInfo* meshing_info,
638  num_t DEFORMED_SCALE_FACTOR) const;
639 
640  void internal_getVisualization_stressDiagrams(
641  mrpt::viz::CSetOfObjects& gl,
642  const DrawStructureOptions& options,
643  const StaticSolveProblemInfo& solverInfo,
644  const MeshOutputInfo* meshingInfo,
645  num_t DEFORMED_SCALE_FACTOR,
646  const StressInfo& stressInfo) const;
647 };
648 } // namespace openbeam
Definition: CFiniteElementProblem.h:212
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:615
std::vector< NodeDoF > m_problem_DoFs
Definition: CFiniteElementProblem.h:588
size_t getNumberOfElements() const
Definition: CFiniteElementProblem.h:316
std::string getNodeLabel(const size_t idx) const
"N%i" or custom label
std::vector< TProblemDOFIndicesForNode > m_problem_DoFs_inverse_list
Definition: CFiniteElementProblem.h:594
TRotationTrans3D & getNodePose(size_t i)
Definition: CFiniteElementProblem.h:378
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:501
void solveStatic(StaticSolveProblemInfo &out_info, const StaticSolverOptions &opts=StaticSolverOptions())
load_list_t m_loads_at_each_dof_equivs
Definition: CFiniteElementProblem.h:522
static std::vector< size_t > complementaryDoFs(const std::vector< size_t > &ds, const size_t nTotalDOFs)
virtual void internalComputeStressAndEquivalentLoads()
Definition: CFiniteElementProblem.h:535
std::map< std::pair< node_index_t, DoF_index >, num_t > m_node_constraint_requests
See addNodeConstraint()
Definition: CFiniteElementProblem.h:512
constraint_list_t m_DoF_constraints
Definition: CFiniteElementProblem.h:509
size_t createElement(_Args &&... __args)
Definition: CFiniteElementProblem.h:304
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:604
const std::vector< NodeDoF > & getProblemDoFs()
Definition: CFiniteElementProblem.h:421
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:364
std::string getProblemDoFsDescription()
std::string describeSingularStiffness(const DynMatrix &Kff, const std::vector< size_t > &free_dof_indices) const
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:385
std::vector< TNodeConnections > m_node_connections
Definition: CFiniteElementProblem.h:610
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:528
const std::map< std::pair< node_index_t, DoF_index >, num_t > & getNodeConstraintRequests() const
Constraints as requested with addNodeConstraint()
Definition: CFiniteElementProblem.h:339
load_list_t m_loads_at_each_dof
Definition: CFiniteElementProblem.h:516
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)
bool addNodeConstraint(node_index_t node, DoF_index dof, num_t value=0)
Definition: CStructureProblem.h:36
Definition: CFiniteElementProblem.h:76
size_t free_index
Definition: CFiniteElementProblem.h:79
size_t bounded_index
Definition: CFiniteElementProblem.h:77
Definition: CFiniteElementProblem.h:74
Eigen::Matrix< num_t, Eigen::Dynamic, 1 > U_b
Definition: CFiniteElementProblem.h:94
Eigen::Matrix< num_t, Eigen::Dynamic, 1 > F_f
Definition: CFiniteElementProblem.h:98
Eigen::Matrix< num_t, Eigen::Dynamic, 1 > F_b_applied
Definition: CFiniteElementProblem.h:102
Definition: CFiniteElementProblem.h:597
unsigned char elementFaceId
To which face in that element.
Definition: CFiniteElementProblem.h:598
used_DoFs_t dofs
DoFs used by that face in that element.
Definition: CFiniteElementProblem.h:599
Definition: CFiniteElementProblem.h:576
std::array< int, 6 > dof_index
Definition: CFiniteElementProblem.h:581
Definition: CFiniteElementProblem.h:493
Definition: DrawStructureOptions.h:34
Definition: types.h:160
Definition: CFiniteElementProblem.h:172
Definition: CFiniteElementProblem.h:152
std::deque< std::vector< element_index_t > > element2elements
List of smaller element IDs resulting from meshing the element [i].
Definition: CFiniteElementProblem.h:168
std::deque< std::vector< node_index_t > > element2nodes
Definition: CFiniteElementProblem.h:165
size_t num_original_elements
Definition: CFiniteElementProblem.h:161
size_t num_original_nodes
Definition: CFiniteElementProblem.h:157
Definition: CFiniteElementProblem.h:142
double max_element_length
In meters (m)
Definition: CFiniteElementProblem.h:145
Definition: CFiniteElementProblem.h:54
DoF_index dof
In the range [0-5].
Definition: CFiniteElementProblem.h:61
Definition: DrawStructureOptions.h:114
Definition: CFiniteElementProblem.h:107
Eigen::Matrix< num_t, Eigen::Dynamic, 1 > U_f
Definition: CFiniteElementProblem.h:117
Eigen::Matrix< num_t, Eigen::Dynamic, 1 > F_b
Definition: CFiniteElementProblem.h:113
BuildProblemInfo build_info
Information from the assembly of the problem.
Definition: CFiniteElementProblem.h:109
num_t rcond
Definition: CFiniteElementProblem.h:133
Eigen::Matrix< num_t, Eigen::Dynamic, 1 > F
Definition: CFiniteElementProblem.h:123
std::vector< std::string > warnings
Non-fatal issues found while solving (e.g. ill-conditioning)
Definition: CFiniteElementProblem.h:136
Eigen::Matrix< num_t, Eigen::Dynamic, 1 > U
Definition: CFiniteElementProblem.h:128
Definition: CFiniteElementProblem.h:180
StaticSolverAlgorithm algorithm
Definition: CFiniteElementProblem.h:185
Definition: CFiniteElementProblem.h:190
std::vector< ElementStress > element_stress
Definition: CFiniteElementProblem.h:198
Definition: types.h:214