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