Branch data Line data Source code
1 : : // *****************************************************************************
2 : : /*!
3 : : \file src/Inciter/AMR/Error.cpp
4 : : \copyright 2012-2015 J. Bakosi,
5 : : 2016-2018 Los Alamos National Security, LLC.,
6 : : 2019-2021 Triad National Security, LLC.,
7 : : 2022-2024 J. Bakosi
8 : : All rights reserved. See the LICENSE file for details.
9 : : \brief Class for computing error estimates for mesh refinement
10 : : \details Class for computing error estimates for mesh refinement.
11 : : */
12 : : // *****************************************************************************
13 : :
14 : : #include <cmath>
15 : : #include <limits>
16 : :
17 : : #include "Exception.hpp"
18 : : #include "Error.hpp"
19 : : #include "Vector.hpp"
20 : : #include "Gradients.hpp"
21 : :
22 : : using AMR::Error;
23 : :
24 : : tk::real
25 : 163744 : Error::scalar( const tk::Fields& u,
26 : : const edge_t& edge,
27 : : uint64_t c,
28 : : const std::array< std::vector< tk::real >, 3 >& coord,
29 : : const std::vector< std::size_t >& inpoel,
30 : : const std::pair< std::vector< std::size_t >,
31 : : std::vector< std::size_t > >& esup,
32 : : const std::string& err ) const
33 : : // *****************************************************************************
34 : : // Estimate error for scalar quantity
35 : : //! \param[in] u Solution vector
36 : : //! \param[in] edge Edge defined by its two end-point IDs
37 : : //! \param[in] c Scalar component to compute error of
38 : : //! \param[in] coord Mesh node coordinates
39 : : //! \param[in] inpoel Mesh element connectivity
40 : : //! \param[in] esup Linked lists storing elements surrounding points, see
41 : : //! tk::genEsup()
42 : : //! \param[in] err AMR Error indicator type
43 : : //! \return Error indicator: a real number between [0...1] inclusive
44 : : // *****************************************************************************
45 : : {
46 [ + + ]: 163744 : if (err == "jump") {
47 : 392 : return error_jump( u, edge, c );
48 [ + - ]: 163352 : } else if (err == "hessian") {
49 : 163352 : return error_hessian( u, edge, c, coord, inpoel, esup );
50 : : } else {
51 [ - - ][ - - ]: 0 : Throw( "No such AMR error indicator type" );
[ - - ]
52 : : }
53 : : }
54 : :
55 : : tk::real
56 : 392 : Error::error_jump( const tk::Fields& u,
57 : : const edge_t& edge,
58 : : uint64_t c ) const
59 : : // *****************************************************************************
60 : : // Estimate error for scalar quantity on edge based on jump in solution
61 : : //! \param[in] u Solution vector
62 : : //! \param[in] edge Edge defined by its two end-point IDs
63 : : //! \param[in] c Scalar component to compute error of
64 : : //! \return Error indicator: a real number between [0...1] inclusive
65 : : // *****************************************************************************
66 : : {
67 : 392 : auto a = edge.first();
68 : 392 : auto b = edge.second();
69 : :
70 : : // Normalization factor with a noise filter
71 : 392 : auto norm = std::abs(u(a,c)) + std::abs(u(b,c)) + 1e-3;
72 : :
73 : : // Normalized error
74 : 392 : return std::abs( u(a,c) - u(b,c) ) / norm;
75 : : }
76 : :
77 : : tk::real
78 : 163352 : Error::error_hessian( const tk::Fields& u,
79 : : const edge_t& edge,
80 : : uint64_t c,
81 : : const std::array< std::vector< tk::real >, 3 >& coord,
82 : : const std::vector< std::size_t >& inpoel,
83 : : const std::pair< std::vector< std::size_t >,
84 : : std::vector< std::size_t > >& esup )
85 : : const
86 : : // *****************************************************************************
87 : : // Estimate error for scalar quantity on edge based on Hessian of solution
88 : : //! \param[in] u Solution vector
89 : : //! \param[in] edge Edge defined by its two end-point IDs
90 : : //! \param[in] c Scalar component to compute error of
91 : : //! \param[in] coord Mesh node coordinates
92 : : //! \param[in] inpoel Mesh element connectivity
93 : : //! \param[in] esup Linked lists storing elements surrounding points, see
94 : : //! tk::genEsup()
95 : : //! \return Error indicator: a real number between [0...1] inclusive
96 : : // *****************************************************************************
97 : : {
98 : 163352 : const tk::real small = std::numeric_limits< tk::real >::epsilon();
99 : :
100 : 163352 : const auto& x = coord[0];
101 : 163352 : const auto& y = coord[1];
102 : 163352 : const auto& z = coord[2];
103 : 163352 : auto a = edge.first();
104 : 163352 : auto b = edge.second();
105 : :
106 : : // Compute edge vector
107 : 163352 : std::array< tk::real, 3 > h {{ x[a]-x[b], y[a]-y[b], z[a]-z[b] }};
108 : :
109 : : // Compute gradients at edge-end points
110 [ + - ]: 163352 : auto ga = nodegrad( a, coord, inpoel, esup, u, c );
111 [ + - ]: 163352 : auto gb = nodegrad( b, coord, inpoel, esup, u, c );
112 : :
113 : : // Compute dot products of gradients and edge vectors
114 : 163352 : auto dua = tk::dot( ga, h );
115 : 163352 : auto dub = tk::dot( gb, h );
116 : :
117 : : // If the normalization factor is zero, return zero error
118 : 163352 : auto norm = std::abs(dua) + std::abs(dub);
119 [ + + ]: 163352 : if (norm < small) return 0.0;
120 : :
121 : 85991 : return std::abs(dub-dua) / norm;
122 : : }
|