OGS
ComputeNaturalCoordsSolver.h
Go to the documentation of this file.
1// SPDX-FileCopyrightText: Copyright (c) OpenGeoSys Community (opengeosys.org)
2// SPDX-License-Identifier: BSD-3-Clause
3
4#pragma once
5
6#include <Eigen/LU>
7#include <array>
8#include <optional>
9
12
13namespace ApplicationUtils
14{
25{
26public:
27 virtual Eigen::Vector3d solve(MeshLib::Element const& e,
28 Eigen::Vector3d const& real_coords,
29 int const max_iter,
30 double const real_coords_tolerance) const = 0;
31
33};
34
35template <typename ShapeFunction>
38{
39 static constexpr int ElementDim = ShapeFunction::DIM;
41
42public:
43 Eigen::Vector3d solve(MeshLib::Element const& e,
44 Eigen::Vector3d const& real_coords,
45 int const max_iter,
46 double const real_coords_tolerance) const override
47 {
49 using LJM = typename Problem::LocalJacobianMatrix;
50 using LRV = typename Problem::LocalResidualVector;
51
52 Problem problem(e, Eigen::Map<const LRV>(real_coords.data()));
53
54 Eigen::PartialPivLU<LJM> linear_solver(ElementDim);
55 LJM jacobian;
56
57 const double increment_tolerance = 0;
58 auto const newton_solver = NumLib::makeNewtonRaphson(
59 linear_solver,
60 [&problem](LJM& J) { problem.updateJacobian(J); },
61 [&problem](LRV& res) { problem.updateResidual(res); },
62 [&problem](auto& delta_r) { problem.updateSolution(delta_r); },
63 {max_iter, real_coords_tolerance, increment_tolerance});
64
65 auto const opt_iter = newton_solver.solve(jacobian);
66
67 if (opt_iter)
68 {
69 DBUG("Newton solver succeeded after {} iterations", *opt_iter);
70
71 Eigen::Vector3d natural_coords = Eigen::Vector3d::Zero();
72 natural_coords.head<ElementDim>() = problem.getNaturalCoordinates();
73 return natural_coords;
74 }
75
77 "Newton solver failed. Please consider increasing the error "
78 "tolerance or the max. number of Newton iterations.");
79 }
80};
81} // namespace ApplicationUtils
#define OGS_FATAL(...)
Definition Error.h:19
void DBUG(fmt::format_string< Args... > fmt, Args &&... args)
Definition Logging.h:22
EigenFixedShapeMatrixPolicy< ShapeFunction, GlobalDim > ShapeMatrixPolicyType
ShapeMatrixPolicyType< ShapeFunction, ElementDim > ShapeMatricesType
Eigen::Vector3d solve(MeshLib::Element const &e, Eigen::Vector3d const &real_coords, int const max_iter, double const real_coords_tolerance) const override
virtual Eigen::Vector3d solve(MeshLib::Element const &e, Eigen::Vector3d const &real_coords, int const max_iter, double const real_coords_tolerance) const =0
NewtonRaphson< LinearSolver, JacobianMatrixUpdate, ResidualUpdate, SolutionUpdate > makeNewtonRaphson(LinearSolver &linear_solver, JacobianMatrixUpdate &&jacobian_update, ResidualUpdate &&residual_update, SolutionUpdate &&solution_update, NewtonRaphsonSolverParameters const &solver_parameters)