Page MenuHomec4science

beck_teboulle.cpp
No OneTemporary

File Metadata

Created
Sun, Nov 17, 09:16

beck_teboulle.cpp

/*
* SPDX-License-Indentifier: AGPL-3.0-or-later
*
* Copyright (©) 2016-2024 EPFL (École Polytechnique Fédérale de Lausanne),
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
* Copyright (©) 2020-2024 Lucas Frérot
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "beck_teboulle.hh"
#include "logger.hh"
#include <iomanip>
/* -------------------------------------------------------------------------- */
namespace tamaas {
BeckTeboulle::BeckTeboulle(Model& model, const GridBase<Real>& surface,
Real tolerance, Real mu)
: Kato(model, surface, tolerance, mu) {}
/* -------------------------------------------------------------------------- */
Real BeckTeboulle::solve(std::vector<Real> g0_vec) {
GridBase<Real> g0(g0_vec.size(), 1);
std::copy(g0_vec.begin(), g0_vec.end(), g0.begin());
TAMAAS_ASSERT(g0.getNbPoints() == pressure->getNbComponents(),
"Target mean gap does not have the right number of components");
Real cost = 0;
switch (model.getType()) {
case model_type::surface_1d:
cost = solveTmpl<model_type::surface_1d>(g0);
break;
case model_type::surface_2d:
cost = solveTmpl<model_type::surface_2d>(g0);
break;
default:
break;
}
return cost;
}
template <model_type type>
Real BeckTeboulle::solveTmpl(GridBase<Real>& g0) {
// Printing column headers
Logger().get(LogLevel::info) << std::setw(5) << "Iter"
<< " " << std::setw(15) << "Cost_f"
<< " " << std::setw(15) << "Error" << '\n'
<< std::fixed;
constexpr UInt comp = model_type_traits<type>::components;
Real cost = 0;
UInt n = 0;
*pressure = 0;
GridBase<Real> z(*pressure);
GridBase<Real> pressure_old(*pressure);
Real t0 = 1;
Real t1 = 1;
Real m = 0;
Real lipschitz = engine.getNeumannNorm();
do {
engine.solveNeumann(*pressure, *gap);
addUniform<comp>(*gap, g0);
*gap -= *surfaceComp;
z = *gap;
z /= -lipschitz;
*pressure += z;
enforcePressureCoulomb<comp>();
z = *pressure;
t1 = 1 + std::sqrt(4 * t0 * t0 + 1) / 2;
m = 1 + (t0 - 1) / t1;
z -= pressure_old;
z *= m;
z += pressure_old;
t0 = t1;
pressure_old = *pressure;
cost = computeCost();
printState(n, cost, cost);
} while (cost > this->tolerance && n++ < this->max_iterations);
computeFinalGap<comp>();
return cost;
}
} // namespace tamaas
/* -------------------------------------------------------------------------- */

Event Timeline