Loading [MathJax]/extensions/tex2jax.js
OGS
ComputeNaturalCoordsSolver.h
Go to the documentation of this file.
1
10#pragma once
11
12#include <Eigen/LU>
13#include <array>
14#include <optional>
15
18
19namespace ApplicationUtils
20{
31{
32public:
33 virtual Eigen::Vector3d solve(MeshLib::Element const& e,
34 Eigen::Vector3d const& real_coords,
35 int const max_iter,
36 double const real_coords_tolerance) const = 0;
37
39};
40
41template <typename ShapeFunction>
44{
45 static constexpr int ElementDim = ShapeFunction::DIM;
47
48public:
49 Eigen::Vector3d solve(MeshLib::Element const& e,
50 Eigen::Vector3d const& real_coords,
51 int const max_iter,
52 double const real_coords_tolerance) const override
53 {
55 using LJM = typename Problem::LocalJacobianMatrix;
56 using LRV = typename Problem::LocalResidualVector;
57
58 Problem problem(e, Eigen::Map<const LRV>(real_coords.data()));
59
60 Eigen::PartialPivLU<LJM> linear_solver(ElementDim);
61 LJM jacobian;
62
63 const double increment_tolerance = 0;
64 auto const newton_solver = NumLib::makeNewtonRaphson(
65 linear_solver,
66 [&problem](LJM& J) { problem.updateJacobian(J); },
67 [&problem](LRV& res) { problem.updateResidual(res); },
68 [&problem](auto& delta_r) { problem.updateSolution(delta_r); },
69 {max_iter, real_coords_tolerance, increment_tolerance});
70
71 auto const opt_iter = newton_solver.solve(jacobian);
72
73 if (opt_iter)
74 {
75 DBUG("Newton solver succeeded after {} iterations", *opt_iter);
76
77 Eigen::Vector3d natural_coords = Eigen::Vector3d::Zero();
78 natural_coords.head<ElementDim>() = problem.getNaturalCoordinates();
79 return natural_coords;
80 }
81
83 "Newton solver failed. Please consider increasing the error "
84 "tolerance or the max. number of Newton iterations.");
85 }
86};
87} // namespace ApplicationUtils
#define OGS_FATAL(...)
Definition Error.h:26
void DBUG(fmt::format_string< Args... > fmt, Args &&... args)
Definition Logging.h:30
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)