Line data Source code
1 : //* This file is part of the MOOSE framework 2 : //* https://mooseframework.inl.gov 3 : //* 4 : //* All rights reserved, see COPYRIGHT for full restrictions 5 : //* https://github.com/idaholab/moose/blob/master/COPYRIGHT 6 : //* 7 : //* Licensed under LGPL 2.1, please see LICENSE for details 8 : //* https://www.gnu.org/licenses/lgpl-2.1.html 9 : 10 : #include "MooseError.h" 11 : #include "MooseUtils.h" 12 : #include "MooseVariable.h" 13 : #include "Registry.h" 14 : 15 : #include "libmesh/string_to_enum.h" 16 : 17 : using namespace libMesh; 18 : 19 : namespace moose 20 : { 21 : 22 : namespace internal 23 : { 24 : 25 : std::string 26 4 : incompatVarMsg(MooseVariableFEBase & var1, MooseVariableFEBase & var2) 27 : { 28 4 : std::stringstream ss; 29 4 : ss << libMesh::Utility::enum_to_string<FEFamily>(var1.feType().family) << ",ORDER" 30 4 : << var1.feType().order 31 8 : << " != " << libMesh::Utility::enum_to_string<FEFamily>(var2.feType().family) << ",ORDER" 32 4 : << var2.feType().order; 33 8 : return ss.str(); 34 4 : } 35 : 36 : std::string 37 48566 : mooseMsgFmt(const std::string & msg, const std::string & title, const std::string & color) 38 : { 39 48566 : std::ostringstream oss; 40 48566 : oss << "\n" << color << "\n" << title << "\n" << msg << COLOR_DEFAULT << "\n"; 41 97132 : return oss.str(); 42 48566 : } 43 : 44 : std::string 45 0 : mooseMsgFmt(const std::string & msg, const std::string & color) 46 : { 47 0 : std::ostringstream oss; 48 0 : oss << "\n" << color << "\n" << msg << COLOR_DEFAULT << "\n"; 49 0 : return oss.str(); 50 0 : } 51 : 52 : [[noreturn]] void 53 4863 : mooseErrorRaw(std::string msg, 54 : const std::string & prefix /* = "" */, 55 : const hit::Node * node /* = nullptr */) 56 : { 57 4863 : if (Moose::_throw_on_error) 58 500 : throw MooseRuntimeError(msg, node); 59 : 60 : // Atomic that will be set as soon as any thread hits this method 61 : static std::atomic_flag aborting = ATOMIC_FLAG_INIT; 62 : 63 : // This branch will be hit after another thread has already set the atomic. 64 : // MPI_Abort, despite its name, does not behave like std::abort but instead 65 : // calls exit handlers and destroys statics. So we don't want to touch 66 : // anything static at this point. We'll just wait until the winning thread 67 : // has incurred program exit 68 4363 : if (aborting.test_and_set(std::memory_order_acq_rel)) 69 : { 70 : // Waiting for the other thread(s), not burning CPU 71 : for (;;) 72 14 : pause(); 73 : } 74 : // We're the first thread to hit this method (we set the atomic), so we're 75 : // responsible for dumping the error and trace(s) while the remaining 76 : // threads wait for us to exit (via MOOSE_ABORT) 77 : else 78 : { 79 : // Output the message if there is one, but flush it without the trace 80 : // as trace retrieval can be slow in some circumstances and we want to 81 : // get the error message out ASAP 82 4349 : if (!msg.empty()) 83 : { 84 : // If we have a node available, add in the hit context (file location) 85 4349 : if (node) 86 2929 : msg = Moose::hitMessagePrefix(*node) + msg; 87 : 88 13047 : msg = mooseMsgFmt(msg, "*** ERROR ***", COLOR_RED) + "\n"; 89 4349 : if (!prefix.empty()) // multiapp prefix 90 40 : MooseUtils::indentMessage(prefix, msg); 91 : 92 : { 93 4349 : Threads::spin_mutex::scoped_lock lock(moose_stream_lock); 94 4349 : Moose::err << msg << std::flush; 95 4349 : } 96 : } 97 : 98 : // Print the trace if enabled and on a single rank 99 4349 : if (Moose::show_trace && libMesh::global_n_processors() == 1) 100 : { 101 2760 : std::ostringstream oss; 102 2760 : print_trace(oss); 103 2760 : auto trace = oss.str(); 104 2760 : if (!prefix.empty()) // multiapp prefix 105 32 : MooseUtils::indentMessage(prefix, trace); 106 : 107 : { 108 2760 : Threads::spin_mutex::scoped_lock lock(moose_stream_lock); 109 2760 : Moose::err << trace << std::flush; 110 2760 : } 111 2760 : } 112 : 113 : // In parallel with libMesh configured with --enable-tracefiles, this will 114 : // dump a trace for each rank to file 115 4349 : if (libMesh::global_n_processors() > 1) 116 0 : libMesh::write_traceout(); 117 : 118 4349 : MOOSE_ABORT; 119 : } 120 : } 121 : 122 : void 123 47582 : mooseStreamAll(std::ostringstream &) 124 : { 125 47582 : } 126 : 127 : std::string 128 8 : formatMooseDocumentedError(const std::string & repo_name, 129 : const unsigned int issue_num, 130 : const std::string & msg) 131 : { 132 8 : const auto & repo_url = Registry::getRepositoryURL(repo_name); 133 8 : std::stringstream oss; 134 8 : oss << msg << "\n\nThis error is documented at " << repo_url << "/issues/" << issue_num << "."; 135 16 : return oss.str(); 136 8 : } 137 : 138 : } // namespace internal 139 : 140 : void 141 0 : translateMetaPhysicLError(const MetaPhysicL::LogicError &) 142 : { 143 0 : mooseError( 144 : "We caught a MetaPhysicL error in while performing element or face loops. This is " 145 : "potentially due to AD not having a sufficiently large derivative container size. To " 146 : "increase the AD container size, you can run configure in the MOOSE root directory with the " 147 : "'--with-derivative-size=<n>' option and then recompile. Other causes of MetaPhysicL logic " 148 : "errors include evaluating functions where they are not defined or differentiable like sqrt " 149 : "(which gets called for vector norm functions) or log with arguments <= 0"); 150 : } 151 : 152 : } // namespace moose