20#ifndef B2MONOLITHIC_SOLVER_H_
21#define B2MONOLITHIC_SOLVER_H_
23#include "b2typed_solver.H"
24#include "time_integration/b2newmark.H"
25#include "utils/linear_algebra/b2linear_algebra_utils.H"
27namespace b2000::solver {
29template <
typename T,
typename MATRIX_FORMAT>
30class MonolithicSolver final :
public TypedSolver<T, MATRIX_FORMAT> {
33 ObjectTypeComplete<MonolithicSolver, typename TypedSolver<T, MATRIX_FORMAT>::type_t>;
35 void solve()
override;
40 void InitializeSolverOnCase()
override;
42 bool solve_iteration()
override;
45template <
typename T,
typename MATRIX_FORMAT>
46void MonolithicSolver<T, MATRIX_FORMAT>::InitializeSolverOnCase() {
47 TypedSolver<T, MATRIX_FORMAT>::InitializeSolverOnCase();
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);
62 int n = this->is_dynamic_ ? 3 : 2;
63 this->dof_.resize(this->dof_.size1(), n);
64 this->case_->set_stage(this->current_stage_);
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_);
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();
92 while ((this->case_ = this->case_iterator_->next())) {
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;
102 InitializeSolverOnCase();
105 while (this->time_ < this->time_max_) {
106 if (this->is_dynamic_ || this->is_damped_) { this->solution_->new_cycle(); }
108 this->iteration_count_ = 0;
110 this->SetSolutionFieldsToZero();
112 this->essential_boundary_conditions_->UpdateEssentialBoundaryConditions(
113 this->time_, this->fixed_dof_, this->dof_, this->dU_);
115 this->natural_boundary_conditions_->UpdateNaturalBoundaryConditions(
116 this->time_, this->fixed_dof_, this->F_eff_);
118 this->time_ += this->step_size_;
120 logger <<
logging::info <<
"Solve for time " << this->time_ << logging::LOGFLUSH;
122 if (this->is_damped_ || this->is_dynamic_) {
123 this->time_integrator_->InitializeFieldsForThisTimeStep(this->dof_, this->dU_);
127 while (solve_iteration());
130 if (!this->is_dynamic_ && !this->is_damped_) {
131 this->solution_->set_dof(this->dof_[0]);
133 this->solution_->set_solution(
134 this->dof_, this->time_, b2linalg::Vector<T, b2linalg::Vdense>::null,
135 b2linalg::Vector<T, b2linalg::Vdense>::null);
139 if (this->case_->get_int(
"GRADIENTS", 0)) {
140 this->MainLoopOverElements(
141 TypedSolver<T, MATRIX_FORMAT>::b2Task::compute_gradients);
145 this->solution_->set_natural_boundary_condition(
146 this->natural_boundary_conditions_->GetPrescribedNodalForces());
148 this->solution_->terminate_cycle(this->time_, this->step_size_, RTable{});
151 this->solution_->terminate_stage();
152 this->solution_->terminate_case(
true, RTable{});
154 logger <<
logging::info <<
"Finished the monolithic solver for case "
155 << this->case_->get_id() << logging::LOGFLUSH;
159template <
typename T,
typename MATRIX_FORMAT>
160bool MonolithicSolver<T, MATRIX_FORMAT>::solve_iteration() {
166 this->MainLoopOverElements(TypedSolver<T, MATRIX_FORMAT>::b2Task::assemble_effective_system);
170 this->SolveEffectiveSystem();
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);
194 tbb::parallel_for(
static_cast<size_t>(0), this->dof_.size1(), UpdateSolutionfields);
196 for (
size_t i{}; i < this->dof_.size1(); ++i) { UpdateSolutionfields(i); }
199 if (this->is_damped_ || this->is_dynamic_) {
200 this->time_integrator_->UpdateFields(this->dof_, this->dU_);
213 if (this->is_linear_) {
return false; }
215 this->iteration_count_++;
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>(),
228 "MLINEAR",
"MSTATIC_LINEAR_SOLUTION",
"MDYNAMIC_LINEAR",
"MTRANSIENT_LINEAR",
229 "MNONLINEAR",
"MSTATIC_NONLINEAR_SOLUTION",
"MDYNAMIC_NONLINEAR",
230 "MTRANSIENT_NONLINEAR"),
231 b2000::solver::module, &TypedSolver<T, MATRIX_FORMAT>::type);
Logger & get_logger(const std::string &logger_name="")
Definition b2logging.H:829