Chaste Commit::1fd4e48e3990e67db148bc1bc4cf6991a0049d0c
PetscException.cpp
1/*
2
3Copyright (c) 2005-2024, University of Oxford.
4All rights reserved.
5
6University of Oxford means the Chancellor, Masters and Scholars of the
7University of Oxford, having an administrative office at Wellington
8Square, Oxford OX1 2JD, UK.
9
10This file is part of Chaste.
11
12Redistribution and use in source and binary forms, with or without
13modification, are permitted provided that the following conditions are met:
14 * Redistributions of source code must retain the above copyright notice,
15 this list of conditions and the following disclaimer.
16 * Redistributions in binary form must reproduce the above copyright notice,
17 this list of conditions and the following disclaimer in the documentation
18 and/or other materials provided with the distribution.
19 * Neither the name of the University of Oxford nor the names of its
20 contributors may be used to endorse or promote products derived from this
21 software without specific prior written permission.
22
23THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
24AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
27LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
29GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
32OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33
34*/
35
36#include <sstream>
37
38#include "PetscException.hpp"
39#include "Exception.hpp"
40#include "Warnings.hpp"
41#include "ChasteBuildRoot.hpp"
42
43
44/*
45 * Positive codes mean that there's an error.
46 * Zero means success.
47 * Negative codes should never happen, but we'll throw anyway.
48 */
49void PetscException(PetscInt petscError,
50 unsigned line,
51 const char* funct,
52 const char* file)
53{
54 if (petscError != 0)
55 {
56 const char* p_text;
57 char default_message[30]="Unknown PETSc error code";
58
59 /*
60 * PetscErrorMessage will swing p_text to point to the error code's message
61 * ...but only if it's a valid code.
62 */
63 PetscErrorMessage(petscError, &p_text, nullptr);
64 if (p_text == nullptr)
65 {
66 p_text=default_message;
67 }
68
69// /todo #2656 - remove ifdef after cmake transition
70#ifdef CHASTE_CMAKE
71 const size_t root_dir_length = std::char_traits<char>::length(ChasteSourceRootDir());
72 EXCEPTION(p_text << " in function '" << funct << "' on line "
73 << line << " of file ./" << file+root_dir_length);
74#else
75 EXCEPTION(p_text << " in function '" << funct << "' on line "
76 << line << " of file " << file);
77#endif
78 }
79}
80
81/*
82 * Positive codes mean that the KSP converged.
83 * Negative codes mean that the KSP diverged, i.e. there's a problem.
84 */
85std::string GetKspErrorMessage(PetscInt kspError)
86{
87 std::string err_string;
88
89#if (PETSC_VERSION_MAJOR == 2 && PETSC_VERSION_MINOR == 2) //PETSc 2.2
90 switch (kspError)
91 {
92 case KSP_DIVERGED_ITS:
93 err_string = "KSP_DIVERGED_ITS";
94 break;
95 case KSP_DIVERGED_DTOL:
96 err_string = "KSP_DIVERGED_DTOL";
97 break;
98 case KSP_DIVERGED_BREAKDOWN:
99 err_string = "KSP_DIVERGED_BREAKDOWN";
100 break;
101 case KSP_DIVERGED_BREAKDOWN_BICG:
102 err_string = "KSP_DIVERGED_BREAKDOWN_BICG";
103 break;
104 case KSP_DIVERGED_NONSYMMETRIC:
105 err_string = "KSP_DIVERGED_NONSYMMETRIC";
106 break;
107 case KSP_DIVERGED_INDEFINITE_PC:
108 err_string = "KSP_DIVERGED_INDEFINITE_PC";
109 break;
110 default:
111 err_string = "Unknown KSP error code";
112 }
113#else
114 // This array contains the strings describing KSP convergence/divergence reasons.
115 // It is exported by libpetscksp.a
116#if (PETSC_VERSION_MAJOR == 3 && PETSC_VERSION_MINOR >= 2) //PETSc 3.2 or later
117 //External declaration of KSPConvergedReasons already happens
118 extern const char * const *KSPConvergedReasons;
119#else
120 extern const char **KSPConvergedReasons;
121#endif
122
123 // The code for the last known error (-10) is hardcoded in PETSc, in future releases it might change.
124 // It is defined in src/ksp/ksp/interface/dlregisksp.c
125 if (kspError >= -10)
126 {
127 err_string = KSPConvergedReasons[kspError];
128 }
129 else
130 {
131 err_string = "Unknown KSP error code";
132 }
133#endif
134
135 return err_string;
136}
137
138/*
139 * Positive codes mean that the KSP converged.
140 * Negative codes mean that the KSP diverged, i.e. there's a problem.
141 */
142void KspException(PetscInt kspError,
143 unsigned line,
144 const char* funct,
145 const char* file)
146{
147 if (kspError < 0)
148 {
149 std::stringstream err_string_stream;
150 // /todo #2656 - remove ifdef after cmake transition
151#ifdef CHASTE_CMAKE
152 const size_t root_dir_length = std::char_traits<char>::length(ChasteSourceRootDir());
153 err_string_stream << GetKspErrorMessage(kspError) << " in function '" << funct << "' on line "
154 << line << " of file ./" << file + root_dir_length;
155#else
156 err_string_stream << GetKspErrorMessage(kspError) << " in function '" << funct << "' on line "
157 << line << " of file " << file;
158#endif
159 EXCEPTION(err_string_stream.str());
160 }
161}
162
163void KspWarnIfFailed(PetscInt kspError)
164{
165 if (kspError < 0)
166 {
167 std::string message = "Linear solve failed: " + GetKspErrorMessage(kspError);
168 WARNING(message);
169 }
170}
const char * ChasteSourceRootDir()
#define EXCEPTION(message)