b2api
B2000++ API Reference Manual, VERSION 4.6
 
Loading...
Searching...
No Matches
b2monolithic_solver.H
1//------------------------------------------------------------------------
2// b2monolithic_solver.H --
3//
4//
5// written by Thomas Blome <thomas.blome@dlr.de>
6// Neda Ebrahimi Pour <neda.ebrahimipour@dlr.de>
7//
8// (c) 2004-2012 SMR Engineering & Development SA
9// 2502 Bienne, Switzerland
10//
11// (c) 2024 Deutsches Zentrum für Luft- und Raumfahrt (DLR) e.V.
12// Linder Höhe, 51147 Köln
13//
14// All Rights Reserved. Proprietary source code. The contents of
15// this file may not be disclosed to third parties, copied or
16// duplicated in any form, in whole or in part, without the prior
17// written permission of SMR.
18//------------------------------------------------------------------------
19
20#ifndef B2MONOLITHIC_SOLVER_H_
21#define B2MONOLITHIC_SOLVER_H_
22
23#include "b2typed_solver.H"
24#include "time_integration/b2newmark.H"
25#include "utils/linear_algebra/b2linear_algebra_utils.H"
26
27namespace b2000::solver {
28
29template <typename T, typename MATRIX_FORMAT>
30class MonolithicSolver final : public TypedSolver<T, MATRIX_FORMAT> {
31public:
32 using type_t =
33 ObjectTypeComplete<MonolithicSolver, typename TypedSolver<T, MATRIX_FORMAT>::type_t>;
34
35 void solve() override;
36
37 static type_t type;
38
39protected:
40 void InitializeSolverOnCase() override;
41
42 bool solve_iteration() override;
43};
44
45template <typename T, typename MATRIX_FORMAT>
46void MonolithicSolver<T, MATRIX_FORMAT>::InitializeSolverOnCase() {
47 TypedSolver<T, MATRIX_FORMAT>::InitializeSolverOnCase();
48
55 if (this->is_dynamic_ || this->is_damped_) {
57 std::string domain_state_id;
58 dynamic_cast<TypedInitialCondition<T>&>(this->model_->get_initial_condition())
59 .get_dynamic_initial_condition_value(
60 this->dof_, this->time_, this->current_stage_, domain_state_id);
61
62 int n = this->is_dynamic_ ? 3 : 2;
63 this->dof_.resize(this->dof_.size1(), n);
64 this->case_->set_stage(this->current_stage_);
65
66 // if (!domain_state_id.empty()) { domain.load_state(domain_state_id); } //! Wofür??
67 // Löschen?
69
70 if (this->is_linear_) {
71 this->time_integrator_.reset(NewmarkIntegrator<T>::type.new_object());
72 this->time_integrator_->InitializeTimeIntegrator(this->dof_, this->step_size_);
73 } else {
74 // time_integrator_.reset(NordsieckIntegrator<T, MATRIX_FORMAT>::type.new_object());
75 // time_integrator_->InitializeTimeIntegrator(...)
76 }
77 }
78
79 // this->essential_boundary_conditions_->UpdateEssentialBoundaryConditions(
80 // this->time_, this->fixed_dof_, this->dof_, this->dU_);
81
82 // this->natural_boundary_conditions_->UpdateNaturalBoundaryConditions(
83 // this->time_, this->fixed_dof_, this->F_eff_);
84}
85
86template <typename T, typename MATRIX_FORMAT>
87void MonolithicSolver<T, MATRIX_FORMAT>::solve() {
88 CaseList& case_list = this->model_->get_case_list();
89 this->case_iterator_ = case_list.get_case_iterator();
90
92 while ((this->case_ = this->case_iterator_->next())) {
93 // solve_on_case(*case_);
94
95 // if (case_ == nullptr) { solve_init(); }
96
97 logging::Logger& logger = logging::get_logger("solver.monolithic");
98 logger << logging::info << "Starting the monolithic solver for case "
99 << this->case_->get_id() << logging::LOGFLUSH;
100 logger << logging::info << "Stage is: " << this->case_->get_stage_id() << logging::LOGFLUSH;
101
102 InitializeSolverOnCase();
103
105 while (this->time_ < this->time_max_) {
106 if (this->is_dynamic_ || this->is_damped_) { this->solution_->new_cycle(); }
107
108 this->iteration_count_ = 0;
109
110 this->SetSolutionFieldsToZero();
111
112 this->essential_boundary_conditions_->UpdateEssentialBoundaryConditions(
113 this->time_, this->fixed_dof_, this->dof_, this->dU_);
114
115 this->natural_boundary_conditions_->UpdateNaturalBoundaryConditions(
116 this->time_, this->fixed_dof_, this->F_eff_);
117
118 this->time_ += this->step_size_;
119
120 logger << logging::info << "Solve for time " << this->time_ << logging::LOGFLUSH;
121
122 if (this->is_damped_ || this->is_dynamic_) {
123 this->time_integrator_->InitializeFieldsForThisTimeStep(this->dof_, this->dU_);
124 }
125
126 // clang-format off
127 while (solve_iteration());
128 // clang-format on
129
130 if (!this->is_dynamic_ && !this->is_damped_) {
131 this->solution_->set_dof(this->dof_[0]);
132 } else {
133 this->solution_->set_solution(
134 this->dof_, this->time_, b2linalg::Vector<T, b2linalg::Vdense>::null,
135 b2linalg::Vector<T, b2linalg::Vdense>::null);
136 }
137
139 if (this->case_->get_int("GRADIENTS", 0)) {
140 this->MainLoopOverElements(
141 TypedSolver<T, MATRIX_FORMAT>::b2Task::compute_gradients);
142 }
143
145 this->solution_->set_natural_boundary_condition(
146 this->natural_boundary_conditions_->GetPrescribedNodalForces());
147
148 this->solution_->terminate_cycle(this->time_, this->step_size_, RTable{});
149 }
150
151 this->solution_->terminate_stage();
152 this->solution_->terminate_case(true, RTable{});
153
154 logger << logging::info << "Finished the monolithic solver for case "
155 << this->case_->get_id() << logging::LOGFLUSH;
156 }
157}
158
159template <typename T, typename MATRIX_FORMAT>
160bool MonolithicSolver<T, MATRIX_FORMAT>::solve_iteration() {
161 bool result{};
162
165
166 this->MainLoopOverElements(TypedSolver<T, MATRIX_FORMAT>::b2Task::assemble_effective_system);
167
168 try {
169 // MainLoopOverElements(b2Task::compute_error);
170 this->SolveEffectiveSystem();
171 } catch (...) {
172 // SolutionMonolithic<T>& solution =
173 // dynamic_cast<SolutionMonolithic<T>&>(model_->get_solution());
174 // solution.terminate_stage(false);
175 // RTable attributes;
176 // solution.terminate_case(false, attributes);
177 throw;
178 }
179
180 auto UpdateSolutionfields{[&](size_t i) {
181 if (this->fixed_dof_[i] >= 0) {
182 this->dU_(i, 1) = this->F_eff_[this->fixed_dof_[i]];
183 this->dU_(i, 0) += this->dU_(i, 1);
184 this->dof_(i, 0) += this->dU_(i, 1);
185 } else if (this->iteration_count_ == 0) {
187 this->dof_(i, 0) += this->dU_(i, 0);
188 this->dU_(i, 0) = 0;
189 }
190 }};
191
193#ifdef HAVE_LIB_TBB
194 tbb::parallel_for(static_cast<size_t>(0), this->dof_.size1(), UpdateSolutionfields);
195#else
196 for (size_t i{}; i < this->dof_.size1(); ++i) { UpdateSolutionfields(i); }
197#endif
198
199 if (this->is_damped_ || this->is_dynamic_) {
200 this->time_integrator_->UpdateFields(this->dof_, this->dU_);
201 }
202
203 // if (!result) { //! < Wofür ist das???
204 // RTable attributes;
205 // // dynamic_cast<SolutionMonolithic<T>&>(model_->get_solution())
206 // // .terminate_case(true, attributes);
207 // case_ = nullptr;
208 // solve_init();
209 // if (case_ == nullptr) { return false; }
210 // }
211
213 if (this->is_linear_) { return false; }
214
215 this->iteration_count_++;
216
217 return true;
218}
219
224template <typename T, typename MATRIX_FORMAT>
225typename MonolithicSolver<T, MATRIX_FORMAT>::type_t MonolithicSolver<T, MATRIX_FORMAT>::type(
226 "MonolithicSolver", type_name<T, MATRIX_FORMAT>(),
227 StringList(
228 "MLINEAR", "MSTATIC_LINEAR_SOLUTION", "MDYNAMIC_LINEAR", "MTRANSIENT_LINEAR",
229 "MNONLINEAR", "MSTATIC_NONLINEAR_SOLUTION", "MDYNAMIC_NONLINEAR",
230 "MTRANSIENT_NONLINEAR"), // Add also "MCOLLAPSE"? (TB)
231 b2000::solver::module, &TypedSolver<T, MATRIX_FORMAT>::type);
232
233} // namespace b2000::solver
234
235#endif // B2MONOLITHIC_SOLVER_H_
Logger & get_logger(const std::string &logger_name="")
Definition b2logging.H:829