Chaste  Release::2017.1
PetscException.cpp
1 /*
2 
3 Copyright (c) 2005-2017, University of Oxford.
4 All rights reserved.
5 
6 University of Oxford means the Chancellor, Masters and Scholars of the
7 University of Oxford, having an administrative office at Wellington
8 Square, Oxford OX1 2JD, UK.
9 
10 This file is part of Chaste.
11 
12 Redistribution and use in source and binary forms, with or without
13 modification, 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 
23 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
24 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
27 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
29 GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
32 OF 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  */
49 void 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  */
85 std::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  */
142 void 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 
163 void 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)
Definition: Exception.hpp:143