ryujin 2.1.1 revision 0f269b6e84acefa08132307953bd597a510add24
newton.h
Go to the documentation of this file.
1//
2// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
3// Copyright (C) 2020 - 2023 by the ryujin authors
4//
5
6#pragma once
7
8#include <compile_time_options.h>
9
10#include "simd.h"
11
12#include <array>
13
14namespace ryujin
15{
20
37 template <typename Number>
38 DEAL_II_ALWAYS_INLINE inline void
40 Number &p_2,
41 const Number phi_p_1,
42 const Number phi_p_2,
43 const Number dphi_p_1,
44 const Number dphi_p_2,
45 const Number sign = Number(1.0))
46 {
47 using ScalarNumber = typename get_value_type<Number>::type;
48 constexpr ScalarNumber eps = std::numeric_limits<ScalarNumber>::epsilon();
49
50 /* Compute divided differences: */
51
52 const auto scaling = ScalarNumber(1.) / (p_2 - p_1 + Number(eps));
53
54 const Number dd_11 = dphi_p_1;
55 const Number dd_12 = (phi_p_2 - phi_p_1) * scaling;
56 const Number dd_22 = dphi_p_2;
57
58 const Number dd_112 = (dd_12 - dd_11) * scaling;
59 const Number dd_122 = (dd_22 - dd_12) * scaling;
60
61 /* Update left and right point: */
62
63 const auto discriminant_1 =
64 std::abs(dphi_p_1 * dphi_p_1 - ScalarNumber(4.) * phi_p_1 * dd_112);
65 const auto discriminant_2 =
66 std::abs(dphi_p_2 * dphi_p_2 - ScalarNumber(4.) * phi_p_2 * dd_122);
67
68 const auto denominator_1 = dphi_p_1 + sign * std::sqrt(discriminant_1);
69 const auto denominator_2 = dphi_p_2 + sign * std::sqrt(discriminant_2);
70
71 /* Make sure we do not produce NaNs: */
72
73 auto t_1 =
74 p_1 - dealii::compare_and_apply_mask<dealii::SIMDComparison::less_than>(
75 std::abs(denominator_1),
76 Number(eps),
77 Number(0.),
78 ScalarNumber(2.) * phi_p_1 / denominator_1);
79
80 auto t_2 =
81 p_2 - dealii::compare_and_apply_mask<dealii::SIMDComparison::less_than>(
82 std::abs(denominator_2),
83 Number(eps),
84 Number(0.),
85 ScalarNumber(2.) * phi_p_2 / denominator_2);
86
87 /* Enforce bounds: */
88
89 t_1 = std::max(p_1, t_1);
90 t_1 = std::min(p_2, t_1);
91
92 t_2 = std::max(p_1, t_2);
93 t_2 = std::min(p_2, t_2);
94
95 /* Ensure that always p_1 <= p_2: */
96
97 p_1 = std::min(t_1, t_2);
98 p_2 = std::max(t_1, t_2);
99
100 return;
101 }
102
104
105} /* namespace ryujin */
DEAL_II_ALWAYS_INLINE void quadratic_newton_step(Number &p_1, Number &p_2, const Number phi_p_1, const Number phi_p_2, const Number dphi_p_1, const Number dphi_p_2, const Number sign=Number(1.0))
Definition: newton.h:39