From 212372f53c60473f1b66032a191f5139e952a9e7 Mon Sep 17 00:00:00 2001 From: "G. P. Mueller" Date: Mon, 25 Apr 2022 21:54:38 +0200 Subject: [PATCH] Core: minor, nonintrusive improvements - remove some unnecessary semicolons - added missing `Exception` copy and move constructors and operators definitions, add `noexcept` specifiers - fixed unnecessary copying in `Geometry` constructor --- core/include/data/Geometry.hpp | 5 +- core/include/engine/Hamiltonian.hpp | 2 +- core/include/engine/Hamiltonian_Gaussian.hpp | 2 +- .../include/engine/Hamiltonian_Heisenberg.hpp | 2 +- core/include/engine/Solver_Depondt.hpp | 8 +- core/include/engine/Solver_Heun.hpp | 8 +- core/include/engine/Solver_Kernels.hpp | 1 + core/include/engine/Solver_RK4.hpp | 8 +- core/include/engine/Solver_SIB.hpp | 8 +- core/include/engine/Solver_VP.hpp | 8 +- core/include/engine/Solver_VP_OSO.hpp | 6 +- core/include/utility/Exception.hpp | 51 +++++++++---- core/src/data/Geometry.cpp | 5 +- core/src/engine/Hamiltonian.cpp | 8 -- core/src/engine/Hamiltonian_Gaussian.cpp | 2 +- core/src/engine/Hamiltonian_Heisenberg.cpp | 2 +- core/src/utility/Exception.cpp | 75 +++++-------------- 17 files changed, 90 insertions(+), 111 deletions(-) diff --git a/core/include/data/Geometry.hpp b/core/include/data/Geometry.hpp index 53b0e80a1..8e33f023d 100644 --- a/core/include/data/Geometry.hpp +++ b/core/include/data/Geometry.hpp @@ -81,8 +81,9 @@ class Geometry // ---------- Constructor // Build a regular lattice from a defined basis cell and translations Geometry( - std::vector bravais_vectors, intfield n_cells, std::vector cell_atoms, - Basis_Cell_Composition cell_composition, scalar lattice_constant, Pinning pinning, Defects defects ); + const std::vector & bravais_vectors, intfield n_cells, const std::vector & cell_atoms, + const Basis_Cell_Composition & cell_composition, scalar lattice_constant, const Pinning & pinning, + const Defects & defects ); // ---------- Convenience functions // Retrieve triangulation, if 2D diff --git a/core/include/engine/Hamiltonian.hpp b/core/include/engine/Hamiltonian.hpp index d1c95005b..0a5519c4e 100644 --- a/core/include/engine/Hamiltonian.hpp +++ b/core/include/engine/Hamiltonian.hpp @@ -86,7 +86,7 @@ class Hamiltonian virtual std::size_t Number_of_Interactions(); // Hamiltonian name as string - virtual const std::string & Name(); + virtual const std::string & Name() const = 0; // Boundary conditions intfield boundary_conditions; // [3] (a, b, c) diff --git a/core/include/engine/Hamiltonian_Gaussian.hpp b/core/include/engine/Hamiltonian_Gaussian.hpp index 4ed4cb96a..e07269b65 100644 --- a/core/include/engine/Hamiltonian_Gaussian.hpp +++ b/core/include/engine/Hamiltonian_Gaussian.hpp @@ -36,7 +36,7 @@ class Hamiltonian_Gaussian : public Hamiltonian scalar Energy_Single_Spin( int ispin, const vectorfield & spins ) override; // Hamiltonian name as string - const std::string & Name() override; + const std::string & Name() const override; // Parameters of the energy landscape int n_gaussians; diff --git a/core/include/engine/Hamiltonian_Heisenberg.hpp b/core/include/engine/Hamiltonian_Heisenberg.hpp index db3cfe275..056ee5aea 100644 --- a/core/include/engine/Hamiltonian_Heisenberg.hpp +++ b/core/include/engine/Hamiltonian_Heisenberg.hpp @@ -64,7 +64,7 @@ class Hamiltonian_Heisenberg : public Hamiltonian scalar Energy_Single_Spin( int ispin, const vectorfield & spins ) override; // Hamiltonian name as string - const std::string & Name() override; + const std::string & Name() const override; // ------------ Single Spin Interactions ------------ // External magnetic field across the sample diff --git a/core/include/engine/Solver_Depondt.hpp b/core/include/engine/Solver_Depondt.hpp index 4abdcd3f0..25ed98c3e 100644 --- a/core/include/engine/Solver_Depondt.hpp +++ b/core/include/engine/Solver_Depondt.hpp @@ -16,7 +16,7 @@ inline void Method_Solver::Initialize() configurations_predictor[i] = std::shared_ptr( new vectorfield( this->nos, { 0, 0, 0 } ) ); this->temp1 = vectorfield( this->nos, { 0, 0, 0 } ); -}; +} /* Template instantiation of the Simulation class for use with the Depondt Solver. @@ -74,16 +74,16 @@ inline void Method_Solver::Iteration() // Get new spin conf n_new = R( (H+H')/2 ) * n Vectormath::rotate( conf, temp1, angle, conf ); } -}; +} template<> inline std::string Method_Solver::SolverName() { return "Depondt"; -}; +} template<> inline std::string Method_Solver::SolverFullName() { return "Depondt"; -}; \ No newline at end of file +} \ No newline at end of file diff --git a/core/include/engine/Solver_Heun.hpp b/core/include/engine/Solver_Heun.hpp index 3f33d89b1..01aa0b654 100644 --- a/core/include/engine/Solver_Heun.hpp +++ b/core/include/engine/Solver_Heun.hpp @@ -16,7 +16,7 @@ inline void Method_Solver::Initialize() configurations_predictor[i] = std::shared_ptr( new vectorfield( this->nos ) ); this->temp1 = vectorfield( this->nos, { 0, 0, 0 } ); -}; +} /* Template instantiation of the Simulation class for use with the Heun Solver. @@ -77,16 +77,16 @@ inline void Method_Solver::Iteration() // Copy out conf = conf_temp; } -}; +} template<> inline std::string Method_Solver::SolverName() { return "Heun"; -}; +} template<> inline std::string Method_Solver::SolverFullName() { return "Heun"; -}; \ No newline at end of file +} \ No newline at end of file diff --git a/core/include/engine/Solver_Kernels.hpp b/core/include/engine/Solver_Kernels.hpp index de55b6bd2..30603755a 100644 --- a/core/include/engine/Solver_Kernels.hpp +++ b/core/include/engine/Solver_Kernels.hpp @@ -17,6 +17,7 @@ namespace Engine { namespace Solver_Kernels { + // SIB void sib_transform( const vectorfield & spins, const vectorfield & force, vectorfield & out ); diff --git a/core/include/engine/Solver_RK4.hpp b/core/include/engine/Solver_RK4.hpp index 6c5cff621..ff1c48ef6 100644 --- a/core/include/engine/Solver_RK4.hpp +++ b/core/include/engine/Solver_RK4.hpp @@ -32,7 +32,7 @@ inline void Method_Solver::Initialize() this->configurations_k4[i] = std::shared_ptr( new vectorfield( this->nos ) ); this->temp1 = vectorfield( this->nos, { 0, 0, 0 } ); -}; +} /* Template instantiation of the Simulation class for use with the 4th order Runge Kutta Solver. @@ -144,16 +144,16 @@ inline void Method_Solver::Iteration() // Copy out conf = conf_temp; } -}; +} template<> inline std::string Method_Solver::SolverName() { return "RK4"; -}; +} template<> inline std::string Method_Solver::SolverFullName() { return "Runge Kutta (4th order)"; -}; \ No newline at end of file +} \ No newline at end of file diff --git a/core/include/engine/Solver_SIB.hpp b/core/include/engine/Solver_SIB.hpp index 7afe1d32d..f95a894aa 100644 --- a/core/include/engine/Solver_SIB.hpp +++ b/core/include/engine/Solver_SIB.hpp @@ -10,7 +10,7 @@ inline void Method_Solver::Initialize() this->configurations_predictor = std::vector>( this->noi ); for( int i = 0; i < this->noi; i++ ) configurations_predictor[i] = std::shared_ptr( new vectorfield( this->nos ) ); -}; +} /* Template instantiation of the Simulation class for use with the SIB Solver. @@ -47,16 +47,16 @@ inline void Method_Solver::Iteration() Solver_Kernels::sib_transform( image, forces_virtual_predictor[i], image ); } -}; +} template<> inline std::string Method_Solver::SolverName() { return "SIB"; -}; +} template<> inline std::string Method_Solver::SolverFullName() { return "Semi-implicit B"; -}; \ No newline at end of file +} \ No newline at end of file diff --git a/core/include/engine/Solver_VP.hpp b/core/include/engine/Solver_VP.hpp index 072d5861b..e7461487e 100644 --- a/core/include/engine/Solver_VP.hpp +++ b/core/include/engine/Solver_VP.hpp @@ -15,7 +15,7 @@ inline void Method_Solver::Initialize() this->forces_previous = velocities; // [noi][nos] this->projection = std::vector( this->noi, 0 ); // [noi] this->force_norm2 = std::vector( this->noi, 0 ); // [noi] -}; +} /* Template instantiation of the Simulation class for use with the VP Solver. @@ -111,16 +111,16 @@ inline void Method_Solver::Iteration() conf[idx] = conf_temp[idx].normalized(); } ); } -}; +} template<> inline std::string Method_Solver::SolverName() { return "VP"; -}; +} template<> inline std::string Method_Solver::SolverFullName() { return "Velocity Projection"; -}; \ No newline at end of file +} \ No newline at end of file diff --git a/core/include/engine/Solver_VP_OSO.hpp b/core/include/engine/Solver_VP_OSO.hpp index 3b4b2333e..f6132fac5 100644 --- a/core/include/engine/Solver_VP_OSO.hpp +++ b/core/include/engine/Solver_VP_OSO.hpp @@ -16,7 +16,7 @@ inline void Method_Solver::Initialize() this->projection = std::vector( this->noi, 0 ); // [noi] this->force_norm2 = std::vector( this->noi, 0 ); // [noi] this->searchdir = std::vector( this->noi, vectorfield( this->nos, { 0, 0, 0 } ) ); -}; +} /* Template instantiation of the Simulation class for use with the VP Solver. @@ -117,10 +117,10 @@ template<> inline std::string Method_Solver::SolverName() { return "VP_OSO"; -}; +} template<> inline std::string Method_Solver::SolverFullName() { return "Velocity Projection using exponential transforms"; -}; \ No newline at end of file +} \ No newline at end of file diff --git a/core/include/utility/Exception.hpp b/core/include/utility/Exception.hpp index d1f70f713..344a2502b 100644 --- a/core/include/utility/Exception.hpp +++ b/core/include/utility/Exception.hpp @@ -6,6 +6,9 @@ #include +#include +#include + namespace Utility { @@ -29,18 +32,17 @@ enum class Exception_Classifier }; /* - * Spirit library exception class: - * Derived from std::runtime_error. - * Adds file, line and function information to the exception message. - * Contains an exception classifier and a level so that the handler - * can decide if execution should be stopped or can continue. + * Spirit library exception class, derived from std::runtime_error. + * + * Adds file, line and function information to the exception message. Contains an exception classifier and a level so + * that the handler can decide if execution should be stopped or can continue. */ class Exception : public std::runtime_error { public: Exception( Exception_Classifier classifier, Log_Level level, const std::string & message, const char * file, - unsigned int line, const char * function ) + unsigned int line, const char * function ) noexcept( false ) : std::runtime_error( fmt::format( "{}:{} in function \'{}\':\n{:>49}{}", file, line, function, " ", message ) ), classifier( classifier ), @@ -51,7 +53,17 @@ class Exception : public std::runtime_error { } - ~Exception() throw() override = default; + // Copy-constructor + Exception( const Exception & ) noexcept = default; + // Copy-assignment operator + Exception & operator=( const Exception & ) = delete; + + // Move-constructor + Exception( Exception && ) noexcept = default; + // Move-assignment constructor + Exception & operator=( Exception && ) = delete; + + ~Exception() noexcept override = default; const Exception_Classifier classifier; const Log_Level level; @@ -60,25 +72,38 @@ class Exception : public std::runtime_error const char * function; }; +// To make sure that the noexcept-specifications are correct +static_assert( + std::is_nothrow_copy_constructible::value, + "Utility::Exception is expected to be nothrow copy-constructible" ); +static_assert( + std::is_nothrow_move_constructible::value, + "Utility::Exception is expected to be nothrow move-constructible" ); +static_assert( + std::is_nothrow_destructible::value, "Utility::Exception is expected to be nothrow destructible" ); + /* * Rethrow (creating a std::nested_exception) an exception using the Exception class * to add file and line info */ -void rethrow( const std::string & message, const char * file, unsigned int line, const char * function ); +void rethrow( const std::string & message, const char * file, const unsigned int line, const char * function ) noexcept( + false ); /* * Handle_Exception_API finalizes what should be done when an exception is encountered at the API layer. - * This function should only be used inside API functions, since that is the top level at which an - * exception is caught. + * This function catches any exceptions and should only be used in the catch-statements of API functions, since that is + * the top level at which an exception is caught. */ void Handle_Exception_API( - const char * file, unsigned int line, const char * function = "", int idx_image = -1, int idx_chain = -1 ); + const char * file, const unsigned int line, const char * function = "", const int idx_image = -1, + const int idx_chain = -1 ) noexcept; /* - * Handle_Exception_Core finalizes what should be done when an exception is encountered inside the core. + * Handle_Exception_Core finalizes what should be done when an exception is encountered inside the core library. * This function should only be used inside the core, below the API layer. */ -void Handle_Exception_Core( const std::string & message, const char * file, unsigned int line, const char * function ); +void Handle_Exception_Core( + const std::string & message, const char * file, unsigned int line, const char * function ) noexcept( false ); // Shorthand for throwing a Spirit library exception with file and line info #define spirit_throw( classifier, level, message ) \ diff --git a/core/src/data/Geometry.cpp b/core/src/data/Geometry.cpp index 288e5c9d8..5b9cf2834 100644 --- a/core/src/data/Geometry.cpp +++ b/core/src/data/Geometry.cpp @@ -20,8 +20,9 @@ namespace Data { Geometry::Geometry( - std::vector bravais_vectors, intfield n_cells, std::vector cell_atoms, - Basis_Cell_Composition cell_composition, scalar lattice_constant, Pinning pinning, Defects defects ) + const std::vector & bravais_vectors, intfield n_cells, const std::vector & cell_atoms, + const Basis_Cell_Composition & cell_composition, scalar lattice_constant, const Pinning & pinning, + const Defects & defects ) : bravais_vectors( bravais_vectors ), n_cells( n_cells ), n_cell_atoms( cell_atoms.size() ), diff --git a/core/src/engine/Hamiltonian.cpp b/core/src/engine/Hamiltonian.cpp index a3aa9cb05..a596cd13a 100644 --- a/core/src/engine/Hamiltonian.cpp +++ b/core/src/engine/Hamiltonian.cpp @@ -177,12 +177,4 @@ scalar Hamiltonian::Energy_Single_Spin( int ispin, const vectorfield & spins ) "Tried to use Hamiltonian::Energy_Single_Spin() of the Hamiltonian base class!" ); } -static const std::string name = "--"; -const std::string & Hamiltonian::Name() -{ - spirit_throw( - Exception_Classifier::Not_Implemented, Log_Level::Error, - "Tried to use Hamiltonian::Name() of the Hamiltonian base class!" ); -} - } // namespace Engine diff --git a/core/src/engine/Hamiltonian_Gaussian.cpp b/core/src/engine/Hamiltonian_Gaussian.cpp index 39c6f07a2..2239bca8b 100644 --- a/core/src/engine/Hamiltonian_Gaussian.cpp +++ b/core/src/engine/Hamiltonian_Gaussian.cpp @@ -123,7 +123,7 @@ scalar Hamiltonian_Gaussian::Energy_Single_Spin( int ispin, const vectorfield & // Hamiltonian name as string static const std::string name = "Gaussian"; -const std::string & Hamiltonian_Gaussian::Name() +const std::string & Hamiltonian_Gaussian::Name() const { return name; } diff --git a/core/src/engine/Hamiltonian_Heisenberg.cpp b/core/src/engine/Hamiltonian_Heisenberg.cpp index d84a9f0ce..2419163bc 100644 --- a/core/src/engine/Hamiltonian_Heisenberg.cpp +++ b/core/src/engine/Hamiltonian_Heisenberg.cpp @@ -1517,7 +1517,7 @@ void Hamiltonian_Heisenberg::Clean_DDI() // Hamiltonian name as string static const std::string name = "Heisenberg"; -const std::string & Hamiltonian_Heisenberg::Name() +const std::string & Hamiltonian_Heisenberg::Name() const { return name; } diff --git a/core/src/utility/Exception.cpp b/core/src/utility/Exception.cpp index f29918ac7..576c0c2da 100644 --- a/core/src/utility/Exception.cpp +++ b/core/src/utility/Exception.cpp @@ -6,7 +6,8 @@ namespace Utility { -void rethrow( const std::string & message, const char * file, const unsigned int line, const char * function ) +void rethrow( const std::string & message, const char * file, const unsigned int line, const char * function ) noexcept( + false ) try { std::rethrow_exception( std::current_exception() ); @@ -27,7 +28,7 @@ catch( ... ) std::throw_with_nested( ex ); } -void Backtrace_Exception() +void Backtrace_Exception() noexcept( false ) try { if( std::exception_ptr eptr = std::current_exception() ) @@ -38,7 +39,7 @@ try { Log( Log_Level::Severe, Log_Sender::API, "Unknown Exception. Terminating" ); Log.Append_to_File(); - std::exit( EXIT_FAILURE ); // Exit the application. May lead to data loss + std::exit( EXIT_FAILURE ); // Exit the application. May lead to data loss! } } catch( const Exception & ex ) @@ -67,7 +68,8 @@ catch( const std::exception & ex ) } void Handle_Exception_API( - const char * file, const unsigned int line, const char * api_function, const int idx_image, const int idx_chain ) + const char * file, const unsigned int line, const char * function, const int idx_image, + const int idx_chain ) noexcept try { // Rethrow in order to get an exception reference (instead of pointer) @@ -85,8 +87,8 @@ try str_exception = "SEVERE exception"; Log( ex.level, Log_Sender::API, fmt::format( - "Caught {} in API function \'{}\' (at {}:{})\n{}Exception backtrace:", str_exception, api_function, - file, line, Log.tags_space ), + "Caught {} in API function \'{}\' (at {}:{})\n{}Exception backtrace:", str_exception, function, file, + line, Log.tags_space ), idx_image, idx_chain ); // Create backtrace @@ -101,7 +103,7 @@ try { Log( Log_Level::Severe, Log_Sender::API, "TERMINATING!", idx_image, idx_chain ); Log.Append_to_File(); - std::exit( EXIT_FAILURE ); // exit the application. May lead to data loss + std::exit( EXIT_FAILURE ); // Exit the application. May lead to data loss! } // If it was recoverable we now write to Log @@ -113,8 +115,8 @@ try idx_chain ); Log( Log_Level::Severe, Log_Sender::API, fmt::format( - "Caught std::exception in API function \'{}\' (at {}:{})\n{:>49}Exception backtrace:", api_function, - file, line, " " ), + "Caught std::exception in API function \'{}\' (at {}:{})\n{:>49}Exception backtrace:", function, file, + line, " " ), idx_image, idx_chain ); // Create backtrace Backtrace_Exception(); @@ -124,7 +126,7 @@ try // Terminate Log( Log_Level::Severe, Log_Sender::API, "TERMINATING!", idx_image, idx_chain ); Log.Append_to_File(); - std::exit( EXIT_FAILURE ); // Exit the application. May lead to data loss + std::exit( EXIT_FAILURE ); // Exit the application. May lead to data loss! } catch( ... ) { @@ -134,25 +136,25 @@ try fmt::format( "Caught unknown exception in API function \'{}\' (at {}:{})\n{:>49}Cannot backtrace unknown " "exceptions...", - api_function, file, line, " " ), + function, file, line, " " ), idx_image, idx_chain ); Log( Log_Level::Severe, Log_Sender::API, "-----------------------------------------------------", idx_image, idx_chain ); Log( Log_Level::Severe, Log_Sender::API, "Unable to handle! TERMINATING!", idx_image, idx_chain ); Log.Append_to_File(); - std::exit( EXIT_FAILURE ); // Exit the application. May lead to data loss + std::exit( EXIT_FAILURE ); // Exit the application. May lead to data loss! } } catch( ... ) { - std::cerr << "Another exception occurred while handling an exception from \'" << api_function << "\' (at " << file + std::cerr << "Another exception occurred while handling an exception from \'" << function << "\' (at " << file << ":" << line << ")!" << std::endl; std::cerr << "TERMINATING!" << std::endl; - std::exit( EXIT_FAILURE ); // Exit the application. May lead to data loss + std::exit( EXIT_FAILURE ); // Exit the application. May lead to data loss! } void Handle_Exception_Core( - const std::string & message, const char * file, const unsigned int line, const char * function ) + const std::string & message, const char * file, const unsigned int line, const char * function ) noexcept( false ) try { // Rethrow in order to get an exception reference (instead of pointer) @@ -196,47 +198,4 @@ catch( ... ) spirit_rethrow( message ); } -// void Spirit_Exception( const Exception & ex, int idx_image, int idx_chain ) -// { -// switch ( ex ) -// { -// case Exception::File_not_Found : -// Log( Log_Level::Warning, Log_Sender::API, "File not found. Unable to open.", -// idx_image, idx_chain ); -// break; - -// case Exception::System_not_Initialized : -// Log( Log_Level::Severe, Log_Sender::API, "System is uninitialized. Terminating.", idx_image, idx_chain ); -// Log.Append_to_File(); -// std::exit( EXIT_FAILURE ); // exit the application. may lead to data loss -// break; - -// case Exception::Division_by_zero: -// Log( Log_Level::Severe, Log_Sender::API, "Division by zero", idx_image, idx_chain ); -// Log.Append_to_File(); -// std::exit( EXIT_FAILURE ); // exit the application. may lead to data loss -// break; - -// case Exception::Simulated_domain_too_small: -// Log( Log_Level::Error, Log_Sender::API, std::string( "Simulated domain is " ) + -// std::string( "too small. No action taken." ), idx_image, idx_chain ); -// break; - -// case Exception::Not_Implemented: -// Log( Log_Level::Warning, Log_Sender::API, std::string( "Feature not " ) + -// std::string( " implemented. No action taken." ), idx_image, idx_chain ); -// break; - -// case Exception::Non_existing_Image: -// Log( Log_Level::Warning, Log_Sender::API, "Non existing image. No action taken.", -// idx_image, idx_chain ); -// break; - -// case Exception::Non_existing_Chain: -// Log( Log_Level::Warning, Log_Sender::API, "Non existing chain. No action taken.", -// idx_image, idx_chain ); -// break; -// } -// } - } // namespace Utility \ No newline at end of file