From f2d6ca7eaa0853ef5ac8f6ecb553aca5686923cd Mon Sep 17 00:00:00 2001 From: Tiago Quintino Date: Mon, 10 Jun 2019 07:44:07 +0100 Subject: [PATCH 01/86] Rely on CMake to find C++11 flags --- CMakeLists.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a5350bbf0..77254af1d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -36,7 +36,8 @@ ecbuild_debug( " ECKIT_FEATURES : [${ECKIT_FEATURES}]" ) # options & dependencies -ecbuild_add_cxx11_flags() +set(CMAKE_CXX_STANDARD 11) +set(CMAKE_CXX_STANDARD_REQUIRED ON) ecbuild_find_python() From 3ed2b141c3d4f9166a1726a68e9681f4264db1b3 Mon Sep 17 00:00:00 2001 From: Pedro Maciel Date: Fri, 7 Jun 2019 13:27:52 +0100 Subject: [PATCH 02/86] MIR-4 wrap_latitude and wrap_angle (projection assumption) --- src/atlas/util/Rotation.cc | 69 +++++++++++++++++++++------ src/tests/projection/test_rotation.cc | 27 +++++------ 2 files changed, 67 insertions(+), 29 deletions(-) diff --git a/src/atlas/util/Rotation.cc b/src/atlas/util/Rotation.cc index b30ef0972..700c3a847 100644 --- a/src/atlas/util/Rotation.cc +++ b/src/atlas/util/Rotation.cc @@ -13,14 +13,43 @@ #include #include +#include "eckit/config/Parametrisation.h" +#include "eckit/types/FloatCompare.h" + #include "atlas/util/Constants.h" #include "atlas/util/CoordinateEnums.h" #include "atlas/util/UnitSphere.h" -#include "eckit/config/Parametrisation.h" namespace atlas { namespace util { +namespace { + +PointLonLat wrap_latitude( const PointLonLat& p ) { + double lon = p.lon(); + double lat = p.lat(); + + while ( lat > 90. ) { + lon += 180.; + lat = 180. - lat; + } + + while ( lat < -90. ) { + lon -= 180.; + lat = -180. - lat; + } + + return {lon, lat}; +} + +double wrap_angle( double a ) { + PointLonLat angle{a, 0}; + angle.normalise(); + return angle.lon(); +} + +} // (anonymous namespace) + void Rotation::print( std::ostream& out ) const { out << "north_pole:" << npole_ << ", south_pole:" << spole_ << ", rotation_angle:" << angle_; } @@ -50,6 +79,21 @@ void Rotation::precompute() { const double sin_phi = std::sin( phi ); const double cos_phi = std::cos( phi ); + // for rotate_old/unrotate_old + const double latrp = ( 90.0 - npole_.lat() ) * Constants::degreesToRadians(); + sin_latrp_ = std::sin( latrp ); + cos_latrp_ = std::cos( latrp ); + + auto eq = []( double a, double b ) { return eckit::types::is_approximately_equal( a, b ); }; + + rotated_ = !eq( angle_, 0 ) || !eq( sin_theta, 0 ) || !eq( cos_theta, 1 ) || !eq( sin_phi, 0 ) || !eq( cos_phi, 1 ); + rotation_angle_only_ = eq( sin_theta, 0 ) && eq( cos_theta, 1 ) && rotated_; + + if ( !rotated_ ) { + rotate_ = unrotate_ = {1., 0., 0., 0., 1., 0., 0., 0., 1.}; + return; + } + // Pt = Rot(z) * Rot(y) * P, rotate about y axes then z // Since we're undoing the rotation described in the definition // of the coordinate system, @@ -82,20 +126,13 @@ void Rotation::precompute() { unrotate_ = {cos_theta * cos_phi, -cos_theta * sin_phi, -sin_theta, sin_phi, cos_phi, 0., sin_theta * cos_phi, -sin_theta * sin_phi, cos_theta}; - - if ( spole_.lon() == 0. && spole_.lat() == -90. && angle_ == 0. ) rotated_ = false; - rotation_angle_only_ = spole_.lon() == 0. && spole_.lat() == -90. && rotated_; - - double latrp = ( 90.0 - npole_.lat() ) * Constants::degreesToRadians(); - cos_latrp_ = std::cos( latrp ); - sin_latrp_ = std::sin( latrp ); } Rotation::Rotation( const PointLonLat& south_pole, double rotation_angle ) { spole_ = south_pole; npole_ = PointLonLat( spole_.lon() - 180., spole_.lat() + 180. ); if ( npole_.lat() > 90 ) npole_.lon() += 180.; - angle_ = rotation_angle; + angle_ = wrap_angle( rotation_angle ); precompute(); } @@ -103,6 +140,7 @@ Rotation::Rotation( const PointLonLat& south_pole, double rotation_angle ) { Rotation::Rotation( const eckit::Parametrisation& p ) { // get rotation angle p.get( "rotation_angle", angle_ ); + angle_ = wrap_angle( angle_ ); // get pole std::vector pole( 2 ); @@ -148,8 +186,8 @@ void Rotation::rotate_old( double crd[] ) const { latt = std::asin( zt ) * Constants::radiansToDegrees(); // rotate - crd[0] = lont + npole_.lon(); - crd[1] = latt; + crd[LON] = lont + npole_.lon(); + crd[LAT] = latt; } void Rotation::unrotate_old( double crd[] ) const { @@ -179,8 +217,8 @@ void Rotation::unrotate_old( double crd[] ) const { z = sin_latrp_ * xt + cos_latrp_ * zt; // back to spherical coordinates - crd[0] = std::atan2( y, x ) * Constants::radiansToDegrees(); - crd[1] = std::asin( z ) * Constants::radiansToDegrees(); + crd[LON] = std::atan2( y, x ) * Constants::radiansToDegrees(); + crd[LAT] = std::asin( z ) * Constants::radiansToDegrees(); } using RotationMatrix = std::array, 3>; @@ -193,12 +231,13 @@ inline PointXYZ rotate_geocentric( const PointXYZ& p, const RotationMatrix& R ) void Rotation::rotate( double crd[] ) const { if ( !rotated_ ) { return; } - else if ( rotation_angle_only_ ) { + + if ( rotation_angle_only_ ) { crd[LON] -= angle_; return; } - const PointLonLat L( crd ); + const PointLonLat L( wrap_latitude({crd[LON], crd[LAT]}) ); PointXYZ P; UnitSphere::convertSphericalToCartesian( L, P ); diff --git a/src/tests/projection/test_rotation.cc b/src/tests/projection/test_rotation.cc index 071d6c797..360455e07 100644 --- a/src/tests/projection/test_rotation.cc +++ b/src/tests/projection/test_rotation.cc @@ -9,6 +9,7 @@ */ #include +#include #include "eckit/types/FloatCompare.h" @@ -28,21 +29,19 @@ namespace test { //----------------------------------------------------------------------------- -constexpr double eps() { - return 1.e-5; +constexpr double eps = 1.e-5; +constexpr double d2r = atlas::util::Constants::degreesToRadians(); +constexpr double r2d = atlas::util::Constants::radiansToDegrees(); + +bool equivalent( const PointLonLat& p1, const PointLonLat& p2 ) { + using eckit::types::is_approximately_equal; + auto f = [=]( double lon ) { return 10. + std::cos( lon * d2r ); }; + + return is_approximately_equal( p1.lat(), p2.lat(), eps ) && + ( std::abs( p2.lat() ) == 90. || is_approximately_equal( f( p1.lon() ), f( p2.lon() ), eps ) ); } -const double d2r = atlas::util::Constants::degreesToRadians(); -const double r2d = atlas::util::Constants::radiansToDegrees(); - -#define EXPECT_EQUIVALENT( p1, p2 ) \ - if ( std::abs( p2.lat() ) == 90. ) \ - EXPECT( eckit::types::is_approximately_equal( p1.lat(), p2.lat(), eps() ) ); \ - else { \ - EXPECT( eckit::types::is_approximately_equal( 10. + std::cos( p1.lon() * d2r ), \ - 10. + std::cos( p2.lon() * d2r ), eps() ) ); \ - EXPECT( eckit::types::is_approximately_equal( 10. + std::sin( p1.lat() * d2r ), \ - 10. + std::sin( p2.lat() * d2r ), eps() ) ); \ - } + +#define EXPECT_EQUIVALENT( p1, p2 ) EXPECT( equivalent( p1, p2 ) ) //----------------------------------------------------------------------------- From a3c9fc74fa1531065b75bb56de2067a2d36010c5 Mon Sep 17 00:00:00 2001 From: Pedro Maciel Date: Fri, 7 Jun 2019 16:52:11 +0100 Subject: [PATCH 03/86] MIR-4 wrap_latitude and wrap_angle (projection assumption) --- src/atlas/util/Rotation.cc | 77 ++------------------------- src/atlas/util/Rotation.h | 9 +--- src/tests/projection/test_rotation.cc | 17 ++++++ 3 files changed, 23 insertions(+), 80 deletions(-) diff --git a/src/atlas/util/Rotation.cc b/src/atlas/util/Rotation.cc index 700c3a847..c57777282 100644 --- a/src/atlas/util/Rotation.cc +++ b/src/atlas/util/Rotation.cc @@ -71,7 +71,7 @@ PointLonLat Rotation::unrotate( const PointLonLat& p ) const { } void Rotation::precompute() { - const double theta = -( 90.0 + spole_.lat() ) * Constants::degreesToRadians(); + const double theta = -( 90. + spole_.lat() ) * Constants::degreesToRadians(); const double phi = -spole_.lon() * Constants::degreesToRadians(); const double sin_theta = std::sin( theta ); @@ -79,12 +79,7 @@ void Rotation::precompute() { const double sin_phi = std::sin( phi ); const double cos_phi = std::cos( phi ); - // for rotate_old/unrotate_old - const double latrp = ( 90.0 - npole_.lat() ) * Constants::degreesToRadians(); - sin_latrp_ = std::sin( latrp ); - cos_latrp_ = std::cos( latrp ); - - auto eq = []( double a, double b ) { return eckit::types::is_approximately_equal( a, b ); }; + auto eq = []( double a, double b ) { return eckit::types::is_approximately_equal( a, b, 1.e-12 ); }; rotated_ = !eq( angle_, 0 ) || !eq( sin_theta, 0 ) || !eq( cos_theta, 1 ) || !eq( sin_phi, 0 ) || !eq( cos_phi, 1 ); rotation_angle_only_ = eq( sin_theta, 0 ) && eq( cos_theta, 1 ) && rotated_; @@ -158,69 +153,6 @@ Rotation::Rotation( const eckit::Parametrisation& p ) { precompute(); } -void Rotation::rotate_old( double crd[] ) const { - // coordinates of the point P on a rotated sphere with specified pole - double lon, lat, lont, latt; - double xt, yt, zt, x, y, z; - double cos_lon, sin_lon, cos_lat, sin_lat; - - lon = crd[LON] * Constants::degreesToRadians(); - lat = crd[LAT] * Constants::degreesToRadians(); - cos_lon = std::cos( lon ); - cos_lat = std::cos( lat ); - sin_lon = std::sin( lon ); - sin_lat = std::sin( lat ); - - // cartesian coordinates - x = cos_lon * cos_lat; - y = sin_lon * cos_lat; - z = sin_lat; - - // tilt - xt = cos_latrp_ * x + sin_latrp_ * z; - yt = y; - zt = -sin_latrp_ * x + cos_latrp_ * z; - - // back to spherical coordinates - lont = std::atan2( yt, xt ) * Constants::radiansToDegrees(); - latt = std::asin( zt ) * Constants::radiansToDegrees(); - - // rotate - crd[LON] = lont + npole_.lon(); - crd[LAT] = latt; -} - -void Rotation::unrotate_old( double crd[] ) const { - // inverse operation of Projection::rotate - - double lont, latt; - double xt, yt, zt, x, y, z; - double cos_lont, sin_lont, cos_latt, sin_latt; - - // unrotate - lont = ( crd[LON] - npole_.lon() ) * Constants::degreesToRadians(); - latt = ( crd[LAT] ) * Constants::degreesToRadians(); - - cos_lont = std::cos( lont ); - cos_latt = std::cos( latt ); - sin_lont = std::sin( lont ); - sin_latt = std::sin( latt ); - - // cartesian coordinates - xt = cos_lont * cos_latt; - yt = sin_lont * cos_latt; - zt = sin_latt; - - // untilt - x = cos_latrp_ * xt - sin_latrp_ * zt; - y = yt; - z = sin_latrp_ * xt + cos_latrp_ * zt; - - // back to spherical coordinates - crd[LON] = std::atan2( y, x ) * Constants::radiansToDegrees(); - crd[LAT] = std::asin( z ) * Constants::radiansToDegrees(); -} - using RotationMatrix = std::array, 3>; inline PointXYZ rotate_geocentric( const PointXYZ& p, const RotationMatrix& R ) { @@ -237,7 +169,7 @@ void Rotation::rotate( double crd[] ) const { return; } - const PointLonLat L( wrap_latitude({crd[LON], crd[LAT]}) ); + const PointLonLat L( wrap_latitude( {crd[LON], crd[LAT]} ) ); PointXYZ P; UnitSphere::convertSphericalToCartesian( L, P ); @@ -252,7 +184,8 @@ void Rotation::rotate( double crd[] ) const { void Rotation::unrotate( double crd[] ) const { if ( !rotated_ ) { return; } - else if ( rotation_angle_only_ ) { + + if ( rotation_angle_only_ ) { crd[LON] += angle_; return; } diff --git a/src/atlas/util/Rotation.h b/src/atlas/util/Rotation.h index 0a797177f..f2295d15c 100644 --- a/src/atlas/util/Rotation.h +++ b/src/atlas/util/Rotation.h @@ -57,14 +57,7 @@ class Rotation { RotationMatrix unrotate_; // unrotate matrix bool rotation_angle_only_; - bool rotated_ = {true}; - - // ---- Older implementation ---- - - void rotate_old( double crd[] ) const; - void unrotate_old( double crd[] ) const; - double cos_latrp_; // cos( 90 - npole_lat ) - double sin_latrp_; // sin( 90 - npole_lat ) + bool rotated_; }; } // namespace util diff --git a/src/tests/projection/test_rotation.cc b/src/tests/projection/test_rotation.cc index 360455e07..a6edf7574 100644 --- a/src/tests/projection/test_rotation.cc +++ b/src/tests/projection/test_rotation.cc @@ -119,6 +119,23 @@ class MagicsRotation { //----------------------------------------------------------------------------- +CASE( "test_rotation_construction" ) { + static const PointLonLat SP{0., -90.}; + static const PointLonLat NP{180., 90.}; + + auto rotation_poles = {SP, NP, {0., -90.1}, {0., 90.1}}; + + for ( auto& p : rotation_poles ) { + Rotation s( Config( "south_pole", std::vector{p.lon(), p.lat()} ) ); + Log::info() << "rotate_south_pole=" << s << std::endl; + EXPECT( s.rotated() == ( p != SP ) ); + + Rotation n( Config( "north_pole", std::vector{p.lon(), p.lat()} ) ); + Log::info() << "rotate_north_pole=" << n << std::endl; + EXPECT( n.rotated() == ( p != NP ) ); + } +} + CASE( "test_rotation" ) { Config config; config.set( "north_pole", std::vector{-176, 40} ); From 2c225b6a5482f586b9e0ea54e9dd354611cb8aa0 Mon Sep 17 00:00:00 2001 From: Pedro Maciel Date: Fri, 7 Jun 2019 18:26:58 +0100 Subject: [PATCH 04/86] MIR-4 wrap_latitude and wrap_angle (projection assumption) --- src/tests/projection/test_rotation.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tests/projection/test_rotation.cc b/src/tests/projection/test_rotation.cc index a6edf7574..05493079a 100644 --- a/src/tests/projection/test_rotation.cc +++ b/src/tests/projection/test_rotation.cc @@ -123,7 +123,7 @@ CASE( "test_rotation_construction" ) { static const PointLonLat SP{0., -90.}; static const PointLonLat NP{180., 90.}; - auto rotation_poles = {SP, NP, {0., -90.1}, {0., 90.1}}; + std::vector rotation_poles = {SP, NP, {0., -90.1}, {0., 90.1}}; for ( auto& p : rotation_poles ) { Rotation s( Config( "south_pole", std::vector{p.lon(), p.lat()} ) ); From 5db84d92cca1084031af54f18cb03ac5deeac609 Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Thu, 6 Jun 2019 11:57:23 +0100 Subject: [PATCH 05/86] ATLAS-235 Fix mgrids and create acceptance tests --- src/apps/CMakeLists.txt | 1 - src/apps/atlas-benchmark.cc | 11 +- src/apps/atlas-grids.cc | 7 +- src/apps/atlas-meshgen.cc | 9 +- src/atlas/functionspace/StructuredColumns.cc | 10 + src/atlas/functionspace/StructuredColumns.h | 3 + .../detail/StructuredColumns_setup.cc | 22 +- src/atlas/interpolation/Interpolation.h | 8 +- src/atlas/runtime/AtlasTool.cc | 218 ++++++++++++++---- src/atlas/runtime/AtlasTool.h | 7 +- .../atlas-benchmark-ifs-setup.cc | 7 +- .../atlas-benchmark-sorting.cc | 7 +- .../atlas-grid-distribution.cc | 7 +- .../atlas-parallel-interpolation.cc | 4 +- src/tests/acceptance_tests/CMakeLists.txt | 90 +++++++- src/tests/acceptance_tests/atest_mgrids.cc | 181 ++++++++++++--- src/tests/acceptance_tests/compare.cmake | 29 +++ 17 files changed, 510 insertions(+), 111 deletions(-) create mode 100644 src/tests/acceptance_tests/compare.cmake diff --git a/src/apps/CMakeLists.txt b/src/apps/CMakeLists.txt index 00ec3ee06..a515999bd 100644 --- a/src/apps/CMakeLists.txt +++ b/src/apps/CMakeLists.txt @@ -10,7 +10,6 @@ if( ECKIT_INCLUDE_DIRS ) # eckit not yet ported to CMake3 include_directories( ${ECKIT_INCLUDE_DIRS} ) endif() - ecbuild_add_executable( TARGET atlas-main OUTPUT_NAME atlas diff --git a/src/apps/atlas-benchmark.cc b/src/apps/atlas-benchmark.cc index 7836a6a13..3595d6964 100644 --- a/src/apps/atlas-benchmark.cc +++ b/src/apps/atlas-benchmark.cc @@ -122,7 +122,7 @@ struct TimerStats { //---------------------------------------------------------------------------------------------------------------------- class AtlasBenchmark : public AtlasTool { - virtual void execute( const Args& args ); + virtual int execute( const Args& args ); public: AtlasBenchmark( int argc, char** argv ) : AtlasTool( argc, argv ) { @@ -170,14 +170,11 @@ class AtlasBenchmark : public AtlasTool { TimerStats haloexchange_timer; idx_t iter; bool progress; - -public: - int exit_code; }; //---------------------------------------------------------------------------------------------------------------------- -void AtlasBenchmark::execute( const Args& args ) { +int AtlasBenchmark::execute( const Args& args ) { Trace timer( Here(), "atlas-benchmark" ); // Timer::Logging set_channel( Log::info() ); @@ -265,7 +262,7 @@ void AtlasBenchmark::execute( const Args& args ) { double res = result(); Log::info() << endl; - exit_code = verify( res ); + return verify( res ); } //---------------------------------------------------------------------------------------------------------------------- @@ -551,7 +548,7 @@ double AtlasBenchmark::result() { int AtlasBenchmark::verify( const double& norm ) { Log::warning() << "Verification is not yet implemented" << endl; - return 1; + return failed(); } //---------------------------------------------------------------------------------------------------------------------- diff --git a/src/apps/atlas-grids.cc b/src/apps/atlas-grids.cc index 4c149cbc6..12de158c1 100644 --- a/src/apps/atlas-grids.cc +++ b/src/apps/atlas-grids.cc @@ -40,7 +40,7 @@ using eckit::JSON; class AtlasGrids : public AtlasTool { virtual bool serial() { return true; } - virtual void execute( const Args& args ); + virtual int execute( const Args& args ); virtual std::string briefDescription() { return "Catalogue of available built-in grids"; } virtual std::string usage() { return name() + " GRID [OPTION]... [--help,-h]"; } virtual std::string longDescription() { @@ -75,7 +75,7 @@ class AtlasGrids : public AtlasTool { //------------------------------------------------------------------------------------------------------ -void AtlasGrids::execute( const Args& args ) { +int AtlasGrids::execute( const Args& args ) { key = ""; if ( args.count() ) key = args( 0 ); @@ -115,7 +115,7 @@ void AtlasGrids::execute( const Args& args ) { catch ( eckit::Exception& ) { } - if ( !grid ) return; + if ( !grid ) return failed(); if ( info ) { double deg, km; @@ -179,6 +179,7 @@ void AtlasGrids::execute( const Args& args ) { std::cout << stream.str() << std::endl; } } + return success(); } //------------------------------------------------------------------------------------------------------ diff --git a/src/apps/atlas-meshgen.cc b/src/apps/atlas-meshgen.cc index 1751e2365..548c5692a 100644 --- a/src/apps/atlas-meshgen.cc +++ b/src/apps/atlas-meshgen.cc @@ -57,7 +57,7 @@ using eckit::PathName; //------------------------------------------------------------------------------ class Meshgen2Gmsh : public AtlasTool { - virtual void execute( const Args& args ); + virtual int execute( const Args& args ); virtual std::string briefDescription() { return "Mesh generator for Structured compatible meshes"; } virtual std::string usage() { return name() + " (--grid.name=name|--grid.json=path) [OPTION]... OUTPUT [--help]"; } @@ -116,7 +116,7 @@ Meshgen2Gmsh::Meshgen2Gmsh( int argc, char** argv ) : AtlasTool( argc, argv ) { //----------------------------------------------------------------------------- -void Meshgen2Gmsh::execute( const Args& args ) { +int Meshgen2Gmsh::execute( const Args& args ) { key = ""; args.get( "grid.name", key ); @@ -148,7 +148,7 @@ void Meshgen2Gmsh::execute( const Args& args ) { if ( path_in_str.empty() && key.empty() ) { Log::warning() << "missing argument --grid.name or --grid.json" << std::endl; Log::warning() << "Usage: " << usage() << std::endl; - return; + return failed(); } if ( edges ) halo = std::max( halo, 1l ); @@ -174,7 +174,7 @@ void Meshgen2Gmsh::execute( const Args& args ) { Log::error() << "No grid specified." << std::endl; } - if ( !grid ) return; + if ( !grid ) return failed(); Log::debug() << "Domain: " << grid.domain() << std::endl; Log::debug() << "Periodic: " << grid.periodic() << std::endl; @@ -239,6 +239,7 @@ void Meshgen2Gmsh::execute( const Args& args ) { mesh.polygon( jhalo ).outputPythonScript( "polygon_halo" + std::to_string( jhalo ) + ".py" ); } } + return success(); } //------------------------------------------------------------------------------ diff --git a/src/atlas/functionspace/StructuredColumns.cc b/src/atlas/functionspace/StructuredColumns.cc index 5f05a31c0..6f8d58392 100644 --- a/src/atlas/functionspace/StructuredColumns.cc +++ b/src/atlas/functionspace/StructuredColumns.cc @@ -712,6 +712,11 @@ StructuredColumns::StructuredColumns( const Grid& grid, const grid::Partitioner& FunctionSpace( new detail::StructuredColumns( grid, partitioner, config ) ), functionspace_( dynamic_cast( get() ) ) {} +StructuredColumns::StructuredColumns( const Grid& grid, const grid::Distribution& distribution, + const eckit::Configuration& config ) : + FunctionSpace( new detail::StructuredColumns( grid, distribution, config ) ), + functionspace_( dynamic_cast( get() ) ) {} + StructuredColumns::StructuredColumns( const Grid& grid, const Vertical& vertical, const eckit::Configuration& config ) : FunctionSpace( new detail::StructuredColumns( grid, vertical, config ) ), functionspace_( dynamic_cast( get() ) ) {} @@ -721,6 +726,11 @@ StructuredColumns::StructuredColumns( const Grid& grid, const Vertical& vertical FunctionSpace( new detail::StructuredColumns( grid, vertical, partitioner, config ) ), functionspace_( dynamic_cast( get() ) ) {} +StructuredColumns::StructuredColumns( const Grid& grid, const grid::Distribution& distribution, + const Vertical& vertical, const eckit::Configuration& config ) : + FunctionSpace( new detail::StructuredColumns( grid, distribution, vertical, config ) ), + functionspace_( dynamic_cast( get() ) ) {} + void StructuredColumns::gather( const FieldSet& local, FieldSet& global ) const { functionspace_->gather( local, global ); } diff --git a/src/atlas/functionspace/StructuredColumns.h b/src/atlas/functionspace/StructuredColumns.h index ba565e818..c61de4a7d 100644 --- a/src/atlas/functionspace/StructuredColumns.h +++ b/src/atlas/functionspace/StructuredColumns.h @@ -307,9 +307,12 @@ class StructuredColumns : public FunctionSpace { StructuredColumns( const FunctionSpace& ); StructuredColumns( const Grid&, const eckit::Configuration& = util::NoConfig() ); StructuredColumns( const Grid&, const grid::Partitioner&, const eckit::Configuration& = util::NoConfig() ); + StructuredColumns( const Grid&, const grid::Distribution&, const eckit::Configuration& = util::NoConfig() ); StructuredColumns( const Grid&, const Vertical&, const eckit::Configuration& = util::NoConfig() ); StructuredColumns( const Grid&, const Vertical&, const grid::Partitioner&, const eckit::Configuration& = util::NoConfig() ); + StructuredColumns( const Grid&, const grid::Distribution&, const Vertical&, + const eckit::Configuration& = util::NoConfig() ); static std::string type() { return detail::StructuredColumns::static_type(); } diff --git a/src/atlas/functionspace/detail/StructuredColumns_setup.cc b/src/atlas/functionspace/detail/StructuredColumns_setup.cc index 899dfe0f8..c705db5df 100644 --- a/src/atlas/functionspace/detail/StructuredColumns_setup.cc +++ b/src/atlas/functionspace/detail/StructuredColumns_setup.cc @@ -365,16 +365,34 @@ void StructuredColumns::setup( const grid::Distribution& distribution, const eck gidx_t k = global_offsets[gp.j] + gp.i; part( gp.r ) = distribution.partition( k ); global_idx( gp.r ) = k + 1; - ghost( gp.r ) = 0; } } if ( not in_domain ) { global_idx( gp.r ) = compute_g( gp.i, gp.j ); part( gp.r ) = compute_p( gp.i, gp.j ); - ghost( gp.r ) = 1; } index_i( gp.r ) = gp.i; index_j( gp.r ) = gp.j; + ghost( gp.r ) = 0; + } + + for ( idx_t j = j_begin_halo_; j < j_begin_; ++j ) { + for ( idx_t i = i_begin_halo_( j ); i < i_end_halo_( j ); ++i ) { + ghost( index( i, j ) ) = 1; + } + } + for ( idx_t j = j_begin_; j < j_end_; ++j ) { + for ( idx_t i = i_begin_halo_( j ); i < i_begin_[j]; ++i ) { + ghost( index( i, j ) ) = 1; + } + for ( idx_t i = i_end_[j]; i < i_end_halo_( j ); ++i ) { + ghost( index( i, j ) ) = 1; + } + } + for ( idx_t j = j_end_; j < j_end_halo_; ++j ) { + for ( idx_t i = i_begin_halo_( j ); i < i_end_halo_( j ); ++i ) { + ghost( index( i, j ) ) = 1; + } } } } diff --git a/src/atlas/interpolation/Interpolation.h b/src/atlas/interpolation/Interpolation.h index a5aae026b..dafa99d4b 100644 --- a/src/atlas/interpolation/Interpolation.h +++ b/src/atlas/interpolation/Interpolation.h @@ -37,16 +37,16 @@ class Interpolation : public util::ObjectHandle { Interpolation() = default; // Setup Interpolation from source to target function space - Interpolation( const Config&, const FunctionSpace& source, const FunctionSpace& target ); + Interpolation( const Config&, const FunctionSpace& source, const FunctionSpace& target ) noexcept( false ); // Setup Interpolation from source to coordinates given in a field with multiple components - Interpolation( const Config&, const FunctionSpace& source, const Field& target ); + Interpolation( const Config&, const FunctionSpace& source, const Field& target ) noexcept( false ); // Setup Interpolation from source to coordinates given by separate fields for each component - Interpolation( const Config&, const FunctionSpace& source, const FieldSet& target ); + Interpolation( const Config&, const FunctionSpace& source, const FieldSet& target ) noexcept( false ); // Setup Interpolation from source grid to target grid - Interpolation( const Config&, const Grid& source, const Grid& target ); + Interpolation( const Config&, const Grid& source, const Grid& target ) noexcept( false ); void execute( const FieldSet& source, FieldSet& target ) const; diff --git a/src/atlas/runtime/AtlasTool.cc b/src/atlas/runtime/AtlasTool.cc index efd6fc746..a80ed1bb1 100644 --- a/src/atlas/runtime/AtlasTool.cc +++ b/src/atlas/runtime/AtlasTool.cc @@ -9,8 +9,11 @@ */ #include +#include +#include #include "eckit/config/LibEcKit.h" +#include "eckit/filesystem/LocalPathName.h" #include "eckit/log/FileTarget.h" #include "eckit/log/PrefixTarget.h" @@ -79,8 +82,122 @@ int getEnv( const std::string& env, int default_value ) { return default_value; } +std::string getEnv( const std::string& env, const std::string& default_value ) { + if (::getenv( env.c_str() ) ) { return ::getenv( env.c_str() ); } + return default_value; +} + +void setEnv( const std::string& env, bool value ) { + ::setenv( env.c_str(), eckit::Translator()( value ).c_str(), 0 ); +} + } // namespace +namespace atlas { + +static std::string exception_what; +static eckit::CodeLocation exception_location; +static std::string exception_callstack; +static bool use_logfile; +static std::string logfile_name; +static std::string workdir; + +void atlas_terminate() { + // This routine is called for uncaught exceptions. + // It can be set with std::set_terminate( &atlas_terminate ) + + Log::flush(); + + if ( not use_logfile and mpi::comm().size() > 1 ) { + eckit::LogTarget* logfile = new eckit::FileTarget( logfile_name ); + Log::error().addTarget( logfile ); + } + if ( std::exception_ptr eptr = std::current_exception() ) { + std::ostream& out = Log::error(); + try { + std::rethrow_exception( eptr ); // throw to recognise the type + } + catch ( const eckit::Abort& exception ) { + out << "\n" + << "=========================================\n" + << "[" << mpi::comm().rank() << "] Aborting " << eckit::Main::instance().displayName() << "\n" + << "-----------------------------------------\n" + << exception.what() << "\n"; + if ( exception.location() ) + out << "-----------------------------------------\n" + << "LOCATION: " << exception.location() << "\n"; + out << "-----------------------------------------\n" + << "BACKTRACE\n" + << "-----------------------------------------\n" + << exception.callStack() << "\n" + << "=========================================\n" + << std::endl; + exception_what = exception.what(); + exception_location = exception.location(); + exception_callstack = exception.callStack(); + } + catch ( const eckit::Exception& exception ) { + out << "\n" + << "=========================================\n" + << "[" << mpi::comm().rank() << "] TERMINATING " << eckit::Main::instance().displayName() << "\n" + << "-----------------------------------------\n" + << exception.what() << "\n" + << "-----------------------------------------\n"; + + if ( exception.location() ) + out << "LOCATION: " << exception.location() << "\n" + << "-----------------------------------------\n"; + + out << "BACKTRACE\n" + << "-----------------------------------------\n" + << exception.callStack() << "\n" + << "=========================================\n" + << std::endl; + exception_what = exception.what(); + exception_location = exception.location(); + exception_callstack = backtrace(); + } + catch ( const std::exception& exception ) { + out << "\n" + << "=========================================\n" + << "[" << mpi::comm().rank() << "] TERMINATING " << eckit::Main::instance().displayName() << "\n" + << "-----------------------------------------\n" + << exception.what() << "\n" + << "-----------------------------------------\n" + << "BACKTRACE\n" + << "-----------------------------------------\n" + << backtrace() << "\n" + << "=========================================\n" + << std::endl; + exception_what = exception.what(); + exception_location = eckit::CodeLocation(); + exception_callstack = backtrace(); + } + catch ( ... ) { + out << "\n" + << "=========================================\n" + << "[" << mpi::comm().rank() << "] TERMINATING " << eckit::Main::instance().displayName() << "\n" + << "-----------------------------------------\n" + << "BACKTRACE\n" + << "-----------------------------------------\n" + << backtrace() << "\n" + << "=========================================" << std::endl; + exception_what = "Uncaught exception"; + exception_location = eckit::CodeLocation(); + exception_callstack = backtrace(); + } + } + + eckit::LibEcKit::instance().abort(); + + // Just in case we end up here, as last resort, exit immediately without + // cleanup. + std::_Exit( EXIT_FAILURE ); +} + +} // namespace atlas + + void atlas::AtlasTool::add_option( eckit::option::Option* option ) { options_.push_back( option ); } @@ -120,72 +237,79 @@ bool atlas::AtlasTool::handle_help() { atlas::AtlasTool::AtlasTool( int argc, char** argv ) : eckit::Tool( argc, argv ) { eckit::LibEcKit::instance().setAbortHandler( [] { - Log::error() << "[" << atlas::mpi::comm().rank() << "] " - << "calling MPI_Abort" << std::endl; + std::cerr << "[" << atlas::mpi::comm().rank() << "] " + << "calling MPI_Abort, logfile: " << logfile_name << std::endl; + std::this_thread::sleep_for( std::chrono::milliseconds( 3000 ) ); atlas::mpi::comm().abort( 1 ); } ); - + std::set_terminate( &atlas_terminate ); + setEnv( "ECKIT_EXCEPTION_IS_SILENT", true ); + setEnv( "ECKIT_ASSERT_FAILED_IS_SILENT", true ); add_option( new SimpleOption( "help", "Print this help" ) ); add_option( new SimpleOption( "debug", "Debug level" ) ); taskID( eckit::mpi::comm( "world" ).rank() ); + workdir = getEnv( "ATLAS_WORKDIR", eckit::PathName( eckit::LocalPathName::cwd() ).fullName() ); + + add_option( new SimpleOption( "display-name", "Name to give to program" ) ); } int atlas::AtlasTool::start() { - int status = 0; try { - run(); - } - catch ( eckit::Exception& e ) { - status = 1; - Log::error() << "** " << e.what() << e.location() << std::endl; - Log::error() << "** Backtrace:\n" << e.callStack() << '\n'; - Log::error() << "** Exception caught in " << Here() << " terminates " << name() << std::endl; - } - catch ( std::exception& e ) { - status = 1; - Log::error() << "** " << e.what() << " caught in " << Here() << '\n'; - Log::error() << "** Exception terminates " << name() << std::endl; + if ( handle_help() ) return success(); + + if ( argc() - 1 < minimumPositionalArguments() ) { + if ( taskID() == 0 ) std::cout << "Usage: " << usage() << std::endl; + return failed(); + } + Options opts = options_; + Args args( &atlas::usage, opts, numberOfPositionalArguments(), minimumPositionalArguments() ); + + atlas::Library::instance().initialise(); + setupLogging(); + int err_code = execute( args ); + atlas::Library::instance().finalise(); + return err_code; } catch ( ... ) { - status = 1; - Log::error() << "** Exception caught in " << Here() << '\n'; - Log::error() << "** Exception terminates " << name() << std::endl; + atlas_terminate(); } - if ( status ) { - Log::error() << std::flush; - eckit::LibEcKit::instance().abort(); - } - - return status; + // catch ( eckit::Exception& e ) { + // status = 1; + // Log::error() << "** " << e.what() << e.location() << std::endl; + // Log::error() << "** Backtrace:\n" << e.callStack() << '\n'; + // Log::error() << "** Exception caught in " << Here() << " terminates " << name() << std::endl; + // } + // catch ( std::exception& e ) { + // status = 1; + // Log::error() << "** " << e.what() << " caught in " << Here() << '\n'; + // Log::error() << "** Exception terminates " << name() << std::endl; + // } + // catch ( ... ) { + // status = 1; + // Log::error() << "** Exception caught in " << Here() << '\n'; + // Log::error() << "** Exception terminates " << name() << std::endl; + // } + // if ( status ) { + // Log::error() << std::flush; + // eckit::LibEcKit::instance().abort(); + // } } -void atlas::AtlasTool::run() { - if ( handle_help() ) return; +void atlas::AtlasTool::run() {} - if ( argc() - 1 < minimumPositionalArguments() ) { - if ( taskID() == 0 ) std::cout << "Usage: " << usage() << std::endl; - return; - } - Options opts = options_; - Args args( &atlas::usage, opts, numberOfPositionalArguments(), minimumPositionalArguments() ); +void atlas::AtlasTool::setupLogging() { + int log_rank = getEnv( "ATLAS_LOG_RANK", 0 ); + use_logfile = getEnv( "ATLAS_LOG_FILE", false ); - atlas::Library::instance().initialise(); - setupLogging(); - execute( args ); - atlas::Library::instance().finalise(); -} + int d = digits( mpi::comm().size() ); + std::string rankstr = std::to_string( taskID() ); + for ( int i = rankstr.size(); i < d; ++i ) + rankstr = "0" + rankstr; -void atlas::AtlasTool::setupLogging() { - int log_rank = getEnv( "ATLAS_LOG_RANK", 0 ); - bool use_logfile = getEnv( "ATLAS_LOG_FILE", false ); + logfile_name = workdir + "/" + displayName() + ".log.p" + rankstr; if ( use_logfile ) { - int d = digits( mpi::comm().size() ); - std::string rankstr = std::to_string( taskID() ); - for ( int i = rankstr.size(); i < d; ++i ) - rankstr = "0" + rankstr; - - eckit::LogTarget* logfile = new eckit::FileTarget( displayName() + ".log.p" + rankstr ); + eckit::LogTarget* logfile = new eckit::FileTarget( logfile_name ); if ( int( mpi::comm().rank() ) == log_rank ) { if ( Log::info() ) Log::info().addTarget( logfile ); diff --git a/src/atlas/runtime/AtlasTool.h b/src/atlas/runtime/AtlasTool.h index b05b8c568..db0bd44f2 100644 --- a/src/atlas/runtime/AtlasTool.h +++ b/src/atlas/runtime/AtlasTool.h @@ -60,9 +60,12 @@ class AtlasTool : public eckit::Tool { int start(); - virtual void run(); + virtual void run(); // unused - virtual void execute( const Args& ) = 0; + virtual int execute( const Args& ) = 0; + + static constexpr int success() { return 0; } + static constexpr int failed() { return 1; } private: void setupLogging(); diff --git a/src/sandbox/benchmark_ifs_setup/atlas-benchmark-ifs-setup.cc b/src/sandbox/benchmark_ifs_setup/atlas-benchmark-ifs-setup.cc index 86372547e..788ae8a39 100644 --- a/src/sandbox/benchmark_ifs_setup/atlas-benchmark-ifs-setup.cc +++ b/src/sandbox/benchmark_ifs_setup/atlas-benchmark-ifs-setup.cc @@ -44,7 +44,7 @@ using eckit::PathName; //------------------------------------------------------------------------------ class Tool : public AtlasTool { - virtual void execute( const Args& args ); + virtual int execute( const Args& args ); virtual std::string briefDescription() { return "Tool to generate a python script that plots the grid-distribution " "of a given grid"; @@ -75,7 +75,7 @@ Tool::Tool( int argc, char** argv ) : AtlasTool( argc, argv ) { //----------------------------------------------------------------------------- -void Tool::execute( const Args& args ) { +int Tool::execute( const Args& args ) { Trace timer( Here(), displayName() ); key = ""; args.get( "grid", key ); @@ -95,7 +95,7 @@ void Tool::execute( const Args& args ) { Log::error() << "No grid specified." << std::endl; } - if ( !grid ) return; + if ( !grid ) return failed(); size_t halo = args.getLong( "halo", halo_default() ); @@ -118,6 +118,7 @@ void Tool::execute( const Args& args ) { } timer.stop(); Log::info() << Trace::report() << std::endl; + return success(); } //------------------------------------------------------------------------------ diff --git a/src/sandbox/benchmark_sorting/atlas-benchmark-sorting.cc b/src/sandbox/benchmark_sorting/atlas-benchmark-sorting.cc index 7c91c6208..54239ead6 100644 --- a/src/sandbox/benchmark_sorting/atlas-benchmark-sorting.cc +++ b/src/sandbox/benchmark_sorting/atlas-benchmark-sorting.cc @@ -174,7 +174,7 @@ void make_nodes_global_index_human_readable( const mesh::actions::BuildHalo& bui //----------------------------------------------------------------------------- class Tool : public AtlasTool { - virtual void execute( const Args& args ); + virtual int execute( const Args& args ); virtual std::string briefDescription() { return "Tool to generate a python script that plots the grid-distribution " "of a given grid"; @@ -201,7 +201,7 @@ Tool::Tool( int argc, char** argv ) : AtlasTool( argc, argv ) { //----------------------------------------------------------------------------- -void Tool::execute( const Args& args ) { +int Tool::execute( const Args& args ) { Trace t( Here(), "main" ); key = ""; @@ -222,7 +222,7 @@ void Tool::execute( const Args& args ) { Log::error() << "No grid specified." << std::endl; } - if ( !grid ) return; + if ( !grid ) return failed(); Log::debug() << "Domain: " << grid.domain() << std::endl; Log::debug() << "Periodic: " << grid.periodic() << std::endl; @@ -257,6 +257,7 @@ void Tool::execute( const Args& args ) { Log::info() << Trace::report( Config( "indent", 2 )( "decimals", 2 ) // ("depth",5) ); + return success(); } //------------------------------------------------------------------------------ diff --git a/src/sandbox/grid_distribution/atlas-grid-distribution.cc b/src/sandbox/grid_distribution/atlas-grid-distribution.cc index 071cf1fa4..ea6f24eba 100644 --- a/src/sandbox/grid_distribution/atlas-grid-distribution.cc +++ b/src/sandbox/grid_distribution/atlas-grid-distribution.cc @@ -40,7 +40,7 @@ using eckit::PathName; //------------------------------------------------------------------------------ class Tool : public AtlasTool { - virtual void execute( const Args& args ); + virtual int execute( const Args& args ); virtual std::string briefDescription() { return "Tool to generate a python script that plots the grid-distribution " "of a given grid"; @@ -68,7 +68,7 @@ Tool::Tool( int argc, char** argv ) : AtlasTool( argc, argv ) { //----------------------------------------------------------------------------- -void Tool::execute( const Args& args ) { +int Tool::execute( const Args& args ) { key = ""; args.get( "grid.name", key ); @@ -96,7 +96,7 @@ void Tool::execute( const Args& args ) { Log::error() << "No grid specified." << std::endl; } - if ( !grid ) return; + if ( !grid ) return failed(); Log::debug() << "Domain: " << grid.domain() << std::endl; Log::debug() << "Periodic: " << grid.periodic() << std::endl; @@ -188,6 +188,7 @@ void Tool::execute( const Args& args ) { "\n" "plt.show()"; } + return success(); } //------------------------------------------------------------------------------ diff --git a/src/sandbox/interpolation/atlas-parallel-interpolation.cc b/src/sandbox/interpolation/atlas-parallel-interpolation.cc index 61d46516d..3d342ec37 100644 --- a/src/sandbox/interpolation/atlas-parallel-interpolation.cc +++ b/src/sandbox/interpolation/atlas-parallel-interpolation.cc @@ -44,7 +44,7 @@ auto vortex_rollup = []( double lon, double lat, double t ) { }; class AtlasParallelInterpolation : public AtlasTool { - void execute( const AtlasTool::Args& args ); + int execute( const AtlasTool::Args& args ); std::string briefDescription() { return "Demonstration of parallel interpolation"; } std::string usage() { return name() + @@ -99,7 +99,7 @@ class AtlasParallelInterpolation : public AtlasTool { } }; -void AtlasParallelInterpolation::execute( const AtlasTool::Args& args ) { +int AtlasParallelInterpolation::execute( const AtlasTool::Args& args ) { // Get user options std::string option; bool trigs = false; diff --git a/src/tests/acceptance_tests/CMakeLists.txt b/src/tests/acceptance_tests/CMakeLists.txt index fa230989b..9053aa74b 100644 --- a/src/tests/acceptance_tests/CMakeLists.txt +++ b/src/tests/acceptance_tests/CMakeLists.txt @@ -6,7 +6,89 @@ # granted to it by virtue of its status as an intergovernmental organisation nor # does it submit to any jurisdiction. -ecbuild_add_executable( TARGET atlas_atest_mgrids - SOURCES atest_mgrids.cc - LIBS atlas - ) +ecbuild_add_executable( + TARGET atlas-atest-mgrids + SOURCES atest_mgrids.cc + LIBS atlas + CONDITION HAVE_TRANS +) + +if( HAVE_TESTS ) + ecbuild_add_option( FEATURE ACCEPTANCE_TESTS DEFAULT OFF ) + + if( HAVE_ACCEPTANCE_TESTS ) + ecbuild_add_option( FEATURE ACCEPTANCE_TESTS_SMALL DEFAULT ON ) + ecbuild_add_option( FEATURE ACCEPTANCE_TESTS_LARGE DEFAULT OFF ) + endif() +endif() + +if( HAVE_ACCEPTANCE_TESTS ) + +if( TARGET atlas-atest-mgrids ) + +function( atlas_atest_mgrids category case nprocs ) + string(REPLACE "/" ";" case ${case} ) + list( GET case 0 gridA ) + list( GET case 1 gridB ) + unset( checksums ) + unset( case_tests ) + foreach( n ${nprocs} ) + foreach( t 1 4 12 ) + set( test_name atlas_atest_${category}_mgrids_${gridA}_to_${gridB}_n${n}_t${t} ) + ecbuild_add_test( TARGET ${test_name} + COMMAND $ + ARGS --gridA=${gridA} + --gridB=${gridB} + --haloA=3 + --haloB=3 + --display-name=${test_name} + --checksum=${test_name}.checksum + --matrix-free + MPI ${n} + OMP ${t} + ) + list( APPEND checksums ${test_name}.checksum ) + list( APPEND case_tests ${test_name} ) + endforeach() + endforeach() + add_test( + NAME atlas_atest_mgrids_${gridA}_to_${gridB}_BitReproducible + COMMAND ${CMAKE_COMMAND} + "-DFILES=${checksums}" -P ${CMAKE_CURRENT_SOURCE_DIR}/compare.cmake + ) + foreach( dep ${case_tests} ) + set_tests_properties( atlas_atest_mgrids_${gridA}_to_${gridB}_BitReproducible PROPERTIES DEPENDS ${dep} ) + endforeach() +endfunction() + +if( HAVE_ACCEPTANCE_TESTS_SMALL ) + unset( cases ) + list( APPEND cases + O32/O16 + O32/L16 + O64/F20 + ) + list( APPEND nprocs + 1 + 4 + 32 + ) + foreach( case ${cases} ) + atlas_atest_mgrids( small ${case} "${nprocs}" ) + endforeach() +endif() + +if( HAVE_ACCEPTANCE_TESTS_LARGE ) + unset( cases ) + list( APPEND cases + O640/O320 + ) + set( nprocs 1 4 36 72 ) + foreach( case ${cases} ) + atlas_atest_mgrids( large ${case} "${nprocs}" ) + endforeach() +endif() + +endif() + +endif() diff --git a/src/tests/acceptance_tests/atest_mgrids.cc b/src/tests/acceptance_tests/atest_mgrids.cc index 837b782f5..156a02318 100644 --- a/src/tests/acceptance_tests/atest_mgrids.cc +++ b/src/tests/acceptance_tests/atest_mgrids.cc @@ -16,11 +16,14 @@ #include #include +#include "eckit/log/OStreamTarget.h" + #include "atlas/field.h" #include "atlas/functionspace.h" #include "atlas/grid.h" #include "atlas/interpolation/Interpolation.h" #include "atlas/mesh.h" +#include "atlas/mesh/actions/BuildHalo.h" #include "atlas/meshgenerator.h" #include "atlas/numerics/fvm/Method.h" #include "atlas/option.h" @@ -29,15 +32,17 @@ #include "atlas/runtime/AtlasTool.h" #include "atlas/runtime/Log.h" #include "atlas/util/Config.h" - -#include "atlas/mesh/actions/BuildHalo.h" +#include "atlas/util/Constants.h" +#include "atlas/util/CoordinateEnums.h" using namespace atlas; +double vortex_rollup( double lon, double lat, double t, double mean ); + //------------------------------------------------------------------------------ class Program : public AtlasTool { - virtual void execute( const Args& args ); + virtual int execute( const Args& args ); public: Program( int argc, char** argv ); @@ -49,54 +54,178 @@ Program::Program( int argc, char** argv ) : AtlasTool( argc, argv ) { add_option( new SimpleOption( "gridA", "grid A" ) ); add_option( new SimpleOption( "gridB", "grid B" ) ); add_option( new SimpleOption( "ghost", "Output ghost elements" ) ); - add_option( new SimpleOption( "haloA", "Halo size" ) ); - add_option( new SimpleOption( "haloB", "Halo size" ) ); - add_option( new SimpleOption( "no-forward", "no forward interpolation" ) ); - add_option( new SimpleOption( "no-backward", "no backward interpolation" ) ); + add_option( new SimpleOption( "haloA", "Halo size for A" ) ); + add_option( new SimpleOption( "haloB", "Halo size for B" ) ); + add_option( new SimpleOption( "matrix-free", "Interpolation without matrix" ) ); + add_option( new SimpleOption( "checksum", "File to write that will contains checksums of run" ) ); + add_option( new SimpleOption( "gmsh", "Output gmsh" ) ); + add_option( new SimpleOption( "no-validate", "Avoid validation of results to increase runtime" ) ); } //----------------------------------------------------------------------------- -void Program::execute( const Args& args ) { - auto ghost = util::Config( "ghost", args.getBool( "ghost", false ) ); - auto haloA = option::halo( args.getLong( "haloA", 1 ) ); - auto haloB = option::halo( args.getLong( "haloB", 1 ) ); +int Program::execute( const Args& args ) { + auto matrix_free = util::Config( "matrix_free", args.getBool( "matrix-free", false ) ); + auto ghost = util::Config( "ghost", args.getBool( "ghost", false ) ); + auto haloA = option::halo( args.getLong( "haloA", 2 ) ); + auto haloB = option::halo( args.getLong( "haloB", 2 ) ); + auto checksum_filepath = args.getString( "checksum", displayName() + ".checksum" ); auto gridA = Grid( args.getString( "gridA" ) ); auto gridB = Grid( args.getString( "gridB" ) ); auto meshgenerator = MeshGenerator( "structured" ); + Trace setup_A( Here(), "Setup A" ); auto distA = grid::Distribution( gridA, grid::Partitioner( "trans" ) ); - auto meshA = meshgenerator.generate( gridA, distA ); + functionspace::StructuredColumns fsA( gridA, distA, haloA ); + setup_A.stop(); - numerics::fvm::Method fvmA( meshA, haloA ); - auto gmshA = output::Gmsh( "meshA.msh", ghost ); - gmshA.write( meshA ); - + Trace setup_B( Here(), "Setup B" ); auto distB = grid::Distribution( gridB, grid::MatchingMeshPartitioner( meshA ) ); + functionspace::StructuredColumns fsB( gridB, distB, haloB ); + setup_B.stop(); + + Trace setup_interpolation_AtoB( Here(), "Setup interpolation AtoB" ); + Interpolation AtoB( option::type( "bicubic" ) | matrix_free, fsA, fsB ); + setup_interpolation_AtoB.stop(); + + Trace setup_interpolation_BtoA( Here(), "Setup interpolation BtoA" ); + Interpolation BtoA( option::type( "bicubic" ) | matrix_free, fsB, fsA ); + setup_interpolation_BtoA.stop(); + + Field fieldA = fsA.createField( option::name( "fieldA" ) ); + Field fieldB = fsB.createField( option::name( "fieldB" ) ); + + auto lonlat = array::make_view( fsA.xy() ); + auto A = array::make_view( fieldA ); + auto B = array::make_view( fieldB ); - auto meshB = meshgenerator.generate( gridB, distB ); + double meanA = 1.; + for ( idx_t n = 0; n < fsA.size(); ++n ) { + A( n ) = vortex_rollup( lonlat( n, LON ), lonlat( n, LAT ), 1., meanA ); + } + fieldA.set_dirty(); + fieldA.haloExchange(); + + + Log::Channel checksums; + checksums.addStream( Log::info() ); + if ( mpi::comm().rank() == 0 ) { checksums.addFile( checksum_filepath ); } - numerics::fvm::Method fvmB( meshB, haloB ); + checksums << "Field A checksum before interpolation AtoB: " << fsA.checksum( fieldA ) << std::endl; - Field fieldB = fvmB.node_columns().createField(); + Trace interpolation_AtoB( Here(), "Interpolation AtoB" ); + AtoB.execute( fieldA, fieldB ); + interpolation_AtoB.stop(); - output::Gmsh gmshB( "meshB.msh", ghost ); - gmshB.write( meshB ); - gmshB.write( fieldB ); + checksums << "Field B checksum after interpolation AtoB: " << fsB.checksum( fieldB ) << std::endl; - if ( not args.getBool( "no-forward", false ) ) { - Interpolation AtoB( option::type( "finite-element" ), fvmA.node_columns(), fvmB.node_columns() ); + for ( idx_t n = 0; n < fsB.size(); ++n ) { + B( n ) = meanA - B( n ); } - if ( not args.getBool( "no-backward", false ) ) { - Interpolation BtoA( option::type( "finite-element" ), fvmB.node_columns(), fvmA.node_columns() ); + fieldB.set_dirty(); + fieldB.haloExchange(); + + Trace interpolation_BtoA( Here(), "Interpolation BtoA" ); + BtoA.execute( fieldB, fieldA ); + interpolation_BtoA.stop(); + + checksums << "Field A checksum after interpolation BtoA: " << fsA.checksum( fieldA ) << std::endl; + + Log::info() << "Timers:" << std::endl; + Log::info() << " Setup A " << setup_A.elapsed() << " s" << std::endl; + Log::info() << " Setup B " << setup_B.elapsed() << " s" << std::endl; + Log::info() << " -----------------------------------------" << std::endl; + Log::info() << " Interpolation AtoB Setup " << setup_interpolation_AtoB.elapsed() << " s" << std::endl; + Log::info() << " Interpolation BtoA Setup " << setup_interpolation_BtoA.elapsed() << " s" << std::endl; + Log::info() << " Interpolation AtoB Execute " << interpolation_AtoB.elapsed() << " s" << std::endl; + Log::info() << " Interpolation BtoA Execute " << interpolation_BtoA.elapsed() << " s" << std::endl; + Log::info() << " -----------------------------------------" << std::endl; + Log::info() << " Interpolation AtoB Total " << setup_interpolation_AtoB.elapsed() + interpolation_AtoB.elapsed() + << " s" << std::endl; + Log::info() << " Interpolation BtoA Total " << setup_interpolation_BtoA.elapsed() + interpolation_BtoA.elapsed() + << " s" << std::endl; + + int status = success(); + + Mesh meshB; + if ( not args.getBool( "no-validate", false ) ) { + double tolerance = 1.e-12; + + meshB = meshgenerator.generate( gridB, distB ); + auto norm_computerB = functionspace::NodeColumns( meshB ); + double sumB; + idx_t countB; + norm_computerB.sum( fieldB, sumB, countB ); + if ( std::abs( sumB ) < tolerance ) { + Log::info() << "Validation B correct: " << std::abs( sumB ) << " < tolerance [" << tolerance << "]" + << std::endl; + } + else { + Log::error() << "Validation B failed: " << std::abs( sumB ) << " > tolerance [" << tolerance << "]" + << std::endl; + status = failed(); + } + + auto norm_computerA = functionspace::NodeColumns( meshA ); + double sumA; + idx_t countA; + norm_computerA.sum( fieldA, sumA, countA ); + if ( std::abs( sumA ) < tolerance ) { + Log::info() << "Validation A correct: " << std::abs( sumA ) << " < tolerance [" << tolerance << "]" + << std::endl; + } + else { + Log::error() << "Validation A failed: " << std::abs( sumA ) << " > tolerance [" << tolerance << "]" + << std::endl; + status = failed(); + } } + + // Gmsh output + if ( args.getBool( "gmsh", false ) ) { + if ( not meshB ) { meshB = meshgenerator.generate( gridB, distB ); } + + auto gmshA = output::Gmsh( displayName() + "_meshA.msh", ghost ); + gmshA.write( meshA ); + gmshA.write( fieldA ); + + auto gmshB = output::Gmsh( displayName() + "_meshB.msh", ghost ); + gmshB.write( meshB ); + gmshB.write( fieldB ); + } + return status; } //------------------------------------------------------------------------------ +double vortex_rollup( double lon, double lat, double t, double mean ) { + // lon and lat in degrees! + + // Formula found in "A Lagrangian Particle Method with Remeshing for Tracer Transport on the Sphere" + // by Peter Bosler, James Kent, Robert Krasny, CHristiane Jablonowski, JCP 2015 + + lon *= util::Constants::degreesToRadians(); + lat *= util::Constants::degreesToRadians(); + + auto sqr = []( const double x ) { return x * x; }; + auto sech = []( const double x ) { return 1. / std::cosh( x ); }; + const double T = 1.; + const double Omega = 2. * M_PI / T; + t *= T; + const double lambda_prime = std::atan2( -std::cos( lon - Omega * t ), std::tan( lat ) ); + const double rho = 3. * std::sqrt( 1. - sqr( std::cos( lat ) ) * sqr( std::sin( lon - Omega * t ) ) ); + double omega = 0.; + double a = util::Earth::radius(); + if ( rho != 0. ) { omega = 0.5 * 3 * std::sqrt( 3 ) * a * Omega * sqr( sech( rho ) ) * std::tanh( rho ) / rho; } + double q = mean - std::tanh( 0.2 * rho * std::sin( lambda_prime - omega / a * t ) ); + return q; +}; + +//------------------------------------------------------------------------------ + int main( int argc, char** argv ) { Program tool( argc, argv ); return tool.start(); diff --git a/src/tests/acceptance_tests/compare.cmake b/src/tests/acceptance_tests/compare.cmake new file mode 100644 index 000000000..76524ea9e --- /dev/null +++ b/src/tests/acceptance_tests/compare.cmake @@ -0,0 +1,29 @@ +# (C) Copyright 2019 ECMWF. +# +# This file is covered by the LICENSING file in the root of this project. +# In applying this licence, ECMWF does not waive the privileges and immunities +# granted to it by virtue of its status as an intergovernmental organisation +# nor does it submit to any jurisdiction. + +function( run_command COMMAND ) + set( COMMAND ${ARGV} ) + string(REPLACE ";" " " PRINT_COMMAND "${COMMAND}" ) + message( "cd ${CMAKE_CURRENT_BINARY_DIR} && ${PRINT_COMMAND}" ) + execute_process( + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + COMMAND ${COMMAND} + RESULT_VARIABLE res + ) + if(res) + message(FATAL_ERROR "[ ${COMMAND} ] failed") + endif() +endfunction() + +message( "Working directory: ${CMAKE_CURRENT_BINARY_DIR}") + +list( GET FILES 0 ref ) +foreach( file ${FILES} ) + if( NOT ${file} STREQUAL ${ref} ) + run_command( ${CMAKE_COMMAND} -E compare_files ${ref} ${file} ) + endif() +endforeach() From 7c1fb88650adcde890858336c85c4e9b04974516 Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Fri, 7 Jun 2019 16:29:26 +0000 Subject: [PATCH 06/86] Allow atlas-atest-mgrids without transi --- src/tests/acceptance_tests/CMakeLists.txt | 7 ++++++- src/tests/acceptance_tests/atest_mgrids.cc | 23 +++++++++++----------- 2 files changed, 17 insertions(+), 13 deletions(-) diff --git a/src/tests/acceptance_tests/CMakeLists.txt b/src/tests/acceptance_tests/CMakeLists.txt index 9053aa74b..1916f31a9 100644 --- a/src/tests/acceptance_tests/CMakeLists.txt +++ b/src/tests/acceptance_tests/CMakeLists.txt @@ -10,7 +10,6 @@ ecbuild_add_executable( TARGET atlas-atest-mgrids SOURCES atest_mgrids.cc LIBS atlas - CONDITION HAVE_TRANS ) if( HAVE_TESTS ) @@ -27,6 +26,11 @@ if( HAVE_ACCEPTANCE_TESTS ) if( TARGET atlas-atest-mgrids ) function( atlas_atest_mgrids category case nprocs ) + + if( HAVE_TRANS ) + set( PARTITIONER "--partitioner=trans" ) + endif() + string(REPLACE "/" ";" case ${case} ) list( GET case 0 gridA ) list( GET case 1 gridB ) @@ -44,6 +48,7 @@ function( atlas_atest_mgrids category case nprocs ) --display-name=${test_name} --checksum=${test_name}.checksum --matrix-free + ${PARTITIONER} MPI ${n} OMP ${t} ) diff --git a/src/tests/acceptance_tests/atest_mgrids.cc b/src/tests/acceptance_tests/atest_mgrids.cc index 156a02318..37fff8c14 100644 --- a/src/tests/acceptance_tests/atest_mgrids.cc +++ b/src/tests/acceptance_tests/atest_mgrids.cc @@ -9,12 +9,9 @@ */ #include -#include #include -#include #include -#include -#include +#include #include "eckit/log/OStreamTarget.h" @@ -23,9 +20,7 @@ #include "atlas/grid.h" #include "atlas/interpolation/Interpolation.h" #include "atlas/mesh.h" -#include "atlas/mesh/actions/BuildHalo.h" #include "atlas/meshgenerator.h" -#include "atlas/numerics/fvm/Method.h" #include "atlas/option.h" #include "atlas/output/Gmsh.h" #include "atlas/parallel/mpi/mpi.h" @@ -43,7 +38,6 @@ double vortex_rollup( double lon, double lat, double t, double mean ); class Program : public AtlasTool { virtual int execute( const Args& args ); - public: Program( int argc, char** argv ); }; @@ -60,24 +54,26 @@ Program::Program( int argc, char** argv ) : AtlasTool( argc, argv ) { add_option( new SimpleOption( "checksum", "File to write that will contains checksums of run" ) ); add_option( new SimpleOption( "gmsh", "Output gmsh" ) ); add_option( new SimpleOption( "no-validate", "Avoid validation of results to increase runtime" ) ); + add_option( new SimpleOption( "partitioner", "Partitioner for gridA (default=equal_regions)") ); } //----------------------------------------------------------------------------- - + int Program::execute( const Args& args ) { + auto matrix_free = util::Config( "matrix_free", args.getBool( "matrix-free", false ) ); auto ghost = util::Config( "ghost", args.getBool( "ghost", false ) ); auto haloA = option::halo( args.getLong( "haloA", 2 ) ); auto haloB = option::halo( args.getLong( "haloB", 2 ) ); auto checksum_filepath = args.getString( "checksum", displayName() + ".checksum" ); - + auto partitioner = args.getString( "partitioner", "equal_regions" ); auto gridA = Grid( args.getString( "gridA" ) ); auto gridB = Grid( args.getString( "gridB" ) ); auto meshgenerator = MeshGenerator( "structured" ); Trace setup_A( Here(), "Setup A" ); - auto distA = grid::Distribution( gridA, grid::Partitioner( "trans" ) ); + auto distA = grid::Distribution( gridA, grid::Partitioner( partitioner ) ); auto meshA = meshgenerator.generate( gridA, distA ); functionspace::StructuredColumns fsA( gridA, distA, haloA ); setup_A.stop(); @@ -109,7 +105,6 @@ int Program::execute( const Args& args ) { fieldA.set_dirty(); fieldA.haloExchange(); - Log::Channel checksums; checksums.addStream( Log::info() ); if ( mpi::comm().rank() == 0 ) { checksums.addFile( checksum_filepath ); } @@ -152,7 +147,7 @@ int Program::execute( const Args& args ) { Mesh meshB; if ( not args.getBool( "no-validate", false ) ) { - double tolerance = 1.e-12; + double tolerance = 1.e-8; meshB = meshgenerator.generate( gridB, distB ); auto norm_computerB = functionspace::NodeColumns( meshB ); @@ -166,6 +161,8 @@ int Program::execute( const Args& args ) { else { Log::error() << "Validation B failed: " << std::abs( sumB ) << " > tolerance [" << tolerance << "]" << std::endl; + norm_computerB.orderIndependentSum( fieldB, sumB, countB ); + Log::info() << " order_independent_sum: " << sumB << " count = " << countB << std::endl; status = failed(); } @@ -180,6 +177,8 @@ int Program::execute( const Args& args ) { else { Log::error() << "Validation A failed: " << std::abs( sumA ) << " > tolerance [" << tolerance << "]" << std::endl; + norm_computerA.orderIndependentSum( fieldA, sumA, countA ); + Log::info() << " order_independent_sum: " << sumA << " count = " << countA << std::endl; status = failed(); } } From 7e464343eeb5fa16b2bf95c34cf21237f3353d60 Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Fri, 7 Jun 2019 16:29:50 +0000 Subject: [PATCH 07/86] Cray compilation warnings --- src/atlas/domain/Domain.cc | 4 ++++ src/atlas/domain/Domain.h | 3 ++- src/atlas/runtime/AtlasTool.cc | 2 +- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/atlas/domain/Domain.cc b/src/atlas/domain/Domain.cc index 9d3475c7f..82c666462 100644 --- a/src/atlas/domain/Domain.cc +++ b/src/atlas/domain/Domain.cc @@ -60,6 +60,10 @@ double RectangularDomain::ymax() const { return domain_->ymax(); } +ZonalBandDomain::ZonalBandDomain( const Interval& y ) : + RectangularDomain( ( ZD::is_global( y ) ) ? new atlas::domain::GlobalDomain() + : new atlas::domain::ZonalBandDomain( y ) ) {} + ZonalBandDomain::ZonalBandDomain( const Interval& y, const double& west ) : RectangularDomain( ( ZD::is_global( y ) ) ? new atlas::domain::GlobalDomain( west ) : new atlas::domain::ZonalBandDomain( y, west ) ) {} diff --git a/src/atlas/domain/Domain.h b/src/atlas/domain/Domain.h index 685864ef5..407a6affc 100644 --- a/src/atlas/domain/Domain.h +++ b/src/atlas/domain/Domain.h @@ -133,7 +133,8 @@ class ZonalBandDomain : public RectangularDomain { public: using RectangularDomain::RectangularDomain; - ZonalBandDomain( const Interval& y, const double& west = 0. ); + ZonalBandDomain( const Interval& y, const double& west ); + ZonalBandDomain( const Interval& y ); ZonalBandDomain( const Domain& ); operator bool() { return domain_; } diff --git a/src/atlas/runtime/AtlasTool.cc b/src/atlas/runtime/AtlasTool.cc index a80ed1bb1..64b193cf3 100644 --- a/src/atlas/runtime/AtlasTool.cc +++ b/src/atlas/runtime/AtlasTool.cc @@ -102,7 +102,7 @@ static bool use_logfile; static std::string logfile_name; static std::string workdir; -void atlas_terminate() { +[[noreturn]] void atlas_terminate() { // This routine is called for uncaught exceptions. // It can be set with std::set_terminate( &atlas_terminate ) From 0e3066ffbaf754782b631b2cd6333296931e4e4e Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Fri, 7 Jun 2019 16:31:39 +0000 Subject: [PATCH 08/86] Safety for NodeColumns::sum() --- .../detail/NodeColumns_FieldStatistics.cc | 35 +++++++++++-------- 1 file changed, 21 insertions(+), 14 deletions(-) diff --git a/src/atlas/functionspace/detail/NodeColumns_FieldStatistics.cc b/src/atlas/functionspace/detail/NodeColumns_FieldStatistics.cc index c85870788..b0daae9ed 100644 --- a/src/atlas/functionspace/detail/NodeColumns_FieldStatistics.cc +++ b/src/atlas/functionspace/detail/NodeColumns_FieldStatistics.cc @@ -97,10 +97,11 @@ void dispatch_sum( const NodeColumns& fs, const Field& field, T& result, idx_t& const array::LocalView arr = make_leveled_scalar_view( field ); T local_sum = 0; const idx_t npts = std::min( arr.shape( 0 ), fs.nb_nodes() ); + const idx_t nlev = arr.shape( 1 ); atlas_omp_pragma( omp parallel for default(shared) reduction(+:local_sum) ) for( idx_t n=0; n void dispatch_sum( const NodeColumns& fs, const Field& field, std::vector& result, idx_t& N ) { const array::LocalView arr = make_leveled_view( field ); const mesh::IsGhostNode is_ghost( fs.nodes() ); + const idx_t npts = std::min( arr.shape( 0 ), fs.nb_nodes() ); + const idx_t nlev = arr.shape( 1 ); const idx_t nvar = arr.shape( 2 ); std::vector local_sum( nvar, 0 ); result.resize( nvar ); atlas_omp_parallel { std::vector local_sum_private( nvar, 0 ); - const idx_t npts = arr.shape( 0 ); atlas_omp_for( idx_t n = 0; n < npts; ++n ) { if ( !is_ghost( n ) ) { - for ( idx_t l = 0; l < arr.shape( 1 ); ++l ) { - for ( idx_t j = 0; j < arr.shape( 2 ); ++j ) { + for ( idx_t l = 0; l < nlev; ++l ) { + for ( idx_t j = 0; j < nvar; ++j ) { local_sum_private[j] += arr( n, l, j ); } } @@ -173,7 +175,7 @@ void dispatch_sum( const NodeColumns& fs, const Field& field, std::vector& re ATLAS_TRACE_MPI( ALLREDUCE ) { mpi::comm().allReduce( local_sum, result, eckit::mpi::sum() ); } - N = fs.nb_nodes_global() * arr.shape( 1 ); + N = fs.nb_nodes_global() * nlev; } template @@ -223,6 +225,10 @@ void dispatch_sum_per_level( const NodeColumns& fs, const Field& field, Field& s auto arr = make_leveled_view( field ); + const idx_t npts = std::min( arr.shape( 0 ), fs.nb_nodes() ); + const idx_t nlev = arr.shape( 1 ); + const idx_t nvar = arr.shape( 2 ); + auto sum_per_level = make_per_level_view( sum ); for ( idx_t l = 0; l < sum_per_level.shape( 0 ); ++l ) { @@ -241,11 +247,10 @@ void dispatch_sum_per_level( const NodeColumns& fs, const Field& field, Field& s } } - const idx_t npts = arr.shape( 0 ); atlas_omp_for( idx_t n = 0; n < npts; ++n ) { if ( !is_ghost( n ) ) { - for ( idx_t l = 0; l < arr.shape( 1 ); ++l ) { - for ( idx_t j = 0; j < arr.shape( 2 ); ++j ) { + for ( idx_t l = 0; l < nlev; ++l ) { + for ( idx_t j = 0; j < nvar; ++j ) { sum_per_level_private_view( l, j ) += arr( n, l, j ); } } @@ -381,22 +386,24 @@ void dispatch_order_independent_sum_2d( const NodeColumns& fs, const Field& fiel template void dispatch_order_independent_sum( const NodeColumns& fs, const Field& field, std::vector& result, idx_t& N ) { if ( field.levels() ) { - const idx_t nvar = field.variables(); const auto arr = make_leveled_view( field ); + const idx_t npts = std::min( arr.shape( 0 ), fs.nb_nodes() ); + const idx_t nlev = arr.shape( 1 ); + const idx_t nvar = arr.shape( 2 ); Field surface_field = fs.createField( option::name( "surface" ) | option::variables( nvar ) | option::levels( false ) ); auto surface = make_surface_view( surface_field ); - atlas_omp_for( idx_t n = 0; n < arr.shape( 0 ); ++n ) { - for ( idx_t j = 0; j < arr.shape( 2 ); ++j ) { + atlas_omp_for( idx_t n = 0; n < npts; ++n ) { + for ( idx_t j = 0; j < nvar; ++j ) { surface( n, j ) = 0; } } - for ( idx_t n = 0; n < arr.shape( 0 ); ++n ) { - for ( idx_t l = 0; l < arr.shape( 1 ); ++l ) { - for ( idx_t j = 0; j < arr.shape( 2 ); ++j ) { + for ( idx_t n = 0; n < npts; ++n ) { + for ( idx_t l = 0; l < nlev; ++l ) { + for ( idx_t j = 0; j < nvar; ++j ) { surface( n, j ) += arr( n, l, j ); } } From b80113295535552db89d0f020f987eb977d0e8ad Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Fri, 7 Jun 2019 16:33:23 +0000 Subject: [PATCH 09/86] ATLAS-236 Fix StructuredColumns::create_remote_index() --- .../detail/StructuredColumns_create_remote_index.cc | 8 +++++--- src/atlas/functionspace/detail/StructuredColumns_setup.cc | 3 --- .../method/structured/StructuredInterpolation2D.tcc | 2 +- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/src/atlas/functionspace/detail/StructuredColumns_create_remote_index.cc b/src/atlas/functionspace/detail/StructuredColumns_create_remote_index.cc index f07b00f9e..003cf91f0 100644 --- a/src/atlas/functionspace/detail/StructuredColumns_create_remote_index.cc +++ b/src/atlas/functionspace/detail/StructuredColumns_create_remote_index.cc @@ -106,12 +106,14 @@ void StructuredColumns::create_remote_index() const { std::vector recv_requests( neighbours.size() ); std::vector recv_size( neighbours.size() ); + std::vector send_size( neighbours.size() ); + int tag = 0; ATLAS_TRACE_SCOPE( "send-receive g_per_neighbour size" ) for ( idx_t j = 0; j < nb_neighbours; ++j ) { - idx_t g_per_neighbour_size = static_cast( g_per_neighbour[j].size() ); - send_requests[j] = comm.iSend( g_per_neighbour_size, neighbours[j], tag ); - recv_requests[j] = comm.iReceive( recv_size[j], neighbours[j], tag ); + send_size[j] = static_cast( g_per_neighbour[j].size() ); + send_requests[j] = comm.iSend( send_size[j], neighbours[j], tag ); + recv_requests[j] = comm.iReceive( recv_size[j], neighbours[j], tag ); } ATLAS_TRACE_MPI( WAIT ) { diff --git a/src/atlas/functionspace/detail/StructuredColumns_setup.cc b/src/atlas/functionspace/detail/StructuredColumns_setup.cc index c705db5df..449a879e8 100644 --- a/src/atlas/functionspace/detail/StructuredColumns_setup.cc +++ b/src/atlas/functionspace/detail/StructuredColumns_setup.cc @@ -22,12 +22,9 @@ #include "atlas/grid/StructuredGrid.h" #include "atlas/library/Library.h" #include "atlas/mesh/Mesh.h" -#include "atlas/parallel/Checksum.h" -#include "atlas/parallel/mpi/Statistics.h" #include "atlas/parallel/mpi/mpi.h" #include "atlas/runtime/Exception.h" #include "atlas/runtime/Trace.h" -#include "atlas/util/Checksum.h" #include "atlas/util/CoordinateEnums.h" namespace atlas { diff --git a/src/atlas/interpolation/method/structured/StructuredInterpolation2D.tcc b/src/atlas/interpolation/method/structured/StructuredInterpolation2D.tcc index 457f2bd83..b43aeb6b8 100644 --- a/src/atlas/interpolation/method/structured/StructuredInterpolation2D.tcc +++ b/src/atlas/interpolation/method/structured/StructuredInterpolation2D.tcc @@ -86,7 +86,7 @@ void StructuredInterpolation2D::setup( const FunctionSpace& source, cons target_ghost_ = tgt.ghost(); } else { - ATLAS_NOTIMPLEMENTED; + throw_NotImplemented("Only interpolation to functionspaces NodeColumns, PointCloud or StructuredColumns are implemented", Here()); } setup( source ); From 066326f8a99cbb6a82a40bd5012dc900e2817680 Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Fri, 7 Jun 2019 17:34:37 +0000 Subject: [PATCH 10/86] atlas-run tool to forward MPI behaviour --- CMakeLists.txt | 11 ++++ src/tests/CMakeLists.txt | 3 ++ src/tests/acc/CMakeLists.txt | 2 + src/tests/acceptance_tests/CMakeLists.txt | 8 ++- src/tests/acceptance_tests/compare.cmake | 8 ++- src/tests/field/CMakeLists.txt | 1 + tools/atlas-run | 63 +++++++++++++++++++++++ 7 files changed, 89 insertions(+), 7 deletions(-) create mode 100755 tools/atlas-run diff --git a/CMakeLists.txt b/CMakeLists.txt index 77254af1d..ce89f917c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -240,6 +240,17 @@ ecbuild_add_option( FEATURE SANDBOX DESCRIPTION "Build the sandbox stuff" ) +### use of atlas-run for tests +ecbuild_add_option( FEATURE ATLAS_RUN + DEFAULT OFF + DESCRIPTION "Use atlas/tools/atlas-run to run atlas tests" ) + +if( HAVE_ATLAS_RUN ) + set( MPIEXEC_EXECUTABLE ${CMAKE_CURRENT_SOURCE_DIR}/tools/atlas-run ) + set( MPIEXEC_NUMPROC_FLAG='-n' ) + set( CMAKE_CROSSCOMPILING_EMULATOR ${CMAKE_CURRENT_SOURCE_DIR}/tools/atlas-run ) +endif() + ################################################################################ # sources diff --git a/src/tests/CMakeLists.txt b/src/tests/CMakeLists.txt index 705a39a73..4a6673647 100644 --- a/src/tests/CMakeLists.txt +++ b/src/tests/CMakeLists.txt @@ -68,6 +68,9 @@ macro( atlas_add_cuda_test ) else() add_test ( NAME ${_PAR_TARGET} COMMAND ${_PAR_TARGET} ) endif() + + set_property( TEST ${_PAR_TARGET} APPEND PROPERTY ENVIRONMENT "ATLAS_RUN_NGPUS=1" ) + endif() endmacro() diff --git a/src/tests/acc/CMakeLists.txt b/src/tests/acc/CMakeLists.txt index 1ddee108e..5fccf38c6 100644 --- a/src/tests/acc/CMakeLists.txt +++ b/src/tests/acc/CMakeLists.txt @@ -19,6 +19,7 @@ if( ATLAS_HAVE_GRIDTOOLS_STORAGE AND GRIDTOOLS_HAVE_CUDA AND ENABLE_TESTS AND HA fctest_unified_memory_with_openacc_cxx.cc LIBS atlas_f LINKER_LANGUAGE Fortran + ENVIRONMENT ATLAS_RUN_NGPUS=1 ) target_link_libraries( atlas_test_unified_memory_with_openacc ${ACC_Fortran_FLAGS} gridtools::storage ) @@ -28,6 +29,7 @@ if( ATLAS_HAVE_GRIDTOOLS_STORAGE AND GRIDTOOLS_HAVE_CUDA AND ENABLE_TESTS AND HA SOURCES fctest_connectivity_openacc.F90 LIBS atlas_f LINKER_LANGUAGE Fortran + ENVIRONMENT ATLAS_RUN_NGPUS=1 ) target_link_libraries( atlas_test_connectivity_openacc ${ACC_Fortran_FLAGS} ) set_target_properties( atlas_test_connectivity_openacc PROPERTIES COMPILE_FLAGS "${ACC_Fortran_FLAGS_STR}" ) diff --git a/src/tests/acceptance_tests/CMakeLists.txt b/src/tests/acceptance_tests/CMakeLists.txt index 1916f31a9..36fa208d5 100644 --- a/src/tests/acceptance_tests/CMakeLists.txt +++ b/src/tests/acceptance_tests/CMakeLists.txt @@ -14,15 +14,13 @@ ecbuild_add_executable( if( HAVE_TESTS ) ecbuild_add_option( FEATURE ACCEPTANCE_TESTS DEFAULT OFF ) - - if( HAVE_ACCEPTANCE_TESTS ) - ecbuild_add_option( FEATURE ACCEPTANCE_TESTS_SMALL DEFAULT ON ) - ecbuild_add_option( FEATURE ACCEPTANCE_TESTS_LARGE DEFAULT OFF ) - endif() endif() if( HAVE_ACCEPTANCE_TESTS ) +set( HAVE_ACCEPTANCE_TESTS_SMALL ON ) +set( HAVE_ACCEPTANCE_TESTS_LARGE ON ) + if( TARGET atlas-atest-mgrids ) function( atlas_atest_mgrids category case nprocs ) diff --git a/src/tests/acceptance_tests/compare.cmake b/src/tests/acceptance_tests/compare.cmake index 76524ea9e..e3c420880 100644 --- a/src/tests/acceptance_tests/compare.cmake +++ b/src/tests/acceptance_tests/compare.cmake @@ -23,7 +23,11 @@ message( "Working directory: ${CMAKE_CURRENT_BINARY_DIR}") list( GET FILES 0 ref ) foreach( file ${FILES} ) - if( NOT ${file} STREQUAL ${ref} ) - run_command( ${CMAKE_COMMAND} -E compare_files ${ref} ${file} ) + if( EXISTS ${file} ) + if( NOT ${file} STREQUAL ${ref} ) + run_command( ${CMAKE_COMMAND} -E compare_files ${ref} ${file} ) + endif() + else() + message( STATUS "Skipping ${file} as it does not exist" ) endif() endforeach() diff --git a/src/tests/field/CMakeLists.txt b/src/tests/field/CMakeLists.txt index 0d188fbc6..411520347 100644 --- a/src/tests/field/CMakeLists.txt +++ b/src/tests/field/CMakeLists.txt @@ -40,6 +40,7 @@ if( HAVE_FCTEST ) LINKER_LANGUAGE Fortran SOURCES fctest_field_gpu.F90 external_acc_routine.F90 LIBS atlas_f + ENVIRONMENT ATLAS_RUN_NGPUS=1 ) if( TARGET atlas_fctest_field_device ) diff --git a/tools/atlas-run b/tools/atlas-run new file mode 100755 index 000000000..d1d2e78d2 --- /dev/null +++ b/tools/atlas-run @@ -0,0 +1,63 @@ +#!/bin/bash +set -e + +key="$1" +case $key in + -n|-np) + ATLAS_RUN_NPROCS="$2" + shift # past argument + shift # past value + ;; + *) # unknown option + ;; +esac + +command_exists() { + type "$1" &> /dev/null ; +} + +if [ -n "${ATLAS_RUN_NTHREADS}" ]; then + export OMP_NUM_THREADS=${ATLAS_RUN_NTHREADS} +fi + +if command_exists aprun ; then + LAUNCH=aprun + if [ -z "${ATLAS_RUN_NPROCS}" ]; then + LAUNCH="${LAUNCH} -n 1" + else + LAUNCH="${LAUNCH} -n ${ATLAS_RUN_NPROCS}" + fi + if [ -n "${OMP_NUM_THREADS}" ]; then + LAUNCH="${LAUNCH} -d ${OMP_NUM_THREADS}" + fi + +elif command_exists srun ; then + LAUNCH=srun + if [ -n "${ATLAS_RUN_NGPUS}" ]; then + LAUNCH="${LAUNCH} --gres=gpu:${ATLAS_RUN_NGPUS}" + fi + if [ -z "${ATLAS_RUN_NPROCS}" ]; then + LAUNCH="${LAUNCH} -n 1" + else + LAUNCH="${LAUNCH} -n ${ATLAS_RUN_NPROCS}" + fi + +else + if [[ ${ARCH:-unset} == "cray" ]]; then + module load cray-snplauncher + fi + if [ -z "${ATLAS_RUN_NPROCS}" ]; then + unset LAUNCH + elif command_exists mpirun ; then + LAUNCH="mpirun -np ${ATLAS_RUN_NPROCS}" + elif command_exists mpiexec; then + LAUNCH="mpiexec -n ${ATLAS_RUN_NPROCS}" + else + echo "No MPI driver found (mpirun,mpiexec,aprun,srun)" + exit 1 + fi +fi + +echo + $LAUNCH "$@" +$LAUNCH "$@" + From 3ae7e02d4181adabb21ce8ad33cd4c144e136d98 Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Fri, 14 Jun 2019 18:12:00 +0000 Subject: [PATCH 11/86] Fix tools/atlas-run for PPN nodes --- CMakeLists.txt | 2 +- tools/atlas-run | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ce89f917c..82d387245 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -242,7 +242,7 @@ ecbuild_add_option( FEATURE SANDBOX ### use of atlas-run for tests ecbuild_add_option( FEATURE ATLAS_RUN - DEFAULT OFF + DEFAULT ON DESCRIPTION "Use atlas/tools/atlas-run to run atlas tests" ) if( HAVE_ATLAS_RUN ) diff --git a/tools/atlas-run b/tools/atlas-run index d1d2e78d2..a309f40b2 100755 --- a/tools/atlas-run +++ b/tools/atlas-run @@ -20,7 +20,7 @@ if [ -n "${ATLAS_RUN_NTHREADS}" ]; then export OMP_NUM_THREADS=${ATLAS_RUN_NTHREADS} fi -if command_exists aprun ; then +if command_exists aprun && [[ ${EC_queue:-unset} != "nf" ]] ; then LAUNCH=aprun if [ -z "${ATLAS_RUN_NPROCS}" ]; then LAUNCH="${LAUNCH} -n 1" @@ -44,6 +44,7 @@ elif command_exists srun ; then else if [[ ${ARCH:-unset} == "cray" ]]; then + echo + module load cray-snplauncher module load cray-snplauncher fi if [ -z "${ATLAS_RUN_NPROCS}" ]; then From 0528b66719fcc867c13188b1e78ce8df1a0513a5 Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Fri, 14 Jun 2019 23:39:34 +0100 Subject: [PATCH 12/86] Moved example grids from json to yaml --- doc/example-grids/classic_gaussian_1.json | 6 ------ doc/example-grids/classic_gaussian_1.yml | 2 ++ doc/example-grids/classic_gaussian_2.json | 7 ------- doc/example-grids/classic_gaussian_2.yml | 9 +++++++++ doc/example-grids/classic_gaussian_3.json | 5 ----- doc/example-grids/classic_gaussian_3.yml | 3 +++ .../cropped_classic_gaussian_1.json | 8 -------- .../cropped_classic_gaussian_1.yml | 9 +++++++++ .../cropped_classic_gaussian_2.json | 8 -------- .../cropped_classic_gaussian_2.yml | 12 ++++++++++++ .../cropped_shifted_lonlat_1.json | 6 ------ doc/example-grids/cropped_shifted_lonlat_1.yml | 7 +++++++ doc/example-grids/custom_structured_1.json | 7 ------- doc/example-grids/custom_structured_1.yml | 5 +++++ doc/example-grids/custom_structured_2.json | 7 ------- doc/example-grids/custom_structured_2.yml | 6 ++++++ doc/example-grids/custom_structured_3.json | 16 ---------------- doc/example-grids/custom_structured_3.yml | 14 ++++++++++++++ doc/example-grids/custom_structured_4.json | 18 ------------------ doc/example-grids/custom_structured_4.yml | 15 +++++++++++++++ doc/example-grids/custom_structured_5.json | 8 -------- doc/example-grids/custom_structured_5.yml | 6 ++++++ doc/example-grids/custom_structured_6.json | 18 ------------------ doc/example-grids/custom_structured_6.yml | 15 +++++++++++++++ doc/example-grids/custom_structured_7.json | 7 ------- doc/example-grids/custom_structured_7.yml | 5 +++++ doc/example-grids/octahedral_gaussian_1.json | 6 ------ doc/example-grids/octahedral_gaussian_1.yml | 4 ++++ doc/example-grids/octahedral_gaussian_2.json | 7 ------- doc/example-grids/octahedral_gaussian_2.yml | 6 ++++++ doc/example-grids/octahedral_gaussian_3.json | 5 ----- doc/example-grids/octahedral_gaussian_3.yml | 3 +++ doc/example-grids/octahedral_gaussian_4.json | 6 ------ doc/example-grids/octahedral_gaussian_4.yml | 4 ++++ doc/example-grids/regional_lambert_1.json | 13 ------------- doc/example-grids/regional_lambert_1.yml | 12 ++++++++++++ doc/example-grids/regional_lambert_2.json | 12 ------------ doc/example-grids/regional_lambert_2.yml | 10 ++++++++++ doc/example-grids/regional_lonlat_1.json | 9 --------- doc/example-grids/regional_lonlat_1.yml | 7 +++++++ .../regional_rotated_mercator_1.json | 13 ------------- .../regional_rotated_mercator_1.yml | 9 +++++++++ doc/example-grids/regular_gaussian_1.json | 6 ------ doc/example-grids/regular_gaussian_1.yml | 4 ++++ doc/example-grids/regular_gaussian_2.json | 7 ------- doc/example-grids/regular_gaussian_2.yml | 8 ++++++++ doc/example-grids/regular_gaussian_3.json | 5 ----- doc/example-grids/regular_gaussian_3.yml | 3 +++ doc/example-grids/regular_lonlat_1.yml | 4 ++++ .../shifted_regular_lonlat_1.json | 10 ---------- doc/example-grids/zonal_band_1.json | 7 ------- doc/example-grids/zonal_band_1.yml | 5 +++++ doc/example-grids/zonal_band_2.json | 6 ------ doc/example-grids/zonal_band_2.yml | 4 ++++ doc/example-grids/zonal_band_3.json | 5 ----- doc/example-grids/zonal_band_3.yml | 3 +++ 56 files changed, 194 insertions(+), 238 deletions(-) delete mode 100644 doc/example-grids/classic_gaussian_1.json create mode 100644 doc/example-grids/classic_gaussian_1.yml delete mode 100644 doc/example-grids/classic_gaussian_2.json create mode 100644 doc/example-grids/classic_gaussian_2.yml delete mode 100644 doc/example-grids/classic_gaussian_3.json create mode 100644 doc/example-grids/classic_gaussian_3.yml delete mode 100644 doc/example-grids/cropped_classic_gaussian_1.json create mode 100644 doc/example-grids/cropped_classic_gaussian_1.yml delete mode 100644 doc/example-grids/cropped_classic_gaussian_2.json create mode 100644 doc/example-grids/cropped_classic_gaussian_2.yml delete mode 100644 doc/example-grids/cropped_shifted_lonlat_1.json create mode 100644 doc/example-grids/cropped_shifted_lonlat_1.yml delete mode 100644 doc/example-grids/custom_structured_1.json create mode 100644 doc/example-grids/custom_structured_1.yml delete mode 100644 doc/example-grids/custom_structured_2.json create mode 100644 doc/example-grids/custom_structured_2.yml delete mode 100644 doc/example-grids/custom_structured_3.json create mode 100644 doc/example-grids/custom_structured_3.yml delete mode 100644 doc/example-grids/custom_structured_4.json create mode 100644 doc/example-grids/custom_structured_4.yml delete mode 100644 doc/example-grids/custom_structured_5.json create mode 100644 doc/example-grids/custom_structured_5.yml delete mode 100644 doc/example-grids/custom_structured_6.json create mode 100644 doc/example-grids/custom_structured_6.yml delete mode 100644 doc/example-grids/custom_structured_7.json create mode 100644 doc/example-grids/custom_structured_7.yml delete mode 100644 doc/example-grids/octahedral_gaussian_1.json create mode 100644 doc/example-grids/octahedral_gaussian_1.yml delete mode 100644 doc/example-grids/octahedral_gaussian_2.json create mode 100644 doc/example-grids/octahedral_gaussian_2.yml delete mode 100644 doc/example-grids/octahedral_gaussian_3.json create mode 100644 doc/example-grids/octahedral_gaussian_3.yml delete mode 100644 doc/example-grids/octahedral_gaussian_4.json create mode 100644 doc/example-grids/octahedral_gaussian_4.yml delete mode 100644 doc/example-grids/regional_lambert_1.json create mode 100644 doc/example-grids/regional_lambert_1.yml delete mode 100644 doc/example-grids/regional_lambert_2.json create mode 100644 doc/example-grids/regional_lambert_2.yml delete mode 100644 doc/example-grids/regional_lonlat_1.json create mode 100644 doc/example-grids/regional_lonlat_1.yml delete mode 100644 doc/example-grids/regional_rotated_mercator_1.json create mode 100644 doc/example-grids/regional_rotated_mercator_1.yml delete mode 100644 doc/example-grids/regular_gaussian_1.json create mode 100644 doc/example-grids/regular_gaussian_1.yml delete mode 100644 doc/example-grids/regular_gaussian_2.json create mode 100644 doc/example-grids/regular_gaussian_2.yml delete mode 100644 doc/example-grids/regular_gaussian_3.json create mode 100644 doc/example-grids/regular_gaussian_3.yml create mode 100644 doc/example-grids/regular_lonlat_1.yml delete mode 100644 doc/example-grids/shifted_regular_lonlat_1.json delete mode 100644 doc/example-grids/zonal_band_1.json create mode 100644 doc/example-grids/zonal_band_1.yml delete mode 100644 doc/example-grids/zonal_band_2.json create mode 100644 doc/example-grids/zonal_band_2.yml delete mode 100644 doc/example-grids/zonal_band_3.json create mode 100644 doc/example-grids/zonal_band_3.yml diff --git a/doc/example-grids/classic_gaussian_1.json b/doc/example-grids/classic_gaussian_1.json deleted file mode 100644 index c8283931a..000000000 --- a/doc/example-grids/classic_gaussian_1.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "//" : "Classic Gaussian grid 'N16'", - - "type" : "classic_gaussian", - "N" : 16 -} diff --git a/doc/example-grids/classic_gaussian_1.yml b/doc/example-grids/classic_gaussian_1.yml new file mode 100644 index 000000000..f63895281 --- /dev/null +++ b/doc/example-grids/classic_gaussian_1.yml @@ -0,0 +1,2 @@ +type : "classic_gaussian" +N : 16 diff --git a/doc/example-grids/classic_gaussian_2.json b/doc/example-grids/classic_gaussian_2.json deleted file mode 100644 index 04cb54ede..000000000 --- a/doc/example-grids/classic_gaussian_2.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "//" : "Classic Gaussian grid 'N16'", - - "type" : "classic_gaussian", - "N" : 16, - "projection" : { "type": "rotated_schmidt", "stretching_factor": 2.0, "north_pole": [3.0,47.0] } -} diff --git a/doc/example-grids/classic_gaussian_2.yml b/doc/example-grids/classic_gaussian_2.yml new file mode 100644 index 000000000..27854eaeb --- /dev/null +++ b/doc/example-grids/classic_gaussian_2.yml @@ -0,0 +1,9 @@ +# Classic Gaussian grid 'N16' + +type : "classic_gaussian" +N : 16 +projection : + type : "rotated_schmidt" + stretching_factor : 2.0 + north_pole : [3.0,47.0] + diff --git a/doc/example-grids/classic_gaussian_3.json b/doc/example-grids/classic_gaussian_3.json deleted file mode 100644 index 9569d47ed..000000000 --- a/doc/example-grids/classic_gaussian_3.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "//" : "Classic Gaussian grid 'O16'", - - "name" : "N16" -} diff --git a/doc/example-grids/classic_gaussian_3.yml b/doc/example-grids/classic_gaussian_3.yml new file mode 100644 index 000000000..b957622f9 --- /dev/null +++ b/doc/example-grids/classic_gaussian_3.yml @@ -0,0 +1,3 @@ +# Classic Gaussian grid 'O16' + +name : "N16" diff --git a/doc/example-grids/cropped_classic_gaussian_1.json b/doc/example-grids/cropped_classic_gaussian_1.json deleted file mode 100644 index 7879c5ec9..000000000 --- a/doc/example-grids/cropped_classic_gaussian_1.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "//" : "Classic Gaussian grid 'N16'", - - "type" : "classic_gaussian", - "N" : 16, - - "domain" : { "type": "zonal_band", "ymax": 90, "ymin": 45 } -} diff --git a/doc/example-grids/cropped_classic_gaussian_1.yml b/doc/example-grids/cropped_classic_gaussian_1.yml new file mode 100644 index 000000000..658b14a9b --- /dev/null +++ b/doc/example-grids/cropped_classic_gaussian_1.yml @@ -0,0 +1,9 @@ +# Classic Gaussian grid 'N16' + +type : "classic_gaussian" +N : 16 + +domain : + type : "zonal_band" + ymax : 90 + ymin : 45 diff --git a/doc/example-grids/cropped_classic_gaussian_2.json b/doc/example-grids/cropped_classic_gaussian_2.json deleted file mode 100644 index 434011a81..000000000 --- a/doc/example-grids/cropped_classic_gaussian_2.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "//" : "Classic Gaussian grid 'N16'", - - "type" : "octahedral_gaussian", - "N" : 16, - - "domain" : { "type": "rectangular", "ymax": 45, "ymin": -45, "xmin": 45, "xmax": 90, "units":"degrees" } -} diff --git a/doc/example-grids/cropped_classic_gaussian_2.yml b/doc/example-grids/cropped_classic_gaussian_2.yml new file mode 100644 index 000000000..095c2e36b --- /dev/null +++ b/doc/example-grids/cropped_classic_gaussian_2.yml @@ -0,0 +1,12 @@ +# Classic Gaussian grid 'N16' + +type : "octahedral_gaussian" +N : 16 + +domain: + type : "rectangular" + ymax : 45 + ymin : -45 + xmin : 45 + xmax : 90 + units : "degrees" diff --git a/doc/example-grids/cropped_shifted_lonlat_1.json b/doc/example-grids/cropped_shifted_lonlat_1.json deleted file mode 100644 index 1204299dd..000000000 --- a/doc/example-grids/cropped_shifted_lonlat_1.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "//" : "Shifted lonlat grid 'S45'", - - "name" : "S45", - "domain" : { "type": "zonal_band", "ymax": 90, "ymin": 45 } -} diff --git a/doc/example-grids/cropped_shifted_lonlat_1.yml b/doc/example-grids/cropped_shifted_lonlat_1.yml new file mode 100644 index 000000000..9ddeb41ca --- /dev/null +++ b/doc/example-grids/cropped_shifted_lonlat_1.yml @@ -0,0 +1,7 @@ +# Shifted lonlat grid 'S45' + +name : "S45" +domain : + type : "zonal_band" + ymax : 90 + ymin : 45 diff --git a/doc/example-grids/custom_structured_1.json b/doc/example-grids/custom_structured_1.json deleted file mode 100644 index 47cce301a..000000000 --- a/doc/example-grids/custom_structured_1.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "//" : "Regular lonlat grid 'L4'", - - "type" : "structured", - "yspace" : { "type":"linear", "N":9, "start":90, "end":-90 }, - "xspace" : { "type":"linear", "N":16, "start":0, "end":360, "endpoint":false } -} diff --git a/doc/example-grids/custom_structured_1.yml b/doc/example-grids/custom_structured_1.yml new file mode 100644 index 000000000..e2d9f4743 --- /dev/null +++ b/doc/example-grids/custom_structured_1.yml @@ -0,0 +1,5 @@ +# Regular lonlat grid 'L4' but given in custom manner + +type : "structured" +yspace : { type : "linear", N : 9, start : 90, end : -90 } +xspace : { type : "linear", N : 16, start : 0, end : 360, endpoint : false } diff --git a/doc/example-grids/custom_structured_2.json b/doc/example-grids/custom_structured_2.json deleted file mode 100644 index 22e3fbcd4..000000000 --- a/doc/example-grids/custom_structured_2.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "//" : "Regular Gaussian grid 'F4'", - - "type" : "structured", - "yspace" : { "type":"gaussian", "N":8, "start":90, "end":-90 }, - "xspace" : { "type":"linear", "N":16, "start":0, "end":360, "endpoint":false } -} diff --git a/doc/example-grids/custom_structured_2.yml b/doc/example-grids/custom_structured_2.yml new file mode 100644 index 000000000..ab68e5485 --- /dev/null +++ b/doc/example-grids/custom_structured_2.yml @@ -0,0 +1,6 @@ +# Regular Gaussian grid 'F4' coded in custom way + +type : "structured" +yspace : { type :"gaussian", N : 8, start : 90, end : -90 } +xspace : { type :"linear", N : 16, start : 0, end : 360, endpoint:false } + diff --git a/doc/example-grids/custom_structured_3.json b/doc/example-grids/custom_structured_3.json deleted file mode 100644 index 2c1a3eb08..000000000 --- a/doc/example-grids/custom_structured_3.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "//" : "Octahedral Gaussian grid 'O4'", - - "type" : "structured", - "yspace" : { "type":"gaussian", "N":8, "start":90, "end":-90 }, - "xspace[]" : [ - { "type":"linear", "N":16, "start":0, "end":360, "endpoint":false }, - { "type":"linear", "N":20, "start":0, "end":360, "endpoint":false }, - { "type":"linear", "N":24, "start":0, "end":360, "endpoint":false }, - { "type":"linear", "N":28, "start":0, "end":360, "endpoint":false }, - { "type":"linear", "N":28, "start":0, "end":360, "endpoint":false }, - { "type":"linear", "N":24, "start":0, "end":360, "endpoint":false }, - { "type":"linear", "N":20, "start":0, "end":360, "endpoint":false }, - { "type":"linear", "N":16, "start":0, "end":360, "endpoint":false } - ] -} diff --git a/doc/example-grids/custom_structured_3.yml b/doc/example-grids/custom_structured_3.yml new file mode 100644 index 000000000..b73803cad --- /dev/null +++ b/doc/example-grids/custom_structured_3.yml @@ -0,0 +1,14 @@ +# Octahedral Gaussian grid 'O4' + +type : "structured" +yspace : { type : "gaussian", N :8, start : 90, end : -90 } +xspace[] : + - { type : "linear", N : 16, start : 0, end : 360, endpoint : false } + - { type : "linear", N : 20, start : 0, end : 360, endpoint : false } + - { type : "linear", N : 24, start : 0, end : 360, endpoint : false } + - { type : "linear", N : 28, start : 0, end : 360, endpoint : false } + - { type : "linear", N : 28, start : 0, end : 360, endpoint : false } + - { type : "linear", N : 24, start : 0, end : 360, endpoint : false } + - { type : "linear", N : 20, start : 0, end : 360, endpoint : false } + - { type : "linear", N : 16, start : 0, end : 360, endpoint : false } + diff --git a/doc/example-grids/custom_structured_4.json b/doc/example-grids/custom_structured_4.json deleted file mode 100644 index 0646a164a..000000000 --- a/doc/example-grids/custom_structured_4.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "//" : "Octahedral Gaussian grid 'O4'", - - "type" : "structured", - "yspace" : { "type":"gaussian", "start":90, "end":-90, "N":8 }, - "xspace" : { "type":"linear", "start":0, "end":360, "endpoint":false, - "N[]": [ - 16, - 20, - 24, - 28, - 28, - 24, - 20, - 16 - ] - } -} diff --git a/doc/example-grids/custom_structured_4.yml b/doc/example-grids/custom_structured_4.yml new file mode 100644 index 000000000..06460d485 --- /dev/null +++ b/doc/example-grids/custom_structured_4.yml @@ -0,0 +1,15 @@ +# Octahedral Gaussian grid 'O4' + +type : "structured" +yspace : { type : "gaussian", start : 90, end : -90, N : 8 } +xspace : { type : "linear", start : 0, end : 360, endpoint : false, + N[]: [ + 16, + 20, + 24, + 28, + 28, + 24, + 20, + 16 + ] } diff --git a/doc/example-grids/custom_structured_5.json b/doc/example-grids/custom_structured_5.json deleted file mode 100644 index 984e6402a..000000000 --- a/doc/example-grids/custom_structured_5.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "//": "Rotated lonlat grid 'L4'", - - "type" : "structured", - "yspace" : { "type":"linear", "N":9, "start":90, "end":-90 }, - "xspace" : { "type":"linear", "N":16, "start":0, "end":360, "endpoint":false }, - "projection" : { "type":"rotated_lonlat", "north_pole":[3,40] } -} diff --git a/doc/example-grids/custom_structured_5.yml b/doc/example-grids/custom_structured_5.yml new file mode 100644 index 000000000..2fe02ffb0 --- /dev/null +++ b/doc/example-grids/custom_structured_5.yml @@ -0,0 +1,6 @@ +# Rotated lonlat grid 'L4' + +type : "structured" +yspace : { type : "linear", N : 9, start : 90, end : -90 } +xspace : { type : "linear", N : 16, start : 0 , end : 360 , endpoint : false } +projection : { type : "rotated_lonlat", north_pole :[3,40] } diff --git a/doc/example-grids/custom_structured_6.json b/doc/example-grids/custom_structured_6.json deleted file mode 100644 index 539782404..000000000 --- a/doc/example-grids/custom_structured_6.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "//" : "Octahedral Gaussian grid 'O4'", - - "type" : "structured", - "yspace" : { "type":"gaussian", "start":90, "end":-90, "N":8 }, - "xspace" : { "type":"linear", "N":16, "length":360, "endpoint":false, - "start[]": [ - 0, - -11.25, - 0, - -11.25, - 0, - -11.25, - 0, - -11.25 - ] - } -} diff --git a/doc/example-grids/custom_structured_6.yml b/doc/example-grids/custom_structured_6.yml new file mode 100644 index 000000000..ad106b310 --- /dev/null +++ b/doc/example-grids/custom_structured_6.yml @@ -0,0 +1,15 @@ +# Octahedral Gaussian grid 'O4' + +type : "structured", +yspace : { type : "gaussian", start : 90, end : -90, N : 8 }, +xspace : { type : "linear", N : 16, length : 360, endpoint : false, + start[]: [ + 0, + -11.25, + 0, + -11.25, + 0, + -11.25, + 0, + -11.25 + ] } diff --git a/doc/example-grids/custom_structured_7.json b/doc/example-grids/custom_structured_7.json deleted file mode 100644 index 9155a4d93..000000000 --- a/doc/example-grids/custom_structured_7.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "//" : "Shifted lat grid 'Slat3'", - - "type" : "structured", - "yspace" : { "type":"custom", "N":6, "values":[75,45,15,-15,-45,-75], "interval":[-90,90] }, - "xspace" : { "type":"linear", "N":12, "start":0, "end":360, "endpoint":false } -} diff --git a/doc/example-grids/custom_structured_7.yml b/doc/example-grids/custom_structured_7.yml new file mode 100644 index 000000000..6681a763e --- /dev/null +++ b/doc/example-grids/custom_structured_7.yml @@ -0,0 +1,5 @@ +# Shifted lat grid 'Slat3' + +type : "structured" +yspace : { type: custom, N : 6, values : [75,45,15,-15,-45,-75], interval:[-90,90] } +xspace : { type: linear, N : 12, start:0, end:360, endpoint:false } diff --git a/doc/example-grids/octahedral_gaussian_1.json b/doc/example-grids/octahedral_gaussian_1.json deleted file mode 100644 index 6319f4570..000000000 --- a/doc/example-grids/octahedral_gaussian_1.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "//" : "Octahedral Gaussian grid 'O16'", - - "type" : "octahedral_gaussian", - "N" : 16 -} diff --git a/doc/example-grids/octahedral_gaussian_1.yml b/doc/example-grids/octahedral_gaussian_1.yml new file mode 100644 index 000000000..81c7443e0 --- /dev/null +++ b/doc/example-grids/octahedral_gaussian_1.yml @@ -0,0 +1,4 @@ +# Octahedral Gaussian grid 'O16' + +type : "octahedral_gaussian" +N : 16 diff --git a/doc/example-grids/octahedral_gaussian_2.json b/doc/example-grids/octahedral_gaussian_2.json deleted file mode 100644 index 55588bbd3..000000000 --- a/doc/example-grids/octahedral_gaussian_2.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "//" : "Octahedral Gaussian grid 'N16'", - - "type" : "octahedral_gaussian", - "N" : 16, - "projection" : { "type": "rotated_schmidt", "stretching_factor": 4.0, "north_pole": [3.0,47.0] } -} diff --git a/doc/example-grids/octahedral_gaussian_2.yml b/doc/example-grids/octahedral_gaussian_2.yml new file mode 100644 index 000000000..71aaffdcf --- /dev/null +++ b/doc/example-grids/octahedral_gaussian_2.yml @@ -0,0 +1,6 @@ +# Octahedral Gaussian grid 'N16' + +type : "octahedral_gaussian" +N : 16 +projection : { type: "rotated_schmidt", stretching_factor : 4.0, north_pole : [3.0,47.0] } + diff --git a/doc/example-grids/octahedral_gaussian_3.json b/doc/example-grids/octahedral_gaussian_3.json deleted file mode 100644 index 861cac459..000000000 --- a/doc/example-grids/octahedral_gaussian_3.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "//" : "Octahedral Gaussian grid 'O16'", - - "name" : "O16" -} diff --git a/doc/example-grids/octahedral_gaussian_3.yml b/doc/example-grids/octahedral_gaussian_3.yml new file mode 100644 index 000000000..e26bddbb4 --- /dev/null +++ b/doc/example-grids/octahedral_gaussian_3.yml @@ -0,0 +1,3 @@ +# Octahedral Gaussian grid 'O16' + +name : "O16" diff --git a/doc/example-grids/octahedral_gaussian_4.json b/doc/example-grids/octahedral_gaussian_4.json deleted file mode 100644 index 37a42e402..000000000 --- a/doc/example-grids/octahedral_gaussian_4.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "//" : "Octahedral Gaussian grid 'O16'", - - "name" : "O16", - "projection" : { "type": "rotated_schmidt", "stretching_factor": 4.0, "north_pole": [3.0,47.0] } -} diff --git a/doc/example-grids/octahedral_gaussian_4.yml b/doc/example-grids/octahedral_gaussian_4.yml new file mode 100644 index 000000000..0b03a314a --- /dev/null +++ b/doc/example-grids/octahedral_gaussian_4.yml @@ -0,0 +1,4 @@ +# Octahedral Gaussian grid 'O16' + +name : "O16" +projection : { type: "rotated_schmidt", stretching_factor: 4.0, north_pole: [3.0,47.0] } diff --git a/doc/example-grids/regional_lambert_1.json b/doc/example-grids/regional_lambert_1.json deleted file mode 100644 index c6b64e5e3..000000000 --- a/doc/example-grids/regional_lambert_1.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "type" : "regional", - "nx" : 50, - "ny" : 40, - "dx" : 50000, - "dy" : 50000, - "lonlat(centre)" : [4,50], - "projection" : { - "type" : "lambert", - "latitude1" : 50, - "longitude0" : 4 - } -} diff --git a/doc/example-grids/regional_lambert_1.yml b/doc/example-grids/regional_lambert_1.yml new file mode 100644 index 000000000..6544f640f --- /dev/null +++ b/doc/example-grids/regional_lambert_1.yml @@ -0,0 +1,12 @@ +type : "regional" +nx : 50 +ny : 40 +dx : 50000 +dy : 50000 +lonlat(centre) : [4,50] +projection : { + type : "lambert", + latitude1 : 50, + longitude0 : 4 + } + diff --git a/doc/example-grids/regional_lambert_2.json b/doc/example-grids/regional_lambert_2.json deleted file mode 100644 index a4502a554..000000000 --- a/doc/example-grids/regional_lambert_2.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "type" : "regional", - "nx" : 451, - "ny" : 337, - "dx" : 13545, - "dy" : 13545, - "lonlat(xmin,ymin)": [-126.138,16.281], - "projection" : { "type" : "lambert", - "latitude1" : 25, - "longitude0" : -95 - } -} \ No newline at end of file diff --git a/doc/example-grids/regional_lambert_2.yml b/doc/example-grids/regional_lambert_2.yml new file mode 100644 index 000000000..0324a3e1a --- /dev/null +++ b/doc/example-grids/regional_lambert_2.yml @@ -0,0 +1,10 @@ +type : "regional" +nx : 451 +ny : 337 +dx : 13545.0 +dy : 13545.0 +lonlat(xmin,ymin): [-126.138,16.281] +projection : + type : "lambert" + latitude1 : 25.0 + longitude0 : -95.0 \ No newline at end of file diff --git a/doc/example-grids/regional_lonlat_1.json b/doc/example-grids/regional_lonlat_1.json deleted file mode 100644 index fb11fef00..000000000 --- a/doc/example-grids/regional_lonlat_1.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "type" : "regional", - "nx" : 35, - "ny" : 25, - "north" : -10, - "south" : -50, - "east" : 170, - "west" : 100 -} \ No newline at end of file diff --git a/doc/example-grids/regional_lonlat_1.yml b/doc/example-grids/regional_lonlat_1.yml new file mode 100644 index 000000000..61c894c89 --- /dev/null +++ b/doc/example-grids/regional_lonlat_1.yml @@ -0,0 +1,7 @@ +type : "regional" +nx : 35 +ny : 25 +north : -10 +south : -50 +east : 170 +west : 100 diff --git a/doc/example-grids/regional_rotated_mercator_1.json b/doc/example-grids/regional_rotated_mercator_1.json deleted file mode 100644 index e9df2e872..000000000 --- a/doc/example-grids/regional_rotated_mercator_1.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "type" : "regional", - "nx" : 50, - "ny" : 40, - "dx" : 50000, - "dy" : 50000, - "lonlat(centre)" : [4,50], - "projection" : { - "type" : "rotated_mercator", - "north_pole" : [-176,40] - } -} - diff --git a/doc/example-grids/regional_rotated_mercator_1.yml b/doc/example-grids/regional_rotated_mercator_1.yml new file mode 100644 index 000000000..f30445efe --- /dev/null +++ b/doc/example-grids/regional_rotated_mercator_1.yml @@ -0,0 +1,9 @@ +type : "regional" +nx : 50 +ny : 40 +dx : 50000 +dy : 50000 +lonlat(centre) : [4,50] +projection : + type : "rotated_mercator" + north_pole : [-176,40] diff --git a/doc/example-grids/regular_gaussian_1.json b/doc/example-grids/regular_gaussian_1.json deleted file mode 100644 index 44fd4eee4..000000000 --- a/doc/example-grids/regular_gaussian_1.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "//" : "Regular Gaussian grid 'F4'", - - "type" : "regular_gaussian", - "N" : 4 -} diff --git a/doc/example-grids/regular_gaussian_1.yml b/doc/example-grids/regular_gaussian_1.yml new file mode 100644 index 000000000..dc9b50cb2 --- /dev/null +++ b/doc/example-grids/regular_gaussian_1.yml @@ -0,0 +1,4 @@ +# Regular Gaussian grid 'F4' + +type : "regular_gaussian" +N : 4 diff --git a/doc/example-grids/regular_gaussian_2.json b/doc/example-grids/regular_gaussian_2.json deleted file mode 100644 index 3c0e643b3..000000000 --- a/doc/example-grids/regular_gaussian_2.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "//" : "Regular Gaussian grid 'F4'", - - "type" : "regular_gaussian", - "N" : 4, - "projection" : { "type": "rotated_schmidt", "stretching_factor": 2.0, "north_pole": [3.0,47.0] } -} diff --git a/doc/example-grids/regular_gaussian_2.yml b/doc/example-grids/regular_gaussian_2.yml new file mode 100644 index 000000000..5f0c4d63c --- /dev/null +++ b/doc/example-grids/regular_gaussian_2.yml @@ -0,0 +1,8 @@ +# Regular Gaussian grid 'F4' + +type : "regular_gaussian" +N : 4 +projection : + type : "rotated_schmidt" + stretching_factor : 2.0 + north_pole : [3.0,47.0] diff --git a/doc/example-grids/regular_gaussian_3.json b/doc/example-grids/regular_gaussian_3.json deleted file mode 100644 index 0b0be4f5d..000000000 --- a/doc/example-grids/regular_gaussian_3.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "//" : "Regular Gaussian grid 'F4'", - - "name" : "F4" -} diff --git a/doc/example-grids/regular_gaussian_3.yml b/doc/example-grids/regular_gaussian_3.yml new file mode 100644 index 000000000..ebe37c224 --- /dev/null +++ b/doc/example-grids/regular_gaussian_3.yml @@ -0,0 +1,3 @@ +# Regular Gaussian grid 'F4' +name : "F4" + diff --git a/doc/example-grids/regular_lonlat_1.yml b/doc/example-grids/regular_lonlat_1.yml new file mode 100644 index 000000000..2332e7924 --- /dev/null +++ b/doc/example-grids/regular_lonlat_1.yml @@ -0,0 +1,4 @@ +# Regular lonlat +type : "regular_lonlat" +nx : 128 +ny : 65 diff --git a/doc/example-grids/shifted_regular_lonlat_1.json b/doc/example-grids/shifted_regular_lonlat_1.json deleted file mode 100644 index 033bb4bda..000000000 --- a/doc/example-grids/shifted_regular_lonlat_1.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "//" : "Shifted lonlat grid 'S45'", - - "name" : "L4", - "!domain" : { "type": "zonal_band", "ymax": 90, "ymin": 45 }, - "projection" : { - "type" : "shifted_lonlat", - "shift" : [-180,0] - } -} diff --git a/doc/example-grids/zonal_band_1.json b/doc/example-grids/zonal_band_1.json deleted file mode 100644 index ac63ff91b..000000000 --- a/doc/example-grids/zonal_band_1.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "type" : "zonal_band", - "nx" : 5, - "ny" : 3, - "north" : 70, - "south" : 30 -} \ No newline at end of file diff --git a/doc/example-grids/zonal_band_1.yml b/doc/example-grids/zonal_band_1.yml new file mode 100644 index 000000000..38a9dbf12 --- /dev/null +++ b/doc/example-grids/zonal_band_1.yml @@ -0,0 +1,5 @@ +type : "zonal_band" +nx : 5 +ny : 3 +north : 70 +south : 30 \ No newline at end of file diff --git a/doc/example-grids/zonal_band_2.json b/doc/example-grids/zonal_band_2.json deleted file mode 100644 index 62c28cb36..000000000 --- a/doc/example-grids/zonal_band_2.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "type" : "zonal_band", - "nx" : 36, - "ny" : 7, - "south" : 30 -} diff --git a/doc/example-grids/zonal_band_2.yml b/doc/example-grids/zonal_band_2.yml new file mode 100644 index 000000000..98a32a216 --- /dev/null +++ b/doc/example-grids/zonal_band_2.yml @@ -0,0 +1,4 @@ +type : "zonal_band" +nx : 36 +ny : 7 +south : 30 diff --git a/doc/example-grids/zonal_band_3.json b/doc/example-grids/zonal_band_3.json deleted file mode 100644 index 6cb30f304..000000000 --- a/doc/example-grids/zonal_band_3.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "type" : "zonal_band", - "nx" : 36, - "ny" : 19 -} diff --git a/doc/example-grids/zonal_band_3.yml b/doc/example-grids/zonal_band_3.yml new file mode 100644 index 000000000..fb16ec81e --- /dev/null +++ b/doc/example-grids/zonal_band_3.yml @@ -0,0 +1,3 @@ +type : "zonal_band" +nx : 36 +ny : 19 From 933d2cc25eb40dcbff17861d0e4666863c138fbe Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Mon, 17 Jun 2019 13:36:20 +0100 Subject: [PATCH 13/86] Allow StructuredGrid::lonlat() iterator --- src/atlas/grid/StructuredGrid.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/atlas/grid/StructuredGrid.h b/src/atlas/grid/StructuredGrid.h index 38b239643..fcb12d660 100644 --- a/src/atlas/grid/StructuredGrid.h +++ b/src/atlas/grid/StructuredGrid.h @@ -83,6 +83,7 @@ class StructuredGrid : public Grid { using Grid::xy; void xy( idx_t i, idx_t j, double xy[] ) const { grid_->xy( i, j, xy ); } + using Grid::lonlat; void lonlat( idx_t i, idx_t j, double lonlat[] ) const { grid_->lonlat( i, j, lonlat ); } PointXY xy( idx_t i, idx_t j ) const { return PointXY( x( i, j ), y( j ) ); } From 09138a69b25d5f19846d4a04fc96673db11c2108 Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Tue, 18 Jun 2019 10:09:37 +0100 Subject: [PATCH 14/86] Implement checks for example grids --- doc/example-grids/classic_gaussian_1.yml | 6 + doc/example-grids/classic_gaussian_2.yml | 6 + doc/example-grids/classic_gaussian_3.yml | 6 + .../cropped_classic_gaussian_1.yml | 7 + .../cropped_classic_gaussian_2.yml | 8 + .../cropped_shifted_lonlat_1.yml | 7 + doc/example-grids/custom_structured_1.yml | 7 + doc/example-grids/custom_structured_2.yml | 6 + doc/example-grids/custom_structured_3.yml | 10 +- doc/example-grids/custom_structured_4.yml | 16 +- doc/example-grids/custom_structured_5.yml | 7 + doc/example-grids/custom_structured_6.yml | 14 +- doc/example-grids/custom_structured_7.yml | 6 + doc/example-grids/octahedral_gaussian_1.yml | 7 + doc/example-grids/octahedral_gaussian_2.yml | 6 + doc/example-grids/octahedral_gaussian_3.yml | 7 + doc/example-grids/octahedral_gaussian_4.yml | 7 + doc/example-grids/regional_lambert_1.yml | 7 + doc/example-grids/regional_lambert_2.yml | 10 +- doc/example-grids/regional_lonlat_1.yml | 8 + .../regional_rotated_mercator_1.yml | 8 + doc/example-grids/regular_gaussian_1.yml | 7 + doc/example-grids/regular_gaussian_2.yml | 7 + doc/example-grids/regular_gaussian_3.yml | 6 + doc/example-grids/regular_gaussian_4.yml | 11 ++ doc/example-grids/regular_lonlat_1.yml | 7 + doc/example-grids/zonal_band_1.yml | 8 +- doc/example-grids/zonal_band_2.yml | 8 + doc/example-grids/zonal_band_3.yml | 7 + src/apps/atlas-grids.cc | 184 ++++++++++++++---- src/atlas/grid/detail/grid/Regional.cc | 7 +- src/tests/projection/test_projection_LAEA.cc | 2 +- 32 files changed, 367 insertions(+), 53 deletions(-) create mode 100644 doc/example-grids/regular_gaussian_4.yml diff --git a/doc/example-grids/classic_gaussian_1.yml b/doc/example-grids/classic_gaussian_1.yml index f63895281..8f5aeb9c8 100644 --- a/doc/example-grids/classic_gaussian_1.yml +++ b/doc/example-grids/classic_gaussian_1.yml @@ -1,2 +1,8 @@ type : "classic_gaussian" N : 16 + +check : + size : 1688 + lonlat(first) : [0,85.7606] + lonlat(last) : [342,-85.7606] + uid : 7ad37fdbeaf287838c9396a5b857ccc7 \ No newline at end of file diff --git a/doc/example-grids/classic_gaussian_2.yml b/doc/example-grids/classic_gaussian_2.yml index 27854eaeb..5189bb8db 100644 --- a/doc/example-grids/classic_gaussian_2.yml +++ b/doc/example-grids/classic_gaussian_2.yml @@ -7,3 +7,9 @@ projection : stretching_factor : 2.0 north_pole : [3.0,47.0] + +check : + size : 1688 + lonlat(first) : [3,44.8796] + lonlat(last) : [-172.453,-54.9736] + uid : f0caeff347f57954191e8e1d7b3a05b6 \ No newline at end of file diff --git a/doc/example-grids/classic_gaussian_3.yml b/doc/example-grids/classic_gaussian_3.yml index b957622f9..07eae3a69 100644 --- a/doc/example-grids/classic_gaussian_3.yml +++ b/doc/example-grids/classic_gaussian_3.yml @@ -1,3 +1,9 @@ # Classic Gaussian grid 'O16' name : "N16" + +check : + size : 1688 + lonlat(first) : [0,85.7606] + lonlat(last) : [342,-85.7606] + uid : 7ad37fdbeaf287838c9396a5b857ccc7 \ No newline at end of file diff --git a/doc/example-grids/cropped_classic_gaussian_1.yml b/doc/example-grids/cropped_classic_gaussian_1.yml index 658b14a9b..202e364e5 100644 --- a/doc/example-grids/cropped_classic_gaussian_1.yml +++ b/doc/example-grids/cropped_classic_gaussian_1.yml @@ -7,3 +7,10 @@ domain : type : "zonal_band" ymax : 90 ymin : 45 + + +check : + size : 332 + lonlat(first) : [0,85.7606] + lonlat(last) : [354,47.0696] + uid : 6e7924fd98acefc8b163941796739636 \ No newline at end of file diff --git a/doc/example-grids/cropped_classic_gaussian_2.yml b/doc/example-grids/cropped_classic_gaussian_2.yml index 095c2e36b..99568faaa 100644 --- a/doc/example-grids/cropped_classic_gaussian_2.yml +++ b/doc/example-grids/cropped_classic_gaussian_2.yml @@ -10,3 +10,11 @@ domain: xmin : 45 xmax : 90 units : "degrees" + + +check : + size : 144 + lonlat(first) : [48.4615,41.5325] + lonlat(last) : [90,-41.5325] + uid : a6bef73fef7e852af21a61421d425583 + \ No newline at end of file diff --git a/doc/example-grids/cropped_shifted_lonlat_1.yml b/doc/example-grids/cropped_shifted_lonlat_1.yml index 9ddeb41ca..576a3939a 100644 --- a/doc/example-grids/cropped_shifted_lonlat_1.yml +++ b/doc/example-grids/cropped_shifted_lonlat_1.yml @@ -5,3 +5,10 @@ domain : type : "zonal_band" ymax : 90 ymin : 45 + + +check : + size : 4140 + lonlat(first) : [1,89] + lonlat(last) : [359,45] + uid : 9ada69c9f3b78c1bd81e8883df522d0a \ No newline at end of file diff --git a/doc/example-grids/custom_structured_1.yml b/doc/example-grids/custom_structured_1.yml index e2d9f4743..dc06f880c 100644 --- a/doc/example-grids/custom_structured_1.yml +++ b/doc/example-grids/custom_structured_1.yml @@ -3,3 +3,10 @@ type : "structured" yspace : { type : "linear", N : 9, start : 90, end : -90 } xspace : { type : "linear", N : 16, start : 0, end : 360, endpoint : false } + + +check : + size : 144 + lonlat(first) : [0,90] + lonlat(last) : [337.5,-90] + uid : 302566694eed4568a78d3904e9eca6a6 \ No newline at end of file diff --git a/doc/example-grids/custom_structured_2.yml b/doc/example-grids/custom_structured_2.yml index ab68e5485..8d21d94bf 100644 --- a/doc/example-grids/custom_structured_2.yml +++ b/doc/example-grids/custom_structured_2.yml @@ -4,3 +4,9 @@ type : "structured" yspace : { type :"gaussian", N : 8, start : 90, end : -90 } xspace : { type :"linear", N : 16, start : 0, end : 360, endpoint:false } + +check : + size : 128 + lonlat(first) : [0,73.7992] + lonlat(last) : [337.5,-73.7992] + uid : 1afa743f953ef3b1c628163029a8d612 \ No newline at end of file diff --git a/doc/example-grids/custom_structured_3.yml b/doc/example-grids/custom_structured_3.yml index b73803cad..f8683cb88 100644 --- a/doc/example-grids/custom_structured_3.yml +++ b/doc/example-grids/custom_structured_3.yml @@ -3,12 +3,18 @@ type : "structured" yspace : { type : "gaussian", N :8, start : 90, end : -90 } xspace[] : - - { type : "linear", N : 16, start : 0, end : 360, endpoint : false } - { type : "linear", N : 20, start : 0, end : 360, endpoint : false } - { type : "linear", N : 24, start : 0, end : 360, endpoint : false } - { type : "linear", N : 28, start : 0, end : 360, endpoint : false } + - { type : "linear", N : 32, start : 0, end : 360, endpoint : false } + - { type : "linear", N : 32, start : 0, end : 360, endpoint : false } - { type : "linear", N : 28, start : 0, end : 360, endpoint : false } - { type : "linear", N : 24, start : 0, end : 360, endpoint : false } - { type : "linear", N : 20, start : 0, end : 360, endpoint : false } - - { type : "linear", N : 16, start : 0, end : 360, endpoint : false } + +check : + size : 208 + lonlat(first) : [0,73.7992] + lonlat(last) : [342,-73.7992] + uid : 662bfa00f7e6e928b2ffeb10726604ef \ No newline at end of file diff --git a/doc/example-grids/custom_structured_4.yml b/doc/example-grids/custom_structured_4.yml index 06460d485..60ee22bb6 100644 --- a/doc/example-grids/custom_structured_4.yml +++ b/doc/example-grids/custom_structured_4.yml @@ -1,15 +1,21 @@ # Octahedral Gaussian grid 'O4' type : "structured" -yspace : { type : "gaussian", start : 90, end : -90, N : 8 } -xspace : { type : "linear", start : 0, end : 360, endpoint : false, +yspace : { type : "gaussian", N : 8 } +xspace : { type : "linear", start : 0, length : 360, endpoint : false, N[]: [ - 16, 20, 24, 28, + 32, + 32, 28, 24, - 20, - 16 + 20 ] } + +check : + size : 208 + lonlat(first) : [0,73.7992] + lonlat(last) : [342,-73.7992] + uid : 662bfa00f7e6e928b2ffeb10726604ef \ No newline at end of file diff --git a/doc/example-grids/custom_structured_5.yml b/doc/example-grids/custom_structured_5.yml index 2fe02ffb0..a38339103 100644 --- a/doc/example-grids/custom_structured_5.yml +++ b/doc/example-grids/custom_structured_5.yml @@ -4,3 +4,10 @@ type : "structured" yspace : { type : "linear", N : 9, start : 90, end : -90 } xspace : { type : "linear", N : 16, start : 0 , end : 360 , endpoint : false } projection : { type : "rotated_lonlat", north_pole :[3,40] } + + +check : + size : 144 + lonlat(first) : [3,40] + lonlat(last) : [-177,-40] + uid : 7f70607c136c64cc9c756ea5addc261e \ No newline at end of file diff --git a/doc/example-grids/custom_structured_6.yml b/doc/example-grids/custom_structured_6.yml index ad106b310..c67137056 100644 --- a/doc/example-grids/custom_structured_6.yml +++ b/doc/example-grids/custom_structured_6.yml @@ -1,7 +1,7 @@ -# Octahedral Gaussian grid 'O4' +# Zigzag Gaussian grid (N=8) -type : "structured", -yspace : { type : "gaussian", start : 90, end : -90, N : 8 }, +type : "structured" +yspace : { type : "gaussian", start : 90, end : -90, N : 8 } xspace : { type : "linear", N : 16, length : 360, endpoint : false, start[]: [ 0, @@ -13,3 +13,11 @@ xspace : { type : "linear", N : 16, length : 360, endpoint : false, 0, -11.25 ] } + + +# Expected +check: + size : 128 + lonlat(first) : [0,73.7992] + lonlat(last) : [326.25,-73.7992] + uid : e975c4aa4103780e461407a20d1b5a62 \ No newline at end of file diff --git a/doc/example-grids/custom_structured_7.yml b/doc/example-grids/custom_structured_7.yml index 6681a763e..4b884075f 100644 --- a/doc/example-grids/custom_structured_7.yml +++ b/doc/example-grids/custom_structured_7.yml @@ -3,3 +3,9 @@ type : "structured" yspace : { type: custom, N : 6, values : [75,45,15,-15,-45,-75], interval:[-90,90] } xspace : { type: linear, N : 12, start:0, end:360, endpoint:false } + +check : + size : 72 + lonlat(first) : [0,75] + lonlat(last) : [330,-75] + uid : 088f8c4b8acca09987e4b8c0b0dad2c3 \ No newline at end of file diff --git a/doc/example-grids/octahedral_gaussian_1.yml b/doc/example-grids/octahedral_gaussian_1.yml index 81c7443e0..0767d602c 100644 --- a/doc/example-grids/octahedral_gaussian_1.yml +++ b/doc/example-grids/octahedral_gaussian_1.yml @@ -2,3 +2,10 @@ type : "octahedral_gaussian" N : 16 + + +check : + size : 1600 + lonlat(first) : [0,85.7606] + lonlat(last) : [342,-85.7606] + uid : 00b0d36c51c046c2cce8fe51e37bdc63 \ No newline at end of file diff --git a/doc/example-grids/octahedral_gaussian_2.yml b/doc/example-grids/octahedral_gaussian_2.yml index 71aaffdcf..6253bfe04 100644 --- a/doc/example-grids/octahedral_gaussian_2.yml +++ b/doc/example-grids/octahedral_gaussian_2.yml @@ -4,3 +4,9 @@ type : "octahedral_gaussian" N : 16 projection : { type: "rotated_schmidt", stretching_factor : 4.0, north_pole : [3.0,47.0] } + +check : + size : 1600 + lonlat(first) : [3,45.9397] + lonlat(last) : [-165.776,-62.6128] + uid : 4978cdc0774cb3a27407591e79b4188c \ No newline at end of file diff --git a/doc/example-grids/octahedral_gaussian_3.yml b/doc/example-grids/octahedral_gaussian_3.yml index e26bddbb4..3994470d0 100644 --- a/doc/example-grids/octahedral_gaussian_3.yml +++ b/doc/example-grids/octahedral_gaussian_3.yml @@ -1,3 +1,10 @@ # Octahedral Gaussian grid 'O16' name : "O16" + + +check : + size : 1600 + lonlat(first) : [0,85.7606] + lonlat(last) : [342,-85.7606] + uid : 00b0d36c51c046c2cce8fe51e37bdc63 \ No newline at end of file diff --git a/doc/example-grids/octahedral_gaussian_4.yml b/doc/example-grids/octahedral_gaussian_4.yml index 0b03a314a..c5cddae3f 100644 --- a/doc/example-grids/octahedral_gaussian_4.yml +++ b/doc/example-grids/octahedral_gaussian_4.yml @@ -2,3 +2,10 @@ name : "O16" projection : { type: "rotated_schmidt", stretching_factor: 4.0, north_pole: [3.0,47.0] } + + +check : + size : 1600 + lonlat(first) : [3,45.9397] + lonlat(last) : [-165.776,-62.6128] + uid : 4978cdc0774cb3a27407591e79b4188c \ No newline at end of file diff --git a/doc/example-grids/regional_lambert_1.yml b/doc/example-grids/regional_lambert_1.yml index 6544f640f..82d8c3ab7 100644 --- a/doc/example-grids/regional_lambert_1.yml +++ b/doc/example-grids/regional_lambert_1.yml @@ -10,3 +10,10 @@ projection : { longitude0 : 4 } +y_numbering : +1 + +check : + size : 2000 + lonlat(first) : [-10.3173,40.22] + lonlat(last) : [24.4368,57.2335] + uid : 0ab14f4f37966a6760d0f5ee9176ad48 \ No newline at end of file diff --git a/doc/example-grids/regional_lambert_2.yml b/doc/example-grids/regional_lambert_2.yml index 0324a3e1a..05c4ae391 100644 --- a/doc/example-grids/regional_lambert_2.yml +++ b/doc/example-grids/regional_lambert_2.yml @@ -7,4 +7,12 @@ lonlat(xmin,ymin): [-126.138,16.281] projection : type : "lambert" latitude1 : 25.0 - longitude0 : -95.0 \ No newline at end of file + longitude0 : -95.0 +y_numbering : +1 + + +check : + size : 151987 + lonlat(first) : [-126.138,16.281] + lonlat(last) : [-57.3811,55.4813] + uid : cd7e504a256290ca525b4dec75550d7a \ No newline at end of file diff --git a/doc/example-grids/regional_lonlat_1.yml b/doc/example-grids/regional_lonlat_1.yml index 61c894c89..697aa1bce 100644 --- a/doc/example-grids/regional_lonlat_1.yml +++ b/doc/example-grids/regional_lonlat_1.yml @@ -5,3 +5,11 @@ north : -10 south : -50 east : 170 west : 100 + +y_numbering: +1 + +check : + size : 875 + lonlat(first) : [100,-50] + lonlat(last) : [170,-10] + uid : 4e4386c0a0f4aafc12fd45843aee9071 \ No newline at end of file diff --git a/doc/example-grids/regional_rotated_mercator_1.yml b/doc/example-grids/regional_rotated_mercator_1.yml index f30445efe..130a58c47 100644 --- a/doc/example-grids/regional_rotated_mercator_1.yml +++ b/doc/example-grids/regional_rotated_mercator_1.yml @@ -7,3 +7,11 @@ lonlat(centre) : [4,50] projection : type : "rotated_mercator" north_pole : [-176,40] + +y_numbering : +1 + +check : + size : 2000 + lonlat(first) : [-10.319,40.2109] + lonlat(last) : [24.4206,57.2263] + uid : 06b876b7f9968628a11910e8e9a381bf \ No newline at end of file diff --git a/doc/example-grids/regular_gaussian_1.yml b/doc/example-grids/regular_gaussian_1.yml index dc9b50cb2..b9a504ee3 100644 --- a/doc/example-grids/regular_gaussian_1.yml +++ b/doc/example-grids/regular_gaussian_1.yml @@ -2,3 +2,10 @@ type : "regular_gaussian" N : 4 + + +check : + size : 128 + lonlat(first) : [0,73.7992] + lonlat(last) : [337.5,-73.7992] + uid : 1afa743f953ef3b1c628163029a8d612 \ No newline at end of file diff --git a/doc/example-grids/regular_gaussian_2.yml b/doc/example-grids/regular_gaussian_2.yml index 5f0c4d63c..aa0f993e9 100644 --- a/doc/example-grids/regular_gaussian_2.yml +++ b/doc/example-grids/regular_gaussian_2.yml @@ -6,3 +6,10 @@ projection : type : "rotated_schmidt" stretching_factor : 2.0 north_pole : [3.0,47.0] + + +check : + size : 128 + lonlat(first) : [3,38.8589] + lonlat(last) : [-135.011,-72.4668] + uid : f744facfd6b8ae49384ed48b0495d6dd \ No newline at end of file diff --git a/doc/example-grids/regular_gaussian_3.yml b/doc/example-grids/regular_gaussian_3.yml index ebe37c224..64e9cef17 100644 --- a/doc/example-grids/regular_gaussian_3.yml +++ b/doc/example-grids/regular_gaussian_3.yml @@ -1,3 +1,9 @@ # Regular Gaussian grid 'F4' name : "F4" + +check: + size : 128 + lonlat(first) : [0,73.7992] + lonlat(last) : [337.5,-73.7992] + uid : 1afa743f953ef3b1c628163029a8d612 \ No newline at end of file diff --git a/doc/example-grids/regular_gaussian_4.yml b/doc/example-grids/regular_gaussian_4.yml new file mode 100644 index 000000000..494e8eee1 --- /dev/null +++ b/doc/example-grids/regular_gaussian_4.yml @@ -0,0 +1,11 @@ +# Regular Gaussian grid (Ngauss=8) starting at -180 and much denser x-spacing than y-spacing + +type : "structured" +yspace : { type : "gaussian", N : 16 } +xspace : { type : "linear", N : 160, start : -180, length : 360, endpoint : false } + +check : + size : 2560 + lonlat(first) : [-180,81.6506] + lonlat(last) : [177.75,-81.6506] + uid : a5362eb4649fce5d8ccf149cf59cabf4 \ No newline at end of file diff --git a/doc/example-grids/regular_lonlat_1.yml b/doc/example-grids/regular_lonlat_1.yml index 2332e7924..b4f95343d 100644 --- a/doc/example-grids/regular_lonlat_1.yml +++ b/doc/example-grids/regular_lonlat_1.yml @@ -2,3 +2,10 @@ type : "regular_lonlat" nx : 128 ny : 65 + + +check: + size : 8320 + lonlat(first) : [0,90] + lonlat(last) : [357.188,-90] + uid : a5b356177b3ca2f1e65843756d64de76 \ No newline at end of file diff --git a/doc/example-grids/zonal_band_1.yml b/doc/example-grids/zonal_band_1.yml index 38a9dbf12..46ffa1916 100644 --- a/doc/example-grids/zonal_band_1.yml +++ b/doc/example-grids/zonal_band_1.yml @@ -2,4 +2,10 @@ type : "zonal_band" nx : 5 ny : 3 north : 70 -south : 30 \ No newline at end of file +south : 30 + +check: + size : 15 + lonlat(first) : [0,70] + lonlat(last) : [288,30] + uid : 5dc6e5c29625c95e86afe4efaae17dd7 \ No newline at end of file diff --git a/doc/example-grids/zonal_band_2.yml b/doc/example-grids/zonal_band_2.yml index 98a32a216..63b56d787 100644 --- a/doc/example-grids/zonal_band_2.yml +++ b/doc/example-grids/zonal_band_2.yml @@ -2,3 +2,11 @@ type : "zonal_band" nx : 36 ny : 7 south : 30 + +y_numbering: +1 + +check: + size : 252 + lonlat(first) : [0,30] + lonlat(last) : [350,90] + uid : ebf1b438a0a770f7fb20fd41885ae086 \ No newline at end of file diff --git a/doc/example-grids/zonal_band_3.yml b/doc/example-grids/zonal_band_3.yml index fb16ec81e..1453c97fe 100644 --- a/doc/example-grids/zonal_band_3.yml +++ b/doc/example-grids/zonal_band_3.yml @@ -1,3 +1,10 @@ type : "zonal_band" nx : 36 ny : 19 +y_numbering: +1 + +check: + size : 684 + lonlat(first) : [0,-90] + lonlat(last) : [350,90] + uid : ae584da2de497b8065c63f73115b08f1 \ No newline at end of file diff --git a/src/apps/atlas-grids.cc b/src/apps/atlas-grids.cc index 12de158c1..2b813e38f 100644 --- a/src/apps/atlas-grids.cc +++ b/src/apps/atlas-grids.cc @@ -24,6 +24,7 @@ #include "eckit/log/Log.h" #include "eckit/parser/JSON.h" #include "eckit/runtime/Main.h" +#include "eckit/types/FloatCompare.h" #include "atlas/grid.h" #include "atlas/grid/detail/grid/GridFactory.h" @@ -35,6 +36,7 @@ using namespace atlas; using namespace atlas::grid; using eckit::JSON; +using eckit::PathName; //---------------------------------------------------------------------------------------------------------------------- @@ -62,6 +64,8 @@ class AtlasGrids : public AtlasTool { add_option( new SimpleOption( "json", "Export json" ) ); add_option( new SimpleOption( "rtable", "Export IFS rtable" ) ); + + add_option( new SimpleOption( "check", "Check grid" ) ); } private: @@ -71,6 +75,7 @@ class AtlasGrids : public AtlasTool { bool json; bool rtable; bool do_run; + bool check; }; //------------------------------------------------------------------------------------------------------ @@ -109,10 +114,13 @@ int AtlasGrids::execute( const Args& args ) { if ( !key.empty() ) { StructuredGrid grid; - try { - grid = Grid( key ); - } - catch ( eckit::Exception& ) { + + PathName spec{ key }; + if( spec.exists() ) { + grid = Grid( Grid::Spec{ spec } ); + } + else { + grid = Grid( key ); } if ( !grid ) return failed(); @@ -126,40 +134,71 @@ int AtlasGrids::execute( const Args& args ) { Log::info() << " Gaussian N number: " << gaussian.N() << std::endl; } Log::info() << " number of points: " << grid.size() << std::endl; - Log::info() << " number of latitudes (N-S): " << grid.ny() << std::endl; - Log::info() << " number of longitudes (max): " << grid.nxmax() << std::endl; - - deg = ( grid.y().front() - grid.y().back() ) / ( grid.ny() - 1 ); - km = deg * 40075. / 360.; - Log::info() << " approximate resolution N-S: " << std::setw( 10 ) << std::fixed << deg - << " deg " << km << " km " << std::endl; - - deg = 360. / static_cast( grid.nx( grid.ny() / 2 ) ); - km = deg * 40075. / 360.; - Log::info() << " approximate resolution E-W equator: " << std::setw( 10 ) << std::fixed << deg - << " deg " << km << " km " << std::endl; - - deg = 360. * std::cos( grid.y( grid.ny() / 4 ) * M_PI / 180. ) / - static_cast( grid.nx( grid.ny() / 4 ) ); - km = deg * 40075. / 360.; - Log::info() << " approximate resolution E-W midlat: " << std::setw( 10 ) << std::fixed << deg - << " deg " << km << " km " << std::endl; - - deg = 360. * std::cos( grid.y().front() * M_PI / 180. ) / static_cast( grid.nx().front() ); - km = deg * 40075. / 360.; + size_t memsize = grid.size() * sizeof( double ); - - Log::info() << " approximate resolution E-W pole: " << std::setw( 10 ) << std::fixed << deg - << " deg " << km << " km " << std::endl; - - Log::info() << " spectral truncation -- linear: " << grid.ny() - 1 << std::endl; - Log::info() << " spectral truncation -- quadratic: " - << static_cast( std::floor( 2. / 3. * grid.ny() + 0.5 ) ) - 1 << std::endl; - Log::info() << " spectral truncation -- cubic: " - << static_cast( std::floor( 0.5 * grid.ny() + 0.5 ) ) - 1 << std::endl; - - Log::info() << " memory footprint per field: " << eckit::Bytes( memsize ) << std::endl; + + Log::info() << " memory footprint per field (dp): " << eckit::Bytes( memsize ) << std::endl; + + + if( not grid.projection() ) { + Log::info() << " number of latitudes (N-S): " << grid.ny() << std::endl; + Log::info() << " number of longitudes (max): " << grid.nxmax() << std::endl; + + deg = ( grid.y().front() - grid.y().back() ) / ( grid.ny() - 1 ); + km = deg * 40075. / 360.; + Log::info() << " approximate resolution N-S: " << std::setw( 10 ) << std::fixed << deg + << " deg " << km << " km " << std::endl; + + deg = 360. / static_cast( grid.nx( grid.ny() / 2 ) ); + km = deg * 40075. / 360.; + Log::info() << " approximate resolution E-W equator: " << std::setw( 10 ) << std::fixed << deg + << " deg " << km << " km " << std::endl; + + deg = 360. * std::cos( grid.y( grid.ny() / 4 ) * M_PI / 180. ) / + static_cast( grid.nx( grid.ny() / 4 ) ); + km = deg * 40075. / 360.; + Log::info() << " approximate resolution E-W midlat: " << std::setw( 10 ) << std::fixed << deg + << " deg " << km << " km " << std::endl; + + deg = 360. * std::cos( grid.y().front() * M_PI / 180. ) / static_cast( grid.nx().front() ); + km = deg * 40075. / 360.; + + + Log::info() << " approximate resolution E-W pole: " << std::setw( 10 ) << std::fixed << deg + << " deg " << km << " km " << std::endl; + + Log::info() << " spectral truncation -- linear: " << grid.ny() - 1 << std::endl; + Log::info() << " spectral truncation -- quadratic: " + << static_cast( std::floor( 2. / 3. * grid.ny() + 0.5 ) ) - 1 << std::endl; + Log::info() << " spectral truncation -- cubic: " + << static_cast( std::floor( 0.5 * grid.ny() + 0.5 ) ) - 1 << std::endl; + } + + PointLonLat first_point = *grid.lonlat().begin(); + PointLonLat last_point; + for( const auto&& p : grid.lonlat() ) { + last_point = p; + } + Log::info() << " lonlat(first): " << first_point << std::endl; + Log::info() << " lonlat(last) : " << last_point << std::endl; + if( grid.projection().units() == "meters" ) { + auto p = Log::info().precision(2); + Log::info() << " x : [ " << std::setw(10) << std::fixed << grid.xspace().min() / 1000. + << " , " << std::setw(10) << std::fixed << grid.xspace().max() / 1000. << " ] km" << std::endl; + Log::info() << " y : [ " << std::setw(10) << std::fixed << grid.yspace().min() / 1000. + << " , " << std::setw(10) << std::fixed << grid.yspace().max() / 1000. << " ] km" << std::endl; + Log::info().precision(p); + } + if( grid.projection().units() == "degrees" ) { + auto p = Log::info().precision(2); + Log::info() << " x : [ " << std::setw(10) << std::fixed << grid.xspace().min() + << " , " << std::setw(10) << std::fixed << grid.xspace().max() << " ] deg" << std::endl; + Log::info() << " y : [ " << std::setw(10) << std::fixed << grid.yspace().min() + << " , " << std::setw(10) << std::fixed << grid.yspace().max() << " ] deg" << std::endl; + Log::info().precision(p); + } + } if ( json ) { std::stringstream stream; @@ -178,6 +217,79 @@ int AtlasGrids::execute( const Args& args ) { stream << "/" << std::flush; std::cout << stream.str() << std::endl; } + + if( check ) { + bool check_failed = false; + Log::Channel out; out.setStream( Log::error() ); + PathName spec{ key }; + if( not spec.exists() ) { + out << "Check failed: " << key << " is not a file" << std::endl; + return failed(); + } + util::Config config_check; + if( not util::Config{spec}.get( "check", config_check ) ) { + out << "Check failed: no \"check\" section in " << key << std::endl; + return failed(); + } + + idx_t size; + if( config_check.get("size",size) ) { + if( grid.size() != size ) { + out << "Check failed: grid size " << grid.size() << " expected to be " << size << std::endl; + check_failed = true; + } + } + else { + Log::warning() << "Check for size skipped" << std::endl; + } + + std::string uid; + if( config_check.get("uid",uid) ) { + if( grid.uid() != uid ) { + out << "Check failed: grid uid " << grid.uid() << " expected to be " << uid << std::endl; + check_failed = true; + } + } + else { + Log::warning() << "Check for uid skipped" << std::endl; + } + + + auto equal = []( const PointLonLat& p, const std::vector& check ) -> bool { + if( not eckit::types::is_approximately_equal( p.lon(), check[0], 5.e-4 ) ) return false; + if( not eckit::types::is_approximately_equal( p.lat(), check[1], 5.e-4 ) ) return false; + return true; + }; + + std::vector first_point_lonlat; + if( config_check.get("lonlat(first)",first_point_lonlat) ) { + PointLonLat first_point = *grid.lonlat().begin(); + if( not equal( first_point, first_point_lonlat ) ) { + out << "Check failed: lonlat(first) " << first_point << " expected to be " << PointLonLat( first_point_lonlat.data() ) << std::endl; + check_failed = true; + } + } + else { + Log::warning() << "Check for lonlat(first) skipped" << std::endl; + } + + std::vector last_point_lonlat; + if( config_check.get("lonlat(last)",last_point_lonlat) ) { + PointLonLat last_point; + for( const auto&& p : grid.lonlat() ) { + last_point = p; + } + if( not equal( last_point, last_point_lonlat ) ) { + out << "Check failed: lonlat(last) " << last_point << " expected to be " << PointLonLat( last_point_lonlat.data() ) << std::endl; + check_failed = true; + } + } + else { + Log::warning() << "Check for lonlat(last) skipped" << std::endl; + } + if( check_failed ) return failed(); + Log::info() << "SUCCESS: All checks passed" << std::endl; + } } return success(); } diff --git a/src/atlas/grid/detail/grid/Regional.cc b/src/atlas/grid/detail/grid/Regional.cc index eb20f1aa0..e3d62fc60 100644 --- a/src/atlas/grid/detail/grid/Regional.cc +++ b/src/atlas/grid/detail/grid/Regional.cc @@ -240,8 +240,7 @@ static class regional : public GridBuilder { throw_Exception( "Could not parse configuration for RegularRegional grid", Here() ); } - YSpace yspace = config.getBool( "y_increasing", true ) ? LinearSpacing( y.min, y.max, y.N, y.endpoint ) - : LinearSpacing( y.max, y.min, y.N, y.endpoint ); + YSpace yspace = config.getInt( "y_numbering", -1 ) < 0 ? LinearSpacing( y.max, y.min, y.N, y.endpoint ) : LinearSpacing( y.min, y.max, y.N, y.endpoint ); bool with_endpoint = true; XSpace xspace( {x.min, x.max}, std::vector( y.N, x.N ), with_endpoint ); @@ -285,8 +284,8 @@ static class zonal_band : public GridBuilder { if ( not( config.get( "ymin", y.min ) or config.get( "south", y.min ) ) ) y.min = -90.; if ( not( config.get( "ymax", y.max ) or config.get( "north", y.max ) ) ) y.max = 90.; - YSpace yspace = config.getBool( "y_increasing", true ) ? LinearSpacing( y.min, y.max, y.N, true ) - : LinearSpacing( y.max, y.min, y.N, true ); + YSpace yspace = config.getInt( "y_numbering", -1 ) < 0 ? LinearSpacing( y.max, y.min, y.N, true ) + : LinearSpacing( y.min, y.max, y.N, true ); XSpace xspace( {0., 360.}, std::vector( y.N, nx ), false ); diff --git a/src/tests/projection/test_projection_LAEA.cc b/src/tests/projection/test_projection_LAEA.cc index e1b563995..477f585ac 100644 --- a/src/tests/projection/test_projection_LAEA.cc +++ b/src/tests/projection/test_projection_LAEA.cc @@ -96,7 +96,7 @@ CASE( "test_grid_creation_from_GRIB" ) { gridspec.set( "dx", dx ); gridspec.set( "dy", dy ); gridspec.set( firstPointLoc, firstPointLonLat ); - gridspec.set( "y_increasing", false ); // Always decrease y for MIR + gridspec.set( "y_numbering", -1 ); // Always decrease y for MIR gridspec.set( "projection", [&]() { Grid::Spec projection; projection.set( "type", "lambert_azimuthal_equal_area" ); From 0571a1d4512fc6e2f0b843e79a80375a78a70d3d Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Tue, 18 Jun 2019 10:34:37 +0100 Subject: [PATCH 15/86] Remove message of logfile when logfiles are not created --- src/atlas/runtime/AtlasTool.cc | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/atlas/runtime/AtlasTool.cc b/src/atlas/runtime/AtlasTool.cc index 64b193cf3..5359326fa 100644 --- a/src/atlas/runtime/AtlasTool.cc +++ b/src/atlas/runtime/AtlasTool.cc @@ -238,7 +238,11 @@ bool atlas::AtlasTool::handle_help() { atlas::AtlasTool::AtlasTool( int argc, char** argv ) : eckit::Tool( argc, argv ) { eckit::LibEcKit::instance().setAbortHandler( [] { std::cerr << "[" << atlas::mpi::comm().rank() << "] " - << "calling MPI_Abort, logfile: " << logfile_name << std::endl; + << "calling MPI_Abort"; + if ( not use_logfile and mpi::comm().size() > 1 ) { + std::cerr << ", logfile: " << logfile_name; + } + std::cerr << std::endl; std::this_thread::sleep_for( std::chrono::milliseconds( 3000 ) ); atlas::mpi::comm().abort( 1 ); } ); From ed562270b82fedd56d26e6960e17f825e0f63874 Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Tue, 18 Jun 2019 12:03:28 +0100 Subject: [PATCH 16/86] Create CMake tests for each example-grid --- doc/example-grids/classic_gaussian_1.yml | 1 + doc/example-grids/classic_gaussian_3.yml | 1 + doc/example-grids/cropped_classic_gaussian_2.yml | 1 - doc/example-grids/custom_structured_4.yml | 1 + doc/example-grids/custom_structured_5.yml | 2 +- doc/example-grids/custom_structured_7.yml | 3 ++- doc/example-grids/regional_lambert_1.yml | 9 ++++----- doc/example-grids/regional_lonlat_1.yml | 2 +- doc/example-grids/regional_rotated_mercator_1.yml | 2 +- doc/example-grids/regular_gaussian_4.yml | 1 + doc/example-grids/zonal_band_1.yml | 1 + doc/example-grids/zonal_band_2.yml | 2 +- doc/example-grids/zonal_band_3.yml | 1 + src/tests/grid/CMakeLists.txt | 11 +++++++++++ 14 files changed, 27 insertions(+), 11 deletions(-) diff --git a/doc/example-grids/classic_gaussian_1.yml b/doc/example-grids/classic_gaussian_1.yml index 8f5aeb9c8..a0d4dba85 100644 --- a/doc/example-grids/classic_gaussian_1.yml +++ b/doc/example-grids/classic_gaussian_1.yml @@ -1,6 +1,7 @@ type : "classic_gaussian" N : 16 + check : size : 1688 lonlat(first) : [0,85.7606] diff --git a/doc/example-grids/classic_gaussian_3.yml b/doc/example-grids/classic_gaussian_3.yml index 07eae3a69..8040d1be8 100644 --- a/doc/example-grids/classic_gaussian_3.yml +++ b/doc/example-grids/classic_gaussian_3.yml @@ -2,6 +2,7 @@ name : "N16" + check : size : 1688 lonlat(first) : [0,85.7606] diff --git a/doc/example-grids/cropped_classic_gaussian_2.yml b/doc/example-grids/cropped_classic_gaussian_2.yml index 99568faaa..4de13a513 100644 --- a/doc/example-grids/cropped_classic_gaussian_2.yml +++ b/doc/example-grids/cropped_classic_gaussian_2.yml @@ -17,4 +17,3 @@ check : lonlat(first) : [48.4615,41.5325] lonlat(last) : [90,-41.5325] uid : a6bef73fef7e852af21a61421d425583 - \ No newline at end of file diff --git a/doc/example-grids/custom_structured_4.yml b/doc/example-grids/custom_structured_4.yml index 60ee22bb6..0985696f0 100644 --- a/doc/example-grids/custom_structured_4.yml +++ b/doc/example-grids/custom_structured_4.yml @@ -14,6 +14,7 @@ xspace : { type : "linear", start : 0, length : 360, endpoint : false, 20 ] } + check : size : 208 lonlat(first) : [0,73.7992] diff --git a/doc/example-grids/custom_structured_5.yml b/doc/example-grids/custom_structured_5.yml index a38339103..08c6c74e6 100644 --- a/doc/example-grids/custom_structured_5.yml +++ b/doc/example-grids/custom_structured_5.yml @@ -1,5 +1,5 @@ # Rotated lonlat grid 'L4' - + type : "structured" yspace : { type : "linear", N : 9, start : 90, end : -90 } xspace : { type : "linear", N : 16, start : 0 , end : 360 , endpoint : false } diff --git a/doc/example-grids/custom_structured_7.yml b/doc/example-grids/custom_structured_7.yml index 4b884075f..543559c33 100644 --- a/doc/example-grids/custom_structured_7.yml +++ b/doc/example-grids/custom_structured_7.yml @@ -1,9 +1,10 @@ # Shifted lat grid 'Slat3' - + type : "structured" yspace : { type: custom, N : 6, values : [75,45,15,-15,-45,-75], interval:[-90,90] } xspace : { type: linear, N : 12, start:0, end:360, endpoint:false } + check : size : 72 lonlat(first) : [0,75] diff --git a/doc/example-grids/regional_lambert_1.yml b/doc/example-grids/regional_lambert_1.yml index 82d8c3ab7..98550874e 100644 --- a/doc/example-grids/regional_lambert_1.yml +++ b/doc/example-grids/regional_lambert_1.yml @@ -4,14 +4,13 @@ ny : 40 dx : 50000 dy : 50000 lonlat(centre) : [4,50] -projection : { - type : "lambert", - latitude1 : 50, +projection : + type : "lambert" + latitude1 : 50 longitude0 : 4 - } - y_numbering : +1 + check : size : 2000 lonlat(first) : [-10.3173,40.22] diff --git a/doc/example-grids/regional_lonlat_1.yml b/doc/example-grids/regional_lonlat_1.yml index 697aa1bce..f556455c1 100644 --- a/doc/example-grids/regional_lonlat_1.yml +++ b/doc/example-grids/regional_lonlat_1.yml @@ -5,9 +5,9 @@ north : -10 south : -50 east : 170 west : 100 - y_numbering: +1 + check : size : 875 lonlat(first) : [100,-50] diff --git a/doc/example-grids/regional_rotated_mercator_1.yml b/doc/example-grids/regional_rotated_mercator_1.yml index 130a58c47..71ead9734 100644 --- a/doc/example-grids/regional_rotated_mercator_1.yml +++ b/doc/example-grids/regional_rotated_mercator_1.yml @@ -7,9 +7,9 @@ lonlat(centre) : [4,50] projection : type : "rotated_mercator" north_pole : [-176,40] - y_numbering : +1 + check : size : 2000 lonlat(first) : [-10.319,40.2109] diff --git a/doc/example-grids/regular_gaussian_4.yml b/doc/example-grids/regular_gaussian_4.yml index 494e8eee1..0bce56d85 100644 --- a/doc/example-grids/regular_gaussian_4.yml +++ b/doc/example-grids/regular_gaussian_4.yml @@ -4,6 +4,7 @@ type : "structured" yspace : { type : "gaussian", N : 16 } xspace : { type : "linear", N : 160, start : -180, length : 360, endpoint : false } + check : size : 2560 lonlat(first) : [-180,81.6506] diff --git a/doc/example-grids/zonal_band_1.yml b/doc/example-grids/zonal_band_1.yml index 46ffa1916..635828580 100644 --- a/doc/example-grids/zonal_band_1.yml +++ b/doc/example-grids/zonal_band_1.yml @@ -4,6 +4,7 @@ ny : 3 north : 70 south : 30 + check: size : 15 lonlat(first) : [0,70] diff --git a/doc/example-grids/zonal_band_2.yml b/doc/example-grids/zonal_band_2.yml index 63b56d787..d1715a541 100644 --- a/doc/example-grids/zonal_band_2.yml +++ b/doc/example-grids/zonal_band_2.yml @@ -2,9 +2,9 @@ type : "zonal_band" nx : 36 ny : 7 south : 30 - y_numbering: +1 + check: size : 252 lonlat(first) : [0,30] diff --git a/doc/example-grids/zonal_band_3.yml b/doc/example-grids/zonal_band_3.yml index 1453c97fe..8871c3efb 100644 --- a/doc/example-grids/zonal_band_3.yml +++ b/doc/example-grids/zonal_band_3.yml @@ -3,6 +3,7 @@ nx : 36 ny : 19 y_numbering: +1 + check: size : 684 lonlat(first) : [0,-90] diff --git a/src/tests/grid/CMakeLists.txt b/src/tests/grid/CMakeLists.txt index d3a80914e..ffd64b53a 100644 --- a/src/tests/grid/CMakeLists.txt +++ b/src/tests/grid/CMakeLists.txt @@ -29,3 +29,14 @@ foreach(test ecbuild_add_test( TARGET atlas_${test} SOURCES ${test}.cc LIBS atlas ) endforeach() + +file( GLOB grids ${PROJECT_SOURCE_DIR}/doc/example-grids/*.yml ) + +foreach( grid ${grids} ) + get_filename_component( grid_name ${grid} NAME_WE ) + set( test_name atlas_test_grid_${grid_name} ) + ecbuild_add_test( TARGET ${test_name} + COMMAND $ + ARGS ${grid} --check + ) +endforeach() From 1fd42562f41b5928e0378e17fb47c8413b791a6c Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Tue, 18 Jun 2019 16:25:21 +0100 Subject: [PATCH 17/86] Add EFAS grid to checklist --- doc/example-grids/regional_lambert_2.yml | 2 +- ...egional_lambert_azimuthal_equal_area_1.yml | 18 +++++++++++ ...egional_lambert_azimuthal_equal_area_2.yml | 20 ++++++++++++ src/apps/atlas-grids.cc | 11 +++++++ src/atlas/grid/detail/grid/Regional.cc | 31 ++++++++++++++++++- 5 files changed, 80 insertions(+), 2 deletions(-) create mode 100644 doc/example-grids/regional_lambert_azimuthal_equal_area_1.yml create mode 100644 doc/example-grids/regional_lambert_azimuthal_equal_area_2.yml diff --git a/doc/example-grids/regional_lambert_2.yml b/doc/example-grids/regional_lambert_2.yml index 05c4ae391..ea50173b9 100644 --- a/doc/example-grids/regional_lambert_2.yml +++ b/doc/example-grids/regional_lambert_2.yml @@ -15,4 +15,4 @@ check : size : 151987 lonlat(first) : [-126.138,16.281] lonlat(last) : [-57.3811,55.4813] - uid : cd7e504a256290ca525b4dec75550d7a \ No newline at end of file + uid : cc3b50fa2a333cb749324321af25a15b diff --git a/doc/example-grids/regional_lambert_azimuthal_equal_area_1.yml b/doc/example-grids/regional_lambert_azimuthal_equal_area_1.yml new file mode 100644 index 000000000..95d0835df --- /dev/null +++ b/doc/example-grids/regional_lambert_azimuthal_equal_area_1.yml @@ -0,0 +1,18 @@ +type : "regional" +nx : 50 +ny : 40 +dx : 50000 +dy : 50000 +lonlat(centre) : [4,50] +projection : + type : "lambert_azimuthal_equal_area" + standard_parallel : 50 + central_longitude : 4 +y_numbering : +1 + + +check : + size : 2000 + lonlat(first) : [-10.4643,40.1877] + lonlat(last) : [24.6228,57.1968] + uid : 7f71ee81a94c8cf92a2280e8a7828a32 diff --git a/doc/example-grids/regional_lambert_azimuthal_equal_area_2.yml b/doc/example-grids/regional_lambert_azimuthal_equal_area_2.yml new file mode 100644 index 000000000..ff2e175ae --- /dev/null +++ b/doc/example-grids/regional_lambert_azimuthal_equal_area_2.yml @@ -0,0 +1,20 @@ +# EFAS grid + +type : "regional" +nx : 1000 +ny : 950 +dx : 5000 +dy : 5000 +lonlat(xmin,ymax) : [-35.034,66.9821] +projection : + type : "lambert_azimuthal_equal_area" + standard_parallel : 52 + central_longitude : 10 +y_numbering : -1 + + +check : + size : 950000 + lonlat(first) : [-35.034,66.9821] + lonlat(last) : [41.2436,23.8962] + uid : 09fcf68cb6f8871668dbef411b45a559 diff --git a/src/apps/atlas-grids.cc b/src/apps/atlas-grids.cc index 2b813e38f..8c4c059d4 100644 --- a/src/apps/atlas-grids.cc +++ b/src/apps/atlas-grids.cc @@ -100,6 +100,10 @@ int AtlasGrids::execute( const Args& args ) { list = false; args.get( "list", list ); if ( list ) do_run = true; + + check = false; + args.get( "check", check ); + if( check && !key.empty() ) do_run = true; if ( !key.empty() && do_run == false ) { Log::error() << "Option wrong or missing after '" << key << "'" << std::endl; @@ -188,6 +192,13 @@ int AtlasGrids::execute( const Args& args ) { << " , " << std::setw(10) << std::fixed << grid.xspace().max() / 1000. << " ] km" << std::endl; Log::info() << " y : [ " << std::setw(10) << std::fixed << grid.yspace().min() / 1000. << " , " << std::setw(10) << std::fixed << grid.yspace().max() / 1000. << " ] km" << std::endl; + Log::info() << "lonlat(centre) : " << grid.projection().lonlat( + { 0.5*(grid.xspace().max()+grid.xspace().min()), + 0.5*(grid.yspace().max()+grid.yspace().min())} ) << std::endl; + Log::info() << "lonlat(xmin,ymax) : " << grid.projection().lonlat( { grid.xspace().min(), grid.yspace().max()} ) << std::endl; + Log::info() << "lonlat(xmin,ymin) : " << grid.projection().lonlat( { grid.xspace().min(), grid.yspace().min()} ) << std::endl; + Log::info() << "lonlat(xmax,ymin) : " << grid.projection().lonlat( { grid.xspace().max(), grid.yspace().min()} ) << std::endl; + Log::info() << "lonlat(xmax,ymax) : " << grid.projection().lonlat( { grid.xspace().max(), grid.yspace().max()} ) << std::endl; Log::info().precision(p); } if( grid.projection().units() == "degrees" ) { diff --git a/src/atlas/grid/detail/grid/Regional.cc b/src/atlas/grid/detail/grid/Regional.cc index e3d62fc60..f9d01322f 100644 --- a/src/atlas/grid/detail/grid/Regional.cc +++ b/src/atlas/grid/detail/grid/Regional.cc @@ -142,6 +142,19 @@ struct Parse_ll00_ll11 : ConfigParser { } }; +struct Parse_xy01_step : ConfigParser { + Parse_xy01_step( const Projection&, const Grid::Config& config ) { + valid = config.get( "nx", x.N ) && config.get( "ny", y.N ) && config.get( "dx", x.step ) && + config.get( "dy", y.step ) && config.get( "xmin", x.min ) && + config.get( "ymax", y.max ); // includes rotation + + if ( not valid ) return; + + x.max = x.min + x.step * ( x.N - 1 ); + y.min = y.max - y.step * ( y.N - 1 ); + } +}; + struct Parse_ll00_step : ConfigParser { Parse_ll00_step( const Projection& p, const Grid::Config& config ) { std::vector sw; @@ -159,6 +172,20 @@ struct Parse_ll00_step : ConfigParser { } }; +struct Parse_xy00_step : ConfigParser { + Parse_xy00_step( const Projection&, const Grid::Config& config ) { + valid = config.get( "nx", x.N ) && config.get( "ny", y.N ) && config.get( "dx", x.step ) && + config.get( "dy", y.step ) && config.get( "xmin", x.min ) && + config.get( "ymin", y.min ); + + if ( not valid ) return; + + x.max = x.min + x.step * ( x.N - 1 ); + y.max = y.min + y.step * ( y.N - 1 ); + } +}; + + struct Parse_ll01_step : ConfigParser { // This resembles GRIB input for "lambert_azimutal_equal_area" Parse_ll01_step( const Projection& p, const Grid::Config& config ) { std::vector nw; @@ -197,9 +224,11 @@ bool ConfigParser::parse( const Projection& projection, const Grid::Config& conf // top-left of domain and increments (any projection allowed) if ( ConfigParser::parse( projection, config, x, y ) ) return true; - + if ( ConfigParser::parse( projection, config, x, y ) ) return true; + // bottom-left of domain and increments (any projection allowed) if ( ConfigParser::parse( projection, config, x, y ) ) return true; + if ( ConfigParser::parse( projection, config, x, y ) ) return true; // bounding box using two points defined in lonlat (any projection allowed) if ( ConfigParser::parse( projection, config, x, y ) ) return true; From 85903ad2ec9aca45f131f8e2fc0766b316aa3664 Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Tue, 18 Jun 2019 17:45:44 +0100 Subject: [PATCH 18/86] More diagnostics in atlas-grids --- src/apps/atlas-grids.cc | 41 +++++++++++++++++++++-------------------- 1 file changed, 21 insertions(+), 20 deletions(-) diff --git a/src/apps/atlas-grids.cc b/src/apps/atlas-grids.cc index 8c4c059d4..5da21cdc6 100644 --- a/src/apps/atlas-grids.cc +++ b/src/apps/atlas-grids.cc @@ -177,39 +177,40 @@ int AtlasGrids::execute( const Args& args ) { << static_cast( std::floor( 2. / 3. * grid.ny() + 0.5 ) ) - 1 << std::endl; Log::info() << " spectral truncation -- cubic: " << static_cast( std::floor( 0.5 * grid.ny() + 0.5 ) ) - 1 << std::endl; - } - - PointLonLat first_point = *grid.lonlat().begin(); - PointLonLat last_point; - for( const auto&& p : grid.lonlat() ) { - last_point = p; } - Log::info() << " lonlat(first): " << first_point << std::endl; - Log::info() << " lonlat(last) : " << last_point << std::endl; + + auto precision = Log::info().precision(3); if( grid.projection().units() == "meters" ) { - auto p = Log::info().precision(2); Log::info() << " x : [ " << std::setw(10) << std::fixed << grid.xspace().min() / 1000. << " , " << std::setw(10) << std::fixed << grid.xspace().max() / 1000. << " ] km" << std::endl; Log::info() << " y : [ " << std::setw(10) << std::fixed << grid.yspace().min() / 1000. << " , " << std::setw(10) << std::fixed << grid.yspace().max() / 1000. << " ] km" << std::endl; - Log::info() << "lonlat(centre) : " << grid.projection().lonlat( + if( grid.xspace().nxmax() == grid.xspace().nxmin() ) { + Log::info() << " dx : " << grid.xspace().dx()[0] / 1000. << " km" << std::endl; + } + Log::info() << " dy : " << std::abs(grid.yspace()[1]-grid.yspace()[0]) / 1000. << " km" << std::endl; + Log::info() << " lonlat(centre) : " << grid.projection().lonlat( { 0.5*(grid.xspace().max()+grid.xspace().min()), 0.5*(grid.yspace().max()+grid.yspace().min())} ) << std::endl; - Log::info() << "lonlat(xmin,ymax) : " << grid.projection().lonlat( { grid.xspace().min(), grid.yspace().max()} ) << std::endl; - Log::info() << "lonlat(xmin,ymin) : " << grid.projection().lonlat( { grid.xspace().min(), grid.yspace().min()} ) << std::endl; - Log::info() << "lonlat(xmax,ymin) : " << grid.projection().lonlat( { grid.xspace().max(), grid.yspace().min()} ) << std::endl; - Log::info() << "lonlat(xmax,ymax) : " << grid.projection().lonlat( { grid.xspace().max(), grid.yspace().max()} ) << std::endl; - Log::info().precision(p); - } - if( grid.projection().units() == "degrees" ) { - auto p = Log::info().precision(2); + Log::info() << " lonlat(xmin,ymax) : " << grid.projection().lonlat( { grid.xspace().min(), grid.yspace().max()} ) << std::endl; + Log::info() << " lonlat(xmin,ymin) : " << grid.projection().lonlat( { grid.xspace().min(), grid.yspace().min()} ) << std::endl; + Log::info() << " lonlat(xmax,ymin) : " << grid.projection().lonlat( { grid.xspace().max(), grid.yspace().min()} ) << std::endl; + Log::info() << " lonlat(xmax,ymax) : " << grid.projection().lonlat( { grid.xspace().max(), grid.yspace().max()} ) << std::endl; + } + if( grid.projection().units() == "degrees" ) { Log::info() << " x : [ " << std::setw(10) << std::fixed << grid.xspace().min() << " , " << std::setw(10) << std::fixed << grid.xspace().max() << " ] deg" << std::endl; Log::info() << " y : [ " << std::setw(10) << std::fixed << grid.yspace().min() << " , " << std::setw(10) << std::fixed << grid.yspace().max() << " ] deg" << std::endl; - Log::info().precision(p); } - + PointLonLat first_point = *grid.lonlat().begin(); + PointLonLat last_point; + for( const auto p : grid.lonlat() ) { + last_point = p; + } + Log::info() << " lonlat(first) : " << first_point << std::endl; + Log::info() << " lonlat(last) : " << last_point << std::endl; + Log::info().precision(precision); } if ( json ) { std::stringstream stream; From 0eac46c00390401b4052a63be893df24b89872d4 Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Wed, 26 Jun 2019 15:39:35 +0100 Subject: [PATCH 19/86] ATLAS-237 Do not check for grid uid at the moment --- doc/example-grids/classic_gaussian_1.yml | 2 +- doc/example-grids/classic_gaussian_2.yml | 2 +- doc/example-grids/classic_gaussian_3.yml | 2 +- doc/example-grids/cropped_classic_gaussian_1.yml | 2 +- doc/example-grids/cropped_classic_gaussian_2.yml | 2 +- doc/example-grids/cropped_shifted_lonlat_1.yml | 2 +- doc/example-grids/custom_structured_1.yml | 2 +- doc/example-grids/custom_structured_2.yml | 2 +- doc/example-grids/custom_structured_3.yml | 2 +- doc/example-grids/custom_structured_4.yml | 2 +- doc/example-grids/custom_structured_5.yml | 2 +- doc/example-grids/custom_structured_6.yml | 2 +- doc/example-grids/custom_structured_7.yml | 2 +- doc/example-grids/octahedral_gaussian_1.yml | 2 +- doc/example-grids/octahedral_gaussian_2.yml | 2 +- doc/example-grids/octahedral_gaussian_3.yml | 2 +- doc/example-grids/octahedral_gaussian_4.yml | 2 +- doc/example-grids/regional_lambert_1.yml | 2 +- doc/example-grids/regional_lambert_2.yml | 2 +- doc/example-grids/regional_lambert_azimuthal_equal_area_1.yml | 2 +- doc/example-grids/regional_lambert_azimuthal_equal_area_2.yml | 2 +- doc/example-grids/regional_lonlat_1.yml | 2 +- doc/example-grids/regional_rotated_mercator_1.yml | 2 +- doc/example-grids/regular_gaussian_1.yml | 2 +- doc/example-grids/regular_gaussian_2.yml | 2 +- doc/example-grids/regular_gaussian_3.yml | 2 +- doc/example-grids/regular_gaussian_4.yml | 2 +- doc/example-grids/regular_lonlat_1.yml | 2 +- doc/example-grids/zonal_band_1.yml | 2 +- doc/example-grids/zonal_band_2.yml | 2 +- doc/example-grids/zonal_band_3.yml | 2 +- 31 files changed, 31 insertions(+), 31 deletions(-) diff --git a/doc/example-grids/classic_gaussian_1.yml b/doc/example-grids/classic_gaussian_1.yml index a0d4dba85..2e393e6a7 100644 --- a/doc/example-grids/classic_gaussian_1.yml +++ b/doc/example-grids/classic_gaussian_1.yml @@ -6,4 +6,4 @@ check : size : 1688 lonlat(first) : [0,85.7606] lonlat(last) : [342,-85.7606] - uid : 7ad37fdbeaf287838c9396a5b857ccc7 \ No newline at end of file + #uid : 7ad37fdbeaf287838c9396a5b857ccc7 diff --git a/doc/example-grids/classic_gaussian_2.yml b/doc/example-grids/classic_gaussian_2.yml index 5189bb8db..5570620a3 100644 --- a/doc/example-grids/classic_gaussian_2.yml +++ b/doc/example-grids/classic_gaussian_2.yml @@ -12,4 +12,4 @@ check : size : 1688 lonlat(first) : [3,44.8796] lonlat(last) : [-172.453,-54.9736] - uid : f0caeff347f57954191e8e1d7b3a05b6 \ No newline at end of file + #uid : f0caeff347f57954191e8e1d7b3a05b6 diff --git a/doc/example-grids/classic_gaussian_3.yml b/doc/example-grids/classic_gaussian_3.yml index 8040d1be8..e37519c37 100644 --- a/doc/example-grids/classic_gaussian_3.yml +++ b/doc/example-grids/classic_gaussian_3.yml @@ -7,4 +7,4 @@ check : size : 1688 lonlat(first) : [0,85.7606] lonlat(last) : [342,-85.7606] - uid : 7ad37fdbeaf287838c9396a5b857ccc7 \ No newline at end of file + #uid : 7ad37fdbeaf287838c9396a5b857ccc7 diff --git a/doc/example-grids/cropped_classic_gaussian_1.yml b/doc/example-grids/cropped_classic_gaussian_1.yml index 202e364e5..760e6d8ea 100644 --- a/doc/example-grids/cropped_classic_gaussian_1.yml +++ b/doc/example-grids/cropped_classic_gaussian_1.yml @@ -13,4 +13,4 @@ check : size : 332 lonlat(first) : [0,85.7606] lonlat(last) : [354,47.0696] - uid : 6e7924fd98acefc8b163941796739636 \ No newline at end of file + #uid : 6e7924fd98acefc8b163941796739636 diff --git a/doc/example-grids/cropped_classic_gaussian_2.yml b/doc/example-grids/cropped_classic_gaussian_2.yml index 4de13a513..2a28d5925 100644 --- a/doc/example-grids/cropped_classic_gaussian_2.yml +++ b/doc/example-grids/cropped_classic_gaussian_2.yml @@ -16,4 +16,4 @@ check : size : 144 lonlat(first) : [48.4615,41.5325] lonlat(last) : [90,-41.5325] - uid : a6bef73fef7e852af21a61421d425583 + #uid : a6bef73fef7e852af21a61421d425583 diff --git a/doc/example-grids/cropped_shifted_lonlat_1.yml b/doc/example-grids/cropped_shifted_lonlat_1.yml index 576a3939a..bf6943270 100644 --- a/doc/example-grids/cropped_shifted_lonlat_1.yml +++ b/doc/example-grids/cropped_shifted_lonlat_1.yml @@ -11,4 +11,4 @@ check : size : 4140 lonlat(first) : [1,89] lonlat(last) : [359,45] - uid : 9ada69c9f3b78c1bd81e8883df522d0a \ No newline at end of file + #uid : 9ada69c9f3b78c1bd81e8883df522d0a diff --git a/doc/example-grids/custom_structured_1.yml b/doc/example-grids/custom_structured_1.yml index dc06f880c..7112fe560 100644 --- a/doc/example-grids/custom_structured_1.yml +++ b/doc/example-grids/custom_structured_1.yml @@ -9,4 +9,4 @@ check : size : 144 lonlat(first) : [0,90] lonlat(last) : [337.5,-90] - uid : 302566694eed4568a78d3904e9eca6a6 \ No newline at end of file + #uid : 302566694eed4568a78d3904e9eca6a6 diff --git a/doc/example-grids/custom_structured_2.yml b/doc/example-grids/custom_structured_2.yml index 8d21d94bf..697a5b047 100644 --- a/doc/example-grids/custom_structured_2.yml +++ b/doc/example-grids/custom_structured_2.yml @@ -9,4 +9,4 @@ check : size : 128 lonlat(first) : [0,73.7992] lonlat(last) : [337.5,-73.7992] - uid : 1afa743f953ef3b1c628163029a8d612 \ No newline at end of file + #uid : 1afa743f953ef3b1c628163029a8d612 diff --git a/doc/example-grids/custom_structured_3.yml b/doc/example-grids/custom_structured_3.yml index f8683cb88..db4b618a5 100644 --- a/doc/example-grids/custom_structured_3.yml +++ b/doc/example-grids/custom_structured_3.yml @@ -17,4 +17,4 @@ check : size : 208 lonlat(first) : [0,73.7992] lonlat(last) : [342,-73.7992] - uid : 662bfa00f7e6e928b2ffeb10726604ef \ No newline at end of file + #uid : 662bfa00f7e6e928b2ffeb10726604ef diff --git a/doc/example-grids/custom_structured_4.yml b/doc/example-grids/custom_structured_4.yml index 0985696f0..58d1af821 100644 --- a/doc/example-grids/custom_structured_4.yml +++ b/doc/example-grids/custom_structured_4.yml @@ -19,4 +19,4 @@ check : size : 208 lonlat(first) : [0,73.7992] lonlat(last) : [342,-73.7992] - uid : 662bfa00f7e6e928b2ffeb10726604ef \ No newline at end of file + #uid : 662bfa00f7e6e928b2ffeb10726604ef diff --git a/doc/example-grids/custom_structured_5.yml b/doc/example-grids/custom_structured_5.yml index 08c6c74e6..869d7e8fd 100644 --- a/doc/example-grids/custom_structured_5.yml +++ b/doc/example-grids/custom_structured_5.yml @@ -10,4 +10,4 @@ check : size : 144 lonlat(first) : [3,40] lonlat(last) : [-177,-40] - uid : 7f70607c136c64cc9c756ea5addc261e \ No newline at end of file + #uid : 7f70607c136c64cc9c756ea5addc261e diff --git a/doc/example-grids/custom_structured_6.yml b/doc/example-grids/custom_structured_6.yml index c67137056..138769ff1 100644 --- a/doc/example-grids/custom_structured_6.yml +++ b/doc/example-grids/custom_structured_6.yml @@ -20,4 +20,4 @@ check: size : 128 lonlat(first) : [0,73.7992] lonlat(last) : [326.25,-73.7992] - uid : e975c4aa4103780e461407a20d1b5a62 \ No newline at end of file + #uid : e975c4aa4103780e461407a20d1b5a62 diff --git a/doc/example-grids/custom_structured_7.yml b/doc/example-grids/custom_structured_7.yml index 543559c33..762fd6a59 100644 --- a/doc/example-grids/custom_structured_7.yml +++ b/doc/example-grids/custom_structured_7.yml @@ -9,4 +9,4 @@ check : size : 72 lonlat(first) : [0,75] lonlat(last) : [330,-75] - uid : 088f8c4b8acca09987e4b8c0b0dad2c3 \ No newline at end of file + #uid : 088f8c4b8acca09987e4b8c0b0dad2c3 diff --git a/doc/example-grids/octahedral_gaussian_1.yml b/doc/example-grids/octahedral_gaussian_1.yml index 0767d602c..59a2710ea 100644 --- a/doc/example-grids/octahedral_gaussian_1.yml +++ b/doc/example-grids/octahedral_gaussian_1.yml @@ -8,4 +8,4 @@ check : size : 1600 lonlat(first) : [0,85.7606] lonlat(last) : [342,-85.7606] - uid : 00b0d36c51c046c2cce8fe51e37bdc63 \ No newline at end of file + #uid : 00b0d36c51c046c2cce8fe51e37bdc63 diff --git a/doc/example-grids/octahedral_gaussian_2.yml b/doc/example-grids/octahedral_gaussian_2.yml index 6253bfe04..a4baff8ca 100644 --- a/doc/example-grids/octahedral_gaussian_2.yml +++ b/doc/example-grids/octahedral_gaussian_2.yml @@ -9,4 +9,4 @@ check : size : 1600 lonlat(first) : [3,45.9397] lonlat(last) : [-165.776,-62.6128] - uid : 4978cdc0774cb3a27407591e79b4188c \ No newline at end of file + #uid : 4978cdc0774cb3a27407591e79b4188c diff --git a/doc/example-grids/octahedral_gaussian_3.yml b/doc/example-grids/octahedral_gaussian_3.yml index 3994470d0..cb8fd9cc0 100644 --- a/doc/example-grids/octahedral_gaussian_3.yml +++ b/doc/example-grids/octahedral_gaussian_3.yml @@ -7,4 +7,4 @@ check : size : 1600 lonlat(first) : [0,85.7606] lonlat(last) : [342,-85.7606] - uid : 00b0d36c51c046c2cce8fe51e37bdc63 \ No newline at end of file + #uid : 00b0d36c51c046c2cce8fe51e37bdc63 diff --git a/doc/example-grids/octahedral_gaussian_4.yml b/doc/example-grids/octahedral_gaussian_4.yml index c5cddae3f..9c50c1e51 100644 --- a/doc/example-grids/octahedral_gaussian_4.yml +++ b/doc/example-grids/octahedral_gaussian_4.yml @@ -8,4 +8,4 @@ check : size : 1600 lonlat(first) : [3,45.9397] lonlat(last) : [-165.776,-62.6128] - uid : 4978cdc0774cb3a27407591e79b4188c \ No newline at end of file + #uid : 4978cdc0774cb3a27407591e79b4188c diff --git a/doc/example-grids/regional_lambert_1.yml b/doc/example-grids/regional_lambert_1.yml index 98550874e..fe71ef461 100644 --- a/doc/example-grids/regional_lambert_1.yml +++ b/doc/example-grids/regional_lambert_1.yml @@ -15,4 +15,4 @@ check : size : 2000 lonlat(first) : [-10.3173,40.22] lonlat(last) : [24.4368,57.2335] - uid : 0ab14f4f37966a6760d0f5ee9176ad48 \ No newline at end of file + #uid : 0ab14f4f37966a6760d0f5ee9176ad48 diff --git a/doc/example-grids/regional_lambert_2.yml b/doc/example-grids/regional_lambert_2.yml index ea50173b9..20f8dd009 100644 --- a/doc/example-grids/regional_lambert_2.yml +++ b/doc/example-grids/regional_lambert_2.yml @@ -15,4 +15,4 @@ check : size : 151987 lonlat(first) : [-126.138,16.281] lonlat(last) : [-57.3811,55.4813] - uid : cc3b50fa2a333cb749324321af25a15b + #uid : cc3b50fa2a333cb749324321af25a15b diff --git a/doc/example-grids/regional_lambert_azimuthal_equal_area_1.yml b/doc/example-grids/regional_lambert_azimuthal_equal_area_1.yml index 95d0835df..f9f33534e 100644 --- a/doc/example-grids/regional_lambert_azimuthal_equal_area_1.yml +++ b/doc/example-grids/regional_lambert_azimuthal_equal_area_1.yml @@ -15,4 +15,4 @@ check : size : 2000 lonlat(first) : [-10.4643,40.1877] lonlat(last) : [24.6228,57.1968] - uid : 7f71ee81a94c8cf92a2280e8a7828a32 + #uid : 7f71ee81a94c8cf92a2280e8a7828a32 diff --git a/doc/example-grids/regional_lambert_azimuthal_equal_area_2.yml b/doc/example-grids/regional_lambert_azimuthal_equal_area_2.yml index ff2e175ae..e144d6456 100644 --- a/doc/example-grids/regional_lambert_azimuthal_equal_area_2.yml +++ b/doc/example-grids/regional_lambert_azimuthal_equal_area_2.yml @@ -17,4 +17,4 @@ check : size : 950000 lonlat(first) : [-35.034,66.9821] lonlat(last) : [41.2436,23.8962] - uid : 09fcf68cb6f8871668dbef411b45a559 + #uid : 09fcf68cb6f8871668dbef411b45a559 diff --git a/doc/example-grids/regional_lonlat_1.yml b/doc/example-grids/regional_lonlat_1.yml index f556455c1..b64c99056 100644 --- a/doc/example-grids/regional_lonlat_1.yml +++ b/doc/example-grids/regional_lonlat_1.yml @@ -12,4 +12,4 @@ check : size : 875 lonlat(first) : [100,-50] lonlat(last) : [170,-10] - uid : 4e4386c0a0f4aafc12fd45843aee9071 \ No newline at end of file + #uid : 4e4386c0a0f4aafc12fd45843aee9071 diff --git a/doc/example-grids/regional_rotated_mercator_1.yml b/doc/example-grids/regional_rotated_mercator_1.yml index 71ead9734..a2b5a6b17 100644 --- a/doc/example-grids/regional_rotated_mercator_1.yml +++ b/doc/example-grids/regional_rotated_mercator_1.yml @@ -14,4 +14,4 @@ check : size : 2000 lonlat(first) : [-10.319,40.2109] lonlat(last) : [24.4206,57.2263] - uid : 06b876b7f9968628a11910e8e9a381bf \ No newline at end of file + #uid : 06b876b7f9968628a11910e8e9a381bf diff --git a/doc/example-grids/regular_gaussian_1.yml b/doc/example-grids/regular_gaussian_1.yml index b9a504ee3..75dfd21b0 100644 --- a/doc/example-grids/regular_gaussian_1.yml +++ b/doc/example-grids/regular_gaussian_1.yml @@ -8,4 +8,4 @@ check : size : 128 lonlat(first) : [0,73.7992] lonlat(last) : [337.5,-73.7992] - uid : 1afa743f953ef3b1c628163029a8d612 \ No newline at end of file + #uid : 1afa743f953ef3b1c628163029a8d612 diff --git a/doc/example-grids/regular_gaussian_2.yml b/doc/example-grids/regular_gaussian_2.yml index aa0f993e9..865caae8c 100644 --- a/doc/example-grids/regular_gaussian_2.yml +++ b/doc/example-grids/regular_gaussian_2.yml @@ -12,4 +12,4 @@ check : size : 128 lonlat(first) : [3,38.8589] lonlat(last) : [-135.011,-72.4668] - uid : f744facfd6b8ae49384ed48b0495d6dd \ No newline at end of file + #uid : f744facfd6b8ae49384ed48b0495d6dd diff --git a/doc/example-grids/regular_gaussian_3.yml b/doc/example-grids/regular_gaussian_3.yml index 64e9cef17..c6141345e 100644 --- a/doc/example-grids/regular_gaussian_3.yml +++ b/doc/example-grids/regular_gaussian_3.yml @@ -6,4 +6,4 @@ check: size : 128 lonlat(first) : [0,73.7992] lonlat(last) : [337.5,-73.7992] - uid : 1afa743f953ef3b1c628163029a8d612 \ No newline at end of file + #uid : 1afa743f953ef3b1c628163029a8d612 diff --git a/doc/example-grids/regular_gaussian_4.yml b/doc/example-grids/regular_gaussian_4.yml index 0bce56d85..af4f6dac9 100644 --- a/doc/example-grids/regular_gaussian_4.yml +++ b/doc/example-grids/regular_gaussian_4.yml @@ -9,4 +9,4 @@ check : size : 2560 lonlat(first) : [-180,81.6506] lonlat(last) : [177.75,-81.6506] - uid : a5362eb4649fce5d8ccf149cf59cabf4 \ No newline at end of file + #uid : a5362eb4649fce5d8ccf149cf59cabf4 diff --git a/doc/example-grids/regular_lonlat_1.yml b/doc/example-grids/regular_lonlat_1.yml index b4f95343d..8cf088dee 100644 --- a/doc/example-grids/regular_lonlat_1.yml +++ b/doc/example-grids/regular_lonlat_1.yml @@ -8,4 +8,4 @@ check: size : 8320 lonlat(first) : [0,90] lonlat(last) : [357.188,-90] - uid : a5b356177b3ca2f1e65843756d64de76 \ No newline at end of file + #uid : a5b356177b3ca2f1e65843756d64de76 diff --git a/doc/example-grids/zonal_band_1.yml b/doc/example-grids/zonal_band_1.yml index 635828580..4c1ac85af 100644 --- a/doc/example-grids/zonal_band_1.yml +++ b/doc/example-grids/zonal_band_1.yml @@ -9,4 +9,4 @@ check: size : 15 lonlat(first) : [0,70] lonlat(last) : [288,30] - uid : 5dc6e5c29625c95e86afe4efaae17dd7 \ No newline at end of file + #uid : 5dc6e5c29625c95e86afe4efaae17dd7 diff --git a/doc/example-grids/zonal_band_2.yml b/doc/example-grids/zonal_band_2.yml index d1715a541..5ee4d06e8 100644 --- a/doc/example-grids/zonal_band_2.yml +++ b/doc/example-grids/zonal_band_2.yml @@ -9,4 +9,4 @@ check: size : 252 lonlat(first) : [0,30] lonlat(last) : [350,90] - uid : ebf1b438a0a770f7fb20fd41885ae086 \ No newline at end of file + #uid : ebf1b438a0a770f7fb20fd41885ae086 diff --git a/doc/example-grids/zonal_band_3.yml b/doc/example-grids/zonal_band_3.yml index 8871c3efb..ba9c9a8b5 100644 --- a/doc/example-grids/zonal_band_3.yml +++ b/doc/example-grids/zonal_band_3.yml @@ -8,4 +8,4 @@ check: size : 684 lonlat(first) : [0,-90] lonlat(last) : [350,90] - uid : ae584da2de497b8065c63f73115b08f1 \ No newline at end of file + #uid : ae584da2de497b8065c63f73115b08f1 From 30ebb469220bd4d1a33590ad0cb6b354db3a7957 Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Wed, 26 Jun 2019 15:59:17 +0100 Subject: [PATCH 20/86] Apply clang-format --- src/apps/atlas-grids.cc | 225 +++++++++++---------- src/atlas/grid/detail/grid/Regional.cc | 8 +- src/atlas/runtime/AtlasTool.cc | 4 +- src/atlas/util/Rotation.cc | 2 +- src/tests/acceptance_tests/atest_mgrids.cc | 10 +- src/tests/projection/test_rotation.cc | 2 +- 6 files changed, 128 insertions(+), 123 deletions(-) diff --git a/src/apps/atlas-grids.cc b/src/apps/atlas-grids.cc index 5da21cdc6..d5d154d19 100644 --- a/src/apps/atlas-grids.cc +++ b/src/apps/atlas-grids.cc @@ -100,10 +100,10 @@ int AtlasGrids::execute( const Args& args ) { list = false; args.get( "list", list ); if ( list ) do_run = true; - + check = false; args.get( "check", check ); - if( check && !key.empty() ) do_run = true; + if ( check && !key.empty() ) do_run = true; if ( !key.empty() && do_run == false ) { Log::error() << "Option wrong or missing after '" << key << "'" << std::endl; @@ -119,12 +119,10 @@ int AtlasGrids::execute( const Args& args ) { if ( !key.empty() ) { StructuredGrid grid; - PathName spec{ key }; - if( spec.exists() ) { - grid = Grid( Grid::Spec{ spec } ); - } + PathName spec{key}; + if ( spec.exists() ) { grid = Grid( Grid::Spec{spec} ); } else { - grid = Grid( key ); + grid = Grid( key ); } if ( !grid ) return failed(); @@ -138,79 +136,85 @@ int AtlasGrids::execute( const Args& args ) { Log::info() << " Gaussian N number: " << gaussian.N() << std::endl; } Log::info() << " number of points: " << grid.size() << std::endl; - + size_t memsize = grid.size() * sizeof( double ); - + Log::info() << " memory footprint per field (dp): " << eckit::Bytes( memsize ) << std::endl; - - - if( not grid.projection() ) { - Log::info() << " number of latitudes (N-S): " << grid.ny() << std::endl; - Log::info() << " number of longitudes (max): " << grid.nxmax() << std::endl; - - deg = ( grid.y().front() - grid.y().back() ) / ( grid.ny() - 1 ); - km = deg * 40075. / 360.; - Log::info() << " approximate resolution N-S: " << std::setw( 10 ) << std::fixed << deg - << " deg " << km << " km " << std::endl; - - deg = 360. / static_cast( grid.nx( grid.ny() / 2 ) ); - km = deg * 40075. / 360.; - Log::info() << " approximate resolution E-W equator: " << std::setw( 10 ) << std::fixed << deg - << " deg " << km << " km " << std::endl; - - deg = 360. * std::cos( grid.y( grid.ny() / 4 ) * M_PI / 180. ) / - static_cast( grid.nx( grid.ny() / 4 ) ); - km = deg * 40075. / 360.; - Log::info() << " approximate resolution E-W midlat: " << std::setw( 10 ) << std::fixed << deg - << " deg " << km << " km " << std::endl; - - deg = 360. * std::cos( grid.y().front() * M_PI / 180. ) / static_cast( grid.nx().front() ); - km = deg * 40075. / 360.; - - - Log::info() << " approximate resolution E-W pole: " << std::setw( 10 ) << std::fixed << deg - << " deg " << km << " km " << std::endl; - - Log::info() << " spectral truncation -- linear: " << grid.ny() - 1 << std::endl; - Log::info() << " spectral truncation -- quadratic: " - << static_cast( std::floor( 2. / 3. * grid.ny() + 0.5 ) ) - 1 << std::endl; - Log::info() << " spectral truncation -- cubic: " - << static_cast( std::floor( 0.5 * grid.ny() + 0.5 ) ) - 1 << std::endl; + + + if ( not grid.projection() ) { + Log::info() << " number of latitudes (N-S): " << grid.ny() << std::endl; + Log::info() << " number of longitudes (max): " << grid.nxmax() << std::endl; + + deg = ( grid.y().front() - grid.y().back() ) / ( grid.ny() - 1 ); + km = deg * 40075. / 360.; + Log::info() << " approximate resolution N-S: " << std::setw( 10 ) << std::fixed << deg + << " deg " << km << " km " << std::endl; + + deg = 360. / static_cast( grid.nx( grid.ny() / 2 ) ); + km = deg * 40075. / 360.; + Log::info() << " approximate resolution E-W equator: " << std::setw( 10 ) << std::fixed << deg + << " deg " << km << " km " << std::endl; + + deg = 360. * std::cos( grid.y( grid.ny() / 4 ) * M_PI / 180. ) / + static_cast( grid.nx( grid.ny() / 4 ) ); + km = deg * 40075. / 360.; + Log::info() << " approximate resolution E-W midlat: " << std::setw( 10 ) << std::fixed << deg + << " deg " << km << " km " << std::endl; + + deg = 360. * std::cos( grid.y().front() * M_PI / 180. ) / static_cast( grid.nx().front() ); + km = deg * 40075. / 360.; + + + Log::info() << " approximate resolution E-W pole: " << std::setw( 10 ) << std::fixed << deg + << " deg " << km << " km " << std::endl; + + Log::info() << " spectral truncation -- linear: " << grid.ny() - 1 << std::endl; + Log::info() << " spectral truncation -- quadratic: " + << static_cast( std::floor( 2. / 3. * grid.ny() + 0.5 ) ) - 1 << std::endl; + Log::info() << " spectral truncation -- cubic: " + << static_cast( std::floor( 0.5 * grid.ny() + 0.5 ) ) - 1 << std::endl; } - auto precision = Log::info().precision(3); - if( grid.projection().units() == "meters" ) { - Log::info() << " x : [ " << std::setw(10) << std::fixed << grid.xspace().min() / 1000. - << " , " << std::setw(10) << std::fixed << grid.xspace().max() / 1000. << " ] km" << std::endl; - Log::info() << " y : [ " << std::setw(10) << std::fixed << grid.yspace().min() / 1000. - << " , " << std::setw(10) << std::fixed << grid.yspace().max() / 1000. << " ] km" << std::endl; - if( grid.xspace().nxmax() == grid.xspace().nxmin() ) { - Log::info() << " dx : " << grid.xspace().dx()[0] / 1000. << " km" << std::endl; - } - Log::info() << " dy : " << std::abs(grid.yspace()[1]-grid.yspace()[0]) / 1000. << " km" << std::endl; - Log::info() << " lonlat(centre) : " << grid.projection().lonlat( - { 0.5*(grid.xspace().max()+grid.xspace().min()), - 0.5*(grid.yspace().max()+grid.yspace().min())} ) << std::endl; - Log::info() << " lonlat(xmin,ymax) : " << grid.projection().lonlat( { grid.xspace().min(), grid.yspace().max()} ) << std::endl; - Log::info() << " lonlat(xmin,ymin) : " << grid.projection().lonlat( { grid.xspace().min(), grid.yspace().min()} ) << std::endl; - Log::info() << " lonlat(xmax,ymin) : " << grid.projection().lonlat( { grid.xspace().max(), grid.yspace().min()} ) << std::endl; - Log::info() << " lonlat(xmax,ymax) : " << grid.projection().lonlat( { grid.xspace().max(), grid.yspace().max()} ) << std::endl; - } - if( grid.projection().units() == "degrees" ) { - Log::info() << " x : [ " << std::setw(10) << std::fixed << grid.xspace().min() - << " , " << std::setw(10) << std::fixed << grid.xspace().max() << " ] deg" << std::endl; - Log::info() << " y : [ " << std::setw(10) << std::fixed << grid.yspace().min() - << " , " << std::setw(10) << std::fixed << grid.yspace().max() << " ] deg" << std::endl; + auto precision = Log::info().precision( 3 ); + if ( grid.projection().units() == "meters" ) { + Log::info() << " x : [ " << std::setw( 10 ) << std::fixed << grid.xspace().min() / 1000. << " , " + << std::setw( 10 ) << std::fixed << grid.xspace().max() / 1000. << " ] km" << std::endl; + Log::info() << " y : [ " << std::setw( 10 ) << std::fixed << grid.yspace().min() / 1000. << " , " + << std::setw( 10 ) << std::fixed << grid.yspace().max() / 1000. << " ] km" << std::endl; + if ( grid.xspace().nxmax() == grid.xspace().nxmin() ) { + Log::info() << " dx : " << grid.xspace().dx()[0] / 1000. << " km" << std::endl; + } + Log::info() << " dy : " << std::abs( grid.yspace()[1] - grid.yspace()[0] ) / 1000. << " km" + << std::endl; + Log::info() << " lonlat(centre) : " + << grid.projection().lonlat( {0.5 * ( grid.xspace().max() + grid.xspace().min() ), + 0.5 * ( grid.yspace().max() + grid.yspace().min() )} ) + << std::endl; + Log::info() << " lonlat(xmin,ymax) : " + << grid.projection().lonlat( {grid.xspace().min(), grid.yspace().max()} ) << std::endl; + Log::info() << " lonlat(xmin,ymin) : " + << grid.projection().lonlat( {grid.xspace().min(), grid.yspace().min()} ) << std::endl; + Log::info() << " lonlat(xmax,ymin) : " + << grid.projection().lonlat( {grid.xspace().max(), grid.yspace().min()} ) << std::endl; + Log::info() << " lonlat(xmax,ymax) : " + << grid.projection().lonlat( {grid.xspace().max(), grid.yspace().max()} ) << std::endl; + } + if ( grid.projection().units() == "degrees" ) { + Log::info() << " x : [ " << std::setw( 10 ) << std::fixed << grid.xspace().min() << " , " + << std::setw( 10 ) << std::fixed << grid.xspace().max() << " ] deg" << std::endl; + Log::info() << " y : [ " << std::setw( 10 ) << std::fixed << grid.yspace().min() << " , " + << std::setw( 10 ) << std::fixed << grid.yspace().max() << " ] deg" << std::endl; } PointLonLat first_point = *grid.lonlat().begin(); PointLonLat last_point; - for( const auto p : grid.lonlat() ) { - last_point = p; + for ( const auto p : grid.lonlat() ) { + last_point = p; } Log::info() << " lonlat(first) : " << first_point << std::endl; Log::info() << " lonlat(last) : " << last_point << std::endl; - Log::info().precision(precision); + Log::info().precision( precision ); } if ( json ) { std::stringstream stream; @@ -229,77 +233,80 @@ int AtlasGrids::execute( const Args& args ) { stream << "/" << std::flush; std::cout << stream.str() << std::endl; } - - if( check ) { + + if ( check ) { bool check_failed = false; - Log::Channel out; out.setStream( Log::error() ); - PathName spec{ key }; - if( not spec.exists() ) { - out << "Check failed: " << key << " is not a file" << std::endl; - return failed(); + Log::Channel out; + out.setStream( Log::error() ); + PathName spec{key}; + if ( not spec.exists() ) { + out << "Check failed: " << key << " is not a file" << std::endl; + return failed(); } util::Config config_check; - if( not util::Config{spec}.get( "check", config_check ) ) { - out << "Check failed: no \"check\" section in " << key << std::endl; - return failed(); + if ( not util::Config{spec}.get( "check", config_check ) ) { + out << "Check failed: no \"check\" section in " << key << std::endl; + return failed(); } idx_t size; - if( config_check.get("size",size) ) { - if( grid.size() != size ) { - out << "Check failed: grid size " << grid.size() << " expected to be " << size << std::endl; - check_failed = true; + if ( config_check.get( "size", size ) ) { + if ( grid.size() != size ) { + out << "Check failed: grid size " << grid.size() << " expected to be " << size << std::endl; + check_failed = true; } } else { - Log::warning() << "Check for size skipped" << std::endl; + Log::warning() << "Check for size skipped" << std::endl; } std::string uid; - if( config_check.get("uid",uid) ) { - if( grid.uid() != uid ) { - out << "Check failed: grid uid " << grid.uid() << " expected to be " << uid << std::endl; - check_failed = true; + if ( config_check.get( "uid", uid ) ) { + if ( grid.uid() != uid ) { + out << "Check failed: grid uid " << grid.uid() << " expected to be " << uid << std::endl; + check_failed = true; } } else { - Log::warning() << "Check for uid skipped" << std::endl; + Log::warning() << "Check for uid skipped" << std::endl; } - + auto equal = []( const PointLonLat& p, const std::vector& check ) -> bool { - if( not eckit::types::is_approximately_equal( p.lon(), check[0], 5.e-4 ) ) return false; - if( not eckit::types::is_approximately_equal( p.lat(), check[1], 5.e-4 ) ) return false; - return true; + if ( not eckit::types::is_approximately_equal( p.lon(), check[0], 5.e-4 ) ) return false; + if ( not eckit::types::is_approximately_equal( p.lat(), check[1], 5.e-4 ) ) return false; + return true; }; - + std::vector first_point_lonlat; - if( config_check.get("lonlat(first)",first_point_lonlat) ) { + if ( config_check.get( "lonlat(first)", first_point_lonlat ) ) { PointLonLat first_point = *grid.lonlat().begin(); - if( not equal( first_point, first_point_lonlat ) ) { - out << "Check failed: lonlat(first) " << first_point << " expected to be " << PointLonLat( first_point_lonlat.data() ) << std::endl; - check_failed = true; + if ( not equal( first_point, first_point_lonlat ) ) { + out << "Check failed: lonlat(first) " << first_point << " expected to be " + << PointLonLat( first_point_lonlat.data() ) << std::endl; + check_failed = true; } } else { - Log::warning() << "Check for lonlat(first) skipped" << std::endl; + Log::warning() << "Check for lonlat(first) skipped" << std::endl; } std::vector last_point_lonlat; - if( config_check.get("lonlat(last)",last_point_lonlat) ) { - PointLonLat last_point; - for( const auto&& p : grid.lonlat() ) { - last_point = p; - } - if( not equal( last_point, last_point_lonlat ) ) { - out << "Check failed: lonlat(last) " << last_point << " expected to be " << PointLonLat( last_point_lonlat.data() ) << std::endl; - check_failed = true; + if ( config_check.get( "lonlat(last)", last_point_lonlat ) ) { + PointLonLat last_point; + for ( const auto&& p : grid.lonlat() ) { + last_point = p; + } + if ( not equal( last_point, last_point_lonlat ) ) { + out << "Check failed: lonlat(last) " << last_point << " expected to be " + << PointLonLat( last_point_lonlat.data() ) << std::endl; + check_failed = true; } } else { - Log::warning() << "Check for lonlat(last) skipped" << std::endl; + Log::warning() << "Check for lonlat(last) skipped" << std::endl; } - if( check_failed ) return failed(); + if ( check_failed ) return failed(); Log::info() << "SUCCESS: All checks passed" << std::endl; } } diff --git a/src/atlas/grid/detail/grid/Regional.cc b/src/atlas/grid/detail/grid/Regional.cc index f9d01322f..06d20bec7 100644 --- a/src/atlas/grid/detail/grid/Regional.cc +++ b/src/atlas/grid/detail/grid/Regional.cc @@ -175,8 +175,7 @@ struct Parse_ll00_step : ConfigParser { struct Parse_xy00_step : ConfigParser { Parse_xy00_step( const Projection&, const Grid::Config& config ) { valid = config.get( "nx", x.N ) && config.get( "ny", y.N ) && config.get( "dx", x.step ) && - config.get( "dy", y.step ) && config.get( "xmin", x.min ) && - config.get( "ymin", y.min ); + config.get( "dy", y.step ) && config.get( "xmin", x.min ) && config.get( "ymin", y.min ); if ( not valid ) return; @@ -225,7 +224,7 @@ bool ConfigParser::parse( const Projection& projection, const Grid::Config& conf // top-left of domain and increments (any projection allowed) if ( ConfigParser::parse( projection, config, x, y ) ) return true; if ( ConfigParser::parse( projection, config, x, y ) ) return true; - + // bottom-left of domain and increments (any projection allowed) if ( ConfigParser::parse( projection, config, x, y ) ) return true; if ( ConfigParser::parse( projection, config, x, y ) ) return true; @@ -269,7 +268,8 @@ static class regional : public GridBuilder { throw_Exception( "Could not parse configuration for RegularRegional grid", Here() ); } - YSpace yspace = config.getInt( "y_numbering", -1 ) < 0 ? LinearSpacing( y.max, y.min, y.N, y.endpoint ) : LinearSpacing( y.min, y.max, y.N, y.endpoint ); + YSpace yspace = config.getInt( "y_numbering", -1 ) < 0 ? LinearSpacing( y.max, y.min, y.N, y.endpoint ) + : LinearSpacing( y.min, y.max, y.N, y.endpoint ); bool with_endpoint = true; XSpace xspace( {x.min, x.max}, std::vector( y.N, x.N ), with_endpoint ); diff --git a/src/atlas/runtime/AtlasTool.cc b/src/atlas/runtime/AtlasTool.cc index 5359326fa..9f177c6c0 100644 --- a/src/atlas/runtime/AtlasTool.cc +++ b/src/atlas/runtime/AtlasTool.cc @@ -239,9 +239,7 @@ atlas::AtlasTool::AtlasTool( int argc, char** argv ) : eckit::Tool( argc, argv ) eckit::LibEcKit::instance().setAbortHandler( [] { std::cerr << "[" << atlas::mpi::comm().rank() << "] " << "calling MPI_Abort"; - if ( not use_logfile and mpi::comm().size() > 1 ) { - std::cerr << ", logfile: " << logfile_name; - } + if ( not use_logfile and mpi::comm().size() > 1 ) { std::cerr << ", logfile: " << logfile_name; } std::cerr << std::endl; std::this_thread::sleep_for( std::chrono::milliseconds( 3000 ) ); atlas::mpi::comm().abort( 1 ); diff --git a/src/atlas/util/Rotation.cc b/src/atlas/util/Rotation.cc index c57777282..5a9dc53ee 100644 --- a/src/atlas/util/Rotation.cc +++ b/src/atlas/util/Rotation.cc @@ -48,7 +48,7 @@ double wrap_angle( double a ) { return angle.lon(); } -} // (anonymous namespace) +} // namespace void Rotation::print( std::ostream& out ) const { out << "north_pole:" << npole_ << ", south_pole:" << spole_ << ", rotation_angle:" << angle_; diff --git a/src/tests/acceptance_tests/atest_mgrids.cc b/src/tests/acceptance_tests/atest_mgrids.cc index 37fff8c14..9702a62dc 100644 --- a/src/tests/acceptance_tests/atest_mgrids.cc +++ b/src/tests/acceptance_tests/atest_mgrids.cc @@ -38,6 +38,7 @@ double vortex_rollup( double lon, double lat, double t, double mean ); class Program : public AtlasTool { virtual int execute( const Args& args ); + public: Program( int argc, char** argv ); }; @@ -54,21 +55,20 @@ Program::Program( int argc, char** argv ) : AtlasTool( argc, argv ) { add_option( new SimpleOption( "checksum", "File to write that will contains checksums of run" ) ); add_option( new SimpleOption( "gmsh", "Output gmsh" ) ); add_option( new SimpleOption( "no-validate", "Avoid validation of results to increase runtime" ) ); - add_option( new SimpleOption( "partitioner", "Partitioner for gridA (default=equal_regions)") ); + add_option( new SimpleOption( "partitioner", "Partitioner for gridA (default=equal_regions)" ) ); } //----------------------------------------------------------------------------- - -int Program::execute( const Args& args ) { +int Program::execute( const Args& args ) { auto matrix_free = util::Config( "matrix_free", args.getBool( "matrix-free", false ) ); auto ghost = util::Config( "ghost", args.getBool( "ghost", false ) ); auto haloA = option::halo( args.getLong( "haloA", 2 ) ); auto haloB = option::halo( args.getLong( "haloB", 2 ) ); auto checksum_filepath = args.getString( "checksum", displayName() + ".checksum" ); auto partitioner = args.getString( "partitioner", "equal_regions" ); - auto gridA = Grid( args.getString( "gridA" ) ); - auto gridB = Grid( args.getString( "gridB" ) ); + auto gridA = Grid( args.getString( "gridA" ) ); + auto gridB = Grid( args.getString( "gridB" ) ); auto meshgenerator = MeshGenerator( "structured" ); diff --git a/src/tests/projection/test_rotation.cc b/src/tests/projection/test_rotation.cc index 05493079a..c869d5cc2 100644 --- a/src/tests/projection/test_rotation.cc +++ b/src/tests/projection/test_rotation.cc @@ -125,7 +125,7 @@ CASE( "test_rotation_construction" ) { std::vector rotation_poles = {SP, NP, {0., -90.1}, {0., 90.1}}; - for ( auto& p : rotation_poles ) { + for ( auto& p : rotation_poles ) { Rotation s( Config( "south_pole", std::vector{p.lon(), p.lat()} ) ); Log::info() << "rotate_south_pole=" << s << std::endl; EXPECT( s.rotated() == ( p != SP ) ); From 45205c981aa1d69b23aca132cec9db894234eafa Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Wed, 26 Jun 2019 16:28:33 +0100 Subject: [PATCH 21/86] Make atlas-run accept arguments before '-np' or '-n' argument --- tools/atlas-run | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/tools/atlas-run b/tools/atlas-run index a309f40b2..e6e34f7d1 100755 --- a/tools/atlas-run +++ b/tools/atlas-run @@ -1,16 +1,25 @@ #!/bin/bash set -e -key="$1" -case $key in +ATLAS_RUN_MPI_ARGS="" + +while test $# -gt 0; do + + case "$1" in + --*) + ATLAS_RUN_MPI_ARGS="${ATLAS_RUN_MPI_ARGS} $1" + shift # past argument + ;; -n|-np) ATLAS_RUN_NPROCS="$2" shift # past argument shift # past value ;; *) # unknown option + break ;; -esac + esac +done command_exists() { type "$1" &> /dev/null ; @@ -21,7 +30,7 @@ if [ -n "${ATLAS_RUN_NTHREADS}" ]; then fi if command_exists aprun && [[ ${EC_queue:-unset} != "nf" ]] ; then - LAUNCH=aprun + LAUNCH="aprun ${ATLAS_RUN_MPI_ARGS}" if [ -z "${ATLAS_RUN_NPROCS}" ]; then LAUNCH="${LAUNCH} -n 1" else @@ -32,7 +41,7 @@ if command_exists aprun && [[ ${EC_queue:-unset} != "nf" ]] ; then fi elif command_exists srun ; then - LAUNCH=srun + LAUNCH="srun ${ATLAS_RUN_MPI_ARGS}" if [ -n "${ATLAS_RUN_NGPUS}" ]; then LAUNCH="${LAUNCH} --gres=gpu:${ATLAS_RUN_NGPUS}" fi @@ -50,9 +59,9 @@ else if [ -z "${ATLAS_RUN_NPROCS}" ]; then unset LAUNCH elif command_exists mpirun ; then - LAUNCH="mpirun -np ${ATLAS_RUN_NPROCS}" + LAUNCH="mpirun ${ATLAS_RUN_MPI_ARGS} -np ${ATLAS_RUN_NPROCS}" elif command_exists mpiexec; then - LAUNCH="mpiexec -n ${ATLAS_RUN_NPROCS}" + LAUNCH="mpiexec ${ATLAS_RUN_MPI_ARGS} -n ${ATLAS_RUN_NPROCS}" else echo "No MPI driver found (mpirun,mpiexec,aprun,srun)" exit 1 From 162ccbcae986a85ceed1620cb0d20a96137fde83 Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Thu, 27 Jun 2019 10:01:11 +0000 Subject: [PATCH 22/86] Fix use of atlas-run on lxg with gpu resources --- src/tests/CMakeLists.txt | 12 +++++++++--- src/tests/acc/CMakeLists.txt | 4 ++-- src/tests/acceptance_tests/CMakeLists.txt | 3 ++- src/tests/array/CMakeLists.txt | 9 +++++++++ src/tests/field/CMakeLists.txt | 6 +++++- src/tests/functionspace/CMakeLists.txt | 13 +++++++++++-- src/tests/grid/CMakeLists.txt | 7 ++++--- src/tests/interpolation/CMakeLists.txt | 7 +++++++ src/tests/io/CMakeLists.txt | 3 +++ src/tests/mesh/CMakeLists.txt | 12 ++++++++++++ src/tests/numerics/CMakeLists.txt | 3 +++ src/tests/parallel/CMakeLists.txt | 2 ++ src/tests/projection/CMakeLists.txt | 2 +- src/tests/runtime/CMakeLists.txt | 4 ++-- src/tests/trans/CMakeLists.txt | 9 +++++++-- src/tests/util/CMakeLists.txt | 6 ++++++ tools/atlas-run | 12 ++++++++++-- 17 files changed, 95 insertions(+), 19 deletions(-) diff --git a/src/tests/CMakeLists.txt b/src/tests/CMakeLists.txt index 4a6673647..007189bc9 100644 --- a/src/tests/CMakeLists.txt +++ b/src/tests/CMakeLists.txt @@ -38,9 +38,9 @@ endif() # Envisioned to become part of ecbuild_add_test with a CUDA option # in a future ecbuild release macro( atlas_add_cuda_test ) - set( options BOOST ) + set( options "" ) set( single_value_args TARGET ) - set( multi_value_args SOURCES LIBS ) + set( multi_value_args SOURCES LIBS ENVIRONMENT ) cmake_parse_arguments( _PAR "${options}" "${single_value_args}" "${multi_value_args}" ${_FIRST_ARG} ${ARGN} ) if(_PAR_UNPARSED_ARGUMENTS) @@ -69,7 +69,9 @@ macro( atlas_add_cuda_test ) add_test ( NAME ${_PAR_TARGET} COMMAND ${_PAR_TARGET} ) endif() - set_property( TEST ${_PAR_TARGET} APPEND PROPERTY ENVIRONMENT "ATLAS_RUN_NGPUS=1" ) + list( APPEND _PAR_ENVIRONMENT "ATLAS_RUN_NGPUS=1" ) + list( REMOVE_DUPLICATES _PAR_ENVIRONMENT ) + set_property( TEST ${_PAR_TARGET} APPEND PROPERTY ENVIRONMENT "${_PAR_ENVIRONMENT}" ) endif() endmacro() @@ -82,6 +84,10 @@ if( TRANSI_VERSION VERSION_LESS 0.6 )# transi not yet ported to CMake3 include_directories( ${TRANSI_INCLUDE_DIRS} ) endif() +if( ATLAS_GRIDTOOLS_STORAGE_BACKEND_CUDA ) + set( ATLAS_TEST_ENVIRONMENT "ATLAS_RUN_NGPUS=1" ) +endif() + add_subdirectory( acc ) add_subdirectory( array ) add_subdirectory( util ) diff --git a/src/tests/acc/CMakeLists.txt b/src/tests/acc/CMakeLists.txt index 5fccf38c6..2ef6cdcce 100644 --- a/src/tests/acc/CMakeLists.txt +++ b/src/tests/acc/CMakeLists.txt @@ -19,7 +19,7 @@ if( ATLAS_HAVE_GRIDTOOLS_STORAGE AND GRIDTOOLS_HAVE_CUDA AND ENABLE_TESTS AND HA fctest_unified_memory_with_openacc_cxx.cc LIBS atlas_f LINKER_LANGUAGE Fortran - ENVIRONMENT ATLAS_RUN_NGPUS=1 + ENVIRONMENT ${ATLAS_TEST_ENVIRONMENT} ATLAS_RUN_NGPUS=1 ) target_link_libraries( atlas_test_unified_memory_with_openacc ${ACC_Fortran_FLAGS} gridtools::storage ) @@ -29,7 +29,7 @@ if( ATLAS_HAVE_GRIDTOOLS_STORAGE AND GRIDTOOLS_HAVE_CUDA AND ENABLE_TESTS AND HA SOURCES fctest_connectivity_openacc.F90 LIBS atlas_f LINKER_LANGUAGE Fortran - ENVIRONMENT ATLAS_RUN_NGPUS=1 + ENVIRONMENT ${ATLAS_TEST_ENVIRONMENT} ATLAS_RUN_NGPUS=1 ) target_link_libraries( atlas_test_connectivity_openacc ${ACC_Fortran_FLAGS} ) set_target_properties( atlas_test_connectivity_openacc PROPERTIES COMPILE_FLAGS "${ACC_Fortran_FLAGS_STR}" ) diff --git a/src/tests/acceptance_tests/CMakeLists.txt b/src/tests/acceptance_tests/CMakeLists.txt index 36fa208d5..7a8e204e8 100644 --- a/src/tests/acceptance_tests/CMakeLists.txt +++ b/src/tests/acceptance_tests/CMakeLists.txt @@ -38,7 +38,7 @@ function( atlas_atest_mgrids category case nprocs ) foreach( t 1 4 12 ) set( test_name atlas_atest_${category}_mgrids_${gridA}_to_${gridB}_n${n}_t${t} ) ecbuild_add_test( TARGET ${test_name} - COMMAND $ + COMMAND atlas-atest-mgrids ARGS --gridA=${gridA} --gridB=${gridB} --haloA=3 @@ -49,6 +49,7 @@ function( atlas_atest_mgrids category case nprocs ) ${PARTITIONER} MPI ${n} OMP ${t} + ENVIRONMENT ${ATLAS_TEST_ENVIRONMENT} ) list( APPEND checksums ${test_name}.checksum ) list( APPEND case_tests ${test_name} ) diff --git a/src/tests/array/CMakeLists.txt b/src/tests/array/CMakeLists.txt index c9ed65871..c5e1a2eba 100644 --- a/src/tests/array/CMakeLists.txt +++ b/src/tests/array/CMakeLists.txt @@ -10,26 +10,32 @@ ecbuild_add_test( TARGET atlas_test_array_slicer SOURCES test_array_slicer.cc LIBS atlas + ENVIRONMENT ${ATLAS_TEST_ENVIRONMENT} ) ecbuild_add_test( TARGET atlas_test_array SOURCES test_array.cc LIBS atlas + ENVIRONMENT ${ATLAS_TEST_ENVIRONMENT} ) #ecbuild_add_test( TARGET atlas_test_table # SOURCES test_table.cc # LIBS atlas +# ENVIRONMENT ${ATLAS_TEST_ENVIRONMENT} #) ecbuild_add_test( TARGET atlas_test_svector SOURCES test_svector.cc LIBS atlas + ENVIRONMENT ${ATLAS_TEST_ENVIRONMENT} + ) ecbuild_add_test( TARGET atlas_test_array_view_util SOURCES test_array_view_util.cc LIBS atlas + ENVIRONMENT ${ATLAS_TEST_ENVIRONMENT} ) @@ -41,16 +47,19 @@ atlas_add_cuda_test( TARGET atlas_test_array_kernel SOURCES test_array_kernel.cu LIBS atlas + ENVIRONMENT ${ATLAS_TEST_ENVIRONMENT} ) atlas_add_cuda_test( TARGET atlas_test_vector_kernel SOURCES test_vector_kernel.cu LIBS atlas + ENVIRONMENT ${ATLAS_TEST_ENVIRONMENT} ) atlas_add_cuda_test( TARGET atlas_test_svector_kernel SOURCES test_svector_kernel.cu LIBS atlas + ENVIRONMENT ${ATLAS_TEST_ENVIRONMENT} ) diff --git a/src/tests/field/CMakeLists.txt b/src/tests/field/CMakeLists.txt index 411520347..02da6d13c 100644 --- a/src/tests/field/CMakeLists.txt +++ b/src/tests/field/CMakeLists.txt @@ -12,12 +12,14 @@ if( HAVE_FCTEST ) LINKER_LANGUAGE Fortran SOURCES fctest_field.F90 LIBS atlas_f + ENVIRONMENT ${ATLAS_TEST_ENVIRONMENT} ) add_fctest( TARGET atlas_fctest_field_wrap LINKER_LANGUAGE Fortran SOURCES fctest_field_wrap.F90 LIBS atlas_f + ENVIRONMENT ${ATLAS_TEST_ENVIRONMENT} ) add_fctest( TARGET atlas_fctest_field_view @@ -25,6 +27,7 @@ if( HAVE_FCTEST ) SOURCES fctest_field_view.F90 LIBS atlas_f OpenMP::OpenMP_Fortran OMP 3 + ENVIRONMENT ${ATLAS_TEST_ENVIRONMENT} CONDITION ATLAS_HAVE_OMP_Fortran ) @@ -33,6 +36,7 @@ if( HAVE_FCTEST ) LINKER_LANGUAGE Fortran SOURCES fctest_field_host.F90 LIBS atlas_f + ENVIRONMENT ${ATLAS_TEST_ENVIRONMENT} ) add_fctest( TARGET atlas_fctest_field_device @@ -40,7 +44,7 @@ if( HAVE_FCTEST ) LINKER_LANGUAGE Fortran SOURCES fctest_field_gpu.F90 external_acc_routine.F90 LIBS atlas_f - ENVIRONMENT ATLAS_RUN_NGPUS=1 + ENVIRONMENT ${ATLAS_TEST_ENVIRONMENT} ATLAS_RUN_NGPUS=1 ) if( TARGET atlas_fctest_field_device ) diff --git a/src/tests/functionspace/CMakeLists.txt b/src/tests/functionspace/CMakeLists.txt index eda39944c..0417dc323 100644 --- a/src/tests/functionspace/CMakeLists.txt +++ b/src/tests/functionspace/CMakeLists.txt @@ -18,6 +18,7 @@ if( HAVE_FCTEST ) LINKER_LANGUAGE Fortran SOURCES fctest_functionspace.F90 LIBS atlas_f + ENVIRONMENT ${ATLAS_TEST_ENVIRONMENT} ) endif() @@ -25,45 +26,53 @@ endif() ecbuild_add_test( TARGET atlas_test_functionspace SOURCES test_functionspace.cc LIBS atlas + ENVIRONMENT ${ATLAS_TEST_ENVIRONMENT} ) ecbuild_add_test( TARGET atlas_test_structuredcolumns SOURCES test_structuredcolumns.cc LIBS atlas MPI 5 + ENVIRONMENT ${ATLAS_TEST_ENVIRONMENT} CONDITION ECKIT_HAVE_MPI ) ecbuild_add_test( TARGET atlas_test_pointcloud SOURCES test_pointcloud.cc LIBS atlas + ENVIRONMENT ${ATLAS_TEST_ENVIRONMENT} ) ecbuild_add_test( TARGET atlas_test_reduced_halo SOURCES test_reduced_halo.cc LIBS atlas + ENVIRONMENT ${ATLAS_TEST_ENVIRONMENT} ) ecbuild_add_test( TARGET atlas_test_stencil SOURCES test_stencil.cc LIBS atlas + ENVIRONMENT ${ATLAS_TEST_ENVIRONMENT} ) ecbuild_add_executable( TARGET atlas_test_stencil_parallel SOURCES test_stencil_parallel.cc LIBS atlas + ENVIRONMENT ${ATLAS_TEST_ENVIRONMENT} NOINSTALL ) ecbuild_add_test( TARGET atlas_test_stencil_parallel_mpi4 - COMMAND $ + COMMAND atlas_test_stencil_parallel MPI 4 + ENVIRONMENT ${ATLAS_TEST_ENVIRONMENT} CONDITION ECKIT_HAVE_MPI ) ecbuild_add_test( TARGET atlas_test_stencil_parallel_mpi16 - COMMAND $ + COMMAND atlas_test_stencil_parallel MPI 16 + ENVIRONMENT ${ATLAS_TEST_ENVIRONMENT} CONDITION ECKIT_HAVE_MPI ) diff --git a/src/tests/grid/CMakeLists.txt b/src/tests/grid/CMakeLists.txt index ffd64b53a..8a7edd654 100644 --- a/src/tests/grid/CMakeLists.txt +++ b/src/tests/grid/CMakeLists.txt @@ -11,7 +11,7 @@ if( HAVE_FCTEST ) fctest_griddistribution fctest_state) - add_fctest( TARGET atlas_${test} SOURCES ${test}.F90 LINKER_LANGUAGE Fortran LIBS atlas_f ) + add_fctest( TARGET atlas_${test} SOURCES ${test}.F90 LINKER_LANGUAGE Fortran LIBS atlas_f ENVIRONMENT ${ATLAS_TEST_ENVIRONMENT} ) endforeach() endif() @@ -26,7 +26,7 @@ foreach(test test_state test_grid_hash) - ecbuild_add_test( TARGET atlas_${test} SOURCES ${test}.cc LIBS atlas ) + ecbuild_add_test( TARGET atlas_${test} SOURCES ${test}.cc LIBS atlas ENVIRONMENT ${ATLAS_TEST_ENVIRONMENT} ) endforeach() @@ -36,7 +36,8 @@ foreach( grid ${grids} ) get_filename_component( grid_name ${grid} NAME_WE ) set( test_name atlas_test_grid_${grid_name} ) ecbuild_add_test( TARGET ${test_name} - COMMAND $ + COMMAND atlas-grids ARGS ${grid} --check + ENVIRONMENT ${ATLAS_TEST_ENVIRONMENT} ) endforeach() diff --git a/src/tests/interpolation/CMakeLists.txt b/src/tests/interpolation/CMakeLists.txt index 738b75bdf..f97cedf56 100644 --- a/src/tests/interpolation/CMakeLists.txt +++ b/src/tests/interpolation/CMakeLists.txt @@ -10,33 +10,40 @@ ecbuild_add_test( TARGET atlas_test_Quad3D CONDITION ECKIT_HAVE_EIGEN SOURCES test_Quad3D.cc LIBS atlas + ENVIRONMENT ${ATLAS_TEST_ENVIRONMENT} ) ecbuild_add_test( TARGET atlas_test_interpolation_finite_element SOURCES test_interpolation_finite_element.cc LIBS atlas + ENVIRONMENT ${ATLAS_TEST_ENVIRONMENT} ) ecbuild_add_test( TARGET atlas_test_interpolation_cubic_prototype SOURCES test_interpolation_cubic_prototype.cc CubicInterpolationPrototype.h LIBS atlas + ENVIRONMENT ${ATLAS_TEST_ENVIRONMENT} ) ecbuild_add_executable( TARGET atlas_test_interpolation_structured2D SOURCES test_interpolation_structured2D.cc LIBS atlas + ENVIRONMENT ${ATLAS_TEST_ENVIRONMENT} NOINSTALL ) ecbuild_add_test( TARGET atlas_test_interpolation_bilinear COMMAND atlas_test_interpolation_structured2D ARGS --scheme linear + ENVIRONMENT ${ATLAS_TEST_ENVIRONMENT} ) ecbuild_add_test( TARGET atlas_test_interpolation_bicubic COMMAND atlas_test_interpolation_structured2D ARGS --scheme cubic + ENVIRONMENT ${ATLAS_TEST_ENVIRONMENT} ) ecbuild_add_test( TARGET atlas_test_interpolation_biquasicubic COMMAND atlas_test_interpolation_structured2D ARGS --scheme quasicubic + ENVIRONMENT ${ATLAS_TEST_ENVIRONMENT} ) diff --git a/src/tests/io/CMakeLists.txt b/src/tests/io/CMakeLists.txt index 05bc36850..114666c98 100644 --- a/src/tests/io/CMakeLists.txt +++ b/src/tests/io/CMakeLists.txt @@ -9,11 +9,13 @@ ecbuild_add_test( TARGET atlas_test_gmsh SOURCES test_gmsh.cc ../TestMeshes.h LIBS atlas + ENVIRONMENT ${ATLAS_TEST_ENVIRONMENT} ) ecbuild_add_test( TARGET atlas_test_pointcloud_io SOURCES test_pointcloud_io.cc LIBS atlas + ENVIRONMENT ${ATLAS_TEST_ENVIRONMENT} ) if( HAVE_FCTEST ) @@ -22,6 +24,7 @@ add_fctest( TARGET atlas_fctest_gmsh LINKER_LANGUAGE Fortran SOURCES fctest_gmsh.F90 LIBS atlas_f + ENVIRONMENT ${ATLAS_TEST_ENVIRONMENT} ) endif() diff --git a/src/tests/mesh/CMakeLists.txt b/src/tests/mesh/CMakeLists.txt index 838c8b7a6..59fc4c6ea 100644 --- a/src/tests/mesh/CMakeLists.txt +++ b/src/tests/mesh/CMakeLists.txt @@ -13,6 +13,7 @@ if( HAVE_FCTEST ) CONDITION NOT atlas_fctest_mesh_DISABLED SOURCES fctest_mesh.F90 LIBS atlas_f + ENVIRONMENT ${ATLAS_TEST_ENVIRONMENT} ) add_fctest( TARGET atlas_fctest_meshgen @@ -20,18 +21,21 @@ if( HAVE_FCTEST ) CONDITION ON SOURCES fctest_meshgen.F90 LIBS atlas_f + ENVIRONMENT ${ATLAS_TEST_ENVIRONMENT} ) add_fctest( TARGET atlas_fctest_connectivity LINKER_LANGUAGE Fortran SOURCES fctest_connectivity.F90 LIBS atlas_f + ENVIRONMENT ${ATLAS_TEST_ENVIRONMENT} ) add_fctest( TARGET atlas_fctest_elements LINKER_LANGUAGE Fortran SOURCES fctest_elements.F90 LIBS atlas_f + ENVIRONMENT ${ATLAS_TEST_ENVIRONMENT} ) endif() @@ -41,6 +45,7 @@ ecbuild_add_test( TARGET atlas_test_parfields CONDITION ECKIT_HAVE_MPI SOURCES test_parfields.cc LIBS atlas + ENVIRONMENT ${ATLAS_TEST_ENVIRONMENT} ) ecbuild_add_test( TARGET atlas_test_halo @@ -48,6 +53,7 @@ ecbuild_add_test( TARGET atlas_test_halo CONDITION ECKIT_HAVE_MPI SOURCES test_halo.cc ../TestMeshes.h LIBS atlas + ENVIRONMENT ${ATLAS_TEST_ENVIRONMENT} ) ecbuild_add_test( TARGET atlas_test_distmesh @@ -55,6 +61,7 @@ ecbuild_add_test( TARGET atlas_test_distmesh CONDITION ECKIT_HAVE_MPI SOURCES test_distmesh.cc ../TestMeshes.h LIBS atlas + ENVIRONMENT ${ATLAS_TEST_ENVIRONMENT} ) ecbuild_add_test( @@ -62,12 +69,14 @@ ecbuild_add_test( SOURCES test_cgal_mesh_gen_from_points.cc CONDITION ATLAS_HAVE_TESSELATION LIBS atlas + ENVIRONMENT ${ATLAS_TEST_ENVIRONMENT} ) ecbuild_add_test( TARGET atlas_test_accumulate_facets SOURCES test_accumulate_facets.cc LIBS atlas + ENVIRONMENT ${ATLAS_TEST_ENVIRONMENT} ) ecbuild_add_test( TARGET atlas_test_mesh_node2cell @@ -75,6 +84,7 @@ ecbuild_add_test( TARGET atlas_test_mesh_node2cell CONDITION ECKIT_HAVE_MPI SOURCES test_mesh_node2cell.cc LIBS atlas + ENVIRONMENT ${ATLAS_TEST_ENVIRONMENT} ) @@ -82,6 +92,7 @@ foreach( test connectivity elements ll meshgen3d rgg ) ecbuild_add_test( TARGET atlas_test_${test} SOURCES test_${test}.cc LIBS atlas + ENVIRONMENT ${ATLAS_TEST_ENVIRONMENT} ) endforeach() @@ -89,4 +100,5 @@ atlas_add_cuda_test( TARGET atlas_test_connectivity_kernel SOURCES test_connectivity_kernel.cu LIBS atlas + ENVIRONMENT ${ATLAS_TEST_ENVIRONMENT} ) diff --git a/src/tests/numerics/CMakeLists.txt b/src/tests/numerics/CMakeLists.txt index 4a4d32683..9995f5cba 100644 --- a/src/tests/numerics/CMakeLists.txt +++ b/src/tests/numerics/CMakeLists.txt @@ -9,6 +9,7 @@ ecbuild_add_test( TARGET atlas_test_fvm_nabla SOURCES test_fvm_nabla.cc LIBS atlas ${OMP_CXX} + ENVIRONMENT ${ATLAS_TEST_ENVIRONMENT} ) if( HAVE_FCTEST) @@ -16,11 +17,13 @@ if( HAVE_FCTEST) LINKER_LANGUAGE Fortran SOURCES fctest_fvm_nabla.F90 LIBS atlas_f ${OMP_Fortran} + ENVIRONMENT ${ATLAS_TEST_ENVIRONMENT} ) add_fctest( TARGET atlas_fctest_ifs_setup LINKER_LANGUAGE Fortran SOURCES fctest_ifs_setup.F90 LIBS atlas_f + ENVIRONMENT ${ATLAS_TEST_ENVIRONMENT} ) endif() diff --git a/src/tests/parallel/CMakeLists.txt b/src/tests/parallel/CMakeLists.txt index 5841f725b..b66a2ad54 100644 --- a/src/tests/parallel/CMakeLists.txt +++ b/src/tests/parallel/CMakeLists.txt @@ -11,6 +11,7 @@ ecbuild_add_test( TARGET atlas_test_haloexchange CONDITION ECKIT_HAVE_MPI SOURCES test_haloexchange.cc LIBS atlas + ENVIRONMENT ${ATLAS_TEST_ENVIRONMENT} ) ecbuild_add_test( TARGET atlas_test_gather @@ -18,5 +19,6 @@ ecbuild_add_test( TARGET atlas_test_gather CONDITION ECKIT_HAVE_MPI SOURCES test_gather.cc LIBS atlas + ENVIRONMENT ${ATLAS_TEST_ENVIRONMENT} ) diff --git a/src/tests/projection/CMakeLists.txt b/src/tests/projection/CMakeLists.txt index cc5c63b5c..72ba3be35 100644 --- a/src/tests/projection/CMakeLists.txt +++ b/src/tests/projection/CMakeLists.txt @@ -10,6 +10,6 @@ foreach(test test_rotation test_projection_LAEA ) - ecbuild_add_test( TARGET atlas_${test} SOURCES ${test}.cc LIBS atlas ) + ecbuild_add_test( TARGET atlas_${test} SOURCES ${test}.cc LIBS atlas ENVIRONMENT ${ATLAS_TEST_ENVIRONMENT} ) endforeach() diff --git a/src/tests/runtime/CMakeLists.txt b/src/tests/runtime/CMakeLists.txt index 34a7b252b..26b4dcd87 100644 --- a/src/tests/runtime/CMakeLists.txt +++ b/src/tests/runtime/CMakeLists.txt @@ -9,7 +9,7 @@ ecbuild_add_test( TARGET atlas_test_trace SOURCES test_trace.cc LIBS atlas ${OMP_CXX} - ENVIRONMENT ATLAS_TRACE_REPORT=1 + ENVIRONMENT ${ATLAS_TEST_ENVIRONMENT} ATLAS_TRACE_REPORT=1 OMP 2 ) @@ -19,7 +19,7 @@ add_fctest( TARGET atlas_fctest_trace SOURCES fctest_trace.fypp LINKER_LANGUAGE Fortran LIBS atlas_f ${OMP_Fortran} - ENVIRONMENT ATLAS_TRACE_REPORT=1 + ENVIRONMENT ${ATLAS_TEST_ENVIRONMENT} ATLAS_TRACE_REPORT=1 ) endif() diff --git a/src/tests/trans/CMakeLists.txt b/src/tests/trans/CMakeLists.txt index adf10ef87..84437d8a8 100644 --- a/src/tests/trans/CMakeLists.txt +++ b/src/tests/trans/CMakeLists.txt @@ -15,6 +15,7 @@ if( HAVE_FCTEST ) LIBS atlas_f CONDITION ECKIT_HAVE_MPI AND TRANSI_HAVE_MPI MPI 4 + ENVIRONMENT ${ATLAS_TEST_ENVIRONMENT} ) endif() @@ -23,6 +24,7 @@ if( HAVE_FCTEST ) LINKER_LANGUAGE Fortran SOURCES fctest_trans_invtrans_grad.F90 LIBS atlas_f + ENVIRONMENT ${ATLAS_TEST_ENVIRONMENT} ) endif() @@ -33,18 +35,21 @@ ecbuild_add_test( TARGET atlas_test_trans SOURCES test_trans.cc CONDITION ATLAS_HAVE_TRANS AND ECKIT_HAVE_MPI AND TRANSI_HAVE_MPI LIBS atlas transi + ENVIRONMENT ${ATLAS_TEST_ENVIRONMENT} ) ecbuild_add_test( TARGET atlas_test_trans_serial SOURCES test_trans.cc CONDITION ATLAS_HAVE_TRANS LIBS atlas transi + ENVIRONMENT ${ATLAS_TEST_ENVIRONMENT} ) ecbuild_add_test( TARGET atlas_test_trans_invtrans_grad SOURCES test_trans_invtrans_grad.cc CONDITION ATLAS_HAVE_TRANS LIBS atlas transi + ENVIRONMENT ${ATLAS_TEST_ENVIRONMENT} ) # Note: This duplication is needed because transi is a private library of atlas, @@ -54,14 +59,14 @@ if( ATLAS_HAVE_TRANS ) ecbuild_add_test( TARGET atlas_test_transgeneral SOURCES test_transgeneral.cc LIBS atlas transi - ENVIRONMENT ATLAS_TRACE_REPORT=1 + ENVIRONMENT ${ATLAS_TEST_ENVIRONMENT} ATLAS_TRACE_REPORT=1 CONDITION ATLAS_HAVE_FFTW ) else() ecbuild_add_test( TARGET atlas_test_transgeneral SOURCES test_transgeneral.cc LIBS atlas - ENVIRONMENT ATLAS_TRACE_REPORT=1 + ENVIRONMENT ${ATLAS_TEST_ENVIRONMENT} ATLAS_TRACE_REPORT=1 CONDITION ATLAS_HAVE_FFTW ) endif() diff --git a/src/tests/util/CMakeLists.txt b/src/tests/util/CMakeLists.txt index fc72e9f75..5d8e91470 100644 --- a/src/tests/util/CMakeLists.txt +++ b/src/tests/util/CMakeLists.txt @@ -13,6 +13,7 @@ if( HAVE_FCTEST ) LINKER_LANGUAGE Fortran SOURCES fctest_logging.F90 LIBS atlas_f + ENVIRONMENT ${ATLAS_TEST_ENVIRONMENT} ) add_fctest( TARGET atlas_fctest_parametrisation @@ -20,12 +21,14 @@ if( HAVE_FCTEST ) LINKER_LANGUAGE Fortran SOURCES fctest_parametrisation.F90 LIBS atlas_f + ENVIRONMENT ${ATLAS_TEST_ENVIRONMENT} ) add_fctest( TARGET atlas_fctest_metadata LINKER_LANGUAGE Fortran SOURCES fctest_metadata.F90 LIBS atlas_f + ENVIRONMENT ${ATLAS_TEST_ENVIRONMENT} ) endif() @@ -34,6 +37,7 @@ foreach( test earth flags footprint indexview polygon point ) ecbuild_add_test( TARGET atlas_test_${test} SOURCES test_${test}.cc LIBS atlas + ENVIRONMENT ${ATLAS_TEST_ENVIRONMENT} ) endforeach() @@ -41,6 +45,7 @@ ecbuild_add_test( TARGET atlas_test_vector SOURCES test_vector.cc LIBS atlas CONDITION ATLAS_HAVE_GRIDTOOLS_STORAGE + ENVIRONMENT ${ATLAS_TEST_ENVIRONMENT} ) ecbuild_add_test( TARGET atlas_test_metadata @@ -48,5 +53,6 @@ ecbuild_add_test( TARGET atlas_test_metadata CONDITION ECKIT_HAVE_MPI SOURCES test_metadata.cc LIBS atlas + ENVIRONMENT ${ATLAS_TEST_ENVIRONMENT} ) diff --git a/tools/atlas-run b/tools/atlas-run index e6e34f7d1..dbbc82f0d 100755 --- a/tools/atlas-run +++ b/tools/atlas-run @@ -1,7 +1,15 @@ #!/bin/bash -set -e -ATLAS_RUN_MPI_ARGS="" +# (C) Copyright 2013 ECMWF. +# +# This software is licensed under the terms of the Apache Licence Version 2.0 +# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0. +# In applying this licence, ECMWF does not waive the privileges and immunities +# granted to it by virtue of its status as an intergovernmental organisation nor +# does it submit to any jurisdiction. + + +set -e while test $# -gt 0; do From deb056940127247b617a41835a840cc9ef78649e Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Thu, 27 Jun 2019 11:09:05 +0100 Subject: [PATCH 23/86] Fix previous commit --- src/tests/functionspace/CMakeLists.txt | 1 - src/tests/interpolation/CMakeLists.txt | 1 - 2 files changed, 2 deletions(-) diff --git a/src/tests/functionspace/CMakeLists.txt b/src/tests/functionspace/CMakeLists.txt index 0417dc323..94f17b1be 100644 --- a/src/tests/functionspace/CMakeLists.txt +++ b/src/tests/functionspace/CMakeLists.txt @@ -58,7 +58,6 @@ ecbuild_add_test( TARGET atlas_test_stencil ecbuild_add_executable( TARGET atlas_test_stencil_parallel SOURCES test_stencil_parallel.cc LIBS atlas - ENVIRONMENT ${ATLAS_TEST_ENVIRONMENT} NOINSTALL ) diff --git a/src/tests/interpolation/CMakeLists.txt b/src/tests/interpolation/CMakeLists.txt index f97cedf56..7ed769f48 100644 --- a/src/tests/interpolation/CMakeLists.txt +++ b/src/tests/interpolation/CMakeLists.txt @@ -28,7 +28,6 @@ ecbuild_add_test( TARGET atlas_test_interpolation_cubic_prototype ecbuild_add_executable( TARGET atlas_test_interpolation_structured2D SOURCES test_interpolation_structured2D.cc LIBS atlas - ENVIRONMENT ${ATLAS_TEST_ENVIRONMENT} NOINSTALL ) From aea47e61a4e25fc4c990680dec510f442f928c9e Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Thu, 27 Jun 2019 12:32:17 +0100 Subject: [PATCH 24/86] Add missing environment to atlas_test_trans_localcache --- src/tests/trans/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tests/trans/CMakeLists.txt b/src/tests/trans/CMakeLists.txt index 84437d8a8..660ff626c 100644 --- a/src/tests/trans/CMakeLists.txt +++ b/src/tests/trans/CMakeLists.txt @@ -75,6 +75,6 @@ endif() ecbuild_add_test( TARGET atlas_test_trans_localcache SOURCES test_trans_localcache.cc LIBS atlas - ENVIRONMENT ATLAS_TRACE_REPORT=1 + ENVIRONMENT ${ATLAS_TEST_ENVIRONMENT} ATLAS_TRACE_REPORT=1 ) From 9470b349cedbd48340ce43d8528f5e3fed8699a9 Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Fri, 28 Jun 2019 10:33:29 +0100 Subject: [PATCH 25/86] Restore compatibility with ecbuild 2.10 --- src/tests/acceptance_tests/CMakeLists.txt | 6 +++++- src/tests/functionspace/CMakeLists.txt | 7 +++++-- src/tests/interpolation/CMakeLists.txt | 9 ++++++--- 3 files changed, 16 insertions(+), 6 deletions(-) diff --git a/src/tests/acceptance_tests/CMakeLists.txt b/src/tests/acceptance_tests/CMakeLists.txt index 7a8e204e8..70a85d54e 100644 --- a/src/tests/acceptance_tests/CMakeLists.txt +++ b/src/tests/acceptance_tests/CMakeLists.txt @@ -12,6 +12,10 @@ ecbuild_add_executable( LIBS atlas ) +set( exe_atlas-atest-mgrids $ ) +# When ECBUILD-432 is fixed (already fixed in develop on top of ecbuild 3.0.0), we don't need TARGET_FILE + + if( HAVE_TESTS ) ecbuild_add_option( FEATURE ACCEPTANCE_TESTS DEFAULT OFF ) endif() @@ -38,7 +42,7 @@ function( atlas_atest_mgrids category case nprocs ) foreach( t 1 4 12 ) set( test_name atlas_atest_${category}_mgrids_${gridA}_to_${gridB}_n${n}_t${t} ) ecbuild_add_test( TARGET ${test_name} - COMMAND atlas-atest-mgrids + COMMAND ${exe_atlas-atest-mgrids} ARGS --gridA=${gridA} --gridB=${gridB} --haloA=3 diff --git a/src/tests/functionspace/CMakeLists.txt b/src/tests/functionspace/CMakeLists.txt index 94f17b1be..b6aa21cc4 100644 --- a/src/tests/functionspace/CMakeLists.txt +++ b/src/tests/functionspace/CMakeLists.txt @@ -61,15 +61,18 @@ ecbuild_add_executable( TARGET atlas_test_stencil_parallel NOINSTALL ) +set( exe_atlas_test_stencil_parallel $ ) +# When ECBUILD-432 is fixed (already fixed in develop on top of ecbuild 3.0.0), we don't need TARGET_FILE + ecbuild_add_test( TARGET atlas_test_stencil_parallel_mpi4 - COMMAND atlas_test_stencil_parallel + COMMAND ${exe_atlas_test_stencil_parallel} MPI 4 ENVIRONMENT ${ATLAS_TEST_ENVIRONMENT} CONDITION ECKIT_HAVE_MPI ) ecbuild_add_test( TARGET atlas_test_stencil_parallel_mpi16 - COMMAND atlas_test_stencil_parallel + COMMAND ${exe_atlas_test_stencil_parallel} MPI 16 ENVIRONMENT ${ATLAS_TEST_ENVIRONMENT} CONDITION ECKIT_HAVE_MPI diff --git a/src/tests/interpolation/CMakeLists.txt b/src/tests/interpolation/CMakeLists.txt index 7ed769f48..cf9b3c368 100644 --- a/src/tests/interpolation/CMakeLists.txt +++ b/src/tests/interpolation/CMakeLists.txt @@ -31,18 +31,21 @@ ecbuild_add_executable( TARGET atlas_test_interpolation_structured2D NOINSTALL ) +set( exe_atlas_test_interpolation_structured2D $ ) +# When ECBUILD-432 is fixed (already fixed in develop on top of ecbuild 3.0.0), we don't need TARGET_FILE + ecbuild_add_test( TARGET atlas_test_interpolation_bilinear - COMMAND atlas_test_interpolation_structured2D ARGS --scheme linear + COMMAND ${exe_atlas_test_interpolation_structured2D} ARGS --scheme linear ENVIRONMENT ${ATLAS_TEST_ENVIRONMENT} ) ecbuild_add_test( TARGET atlas_test_interpolation_bicubic - COMMAND atlas_test_interpolation_structured2D ARGS --scheme cubic + COMMAND ${exe_atlas_test_interpolation_structured2D} ARGS --scheme cubic ENVIRONMENT ${ATLAS_TEST_ENVIRONMENT} ) ecbuild_add_test( TARGET atlas_test_interpolation_biquasicubic - COMMAND atlas_test_interpolation_structured2D ARGS --scheme quasicubic + COMMAND ${exe_atlas_test_interpolation_structured2D} ARGS --scheme quasicubic ENVIRONMENT ${ATLAS_TEST_ENVIRONMENT} ) From 3d877fda298095cee6ab2779295aba023ed705ff Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Mon, 1 Jul 2019 08:47:34 +0000 Subject: [PATCH 26/86] Restore compatibility with ecbuild 2.10 --- src/tests/interpolation/CMakeLists.txt | 36 ++++++++++++++++++++++---- 1 file changed, 31 insertions(+), 5 deletions(-) diff --git a/src/tests/interpolation/CMakeLists.txt b/src/tests/interpolation/CMakeLists.txt index cf9b3c368..67e72b624 100644 --- a/src/tests/interpolation/CMakeLists.txt +++ b/src/tests/interpolation/CMakeLists.txt @@ -31,21 +31,47 @@ ecbuild_add_executable( TARGET atlas_test_interpolation_structured2D NOINSTALL ) -set( exe_atlas_test_interpolation_structured2D $ ) +if( ECBUILD-432-fixed ) # When ECBUILD-432 is fixed (already fixed in develop on top of ecbuild 3.0.0), we don't need TARGET_FILE - ecbuild_add_test( TARGET atlas_test_interpolation_bilinear - COMMAND ${exe_atlas_test_interpolation_structured2D} ARGS --scheme linear + COMMAND atlas_test_interpolation_structured2D ARGS --scheme linear ENVIRONMENT ${ATLAS_TEST_ENVIRONMENT} ) ecbuild_add_test( TARGET atlas_test_interpolation_bicubic - COMMAND ${exe_atlas_test_interpolation_structured2D} ARGS --scheme cubic + COMMAND atlas_test_interpolation_structured2D ARGS --scheme cubic ENVIRONMENT ${ATLAS_TEST_ENVIRONMENT} ) ecbuild_add_test( TARGET atlas_test_interpolation_biquasicubic - COMMAND ${exe_atlas_test_interpolation_structured2D} ARGS --scheme quasicubic + COMMAND atlas_test_interpolation_structured2D ARGS --scheme quasicubic ENVIRONMENT ${ATLAS_TEST_ENVIRONMENT} ) +else() + # TO BE REMOVED! + + set( exe_atlas_test_interpolation_structured2D $ ) + if( CMAKE_CROSSCOMPILING_EMULATOR ) + set( exe_atlas_test_interpolation_structured2D ${CMAKE_CROSSCOMPILING_EMULATOR} ) + set( arg_atlas_test_interpolation_structured2D $ ) + endif() + + ecbuild_add_test( TARGET atlas_test_interpolation_bilinear + COMMAND ${exe_atlas_test_interpolation_structured2D} ARGS ${arg_atlas_test_interpolation_structured2D} --scheme linear + ENVIRONMENT ${ATLAS_TEST_ENVIRONMENT} + ) + + ecbuild_add_test( TARGET atlas_test_interpolation_bicubic + COMMAND ${exe_atlas_test_interpolation_structured2D} ARGS ${arg_atlas_test_interpolation_structured2D} --scheme cubic + ENVIRONMENT ${ATLAS_TEST_ENVIRONMENT} + ) + + ecbuild_add_test( TARGET atlas_test_interpolation_biquasicubic + COMMAND ${exe_atlas_test_interpolation_structured2D} ARGS ${arg_atlas_test_interpolation_structured2D} --scheme quasicubic + ENVIRONMENT ${ATLAS_TEST_ENVIRONMENT} + ) +endif() + + + From bfd993a8e835139cc297d0d05b2d9783811e4065 Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Fri, 28 Jun 2019 15:08:55 +0100 Subject: [PATCH 27/86] Allow to create GlobalDomain easily --- src/atlas/domain/Domain.cc | 22 +++++++++++++++++++--- src/atlas/domain/Domain.h | 19 +++++++++++++++++++ 2 files changed, 38 insertions(+), 3 deletions(-) diff --git a/src/atlas/domain/Domain.cc b/src/atlas/domain/Domain.cc index 82c666462..268533d2a 100644 --- a/src/atlas/domain/Domain.cc +++ b/src/atlas/domain/Domain.cc @@ -26,7 +26,8 @@ RectangularDomain::RectangularDomain( const Interval& x, const Interval& y, cons Domain( ( RD::is_global( x, y, units ) ) ? new atlas::domain::GlobalDomain( x[0] ) : ( RD::is_zonal_band( x, units ) ? new atlas::domain::ZonalBandDomain( y, x[0] ) - : new atlas::domain::RectangularDomain( x, y, units ) ) ) {} + : new atlas::domain::RectangularDomain( x, y, units ) ) ), + domain_( dynamic_cast( get() ) ) {} RectangularDomain::RectangularDomain( const Domain& domain ) : Domain( domain ), @@ -62,16 +63,31 @@ double RectangularDomain::ymax() const { ZonalBandDomain::ZonalBandDomain( const Interval& y ) : RectangularDomain( ( ZD::is_global( y ) ) ? new atlas::domain::GlobalDomain() - : new atlas::domain::ZonalBandDomain( y ) ) {} + : new atlas::domain::ZonalBandDomain( y ) ), + domain_( dynamic_cast( get() ) ) {} ZonalBandDomain::ZonalBandDomain( const Interval& y, const double& west ) : RectangularDomain( ( ZD::is_global( y ) ) ? new atlas::domain::GlobalDomain( west ) - : new atlas::domain::ZonalBandDomain( y, west ) ) {} + : new atlas::domain::ZonalBandDomain( y, west ) ), + domain_( dynamic_cast( get() ) ) {} ZonalBandDomain::ZonalBandDomain( const Domain& domain ) : RectangularDomain( domain ), domain_( dynamic_cast( get() ) ) {} +GlobalDomain::GlobalDomain( const double& west ) : + ZonalBandDomain( new atlas::domain::GlobalDomain( west ) ), + domain_( dynamic_cast( get() ) ) {} + +GlobalDomain::GlobalDomain() : + ZonalBandDomain( new atlas::domain::GlobalDomain() ), + domain_( dynamic_cast( get() ) ) {} + +GlobalDomain::GlobalDomain( const Domain& domain ) : + ZonalBandDomain( domain ), + domain_( dynamic_cast( get() ) ) {} + + std::string atlas::Domain::type() const { return get()->type(); } diff --git a/src/atlas/domain/Domain.h b/src/atlas/domain/Domain.h index 407a6affc..5b8129379 100644 --- a/src/atlas/domain/Domain.h +++ b/src/atlas/domain/Domain.h @@ -143,6 +143,25 @@ class ZonalBandDomain : public RectangularDomain { const ::atlas::domain::ZonalBandDomain* domain_; }; + +namespace domain { +class GlobalDomain; +} + +//--------------------------------------------------------------------------------------------------------------------- + +class GlobalDomain : public ZonalBandDomain { +public: + GlobalDomain( const double& west ); + GlobalDomain( ); + GlobalDomain( const Domain& ); + + operator bool() { return domain_; } + +private: + const ::atlas::domain::GlobalDomain* domain_; +}; + //--------------------------------------------------------------------------------------------------------------------- } // namespace atlas From d140a0b94f304d6dc39b7a0c1f87d2a2a8ae8f26 Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Fri, 28 Jun 2019 15:14:40 +0100 Subject: [PATCH 28/86] ATLAS-238 UnstructuredGrid creation through Config --- doc/example-grids/unstructured_1.yml | 14 ++ src/apps/atlas-grids.cc | 171 +++++++++++---------- src/atlas/grid/detail/grid/Unstructured.cc | 76 +++++++-- 3 files changed, 166 insertions(+), 95 deletions(-) create mode 100644 doc/example-grids/unstructured_1.yml diff --git a/doc/example-grids/unstructured_1.yml b/doc/example-grids/unstructured_1.yml new file mode 100644 index 000000000..2df89a218 --- /dev/null +++ b/doc/example-grids/unstructured_1.yml @@ -0,0 +1,14 @@ +type : "unstructured" + +xy : [ + 0, 90, + 0, -90, + 180,-90, + 180, 90 +] + +check : + size : 4 + lonlat(first) : [0,90] + lonlat(last) : [180,90] + uid : b704ab522505497c6d622f27c429bffe diff --git a/src/apps/atlas-grids.cc b/src/apps/atlas-grids.cc index d5d154d19..b08290f00 100644 --- a/src/apps/atlas-grids.cc +++ b/src/apps/atlas-grids.cc @@ -117,10 +117,12 @@ int AtlasGrids::execute( const Args& args ) { } if ( !key.empty() ) { - StructuredGrid grid; + Grid grid; PathName spec{key}; - if ( spec.exists() ) { grid = Grid( Grid::Spec{spec} ); } + if ( spec.exists() ) { + grid = Grid( Grid::Spec{spec} ); + } else { grid = Grid( key ); } @@ -128,7 +130,6 @@ int AtlasGrids::execute( const Args& args ) { if ( !grid ) return failed(); if ( info ) { - double deg, km; Log::info() << "Grid " << key << std::endl; Log::info() << " name: " << grid.name() << std::endl; Log::info() << " uid: " << grid.uid() << std::endl; @@ -142,79 +143,83 @@ int AtlasGrids::execute( const Args& args ) { Log::info() << " memory footprint per field (dp): " << eckit::Bytes( memsize ) << std::endl; - - if ( not grid.projection() ) { - Log::info() << " number of latitudes (N-S): " << grid.ny() << std::endl; - Log::info() << " number of longitudes (max): " << grid.nxmax() << std::endl; - - deg = ( grid.y().front() - grid.y().back() ) / ( grid.ny() - 1 ); - km = deg * 40075. / 360.; - Log::info() << " approximate resolution N-S: " << std::setw( 10 ) << std::fixed << deg - << " deg " << km << " km " << std::endl; - - deg = 360. / static_cast( grid.nx( grid.ny() / 2 ) ); - km = deg * 40075. / 360.; - Log::info() << " approximate resolution E-W equator: " << std::setw( 10 ) << std::fixed << deg - << " deg " << km << " km " << std::endl; - - deg = 360. * std::cos( grid.y( grid.ny() / 4 ) * M_PI / 180. ) / - static_cast( grid.nx( grid.ny() / 4 ) ); - km = deg * 40075. / 360.; - Log::info() << " approximate resolution E-W midlat: " << std::setw( 10 ) << std::fixed << deg - << " deg " << km << " km " << std::endl; - - deg = 360. * std::cos( grid.y().front() * M_PI / 180. ) / static_cast( grid.nx().front() ); - km = deg * 40075. / 360.; - - - Log::info() << " approximate resolution E-W pole: " << std::setw( 10 ) << std::fixed << deg - << " deg " << km << " km " << std::endl; - - Log::info() << " spectral truncation -- linear: " << grid.ny() - 1 << std::endl; - Log::info() << " spectral truncation -- quadratic: " - << static_cast( std::floor( 2. / 3. * grid.ny() + 0.5 ) ) - 1 << std::endl; - Log::info() << " spectral truncation -- cubic: " - << static_cast( std::floor( 0.5 * grid.ny() + 0.5 ) ) - 1 << std::endl; - } - - auto precision = Log::info().precision( 3 ); - if ( grid.projection().units() == "meters" ) { - Log::info() << " x : [ " << std::setw( 10 ) << std::fixed << grid.xspace().min() / 1000. << " , " - << std::setw( 10 ) << std::fixed << grid.xspace().max() / 1000. << " ] km" << std::endl; - Log::info() << " y : [ " << std::setw( 10 ) << std::fixed << grid.yspace().min() / 1000. << " , " - << std::setw( 10 ) << std::fixed << grid.yspace().max() / 1000. << " ] km" << std::endl; - if ( grid.xspace().nxmax() == grid.xspace().nxmin() ) { - Log::info() << " dx : " << grid.xspace().dx()[0] / 1000. << " km" << std::endl; + if ( auto structuredgrid = StructuredGrid( grid ) ) { + + if ( not grid.projection() ) { + double deg, km; + + Log::info() << " number of latitudes (N-S): " << structuredgrid.ny() << std::endl; + Log::info() << " number of longitudes (max): " << structuredgrid.nxmax() << std::endl; + + deg = ( structuredgrid.y().front() - structuredgrid.y().back() ) / ( structuredgrid.ny() - 1 ); + km = deg * 40075. / 360.; + Log::info() << " approximate resolution N-S: " << std::setw( 10 ) << std::fixed << deg + << " deg " << km << " km " << std::endl; + + deg = 360. / static_cast( structuredgrid.nx( structuredgrid.ny() / 2 ) ); + km = deg * 40075. / 360.; + Log::info() << " approximate resolution E-W equator: " << std::setw( 10 ) << std::fixed << deg + << " deg " << km << " km " << std::endl; + + deg = 360. * std::cos( structuredgrid.y( structuredgrid.ny() / 4 ) * M_PI / 180. ) / + static_cast( structuredgrid.nx( structuredgrid.ny() / 4 ) ); + km = deg * 40075. / 360.; + Log::info() << " approximate resolution E-W midlat: " << std::setw( 10 ) << std::fixed << deg + << " deg " << km << " km " << std::endl; + + deg = 360. * std::cos( structuredgrid.y().front() * M_PI / 180. ) / static_cast( structuredgrid.nx().front() ); + km = deg * 40075. / 360.; + + + Log::info() << " approximate resolution E-W pole: " << std::setw( 10 ) << std::fixed << deg + << " deg " << km << " km " << std::endl; + + Log::info() << " spectral truncation -- linear: " << structuredgrid.ny() - 1 << std::endl; + Log::info() << " spectral truncation -- quadratic: " + << static_cast( std::floor( 2. / 3. * structuredgrid.ny() + 0.5 ) ) - 1 << std::endl; + Log::info() << " spectral truncation -- cubic: " + << static_cast( std::floor( 0.5 * structuredgrid.ny() + 0.5 ) ) - 1 << std::endl; } - Log::info() << " dy : " << std::abs( grid.yspace()[1] - grid.yspace()[0] ) / 1000. << " km" - << std::endl; - Log::info() << " lonlat(centre) : " - << grid.projection().lonlat( {0.5 * ( grid.xspace().max() + grid.xspace().min() ), - 0.5 * ( grid.yspace().max() + grid.yspace().min() )} ) - << std::endl; - Log::info() << " lonlat(xmin,ymax) : " - << grid.projection().lonlat( {grid.xspace().min(), grid.yspace().max()} ) << std::endl; - Log::info() << " lonlat(xmin,ymin) : " - << grid.projection().lonlat( {grid.xspace().min(), grid.yspace().min()} ) << std::endl; - Log::info() << " lonlat(xmax,ymin) : " - << grid.projection().lonlat( {grid.xspace().max(), grid.yspace().min()} ) << std::endl; - Log::info() << " lonlat(xmax,ymax) : " - << grid.projection().lonlat( {grid.xspace().max(), grid.yspace().max()} ) << std::endl; - } - if ( grid.projection().units() == "degrees" ) { - Log::info() << " x : [ " << std::setw( 10 ) << std::fixed << grid.xspace().min() << " , " - << std::setw( 10 ) << std::fixed << grid.xspace().max() << " ] deg" << std::endl; - Log::info() << " y : [ " << std::setw( 10 ) << std::fixed << grid.yspace().min() << " , " - << std::setw( 10 ) << std::fixed << grid.yspace().max() << " ] deg" << std::endl; - } - PointLonLat first_point = *grid.lonlat().begin(); - PointLonLat last_point; - for ( const auto p : grid.lonlat() ) { - last_point = p; + + auto precision = Log::info().precision( 3 ); + if ( grid.projection().units() == "meters" ) { + Log::info() << " x : [ " << std::setw( 10 ) << std::fixed << structuredgrid.xspace().min() / 1000. << " , " + << std::setw( 10 ) << std::fixed << structuredgrid.xspace().max() / 1000. << " ] km" << std::endl; + Log::info() << " y : [ " << std::setw( 10 ) << std::fixed << structuredgrid.yspace().min() / 1000. << " , " + << std::setw( 10 ) << std::fixed << structuredgrid.yspace().max() / 1000. << " ] km" << std::endl; + if ( structuredgrid.xspace().nxmax() == structuredgrid.xspace().nxmin() ) { + Log::info() << " dx : " << structuredgrid.xspace().dx()[0] / 1000. << " km" << std::endl; + } + Log::info() << " dy : " << std::abs( structuredgrid.yspace()[1] - structuredgrid.yspace()[0] ) / 1000. << " km" + << std::endl; + Log::info() << " lonlat(centre) : " + << grid.projection().lonlat( {0.5 * ( structuredgrid.xspace().max() + structuredgrid.xspace().min() ), + 0.5 * ( structuredgrid.yspace().max() + structuredgrid.yspace().min() )} ) + << std::endl; + Log::info() << " lonlat(xmin,ymax) : " + << grid.projection().lonlat( {structuredgrid.xspace().min(), structuredgrid.yspace().max()} ) << std::endl; + Log::info() << " lonlat(xmin,ymin) : " + << grid.projection().lonlat( {structuredgrid.xspace().min(), structuredgrid.yspace().min()} ) << std::endl; + Log::info() << " lonlat(xmax,ymin) : " + << grid.projection().lonlat( {structuredgrid.xspace().max(), structuredgrid.yspace().min()} ) << std::endl; + Log::info() << " lonlat(xmax,ymax) : " + << grid.projection().lonlat( {structuredgrid.xspace().max(), structuredgrid.yspace().max()} ) << std::endl; + } + if ( grid.projection().units() == "degrees" ) { + Log::info() << " x : [ " << std::setw( 10 ) << std::fixed << structuredgrid.xspace().min() << " , " + << std::setw( 10 ) << std::fixed << structuredgrid.xspace().max() << " ] deg" << std::endl; + Log::info() << " y : [ " << std::setw( 10 ) << std::fixed << structuredgrid.yspace().min() << " , " + << std::setw( 10 ) << std::fixed << structuredgrid.yspace().max() << " ] deg" << std::endl; + } + PointLonLat first_point = *grid.lonlat().begin(); + PointLonLat last_point; + for ( const auto p : grid.lonlat() ) { + last_point = p; + } + Log::info() << " lonlat(first) : " << first_point << std::endl; + Log::info() << " lonlat(last) : " << last_point << std::endl; + Log::info().precision( precision ); } - Log::info() << " lonlat(first) : " << first_point << std::endl; - Log::info() << " lonlat(last) : " << last_point << std::endl; - Log::info().precision( precision ); } if ( json ) { std::stringstream stream; @@ -225,13 +230,15 @@ int AtlasGrids::execute( const Args& args ) { } if ( rtable ) { - std::stringstream stream; - stream << "&NAMRGRI\n"; - for ( idx_t j = 0; j < grid.ny(); ++j ) - stream << " NRGRI(" << std::setfill( '0' ) << std::setw( 5 ) << 1 + j << ")=" << std::setfill( ' ' ) - << std::setw( 5 ) << grid.nx( j ) << ",\n"; - stream << "/" << std::flush; - std::cout << stream.str() << std::endl; + if ( auto structuredgrid = StructuredGrid( grid ) ) { + std::stringstream stream; + stream << "&NAMRGRI\n"; + for ( idx_t j = 0; j < structuredgrid.ny(); ++j ) + stream << " NRGRI(" << std::setfill( '0' ) << std::setw( 5 ) << 1 + j << ")=" << std::setfill( ' ' ) + << std::setw( 5 ) << structuredgrid.nx( j ) << ",\n"; + stream << "/" << std::flush; + std::cout << stream.str() << std::endl; + } } if ( check ) { @@ -294,7 +301,7 @@ int AtlasGrids::execute( const Args& args ) { std::vector last_point_lonlat; if ( config_check.get( "lonlat(last)", last_point_lonlat ) ) { PointLonLat last_point; - for ( const auto&& p : grid.lonlat() ) { + for ( const auto p : grid.lonlat() ) { last_point = p; } if ( not equal( last_point, last_point_lonlat ) ) { diff --git a/src/atlas/grid/detail/grid/Unstructured.cc b/src/atlas/grid/detail/grid/Unstructured.cc index 64513e77a..de964ff73 100644 --- a/src/atlas/grid/detail/grid/Unstructured.cc +++ b/src/atlas/grid/detail/grid/Unstructured.cc @@ -13,6 +13,7 @@ #include #include #include +#include #include "eckit/types/FloatCompare.h" #include "eckit/utils/Hash.h" @@ -21,6 +22,7 @@ #include "atlas/field/Field.h" #include "atlas/grid/Iterator.h" #include "atlas/grid/detail/grid/GridFactory.h" +#include "atlas/grid/detail/grid/GridBuilder.h" #include "atlas/mesh/Mesh.h" #include "atlas/mesh/Nodes.h" #include "atlas/option.h" @@ -79,7 +81,7 @@ Unstructured::Unstructured( const Grid& grid, Domain domain ) : Grid() { domain_ = domain; points_.reset( new std::vector ); points_->reserve( grid.size() ); - if ( not domain_ ) { domain_ = Domain( option::type( "global" ) ); } + if ( not domain_ ) { domain_ = GlobalDomain(); } atlas::grid::IteratorXY it( grid.xy_begin() ); PointXY p; if ( RectangularDomain( domain_ ) ) { @@ -102,33 +104,52 @@ Unstructured::Unstructured( const Grid& grid, Domain domain ) : Grid() { points_->shrink_to_fit(); } -Unstructured::Unstructured( const util::Config& ) : Grid() { +Unstructured::Unstructured( const util::Config& config ) : Grid() { util::Config config_domain; - config_domain.set( "type", "global" ); + if( not config.get("domain", config_domain) ) { + config_domain.set( "type", "global" ); + } domain_ = Domain( config_domain ); - ATLAS_NOTIMPLEMENTED; + std::vector xy; + if( config.get( "xy", xy ) ) { + const size_t N = xy.size()/2; + points_.reset( new std::vector ); + points_->reserve( N ); + for( size_t n=0; nemplace_back( PointXY{xy[2*n],xy[2*n+1]} ); + } + } else { + std::vector x; + std::vector y; + if( not config.get( "x", x ) ) { + throw_Exception("x missing from configuration"); + } + if( not config.get( "y", y ) ) { + throw_Exception("y missing from configuration"); + } + ATLAS_ASSERT( x.size() == y.size() ); + points_.reset( new std::vector ); + points_->reserve( x.size() ); + for( size_t n=0; nemplace_back( PointXY{x[n],y[n]} ); + } + } } Unstructured::Unstructured( std::vector* pts ) : Grid(), points_( pts ) { - util::Config config_domain; - config_domain.set( "type", "global" ); - domain_ = Domain( config_domain ); + domain_ = GlobalDomain(); } Unstructured::Unstructured( std::vector&& pts ) : Grid(), points_( new std::vector( std::move( pts ) ) ) { - util::Config config_domain; - config_domain.set( "type", "global" ); - domain_ = Domain( config_domain ); + domain_ = GlobalDomain(); } Unstructured::Unstructured( std::initializer_list initializer_list ) : Grid(), points_( new std::vector( initializer_list ) ) { - util::Config config_domain; - config_domain.set( "type", "global" ); - domain_ = Domain( config_domain ); + domain_ = GlobalDomain(); } Unstructured::~Unstructured() {} @@ -202,6 +223,35 @@ bool Unstructured::IteratorXYPredicated::next( PointXY& /*xy*/ ) { #endif } +#if 1 +namespace { // anonymous + +static class unstructured : public GridBuilder { + using Implementation = atlas::Grid::Implementation; + using Config = Grid::Config; + +public: + unstructured() : GridBuilder( "unstructured" ) {} + + virtual void print( std::ostream& os ) const { + os << std::left << std::setw( 20 ) << " " + << "Unstructured grid"; + } + + virtual const Implementation* create( const std::string& /* name */, const Config& ) const { + throw_NotImplemented( "Cannot create unstructured grid from name", Here() ); + } + + virtual const Implementation* create( const Config& config ) const { + return new Unstructured( config ); + } + +} unstructured_; + +} // anonymous namespace +#endif + + } // namespace grid } // namespace detail } // namespace grid From 79b2ec72eb69d959ca9c3fe81731246935410a26 Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Tue, 11 Jun 2019 13:39:17 +0100 Subject: [PATCH 29/86] ATLAS-233 Allow TransLocal backend to atlas_Trans to be used in Fortran --- src/atlas/CMakeLists.txt | 2 + src/atlas/functionspace/Spectral.cc | 11 +- src/atlas/functionspace/Spectral.h | 2 +- src/atlas/trans/Trans.cc | 4 + src/atlas/trans/Trans.h | 4 + src/atlas/trans/detail/TransImpl.cc | 5 + src/atlas/trans/detail/TransImpl.h | 20 +- src/atlas/trans/detail/TransInterface.cc | 224 ++++++++++++++ src/atlas/trans/detail/TransInterface.h | 96 ++++++ src/atlas/trans/ifs/TransIFS.cc | 32 +- src/atlas/trans/ifs/TransIFS.h | 60 +--- src/atlas/trans/ifs/TransIFSNodeColumns.cc | 1 + .../trans/ifs/TransIFSStructuredColumns.cc | 1 + src/atlas/trans/local/TransLocal.cc | 81 ++++- src/atlas/trans/local/TransLocal.h | 9 +- src/atlas_f/CMakeLists.txt | 2 +- src/atlas_f/trans/atlas_Trans_module.F90 | 292 ++++-------------- src/tests/trans/CMakeLists.txt | 6 +- src/tests/trans/fctest_trans.F90 | 23 +- 19 files changed, 546 insertions(+), 329 deletions(-) create mode 100644 src/atlas/trans/detail/TransInterface.cc create mode 100644 src/atlas/trans/detail/TransInterface.h diff --git a/src/atlas/CMakeLists.txt b/src/atlas/CMakeLists.txt index 6b845578c..21fda484d 100644 --- a/src/atlas/CMakeLists.txt +++ b/src/atlas/CMakeLists.txt @@ -391,6 +391,8 @@ trans/detail/TransFactory.h trans/detail/TransFactory.cc trans/detail/TransImpl.h trans/detail/TransImpl.cc +trans/detail/TransInterface.h +trans/detail/TransInterface.cc ) if( ATLAS_HAVE_TRANS ) list( APPEND atlas_numerics_srcs diff --git a/src/atlas/functionspace/Spectral.cc b/src/atlas/functionspace/Spectral.cc index e25793a04..a5d33d258 100644 --- a/src/atlas/functionspace/Spectral.cc +++ b/src/atlas/functionspace/Spectral.cc @@ -42,7 +42,6 @@ namespace atlas { namespace functionspace { namespace detail { - #if ATLAS_HAVE_TRANS class Spectral::Parallelisation { public: @@ -175,11 +174,13 @@ Spectral::Spectral( const int truncation, const eckit::Configuration& config ) : Spectral::Spectral( const trans::Trans& trans, const eckit::Configuration& config ) : nb_levels_( 0 ), truncation_( trans.truncation() ), + parallelisation_( [&trans, this]() -> Parallelisation* { #if ATLAS_HAVE_TRANS - parallelisation_( new Parallelisation( dynamic_cast( *trans.get() ).trans_ ) ) { -#else - parallelisation_( new Parallelisation( truncation_ ) ) { + const auto* trans_ifs = dynamic_cast( trans.get() ); + if ( trans_ifs ) { return new Parallelisation( trans_ifs->trans_ ); } #endif + return new Parallelisation( truncation_ ); + }() ) { config.get( "levels", nb_levels_ ); } @@ -408,6 +409,8 @@ array::LocalView Spectral::nasm0() const { // ---------------------------------------------------------------------- +Spectral::Spectral() : FunctionSpace(), functionspace_{nullptr} {} + Spectral::Spectral( const FunctionSpace& functionspace ) : FunctionSpace( functionspace ), functionspace_( dynamic_cast( get() ) ) {} diff --git a/src/atlas/functionspace/Spectral.h b/src/atlas/functionspace/Spectral.h index cee6e1719..d78a65f63 100644 --- a/src/atlas/functionspace/Spectral.h +++ b/src/atlas/functionspace/Spectral.h @@ -199,7 +199,6 @@ class Spectral : public FunctionSpaceImpl { array::LocalView nmyms() const; // Return list of local zonal wavenumbers "m" array::LocalView nasm0() const; - private: // data idx_t nb_levels_; int truncation_; @@ -214,6 +213,7 @@ class Spectral : public FunctionSpaceImpl { class Spectral : public FunctionSpace { public: + Spectral(); Spectral( const FunctionSpace& ); Spectral( const eckit::Configuration& ); Spectral( const int truncation, const eckit::Configuration& = util::NoConfig() ); diff --git a/src/atlas/trans/Trans.cc b/src/atlas/trans/Trans.cc index 9cc8c4376..37f5bb972 100644 --- a/src/atlas/trans/Trans.cc +++ b/src/atlas/trans/Trans.cc @@ -83,6 +83,10 @@ const Grid& Trans::grid() const { return get()->grid(); } +const functionspace::Spectral& Trans::spectral() const { + return get()->spectral(); +} + size_t Trans::spectralCoefficients() const { return get()->spectralCoefficients(); } diff --git a/src/atlas/trans/Trans.h b/src/atlas/trans/Trans.h index 53bc8048f..e1b3da66c 100644 --- a/src/atlas/trans/Trans.h +++ b/src/atlas/trans/Trans.h @@ -25,6 +25,9 @@ class FieldSet; class FunctionSpace; class Grid; class Domain; +namespace functionspace { +class Spectral; +} } // namespace atlas //----------------------------------------------------------------------------- @@ -61,6 +64,7 @@ class Trans : public util::ObjectHandle { int truncation() const; size_t spectralCoefficients() const; const Grid& grid() const; + const functionspace::Spectral& spectral() const; void dirtrans( const Field& gpfield, Field& spfield, const eckit::Configuration& = util::NoConfig() ) const; diff --git a/src/atlas/trans/detail/TransImpl.cc b/src/atlas/trans/detail/TransImpl.cc index 1d03ee973..33341453b 100644 --- a/src/atlas/trans/detail/TransImpl.cc +++ b/src/atlas/trans/detail/TransImpl.cc @@ -10,11 +10,16 @@ #include "TransImpl.h" +#include "atlas/runtime/Exception.h" namespace atlas { namespace trans { TransImpl::~TransImpl() {} +int TransImpl::handle() const { + ATLAS_NOTIMPLEMENTED; +} + } // namespace trans } // namespace atlas diff --git a/src/atlas/trans/detail/TransImpl.h b/src/atlas/trans/detail/TransImpl.h index b75439714..bce310d60 100644 --- a/src/atlas/trans/detail/TransImpl.h +++ b/src/atlas/trans/detail/TransImpl.h @@ -23,6 +23,9 @@ class FieldSet; class FunctionSpace; class Grid; class Domain; +namespace functionspace { +class Spectral; +} } // namespace atlas //----------------------------------------------------------------------------- @@ -34,14 +37,20 @@ namespace trans { class TransImpl : public util::Object { public: + virtual std::string type() const { return "wrong value"; } + virtual ~TransImpl() = 0; virtual int truncation() const = 0; - virtual size_t spectralCoefficients() const = 0; + virtual size_t nb_spectral_coefficients() const = 0; + + virtual size_t nb_spectral_coefficients_global() const = 0; virtual const Grid& grid() const = 0; + virtual const functionspace::Spectral& spectral() const = 0; + virtual void dirtrans( const Field& gpfield, Field& spfield, const eckit::Configuration& = util::NoConfig() ) const = 0; @@ -115,6 +124,15 @@ class TransImpl : public util::Object { */ virtual void dirtrans( const int nb_fields, const double wind_fields[], double vorticity_spectra[], double divergence_spectra[], const eckit::Configuration& = util::NoConfig() ) const = 0; + + + // deprecated + virtual size_t spectralCoefficients() const { return nb_spectral_coefficients(); } + +private: + friend class TransInterface; + // Only for TransIFS backend + virtual int handle() const; }; //---------------------------------------------------------------------------------------------------------------------- diff --git a/src/atlas/trans/detail/TransInterface.cc b/src/atlas/trans/detail/TransInterface.cc new file mode 100644 index 000000000..b1f2a1cb2 --- /dev/null +++ b/src/atlas/trans/detail/TransInterface.cc @@ -0,0 +1,224 @@ +/* + * (C) Copyright 2013 ECMWF. + * + * This software is licensed under the terms of the Apache Licence Version 2.0 + * which can be obtained at http://www.apache.org/licenses/LICENSE-2.0. + * In applying this licence, ECMWF does not waive the privileges and immunities + * granted to it by virtue of its status as an intergovernmental organisation + * nor does it submit to any jurisdiction. + */ + +#include "TransInterface.h" + +#include + +#include "atlas/array.h" +#include "atlas/field/Field.h" +#include "atlas/field/FieldSet.h" +#include "atlas/functionspace/Spectral.h" +#include "atlas/library/config.h" +#include "atlas/mesh/Nodes.h" +#include "atlas/runtime/Exception.h" +#include "atlas/runtime/Log.h" +#include "atlas/trans/Trans.h" +#include "atlas/trans/detail/TransFactory.h" +#include "atlas/trans/detail/TransImpl.h" + +namespace atlas { +namespace trans { + +class TransInterface { +private: + const TransImpl* trans_; + +public: + TransInterface( const TransImpl* trans ) : trans_( trans ) {} + int handle() const { return trans_->handle(); } +}; + +/////////////////////////////////////////////////////////////////////////////// + +extern "C" { + +int atlas__Trans__has_backend( const char* backend ) { + return Trans::hasBackend( std::string( backend ) ); +} +void atlas__Trans__set_backend( const char* backend ) { + Trans::backend( std::string( backend ) ); +} +void atlas__Trans__backend( char*& backend, size_t& size ) { + std::string s = Trans::backend(); + size = s.size() + 1; + backend = new char[size]; + strcpy( backend, s.c_str() ); +} + + +TransImpl* atlas__Trans__new( const Grid::Implementation* grid, int truncation ) { + ATLAS_ASSERT( grid != nullptr, "Grid must not be null" ); + TransImpl* trans; + { + Grid g( grid ); + Trans t( g, truncation ); + trans = t.get(); + trans->attach(); + } + trans->detach(); + return trans; +} + +TransImpl* atlas__Trans__new_config( const Grid::Implementation* grid, int truncation, + const eckit::Configuration* config ) { + ATLAS_ASSERT( grid != nullptr, "Grid must not be null" ); + ATLAS_ASSERT( config != nullptr, "config must not be null" ); + TransImpl* trans; + { + Grid g( grid ); + Trans t( g, truncation, *config ); + trans = t.get(); + trans->attach(); + } + trans->detach(); + return trans; +} + + +void atlas__Trans__delete( TransImpl* This ) { + ATLAS_ASSERT( This != nullptr ); + delete This; +} + +int atlas__Trans__handle( const TransImpl* This ) { + ATLAS_ASSERT( This != nullptr ); + return TransInterface( This ).handle(); +} + + +void atlas__Trans__invtrans_scalar( const TransImpl* t, int nb_fields, double scalar_spectra[], + double scalar_fields[] ) { + ATLAS_ASSERT( t != nullptr ); + return t->invtrans( nb_fields, scalar_spectra, scalar_fields ); +} + +void atlas__Trans__invtrans_vordiv2wind( const TransImpl* t, int nb_fields, double vorticity_spectra[], + double divergence_spectra[], double wind_fields[] ) { + ATLAS_ASSERT( t != nullptr ); + return t->invtrans( nb_fields, vorticity_spectra, divergence_spectra, wind_fields ); +} + +void atlas__Trans__dirtrans_scalar( const TransImpl* t, int nb_fields, double scalar_fields[], + double scalar_spectra[] ) { + ATLAS_ASSERT( t != nullptr ); + return t->dirtrans( nb_fields, scalar_fields, scalar_spectra ); +} + +void atlas__Trans__dirtrans_wind2vordiv( const TransImpl* t, int nb_fields, double wind_fields[], + double vorticity_spectra[], double divergence_spectra[] ) { + ATLAS_ASSERT( t != nullptr ); + return t->dirtrans( nb_fields, wind_fields, vorticity_spectra, divergence_spectra ); +} + +int atlas__Trans__truncation( const TransImpl* This ) { + ATLAS_ASSERT( This != nullptr ); + return This->truncation(); +} + +const Grid::Implementation* atlas__Trans__grid( const TransImpl* This ) { + ATLAS_ASSERT( This != nullptr ); + ATLAS_ASSERT( This->grid() ); + return This->grid().get(); +} + +const functionspace::FunctionSpaceImpl* atlas__Trans__spectral( const TransImpl* This ) { + ATLAS_ASSERT( This != nullptr ); + const auto spectral = This->spectral(); + ATLAS_ASSERT( spectral ); + return spectral.get(); +} + + +void atlas__Trans__dirtrans_fieldset( const TransImpl* This, const field::FieldSetImpl* gpfields, + field::FieldSetImpl* spfields, const eckit::Configuration* parameters ) { + ATLAS_ASSERT( This != nullptr ); + ATLAS_ASSERT( gpfields ); + ATLAS_ASSERT( spfields ); + ATLAS_ASSERT( parameters ); + FieldSet fspfields( spfields ); + This->dirtrans( gpfields, fspfields, *parameters ); +} + +void atlas__Trans__dirtrans_field( const TransImpl* This, const field::FieldImpl* gpfield, field::FieldImpl* spfield, + const eckit::Configuration* parameters ) { + ATLAS_ASSERT( This != nullptr ); + ATLAS_ASSERT( spfield ); + ATLAS_ASSERT( gpfield ); + ATLAS_ASSERT( parameters ); + Field fspfield( spfield ); + This->dirtrans( gpfield, fspfield, *parameters ); +} + +void atlas__Trans__invtrans_fieldset( const TransImpl* This, const field::FieldSetImpl* spfields, + field::FieldSetImpl* gpfields, const eckit::Configuration* parameters ) { + ATLAS_ASSERT( This != nullptr ); + ATLAS_ASSERT( spfields ); + ATLAS_ASSERT( gpfields ); + ATLAS_ASSERT( parameters ); + FieldSet fgpfields( gpfields ); + This->invtrans( spfields, fgpfields, *parameters ); +} + +void atlas__Trans__invtrans_field( const TransImpl* This, const field::FieldImpl* spfield, field::FieldImpl* gpfield, + const eckit::Configuration* parameters ) { + ATLAS_ASSERT( This != nullptr ); + ATLAS_ASSERT( spfield ); + ATLAS_ASSERT( gpfield ); + ATLAS_ASSERT( parameters ); + Field fgpfield( gpfield ); + This->invtrans( spfield, fgpfield, *parameters ); +} + +void atlas__Trans__dirtrans_wind2vordiv_field( const TransImpl* This, const field::FieldImpl* gpwind, + field::FieldImpl* spvor, field::FieldImpl* spdiv, + const eckit::Configuration* parameters ) { + ATLAS_ASSERT( This != nullptr ); + ATLAS_ASSERT( gpwind ); + ATLAS_ASSERT( spvor ); + ATLAS_ASSERT( spdiv ); + ATLAS_ASSERT( parameters ); + Field fspvor( spvor ); + Field fspdiv( spdiv ); + This->dirtrans_wind2vordiv( gpwind, fspvor, fspdiv, *parameters ); +} + +void atlas__Trans__invtrans_vordiv2wind_field( const TransImpl* This, const field::FieldImpl* spvor, + const field::FieldImpl* spdiv, field::FieldImpl* gpwind, + const eckit::Configuration* parameters ) { + ATLAS_ASSERT( This != nullptr ); + ATLAS_ASSERT( spvor ); + ATLAS_ASSERT( spdiv ); + ATLAS_ASSERT( gpwind ); + ATLAS_ASSERT( parameters ); + Field fgpwind( gpwind ); + This->invtrans_vordiv2wind( spvor, spdiv, fgpwind, *parameters ); +} + +void atlas__Trans__invtrans( const TransImpl* This, int nb_scalar_fields, double scalar_spectra[], int nb_vordiv_fields, + double vorticity_spectra[], double divergence_spectra[], double gp_fields[], + const eckit::Configuration* parameters ) { + ATLAS_ASSERT( This != nullptr ); + This->invtrans( nb_scalar_fields, scalar_spectra, nb_vordiv_fields, vorticity_spectra, divergence_spectra, + gp_fields, *parameters ); +} + +void atlas__Trans__invtrans_grad_field( const TransImpl* This, const field::FieldImpl* spfield, + field::FieldImpl* gpfield, const eckit::Configuration* config ) { + ATLAS_ASSERT( This != nullptr ); + ATLAS_ASSERT( spfield ); + ATLAS_ASSERT( gpfield ); + Field fgpfield( gpfield ); + This->invtrans_grad( spfield, fgpfield, *config ); +} +} + +} // namespace trans +} // namespace atlas diff --git a/src/atlas/trans/detail/TransInterface.h b/src/atlas/trans/detail/TransInterface.h new file mode 100644 index 000000000..a29dd60ac --- /dev/null +++ b/src/atlas/trans/detail/TransInterface.h @@ -0,0 +1,96 @@ +/* + * (C) Copyright 2013 ECMWF. + * + * This software is licensed under the terms of the Apache Licence Version 2.0 + * which can be obtained at http://www.apache.org/licenses/LICENSE-2.0. + * In applying this licence, ECMWF does not waive the privileges and immunities + * granted to it by virtue of its status as an intergovernmental organisation + * nor does it submit to any jurisdiction. + */ + +#pragma once + +#include "atlas/grid/Grid.h" +#include "atlas/trans/detail/TransImpl.h" + +//----------------------------------------------------------------------------- +// Forward declarations + +namespace eckit { +class Configuration; +} // namespace eckit + +namespace atlas { +class Field; +class FieldSet; +namespace field { +class FieldImpl; +class FieldSetImpl; +} // namespace field +namespace functionspace { +class FunctionSpaceImpl; +} +} // namespace atlas + +//----------------------------------------------------------------------------- + +namespace atlas { +namespace trans { + +//----------------------------------------------------------------------------- + +// C wrapper interfaces to C++ routines + +extern "C" { + +int atlas__Trans__has_backend( const char* backend ); +void atlas__Trans__set_backend( const char* backend ); +void atlas__Trans__backend( char*& backend, size_t& size ); + +TransImpl* atlas__Trans__new( const Grid::Implementation* grid, int truncation ); +TransImpl* atlas__Trans__new_config( const Grid::Implementation* grid, int truncation, + const eckit::Configuration* config ); +void atlas__Trans__delete( TransImpl* trans ); +void atlas__Trans__invtrans( const TransImpl* t, int nb_scalar_fields, double scalar_spectra[], int nb_vordiv_fields, + double vorticity_spectra[], double divergence_spectra[], double gp_fields[], + const eckit::Configuration* parameters ); +void atlas__Trans__invtrans_scalar( const TransImpl* t, int nb_fields, double scalar_spectra[], + double scalar_fields[] ); +void atlas__Trans__invtrans_vordiv2wind( const TransImpl* t, int nb_fields, double vorticity_spectra[], + double divergence_spectra[], double wind_fields[] ); +void atlas__Trans__dirtrans_scalar( const TransImpl* t, int nb_fields, double scalar_fields[], + double scalar_spectra[] ); +void atlas__Trans__dirtrans_wind2vordiv( const TransImpl* t, int nb_fields, double wind_fields[], + double vorticity_spectra[], double divergence_spectra[] ); +void atlas__Trans__dirtrans_wind2vordiv_field( const TransImpl* This, const field::FieldImpl* gpwind, + field::FieldImpl* spvor, field::FieldImpl* spdiv, + const eckit::Configuration* parameters ); +// void atlas__Trans__specnorm( const TransImpl* t, int nb_fields, double spectra[], double norms[], int rank ); +void atlas__Trans__dirtrans_fieldset( const TransImpl* This, const field::FieldSetImpl* gpfields, + field::FieldSetImpl* spfields, const eckit::Configuration* parameters ); +void atlas__Trans__dirtrans_field( const TransImpl* This, const field::FieldImpl* gpfield, field::FieldImpl* spfield, + const eckit::Configuration* parameters ); +void atlas__Trans__invtrans_fieldset( const TransImpl* This, const field::FieldSetImpl* spfields, + field::FieldSetImpl* gpfields, const eckit::Configuration* parameters ); +void atlas__Trans__invtrans_field( const TransImpl* This, const field::FieldImpl* spfield, field::FieldImpl* gpfield, + const eckit::Configuration* parameters ); +void atlas__Trans__invtrans_grad_field( const TransImpl* This, const field::FieldImpl* spfield, + field::FieldImpl* gpfield, const eckit::Configuration* parameters ); +void atlas__Trans__invtrans_vordiv2wind_field( const TransImpl* This, const field::FieldImpl* spvor, + const field::FieldImpl* spdiv, field::FieldImpl* gpwind, + const eckit::Configuration* parameters ); + +int atlas__Trans__handle( const TransImpl* trans ); +int atlas__Trans__truncation( const TransImpl* This ); +// int atlas__Trans__nspec2( const TransImpl* This ); +// int atlas__Trans__nspec2g( const TransImpl* This ); +// int atlas__Trans__ngptot( const TransImpl* This ); +// int atlas__Trans__ngptotg( const TransImpl* This ); +const Grid::Implementation* atlas__Trans__grid( const TransImpl* This ); +const functionspace::FunctionSpaceImpl* atlas__Trans__spectral( const TransImpl* This ); +} + +// ------------------------------------------------------------------ + +} // namespace trans +} // namespace atlas diff --git a/src/atlas/trans/ifs/TransIFS.cc b/src/atlas/trans/ifs/TransIFS.cc index 114d22369..0f7e16355 100644 --- a/src/atlas/trans/ifs/TransIFS.cc +++ b/src/atlas/trans/ifs/TransIFS.cc @@ -23,6 +23,7 @@ #include "atlas/parallel/mpi/mpi.h" #include "atlas/runtime/Exception.h" #include "atlas/runtime/Log.h" +#include "atlas/trans/Trans.h" #include "atlas/trans/detail/TransFactory.h" #include "atlas/trans/ifs/TransIFS.h" @@ -655,10 +656,7 @@ TransIFS::TransIFS( const Cache& cache, const Grid& grid, const long truncation, } TransIFS::TransIFS( const Grid& grid, const long truncation, const eckit::Configuration& config ) : - TransIFS( Cache(), grid, truncation, config ) { - ATLAS_ASSERT( grid.domain().global() ); - ATLAS_ASSERT( not grid.projection() ); -} + TransIFS( Cache(), grid, truncation, config ) {} TransIFS::TransIFS( const Grid& grid, const eckit::Configuration& config ) : TransIFS( grid, /*grid-only*/ -1, config ) {} @@ -856,10 +854,19 @@ int atlas::trans::TransIFS::truncation() const { return std::max( 0, trans_->nsmax ); } -size_t atlas::trans::TransIFS::spectralCoefficients() const { +size_t TransIFS::nb_spectral_coefficients() const { + return trans_->nspec2; +} + +size_t TransIFS::nb_spectral_coefficients_global() const { return trans_->nspec2g; } +const functionspace::Spectral& TransIFS::spectral() const { + if ( not spectral_ ) { spectral_ = functionspace::Spectral( Trans( this ) ); } + return spectral_; +} + void TransIFS::ctor( const Grid& grid, long truncation, const eckit::Configuration& config ) { trans_ = std::shared_ptr<::Trans_t>( new ::Trans_t, [](::Trans_t* p ) { ::trans_delete( p ); @@ -879,17 +886,6 @@ void TransIFS::ctor( const Grid& grid, long truncation, const eckit::Configurati throw_NotImplemented( "Grid type not supported for Spectral Transforms", Here() ); } -void TransIFS::ctor_spectral_only( long truncation, const eckit::Configuration& ) { - trans_ = std::shared_ptr<::Trans_t>( new ::Trans_t, [](::Trans_t* p ) { - ::trans_delete( p ); - delete p; - } ); - TRANS_CHECK(::trans_new( trans_.get() ) ); - TRANS_CHECK(::trans_set_trunc( trans_.get(), truncation ) ); - TRANS_CHECK(::trans_use_mpi( mpi::comm().size() > 1 ) ); - TRANS_CHECK(::trans_setup( trans_.get() ) ); -} - void TransIFS::ctor_rgg( const long nlat, const idx_t pl[], long truncation, const eckit::Configuration& config ) { TransParameters p( *this, config ); std::vector nloen( nlat ); @@ -1531,6 +1527,9 @@ void TransIFS::specnorm( const int nb_fields, const double spectra[], double nor /////////////////////////////////////////////////////////////////////////////// +// Moved to TransInterface +#if 0 + extern "C" { TransIFS* atlas__Trans__new( const Grid::Implementation* grid, int nsmax ) { @@ -1734,6 +1733,7 @@ void atlas__Trans__invtrans_grad_field( const TransIFS* This, const field::Field This->invtrans_grad( spfield, fgpfield, *config ); } } +#endif } // namespace trans } // namespace atlas diff --git a/src/atlas/trans/ifs/TransIFS.h b/src/atlas/trans/ifs/TransIFS.h index da24c6b49..721a00a20 100644 --- a/src/atlas/trans/ifs/TransIFS.h +++ b/src/atlas/trans/ifs/TransIFS.h @@ -13,6 +13,7 @@ #include "eckit/filesystem/PathName.h" #include "atlas/array/LocalView.h" +#include "atlas/functionspace/Spectral.h" #include "atlas/grid/Grid.h" #include "atlas/grid/StructuredGrid.h" #include "atlas/runtime/Exception.h" @@ -89,9 +90,11 @@ class TransIFS : public trans::TransImpl { ::Trans_t* trans() const { return trans_.get(); } virtual int truncation() const override; - virtual size_t spectralCoefficients() const override; + virtual size_t nb_spectral_coefficients() const override; + virtual size_t nb_spectral_coefficients_global() const override; virtual const Grid& grid() const override { return grid_; } + virtual const functionspace::Spectral& spectral() const override; // pure virtual interface @@ -219,8 +222,6 @@ class TransIFS : public trans::TransImpl { void ctor_lonlat( const long nlon, const long nlat, long nsmax, const eckit::Configuration& ); - void ctor_spectral_only( long truncation, const eckit::Configuration& ); - private: friend class grid::detail::partitioner::TransPartitioner; @@ -328,57 +329,10 @@ class TransIFS : public trans::TransImpl { StructuredGrid grid_; const void* cache_{nullptr}; size_t cachesize_{0}; -}; - -//----------------------------------------------------------------------------- -// C wrapper interfaces to C++ routines - -extern "C" { -TransIFS* atlas__Trans__new( const Grid::Implementation* grid, int nsmax ); -void atlas__Trans__delete( TransIFS* trans ); -void atlas__Trans__distspec( const TransIFS* t, int nb_fields, int origin[], double global_spectra[], - double spectra[] ); -void atlas__Trans__gathspec( const TransIFS* t, int nb_fields, int destination[], double spectra[], - double global_spectra[] ); -void atlas__Trans__distgrid( const TransIFS* t, int nb_fields, int origin[], double global_fields[], double fields[] ); -void atlas__Trans__gathgrid( const TransIFS* t, int nb_fields, int destination[], double fields[], - double global_fields[] ); -void atlas__Trans__invtrans( const TransIFS* t, int nb_scalar_fields, double scalar_spectra[], int nb_vordiv_fields, - double vorticity_spectra[], double divergence_spectra[], double gp_fields[], - const eckit::Configuration* parameters ); -void atlas__Trans__invtrans_scalar( const TransIFS* t, int nb_fields, double scalar_spectra[], double scalar_fields[] ); -void atlas__Trans__invtrans_vordiv2wind( const TransIFS* t, int nb_fields, double vorticity_spectra[], - double divergence_spectra[], double wind_fields[] ); -void atlas__Trans__dirtrans_scalar( const TransIFS* t, int nb_fields, double scalar_fields[], double scalar_spectra[] ); -void atlas__Trans__dirtrans_wind2vordiv( const TransIFS* t, int nb_fields, double wind_fields[], - double vorticity_spectra[], double divergence_spectra[] ); -void atlas__Trans__dirtrans_wind2vordiv_field( const TransIFS* This, const field::FieldImpl* gpwind, - field::FieldImpl* spvor, field::FieldImpl* spdiv, - const eckit::Configuration* parameters ); -void atlas__Trans__specnorm( const TransIFS* t, int nb_fields, double spectra[], double norms[], int rank ); -void atlas__Trans__dirtrans_fieldset( const TransIFS* This, const field::FieldSetImpl* gpfields, - field::FieldSetImpl* spfields, const eckit::Configuration* parameters ); -void atlas__Trans__dirtrans_field( const TransIFS* This, const field::FieldImpl* gpfield, field::FieldImpl* spfield, - const eckit::Configuration* parameters ); -void atlas__Trans__invtrans_fieldset( const TransIFS* This, const field::FieldSetImpl* spfields, - field::FieldSetImpl* gpfields, const eckit::Configuration* parameters ); -void atlas__Trans__invtrans_field( const TransIFS* This, const field::FieldImpl* spfield, field::FieldImpl* gpfield, - const eckit::Configuration* parameters ); -void atlas__Trans__invtrans_grad_field( const TransIFS* This, const field::FieldImpl* spfield, - field::FieldImpl* gpfield, const eckit::Configuration* parameters ); -void atlas__Trans__invtrans_vordiv2wind_field( const TransIFS* This, const field::FieldImpl* spvor, - const field::FieldImpl* spdiv, field::FieldImpl* gpwind, - const eckit::Configuration* parameters ); - -int atlas__Trans__handle( const TransIFS* trans ); -int atlas__Trans__truncation( const TransIFS* This ); -int atlas__Trans__nspec2( const TransIFS* This ); -int atlas__Trans__nspec2g( const TransIFS* This ); -int atlas__Trans__ngptot( const TransIFS* This ); -int atlas__Trans__ngptotg( const TransIFS* This ); -const Grid::Implementation* atlas__Trans__grid( const TransIFS* This ); -} +protected: + mutable functionspace::Spectral spectral_; +}; // ------------------------------------------------------------------ diff --git a/src/atlas/trans/ifs/TransIFSNodeColumns.cc b/src/atlas/trans/ifs/TransIFSNodeColumns.cc index 2c8ef92ae..73d75161d 100644 --- a/src/atlas/trans/ifs/TransIFSNodeColumns.cc +++ b/src/atlas/trans/ifs/TransIFSNodeColumns.cc @@ -24,6 +24,7 @@ TransIFSNodeColumns::TransIFSNodeColumns( const Cache& cache, const functionspac const functionspace::Spectral& sp, const eckit::Configuration& config ) : TransIFS( cache, gp.mesh().grid(), sp.truncation(), config ) { assertCompatibleDistributions( gp, sp ); + spectral_ = sp; } TransIFSNodeColumns::~TransIFSNodeColumns() {} diff --git a/src/atlas/trans/ifs/TransIFSStructuredColumns.cc b/src/atlas/trans/ifs/TransIFSStructuredColumns.cc index af999a777..1da27e1ef 100644 --- a/src/atlas/trans/ifs/TransIFSStructuredColumns.cc +++ b/src/atlas/trans/ifs/TransIFSStructuredColumns.cc @@ -26,6 +26,7 @@ TransIFSStructuredColumns::TransIFSStructuredColumns( const Cache& cache, const const eckit::Configuration& config ) : TransIFS( cache, gp.grid(), sp.truncation(), config ) { assertCompatibleDistributions( gp, sp ); + spectral_ = sp; } TransIFSStructuredColumns::~TransIFSStructuredColumns() {} diff --git a/src/atlas/trans/local/TransLocal.cc b/src/atlas/trans/local/TransLocal.cc index 2b1ec9707..a5edbf84e 100644 --- a/src/atlas/trans/local/TransLocal.cc +++ b/src/atlas/trans/local/TransLocal.cc @@ -24,12 +24,14 @@ #include "eckit/types/FloatCompare.h" #include "atlas/array.h" +#include "atlas/field.h" #include "atlas/grid/Iterator.h" #include "atlas/grid/StructuredGrid.h" #include "atlas/option.h" #include "atlas/parallel/mpi/mpi.h" #include "atlas/runtime/Exception.h" #include "atlas/runtime/Log.h" +#include "atlas/trans/Trans.h" #include "atlas/trans/VorDivToUV.h" #include "atlas/trans/detail/TransFactory.h" #include "atlas/trans/local/LegendrePolynomials.h" @@ -301,6 +303,7 @@ TransLocal::TransLocal( const Cache& cache, const Grid& grid, const Domain& doma nlatsLegReduced_ = 0; bool useGlobalLeg = true; bool no_nest = false; + if ( StructuredGrid( grid_ ) && not grid_.projection() ) { StructuredGrid g( grid_ ); nlats = g.ny(); @@ -663,7 +666,7 @@ TransLocal::TransLocal( const Cache& cache, const Grid& grid, const Domain& doma "Caching for unstructured grids or structured grids with projections not yet implemented", Here() ); } } -} // namespace trans +} // -------------------------------------------------------------------------------------------------------------------- @@ -706,41 +709,52 @@ TransLocal::~TransLocal() { // -------------------------------------------------------------------------------------------------------------------- -void TransLocal::invtrans( const Field& /*spfield*/, Field& /*gpfield*/, const eckit::Configuration& ) const { - ATLAS_NOTIMPLEMENTED; +const functionspace::Spectral& TransLocal::spectral() const { + if ( not spectral_ ) { spectral_ = functionspace::Spectral( Trans( this ) ); } + return spectral_; } // -------------------------------------------------------------------------------------------------------------------- -void TransLocal::invtrans( const FieldSet& /*spfields*/, FieldSet& /*gpfields*/, const eckit::Configuration& ) const { - ATLAS_NOTIMPLEMENTED; -} +void TransLocal::invtrans( const Field& spfield, Field& gpfield, const eckit::Configuration& config ) const { -// -------------------------------------------------------------------------------------------------------------------- +// VERY PRELIMINARY IMPLEMENTATION WITHOUT ANY GUARANTEES + int nb_scalar_fields = 1; + const auto scalar_spectra = array::make_view( spfield ); + auto gp_fields = array::make_view( spfield ); + + if( gp_fields.shape(0) != grid().size() ) { + ATLAS_DEBUG_VAR( gp_fields.shape(0) ); + ATLAS_DEBUG_VAR( grid().size() ); + ATLAS_ASSERT( gp_fields.shape(0) == grid().size() ); + } + + invtrans( nb_scalar_fields, scalar_spectra.data(), gp_fields.data(), config ); -void TransLocal::invtrans_grad( const Field& /*spfield*/, Field& /*gradfield*/, const eckit::Configuration& ) const { - ATLAS_NOTIMPLEMENTED; } // -------------------------------------------------------------------------------------------------------------------- -void TransLocal::invtrans_grad( const FieldSet& /*spfields*/, FieldSet& /*gradfields*/, - const eckit::Configuration& ) const { - ATLAS_NOTIMPLEMENTED; +void TransLocal::invtrans( const FieldSet& spfields, FieldSet& gpfields, const eckit::Configuration& config ) const { + +// VERY PRELIMINARY IMPLEMENTATION WITHOUT ANY GUARANTEES + ATLAS_ASSERT( spfields.size() == gpfields.size() ); + for( idx_t f=0; f( spvor ); + const auto divergence_spectra = array::make_view( spdiv ); + auto gp_fields = array::make_view( gpwind ); + + if( gp_fields.shape(1) == grid().size() && gp_fields.shape(0) == 2 ) { + invtrans( nb_vordiv_fields, vorticity_spectra.data(), divergence_spectra.data(), gp_fields.data(), config ); + } + else if( gp_fields.shape(0) == grid().size() && gp_fields.shape(1) == 2 ) { + array::ArrayT gpwind_t( gp_fields.shape(1), gp_fields.shape(0) ); + auto gp_fields_t = array::make_view( gpwind_t ); + invtrans( nb_vordiv_fields, vorticity_spectra.data(), divergence_spectra.data(), gp_fields_t.data(), config ); + gp_transpose( grid().size(), 2, gp_fields_t.data(), gp_fields.data() ); + } + else { + ATLAS_NOTIMPLEMENTED; + } +} + +// -------------------------------------------------------------------------------------------------------------------- + +void TransLocal::invtrans( const int nb_scalar_fields, const double scalar_spectra[], double gp_fields[], + const eckit::Configuration& config ) const { + invtrans_uv( truncation_, nb_scalar_fields, 0, scalar_spectra, gp_fields, config ); +} + + // -------------------------------------------------------------------------------------------------------------------- void TransLocal::invtrans_legendre( const int truncation, const int nlats, const int nb_fields, diff --git a/src/atlas/trans/local/TransLocal.h b/src/atlas/trans/local/TransLocal.h index 2d5611cf3..ca1458c9c 100644 --- a/src/atlas/trans/local/TransLocal.h +++ b/src/atlas/trans/local/TransLocal.h @@ -14,6 +14,7 @@ #include #include "atlas/array.h" +#include "atlas/functionspace/Spectral.h" #include "atlas/grid/Grid.h" #include "atlas/trans/detail/TransImpl.h" @@ -76,9 +77,14 @@ class TransLocal : public trans::TransImpl { virtual ~TransLocal() override; virtual int truncation() const override { return truncation_; } - virtual size_t spectralCoefficients() const override { return ( truncation_ + 1 ) * ( truncation_ + 2 ); } + + virtual size_t nb_spectral_coefficients() const override { return ( truncation_ + 1 ) * ( truncation_ + 2 ); } + virtual size_t nb_spectral_coefficients_global() const override { + return ( truncation_ + 1 ) * ( truncation_ + 2 ); + } virtual const Grid& grid() const override { return grid_; } + virtual const functionspace::Spectral& spectral() const override; virtual void invtrans( const Field& spfield, Field& gpfield, const eckit::Configuration& = util::NoConfig() ) const override; @@ -162,6 +168,7 @@ class TransLocal : public trans::TransImpl { friend class LegendreCacheCreatorLocal; private: + mutable functionspace::Spectral spectral_; Grid grid_; Grid gridGlobal_; bool useFFT_; diff --git a/src/atlas_f/CMakeLists.txt b/src/atlas_f/CMakeLists.txt index 8f50c54b9..276c1ca81 100644 --- a/src/atlas_f/CMakeLists.txt +++ b/src/atlas_f/CMakeLists.txt @@ -115,7 +115,7 @@ generate_fortran_bindings(FORTRAN_BINDINGS ../atlas/numerics/fvm/Method.h generate_fortran_bindings(FORTRAN_BINDINGS ../atlas/interpolation/Interpolation.h MODULE atlas_interpolation_c_binding OUTPUT interpolation_c_binding.f90 ) -generate_fortran_bindings(FORTRAN_BINDINGS ../atlas/trans/ifs/TransIFS.h +generate_fortran_bindings(FORTRAN_BINDINGS ../atlas/trans/detail/TransInterface.h MODULE atlas_trans_c_binding OUTPUT trans_c_binding.f90 ) generate_fortran_bindings(FORTRAN_BINDINGS ../atlas/util/Allocate.h) diff --git a/src/atlas_f/trans/atlas_Trans_module.F90 b/src/atlas_f/trans/atlas_Trans_module.F90 index fac94f63b..c97335b3f 100644 --- a/src/atlas_f/trans/atlas_Trans_module.F90 +++ b/src/atlas_f/trans/atlas_Trans_module.F90 @@ -17,6 +17,7 @@ module atlas_Trans_module use atlas_field_module, only : atlas_Field use atlas_fieldset_module, only : atlas_FieldSet use atlas_grid_module, only : atlas_Grid +use atlas_functionspace_module, only : atlas_functionspace implicit none @@ -44,13 +45,20 @@ module atlas_Trans_module !------------------------------------------------------------------------------ contains + procedure, nopass :: has_backend + procedure, nopass :: set_backend + procedure, nopass :: backend + procedure :: handle procedure :: grid procedure :: truncation + procedure :: spectral +#if 0 procedure :: nb_spectral_coefficients procedure :: nb_spectral_coefficients_global procedure :: nb_gridpoints procedure :: nb_gridpoints_global +#endif procedure, private :: dirtrans_field procedure, private :: dirtrans_fieldset @@ -70,6 +78,8 @@ module atlas_Trans_module generic, public :: invtrans_grad => & & invtrans_grad_field +! removed +#if 0 procedure, private :: gathspec_r1 procedure, private :: gathspec_r2 generic, public :: gathspec => gathspec_r1, gathspec_r2 @@ -77,6 +87,7 @@ module atlas_Trans_module procedure, private :: specnorm_r1_scalar procedure, private :: specnorm_r2 generic, public :: specnorm => specnorm_r1_scalar, specnorm_r2 +#endif #if FCKIT_FINAL_NOT_INHERITING final :: atlas_Trans__final_auto @@ -102,37 +113,66 @@ module atlas_Trans_module !======================================================== contains !======================================================== + ! ----------------------------------------------------------------------------- ! Trans routines -#define THROW_ERROR call te("atlas_Trans_module.F90",__LINE__) +function backend() + use, intrinsic :: iso_c_binding, only: c_size_t, c_ptr + use atlas_trans_c_binding + use fckit_c_interop_module, only : c_str, c_ptr_to_string, c_ptr_free + character(len=:), allocatable :: backend + type(c_ptr) :: value_cptr + integer(c_size_t) :: value_size + call atlas__Trans__backend(value_cptr,value_size) + allocate( character(len=value_size) :: backend ) + backend = c_ptr_to_string(value_cptr) + call c_ptr_free(value_cptr) +end function + +function has_backend( backend ) + use, intrinsic :: iso_c_binding, only: c_int + use fckit_c_interop_module, only : c_str + use atlas_trans_c_binding + logical :: has_backend + character(len=*) :: backend + integer(c_int) :: has_backend_int + has_backend_int = atlas__Trans__has_backend( c_str(backend) ) + if( has_backend_int == 1 ) then + has_backend = .True. + else + has_backend = .False. + end if +end function -subroutine te(file,line) - use fckit_exception_module, only : fckit_exception - character(len=*), intent(in) :: file - integer, intent(in) :: line - call fckit_exception%throw( "Cannot use atlas_Trans since atlas is compiled without" // & - & "ENABLE_TRANS=ON", file, line ) +subroutine set_backend( backend ) + use atlas_trans_c_binding + use fckit_c_interop_module, only : c_str + character(len=*), intent(in) :: backend + call atlas__Trans__set_backend( c_str(backend) ) end subroutine -function atlas_Trans__ctor( grid, nsmax ) result(this) + +function atlas_Trans__ctor( grid, nsmax, config ) result(this) use, intrinsic :: iso_c_binding, only: c_null_ptr use atlas_trans_c_binding type(atlas_Trans) :: this class(atlas_Grid), intent(in) :: grid integer, intent(in), optional :: nsmax -#if ATLAS_HAVE_TRANS - if( present(nsmax) ) then - call this%reset_c_ptr( atlas__Trans__new( grid%CPTR_PGIBUG_A, nsmax ) ) + type(atlas_Config), intent(in), optional :: config + if( present( config ) ) then + if( present(nsmax) ) then + call this%reset_c_ptr( atlas__Trans__new_config( grid%CPTR_PGIBUG_A, nsmax, config%CPTR_PGIBUG_B ) ) + else + call this%reset_c_ptr( atlas__Trans__new_config( grid%CPTR_PGIBUG_A, 0, config%CPTR_PGIBUG_B ) ) + endif else - call this%reset_c_ptr( atlas__Trans__new( grid%CPTR_PGIBUG_A, 0 ) ) + if( present(nsmax) ) then + call this%reset_c_ptr( atlas__Trans__new( grid%CPTR_PGIBUG_A, nsmax ) ) + else + call this%reset_c_ptr( atlas__Trans__new( grid%CPTR_PGIBUG_A, 0 ) ) + endif endif -#else - ! IGNORE - call this%reset_c_ptr( c_null_ptr ) - FCKIT_SUPPRESS_UNUSED( grid ) - FCKIT_SUPPRESS_UNUSED( nsmax ) -#endif call this%return() end function atlas_Trans__ctor @@ -140,78 +180,22 @@ function handle( this ) use atlas_trans_c_binding integer :: handle class(atlas_Trans) :: this -#if ATLAS_HAVE_TRANS handle = atlas__Trans__handle (this%CPTR_PGIBUG_A) -#else - THROW_ERROR - handle = 0 - FCKIT_SUPPRESS_UNUSED( this ) -#endif end function function truncation( this ) use atlas_trans_c_binding integer :: truncation class(atlas_Trans) :: this -#if ATLAS_HAVE_TRANS truncation = atlas__Trans__truncation (this%CPTR_PGIBUG_A) -#else - THROW_ERROR - truncation = 0 - FCKIT_SUPPRESS_UNUSED( this ) -#endif end function -function nb_spectral_coefficients( this ) +function spectral( this ) use atlas_trans_c_binding - integer :: nb_spectral_coefficients + type(atlas_FunctionSpace) :: spectral class(atlas_Trans) :: this -#if ATLAS_HAVE_TRANS - nb_spectral_coefficients = atlas__Trans__nspec2 (this%CPTR_PGIBUG_A) -#else - THROW_ERROR - nb_spectral_coefficients = 0 - FCKIT_SUPPRESS_UNUSED( this ) -#endif -end function - -function nb_spectral_coefficients_global( this ) - use atlas_trans_c_binding - integer :: nb_spectral_coefficients_global - class(atlas_Trans) :: this -#if ATLAS_HAVE_TRANS - nb_spectral_coefficients_global = atlas__Trans__nspec2g (this%CPTR_PGIBUG_A) -#else - THROW_ERROR - nb_spectral_coefficients_global = 0 - FCKIT_SUPPRESS_UNUSED( this ) -#endif -end function - -function nb_gridpoints( this ) - use atlas_trans_c_binding - integer :: nb_gridpoints - class(atlas_Trans) :: this -#if ATLAS_HAVE_TRANS - nb_gridpoints = atlas__Trans__ngptot (this%CPTR_PGIBUG_A) -#else - THROW_ERROR - nb_gridpoints = 0 - FCKIT_SUPPRESS_UNUSED( this ) -#endif -end function - -function nb_gridpoints_global( this ) - use atlas_trans_c_binding - integer :: nb_gridpoints_global - class(atlas_Trans) :: this -#if ATLAS_HAVE_TRANS - nb_gridpoints_global = atlas__Trans__ngptotg (this%CPTR_PGIBUG_A) -#else - THROW_ERROR - nb_gridpoints_global = 0 - FCKIT_SUPPRESS_UNUSED( this ) -#endif + spectral = atlas_FunctionSpace( atlas__Trans__spectral (this%CPTR_PGIBUG_A) ) + call spectral%return() end function function grid( this ) @@ -219,15 +203,8 @@ function grid( this ) use atlas_trans_c_binding class(atlas_Trans) :: this type(atlas_Grid) :: grid -#if ATLAS_HAVE_TRANS grid = atlas_Grid( atlas__Trans__grid(this%CPTR_PGIBUG_A) ) call grid%return() -#else - THROW_ERROR - FCKIT_SUPPRESS_UNUSED( this ) - grid = atlas_Grid( c_null_ptr ) - FCKIT_SUPPRESS_UNUSED( grid ) -#endif end function @@ -237,7 +214,6 @@ subroutine dirtrans_fieldset(this, gpfields, spfields, config) class(atlas_FieldSet), intent(in) :: gpfields class(atlas_FieldSet), intent(inout) :: spfields class(atlas_Config), intent(in), optional :: config -#if ATLAS_HAVE_TRANS type(atlas_Config) :: p if( present(config) ) then @@ -254,13 +230,6 @@ subroutine dirtrans_fieldset(this, gpfields, spfields, config) if( .not. present(config) ) then call p%final() endif -#else - THROW_ERROR - FCKIT_SUPPRESS_UNUSED( this ) - FCKIT_SUPPRESS_UNUSED( gpfields ) - FCKIT_SUPPRESS_UNUSED( spfields ) - FCKIT_SUPPRESS_UNUSED( config ) -#endif end subroutine dirtrans_fieldset @@ -270,7 +239,6 @@ subroutine invtrans_fieldset(this, spfields, gpfields, config) class(atlas_FieldSet), intent(in) :: spfields class(atlas_FieldSet), intent(inout) :: gpfields class(atlas_Config), intent(in), optional :: config -#if ATLAS_HAVE_TRANS type(atlas_Config) :: p if( present(config) ) then @@ -287,13 +255,6 @@ subroutine invtrans_fieldset(this, spfields, gpfields, config) if( .not. present(config) ) then call p%final() endif -#else - THROW_ERROR - FCKIT_SUPPRESS_UNUSED( this ) - FCKIT_SUPPRESS_UNUSED( spfields ) - FCKIT_SUPPRESS_UNUSED( gpfields ) - FCKIT_SUPPRESS_UNUSED( config ) -#endif end subroutine invtrans_fieldset subroutine dirtrans_field(this, gpfield, spfield, config) @@ -302,7 +263,6 @@ subroutine dirtrans_field(this, gpfield, spfield, config) class(atlas_Field), intent(in) :: gpfield class(atlas_Field), intent(inout) :: spfield class(atlas_Config), intent(in), optional :: config -#if ATLAS_HAVE_TRANS type(atlas_Config) :: p if( present(config) ) then @@ -319,13 +279,6 @@ subroutine dirtrans_field(this, gpfield, spfield, config) if( .not. present(config) ) then call p%final() endif -#else - THROW_ERROR - FCKIT_SUPPRESS_UNUSED( this ) - FCKIT_SUPPRESS_UNUSED( gpfield ) - FCKIT_SUPPRESS_UNUSED( spfield ) - FCKIT_SUPPRESS_UNUSED( config ) -#endif end subroutine dirtrans_field subroutine dirtrans_wind2vordiv_field(this, gpwind, spvor, spdiv, config) @@ -335,7 +288,6 @@ subroutine dirtrans_wind2vordiv_field(this, gpwind, spvor, spdiv, config) type(atlas_Field), intent(inout) :: spvor type(atlas_Field), intent(inout) :: spdiv type(atlas_Config), intent(in), optional :: config -#if ATLAS_HAVE_TRANS type(atlas_Config) :: p if( present(config) ) then @@ -353,14 +305,6 @@ subroutine dirtrans_wind2vordiv_field(this, gpwind, spvor, spdiv, config) if( .not. present(config) ) then call p%final() endif -#else - THROW_ERROR - FCKIT_SUPPRESS_UNUSED( this ) - FCKIT_SUPPRESS_UNUSED( gpwind ) - FCKIT_SUPPRESS_UNUSED( spvor ) - FCKIT_SUPPRESS_UNUSED( spdiv ) - FCKIT_SUPPRESS_UNUSED( config ) -#endif end subroutine dirtrans_wind2vordiv_field @@ -371,7 +315,6 @@ subroutine invtrans_field(this, spfield, gpfield, config) class(atlas_Field), intent(in) :: spfield class(atlas_Field), intent(inout) :: gpfield class(atlas_Config), intent(in), optional :: config -#if ATLAS_HAVE_TRANS type(atlas_Config) :: p if( present(config) ) then @@ -388,13 +331,6 @@ subroutine invtrans_field(this, spfield, gpfield, config) if( .not. present(config) ) then call p%final() endif -#else - THROW_ERROR - FCKIT_SUPPRESS_UNUSED( this ) - FCKIT_SUPPRESS_UNUSED( spfield ) - FCKIT_SUPPRESS_UNUSED( gpfield ) - FCKIT_SUPPRESS_UNUSED( config ) -#endif end subroutine invtrans_field @@ -405,7 +341,6 @@ subroutine invtrans_vordiv2wind_field(this, spvor, spdiv, gpwind, config) class(atlas_Field), intent(in) :: spdiv class(atlas_Field), intent(inout) :: gpwind class(atlas_Config), intent(in), optional :: config -#if ATLAS_HAVE_TRANS type(atlas_Config) :: p if( present(config) ) then @@ -423,14 +358,6 @@ subroutine invtrans_vordiv2wind_field(this, spvor, spdiv, gpwind, config) if( .not. present(config) ) then call p%final() endif -#else - THROW_ERROR - FCKIT_SUPPRESS_UNUSED( this ) - FCKIT_SUPPRESS_UNUSED( spvor ) - FCKIT_SUPPRESS_UNUSED( spdiv ) - FCKIT_SUPPRESS_UNUSED( gpwind ) - FCKIT_SUPPRESS_UNUSED( config ) -#endif end subroutine invtrans_vordiv2wind_field @@ -440,7 +367,6 @@ subroutine invtrans_grad_field(this, spfield, gpfield) class(atlas_Trans), intent(in) :: this class(atlas_Field), intent(in) :: spfield class(atlas_Field), intent(inout) :: gpfield -#if ATLAS_HAVE_TRANS type(atlas_Config) :: config config = atlas_Config() call atlas__Trans__invtrans_grad_field( this%CPTR_PGIBUG_A, & @@ -448,102 +374,8 @@ subroutine invtrans_grad_field(this, spfield, gpfield) & gpfield%CPTR_PGIBUG_A, & & config%CPTR_PGIBUG_B) call config%final() -#else - THROW_ERROR - FCKIT_SUPPRESS_UNUSED( this ) - FCKIT_SUPPRESS_UNUSED( spfield ) - FCKIT_SUPPRESS_UNUSED( gpfield ) -#endif end subroutine invtrans_grad_field - - -subroutine gathspec_r1(this, local, global) - use atlas_trans_c_binding - use, intrinsic :: iso_c_binding, only : c_double - class(atlas_Trans), intent(in) :: this - real(c_double), intent(in) :: local(:) - real(c_double), intent(inout) :: global(:) -#if ATLAS_HAVE_TRANS - call atlas__Trans__gathspec(this%CPTR_PGIBUG_A, 1, (/1/), local, global ) -#else - THROW_ERROR - FCKIT_SUPPRESS_UNUSED( this ) - FCKIT_SUPPRESS_UNUSED( local ) - FCKIT_SUPPRESS_UNUSED( global ) -#endif -end subroutine gathspec_r1 - -subroutine gathspec_r2(this, local, global) - use, intrinsic :: iso_c_binding, only : c_double - use fckit_array_module, only: array_view1d - use atlas_trans_c_binding - class(atlas_Trans), intent(in) :: this - real(c_double), intent(in) :: local(:,:) - real(c_double), intent(inout) :: global(:,:) -#if ATLAS_HAVE_TRANS - real(c_double), pointer :: local_view(:), global_view(:) - integer :: destination(size(local,1)) - destination(:) = 1 - local_view => array_view1d(local) - global_view => array_view1d(global) - call atlas__Trans__gathspec(this%CPTR_PGIBUG_A, size(local,1), destination, local_view, global_view ) -#else - THROW_ERROR - FCKIT_SUPPRESS_UNUSED( this ) - FCKIT_SUPPRESS_UNUSED( local ) - FCKIT_SUPPRESS_UNUSED( global ) -#endif -end subroutine gathspec_r2 - - -subroutine specnorm_r1_scalar(this, spectra, norm, rank) - use atlas_trans_c_binding - use, intrinsic :: iso_c_binding, only : c_double - class(atlas_Trans), intent(in) :: this - real(c_double), intent(in) :: spectra(:) - real(c_double), intent(out) :: norm - integer, optional :: rank ! MPI rank -#if ATLAS_HAVE_TRANS - integer :: rank_opt - real(c_double) :: norms(1) - rank_opt = 0 - if( present(rank) ) rank_opt = rank - call atlas__Trans__specnorm(this%CPTR_PGIBUG_A, 1, spectra, norms, rank_opt ) - norm = norms(1) -#else - norm=0 - THROW_ERROR - FCKIT_SUPPRESS_UNUSED( this ) - FCKIT_SUPPRESS_UNUSED( spectra ) - FCKIT_SUPPRESS_UNUSED( rank ) -#endif -end subroutine - -subroutine specnorm_r2(this, spectra, norm, rank) - use, intrinsic :: iso_c_binding, only : c_double - use fckit_array_module, only: array_view1d - use atlas_trans_c_binding - class(atlas_Trans), intent(in) :: this - real(c_double), intent(in) :: spectra(:,:) - real(c_double), intent(inout) :: norm(:) - integer, optional :: rank ! MPI rank -#if ATLAS_HAVE_TRANS - integer :: rank_opt - real(c_double), pointer :: spectra_view(:) - rank_opt = 0 - if( present(rank) ) rank_opt = rank - spectra_view => array_view1d(spectra) - call atlas__Trans__specnorm(this%CPTR_PGIBUG_A, size(spectra,1), spectra_view, norm, rank_opt ) -#else - THROW_ERROR - FCKIT_SUPPRESS_UNUSED( this ) - FCKIT_SUPPRESS_UNUSED( spectra ) - FCKIT_SUPPRESS_UNUSED( norm ) - FCKIT_SUPPRESS_UNUSED( rank ) -#endif -end subroutine - !------------------------------------------------------------------------------- ATLAS_FINAL subroutine atlas_Trans__final_auto(this) diff --git a/src/tests/trans/CMakeLists.txt b/src/tests/trans/CMakeLists.txt index 660ff626c..3f38d00e2 100644 --- a/src/tests/trans/CMakeLists.txt +++ b/src/tests/trans/CMakeLists.txt @@ -8,6 +8,8 @@ if( HAVE_FCTEST ) +ecbuild_warn_var( ECKIT_HAVE_MPI ) +ecbuild_warn_var( TRANSI_HAVE_MPI ) if( ATLAS_HAVE_TRANS ) add_fctest( TARGET atlas_fctest_trans LINKER_LANGUAGE Fortran @@ -19,14 +21,14 @@ if( HAVE_FCTEST ) ) endif() - if( ATLAS_HAVE_TRANS ) +# if( ATLAS_HAVE_TRANS ) add_fctest( TARGET atlas_fctest_trans_invtrans_grad LINKER_LANGUAGE Fortran SOURCES fctest_trans_invtrans_grad.F90 LIBS atlas_f ENVIRONMENT ${ATLAS_TEST_ENVIRONMENT} ) - endif() +# endif() endif() diff --git a/src/tests/trans/fctest_trans.F90 b/src/tests/trans/fctest_trans.F90 index 523e5d90f..f9721082e 100644 --- a/src/tests/trans/fctest_trans.F90 +++ b/src/tests/trans/fctest_trans.F90 @@ -44,6 +44,19 @@ end module fctest_atlas_trans_fixture ! ----------------------------------------------------------------------------- +TEST( test_trans_backend ) + type(atlas_Trans) :: trans + FCTEST_CHECK( trans%has_backend("local") ) + FCTEST_CHECK( trans%has_backend("ifs") ) + if( trans%has_backend("ifs") ) then + FCTEST_CHECK_EQUAL( trans%backend(), "ifs" ) + else + FCTEST_CHECK_EQUAL( trans%backend(), "local" ) + endif +END_TEST + +! ----------------------------------------------------------------------------- + TEST( test_trans ) type(atlas_StructuredGrid) :: grid type(atlas_StructuredGrid) :: trans_grid @@ -52,7 +65,7 @@ end module fctest_atlas_trans_fixture type(atlas_Trans) :: trans type(atlas_mesh_Nodes) :: nodes type(atlas_functionspace_NodeColumns) :: nodes_fs - type(atlas_functionspace_Spectral) :: spectral_fs + type(atlas_functionspace_Spectral) :: spectral_fs, trans_spectral type(atlas_Field) :: scalarfield1, scalarfield2 type(atlas_Field) :: windfield type(atlas_Field) :: vorfield,divfield @@ -86,14 +99,16 @@ end module fctest_atlas_trans_fixture trans = atlas_Trans(grid,truncation) FCTEST_CHECK_EQUAL( grid%owners(), 3 ) ! trans tracks grid - FCTEST_CHECK_EQUAL( trans%nb_gridpoints_global(), int(grid%size()) ) + ! FCTEST_CHECK_EQUAL( trans%nb_gridpoints_global(), int(grid%size()) ) trans_grid = trans%grid() FCTEST_CHECK_EQUAL( trans_grid%owners(), 4 ) FCTEST_CHECK( .not. trans%is_null() ) FCTEST_CHECK_EQUAL( trans%truncation(), truncation ) - FCTEST_CHECK_EQUAL( trans%nb_spectral_coefficients_global(), (truncation+1)*(truncation+2) ) + + trans_spectral = trans%spectral() + FCTEST_CHECK_EQUAL( trans_spectral%nb_spectral_coefficients_global(), (truncation+1)*(truncation+2) ) nodes = mesh%nodes() nodes_fs = atlas_functionspace_NodeColumns(mesh,0) @@ -109,6 +124,8 @@ end module fctest_atlas_trans_fixture spectral_fs = atlas_functionspace_Spectral(trans) write(msg,*) "spectral_fs%owners()",spectral_fs%owners(); call fckit_log%info(msg) + FCTEST_CHECK_EQUAL( spectral_fs%nb_spectral_coefficients_global(), (truncation+1)*(truncation+2) ) + spectralfield1 = spectral_fs%create_field(name="spectral1",kind=atlas_real(c_double),levels=nlev) write(msg,*) "spectral_fs%owners()",spectral_fs%owners(); call fckit_log%info(msg) From f1a115f50235c0cb4efa27d3854859922d4561dc Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Tue, 11 Jun 2019 14:46:21 +0100 Subject: [PATCH 30/86] ATLAS-234 Unstructured grids in Fortran --- src/apps/atlas-grids.cc | 75 +++--- src/atlas/domain/Domain.h | 2 +- src/atlas/grid/detail/grid/Unstructured.cc | 61 +++-- src/atlas/grid/detail/grid/Unstructured.h | 6 + .../detail/DelaunayMeshGenerator.cc | 2 + .../meshgenerator/detail/MeshGeneratorImpl.cc | 4 + .../meshgenerator/detail/MeshGeneratorImpl.h | 1 + src/atlas/trans/local/TransLocal.cc | 40 ++- src/atlas_f/CMakeLists.txt | 3 + src/atlas_f/atlas_module.F90 | 3 +- src/atlas_f/grid/atlas_Grid_module.F90 | 73 ++++++ .../mesh/atlas_MeshGenerator_module.F90 | 9 + src/tests/grid/CMakeLists.txt | 3 +- src/tests/grid/fctest_unstructuredgrid.F90 | 243 ++++++++++++++++++ 14 files changed, 444 insertions(+), 81 deletions(-) create mode 100644 src/tests/grid/fctest_unstructuredgrid.F90 diff --git a/src/apps/atlas-grids.cc b/src/apps/atlas-grids.cc index b08290f00..958329d3b 100644 --- a/src/apps/atlas-grids.cc +++ b/src/apps/atlas-grids.cc @@ -120,9 +120,7 @@ int AtlasGrids::execute( const Args& args ) { Grid grid; PathName spec{key}; - if ( spec.exists() ) { - grid = Grid( Grid::Spec{spec} ); - } + if ( spec.exists() ) { grid = Grid( Grid::Spec{spec} ); } else { grid = Grid( key ); } @@ -144,72 +142,87 @@ int AtlasGrids::execute( const Args& args ) { Log::info() << " memory footprint per field (dp): " << eckit::Bytes( memsize ) << std::endl; if ( auto structuredgrid = StructuredGrid( grid ) ) { - if ( not grid.projection() ) { double deg, km; - + Log::info() << " number of latitudes (N-S): " << structuredgrid.ny() << std::endl; Log::info() << " number of longitudes (max): " << structuredgrid.nxmax() << std::endl; - + deg = ( structuredgrid.y().front() - structuredgrid.y().back() ) / ( structuredgrid.ny() - 1 ); km = deg * 40075. / 360.; Log::info() << " approximate resolution N-S: " << std::setw( 10 ) << std::fixed << deg << " deg " << km << " km " << std::endl; - + deg = 360. / static_cast( structuredgrid.nx( structuredgrid.ny() / 2 ) ); km = deg * 40075. / 360.; Log::info() << " approximate resolution E-W equator: " << std::setw( 10 ) << std::fixed << deg << " deg " << km << " km " << std::endl; - + deg = 360. * std::cos( structuredgrid.y( structuredgrid.ny() / 4 ) * M_PI / 180. ) / static_cast( structuredgrid.nx( structuredgrid.ny() / 4 ) ); km = deg * 40075. / 360.; Log::info() << " approximate resolution E-W midlat: " << std::setw( 10 ) << std::fixed << deg << " deg " << km << " km " << std::endl; - - deg = 360. * std::cos( structuredgrid.y().front() * M_PI / 180. ) / static_cast( structuredgrid.nx().front() ); - km = deg * 40075. / 360.; - - + + deg = 360. * std::cos( structuredgrid.y().front() * M_PI / 180. ) / + static_cast( structuredgrid.nx().front() ); + km = deg * 40075. / 360.; + + Log::info() << " approximate resolution E-W pole: " << std::setw( 10 ) << std::fixed << deg << " deg " << km << " km " << std::endl; - + Log::info() << " spectral truncation -- linear: " << structuredgrid.ny() - 1 << std::endl; Log::info() << " spectral truncation -- quadratic: " - << static_cast( std::floor( 2. / 3. * structuredgrid.ny() + 0.5 ) ) - 1 << std::endl; + << static_cast( std::floor( 2. / 3. * structuredgrid.ny() + 0.5 ) ) - 1 + << std::endl; Log::info() << " spectral truncation -- cubic: " << static_cast( std::floor( 0.5 * structuredgrid.ny() + 0.5 ) ) - 1 << std::endl; } - + auto precision = Log::info().precision( 3 ); if ( grid.projection().units() == "meters" ) { - Log::info() << " x : [ " << std::setw( 10 ) << std::fixed << structuredgrid.xspace().min() / 1000. << " , " - << std::setw( 10 ) << std::fixed << structuredgrid.xspace().max() / 1000. << " ] km" << std::endl; - Log::info() << " y : [ " << std::setw( 10 ) << std::fixed << structuredgrid.yspace().min() / 1000. << " , " - << std::setw( 10 ) << std::fixed << structuredgrid.yspace().max() / 1000. << " ] km" << std::endl; + Log::info() << " x : [ " << std::setw( 10 ) << std::fixed << structuredgrid.xspace().min() / 1000. + << " , " << std::setw( 10 ) << std::fixed << structuredgrid.xspace().max() / 1000. + << " ] km" << std::endl; + Log::info() << " y : [ " << std::setw( 10 ) << std::fixed << structuredgrid.yspace().min() / 1000. + << " , " << std::setw( 10 ) << std::fixed << structuredgrid.yspace().max() / 1000. + << " ] km" << std::endl; if ( structuredgrid.xspace().nxmax() == structuredgrid.xspace().nxmin() ) { Log::info() << " dx : " << structuredgrid.xspace().dx()[0] / 1000. << " km" << std::endl; } - Log::info() << " dy : " << std::abs( structuredgrid.yspace()[1] - structuredgrid.yspace()[0] ) / 1000. << " km" + Log::info() << " dy : " + << std::abs( structuredgrid.yspace()[1] - structuredgrid.yspace()[0] ) / 1000. << " km" << std::endl; Log::info() << " lonlat(centre) : " - << grid.projection().lonlat( {0.5 * ( structuredgrid.xspace().max() + structuredgrid.xspace().min() ), - 0.5 * ( structuredgrid.yspace().max() + structuredgrid.yspace().min() )} ) + << grid.projection().lonlat( + {0.5 * ( structuredgrid.xspace().max() + structuredgrid.xspace().min() ), + 0.5 * ( structuredgrid.yspace().max() + structuredgrid.yspace().min() )} ) << std::endl; Log::info() << " lonlat(xmin,ymax) : " - << grid.projection().lonlat( {structuredgrid.xspace().min(), structuredgrid.yspace().max()} ) << std::endl; + << grid.projection().lonlat( + {structuredgrid.xspace().min(), structuredgrid.yspace().max()} ) + << std::endl; Log::info() << " lonlat(xmin,ymin) : " - << grid.projection().lonlat( {structuredgrid.xspace().min(), structuredgrid.yspace().min()} ) << std::endl; + << grid.projection().lonlat( + {structuredgrid.xspace().min(), structuredgrid.yspace().min()} ) + << std::endl; Log::info() << " lonlat(xmax,ymin) : " - << grid.projection().lonlat( {structuredgrid.xspace().max(), structuredgrid.yspace().min()} ) << std::endl; + << grid.projection().lonlat( + {structuredgrid.xspace().max(), structuredgrid.yspace().min()} ) + << std::endl; Log::info() << " lonlat(xmax,ymax) : " - << grid.projection().lonlat( {structuredgrid.xspace().max(), structuredgrid.yspace().max()} ) << std::endl; + << grid.projection().lonlat( + {structuredgrid.xspace().max(), structuredgrid.yspace().max()} ) + << std::endl; } if ( grid.projection().units() == "degrees" ) { - Log::info() << " x : [ " << std::setw( 10 ) << std::fixed << structuredgrid.xspace().min() << " , " - << std::setw( 10 ) << std::fixed << structuredgrid.xspace().max() << " ] deg" << std::endl; - Log::info() << " y : [ " << std::setw( 10 ) << std::fixed << structuredgrid.yspace().min() << " , " - << std::setw( 10 ) << std::fixed << structuredgrid.yspace().max() << " ] deg" << std::endl; + Log::info() << " x : [ " << std::setw( 10 ) << std::fixed << structuredgrid.xspace().min() + << " , " << std::setw( 10 ) << std::fixed << structuredgrid.xspace().max() << " ] deg" + << std::endl; + Log::info() << " y : [ " << std::setw( 10 ) << std::fixed << structuredgrid.yspace().min() + << " , " << std::setw( 10 ) << std::fixed << structuredgrid.yspace().max() << " ] deg" + << std::endl; } PointLonLat first_point = *grid.lonlat().begin(); PointLonLat last_point; diff --git a/src/atlas/domain/Domain.h b/src/atlas/domain/Domain.h index 5b8129379..50dccff4a 100644 --- a/src/atlas/domain/Domain.h +++ b/src/atlas/domain/Domain.h @@ -153,7 +153,7 @@ class GlobalDomain; class GlobalDomain : public ZonalBandDomain { public: GlobalDomain( const double& west ); - GlobalDomain( ); + GlobalDomain(); GlobalDomain( const Domain& ); operator bool() { return domain_; } diff --git a/src/atlas/grid/detail/grid/Unstructured.cc b/src/atlas/grid/detail/grid/Unstructured.cc index de964ff73..3d5f82373 100644 --- a/src/atlas/grid/detail/grid/Unstructured.cc +++ b/src/atlas/grid/detail/grid/Unstructured.cc @@ -11,9 +11,9 @@ #include "atlas/grid/detail/grid/Unstructured.h" #include +#include #include #include -#include #include "eckit/types/FloatCompare.h" #include "eckit/utils/Hash.h" @@ -21,8 +21,8 @@ #include "atlas/array/ArrayView.h" #include "atlas/field/Field.h" #include "atlas/grid/Iterator.h" -#include "atlas/grid/detail/grid/GridFactory.h" #include "atlas/grid/detail/grid/GridBuilder.h" +#include "atlas/grid/detail/grid/GridFactory.h" #include "atlas/mesh/Mesh.h" #include "atlas/mesh/Nodes.h" #include "atlas/option.h" @@ -36,8 +36,6 @@ namespace grid { namespace detail { namespace grid { -//static eckit::ConcreteBuilderT1 builder_Unstructured( Unstructured::static_type() ); - namespace { static GridFactoryBuilder __register_Unstructured( Unstructured::static_type() ); } @@ -106,32 +104,27 @@ Unstructured::Unstructured( const Grid& grid, Domain domain ) : Grid() { Unstructured::Unstructured( const util::Config& config ) : Grid() { util::Config config_domain; - if( not config.get("domain", config_domain) ) { - config_domain.set( "type", "global" ); - } + if ( not config.get( "domain", config_domain ) ) { config_domain.set( "type", "global" ); } domain_ = Domain( config_domain ); std::vector xy; - if( config.get( "xy", xy ) ) { - const size_t N = xy.size()/2; + if ( config.get( "xy", xy ) ) { + const size_t N = xy.size() / 2; points_.reset( new std::vector ); points_->reserve( N ); - for( size_t n=0; nemplace_back( PointXY{xy[2*n],xy[2*n+1]} ); + for ( size_t n = 0; n < N; ++n ) { + points_->emplace_back( PointXY{xy[2 * n], xy[2 * n + 1]} ); } - } else { + } + else { std::vector x; std::vector y; - if( not config.get( "x", x ) ) { - throw_Exception("x missing from configuration"); - } - if( not config.get( "y", y ) ) { - throw_Exception("y missing from configuration"); - } + if ( not config.get( "x", x ) ) { throw_Exception( "x missing from configuration" ); } + if ( not config.get( "y", y ) ) { throw_Exception( "y missing from configuration" ); } ATLAS_ASSERT( x.size() == y.size() ); points_.reset( new std::vector ); points_->reserve( x.size() ); - for( size_t n=0; nemplace_back( PointXY{x[n],y[n]} ); + for ( size_t n = 0; n < x.size(); ++n ) { + points_->emplace_back( PointXY{x[n], y[n]} ); } } } @@ -223,7 +216,6 @@ bool Unstructured::IteratorXYPredicated::next( PointXY& /*xy*/ ) { #endif } -#if 1 namespace { // anonymous static class unstructured : public GridBuilder { @@ -242,14 +234,33 @@ static class unstructured : public GridBuilder { throw_NotImplemented( "Cannot create unstructured grid from name", Here() ); } - virtual const Implementation* create( const Config& config ) const { - return new Unstructured( config ); - } + virtual const Implementation* create( const Config& config ) const { return new Unstructured( config ); } } unstructured_; } // anonymous namespace -#endif + +extern "C" { +const Unstructured* atlas__grid__Unstructured__points( const double xy[], int shapef[], int stridesf[] ) { + size_t nb_points = shapef[1]; + ATLAS_ASSERT( shapef[0] == 2 ); + size_t stride_n = stridesf[1]; + size_t stride_v = stridesf[0]; + std::vector points; + points.reserve( nb_points ); + for ( idx_t n = 0; n < nb_points; ++n ) { + points.emplace_back( PointXY{xy[n * stride_n + 0], xy[n * stride_n + 1 * stride_v]} ); + } + return new Unstructured( std::move( points ) ); +} + +const Unstructured* atlas__grid__Unstructured__config( util::Config* conf ) { + ATLAS_ASSERT( conf != nullptr ); + const Unstructured* grid = dynamic_cast( Grid::create( *conf ) ); + ATLAS_ASSERT( grid != nullptr ); + return grid; +} +} } // namespace grid diff --git a/src/atlas/grid/detail/grid/Unstructured.h b/src/atlas/grid/detail/grid/Unstructured.h index 799f979bf..2af80723c 100644 --- a/src/atlas/grid/detail/grid/Unstructured.h +++ b/src/atlas/grid/detail/grid/Unstructured.h @@ -209,6 +209,12 @@ class Unstructured : public Grid { mutable std::unique_ptr cached_spec_; }; +extern "C" { +const Unstructured* atlas__grid__Unstructured__points( const double lonlat[], int shapef[], int stridesf[] ); +const Unstructured* atlas__grid__Unstructured__config( util::Config* conf ); +} + + } // namespace grid } // namespace detail } // namespace grid diff --git a/src/atlas/meshgenerator/detail/DelaunayMeshGenerator.cc b/src/atlas/meshgenerator/detail/DelaunayMeshGenerator.cc index 5a591c689..64a96c406 100644 --- a/src/atlas/meshgenerator/detail/DelaunayMeshGenerator.cc +++ b/src/atlas/meshgenerator/detail/DelaunayMeshGenerator.cc @@ -74,6 +74,8 @@ void DelaunayMeshGenerator::generate( const Grid& g, Mesh& mesh ) const { mesh::actions::ExtendNodesGlobal()( g, mesh ); ///< does nothing if global domain mesh::actions::BuildConvexHull3D()( mesh ); + + setGrid( mesh, g, "serial" ); } void DelaunayMeshGenerator::createNodes( const Grid& grid, Mesh& mesh ) const { diff --git a/src/atlas/meshgenerator/detail/MeshGeneratorImpl.cc b/src/atlas/meshgenerator/detail/MeshGeneratorImpl.cc index 8d2a5a4f1..d08b62001 100644 --- a/src/atlas/meshgenerator/detail/MeshGeneratorImpl.cc +++ b/src/atlas/meshgenerator/detail/MeshGeneratorImpl.cc @@ -96,6 +96,10 @@ void MeshGeneratorImpl::setGrid( Mesh& mesh, const Grid& g, const grid::Distribu mesh.setGrid( g ); mesh.metadata().set( "distribution", d.type() ); } +void MeshGeneratorImpl::setGrid( Mesh& mesh, const Grid& g, const std::string& d ) const { + mesh.setGrid( g ); + mesh.metadata().set( "distribution", d ); +} //---------------------------------------------------------------------------------------------------------------------- diff --git a/src/atlas/meshgenerator/detail/MeshGeneratorImpl.h b/src/atlas/meshgenerator/detail/MeshGeneratorImpl.h index 679b61c46..6dd48f27e 100644 --- a/src/atlas/meshgenerator/detail/MeshGeneratorImpl.h +++ b/src/atlas/meshgenerator/detail/MeshGeneratorImpl.h @@ -55,6 +55,7 @@ class MeshGeneratorImpl : public util::Object { void generateGlobalElementNumbering( Mesh& mesh ) const; void setProjection( Mesh&, const Projection& ) const; void setGrid( Mesh&, const Grid&, const grid::Distribution& ) const; + void setGrid( Mesh&, const Grid&, const std::string& distribution ) const; }; //---------------------------------------------------------------------------------------------------------------------- diff --git a/src/atlas/trans/local/TransLocal.cc b/src/atlas/trans/local/TransLocal.cc index a5edbf84e..53fbf227e 100644 --- a/src/atlas/trans/local/TransLocal.cc +++ b/src/atlas/trans/local/TransLocal.cc @@ -717,29 +717,26 @@ const functionspace::Spectral& TransLocal::spectral() const { // -------------------------------------------------------------------------------------------------------------------- void TransLocal::invtrans( const Field& spfield, Field& gpfield, const eckit::Configuration& config ) const { + // VERY PRELIMINARY IMPLEMENTATION WITHOUT ANY GUARANTEES + int nb_scalar_fields = 1; + const auto scalar_spectra = array::make_view( spfield ); + auto gp_fields = array::make_view( spfield ); -// VERY PRELIMINARY IMPLEMENTATION WITHOUT ANY GUARANTEES - int nb_scalar_fields = 1; - const auto scalar_spectra = array::make_view( spfield ); - auto gp_fields = array::make_view( spfield ); - - if( gp_fields.shape(0) != grid().size() ) { - ATLAS_DEBUG_VAR( gp_fields.shape(0) ); + if ( gp_fields.shape( 0 ) != grid().size() ) { + ATLAS_DEBUG_VAR( gp_fields.shape( 0 ) ); ATLAS_DEBUG_VAR( grid().size() ); - ATLAS_ASSERT( gp_fields.shape(0) == grid().size() ); + ATLAS_ASSERT( gp_fields.shape( 0 ) == grid().size() ); } invtrans( nb_scalar_fields, scalar_spectra.data(), gp_fields.data(), config ); - } // -------------------------------------------------------------------------------------------------------------------- void TransLocal::invtrans( const FieldSet& spfields, FieldSet& gpfields, const eckit::Configuration& config ) const { - -// VERY PRELIMINARY IMPLEMENTATION WITHOUT ANY GUARANTEES + // VERY PRELIMINARY IMPLEMENTATION WITHOUT ANY GUARANTEES ATLAS_ASSERT( spfields.size() == gpfields.size() ); - for( idx_t f=0; f( spvor ); + const auto divergence_spectra = array::make_view( spdiv ); + auto gp_fields = array::make_view( gpwind ); -// VERY PRELIMINARY IMPLEMENTATION WITHOUT ANY GUARANTEES - int nb_vordiv_fields = 1; - const auto vorticity_spectra = array::make_view( spvor ); - const auto divergence_spectra = array::make_view( spdiv ); - auto gp_fields = array::make_view( gpwind ); - - if( gp_fields.shape(1) == grid().size() && gp_fields.shape(0) == 2 ) { + if ( gp_fields.shape( 1 ) == grid().size() && gp_fields.shape( 0 ) == 2 ) { invtrans( nb_vordiv_fields, vorticity_spectra.data(), divergence_spectra.data(), gp_fields.data(), config ); } - else if( gp_fields.shape(0) == grid().size() && gp_fields.shape(1) == 2 ) { - array::ArrayT gpwind_t( gp_fields.shape(1), gp_fields.shape(0) ); - auto gp_fields_t = array::make_view( gpwind_t ); + else if ( gp_fields.shape( 0 ) == grid().size() && gp_fields.shape( 1 ) == 2 ) { + array::ArrayT gpwind_t( gp_fields.shape( 1 ), gp_fields.shape( 0 ) ); + auto gp_fields_t = array::make_view( gpwind_t ); invtrans( nb_vordiv_fields, vorticity_spectra.data(), divergence_spectra.data(), gp_fields_t.data(), config ); gp_transpose( grid().size(), 2, gp_fields_t.data(), gp_fields.data() ); } diff --git a/src/atlas_f/CMakeLists.txt b/src/atlas_f/CMakeLists.txt index 276c1ca81..8ed090448 100644 --- a/src/atlas_f/CMakeLists.txt +++ b/src/atlas_f/CMakeLists.txt @@ -58,6 +58,9 @@ generate_fortran_bindings(FORTRAN_BINDINGS ../atlas/grid.h) generate_fortran_bindings(FORTRAN_BINDINGS ../atlas/grid/detail/grid/Structured.h MODULE atlas_grid_Structured_c_binding OUTPUT grid_Structured_c_binding.f90 ) +generate_fortran_bindings(FORTRAN_BINDINGS ../atlas/grid/detail/grid/Unstructured.h + MODULE atlas_grid_Unstructured_c_binding + OUTPUT grid_Unstructured_c_binding.f90 ) generate_fortran_bindings(FORTRAN_BINDINGS ../atlas/grid/detail/distribution/DistributionImpl.h MODULE atlas_distribution_c_binding OUTPUT distribution_c_binding.f90 ) diff --git a/src/atlas_f/atlas_module.F90 b/src/atlas_f/atlas_module.F90 index 64358778e..0478bd0c4 100644 --- a/src/atlas_f/atlas_module.F90 +++ b/src/atlas_f/atlas_module.F90 @@ -67,7 +67,8 @@ module atlas_module use atlas_GridDistribution_module, only: & & atlas_GridDistribution use atlas_Grid_module, only: & - & atlas_Grid , & + & atlas_Grid, & + & atlas_UnstructuredGrid, & & atlas_StructuredGrid, & & atlas_GaussianGrid, & & atlas_ReducedGaussianGrid, & diff --git a/src/atlas_f/grid/atlas_Grid_module.F90 b/src/atlas_f/grid/atlas_Grid_module.F90 index 82ecc9447..77480bccd 100644 --- a/src/atlas_f/grid/atlas_Grid_module.F90 +++ b/src/atlas_f/grid/atlas_Grid_module.F90 @@ -22,6 +22,7 @@ module atlas_Grid_module private :: c_ptr public :: atlas_Grid +public :: atlas_UnstructuredGrid public :: atlas_StructuredGrid public :: atlas_GaussianGrid public :: atlas_ReducedGaussianGrid @@ -62,6 +63,34 @@ module atlas_Grid_module !------------------------------------------------------------------------------ +TYPE, extends(atlas_Grid) :: atlas_UnstructuredGrid + +! Purpose : +! ------- +! *atlas_UnstructuredGrid* : Object Grid specifications for Reduced Grids + +! Methods : +! ------- + +! Author : +! ------ +! 8-Jun-2019 Willem Deconinck *ECMWF* + +!------------------------------------------------------------------------------ +contains +#if FCKIT_FINAL_NOT_INHERITING + final :: atlas_UnstructuredGrid__final_auto +#endif +END TYPE atlas_UnstructuredGrid + +interface atlas_UnstructuredGrid + module procedure atlas_UnstructuredGrid__ctor_points + module procedure atlas_UnstructuredGrid__ctor_config + module procedure atlas_UnstructuredGrid__ctor_cptr +end interface + +!------------------------------------------------------------------------------ + TYPE, extends(atlas_Grid) :: atlas_StructuredGrid ! Purpose : @@ -265,6 +294,14 @@ ATLAS_FINAL subroutine atlas_Grid__final_auto(this) FCKIT_SUPPRESS_UNUSED( this ) end subroutine +ATLAS_FINAL subroutine atlas_UnstructuredGrid__final_auto(this) + type(atlas_UnstructuredGrid), intent(inout) :: this +#if FCKIT_FINAL_NOT_PROPAGATING + call this%final() +#endif + FCKIT_SUPPRESS_UNUSED( this ) +end subroutine + ATLAS_FINAL subroutine atlas_StructuredGrid__final_auto(this) type(atlas_StructuredGrid), intent(inout) :: this #if FCKIT_FINAL_NOT_PROPAGATING @@ -338,6 +375,42 @@ function atlas_Grid__ctor_cptr(cptr) result(this) ! ----------------------------------------------------------------------------- +function atlas_UnstructuredGrid__ctor_config(config) result(this) + use atlas_grid_unstructured_c_binding + type(atlas_UnstructuredGrid) :: this + type(atlas_Config), intent(in) :: config + call this%reset_c_ptr( atlas__grid__Unstructured__config(config%CPTR_PGIBUG_B) ) + call this%return() +end function + +function atlas_UnstructuredGrid__ctor_cptr(cptr) result(this) + use fckit_c_interop_module, only: c_str + use atlas_grid_unstructured_c_binding + type(atlas_UnstructuredGrid) :: this + type(c_ptr), intent(in) :: cptr + call this%reset_c_ptr( cptr ) + call this%return() +end function + +function atlas_UnstructuredGrid__ctor_points( xy ) result(this) + use, intrinsic :: iso_c_binding, only : c_double, c_int + use fckit_c_interop_module, only : c_str + use fckit_array_module, only : array_strides, array_view1d + use atlas_grid_unstructured_c_binding + type(atlas_UnstructuredGrid) :: this + real(c_double), intent(in) :: xy(:,:) + integer(c_int) :: shapef(2) + integer(c_int) :: stridesf(2) + real(c_double), pointer :: xy1d(:) + xy1d => array_view1d(xy) + shapef = shape(xy) + stridesf = array_strides(xy) + call this%reset_c_ptr( atlas__grid__Unstructured__points( xy1d, shapef, stridesf ) ) + call this%return() +end function + +! ----------------------------------------------------------------------------- + function atlas_StructuredGrid__ctor_id(identifier) result(this) use fckit_c_interop_module, only: c_str use atlas_grid_Structured_c_binding diff --git a/src/atlas_f/mesh/atlas_MeshGenerator_module.F90 b/src/atlas_f/mesh/atlas_MeshGenerator_module.F90 index 0e0c6a4fc..f5db338c3 100644 --- a/src/atlas_f/mesh/atlas_MeshGenerator_module.F90 +++ b/src/atlas_f/mesh/atlas_MeshGenerator_module.F90 @@ -38,6 +38,7 @@ module atlas_MeshGenerator_module interface atlas_MeshGenerator module procedure atlas_MeshGenerator__cptr module procedure atlas_MeshGenerator__config + module procedure atlas_MeshGenerator__type end interface !------------------------------------------------------------------------------ @@ -56,6 +57,14 @@ function atlas_MeshGenerator__cptr(cptr) result(this) call this%return() end function +function atlas_MeshGenerator__type(type) result(this) + use fckit_c_interop_module, only: c_str + use atlas_MeshGenerator_c_binding + type(atlas_MeshGenerator) :: this + character(len=*), intent(in) :: type + call this%reset_c_ptr( atlas__MeshGenerator__create_noconfig(c_str(type)) ) + call this%return() +end function function atlas_MeshGenerator__config(config) result(this) use fckit_c_interop_module, only: c_str diff --git a/src/tests/grid/CMakeLists.txt b/src/tests/grid/CMakeLists.txt index 8a7edd654..c36d33bde 100644 --- a/src/tests/grid/CMakeLists.txt +++ b/src/tests/grid/CMakeLists.txt @@ -9,7 +9,8 @@ if( HAVE_FCTEST ) foreach(test fctest_griddistribution - fctest_state) + fctest_state + fctest_unstructuredgrid) add_fctest( TARGET atlas_${test} SOURCES ${test}.F90 LINKER_LANGUAGE Fortran LIBS atlas_f ENVIRONMENT ${ATLAS_TEST_ENVIRONMENT} ) diff --git a/src/tests/grid/fctest_unstructuredgrid.F90 b/src/tests/grid/fctest_unstructuredgrid.F90 new file mode 100644 index 000000000..3e3e31458 --- /dev/null +++ b/src/tests/grid/fctest_unstructuredgrid.F90 @@ -0,0 +1,243 @@ +! (C) Copyright 2013 ECMWF. +! This software is licensed under the terms of the Apache Licence Version 2.0 +! which can be obtained at http://www.apache.org/licenses/LICENSE-2.0. +! In applying this licence, ECMWF does not waive the privileges and immunities +! granted to it by virtue of its status as an intergovernmental organisation nor +! does it submit to any jurisdiction. + +! This File contains Unit Tests for testing the +! C++ / Fortran Interfaces to the Mesh Datastructure +! @author Willem Deconinck + +#include "fckit/fctest.h" + +! ----------------------------------------------------------------------------- + +TESTSUITE(fctest_GridDist) + +! ----------------------------------------------------------------------------- + +TESTSUITE_INIT + use atlas_module + call atlas_library%initialise() +END_TESTSUITE_INIT + +! ----------------------------------------------------------------------------- + +TESTSUITE_FINALIZE + use atlas_module + call atlas_library%finalise() +END_TESTSUITE_FINALIZE + +! ---------------------------------------------------------------------------- + +TEST( test_unstructuredgrid ) + use, intrinsic :: iso_c_binding + use atlas_module + implicit none + type(atlas_UnstructuredGrid) :: grid + type(atlas_Mesh) :: mesh + type(atlas_Output) :: gmsh + type(atlas_MeshGenerator) :: meshgenerator + type(atlas_Config) :: config + + real(c_double) :: xy(2,173) + xy(:,1) = [180,0] + xy(:,2) = [90,0] + xy(:,3) = [-90,0] + xy(:,4) = [0,90] + xy(:,5) = [0,-90] + xy(:,6) = [0,0] + xy(:,7) = [18,0] + xy(:,8) = [36,0] + xy(:,9) = [54,0] + xy(:,10) = [72,0] + xy(:,11) = [108,0] + xy(:,12) = [126,0] + xy(:,13) = [144,0] + xy(:,14) = [162,0] + xy(:,15) = [-162,0] + xy(:,16) = [-144,0] + xy(:,17) = [-126,0] + xy(:,18) = [-108,0] + xy(:,19) = [-72,0] + xy(:,20) = [-54,0] + xy(:,21) = [-36,0] + xy(:,22) = [-18,0] + xy(:,23) = [0,18] + xy(:,24) = [0,36] + xy(:,25) = [0,54] + xy(:,26) = [0,72] + xy(:,27) = [180,72] + xy(:,28) = [180,54] + xy(:,29) = [180,36] + xy(:,30) = [180,18] + xy(:,31) = [180,-18] + xy(:,32) = [180,-36] + xy(:,33) = [180,-54] + xy(:,34) = [180,-72] + xy(:,35) = [0,-72] + xy(:,36) = [0,-54] + xy(:,37) = [0,-36] + xy(:,38) = [0,-18] + xy(:,39) = [90,18] + xy(:,40) = [90,36] + xy(:,41) = [90,54] + xy(:,42) = [90,72] + xy(:,43) = [-90,72] + xy(:,44) = [-90,54] + xy(:,45) = [-90,36] + xy(:,46) = [-90,18] + xy(:,47) = [-90,-18] + xy(:,48) = [-90,-36] + xy(:,49) = [-90,-54] + xy(:,50) = [-90,-72] + xy(:,51) = [90,-72] + xy(:,52) = [90,-54] + xy(:,53) = [90,-36] + xy(:,54) = [90,-18] + xy(:,55) = [123.974,-58.6741] + xy(:,56) = [154.087,-16.9547] + xy(:,57) = [154.212,-58.8675] + xy(:,58) = [114.377,-41.9617] + xy(:,59) = [125.567,-23.5133] + xy(:,60) = [137.627,-40.8524] + xy(:,61) = [106.162,-24.5874] + xy(:,62) = [158.508,-38.55] + xy(:,63) = [137.826,-72.8109] + xy(:,64) = [142.103,-26.799] + xy(:,65) = [138.256,-13.8871] + xy(:,66) = [168.39,-24.3266] + xy(:,67) = [168.954,-12.0094] + xy(:,68) = [117.333,-12.35] + xy(:,69) = [102.254,-11.1537] + xy(:,70) = [120.307,59.7167] + xy(:,71) = [107.196,26.0167] + xy(:,72) = [144.768,28.3721] + xy(:,73) = [150.891,60.0343] + xy(:,74) = [164.566,25.5053] + xy(:,75) = [116.851,14.0295] + xy(:,76) = [124.84,28.3978] + xy(:,77) = [157.901,42.042] + xy(:,78) = [111.41,43.1056] + xy(:,79) = [134.333,44.6677] + xy(:,80) = [103.277,11.707] + xy(:,81) = [135.358,73.2119] + xy(:,82) = [135.349,14.2311] + xy(:,83) = [153.48,13.386] + xy(:,84) = [168.071,11.5344] + xy(:,85) = [-162.99,26.3775] + xy(:,86) = [-147.519,56.1313] + xy(:,87) = [-122.579,27.4824] + xy(:,88) = [-117.909,59.2376] + xy(:,89) = [-104.052,27.3616] + xy(:,90) = [-153.107,14.9717] + xy(:,91) = [-110.833,41.7436] + xy(:,92) = [-144.847,32.8534] + xy(:,93) = [-161.546,42.1031] + xy(:,94) = [-129.866,44.5201] + xy(:,95) = [-133.883,72.4163] + xy(:,96) = [-166.729,11.8907] + xy(:,97) = [-135.755,15.2529] + xy(:,98) = [-106.063,14.4869] + xy(:,99) = [-119.452,11.7037] + xy(:,100) = [-146.026,-58.6741] + xy(:,101) = [-115.913,-16.9547] + xy(:,102) = [-115.788,-58.8675] + xy(:,103) = [-155.623,-41.9617] + xy(:,104) = [-144.433,-23.5133] + xy(:,105) = [-132.373,-40.8524] + xy(:,106) = [-163.838,-24.5874] + xy(:,107) = [-111.492,-38.55] + xy(:,108) = [-132.174,-72.8109] + xy(:,109) = [-127.897,-26.799] + xy(:,110) = [-131.744,-13.8871] + xy(:,111) = [-101.61,-24.3266] + xy(:,112) = [-101.046,-12.0094] + xy(:,113) = [-152.667,-12.35] + xy(:,114) = [-167.746,-11.1537] + xy(:,115) = [-14.0127,-27.2963] + xy(:,116) = [-59.193,-57.0815] + xy(:,117) = [-56.465,-19.5751] + xy(:,118) = [-27.056,-59.3077] + xy(:,119) = [-57.124,-35.9752] + xy(:,120) = [-33.4636,-28.3914] + xy(:,121) = [-74.8037,-46.8602] + xy(:,122) = [-40.089,-45.1376] + xy(:,123) = [-74.8149,-28.3136] + xy(:,124) = [-21.3072,-42.2177] + xy(:,125) = [-44.0778,-72.6353] + xy(:,126) = [-19.6969,-12.8527] + xy(:,127) = [-40.1318,-12.1601] + xy(:,128) = [-72.691,-11.4129] + xy(:,129) = [-56.0261,58.6741] + xy(:,130) = [-25.9127,16.9547] + xy(:,131) = [-25.7876,58.8675] + xy(:,132) = [-65.6229,41.9617] + xy(:,133) = [-54.4335,23.5133] + xy(:,134) = [-42.373,40.8524] + xy(:,135) = [-73.838,24.5874] + xy(:,136) = [-21.4917,38.55] + xy(:,137) = [-42.1744,72.8109] + xy(:,138) = [-37.8974,26.799] + xy(:,139) = [-41.7437,13.8871] + xy(:,140) = [-11.6095,24.3266] + xy(:,141) = [-11.0459,12.0094] + xy(:,142) = [-62.667,12.35] + xy(:,143) = [-77.7456,11.1537] + xy(:,144) = [30.3071,59.7167] + xy(:,145) = [17.1956,26.0167] + xy(:,146) = [54.7676,28.3721] + xy(:,147) = [60.8915,60.0343] + xy(:,148) = [74.5657,25.5053] + xy(:,149) = [26.8506,14.0295] + xy(:,150) = [34.8398,28.3978] + xy(:,151) = [67.9014,42.042] + xy(:,152) = [21.41,43.1056] + xy(:,153) = [44.3335,44.6677] + xy(:,154) = [13.2772,11.707] + xy(:,155) = [45.3579,73.2119] + xy(:,156) = [45.3492,14.2311] + xy(:,157) = [63.4799,13.386] + xy(:,158) = [78.0714,11.5344] + xy(:,159) = [17.01,-26.3775] + xy(:,160) = [32.4806,-56.1313] + xy(:,161) = [57.4213,-27.4824] + xy(:,162) = [62.0912,-59.2376] + xy(:,163) = [75.9483,-27.3616] + xy(:,164) = [26.893,-14.9717] + xy(:,165) = [69.1672,-41.7436] + xy(:,166) = [35.1527,-32.8534] + xy(:,167) = [18.4543,-42.1031] + xy(:,168) = [50.1344,-44.5201] + xy(:,169) = [46.1172,-72.4163] + xy(:,170) = [13.2711,-11.8907] + xy(:,171) = [44.2448,-15.2529] + xy(:,172) = [73.9368,-14.4869] + xy(:,173) = [60.5478,-11.7037] + + grid = atlas_UnstructuredGrid(xy) + + FCTEST_CHECK_EQUAL( grid%owners(), 1 ) + + meshgenerator = atlas_MeshGenerator("delaunay") + mesh = meshgenerator%generate(grid) + FCTEST_CHECK_EQUAL( mesh%owners(), 1 ) + + FCTEST_CHECK_EQUAL( grid%owners(), 2 ) + + gmsh = atlas_output_Gmsh("atlas_fctest_unstructuredgrid.msh",coordinates="xyz") + call gmsh%write(mesh) + + + call mesh%final() + FCTEST_CHECK_EQUAL( grid%owners(), 1 ) + call gmsh%final() + call grid%final() + call meshgenerator%final() +END_TEST + +! ----------------------------------------------------------------------------- + +END_TESTSUITE + From dab98f41b32251d8f47132df5ba93cef54ccb6cb Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Tue, 11 Jun 2019 16:47:03 +0100 Subject: [PATCH 31/86] Apply transforms to unstructured grid in Fortran --- src/tests/trans/CMakeLists.txt | 12 ++- src/tests/trans/fctest_trans_unstructured.F90 | 86 +++++++++++++++++++ 2 files changed, 94 insertions(+), 4 deletions(-) create mode 100644 src/tests/trans/fctest_trans_unstructured.F90 diff --git a/src/tests/trans/CMakeLists.txt b/src/tests/trans/CMakeLists.txt index 3f38d00e2..d21a0d5cd 100644 --- a/src/tests/trans/CMakeLists.txt +++ b/src/tests/trans/CMakeLists.txt @@ -8,8 +8,6 @@ if( HAVE_FCTEST ) -ecbuild_warn_var( ECKIT_HAVE_MPI ) -ecbuild_warn_var( TRANSI_HAVE_MPI ) if( ATLAS_HAVE_TRANS ) add_fctest( TARGET atlas_fctest_trans LINKER_LANGUAGE Fortran @@ -21,14 +19,20 @@ ecbuild_warn_var( TRANSI_HAVE_MPI ) ) endif() -# if( ATLAS_HAVE_TRANS ) + if( ATLAS_HAVE_TRANS ) add_fctest( TARGET atlas_fctest_trans_invtrans_grad LINKER_LANGUAGE Fortran SOURCES fctest_trans_invtrans_grad.F90 LIBS atlas_f ENVIRONMENT ${ATLAS_TEST_ENVIRONMENT} ) -# endif() + endif() + + add_fctest( TARGET atlas_fctest_trans_unstructured + LINKER_LANGUAGE Fortran + SOURCES fctest_trans_unstructured.F90 + LIBS atlas_f + ) endif() diff --git a/src/tests/trans/fctest_trans_unstructured.F90 b/src/tests/trans/fctest_trans_unstructured.F90 new file mode 100644 index 000000000..e15566ee8 --- /dev/null +++ b/src/tests/trans/fctest_trans_unstructured.F90 @@ -0,0 +1,86 @@ +! (C) Copyright 2013 ECMWF. +! This software is licensed under the terms of the Apache Licence Version 2.0 +! which can be obtained at http://www.apache.org/licenses/LICENSE-2.0. +! In applying this licence, ECMWF does not waive the privileges and immunities +! granted to it by virtue of its status as an intergovernmental organisation nor +! does it submit to any jurisdiction. + +! @author Willem Deconinck + +#include "fckit/fctest.h" + +! ----------------------------------------------------------------------------- + + +TESTSUITE(fctest_atlas_trans_unstr) + +! ----------------------------------------------------------------------------- + +TESTSUITE_INIT + use atlas_module + type(atlas_Trans) :: trans + call atlas_library%initialise() + call trans%set_backend("local") +END_TESTSUITE_INIT + +! ----------------------------------------------------------------------------- + +TESTSUITE_FINALIZE + use atlas_module + call atlas_library%finalise() +END_TESTSUITE_FINALIZE + +! ----------------------------------------------------------------------------- + +TEST( test_trans ) + use atlas_module + implicit none + type(atlas_UnstructuredGrid) :: grid + type(atlas_Trans) :: trans + type(atlas_functionspace_Spectral) :: spectral + type(atlas_Field) :: gp_scal_field, gp_wind_field + type(atlas_Field) :: sp_scal_field, sp_vor_field, sp_div_field + type(atlas_Config) :: config + integer :: truncation + + real(c_double) :: xy(2,10) + + xy(:,1) = [107.196,26.0167] + xy(:,2) = [144.768,28.3721] + xy(:,3) = [150.891,60.0343] + xy(:,4) = [164.566,25.5053] + xy(:,5) = [116.851,14.0295] + xy(:,6) = [124.84,28.3978] + xy(:,7) = [157.901,42.042] + xy(:,8) = [111.41,43.1056] + xy(:,9) = [134.333,44.6677] + xy(:,10) = [120.307,59.7167] + + grid = atlas_UnstructuredGrid( xy ) + + truncation = 1279 + + trans = atlas_Trans(grid,truncation) + + FCTEST_CHECK_EQUAL( trans%truncation(), truncation ) + + spectral = trans%spectral() + + sp_scal_field = spectral%create_field(name="spectral_scalar",kind=atlas_real(8)) + sp_vor_field = spectral%create_field(name="spectral_vorticity",kind=atlas_real(8)) + sp_div_field = spectral%create_field(name="spectral_divergence",kind=atlas_real(8)) + + gp_scal_field = atlas_Field(name="gridpoint_scalar",kind=atlas_real(8),shape=[10]) + gp_wind_field = atlas_Field(name="gridpoint_wind",kind=atlas_real(8),shape=[10,2]) + + config = atlas_Config() + call config%set("warning",0) ! turn off warnings for unstructured grids + + call trans%invtrans( sp_scal_field, gp_scal_field, config ) + call trans%invtrans_vordiv2wind( sp_vor_field, sp_div_field, gp_wind_field, config ) + +END_TEST + + +END_TESTSUITE + From 0434979f40a65a203415153227801563e73cdb96 Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Tue, 11 Jun 2019 17:24:48 +0100 Subject: [PATCH 32/86] Fix bug in dimension for scalar invtrans (TransLocal) --- src/atlas/trans/local/TransLocal.cc | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/atlas/trans/local/TransLocal.cc b/src/atlas/trans/local/TransLocal.cc index 53fbf227e..81d158412 100644 --- a/src/atlas/trans/local/TransLocal.cc +++ b/src/atlas/trans/local/TransLocal.cc @@ -720,12 +720,13 @@ void TransLocal::invtrans( const Field& spfield, Field& gpfield, const eckit::Co // VERY PRELIMINARY IMPLEMENTATION WITHOUT ANY GUARANTEES int nb_scalar_fields = 1; const auto scalar_spectra = array::make_view( spfield ); - auto gp_fields = array::make_view( spfield ); + auto gp_fields = array::make_view( gpfield ); - if ( gp_fields.shape( 0 ) != grid().size() ) { + if ( gp_fields.shape( 0 ) < grid().size() ) { + // Hopefully the halo (if present) is appended ATLAS_DEBUG_VAR( gp_fields.shape( 0 ) ); ATLAS_DEBUG_VAR( grid().size() ); - ATLAS_ASSERT( gp_fields.shape( 0 ) == grid().size() ); + ATLAS_ASSERT( gp_fields.shape( 0 ) < grid().size() ); } invtrans( nb_scalar_fields, scalar_spectra.data(), gp_fields.data(), config ); From 5385a7026fab6456e5e9851154527a4f9866a798 Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Fri, 14 Jun 2019 11:19:09 +0100 Subject: [PATCH 33/86] ATLAS-234 Fix few oversights --- src/tests/grid/CMakeLists.txt | 4 ++-- src/tests/grid/fctest_unstructuredgrid.F90 | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/tests/grid/CMakeLists.txt b/src/tests/grid/CMakeLists.txt index c36d33bde..622f28652 100644 --- a/src/tests/grid/CMakeLists.txt +++ b/src/tests/grid/CMakeLists.txt @@ -9,12 +9,12 @@ if( HAVE_FCTEST ) foreach(test fctest_griddistribution - fctest_state - fctest_unstructuredgrid) + fctest_state ) add_fctest( TARGET atlas_${test} SOURCES ${test}.F90 LINKER_LANGUAGE Fortran LIBS atlas_f ENVIRONMENT ${ATLAS_TEST_ENVIRONMENT} ) endforeach() + add_fctest( TARGET atlas_fctest_unstructuredgrid SOURCES fctest_unstructuredgrid.F90 LINKER_LANGUAGE Fortran LIBS atlas_f CONDITION HAVE_TESSELATION ) endif() foreach(test diff --git a/src/tests/grid/fctest_unstructuredgrid.F90 b/src/tests/grid/fctest_unstructuredgrid.F90 index 3e3e31458..3de694311 100644 --- a/src/tests/grid/fctest_unstructuredgrid.F90 +++ b/src/tests/grid/fctest_unstructuredgrid.F90 @@ -13,7 +13,7 @@ ! ----------------------------------------------------------------------------- -TESTSUITE(fctest_GridDist) +TESTSUITE(fctest_unstructuredgrid) ! ----------------------------------------------------------------------------- From e6d12c5308b31adedb66b1a4299f252d7a30ae4c Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Mon, 1 Jul 2019 16:32:19 +0100 Subject: [PATCH 34/86] Fix atlas_test_trans --- src/atlas/trans/ifs/TransIFS.h | 2 +- src/tests/trans/test_trans.cc | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/atlas/trans/ifs/TransIFS.h b/src/atlas/trans/ifs/TransIFS.h index 721a00a20..1bdb50df4 100644 --- a/src/atlas/trans/ifs/TransIFS.h +++ b/src/atlas/trans/ifs/TransIFS.h @@ -229,7 +229,7 @@ class TransIFS : public trans::TransImpl { /// partitioning/parallelisation routines) TransIFS( const Grid& g, const eckit::Configuration& = util::NoConfig() ); - int handle() const; + virtual int handle() const override; int ndgl() const; int nsmax() const; int ngptot() const; diff --git a/src/tests/trans/test_trans.cc b/src/tests/trans/test_trans.cc index 43a96d247..0115885da 100644 --- a/src/tests/trans/test_trans.cc +++ b/src/tests/trans/test_trans.cc @@ -63,12 +63,12 @@ struct AtlasTransEnvironment : public AtlasTestEnvironment { //----------------------------------------------------------------------------- -void read_rspecg( trans::TransImpl& trans, std::vector& rspecg, std::vector& nfrom, int& nfld ) { +void read_rspecg( const trans::TransImpl& trans, std::vector& rspecg, std::vector& nfrom, int& nfld ) { Log::info() << "read_rspecg ...\n"; nfld = 2; if ( mpi::comm().rank() == 0 ) { - rspecg.resize( nfld * trans.spectralCoefficients() ); - for ( size_t i = 0; i < trans.spectralCoefficients(); ++i ) { + rspecg.resize( nfld * trans.nb_spectral_coefficients_global() ); + for ( size_t i = 0; i < trans.nb_spectral_coefficients_global(); ++i ) { rspecg[i * nfld + 0] = ( i == 0 ? 1. : 0. ); // scalar field 1 rspecg[i * nfld + 1] = ( i == 0 ? 2. : 0. ); // scalar field 2 } From 8e284ea8c986d510088eb5c59a088a4bb729f99f Mon Sep 17 00:00:00 2001 From: Pedro Maciel Date: Mon, 17 Jun 2019 21:56:33 +0100 Subject: [PATCH 35/86] MIR-4: move grid::boundingBox --- src/atlas/grid/detail/grid/Grid.h | 3 + src/atlas/grid/detail/grid/Structured.cc | 253 ++++++++++++++++++++- src/atlas/grid/detail/grid/Structured.h | 2 + src/atlas/grid/detail/grid/Unstructured.cc | 4 + src/atlas/grid/detail/grid/Unstructured.h | 5 +- 5 files changed, 262 insertions(+), 5 deletions(-) diff --git a/src/atlas/grid/detail/grid/Grid.h b/src/atlas/grid/detail/grid/Grid.h index 7facda769..e413ab894 100644 --- a/src/atlas/grid/detail/grid/Grid.h +++ b/src/atlas/grid/detail/grid/Grid.h @@ -99,6 +99,9 @@ class Grid : public util::Object { /// @return area represented by the grid const Domain& domain() const { return domain_; } + /// @return parallel/meridian limits containing the grid + virtual Domain boundingBox() = 0; + /// @return projection (mapping between geographic coordinates and grid /// coordinates) const Projection& projection() const { return projection_; } diff --git a/src/atlas/grid/detail/grid/Structured.cc b/src/atlas/grid/detail/grid/Structured.cc index 2192b75c8..8b986dd46 100644 --- a/src/atlas/grid/detail/grid/Structured.cc +++ b/src/atlas/grid/detail/grid/Structured.cc @@ -24,8 +24,11 @@ #include "atlas/grid/detail/grid/GridFactory.h" #include "atlas/grid/detail/spacing/CustomSpacing.h" #include "atlas/grid/detail/spacing/LinearSpacing.h" +#include "atlas/interpolation/element/Quad3D.h" +#include "atlas/interpolation/method/Ray.h" #include "atlas/runtime/Exception.h" #include "atlas/runtime/Log.h" +#include "atlas/util/Earth.h" #include "atlas/util/NormaliseLongitude.h" #include "atlas/util/Point.h" #include "atlas/util/UnitSphere.h" @@ -52,10 +55,7 @@ Structured::Structured( const std::string& name, XSpace xspace, YSpace yspace, P xspace_( xspace ), yspace_( yspace ) { // Copy members - if ( projection ) - projection_ = projection; - else - projection_ = Projection(); + projection_ = projection ? projection : Projection(); y_.assign( yspace_.begin(), yspace_.end() ); idx_t ny{static_cast( y_.size() )}; @@ -495,6 +495,251 @@ void Structured::hash( eckit::Hash& h ) const { domain().hash( h ); } +Grid::Domain Structured::boundingBox() { + using eckit::types::is_approximately_lesser_or_equal; + using eckit::types::is_strictly_greater; + + computeDomain(); + if ( !projection_ ) { + return domain_; + } + + + // 0. setup + ATLAS_ASSERT( xspace_.min() <= xspace_.max() ); + ATLAS_ASSERT( yspace_.min() <= yspace_.max() ); + + Point2 min; + Point2 max; + constexpr double h = 0.001; + constexpr size_t Niter = 100; + +#if 0 + auto derivate_forwards = [&]( PointXY P, const PointXY& H ) -> PointXY { + PointXY A( P ); + PointXY B( PointXY::add( P, H ) ); + projection_.xy2lonlat( A.data() ); + projection_.xy2lonlat( B.data() ); + + return PointXY::div( PointXY::sub( B, A ), PointXY::norm( H ) ); + }; + + + auto derivate_backwards = [&]( PointXY P, const PointXY& H ) -> PointXY { + PointXY A( PointXY::sub( P, H ) ); + PointXY B( P ); + projection_.xy2lonlat( A.data() ); + projection_.xy2lonlat( B.data() ); + + return PointXY::div( PointXY::sub( B, A ), PointXY::norm( H ) ); + }; +#endif + + auto derivate_central = [&]( PointXY P, const PointXY& H ) -> PointXY { + PointXY H2( PointXY::mul( H, 0.5 ) ); + PointXY A( PointXY::sub( P, H2 ) ); + PointXY B( PointXY::add( P, H2 ) ); + projection_.xy2lonlat( A.data() ); + projection_.xy2lonlat( B.data() ); + + return PointXY::div( PointXY::sub( B, A ), PointXY::norm( H ) ); + }; + + auto derivate = derivate_central; + + // 1. determine box from projected/rotated corners + const std::vector corners{{xspace_.min(), yspace_.max()}, + {xspace_.max(), yspace_.max()}, + {xspace_.max(), yspace_.min()}, + {xspace_.min(), yspace_.min()}}; + + bool first = true; + for ( auto& p : corners ) { + PointXY r( p ); + projection_.xy2lonlat( r.data() ); + + min = first ? r : Point2::componentsMin( min, r ); + max = first ? r : Point2::componentsMax( max, r ); + first = false; + } + + struct crosses_t { + crosses_t( const Projection& projection, const PointXY& p1, const PointXY& p2, const PointXY& p3, + const PointXY& p4 ) : + projection_( projection ), + quadrilateral_( xy_to_xyz( projection, p1 ), xy_to_xyz( projection, p2 ), xy_to_xyz( projection, p3 ), + xy_to_xyz( projection, p4 ) ) {} + + bool operator()( const PointXY& p ) { + interpolation::method::Ray r( xy_to_xyz( projection_, p ) ); + return quadrilateral_.intersects( r ); + } + + private: + const Projection& projection_; + interpolation::element::Quad3D quadrilateral_; + + static PointXYZ xy_to_xyz( const Projection& projection, const PointXY& p ) { + PointLonLat q( p ); + projection.xy2lonlat( q.data() ); + + PointXYZ r; + util::Earth::convertSphericalToCartesian( q, r ); + return r; + } + } crosses( projection_, corners[0], corners[1], corners[2], corners[3] ); + + + // 2. locate latitude extrema by checking if poles are included (in the + // projected/rotated frame) and if not, find extrema not at the corners by refining + // iteratively + + PointXY NP{0, 90}; + PointXY SP{0, -90}; + projection_.lonlat2xy( NP.data() ); // un-project (or unrotate, in case of rotation) + projection_.lonlat2xy( SP.data() ); + + bool includesNorthPole = crosses( NP ); + bool includesSouthPole = crosses( SP ); + + if ( !includesNorthPole || !includesSouthPole ) { + for ( size_t i = 0; i < corners.size(); ++i ) { + PointXY A = corners[i]; + PointXY B = corners[( i + 1 ) % corners.size()]; + + // finite difference vector derivative (H is the perturbation vector) + const PointXY H{Point2::mul( Point2::normalize( Point2::sub( B, A ) ), h )}; + double dAdy = derivate( A, H ).y(); + double dBdy = derivate( B, H ).y(); + + if ( !is_strictly_greater( dAdy * dBdy, 0. ) ) { + for ( size_t cnt = 0; cnt < Niter; ++cnt ) { + PointXY M = PointXY::middle( A, B ); + double dMdy = derivate( M, H ).y(); + if ( is_strictly_greater( dAdy * dMdy, 0. ) ) { + A = M; + dAdy = dMdy; + } + else if ( is_strictly_greater( dBdy * dMdy, 0. ) ) { + B = M; + dBdy = dMdy; + } + else { + break; + } + } + + PointXY middle( PointXY::middle( A, B ) ); + projection_.xy2lonlat( middle.data() ); + + min = Point2::componentsMin( min, middle ); + max = Point2::componentsMax( max, middle ); + } + } + + // extend by 'a small amount' (arbitrary) and limit + min = Point2::sub( min, Point2{0, h} ); + max = Point2::add( max, Point2{0, h} ); + min[1] = std::max( min[1], -90. ); + max[1] = std::min( max[1], 90. ); + + includesNorthPole = includesNorthPole || is_approximately_lesser_or_equal( 90., max[1] ); + includesSouthPole = includesSouthPole || is_approximately_lesser_or_equal( min[1], -90. ); + } + ATLAS_ASSERT( min[1] < max[1] ); + + + // 3. locate latitude extrema by checking if date line is crossed (in the + // projected/rotated frame), in which case we assume periodicity and if not, find + // extrema not at the corners by refining iteratively + + bool crossesDateLine = includesNorthPole || includesSouthPole; + +#if 0 + if (!crossesDateLine) { + PointXY A{Longitude::DATE_LINE.value(), -10.}; + PointXY B{Longitude::DATE_LINE.value(), 10.}; + projection_.lonlat2xy(A.data()); + projection_.lonlat2xy(B.data()); + + eckit::geometry::GreatCircle GC(A, B); + + for (auto x : {xspace_.min(), xspace_.max()}) { + if (!crossesDateLine) { + for (auto y : GC.latitude(x)) { + PointXY DL(x, y); + if ((crossesDateLine = crosses(DL))) { + PointLonLat p{x, y}; + projection_.xy2lonlat(p.data()); + break; + } + } + } + } + + for (auto y : {yspace_.max(), yspace_.min()}) { + if (!crossesDateLine) { + for (auto x : GC.longitude(y)) { + PointXY DL(x, y); + if ((crossesDateLine = crosses(DL))) { + break; + } + } + } + } + } +#endif + + if ( !crossesDateLine ) { + for ( size_t i = 0; i < corners.size(); ++i ) { + PointXY A = corners[i]; + PointXY B = corners[( i + 1 ) % corners.size()]; + + // finite difference vector derivative (H is the perturbation vector) + const PointXY H{Point2::mul( Point2::normalize( Point2::sub( B, A ) ), h )}; + double dAdx = derivate( A, H ).x(); + double dBdx = derivate( B, H ).x(); + + if ( !is_strictly_greater( dAdx * dBdx, 0. ) ) { + for ( size_t cnt = 0; cnt < Niter; ++cnt ) { + PointXY M = PointXY::middle( A, B ); + double dMdx = derivate( M, H ).x(); + if ( is_strictly_greater( dAdx * dMdx, 0. ) ) { + A = M; + dAdx = dMdx; + } + else if ( is_strictly_greater( dBdx * dMdx, 0. ) ) { + B = M; + dBdx = dMdx; + } + else { + break; + } + } + + PointXY middle( PointXY::middle( A, B ) ); + projection_.xy2lonlat( middle.data() ); + + min = Point2::componentsMin( min, middle ); + max = Point2::componentsMax( max, middle ); + } + } + + // extend by 'a small amount' (arbitrary) and limit + min = Point2::sub( min, Point2{h, 0} ); + max = Point2::add( max, Point2{h, 0} ); + max[0] = std::min( max[0], min[0] + 360. ); + + crossesDateLine = is_approximately_lesser_or_equal( 360., max[0] - min[0] ); + } + ATLAS_ASSERT( min[0] < max[0] ); + + + // 4. return bounding box + return crossesDateLine ? ZonalBandDomain( {min[1], max[1]} ) + : RectangularDomain( {min[0], max[0]}, {min[1], max[1]} ); +} + Grid::Spec Structured::spec() const { Grid::Spec grid_spec; diff --git a/src/atlas/grid/detail/grid/Structured.h b/src/atlas/grid/detail/grid/Structured.h index 95e126a8a..8cd61a713 100644 --- a/src/atlas/grid/detail/grid/Structured.h +++ b/src/atlas/grid/detail/grid/Structured.h @@ -380,6 +380,8 @@ class Structured : public Grid { virtual void hash( eckit::Hash& ) const override; + virtual Domain boundingBox() override; + void computeTruePeriodicity(); void computeDomain(); diff --git a/src/atlas/grid/detail/grid/Unstructured.cc b/src/atlas/grid/detail/grid/Unstructured.cc index 3d5f82373..46de8f3f2 100644 --- a/src/atlas/grid/detail/grid/Unstructured.cc +++ b/src/atlas/grid/detail/grid/Unstructured.cc @@ -170,6 +170,10 @@ void Unstructured::hash( eckit::Hash& h ) const { projection().hash( h ); } +Grid::Domain Unstructured::boundingBox() { + throw_NotImplemented( "Cannot create boundingBox from Unstructured grid", Here() ); +} + idx_t Unstructured::size() const { ATLAS_ASSERT( points_ != nullptr ); return static_cast( points_->size() ); diff --git a/src/atlas/grid/detail/grid/Unstructured.h b/src/atlas/grid/detail/grid/Unstructured.h index 2af80723c..afba744de 100644 --- a/src/atlas/grid/detail/grid/Unstructured.h +++ b/src/atlas/grid/detail/grid/Unstructured.h @@ -195,9 +195,12 @@ class Unstructured : public Grid { private: // methods virtual void print( std::ostream& ) const; - /// Hash of the lonlat array + BoundingBox + /// Hash of the lonlat array virtual void hash( eckit::Hash& ) const; + /// @return parallel/meridian limits containing the grid + virtual Domain boundingBox() override; + protected: /// Storage of coordinate points std::unique_ptr> points_; From aaf48c16b60a1716bc4ecc6094afddd651420f5c Mon Sep 17 00:00:00 2001 From: Pedro Maciel Date: Thu, 27 Jun 2019 20:26:24 +0100 Subject: [PATCH 36/86] MIR-4: Grid::boundingBox, Projection::boundingBox --- src/atlas/grid/detail/grid/Structured.cc | 247 +------------ src/atlas/projection/Projection.cc | 4 + src/atlas/projection/Projection.h | 2 + .../LambertAzimuthalEqualAreaProjection.h | 8 +- .../projection/detail/LambertProjection.h | 27 +- .../projection/detail/LonLatProjection.cc | 253 +++++++++++++- .../projection/detail/LonLatProjection.h | 26 +- .../projection/detail/MercatorProjection.h | 24 +- src/atlas/projection/detail/ProjectionImpl.cc | 208 +++++++++++ src/atlas/projection/detail/ProjectionImpl.h | 16 +- .../projection/detail/SchmidtProjection.h | 20 +- src/atlas/util/Rotation.cc | 50 ++- src/tests/projection/CMakeLists.txt | 5 +- src/tests/projection/test_bounding_box.cc | 324 ++++++++++++++++++ 14 files changed, 879 insertions(+), 335 deletions(-) create mode 100644 src/tests/projection/test_bounding_box.cc diff --git a/src/atlas/grid/detail/grid/Structured.cc b/src/atlas/grid/detail/grid/Structured.cc index 8b986dd46..a509d3584 100644 --- a/src/atlas/grid/detail/grid/Structured.cc +++ b/src/atlas/grid/detail/grid/Structured.cc @@ -24,11 +24,8 @@ #include "atlas/grid/detail/grid/GridFactory.h" #include "atlas/grid/detail/spacing/CustomSpacing.h" #include "atlas/grid/detail/spacing/LinearSpacing.h" -#include "atlas/interpolation/element/Quad3D.h" -#include "atlas/interpolation/method/Ray.h" #include "atlas/runtime/Exception.h" #include "atlas/runtime/Log.h" -#include "atlas/util/Earth.h" #include "atlas/util/NormaliseLongitude.h" #include "atlas/util/Point.h" #include "atlas/util/UnitSphere.h" @@ -496,248 +493,8 @@ void Structured::hash( eckit::Hash& h ) const { } Grid::Domain Structured::boundingBox() { - using eckit::types::is_approximately_lesser_or_equal; - using eckit::types::is_strictly_greater; - computeDomain(); - if ( !projection_ ) { - return domain_; - } - - - // 0. setup - ATLAS_ASSERT( xspace_.min() <= xspace_.max() ); - ATLAS_ASSERT( yspace_.min() <= yspace_.max() ); - - Point2 min; - Point2 max; - constexpr double h = 0.001; - constexpr size_t Niter = 100; - -#if 0 - auto derivate_forwards = [&]( PointXY P, const PointXY& H ) -> PointXY { - PointXY A( P ); - PointXY B( PointXY::add( P, H ) ); - projection_.xy2lonlat( A.data() ); - projection_.xy2lonlat( B.data() ); - - return PointXY::div( PointXY::sub( B, A ), PointXY::norm( H ) ); - }; - - - auto derivate_backwards = [&]( PointXY P, const PointXY& H ) -> PointXY { - PointXY A( PointXY::sub( P, H ) ); - PointXY B( P ); - projection_.xy2lonlat( A.data() ); - projection_.xy2lonlat( B.data() ); - - return PointXY::div( PointXY::sub( B, A ), PointXY::norm( H ) ); - }; -#endif - - auto derivate_central = [&]( PointXY P, const PointXY& H ) -> PointXY { - PointXY H2( PointXY::mul( H, 0.5 ) ); - PointXY A( PointXY::sub( P, H2 ) ); - PointXY B( PointXY::add( P, H2 ) ); - projection_.xy2lonlat( A.data() ); - projection_.xy2lonlat( B.data() ); - - return PointXY::div( PointXY::sub( B, A ), PointXY::norm( H ) ); - }; - - auto derivate = derivate_central; - - // 1. determine box from projected/rotated corners - const std::vector corners{{xspace_.min(), yspace_.max()}, - {xspace_.max(), yspace_.max()}, - {xspace_.max(), yspace_.min()}, - {xspace_.min(), yspace_.min()}}; - - bool first = true; - for ( auto& p : corners ) { - PointXY r( p ); - projection_.xy2lonlat( r.data() ); - - min = first ? r : Point2::componentsMin( min, r ); - max = first ? r : Point2::componentsMax( max, r ); - first = false; - } - - struct crosses_t { - crosses_t( const Projection& projection, const PointXY& p1, const PointXY& p2, const PointXY& p3, - const PointXY& p4 ) : - projection_( projection ), - quadrilateral_( xy_to_xyz( projection, p1 ), xy_to_xyz( projection, p2 ), xy_to_xyz( projection, p3 ), - xy_to_xyz( projection, p4 ) ) {} - - bool operator()( const PointXY& p ) { - interpolation::method::Ray r( xy_to_xyz( projection_, p ) ); - return quadrilateral_.intersects( r ); - } - - private: - const Projection& projection_; - interpolation::element::Quad3D quadrilateral_; - - static PointXYZ xy_to_xyz( const Projection& projection, const PointXY& p ) { - PointLonLat q( p ); - projection.xy2lonlat( q.data() ); - - PointXYZ r; - util::Earth::convertSphericalToCartesian( q, r ); - return r; - } - } crosses( projection_, corners[0], corners[1], corners[2], corners[3] ); - - - // 2. locate latitude extrema by checking if poles are included (in the - // projected/rotated frame) and if not, find extrema not at the corners by refining - // iteratively - - PointXY NP{0, 90}; - PointXY SP{0, -90}; - projection_.lonlat2xy( NP.data() ); // un-project (or unrotate, in case of rotation) - projection_.lonlat2xy( SP.data() ); - - bool includesNorthPole = crosses( NP ); - bool includesSouthPole = crosses( SP ); - - if ( !includesNorthPole || !includesSouthPole ) { - for ( size_t i = 0; i < corners.size(); ++i ) { - PointXY A = corners[i]; - PointXY B = corners[( i + 1 ) % corners.size()]; - - // finite difference vector derivative (H is the perturbation vector) - const PointXY H{Point2::mul( Point2::normalize( Point2::sub( B, A ) ), h )}; - double dAdy = derivate( A, H ).y(); - double dBdy = derivate( B, H ).y(); - - if ( !is_strictly_greater( dAdy * dBdy, 0. ) ) { - for ( size_t cnt = 0; cnt < Niter; ++cnt ) { - PointXY M = PointXY::middle( A, B ); - double dMdy = derivate( M, H ).y(); - if ( is_strictly_greater( dAdy * dMdy, 0. ) ) { - A = M; - dAdy = dMdy; - } - else if ( is_strictly_greater( dBdy * dMdy, 0. ) ) { - B = M; - dBdy = dMdy; - } - else { - break; - } - } - - PointXY middle( PointXY::middle( A, B ) ); - projection_.xy2lonlat( middle.data() ); - - min = Point2::componentsMin( min, middle ); - max = Point2::componentsMax( max, middle ); - } - } - - // extend by 'a small amount' (arbitrary) and limit - min = Point2::sub( min, Point2{0, h} ); - max = Point2::add( max, Point2{0, h} ); - min[1] = std::max( min[1], -90. ); - max[1] = std::min( max[1], 90. ); - - includesNorthPole = includesNorthPole || is_approximately_lesser_or_equal( 90., max[1] ); - includesSouthPole = includesSouthPole || is_approximately_lesser_or_equal( min[1], -90. ); - } - ATLAS_ASSERT( min[1] < max[1] ); - - - // 3. locate latitude extrema by checking if date line is crossed (in the - // projected/rotated frame), in which case we assume periodicity and if not, find - // extrema not at the corners by refining iteratively - - bool crossesDateLine = includesNorthPole || includesSouthPole; - -#if 0 - if (!crossesDateLine) { - PointXY A{Longitude::DATE_LINE.value(), -10.}; - PointXY B{Longitude::DATE_LINE.value(), 10.}; - projection_.lonlat2xy(A.data()); - projection_.lonlat2xy(B.data()); - - eckit::geometry::GreatCircle GC(A, B); - - for (auto x : {xspace_.min(), xspace_.max()}) { - if (!crossesDateLine) { - for (auto y : GC.latitude(x)) { - PointXY DL(x, y); - if ((crossesDateLine = crosses(DL))) { - PointLonLat p{x, y}; - projection_.xy2lonlat(p.data()); - break; - } - } - } - } - - for (auto y : {yspace_.max(), yspace_.min()}) { - if (!crossesDateLine) { - for (auto x : GC.longitude(y)) { - PointXY DL(x, y); - if ((crossesDateLine = crosses(DL))) { - break; - } - } - } - } - } -#endif - - if ( !crossesDateLine ) { - for ( size_t i = 0; i < corners.size(); ++i ) { - PointXY A = corners[i]; - PointXY B = corners[( i + 1 ) % corners.size()]; - - // finite difference vector derivative (H is the perturbation vector) - const PointXY H{Point2::mul( Point2::normalize( Point2::sub( B, A ) ), h )}; - double dAdx = derivate( A, H ).x(); - double dBdx = derivate( B, H ).x(); - - if ( !is_strictly_greater( dAdx * dBdx, 0. ) ) { - for ( size_t cnt = 0; cnt < Niter; ++cnt ) { - PointXY M = PointXY::middle( A, B ); - double dMdx = derivate( M, H ).x(); - if ( is_strictly_greater( dAdx * dMdx, 0. ) ) { - A = M; - dAdx = dMdx; - } - else if ( is_strictly_greater( dBdx * dMdx, 0. ) ) { - B = M; - dBdx = dMdx; - } - else { - break; - } - } - - PointXY middle( PointXY::middle( A, B ) ); - projection_.xy2lonlat( middle.data() ); - - min = Point2::componentsMin( min, middle ); - max = Point2::componentsMax( max, middle ); - } - } - - // extend by 'a small amount' (arbitrary) and limit - min = Point2::sub( min, Point2{h, 0} ); - max = Point2::add( max, Point2{h, 0} ); - max[0] = std::min( max[0], min[0] + 360. ); - - crossesDateLine = is_approximately_lesser_or_equal( 360., max[0] - min[0] ); - } - ATLAS_ASSERT( min[0] < max[0] ); - - - // 4. return bounding box - return crossesDateLine ? ZonalBandDomain( {min[1], max[1]} ) - : RectangularDomain( {min[0], max[0]}, {min[1], max[1]} ); + return projection_ ? projection_.boundingBox( domain_ ) : domain_; } Grid::Spec Structured::spec() const { @@ -756,7 +513,7 @@ Grid::Spec Structured::spec() const { return grid_spec; } - // -------------------------------------------------------------------- +// -------------------------------------------------------------------- #if 1 namespace { // anonymous diff --git a/src/atlas/projection/Projection.cc b/src/atlas/projection/Projection.cc index 65acd4199..83d2bc2bd 100644 --- a/src/atlas/projection/Projection.cc +++ b/src/atlas/projection/Projection.cc @@ -50,6 +50,10 @@ bool atlas::Projection::strictlyRegional() const { return get()->strictlyRegional(); } +Domain Projection::boundingBox( const Domain& domain) const { + return get()->boundingBox( domain ); +} + Projection::Spec atlas::Projection::spec() const { return get()->spec(); } diff --git a/src/atlas/projection/Projection.h b/src/atlas/projection/Projection.h index a7af6650e..1dffc3ea4 100644 --- a/src/atlas/projection/Projection.h +++ b/src/atlas/projection/Projection.h @@ -13,6 +13,7 @@ #include #include "atlas/util/ObjectHandle.h" +#include "atlas/domain/Domain.h" //--------------------------------------------------------------------------------------------------------------------- @@ -57,6 +58,7 @@ class Projection : public util::ObjectHandle PointXY xy( const PointLonLat& ) const; bool strictlyRegional() const; + Domain boundingBox( const Domain& ) const; Spec spec() const; diff --git a/src/atlas/projection/detail/LambertAzimuthalEqualAreaProjection.h b/src/atlas/projection/detail/LambertAzimuthalEqualAreaProjection.h index 4de3c120d..9ead0b432 100644 --- a/src/atlas/projection/detail/LambertAzimuthalEqualAreaProjection.h +++ b/src/atlas/projection/detail/LambertAzimuthalEqualAreaProjection.h @@ -8,17 +8,15 @@ * nor does it submit to any jurisdiction. */ - #pragma once +#include "atlas/domain.h" #include "atlas/projection/detail/ProjectionImpl.h" - namespace atlas { namespace projection { namespace detail { - class LambertAzimuthalEqualAreaProjection final : public ProjectionImpl { public: // constructor @@ -26,8 +24,6 @@ class LambertAzimuthalEqualAreaProjection final : public ProjectionImpl { // projection name static std::string static_type() { return "lambert_azimuthal_equal_area"; } - - // projection name std::string type() const override { return static_type(); } // projection and inverse projection @@ -35,6 +31,7 @@ class LambertAzimuthalEqualAreaProjection final : public ProjectionImpl { void lonlat2xy( double crd[] ) const override; bool strictlyRegional() const override { return true; } + Domain boundingBox( const Domain& domain ) const override { return ProjectionImpl::boundingBox( domain ); } // specification Spec spec() const override; @@ -53,7 +50,6 @@ class LambertAzimuthalEqualAreaProjection final : public ProjectionImpl { double cos_phi1_; }; - } // namespace detail } // namespace projection } // namespace atlas diff --git a/src/atlas/projection/detail/LambertProjection.h b/src/atlas/projection/detail/LambertProjection.h index 6fb507969..b697c132e 100644 --- a/src/atlas/projection/detail/LambertProjection.h +++ b/src/atlas/projection/detail/LambertProjection.h @@ -10,38 +10,35 @@ #pragma once +#include "atlas/domain.h" #include "atlas/projection/detail/ProjectionImpl.h" namespace atlas { namespace projection { namespace detail { -class LambertProjection : public ProjectionImpl { +class LambertProjection final : public ProjectionImpl { public: // constructor - LambertProjection( const eckit::Parametrisation& p ); + LambertProjection( const eckit::Parametrisation& ); - // destructor - ~LambertProjection() override {} - - // class name + // projection name static std::string static_type() { return "lambert"; } - virtual std::string type() const override { return static_type(); } + std::string type() const override { return static_type(); } // projection and inverse projection - virtual void xy2lonlat( double crd[] ) const override; - virtual void lonlat2xy( double crd[] ) const override; + void xy2lonlat( double crd[] ) const override; + void lonlat2xy( double crd[] ) const override; - virtual bool strictlyRegional() const override { - return true; - } // lambert projection cannot be used for global grids + bool strictlyRegional() const override { return true; } + Domain boundingBox( const Domain& domain ) const override { return ProjectionImpl::boundingBox( domain ); } // specification - virtual Spec spec() const override; + Spec spec() const override; - virtual std::string units() const override { return "meters"; } + std::string units() const override { return "meters"; } - virtual void hash( eckit::Hash& ) const override; + void hash( eckit::Hash& ) const override; private: double lat1_, lat2_; // First and second latitude at which the secant cone diff --git a/src/atlas/projection/detail/LonLatProjection.cc b/src/atlas/projection/detail/LonLatProjection.cc index 75a0abb15..3e80b6c26 100644 --- a/src/atlas/projection/detail/LonLatProjection.cc +++ b/src/atlas/projection/detail/LonLatProjection.cc @@ -8,21 +8,270 @@ * nor does it submit to any jurisdiction. */ +#include + +#include "eckit/geometry/GreatCircle.h" +#include "eckit/types/FloatCompare.h" #include "eckit/utils/Hash.h" +#include "atlas/domain.h" #include "atlas/projection/detail/LonLatProjection.h" #include "atlas/projection/detail/ProjectionFactory.h" +#include "atlas/runtime/Exception.h" +#include "atlas/runtime/Log.h" #include "atlas/util/Config.h" namespace atlas { namespace projection { namespace detail { +namespace { + +struct Derivate { + Derivate( const util::Rotation& rotation, PointLonLat H ) : rotation_( rotation ), H_( H ) {} + virtual PointLonLat d( PointLonLat ) const = 0; + const util::Rotation& rotation_; + const PointLonLat H_; + void xy2lonlat( double crd[] ) const { rotation_.rotate( crd ); } +}; + +struct DerivateForwards final : Derivate { + using Derivate::Derivate; + PointLonLat d( PointLonLat P ) const override { + PointXY A( P ); + PointXY B( PointXY::add( P, Derivate::H_ ) ); + Derivate::xy2lonlat( A.data() ); + Derivate::xy2lonlat( B.data() ); + return PointXY::div( PointXY::sub( B, A ), PointXY::norm( Derivate::H_ ) ); + } +}; + +struct DerivateBackwards final : Derivate { + using Derivate::Derivate; + PointLonLat d( PointLonLat P ) const override { + PointXY A( PointXY::sub( P, Derivate::H_ ) ); + PointXY B( P ); + Derivate::xy2lonlat( A.data() ); + Derivate::xy2lonlat( B.data() ); + return PointXY::div( PointXY::sub( B, A ), PointXY::norm( Derivate::H_ ) ); + } +}; + +struct DerivateCentral final : Derivate { + using Derivate::Derivate; + PointLonLat d( PointLonLat P ) const override { + PointXY H2( PointXY::mul( Derivate::H_, 0.5 ) ); + PointXY A( PointXY::sub( P, H2 ) ); + PointXY B( PointXY::add( P, H2 ) ); + Derivate::xy2lonlat( A.data() ); + Derivate::xy2lonlat( B.data() ); + return PointXY::div( PointXY::sub( B, A ), PointXY::norm( Derivate::H_ ) ); + } +}; + +} // (anonymous namespace) + template LonLatProjectionT::LonLatProjectionT( const eckit::Parametrisation& config ) : ProjectionImpl(), rotation_( config ) {} +template <> +PointLonLat LonLatProjectionT::rotate( const PointXY& p ) const { + return {p}; +} + +template <> +PointXY LonLatProjectionT::unrotate( const PointLonLat& q ) const { + return {q}; +} + +template +PointLonLat LonLatProjectionT::rotate( const PointXY& p ) const { + PointLonLat q( p ); + this->xy2lonlat( q.data() ); + return q; +} + +template +PointXY LonLatProjectionT::unrotate( const PointLonLat& q ) const { + PointLonLat p( q ); + this->lonlat2xy( p.data() ); + return p; +} + +template <> +Domain LonLatProjectionT::boundingBox( const Domain& domain ) const { + return domain; +} + +template +Domain LonLatProjectionT::boundingBox( const Domain& domain ) const { + using eckit::types::is_approximately_lesser_or_equal; + using eckit::types::is_strictly_greater; + + RectangularDomain rect( domain ); + ATLAS_ASSERT( rect ); + + // 0. setup + Point2 min, max; + + constexpr double h = 0.001; + + // 1. determine box from rotated corners + + const std::vector corners{ + {rect.xmin(), rect.ymax()}, {rect.xmax(), rect.ymax()}, {rect.xmax(), rect.ymin()}, {rect.xmin(), rect.ymin()}}; + + bool first = true; + for ( auto& p : corners ) { + PointLonLat r( rotate( p ) ); + min = first ? r : Point2::componentsMin( min, r ); + max = first ? r : Point2::componentsMax( max, r ); + first = false; + } + + + // 2. locate latitude extrema by checking if poles are included (in the + // unrotated frame) and if not, find extrema not at the corners by refining + // iteratively + + PointLonLat NP{unrotate( {0., 90.} )}; + PointLonLat SP{unrotate( {0., -90.} )}; + + bool includesNorthPole = domain.contains( NP.lon(), NP.lat() ); + bool includesSouthPole = domain.contains( SP.lon(), SP.lat() ); + + if ( !includesNorthPole || !includesSouthPole ) { + for ( size_t i = 0; i < corners.size(); ++i ) { + PointLonLat A = corners[i]; + PointLonLat B = corners[( i + 1 ) % corners.size()]; + + // finite difference vector derivative (H is the perturbation vector) + const PointLonLat H{Point2::mul( Point2::normalize( Point2::sub( B, A ) ), h )}; + std::unique_ptr derivate( new DerivateCentral( this->rotation_, H) ); + + double derivativeAtA = derivate->d( A ).lat(); + double derivativeAtB = derivate->d( B ).lat(); + + if ( !is_strictly_greater( derivativeAtA * derivativeAtB, 0. ) ) { + for ( size_t cnt = 0; cnt < 100; ++cnt ) { + PointLonLat M = PointLonLat::middle( A, B ); + double derivativeAtM = derivate->d( M ).lat(); + if ( is_strictly_greater( derivativeAtA * derivativeAtM, 0. ) ) { + A = M; + derivativeAtA = derivativeAtM; + } + else if ( is_strictly_greater( derivativeAtB * derivativeAtM, 0. ) ) { + B = M; + derivativeAtB = derivativeAtM; + } + else { + break; + } + } + + PointLonLat r( rotate( PointLonLat::middle( A, B ) ) ); + min = Point2::componentsMin( min, r ); + max = Point2::componentsMax( max, r ); + } + } + + // extend by 'a small amount' (arbitrary) + min = Point2::sub( min, Point2{0, h} ); + max = Point2::add( max, Point2{0, h} ); + + includesNorthPole = includesNorthPole || is_approximately_lesser_or_equal( 90., max[1] ); + includesSouthPole = includesSouthPole || is_approximately_lesser_or_equal( min[1], -90. ); + } + ATLAS_ASSERT( min[1] < max[1] ); + + + // 3. locate latitude extrema by checking if date line is crossed (in the + // unrotated frame), in which case we assume periodicity and if not, find + // extrema not at the corners by refining iteratively + + bool crossesDateLine = includesNorthPole || includesSouthPole; + + if ( !crossesDateLine ) { + PointLonLat A{unrotate( {180., -10} )}; + PointLonLat B{unrotate( {180., 10} )}; + eckit::geometry::GreatCircle DL( A, B ); + + for ( auto lon : {rect.xmin(), rect.xmax()} ) { + if ( !crossesDateLine ) { + for ( auto lat : DL.latitude( lon ) ) { + if ( ( crossesDateLine = domain.contains( lon, lat ) ) ) { + break; + } + } + } + } + + for ( auto lat : {rect.ymin(), rect.ymax()} ) { + if ( !crossesDateLine ) { + for ( auto lon : DL.longitude( lat ) ) { + if ( ( crossesDateLine = domain.contains( lon, lat ) ) ) { + break; + } + } + } + } + } + + if ( !crossesDateLine ) { + for ( size_t i = 0; i < corners.size(); ++i ) { + PointLonLat A = corners[i]; + PointLonLat B = corners[( i + 1 ) % corners.size()]; + + // finite difference vector derivative (H is the perturbation vector) + const PointLonLat H{Point2::mul( Point2::normalize( Point2::sub( B, A ) ), h )}; + std::unique_ptr derivate( new DerivateCentral( this->rotation_, H) ); + + double derivativeAtA = derivate->d( A ).lon(); + double derivativeAtB = derivate->d( B ).lon(); + + if ( !is_strictly_greater( derivativeAtA * derivativeAtB, 0. ) ) { + for ( size_t cnt = 0; cnt < 100; ++cnt ) { + PointLonLat M = PointLonLat::middle( A, B ); + double derivativeAtM = derivate->d( M ).lon(); + if ( is_strictly_greater( derivativeAtA * derivativeAtM, 0. ) ) { + A = M; + derivativeAtA = derivativeAtM; + } + else if ( is_strictly_greater( derivativeAtB * derivativeAtM, 0. ) ) { + B = M; + derivativeAtB = derivativeAtM; + } + else { + break; + } + } + + PointLonLat r( rotate( PointLonLat::middle( A, B ) ) ); + min = Point2::componentsMin( min, r ); + max = Point2::componentsMax( max, r ); + } + } + + // extend by 'a small amount' (arbitrary) + min = Point2::sub( min, Point2{h, 0} ); + max = Point2::add( max, Point2{h, 0} ); + + crossesDateLine = is_approximately_lesser_or_equal( 360., max[0] - min[0] ); + } + ATLAS_ASSERT( min[0] < max[0] ); + + + // 4. set bounding box + double n = includesNorthPole ? 90. : max[1]; + double s = includesSouthPole ? -90. : min[1]; + double w = crossesDateLine ? 0 : min[0]; + double e = crossesDateLine ? 360. : max[0]; + + return RectangularDomain({w, e}, {s, n}); +} + template typename LonLatProjectionT::Spec LonLatProjectionT::spec() const { Spec proj_spec; @@ -43,7 +292,9 @@ template class LonLatProjectionT; namespace { static ProjectionBuilder register_1( LonLatProjection::static_type() ); static ProjectionBuilder register_2( RotatedLonLatProjection::static_type() ); -} // namespace +} + +// namespace } // namespace detail } // namespace projection diff --git a/src/atlas/projection/detail/LonLatProjection.h b/src/atlas/projection/detail/LonLatProjection.h index 9e01459af..93af45f38 100644 --- a/src/atlas/projection/detail/LonLatProjection.h +++ b/src/atlas/projection/detail/LonLatProjection.h @@ -21,7 +21,7 @@ namespace projection { namespace detail { template -class LonLatProjectionT : public ProjectionImpl { +class LonLatProjectionT final : public ProjectionImpl { private: friend class atlas::Projection; LonLatProjectionT() = default; @@ -31,29 +31,33 @@ class LonLatProjectionT : public ProjectionImpl { LonLatProjectionT( const eckit::Parametrisation& ); // destructor - ~LonLatProjectionT() {} + ~LonLatProjectionT() = default; - // class name + // projection name static std::string static_type() { return Rotation::typePrefix() + "lonlat"; } - virtual std::string type() const override { return static_type(); } + std::string type() const override { return static_type(); } // projection and inverse projection - virtual void xy2lonlat( double crd[] ) const override { rotation_.rotate( crd ); } - virtual void lonlat2xy( double crd[] ) const override { rotation_.unrotate( crd ); } + void xy2lonlat( double crd[] ) const override { rotation_.rotate( crd ); } + void lonlat2xy( double crd[] ) const override { rotation_.unrotate( crd ); } - virtual bool strictlyRegional() const override { return false; } + bool strictlyRegional() const override { return false; } + Domain boundingBox( const Domain& ) const override; // specification - virtual Spec spec() const override; + Spec spec() const override; - virtual std::string units() const override { return "degrees"; } + std::string units() const override { return "degrees"; } - virtual operator bool() const override { return rotation_.rotated(); } + operator bool() const override { return rotation_.rotated(); } - virtual void hash( eckit::Hash& ) const override; + void hash( eckit::Hash& ) const override; private: Rotation rotation_; + + PointLonLat rotate( const PointXY& ) const; + PointXY unrotate( const PointLonLat& ) const; }; using LonLatProjection = LonLatProjectionT; diff --git a/src/atlas/projection/detail/MercatorProjection.h b/src/atlas/projection/detail/MercatorProjection.h index cb1f0291a..aaa3515af 100644 --- a/src/atlas/projection/detail/MercatorProjection.h +++ b/src/atlas/projection/detail/MercatorProjection.h @@ -10,6 +10,7 @@ #pragma once +#include "atlas/domain.h" #include "atlas/projection/detail/ProjectionImpl.h" namespace atlas { @@ -17,29 +18,28 @@ namespace projection { namespace detail { template -class MercatorProjectionT : public ProjectionImpl { +class MercatorProjectionT final : public ProjectionImpl { public: // constructor - MercatorProjectionT( const eckit::Parametrisation& p ); + MercatorProjectionT( const eckit::Parametrisation& ); - // class name + // projection name static std::string static_type() { return Rotation::typePrefix() + "mercator"; } - virtual std::string type() const override { return static_type(); } + std::string type() const override { return static_type(); } // projection and inverse projection - virtual void xy2lonlat( double crd[] ) const override; - virtual void lonlat2xy( double crd[] ) const override; + void xy2lonlat( double crd[] ) const override; + void lonlat2xy( double crd[] ) const override; - virtual bool strictlyRegional() const override { - return true; - } // Mercator projection cannot be used for global grids + bool strictlyRegional() const override { return true; } // Mercator projection cannot be used for global grids + Domain boundingBox( const Domain& domain ) const override { return ProjectionImpl::boundingBox( domain ); } // specification - virtual Spec spec() const override; + Spec spec() const override; - virtual std::string units() const override { return "meters"; } + std::string units() const override { return "meters"; } - virtual void hash( eckit::Hash& ) const override; + void hash( eckit::Hash& ) const override; protected: double lon0_; // central longitude diff --git a/src/atlas/projection/detail/ProjectionImpl.cc b/src/atlas/projection/detail/ProjectionImpl.cc index a31f0d78f..09acb9b5e 100644 --- a/src/atlas/projection/detail/ProjectionImpl.cc +++ b/src/atlas/projection/detail/ProjectionImpl.cc @@ -8,13 +8,17 @@ * nor does it submit to any jurisdiction. */ +#include "eckit/types/FloatCompare.h" #include "eckit/utils/Hash.h" +#include "atlas/interpolation/element/Quad3D.h" +#include "atlas/interpolation/method/Ray.h" #include "atlas/projection/detail/LonLatProjection.h" #include "atlas/projection/detail/ProjectionFactory.h" #include "atlas/projection/detail/ProjectionImpl.h" #include "atlas/runtime/Exception.h" #include "atlas/util/Config.h" +#include "atlas/util/Earth.h" namespace atlas { @@ -29,6 +33,210 @@ const ProjectionImpl* ProjectionImpl::create( const eckit::Parametrisation& p ) throw_Exception( "type missing in Params", Here() ); } +Domain ProjectionImpl::boundingBox( const Domain& domain ) const { + using eckit::types::is_approximately_lesser_or_equal; + using eckit::types::is_strictly_greater; + + // 0. setup + RectangularDomain rect( domain ); + + PointLonLat min; + PointLonLat max; + constexpr double h = 0.001; + constexpr size_t Niter = 100; + +#if 0 + auto derivate_forwards = [&]( PointXY P, const PointXY& H ) -> PointXY { + PointXY A( P ); + PointXY B( PointXY::add( P, H ) ); + xy2lonlat( A.data() ); + xy2lonlat( B.data() ); + + return PointXY::div( PointXY::sub( B, A ), PointXY::norm( H ) ); + }; + + + auto derivate_backwards = [&]( PointXY P, const PointXY& H ) -> PointXY { + PointXY A( PointXY::sub( P, H ) ); + PointXY B( P ); + xy2lonlat( A.data() ); + xy2lonlat( B.data() ); + + return PointXY::div( PointXY::sub( B, A ), PointXY::norm( H ) ); + }; +#endif + + auto derivate_central = [&]( PointXY P, const PointXY& H ) -> PointXY { + PointXY H2( PointXY::mul( H, 0.5 ) ); + PointXY A( PointXY::sub( P, H2 ) ); + PointXY B( PointXY::add( P, H2 ) ); + xy2lonlat( A.data() ); + xy2lonlat( B.data() ); + + return PointXY::div( PointXY::sub( B, A ), PointXY::norm( H ) ); + }; + + auto derivate = derivate_central; + + // 1. determine box from projected/rotated corners + const std::vector corners{{rect.xmin(), rect.ymax()}, + {rect.xmax(), rect.ymax()}, + {rect.xmax(), rect.ymin()}, + {rect.xmin(), rect.ymin()}}; + + bool first = true; + for ( auto& p : corners ) { + PointXY r( p ); + xy2lonlat( r.data() ); + + min = first ? r : PointLonLat::componentsMin( min, r ); + max = first ? r : PointLonLat::componentsMax( max, r ); + first = false; + } + + struct crosses_t { + crosses_t( const ProjectionImpl& projection, const PointXY& p1, const PointXY& p2, const PointXY& p3, + const PointXY& p4 ) : + projection_(projection), + quadrilateral_( xy_to_xyz( projection, p1 ), xy_to_xyz( projection, p2 ), xy_to_xyz( projection, p3 ), + xy_to_xyz( projection, p4 ) ) {} + + bool operator()( const PointXY& p ) { + interpolation::method::Ray r( xy_to_xyz( projection_, p ) ); + return quadrilateral_.intersects( r ); + } + + private: + const ProjectionImpl& projection_; + interpolation::element::Quad3D quadrilateral_; + + static PointXYZ xy_to_xyz( const ProjectionImpl& projection, const PointXY& p ) { + PointLonLat q( p ); + projection.xy2lonlat( q.data() ); + + PointXYZ r; + util::Earth::convertSphericalToCartesian( q, r ); + return r; + } + } crosses( *this, corners[0], corners[1], corners[2], corners[3] ); + + + // 2. locate latitude extrema by checking if poles are included (in the + // projected/rotated frame) and if not, find extrema not at the corners by refining + // iteratively + + PointXY NP{0, 90}; + PointXY SP{0, -90}; + lonlat2xy( NP.data() ); // un-project (or unrotate, in case of rotation) + lonlat2xy( SP.data() ); + + bool includesNorthPole = crosses( NP ); + bool includesSouthPole = crosses( SP ); + + if ( !includesNorthPole || !includesSouthPole ) { + for ( size_t i = 0; i < corners.size(); ++i ) { + PointXY A = corners[i]; + PointXY B = corners[( i + 1 ) % corners.size()]; + + // finite difference vector derivative (H is the perturbation vector) + const PointXY H{PointLonLat::mul( PointLonLat::normalize( PointLonLat::sub( B, A ) ), h )}; + double dAdy = derivate( A, H ).y(); + double dBdy = derivate( B, H ).y(); + + if ( !is_strictly_greater( dAdy * dBdy, 0. ) ) { + for ( size_t cnt = 0; cnt < Niter; ++cnt ) { + PointXY M = PointXY::middle( A, B ); + double dMdy = derivate( M, H ).y(); + if ( is_strictly_greater( dAdy * dMdy, 0. ) ) { + A = M; + dAdy = dMdy; + } + else if ( is_strictly_greater( dBdy * dMdy, 0. ) ) { + B = M; + dBdy = dMdy; + } + else { + break; + } + } + + PointXY middle( PointXY::middle( A, B ) ); + xy2lonlat( middle.data() ); + + min = PointLonLat::componentsMin( min, middle ); + max = PointLonLat::componentsMax( max, middle ); + } + } + + // extend by 'a small amount' (arbitrary) and limit + min = PointLonLat::sub( min, PointLonLat{0, h} ); + max = PointLonLat::add( max, PointLonLat{0, h} ); + min[1] = std::max( min[1], -90. ); + max[1] = std::min( max[1], 90. ); + + includesNorthPole = includesNorthPole || is_approximately_lesser_or_equal( 90., max[1] ); + includesSouthPole = includesSouthPole || is_approximately_lesser_or_equal( min[1], -90. ); + } + ATLAS_ASSERT( min[1] < max[1] ); + + + // 3. locate latitude extrema by checking if date line is crossed (in the + // projected/rotated frame), in which case we assume periodicity and if not, find + // extrema not at the corners by refining iteratively + + bool crossesDateLine = includesNorthPole || includesSouthPole; + + if ( !crossesDateLine ) { + for ( size_t i = 0; i < corners.size(); ++i ) { + PointXY A = corners[i]; + PointXY B = corners[( i + 1 ) % corners.size()]; + + // finite difference vector derivative (H is the perturbation vector) + const PointXY H{PointLonLat::mul( PointLonLat::normalize( PointLonLat::sub( B, A ) ), h )}; + double dAdx = derivate( A, H ).x(); + double dBdx = derivate( B, H ).x(); + + if ( !is_strictly_greater( dAdx * dBdx, 0. ) ) { + for ( size_t cnt = 0; cnt < Niter; ++cnt ) { + PointXY M = PointXY::middle( A, B ); + double dMdx = derivate( M, H ).x(); + if ( is_strictly_greater( dAdx * dMdx, 0. ) ) { + A = M; + dAdx = dMdx; + } + else if ( is_strictly_greater( dBdx * dMdx, 0. ) ) { + B = M; + dBdx = dMdx; + } + else { + break; + } + } + + PointXY middle( PointXY::middle( A, B ) ); + xy2lonlat( middle.data() ); + + min = PointLonLat::componentsMin( min, middle ); + max = PointLonLat::componentsMax( max, middle ); + } + } + + // extend by 'a small amount' (arbitrary) and limit + min = PointLonLat::sub( min, PointLonLat{h, 0} ); + max = PointLonLat::add( max, PointLonLat{h, 0} ); + max[0] = std::min( max[0], min[0] + 360. ); + + crossesDateLine = is_approximately_lesser_or_equal( 360., max[0] - min[0] ); + } + ATLAS_ASSERT( min[0] < max[0] ); + + + // 4. return bounding box + return crossesDateLine ? ZonalBandDomain( {min[1], max[1]} ) + : RectangularDomain( {min[0], max[0]}, {min[1], max[1]} );} + +//--------------------------------------------------------------------------------------------------------------------- + Rotated::Rotated( const PointLonLat& south_pole, double rotation_angle ) : util::Rotation( south_pole, rotation_angle ) {} diff --git a/src/atlas/projection/detail/ProjectionImpl.h b/src/atlas/projection/detail/ProjectionImpl.h index f948ca8c9..044bd1643 100644 --- a/src/atlas/projection/detail/ProjectionImpl.h +++ b/src/atlas/projection/detail/ProjectionImpl.h @@ -23,6 +23,7 @@ class Hash; } // namespace eckit namespace atlas { +class Domain; namespace util { class Config; } @@ -39,8 +40,8 @@ class ProjectionImpl : public util::Object { public: static const ProjectionImpl* create( const eckit::Parametrisation& p ); - ProjectionImpl() {} - virtual ~ProjectionImpl() {} // destructor should be virtual + ProjectionImpl() = default; + virtual ~ProjectionImpl() = default; // destructor should be virtual virtual std::string type() const = 0; @@ -50,7 +51,8 @@ class ProjectionImpl : public util::Object { PointLonLat lonlat( const PointXY& ) const; PointXY xy( const PointLonLat& ) const; - virtual bool strictlyRegional() const = 0; + virtual bool strictlyRegional() const = 0; + virtual Domain boundingBox( const Domain& ) const = 0; virtual Spec spec() const = 0; @@ -73,13 +75,15 @@ inline PointXY ProjectionImpl::xy( const PointLonLat& lonlat ) const { return xy; } +//--------------------------------------------------------------------------------------------------------------------- + class Rotated : public util::Rotation { public: using Spec = ProjectionImpl::Spec; Rotated( const PointLonLat& south_pole, double rotation_angle = 0. ); Rotated( const eckit::Parametrisation& ); - virtual ~Rotated() {} + virtual ~Rotated() = default; static std::string classNamePrefix() { return "Rotated"; } static std::string typePrefix() { return "rotated_"; } @@ -93,9 +97,9 @@ class NotRotated { public: using Spec = ProjectionImpl::Spec; - NotRotated() {} + NotRotated() = default; NotRotated( const eckit::Parametrisation& ) {} - virtual ~NotRotated() {} + virtual ~NotRotated() = default; static std::string classNamePrefix() { return ""; } // deliberately empty static std::string typePrefix() { return ""; } // deliberately empty diff --git a/src/atlas/projection/detail/SchmidtProjection.h b/src/atlas/projection/detail/SchmidtProjection.h index df61f9da2..c00ba31ff 100644 --- a/src/atlas/projection/detail/SchmidtProjection.h +++ b/src/atlas/projection/detail/SchmidtProjection.h @@ -10,6 +10,7 @@ #pragma once +#include "atlas/domain.h" #include "atlas/projection/detail/ProjectionImpl.h" namespace atlas { @@ -17,28 +18,29 @@ namespace projection { namespace detail { template -class SchmidtProjectionT : public ProjectionImpl { +class SchmidtProjectionT final : public ProjectionImpl { public: // constructor SchmidtProjectionT( const eckit::Parametrisation& p ); SchmidtProjectionT(); - // class name + // projection name static std::string static_type() { return Rotation::typePrefix() + "schmidt"; } - virtual std::string type() const override { return static_type(); } + std::string type() const override { return static_type(); } // projection and inverse projection - virtual void xy2lonlat( double crd[] ) const override; - virtual void lonlat2xy( double crd[] ) const override; + void xy2lonlat( double crd[] ) const override; + void lonlat2xy( double crd[] ) const override; - virtual bool strictlyRegional() const override { return false; } // schmidt is global grid + bool strictlyRegional() const override { return false; } // schmidt is global grid + Domain boundingBox( const Domain& domain ) const override { return ProjectionImpl::boundingBox( domain ); } // specification - virtual Spec spec() const override; + Spec spec() const override; - virtual std::string units() const override { return "degrees"; } + std::string units() const override { return "degrees"; } - virtual void hash( eckit::Hash& ) const override; + void hash( eckit::Hash& ) const override; private: double c_; // stretching factor diff --git a/src/atlas/util/Rotation.cc b/src/atlas/util/Rotation.cc index 5a9dc53ee..daa5b589c 100644 --- a/src/atlas/util/Rotation.cc +++ b/src/atlas/util/Rotation.cc @@ -164,45 +164,39 @@ inline PointXYZ rotate_geocentric( const PointXYZ& p, const RotationMatrix& R ) void Rotation::rotate( double crd[] ) const { if ( !rotated_ ) { return; } - if ( rotation_angle_only_ ) { - crd[LON] -= angle_; - return; - } - - const PointLonLat L( wrap_latitude( {crd[LON], crd[LAT]} ) ); - PointXYZ P; - UnitSphere::convertSphericalToCartesian( L, P ); + if ( !rotation_angle_only_ ) { + const PointLonLat L( wrap_latitude( {crd[LON], crd[LAT]} ) ); + PointXYZ P; + UnitSphere::convertSphericalToCartesian( L, P ); - const PointXYZ Pt = rotate_geocentric( P, rotate_ ); + const PointXYZ Pt = rotate_geocentric( P, rotate_ ); + PointLonLat Lt; + UnitSphere::convertCartesianToSpherical( Pt, Lt ); - PointLonLat Lt; - UnitSphere::convertCartesianToSpherical( Pt, Lt ); + crd[LON] = Lt.lon(); + crd[LAT] = Lt.lat(); + } - crd[LON] = Lt.lon() - angle_; - crd[LAT] = Lt.lat(); + crd[LON] -= angle_; } void Rotation::unrotate( double crd[] ) const { if ( !rotated_ ) { return; } - if ( rotation_angle_only_ ) { - crd[LON] += angle_; - return; - } - - PointLonLat Lt( crd ); - Lt.lon() += angle_; + crd[LON] += angle_; - PointXYZ Pt; - UnitSphere::convertSphericalToCartesian( Lt, Pt ); + if ( !rotation_angle_only_ ) { + const PointLonLat Lt( crd ); + PointXYZ Pt; + UnitSphere::convertSphericalToCartesian( Lt, Pt ); - const PointXYZ P = rotate_geocentric( Pt, unrotate_ ); + const PointXYZ P = rotate_geocentric( Pt, unrotate_ ); + PointLonLat L; + UnitSphere::convertCartesianToSpherical( P, L ); - PointLonLat L; - UnitSphere::convertCartesianToSpherical( P, L ); - - crd[LON] = L.lon(); - crd[LAT] = L.lat(); + crd[LON] = L.lon(); + crd[LAT] = L.lat(); + } } } // namespace util diff --git a/src/tests/projection/CMakeLists.txt b/src/tests/projection/CMakeLists.txt index 72ba3be35..bca0bf4a7 100644 --- a/src/tests/projection/CMakeLists.txt +++ b/src/tests/projection/CMakeLists.txt @@ -7,8 +7,9 @@ # does it submit to any jurisdiction. foreach(test - test_rotation - test_projection_LAEA ) + test_bounding_box + test_projection_LAEA + test_rotation ) ecbuild_add_test( TARGET atlas_${test} SOURCES ${test}.cc LIBS atlas ENVIRONMENT ${ATLAS_TEST_ENVIRONMENT} ) diff --git a/src/tests/projection/test_bounding_box.cc b/src/tests/projection/test_bounding_box.cc new file mode 100644 index 000000000..ec6cf33ee --- /dev/null +++ b/src/tests/projection/test_bounding_box.cc @@ -0,0 +1,324 @@ +/* + * (C) Copyright 1996- ECMWF. + * + * This software is licensed under the terms of the Apache Licence Version 2.0 + * which can be obtained at http://www.apache.org/licenses/LICENSE-2.0. + * In applying this licence, ECMWF does not waive the privileges and immunities + * granted to it by virtue of its status as an intergovernmental organisation nor + * does it submit to any jurisdiction. + */ + + +#include +#include +#include +#include +#include + +#include "eckit/geometry/Point2.h" +#include "eckit/log/Plural.h" +#include "eckit/types/FloatCompare.h" + +#include "atlas/domain.h" +#include "atlas/grid.h" +#include "atlas/domain/detail/GlobalDomain.h" // FIXME not included by atlas/domain.h +#include "atlas/grid.h" +#include "atlas/runtime/Log.h" +#include "atlas/util/Point.h" +#include "atlas/util/Rotation.h" +#include "tests/AtlasTestEnvironment.h" + + +namespace atlas { +namespace test { + +//----------------------------------------------------------------------------- + +double normalise( double weird, double minimum ) { + double lon = weird; + + double GLOBE = 360.; + while ( lon < minimum ) { + lon += GLOBE; + } + while ( lon >= minimum + GLOBE ) { + lon -= GLOBE; + } + + return lon; +} + + +struct BoundingBox : public std::array { + BoundingBox( double n, double w, double s, double e ) : std::array{n, w, s, e} {} + BoundingBox() : BoundingBox( 90, 0, -90, 360 ) {} + + double north() const { return operator[]( 0 ); } + double south() const { return operator[]( 2 ); } + double west() const { return operator[]( 1 ); } + double east() const { return operator[]( 3 ); } + + operator RectangularDomain() const { return {{{west(), east()}}, {{south(), north()}}}; } + + bool contains( const double& lat, const double& lon ) const { + return ( lat <= north() ) && ( lat >= south() ) && ( normalise( lon, west() ) <= east() ); + } + + bool contains( const BoundingBox& other ) const { + bool otherEmpty = !eckit::types::is_strictly_greater( other.north(), other.south() ) || + !eckit::types::is_strictly_greater( other.east(), other.west() ); + + if ( otherEmpty ) { + return contains( other.south(), other.west() ); + } + + // check for West/East range (if non-periodic), then other's corners + if ( east() - west() < other.east() - other.west() || east() < normalise( other.east(), west() ) ) { + return false; + } + + return contains( other.north(), other.west() ) && contains( other.north(), other.east() ) && + contains( other.south(), other.west() ) && contains( other.south(), other.east() ); + } +}; + + +struct Rotation : std::array { + Rotation( double lat, double lon ) : std::array{lon, lat} {} + double south_pole_latitude() const { return operator[]( 1 ); } + double south_pole_longitude() const { return normalise( operator[]( 0 ), 0. ); } + BoundingBox rotate( const BoundingBox& box ) const { + util::Config config; + config.set( "type", "rotated_lonlat" ); + config.set( "south_pole", std::vector( {south_pole_longitude(), south_pole_latitude()} ) ); + atlas::Projection p( config ); + + RectangularDomain before({box.west(), box.east()}, {box.south(), box.north()}); + Domain after = p.boundingBox( before ); + + if ( after.global() ) { + return {}; + } + + RectangularDomain r( after ); + ATLAS_ASSERT( r ); + + bool zonal = ZonalBandDomain( after ); + + double n = std::min( 90., r.ymax() ); + double s = std::max( -90., r.ymin() ); + double w = zonal ? 0. : r.xmin(); + double e = zonal ? 360. : r.xmax(); + + return {n, w, s, e}; + } +}; + + +using NiNj = std::array; + + +struct test_poles_t { +public: + + test_poles_t(const NiNj& ninj, + const Rotation& rotation, + const BoundingBox& bbox, + bool includesNorthPole = false, + bool includesSouthPole = false) : + ninj_(ninj), + rotation_(rotation), + bbox_(bbox), + includesNorthPole_(includesNorthPole), + includesSouthPole_(includesSouthPole) { + } + + const NiNj ninj_; + const Rotation rotation_; + const BoundingBox bbox_; + const bool includesNorthPole_; + const bool includesSouthPole_; + +private: + friend std::ostream& operator<<(std::ostream& out, const test_poles_t& test) { + return (out << "test:" + << "\n\t" << "NiNj = " << test.ninj_ + << "\n\t" << "Rotation = " << test.rotation_ + << "\n\t" << "BoundingBox = " << test.bbox_ + << "\n\t" << "includesNorthPole? " << test.includesNorthPole_ + << "\n\t" << "includesSouthPole? " << test.includesSouthPole_); + } +}; + + +struct test_expected_rotation_t { + const NiNj ninj_; + const Rotation rotation_; + const BoundingBox bbox_; + const BoundingBox rotatedBbox_; + +private: + friend std::ostream& operator<<(std::ostream& out, const test_expected_rotation_t& test) { + return (out << "test:" + << "\n\t" << "NiNj = " << test.ninj_ + << "\n\t" << "Rotation = " << test.rotation_ + << "\n\t" << "BoundingBox = " << test.bbox_ + << "\n\t" << "rotatedBbox = " << test.rotatedBbox_); + } +}; + +//----------------------------------------------------------------------------- + +CASE("MIR-282") { + auto old = Log::info().precision(16); + + + std::vector test_poles { + { NiNj{ 124, 118}, Rotation(-35., 0.), BoundingBox{12, -14.5, -17.25, 16.25} }, + { NiNj{ 360, 181}, Rotation(-90., 0.), BoundingBox(), true, true }, + { NiNj{ 81, 56}, Rotation(-75., 15.), BoundingBox{75., -35., 20., 45.}, true }, + { NiNj{ 111, 86}, Rotation(-35., 15.), BoundingBox{40., -55., -45., 55.}, true }, + { NiNj{ 91, 76}, Rotation(-30., -15.), BoundingBox{35., -40., -40., 50.}, true }, + { NiNj{ 101, 81}, Rotation(-25., 0.), BoundingBox{40., -50., -40., 50.}, true }, + { NiNj{ 56, 61}, Rotation(-15., 45.), BoundingBox{30., -50., -30., 5.}, true }, + { NiNj{ 96, 91}, Rotation( 0., 80.), BoundingBox{50., -65., -40., 30.}, true }, + + { NiNj{ 178, 143}, Rotation(-40., 10.), BoundingBox{22.7, -13.6, -5.9, 21.8} }, + { NiNj{ 117, 79}, Rotation(-43., 10.), BoundingBox{ 3.4, -6.8, -4.4, 4.8} }, + { NiNj{ 776, 492}, Rotation(-30., 0.), BoundingBox{18.1, -37.6, -31., 39.9} }, + { NiNj{ 149, 105}, Rotation(-76., 14.), BoundingBox{72., -32., 20., 42.} }, + { NiNj{ 240, 240}, Rotation(-30., -5.), BoundingBox{ 9.875, -15., -20., 14.875} }, + + { NiNj{ 321, 370}, Rotation(-15., 45.), BoundingBox{27.5, -46.5, -28, 1.5}, true }, + { NiNj{ 202, 235}, Rotation( 0., 130.), BoundingBox{32.75, -86.75, -37.75, -26.15}, false }, + { NiNj{ 409, 309}, Rotation(-35., 15.), BoundingBox{36., -51., -41., 51.}, true }, + + { NiNj{ 171, 6}, Rotation(-35., 160.), BoundingBox{80., 30., 75., 200.} }, + { NiNj{ 81, 11}, Rotation( 30., -30.), BoundingBox{70., 120., 60., 200.} }, + { NiNj{ 261, 66}, Rotation( 45., -120.), BoundingBox{55., -120., -10., 140.} }, + + { NiNj{ 4, 4}, Rotation(50., 100.), BoundingBox{10., 70., -20., 100.} }, + }; + + + std::vector test_expected_rotations { + { NiNj{21, 21}, Rotation(-40., 22.), BoundingBox{ 90, -10, 70, 10}, BoundingBox{ 60, -164.730, 40, -151.270} }, + { NiNj{21, 21}, Rotation(-40., 22.), BoundingBox{ -70, -10, -90, 10}, BoundingBox{-20, 18.370, -40, 25.630} }, + }; + + + SECTION("MIR-282: rotated_ll covering North/South poles") { + for (auto& test : test_poles) { + Log::info() << test << std::endl; + + const PointLonLat southPole( + test.rotation_.south_pole_longitude(), + test.rotation_.south_pole_latitude() ); + + const util::Rotation r(southPole); + + // check bbox including poles (in the unrotated frame) + PointLonLat NP{ r.unrotate({0., 90.}) }; + PointLonLat SP{ r.unrotate({0., -90.}) }; + + bool includesNorthPole = test.bbox_.contains(NP.lat(), NP.lon()); + bool includesSouthPole = test.bbox_.contains(SP.lat(), SP.lon()); + + Log::info() << "check:" + << "\n\t" << "includesNorthPole? " << includesNorthPole + << "\n\t" << "includesSouthPole? " << includesSouthPole + << std::endl; + + EXPECT(includesNorthPole == test.includesNorthPole_); + EXPECT(includesSouthPole == test.includesSouthPole_); + + } + } + + + SECTION("MIR-282: rotated_ll contained by cropping") { + for (auto& test : test_poles) { + Log::info() << test << std::endl; + + double n = test.bbox_.north(); + double s = test.bbox_.south(); + double w = test.bbox_.west(); + double e = test.bbox_.east(); + + RectangularDomain dom( test.bbox_ ); + + using grid::LinearSpacing; + StructuredGrid::XSpace xspace( LinearSpacing( w, e, test.ninj_[0], !ZonalBandDomain( dom ) ) ); + StructuredGrid::YSpace yspace( LinearSpacing( n, s, test.ninj_[1] ) ); + + util::Config config; + config.set( "type", "rotated_lonlat" ); + config.set( "south_pole", std::vector( {test.rotation_.south_pole_longitude(), + test.rotation_.south_pole_latitude()} ) ); + Projection rotation( config ); + + Grid g = StructuredGrid( xspace, yspace, rotation, dom ); + ATLAS_ASSERT( g ); + + BoundingBox crop(test.rotation_.rotate(test.bbox_)); + + Log::info() << "contained by cropping" + << "\n\t " << test.bbox_ + << "\n\t + " << test.rotation_ + << "\n\t = " << crop + << std::endl; + + for ( PointLonLat p : g.lonlat() ) { + EXPECT( crop.contains( p.lat(), p.lon() ) ); + } + Log::info() << "checked " << eckit::Plural( g.size(), "point" ) << std::endl; + } + } + + + SECTION("MIR-309: expected rotations") { + + auto is_approximately_equal = [] (const BoundingBox& a, const BoundingBox& b, double eps) { + auto slightly_bigger = [eps](const BoundingBox& bbox) { + + double n = std::min(90., bbox.north() + eps); + double s = std::max(-90., bbox.south() - eps); + + // periodicity not considered + double w = bbox.west() - eps; + double e = bbox.east() + eps; + + return BoundingBox{n, w, s, e}; + }; + + return slightly_bigger(a).contains(b) && + slightly_bigger(b).contains(a); + }; + + + for (auto& test : test_expected_rotations) { + auto rotated = test.rotation_.rotate(test.bbox_); + Log::info() << test + << "\n\t" "reference:\t" << test.rotatedBbox_ + << "\n\t" "calculated:\t" << rotated + << std::endl; + + static constexpr double eps = 0.0015; + EXPECT(is_approximately_equal(test.rotatedBbox_, rotated, eps)); + } + } + + + Log::info().precision(old); +} + +//----------------------------------------------------------------------------- + +} // namespace test +} // namespace atlas + + +int main(int argc, char **argv) { + return atlas::test::run( argc, argv ); +} + From 86fd2c204451bd32ed948d8050827f837b953777 Mon Sep 17 00:00:00 2001 From: Pedro Maciel Date: Thu, 27 Jun 2019 23:17:16 +0100 Subject: [PATCH 37/86] MIR-4: Grid::boundingBox, Projection::boundingBox --- .../projection/detail/LonLatProjection.cc | 219 ++++++--------- src/atlas/projection/detail/ProjectionImpl.cc | 259 ++++++++++++------ src/atlas/projection/detail/ProjectionImpl.h | 18 ++ src/tests/projection/test_bounding_box.cc | 16 +- 4 files changed, 285 insertions(+), 227 deletions(-) diff --git a/src/atlas/projection/detail/LonLatProjection.cc b/src/atlas/projection/detail/LonLatProjection.cc index 3e80b6c26..fae801d62 100644 --- a/src/atlas/projection/detail/LonLatProjection.cc +++ b/src/atlas/projection/detail/LonLatProjection.cc @@ -25,52 +25,6 @@ namespace atlas { namespace projection { namespace detail { -namespace { - -struct Derivate { - Derivate( const util::Rotation& rotation, PointLonLat H ) : rotation_( rotation ), H_( H ) {} - virtual PointLonLat d( PointLonLat ) const = 0; - const util::Rotation& rotation_; - const PointLonLat H_; - void xy2lonlat( double crd[] ) const { rotation_.rotate( crd ); } -}; - -struct DerivateForwards final : Derivate { - using Derivate::Derivate; - PointLonLat d( PointLonLat P ) const override { - PointXY A( P ); - PointXY B( PointXY::add( P, Derivate::H_ ) ); - Derivate::xy2lonlat( A.data() ); - Derivate::xy2lonlat( B.data() ); - return PointXY::div( PointXY::sub( B, A ), PointXY::norm( Derivate::H_ ) ); - } -}; - -struct DerivateBackwards final : Derivate { - using Derivate::Derivate; - PointLonLat d( PointLonLat P ) const override { - PointXY A( PointXY::sub( P, Derivate::H_ ) ); - PointXY B( P ); - Derivate::xy2lonlat( A.data() ); - Derivate::xy2lonlat( B.data() ); - return PointXY::div( PointXY::sub( B, A ), PointXY::norm( Derivate::H_ ) ); - } -}; - -struct DerivateCentral final : Derivate { - using Derivate::Derivate; - PointLonLat d( PointLonLat P ) const override { - PointXY H2( PointXY::mul( Derivate::H_, 0.5 ) ); - PointXY A( PointXY::sub( P, H2 ) ); - PointXY B( PointXY::add( P, H2 ) ); - Derivate::xy2lonlat( A.data() ); - Derivate::xy2lonlat( B.data() ); - return PointXY::div( PointXY::sub( B, A ), PointXY::norm( Derivate::H_ ) ); - } -}; - -} // (anonymous namespace) - template LonLatProjectionT::LonLatProjectionT( const eckit::Parametrisation& config ) : ProjectionImpl(), @@ -110,81 +64,90 @@ Domain LonLatProjectionT::boundingBox( const Domain& domain ) const { using eckit::types::is_approximately_lesser_or_equal; using eckit::types::is_strictly_greater; + // 0. setup + + if ( domain.global() ) { + return domain; + } RectangularDomain rect( domain ); ATLAS_ASSERT( rect ); - // 0. setup - Point2 min, max; - - constexpr double h = 0.001; + PointLonLat min; + PointLonLat max; + constexpr double h = 0.001; + constexpr size_t Niter = 100; // 1. determine box from rotated corners - const std::vector corners{ + const std::vector corners{ {rect.xmin(), rect.ymax()}, {rect.xmax(), rect.ymax()}, {rect.xmax(), rect.ymin()}, {rect.xmin(), rect.ymin()}}; bool first = true; for ( auto& p : corners ) { PointLonLat r( rotate( p ) ); - min = first ? r : Point2::componentsMin( min, r ); - max = first ? r : Point2::componentsMax( max, r ); - first = false; + auto rmin = PointLonLat::sub( r, PointLonLat{h, h} ); + auto rmax = PointLonLat::add( r, PointLonLat{h, h} ); + min = first ? rmin : PointLonLat::componentsMin( min, rmin ); + max = first ? rmax : PointLonLat::componentsMax( max, rmax ); + first = false; } + // 2. locate latitude extrema by checking if poles are included (in the unrotated frame) and if not, find extrema + // not at the corners by refining iteratively - // 2. locate latitude extrema by checking if poles are included (in the - // unrotated frame) and if not, find extrema not at the corners by refining - // iteratively - - PointLonLat NP{unrotate( {0., 90.} )}; - PointLonLat SP{unrotate( {0., -90.} )}; + PointXY NP{unrotate( {0., 90.} )}; + PointXY SP{unrotate( {0., -90.} )}; - bool includesNorthPole = domain.contains( NP.lon(), NP.lat() ); - bool includesSouthPole = domain.contains( SP.lon(), SP.lat() ); + bool includesNorthPole = rect.contains( NP ); + bool includesSouthPole = rect.contains( SP ); - if ( !includesNorthPole || !includesSouthPole ) { - for ( size_t i = 0; i < corners.size(); ++i ) { - PointLonLat A = corners[i]; - PointLonLat B = corners[( i + 1 ) % corners.size()]; + for ( size_t i = 0; i < corners.size(); ++i ) { + if ( !includesNorthPole || !includesSouthPole ) { + PointXY A = corners[i]; + PointXY B = corners[( i + 1 ) % corners.size()]; // finite difference vector derivative (H is the perturbation vector) - const PointLonLat H{Point2::mul( Point2::normalize( Point2::sub( B, A ) ), h )}; - std::unique_ptr derivate( new DerivateCentral( this->rotation_, H) ); - - double derivativeAtA = derivate->d( A ).lat(); - double derivativeAtB = derivate->d( B ).lat(); - - if ( !is_strictly_greater( derivativeAtA * derivativeAtB, 0. ) ) { - for ( size_t cnt = 0; cnt < 100; ++cnt ) { - PointLonLat M = PointLonLat::middle( A, B ); - double derivativeAtM = derivate->d( M ).lat(); - if ( is_strictly_greater( derivativeAtA * derivativeAtM, 0. ) ) { - A = M; - derivativeAtA = derivativeAtM; + const PointXY H{PointXY::mul( PointXY::normalize( PointXY::sub( B, A ) ), h )}; + std::unique_ptr derivate( DerivateFactory::build( "central", *this, H ) ); + + double dAdy = derivate->d( A ).lat(); + double dBdy = derivate->d( B ).lat(); + + if ( !is_strictly_greater( dAdy * dBdy, 0. ) ) { + for ( size_t cnt = 0; cnt < Niter; ++cnt ) { + PointXY M = PointXY::middle( A, B ); + double dMdy = derivate->d( M ).lat(); + if ( is_strictly_greater( dAdy * dMdy, 0. ) ) { + A = M; + dAdy = dMdy; } - else if ( is_strictly_greater( derivativeAtB * derivativeAtM, 0. ) ) { - B = M; - derivativeAtB = derivativeAtM; + else if ( is_strictly_greater( dBdy * dMdy, 0. ) ) { + B = M; + dBdy = dMdy; } else { break; } } - PointLonLat r( rotate( PointLonLat::middle( A, B ) ) ); - min = Point2::componentsMin( min, r ); - max = Point2::componentsMax( max, r ); - } - } + // update extrema, extended by 'a small amount' (arbitrary) + PointLonLat middle( rotate( PointXY::middle( A, B ) ) ); - // extend by 'a small amount' (arbitrary) - min = Point2::sub( min, Point2{0, h} ); - max = Point2::add( max, Point2{0, h} ); + min = PointLonLat::componentsMin( min, PointLonLat::sub( middle, PointLonLat{0, h} ) ); + if ( includesSouthPole || is_approximately_lesser_or_equal( min[1], -90. ) ) { + includesSouthPole = true; + min[1] = -90.; + } - includesNorthPole = includesNorthPole || is_approximately_lesser_or_equal( 90., max[1] ); - includesSouthPole = includesSouthPole || is_approximately_lesser_or_equal( min[1], -90. ); + max = PointLonLat::componentsMax( max, PointLonLat::add( middle, PointLonLat{0, h} ) ); + if ( includesNorthPole || is_approximately_lesser_or_equal( 90., max[1] ) ) { + includesNorthPole = true; + max[1] = 90.; + } + } + } } - ATLAS_ASSERT( min[1] < max[1] ); + ATLAS_ASSERT( min < max ); // 3. locate latitude extrema by checking if date line is crossed (in the @@ -219,57 +182,53 @@ Domain LonLatProjectionT::boundingBox( const Domain& domain ) const { } } - if ( !crossesDateLine ) { - for ( size_t i = 0; i < corners.size(); ++i ) { - PointLonLat A = corners[i]; - PointLonLat B = corners[( i + 1 ) % corners.size()]; + for ( size_t i = 0; i < corners.size(); ++i ) { + if ( !crossesDateLine ) { + PointXY A = corners[i]; + PointXY B = corners[( i + 1 ) % corners.size()]; // finite difference vector derivative (H is the perturbation vector) - const PointLonLat H{Point2::mul( Point2::normalize( Point2::sub( B, A ) ), h )}; - std::unique_ptr derivate( new DerivateCentral( this->rotation_, H) ); - - double derivativeAtA = derivate->d( A ).lon(); - double derivativeAtB = derivate->d( B ).lon(); - - if ( !is_strictly_greater( derivativeAtA * derivativeAtB, 0. ) ) { - for ( size_t cnt = 0; cnt < 100; ++cnt ) { - PointLonLat M = PointLonLat::middle( A, B ); - double derivativeAtM = derivate->d( M ).lon(); - if ( is_strictly_greater( derivativeAtA * derivativeAtM, 0. ) ) { - A = M; - derivativeAtA = derivativeAtM; + const PointXY H{PointXY::mul( PointXY::normalize( PointXY::sub( B, A ) ), h )}; + std::unique_ptr derivate( DerivateFactory::build( "central", *this, H ) ); + + double dAdx = derivate->d( A ).lon(); + double dBdx = derivate->d( B ).lon(); + + if ( !is_strictly_greater( dAdx * dBdx, 0. ) ) { + for ( size_t cnt = 0; cnt < Niter; ++cnt ) { + PointXY M = PointXY::middle( A, B ); + double dMdx = derivate->d( M ).lon(); + if ( is_strictly_greater( dAdx * dMdx, 0. ) ) { + A = M; + dAdx = dMdx; } - else if ( is_strictly_greater( derivativeAtB * derivativeAtM, 0. ) ) { - B = M; - derivativeAtB = derivativeAtM; + else if ( is_strictly_greater( dBdx * dMdx, 0. ) ) { + B = M; + dBdx = dMdx; } else { break; } } - PointLonLat r( rotate( PointLonLat::middle( A, B ) ) ); - min = Point2::componentsMin( min, r ); - max = Point2::componentsMax( max, r ); + // update extrema, extended by 'a small amount' (arbitrary) + PointLonLat middle( rotate( PointXY::middle( A, B ) ) ); + + min = PointLonLat::componentsMin( min, PointLonLat::sub( middle, PointLonLat{h, 0} ) ); + max = PointLonLat::componentsMax( max, PointLonLat::add( middle, PointLonLat{h, 0} ) ); + if ( is_approximately_lesser_or_equal( 360., max[0] - min[0] ) ) { + crossesDateLine = true; + max[0] = min[0] + 360.; + } } } - - // extend by 'a small amount' (arbitrary) - min = Point2::sub( min, Point2{h, 0} ); - max = Point2::add( max, Point2{h, 0} ); - - crossesDateLine = is_approximately_lesser_or_equal( 360., max[0] - min[0] ); } - ATLAS_ASSERT( min[0] < max[0] ); - + ATLAS_ASSERT( min < max ); - // 4. set bounding box - double n = includesNorthPole ? 90. : max[1]; - double s = includesSouthPole ? -90. : min[1]; - double w = crossesDateLine ? 0 : min[0]; - double e = crossesDateLine ? 360. : max[0]; - return RectangularDomain({w, e}, {s, n}); + // 4. return bounding box + return crossesDateLine ? ZonalBandDomain( {min[1], max[1]} ) + : RectangularDomain( {min[0], max[0]}, {min[1], max[1]} ); } template diff --git a/src/atlas/projection/detail/ProjectionImpl.cc b/src/atlas/projection/detail/ProjectionImpl.cc index 09acb9b5e..71e7c7ed7 100644 --- a/src/atlas/projection/detail/ProjectionImpl.cc +++ b/src/atlas/projection/detail/ProjectionImpl.cc @@ -8,6 +8,9 @@ * nor does it submit to any jurisdiction. */ +#include + +#include "eckit/thread/AutoLock.h" #include "eckit/types/FloatCompare.h" #include "eckit/utils/Hash.h" @@ -17,14 +20,124 @@ #include "atlas/projection/detail/ProjectionFactory.h" #include "atlas/projection/detail/ProjectionImpl.h" #include "atlas/runtime/Exception.h" +#include "atlas/runtime/Log.h" #include "atlas/util/Config.h" #include "atlas/util/Earth.h" - namespace atlas { namespace projection { namespace detail { +// -------------------------------------------------------------------------------------------------------------------- + +namespace { + +template +struct DerivateBuilder : public ProjectionImpl::DerivateFactory { + DerivateBuilder( const std::string& type ) : DerivateFactory( type ) {} + ProjectionImpl::Derivate* make( const ProjectionImpl& p, PointLonLat H ) { return new T( p, H ); } +}; + +static pthread_once_t once = PTHREAD_ONCE_INIT; +static eckit::Mutex* mtx = nullptr; + +static std::map* m = nullptr; +static void init() { + mtx = new eckit::Mutex(); + m = new std::map(); +} + +} // (anonymous namespace) + +ProjectionImpl::Derivate* ProjectionImpl::DerivateFactory::build( const std::string& type, const ProjectionImpl& p, + PointLonLat H ) { + pthread_once( &once, init ); + eckit::AutoLock __lock( mtx ); + + auto j = m->find( type ); + if ( j == m->end() ) { + list( Log::error() << "DerivateFactory: unknown '" << type << "', choices are: " ); + throw_Exception( "DerivateFactory: unknown '" + type + "'", Here() ); + } + return ( *j ).second->make( p, H ); +} + +void ProjectionImpl::DerivateFactory::list( std::ostream& out ) { + pthread_once( &once, init ); + eckit::AutoLock __lock( mtx ); + + const char* sep = ""; + for ( const auto& j : *m ) { + out << sep << j.first; + sep = ", "; + } +} + +ProjectionImpl::DerivateFactory::DerivateFactory( const std::string& type ) { + pthread_once( &once, init ); + eckit::AutoLock __lock( mtx ); + + if ( m->find( type ) != m->end() ) { + throw_Exception( "DerivateFactory: duplicate '" + type + "'", Here() ); + } + ( *m )[type] = this; +} + +ProjectionImpl::DerivateFactory::~DerivateFactory() { + eckit::AutoLock __lock( mtx ); + + for ( auto& i : *m ) { + delete i.second; + } + m->clear(); +} + +// -------------------------------------------------------------------------------------------------------------------- + +namespace { + +struct DerivateForwards final : ProjectionImpl::Derivate { + using Derivate::Derivate; + PointLonLat d( PointLonLat P ) const override { + PointXY A( P ); + PointXY B( PointXY::add( P, Derivate::H_ ) ); + Derivate::xy2lonlat( A.data() ); + Derivate::xy2lonlat( B.data() ); + return PointXY::div( PointXY::sub( B, A ), PointXY::norm( Derivate::H_ ) ); + } +}; + +struct DerivateBackwards final : ProjectionImpl::Derivate { + using Derivate::Derivate; + PointLonLat d( PointLonLat P ) const override { + PointXY A( PointXY::sub( P, Derivate::H_ ) ); + PointXY B( P ); + Derivate::xy2lonlat( A.data() ); + Derivate::xy2lonlat( B.data() ); + return PointXY::div( PointXY::sub( B, A ), PointXY::norm( Derivate::H_ ) ); + } +}; + +struct DerivateCentral final : ProjectionImpl::Derivate { + using Derivate::Derivate; + PointLonLat d( PointLonLat P ) const override { + PointXY H2( PointXY::mul( Derivate::H_, 0.5 ) ); + PointXY A( PointXY::sub( P, H2 ) ); + PointXY B( PointXY::add( P, H2 ) ); + Derivate::xy2lonlat( A.data() ); + Derivate::xy2lonlat( B.data() ); + return PointXY::div( PointXY::sub( B, A ), PointXY::norm( Derivate::H_ ) ); + } +}; + +DerivateBuilder __derivate1( "forwards" ); +DerivateBuilder __derivate2( "backwards" ); +DerivateBuilder __derivate3( "central" ); + +} // (anonymous namespace) + +// -------------------------------------------------------------------------------------------------------------------- + const ProjectionImpl* ProjectionImpl::create( const eckit::Parametrisation& p ) { std::string projectionType; if ( p.get( "type", projectionType ) ) { return ProjectionFactory::build( projectionType, p ); } @@ -38,66 +151,38 @@ Domain ProjectionImpl::boundingBox( const Domain& domain ) const { using eckit::types::is_strictly_greater; // 0. setup + + if ( domain.global() ) { + return domain; + } RectangularDomain rect( domain ); + ATLAS_ASSERT( rect ); PointLonLat min; PointLonLat max; constexpr double h = 0.001; constexpr size_t Niter = 100; -#if 0 - auto derivate_forwards = [&]( PointXY P, const PointXY& H ) -> PointXY { - PointXY A( P ); - PointXY B( PointXY::add( P, H ) ); - xy2lonlat( A.data() ); - xy2lonlat( B.data() ); - - return PointXY::div( PointXY::sub( B, A ), PointXY::norm( H ) ); - }; - - - auto derivate_backwards = [&]( PointXY P, const PointXY& H ) -> PointXY { - PointXY A( PointXY::sub( P, H ) ); - PointXY B( P ); - xy2lonlat( A.data() ); - xy2lonlat( B.data() ); - - return PointXY::div( PointXY::sub( B, A ), PointXY::norm( H ) ); - }; -#endif - - auto derivate_central = [&]( PointXY P, const PointXY& H ) -> PointXY { - PointXY H2( PointXY::mul( H, 0.5 ) ); - PointXY A( PointXY::sub( P, H2 ) ); - PointXY B( PointXY::add( P, H2 ) ); - xy2lonlat( A.data() ); - xy2lonlat( B.data() ); - - return PointXY::div( PointXY::sub( B, A ), PointXY::norm( H ) ); - }; - - auto derivate = derivate_central; - // 1. determine box from projected/rotated corners - const std::vector corners{{rect.xmin(), rect.ymax()}, - {rect.xmax(), rect.ymax()}, - {rect.xmax(), rect.ymin()}, - {rect.xmin(), rect.ymin()}}; + + const std::vector corners{ + {rect.xmin(), rect.ymax()}, {rect.xmax(), rect.ymax()}, {rect.xmax(), rect.ymin()}, {rect.xmin(), rect.ymin()}}; bool first = true; for ( auto& p : corners ) { - PointXY r( p ); + PointLonLat r( p ); xy2lonlat( r.data() ); - - min = first ? r : PointLonLat::componentsMin( min, r ); - max = first ? r : PointLonLat::componentsMax( max, r ); - first = false; + auto rmin = PointLonLat::sub( r, PointLonLat{h, h} ); + auto rmax = PointLonLat::add( r, PointLonLat{h, h} ); + min = first ? rmin : PointLonLat::componentsMin( min, rmin ); + max = first ? rmax : PointLonLat::componentsMax( max, rmax ); + first = false; } struct crosses_t { crosses_t( const ProjectionImpl& projection, const PointXY& p1, const PointXY& p2, const PointXY& p3, const PointXY& p4 ) : - projection_(projection), + projection_( projection ), quadrilateral_( xy_to_xyz( projection, p1 ), xy_to_xyz( projection, p2 ), xy_to_xyz( projection, p3 ), xy_to_xyz( projection, p4 ) ) {} @@ -121,32 +206,33 @@ Domain ProjectionImpl::boundingBox( const Domain& domain ) const { } crosses( *this, corners[0], corners[1], corners[2], corners[3] ); - // 2. locate latitude extrema by checking if poles are included (in the - // projected/rotated frame) and if not, find extrema not at the corners by refining - // iteratively + // 2. locate latitude extrema by checking if poles are included (in the unrotated/un-projected frame) and if not, + // find extrema not at the corners by refining iteratively PointXY NP{0, 90}; PointXY SP{0, -90}; - lonlat2xy( NP.data() ); // un-project (or unrotate, in case of rotation) + lonlat2xy( NP.data() ); // unrotate/un-project lonlat2xy( SP.data() ); bool includesNorthPole = crosses( NP ); bool includesSouthPole = crosses( SP ); - if ( !includesNorthPole || !includesSouthPole ) { - for ( size_t i = 0; i < corners.size(); ++i ) { + for ( size_t i = 0; i < corners.size(); ++i ) { + if ( !includesNorthPole || !includesSouthPole ) { PointXY A = corners[i]; PointXY B = corners[( i + 1 ) % corners.size()]; // finite difference vector derivative (H is the perturbation vector) - const PointXY H{PointLonLat::mul( PointLonLat::normalize( PointLonLat::sub( B, A ) ), h )}; - double dAdy = derivate( A, H ).y(); - double dBdy = derivate( B, H ).y(); + const PointXY H{PointXY::mul( PointXY::normalize( PointXY::sub( B, A ) ), h )}; + std::unique_ptr derivate( DerivateFactory::build( "central", *this, H ) ); + + double dAdy = derivate->d( A ).lat(); + double dBdy = derivate->d( B ).lat(); if ( !is_strictly_greater( dAdy * dBdy, 0. ) ) { for ( size_t cnt = 0; cnt < Niter; ++cnt ) { PointXY M = PointXY::middle( A, B ); - double dMdy = derivate( M, H ).y(); + double dMdy = derivate->d( M ).lat(); if ( is_strictly_greater( dAdy * dMdy, 0. ) ) { A = M; dAdy = dMdy; @@ -160,24 +246,25 @@ Domain ProjectionImpl::boundingBox( const Domain& domain ) const { } } - PointXY middle( PointXY::middle( A, B ) ); + // update extrema, extended by 'a small amount' (arbitrary) + PointLonLat middle( PointXY::middle( A, B ) ); xy2lonlat( middle.data() ); - min = PointLonLat::componentsMin( min, middle ); - max = PointLonLat::componentsMax( max, middle ); + min = PointLonLat::componentsMin( min, PointLonLat::sub( middle, PointLonLat{0, h} ) ); + if ( includesSouthPole || is_approximately_lesser_or_equal( min[1], -90. ) ) { + includesSouthPole = true; + min[1] = -90.; + } + + max = PointLonLat::componentsMax( max, PointLonLat::add( middle, PointLonLat{0, h} ) ); + if ( includesNorthPole || is_approximately_lesser_or_equal( 90., max[1] ) ) { + includesNorthPole = true; + max[1] = 90.; + } } } - - // extend by 'a small amount' (arbitrary) and limit - min = PointLonLat::sub( min, PointLonLat{0, h} ); - max = PointLonLat::add( max, PointLonLat{0, h} ); - min[1] = std::max( min[1], -90. ); - max[1] = std::min( max[1], 90. ); - - includesNorthPole = includesNorthPole || is_approximately_lesser_or_equal( 90., max[1] ); - includesSouthPole = includesSouthPole || is_approximately_lesser_or_equal( min[1], -90. ); } - ATLAS_ASSERT( min[1] < max[1] ); + ATLAS_ASSERT( min < max ); // 3. locate latitude extrema by checking if date line is crossed (in the @@ -186,20 +273,22 @@ Domain ProjectionImpl::boundingBox( const Domain& domain ) const { bool crossesDateLine = includesNorthPole || includesSouthPole; - if ( !crossesDateLine ) { - for ( size_t i = 0; i < corners.size(); ++i ) { + for ( size_t i = 0; i < corners.size(); ++i ) { + if ( !crossesDateLine ) { PointXY A = corners[i]; PointXY B = corners[( i + 1 ) % corners.size()]; // finite difference vector derivative (H is the perturbation vector) - const PointXY H{PointLonLat::mul( PointLonLat::normalize( PointLonLat::sub( B, A ) ), h )}; - double dAdx = derivate( A, H ).x(); - double dBdx = derivate( B, H ).x(); + const PointXY H{PointXY::mul( PointXY::normalize( PointXY::sub( B, A ) ), h )}; + std::unique_ptr derivate( DerivateFactory::build( "central", *this, H ) ); + + double dAdx = derivate->d( A ).lon(); + double dBdx = derivate->d( B ).lon(); if ( !is_strictly_greater( dAdx * dBdx, 0. ) ) { for ( size_t cnt = 0; cnt < Niter; ++cnt ) { PointXY M = PointXY::middle( A, B ); - double dMdx = derivate( M, H ).x(); + double dMdx = derivate->d( M ).lon(); if ( is_strictly_greater( dAdx * dMdx, 0. ) ) { A = M; dAdx = dMdx; @@ -213,27 +302,26 @@ Domain ProjectionImpl::boundingBox( const Domain& domain ) const { } } - PointXY middle( PointXY::middle( A, B ) ); + // update extrema, extended by 'a small amount' (arbitrary) + PointLonLat middle( PointXY::middle( A, B ) ); xy2lonlat( middle.data() ); - min = PointLonLat::componentsMin( min, middle ); - max = PointLonLat::componentsMax( max, middle ); + min = PointLonLat::componentsMin( min, PointLonLat::sub( middle, PointLonLat{h, 0} ) ); + max = PointLonLat::componentsMax( max, PointLonLat::add( middle, PointLonLat{h, 0} ) ); + if ( is_approximately_lesser_or_equal( 360., max[0] - min[0] ) ) { + crossesDateLine = true; + max[0] = min[0] + 360.; + } } } - - // extend by 'a small amount' (arbitrary) and limit - min = PointLonLat::sub( min, PointLonLat{h, 0} ); - max = PointLonLat::add( max, PointLonLat{h, 0} ); - max[0] = std::min( max[0], min[0] + 360. ); - - crossesDateLine = is_approximately_lesser_or_equal( 360., max[0] - min[0] ); } - ATLAS_ASSERT( min[0] < max[0] ); + ATLAS_ASSERT( min < max ); // 4. return bounding box return crossesDateLine ? ZonalBandDomain( {min[1], max[1]} ) - : RectangularDomain( {min[0], max[0]}, {min[1], max[1]} );} + : RectangularDomain( {min[0], max[0]}, {min[1], max[1]} ); +} //--------------------------------------------------------------------------------------------------------------------- @@ -257,6 +345,7 @@ void Rotated::hash( eckit::Hash& hsh ) const { hsh.add( rotationAngle() ); } + } // namespace detail } // namespace projection } // namespace atlas diff --git a/src/atlas/projection/detail/ProjectionImpl.h b/src/atlas/projection/detail/ProjectionImpl.h index 044bd1643..de09043e4 100644 --- a/src/atlas/projection/detail/ProjectionImpl.h +++ b/src/atlas/projection/detail/ProjectionImpl.h @@ -61,6 +61,24 @@ class ProjectionImpl : public util::Object { virtual operator bool() const { return true; } virtual void hash( eckit::Hash& ) const = 0; + + struct Derivate { + Derivate( const ProjectionImpl& p, PointLonLat H ) : projection_( p ), H_( H ) {} + virtual PointLonLat d( PointLonLat ) const = 0; + const ProjectionImpl& projection_; + const PointLonLat H_; + void xy2lonlat( double crd[] ) const { projection_.xy2lonlat( crd ); } + }; + + struct DerivateFactory { + static ProjectionImpl::Derivate* build( const std::string& type, const ProjectionImpl& p, PointLonLat H ); + static void list( std::ostream& out ); + + protected: + DerivateFactory( const std::string& ); + virtual ProjectionImpl::Derivate* make( const ProjectionImpl& p, PointLonLat H ) = 0; + virtual ~DerivateFactory(); + }; }; inline PointLonLat ProjectionImpl::lonlat( const PointXY& xy ) const { diff --git a/src/tests/projection/test_bounding_box.cc b/src/tests/projection/test_bounding_box.cc index ec6cf33ee..65a369a20 100644 --- a/src/tests/projection/test_bounding_box.cc +++ b/src/tests/projection/test_bounding_box.cc @@ -95,22 +95,12 @@ struct Rotation : std::array { RectangularDomain before({box.west(), box.east()}, {box.south(), box.north()}); Domain after = p.boundingBox( before ); - - if ( after.global() ) { - return {}; - } + ATLAS_ASSERT( after ); RectangularDomain r( after ); ATLAS_ASSERT( r ); - bool zonal = ZonalBandDomain( after ); - - double n = std::min( 90., r.ymax() ); - double s = std::max( -90., r.ymin() ); - double w = zonal ? 0. : r.xmin(); - double e = zonal ? 360. : r.xmax(); - - return {n, w, s, e}; + return {r.ymax(), r.xmin(), r.ymin(), r.xmax()}; } }; @@ -189,7 +179,9 @@ CASE("MIR-282") { { NiNj{ 149, 105}, Rotation(-76., 14.), BoundingBox{72., -32., 20., 42.} }, { NiNj{ 240, 240}, Rotation(-30., -5.), BoundingBox{ 9.875, -15., -20., 14.875} }, + { NiNj{ 13, 12}, Rotation(-15., 45.), BoundingBox{27.5, -46.5, -28, 1.5}, true }, { NiNj{ 321, 370}, Rotation(-15., 45.), BoundingBox{27.5, -46.5, -28, 1.5}, true }, + { NiNj{ 202, 235}, Rotation( 0., 130.), BoundingBox{32.75, -86.75, -37.75, -26.15}, false }, { NiNj{ 409, 309}, Rotation(-35., 15.), BoundingBox{36., -51., -41., 51.}, true }, From c067585270fc1628d98438cae93eb75c822b86d1 Mon Sep 17 00:00:00 2001 From: Pedro Maciel Date: Thu, 27 Jun 2019 23:35:46 +0100 Subject: [PATCH 38/86] MIR-4: Grid::boundingBox, Projection::boundingBox --- src/atlas/projection/detail/LonLatProjection.cc | 5 ++++- src/atlas/projection/detail/ProjectionImpl.cc | 5 ++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/atlas/projection/detail/LonLatProjection.cc b/src/atlas/projection/detail/LonLatProjection.cc index fae801d62..b84cfe602 100644 --- a/src/atlas/projection/detail/LonLatProjection.cc +++ b/src/atlas/projection/detail/LonLatProjection.cc @@ -218,11 +218,14 @@ Domain LonLatProjectionT::boundingBox( const Domain& domain ) const { max = PointLonLat::componentsMax( max, PointLonLat::add( middle, PointLonLat{h, 0} ) ); if ( is_approximately_lesser_or_equal( 360., max[0] - min[0] ) ) { crossesDateLine = true; - max[0] = min[0] + 360.; } } } } + + if ( crossesDateLine ) { + max[0] = min[0] + 360.; + } ATLAS_ASSERT( min < max ); diff --git a/src/atlas/projection/detail/ProjectionImpl.cc b/src/atlas/projection/detail/ProjectionImpl.cc index 71e7c7ed7..45a3d8510 100644 --- a/src/atlas/projection/detail/ProjectionImpl.cc +++ b/src/atlas/projection/detail/ProjectionImpl.cc @@ -310,11 +310,14 @@ Domain ProjectionImpl::boundingBox( const Domain& domain ) const { max = PointLonLat::componentsMax( max, PointLonLat::add( middle, PointLonLat{h, 0} ) ); if ( is_approximately_lesser_or_equal( 360., max[0] - min[0] ) ) { crossesDateLine = true; - max[0] = min[0] + 360.; } } } } + + if ( crossesDateLine ) { + max[0] = min[0] + 360.; + } ATLAS_ASSERT( min < max ); From 09aea4f0d3789f62d762f0541ad641e78daa0620 Mon Sep 17 00:00:00 2001 From: Pedro Maciel Date: Fri, 28 Jun 2019 00:02:13 +0100 Subject: [PATCH 39/86] MIR-4: Grid::boundingBox, Projection::boundingBox --- src/atlas/projection/detail/ProjectionImpl.cc | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/src/atlas/projection/detail/ProjectionImpl.cc b/src/atlas/projection/detail/ProjectionImpl.cc index 45a3d8510..b35a33b36 100644 --- a/src/atlas/projection/detail/ProjectionImpl.cc +++ b/src/atlas/projection/detail/ProjectionImpl.cc @@ -83,14 +83,7 @@ ProjectionImpl::DerivateFactory::DerivateFactory( const std::string& type ) { ( *m )[type] = this; } -ProjectionImpl::DerivateFactory::~DerivateFactory() { - eckit::AutoLock __lock( mtx ); - - for ( auto& i : *m ) { - delete i.second; - } - m->clear(); -} +ProjectionImpl::DerivateFactory::~DerivateFactory() = default; // -------------------------------------------------------------------------------------------------------------------- From 61427de4e0d0b09315e8a509c0bdf301b888ebf6 Mon Sep 17 00:00:00 2001 From: Pedro Maciel Date: Fri, 28 Jun 2019 12:31:01 +0100 Subject: [PATCH 40/86] MIR-4: Grid::boundingBox, Projection::boundingBox --- .../projection/detail/LonLatProjection.cc | 10 +-- src/atlas/projection/detail/ProjectionImpl.cc | 69 ++++++++++--------- src/atlas/projection/detail/ProjectionImpl.h | 23 ++++--- 3 files changed, 54 insertions(+), 48 deletions(-) diff --git a/src/atlas/projection/detail/LonLatProjection.cc b/src/atlas/projection/detail/LonLatProjection.cc index b84cfe602..4eac75657 100644 --- a/src/atlas/projection/detail/LonLatProjection.cc +++ b/src/atlas/projection/detail/LonLatProjection.cc @@ -106,10 +106,7 @@ Domain LonLatProjectionT::boundingBox( const Domain& domain ) const { PointXY A = corners[i]; PointXY B = corners[( i + 1 ) % corners.size()]; - // finite difference vector derivative (H is the perturbation vector) - const PointXY H{PointXY::mul( PointXY::normalize( PointXY::sub( B, A ) ), h )}; - std::unique_ptr derivate( DerivateFactory::build( "central", *this, H ) ); - + std::unique_ptr derivate( DerivateFactory::build( "central", *this, A, B ) ); double dAdy = derivate->d( A ).lat(); double dBdy = derivate->d( B ).lat(); @@ -187,10 +184,7 @@ Domain LonLatProjectionT::boundingBox( const Domain& domain ) const { PointXY A = corners[i]; PointXY B = corners[( i + 1 ) % corners.size()]; - // finite difference vector derivative (H is the perturbation vector) - const PointXY H{PointXY::mul( PointXY::normalize( PointXY::sub( B, A ) ), h )}; - std::unique_ptr derivate( DerivateFactory::build( "central", *this, H ) ); - + std::unique_ptr derivate( DerivateFactory::build( "central", *this, A, B ) ); double dAdx = derivate->d( A ).lon(); double dBdx = derivate->d( B ).lon(); diff --git a/src/atlas/projection/detail/ProjectionImpl.cc b/src/atlas/projection/detail/ProjectionImpl.cc index b35a33b36..a4524f5a8 100644 --- a/src/atlas/projection/detail/ProjectionImpl.cc +++ b/src/atlas/projection/detail/ProjectionImpl.cc @@ -35,7 +35,7 @@ namespace { template struct DerivateBuilder : public ProjectionImpl::DerivateFactory { DerivateBuilder( const std::string& type ) : DerivateFactory( type ) {} - ProjectionImpl::Derivate* make( const ProjectionImpl& p, PointLonLat H ) { return new T( p, H ); } + ProjectionImpl::Derivate* make( const ProjectionImpl& p, PointXY A, PointXY B, double h ) { return new T( p, A, B, h ); } }; static pthread_once_t once = PTHREAD_ONCE_INIT; @@ -50,16 +50,25 @@ static void init() { } // (anonymous namespace) ProjectionImpl::Derivate* ProjectionImpl::DerivateFactory::build( const std::string& type, const ProjectionImpl& p, - PointLonLat H ) { + PointXY A, PointXY B, double h ) { pthread_once( &once, init ); eckit::AutoLock __lock( mtx ); + ATLAS_ASSERT( 0. < h ); + if ( A.distance2( B ) < h * h ) { + struct DerivateDegenerate final : Derivate { + using Derivate::Derivate; + PointLonLat d( PointXY ) const override { return {}; } + }; + return new DerivateDegenerate( p, A, B, h ); + } + auto j = m->find( type ); if ( j == m->end() ) { list( Log::error() << "DerivateFactory: unknown '" << type << "', choices are: " ); throw_Exception( "DerivateFactory: unknown '" + type + "'", Here() ); } - return ( *j ).second->make( p, H ); + return ( *j ).second->make( p, A, B, h ); } void ProjectionImpl::DerivateFactory::list( std::ostream& out ) { @@ -87,39 +96,42 @@ ProjectionImpl::DerivateFactory::~DerivateFactory() = default; // -------------------------------------------------------------------------------------------------------------------- +ProjectionImpl::Derivate::Derivate( const ProjectionImpl& p, PointXY A, PointXY B, double h ) : + projection_( p ), + H_{PointXY::mul( PointXY::normalize( PointXY::sub( B, A ) ), h )}, + normH_( PointXY::norm( H_ ) ) {} + +ProjectionImpl::Derivate::~Derivate() = default; + namespace { struct DerivateForwards final : ProjectionImpl::Derivate { using Derivate::Derivate; - PointLonLat d( PointLonLat P ) const override { - PointXY A( P ); - PointXY B( PointXY::add( P, Derivate::H_ ) ); - Derivate::xy2lonlat( A.data() ); - Derivate::xy2lonlat( B.data() ); - return PointXY::div( PointXY::sub( B, A ), PointXY::norm( Derivate::H_ ) ); + PointLonLat d( PointXY P ) const override { + PointXY A( xy2lonlat( P ) ); + PointXY B( xy2lonlat( PointXY::add( P, H_ ) ) ); + return PointXY::div( PointXY::sub( B, A ), normH_ ); } }; struct DerivateBackwards final : ProjectionImpl::Derivate { using Derivate::Derivate; - PointLonLat d( PointLonLat P ) const override { - PointXY A( PointXY::sub( P, Derivate::H_ ) ); - PointXY B( P ); - Derivate::xy2lonlat( A.data() ); - Derivate::xy2lonlat( B.data() ); - return PointXY::div( PointXY::sub( B, A ), PointXY::norm( Derivate::H_ ) ); + PointLonLat d( PointXY P ) const override { + PointXY A( xy2lonlat( PointXY::sub( P, H_ ) ) ); + PointXY B( xy2lonlat( P ) ); + return PointXY::div( PointXY::sub( B, A ), normH_ ); } }; struct DerivateCentral final : ProjectionImpl::Derivate { - using Derivate::Derivate; - PointLonLat d( PointLonLat P ) const override { - PointXY H2( PointXY::mul( Derivate::H_, 0.5 ) ); - PointXY A( PointXY::sub( P, H2 ) ); - PointXY B( PointXY::add( P, H2 ) ); - Derivate::xy2lonlat( A.data() ); - Derivate::xy2lonlat( B.data() ); - return PointXY::div( PointXY::sub( B, A ), PointXY::norm( Derivate::H_ ) ); + DerivateCentral( const ProjectionImpl& p, PointXY A, PointXY B, double h ) : + Derivate( p, A, B, h ), + H2_{PointXY::mul( H_, 0.5 )} {} + const PointXY H2_; + PointLonLat d( PointXY P ) const override { + PointXY A( xy2lonlat( PointXY::sub( P, H2_ ) ) ); + PointXY B( xy2lonlat( PointXY::add( P, H2_ ) ) ); + return PointXY::div( PointXY::sub( B, A ), normH_ ); } }; @@ -215,10 +227,7 @@ Domain ProjectionImpl::boundingBox( const Domain& domain ) const { PointXY A = corners[i]; PointXY B = corners[( i + 1 ) % corners.size()]; - // finite difference vector derivative (H is the perturbation vector) - const PointXY H{PointXY::mul( PointXY::normalize( PointXY::sub( B, A ) ), h )}; - std::unique_ptr derivate( DerivateFactory::build( "central", *this, H ) ); - + std::unique_ptr derivate( DerivateFactory::build( "central", *this, A, B ) ); double dAdy = derivate->d( A ).lat(); double dBdy = derivate->d( B ).lat(); @@ -271,10 +280,7 @@ Domain ProjectionImpl::boundingBox( const Domain& domain ) const { PointXY A = corners[i]; PointXY B = corners[( i + 1 ) % corners.size()]; - // finite difference vector derivative (H is the perturbation vector) - const PointXY H{PointXY::mul( PointXY::normalize( PointXY::sub( B, A ) ), h )}; - std::unique_ptr derivate( DerivateFactory::build( "central", *this, H ) ); - + std::unique_ptr derivate( DerivateFactory::build( "central", *this, A, B ) ); double dAdx = derivate->d( A ).lon(); double dBdx = derivate->d( B ).lon(); @@ -341,7 +347,6 @@ void Rotated::hash( eckit::Hash& hsh ) const { hsh.add( rotationAngle() ); } - } // namespace detail } // namespace projection } // namespace atlas diff --git a/src/atlas/projection/detail/ProjectionImpl.h b/src/atlas/projection/detail/ProjectionImpl.h index de09043e4..d65ff5d68 100644 --- a/src/atlas/projection/detail/ProjectionImpl.h +++ b/src/atlas/projection/detail/ProjectionImpl.h @@ -63,23 +63,30 @@ class ProjectionImpl : public util::Object { virtual void hash( eckit::Hash& ) const = 0; struct Derivate { - Derivate( const ProjectionImpl& p, PointLonLat H ) : projection_( p ), H_( H ) {} - virtual PointLonLat d( PointLonLat ) const = 0; + Derivate( const ProjectionImpl& p, PointXY A, PointXY B, double h ); + virtual ~Derivate(); + virtual PointLonLat d( PointXY ) const = 0; + protected: const ProjectionImpl& projection_; - const PointLonLat H_; - void xy2lonlat( double crd[] ) const { projection_.xy2lonlat( crd ); } + const PointXY H_; + const double normH_; + PointLonLat xy2lonlat( const PointXY& p ) const { + PointLonLat q( p ); + projection_.xy2lonlat( q.data() ); + return q; + } }; struct DerivateFactory { - static ProjectionImpl::Derivate* build( const std::string& type, const ProjectionImpl& p, PointLonLat H ); + static ProjectionImpl::Derivate* build( const std::string& type, const ProjectionImpl& p, PointXY A, PointXY B, + double h = 0.001 ); static void list( std::ostream& out ); protected: DerivateFactory( const std::string& ); - virtual ProjectionImpl::Derivate* make( const ProjectionImpl& p, PointLonLat H ) = 0; + virtual ProjectionImpl::Derivate* make( const ProjectionImpl& p, PointXY A, PointXY B, double h ) = 0; virtual ~DerivateFactory(); - }; -}; + };}; inline PointLonLat ProjectionImpl::lonlat( const PointXY& xy ) const { PointLonLat lonlat( xy ); From 0d35a37d4a3ba91b6f367272320ae7f1c7295630 Mon Sep 17 00:00:00 2001 From: Pedro Maciel Date: Fri, 28 Jun 2019 13:47:41 +0100 Subject: [PATCH 41/86] MIR-4: Grid::boundingBox, Projection::boundingBox --- .../projection/detail/LonLatProjection.cc | 105 +++--------- .../projection/detail/LonLatProjection.h | 3 - src/atlas/projection/detail/ProjectionImpl.cc | 158 +++++++++--------- src/atlas/projection/detail/ProjectionImpl.h | 21 +++ 4 files changed, 125 insertions(+), 162 deletions(-) diff --git a/src/atlas/projection/detail/LonLatProjection.cc b/src/atlas/projection/detail/LonLatProjection.cc index 4eac75657..36dbda4f5 100644 --- a/src/atlas/projection/detail/LonLatProjection.cc +++ b/src/atlas/projection/detail/LonLatProjection.cc @@ -31,28 +31,10 @@ LonLatProjectionT::LonLatProjectionT( const eckit::Parametrisation& co rotation_( config ) {} template <> -PointLonLat LonLatProjectionT::rotate( const PointXY& p ) const { - return {p}; -} +void LonLatProjectionT::xy2lonlat( double[] ) const {} template <> -PointXY LonLatProjectionT::unrotate( const PointLonLat& q ) const { - return {q}; -} - -template -PointLonLat LonLatProjectionT::rotate( const PointXY& p ) const { - PointLonLat q( p ); - this->xy2lonlat( q.data() ); - return q; -} - -template -PointXY LonLatProjectionT::unrotate( const PointLonLat& q ) const { - PointLonLat p( q ); - this->lonlat2xy( p.data() ); - return p; -} +void LonLatProjectionT::lonlat2xy( double[] ) const {} template <> Domain LonLatProjectionT::boundingBox( const Domain& domain ) const { @@ -61,9 +43,9 @@ Domain LonLatProjectionT::boundingBox( const Domain& domain ) const template Domain LonLatProjectionT::boundingBox( const Domain& domain ) const { - using eckit::types::is_approximately_lesser_or_equal; using eckit::types::is_strictly_greater; + // 0. setup if ( domain.global() ) { @@ -72,37 +54,32 @@ Domain LonLatProjectionT::boundingBox( const Domain& domain ) const { RectangularDomain rect( domain ); ATLAS_ASSERT( rect ); - PointLonLat min; - PointLonLat max; constexpr double h = 0.001; constexpr size_t Niter = 100; - // 1. determine box from rotated corners + + // 1. determine box from projected corners const std::vector corners{ {rect.xmin(), rect.ymax()}, {rect.xmax(), rect.ymax()}, {rect.xmax(), rect.ymin()}, {rect.xmin(), rect.ymin()}}; - bool first = true; + BoundLonLat bounds; for ( auto& p : corners ) { - PointLonLat r( rotate( p ) ); - auto rmin = PointLonLat::sub( r, PointLonLat{h, h} ); - auto rmax = PointLonLat::add( r, PointLonLat{h, h} ); - min = first ? rmin : PointLonLat::componentsMin( min, rmin ); - max = first ? rmax : PointLonLat::componentsMax( max, rmax ); - first = false; + bounds.extend( lonlat( p ), PointLonLat{h, h} ); } - // 2. locate latitude extrema by checking if poles are included (in the unrotated frame) and if not, find extrema + + // 2. locate latitude extrema by checking if poles are included (in the un-projected frame) and if not, find extrema // not at the corners by refining iteratively - PointXY NP{unrotate( {0., 90.} )}; - PointXY SP{unrotate( {0., -90.} )}; + PointXY NP{xy( {0., 90.} )}; + PointXY SP{xy( {0., -90.} )}; - bool includesNorthPole = rect.contains( NP ); - bool includesSouthPole = rect.contains( SP ); + bounds.includesNorthPole( rect.contains( NP ) ); + bounds.includesSouthPole( rect.contains( SP ) ); for ( size_t i = 0; i < corners.size(); ++i ) { - if ( !includesNorthPole || !includesSouthPole ) { + if ( !bounds.includesNorthPole() || !bounds.includesSouthPole() ) { PointXY A = corners[i]; PointXY B = corners[( i + 1 ) % corners.size()]; @@ -128,40 +105,24 @@ Domain LonLatProjectionT::boundingBox( const Domain& domain ) const { } // update extrema, extended by 'a small amount' (arbitrary) - PointLonLat middle( rotate( PointXY::middle( A, B ) ) ); - - min = PointLonLat::componentsMin( min, PointLonLat::sub( middle, PointLonLat{0, h} ) ); - if ( includesSouthPole || is_approximately_lesser_or_equal( min[1], -90. ) ) { - includesSouthPole = true; - min[1] = -90.; - } - - max = PointLonLat::componentsMax( max, PointLonLat::add( middle, PointLonLat{0, h} ) ); - if ( includesNorthPole || is_approximately_lesser_or_equal( 90., max[1] ) ) { - includesNorthPole = true; - max[1] = 90.; - } + bounds.extend( lonlat( PointXY::middle( A, B ) ), PointLonLat{0, h} ); } } } - ATLAS_ASSERT( min < max ); - // 3. locate latitude extrema by checking if date line is crossed (in the - // unrotated frame), in which case we assume periodicity and if not, find - // extrema not at the corners by refining iteratively + // 3. locate latitude extrema by checking if date line is crossed (in the un-projected frame), in which case we + // assume periodicity and if not, find extrema not at the corners by refining iteratively - bool crossesDateLine = includesNorthPole || includesSouthPole; - - if ( !crossesDateLine ) { - PointLonLat A{unrotate( {180., -10} )}; - PointLonLat B{unrotate( {180., 10} )}; + if ( !bounds.crossesDateLine() ) { + PointLonLat A{xy( {180., -10.} )}; + PointLonLat B{xy( {180., 10.} )}; eckit::geometry::GreatCircle DL( A, B ); for ( auto lon : {rect.xmin(), rect.xmax()} ) { - if ( !crossesDateLine ) { + if ( !bounds.crossesDateLine() ) { for ( auto lat : DL.latitude( lon ) ) { - if ( ( crossesDateLine = domain.contains( lon, lat ) ) ) { + if ( ( bounds.crossesDateLine( domain.contains( lon, lat ) ) ) ) { break; } } @@ -169,9 +130,9 @@ Domain LonLatProjectionT::boundingBox( const Domain& domain ) const { } for ( auto lat : {rect.ymin(), rect.ymax()} ) { - if ( !crossesDateLine ) { + if ( !bounds.crossesDateLine() ) { for ( auto lon : DL.longitude( lat ) ) { - if ( ( crossesDateLine = domain.contains( lon, lat ) ) ) { + if ( ( bounds.crossesDateLine( domain.contains( lon, lat ) ) ) ) { break; } } @@ -180,7 +141,7 @@ Domain LonLatProjectionT::boundingBox( const Domain& domain ) const { } for ( size_t i = 0; i < corners.size(); ++i ) { - if ( !crossesDateLine ) { + if ( !bounds.crossesDateLine() ) { PointXY A = corners[i]; PointXY B = corners[( i + 1 ) % corners.size()]; @@ -206,26 +167,14 @@ Domain LonLatProjectionT::boundingBox( const Domain& domain ) const { } // update extrema, extended by 'a small amount' (arbitrary) - PointLonLat middle( rotate( PointXY::middle( A, B ) ) ); - - min = PointLonLat::componentsMin( min, PointLonLat::sub( middle, PointLonLat{h, 0} ) ); - max = PointLonLat::componentsMax( max, PointLonLat::add( middle, PointLonLat{h, 0} ) ); - if ( is_approximately_lesser_or_equal( 360., max[0] - min[0] ) ) { - crossesDateLine = true; - } + bounds.extend( lonlat( PointXY::middle( A, B ) ), PointLonLat{h, 0} ); } } } - if ( crossesDateLine ) { - max[0] = min[0] + 360.; - } - ATLAS_ASSERT( min < max ); - // 4. return bounding box - return crossesDateLine ? ZonalBandDomain( {min[1], max[1]} ) - : RectangularDomain( {min[0], max[0]}, {min[1], max[1]} ); + return bounds; } template diff --git a/src/atlas/projection/detail/LonLatProjection.h b/src/atlas/projection/detail/LonLatProjection.h index 93af45f38..e450e9803 100644 --- a/src/atlas/projection/detail/LonLatProjection.h +++ b/src/atlas/projection/detail/LonLatProjection.h @@ -55,9 +55,6 @@ class LonLatProjectionT final : public ProjectionImpl { private: Rotation rotation_; - - PointLonLat rotate( const PointXY& ) const; - PointXY unrotate( const PointLonLat& ) const; }; using LonLatProjection = LonLatProjectionT; diff --git a/src/atlas/projection/detail/ProjectionImpl.cc b/src/atlas/projection/detail/ProjectionImpl.cc index a4524f5a8..3e69204f1 100644 --- a/src/atlas/projection/detail/ProjectionImpl.cc +++ b/src/atlas/projection/detail/ProjectionImpl.cc @@ -96,6 +96,57 @@ ProjectionImpl::DerivateFactory::~DerivateFactory() = default; // -------------------------------------------------------------------------------------------------------------------- +ProjectionImpl::BoundLonLat::operator Domain() const { + return RectangularDomain( {min_[0], max_[0]}, {min_[1], max_[1]}, "degrees" ); +} + +bool ProjectionImpl::BoundLonLat::crossesDateLine( bool yes ) { + if ( ( crossesDateLine_ = crossesDateLine_ || yes ) ) { + max_.lon() = min_.lon() + 360.; + } + return crossesDateLine_; +} + +bool ProjectionImpl::BoundLonLat::includesNorthPole( bool yes ) { + if ( ( includesNorthPole_ = includesNorthPole_ || yes ) ) { + max_.lat() = 90.; + } + crossesDateLine( includesNorthPole_ ); + return includesNorthPole_; +} + +bool ProjectionImpl::BoundLonLat::includesSouthPole( bool yes ) { + if ( ( includesSouthPole_ = includesSouthPole_ || yes ) ) { + min_.lat() = -90.; + } + crossesDateLine( includesSouthPole_ ); + return includesSouthPole_; +} + +void ProjectionImpl::BoundLonLat::extend( PointLonLat p, PointLonLat eps ) { + ATLAS_ASSERT( PointLonLat{} < eps ); + if ( first_ ) { + min_ = PointLonLat::sub( p, eps ); + max_ = PointLonLat::add( p, eps ); + first_ = false; + return; + } + + min_ = PointLonLat::componentsMin( min_, PointLonLat::sub( p, eps ) ); + max_ = PointLonLat::componentsMax( max_, PointLonLat::add( p, eps ) ); + + min_.lat() = std::max( min_.lat(), -90. ); + max_.lat() = std::min( max_.lat(), 90. ); + max_.lon() = std::min( max_.lon(), min_.lon() + 360. ); + ATLAS_ASSERT( min_ < max_ ); + + includesSouthPole(eckit::types::is_approximately_equal( min_.lat(), -90. )); + includesNorthPole(eckit::types::is_approximately_equal( max_.lat(), 90. )); + crossesDateLine(eckit::types::is_approximately_equal( max_.lon() - min_.lon(), 360. )); +} + +// -------------------------------------------------------------------------------------------------------------------- + ProjectionImpl::Derivate::Derivate( const ProjectionImpl& p, PointXY A, PointXY B, double h ) : projection_( p ), H_{PointXY::mul( PointXY::normalize( PointXY::sub( B, A ) ), h )}, @@ -152,9 +203,9 @@ const ProjectionImpl* ProjectionImpl::create( const eckit::Parametrisation& p ) } Domain ProjectionImpl::boundingBox( const Domain& domain ) const { - using eckit::types::is_approximately_lesser_or_equal; using eckit::types::is_strictly_greater; + // 0. setup if ( domain.global() ) { @@ -163,67 +214,43 @@ Domain ProjectionImpl::boundingBox( const Domain& domain ) const { RectangularDomain rect( domain ); ATLAS_ASSERT( rect ); - PointLonLat min; - PointLonLat max; constexpr double h = 0.001; constexpr size_t Niter = 100; - // 1. determine box from projected/rotated corners + + // 1. determine box from projected corners const std::vector corners{ {rect.xmin(), rect.ymax()}, {rect.xmax(), rect.ymax()}, {rect.xmax(), rect.ymin()}, {rect.xmin(), rect.ymin()}}; - bool first = true; + BoundLonLat bounds; for ( auto& p : corners ) { - PointLonLat r( p ); - xy2lonlat( r.data() ); - auto rmin = PointLonLat::sub( r, PointLonLat{h, h} ); - auto rmax = PointLonLat::add( r, PointLonLat{h, h} ); - min = first ? rmin : PointLonLat::componentsMin( min, rmin ); - max = first ? rmax : PointLonLat::componentsMax( max, rmax ); - first = false; + bounds.extend( lonlat( p ), PointLonLat{h, h} ); } - struct crosses_t { - crosses_t( const ProjectionImpl& projection, const PointXY& p1, const PointXY& p2, const PointXY& p3, - const PointXY& p4 ) : - projection_( projection ), - quadrilateral_( xy_to_xyz( projection, p1 ), xy_to_xyz( projection, p2 ), xy_to_xyz( projection, p3 ), - xy_to_xyz( projection, p4 ) ) {} - bool operator()( const PointXY& p ) { - interpolation::method::Ray r( xy_to_xyz( projection_, p ) ); - return quadrilateral_.intersects( r ); - } + // 2. locate latitude extrema by checking if poles are included (in the un-projected frame) and if not, find extrema + // not at the corners by refining iteratively - private: - const ProjectionImpl& projection_; - interpolation::element::Quad3D quadrilateral_; + auto xyz = [=]( const PointXY& p ) -> PointXYZ { + static auto& projection( *this ); + PointXYZ r; + util::Earth::convertSphericalToCartesian( projection.lonlat( p ), r ); + return r; + }; - static PointXYZ xy_to_xyz( const ProjectionImpl& projection, const PointXY& p ) { - PointLonLat q( p ); - projection.xy2lonlat( q.data() ); + using interpolation::element::Quad3D; + using interpolation::method::Ray; + const Quad3D quad( xyz( corners[0] ), xyz( corners[1] ), xyz( corners[2] ), xyz( corners[3] ) ); - PointXYZ r; - util::Earth::convertSphericalToCartesian( q, r ); - return r; - } - } crosses( *this, corners[0], corners[1], corners[2], corners[3] ); + PointXY NP{xy( {0., 90.} )}; + PointXY SP{xy( {0., -90.} )}; - - // 2. locate latitude extrema by checking if poles are included (in the unrotated/un-projected frame) and if not, - // find extrema not at the corners by refining iteratively - - PointXY NP{0, 90}; - PointXY SP{0, -90}; - lonlat2xy( NP.data() ); // unrotate/un-project - lonlat2xy( SP.data() ); - - bool includesNorthPole = crosses( NP ); - bool includesSouthPole = crosses( SP ); + bounds.includesNorthPole( quad.intersects( Ray( xyz( NP ) ) ) ); + bounds.includesNorthPole( quad.intersects( Ray( xyz( SP ) ) ) ); for ( size_t i = 0; i < corners.size(); ++i ) { - if ( !includesNorthPole || !includesSouthPole ) { + if ( !bounds.includesNorthPole() || !bounds.includesSouthPole() ) { PointXY A = corners[i]; PointXY B = corners[( i + 1 ) % corners.size()]; @@ -249,34 +276,16 @@ Domain ProjectionImpl::boundingBox( const Domain& domain ) const { } // update extrema, extended by 'a small amount' (arbitrary) - PointLonLat middle( PointXY::middle( A, B ) ); - xy2lonlat( middle.data() ); - - min = PointLonLat::componentsMin( min, PointLonLat::sub( middle, PointLonLat{0, h} ) ); - if ( includesSouthPole || is_approximately_lesser_or_equal( min[1], -90. ) ) { - includesSouthPole = true; - min[1] = -90.; - } - - max = PointLonLat::componentsMax( max, PointLonLat::add( middle, PointLonLat{0, h} ) ); - if ( includesNorthPole || is_approximately_lesser_or_equal( 90., max[1] ) ) { - includesNorthPole = true; - max[1] = 90.; - } + bounds.extend( lonlat( PointXY::middle( A, B ) ), PointLonLat{0, h} ); } } } - ATLAS_ASSERT( min < max ); - - // 3. locate latitude extrema by checking if date line is crossed (in the - // projected/rotated frame), in which case we assume periodicity and if not, find - // extrema not at the corners by refining iteratively - bool crossesDateLine = includesNorthPole || includesSouthPole; + // 3. locate latitude extrema not at the corners by refining iteratively for ( size_t i = 0; i < corners.size(); ++i ) { - if ( !crossesDateLine ) { + if ( !bounds.crossesDateLine() ) { PointXY A = corners[i]; PointXY B = corners[( i + 1 ) % corners.size()]; @@ -302,27 +311,14 @@ Domain ProjectionImpl::boundingBox( const Domain& domain ) const { } // update extrema, extended by 'a small amount' (arbitrary) - PointLonLat middle( PointXY::middle( A, B ) ); - xy2lonlat( middle.data() ); - - min = PointLonLat::componentsMin( min, PointLonLat::sub( middle, PointLonLat{h, 0} ) ); - max = PointLonLat::componentsMax( max, PointLonLat::add( middle, PointLonLat{h, 0} ) ); - if ( is_approximately_lesser_or_equal( 360., max[0] - min[0] ) ) { - crossesDateLine = true; - } + bounds.extend( lonlat( PointXY::middle( A, B ) ), PointLonLat{h, 0} ); } } } - if ( crossesDateLine ) { - max[0] = min[0] + 360.; - } - ATLAS_ASSERT( min < max ); - // 4. return bounding box - return crossesDateLine ? ZonalBandDomain( {min[1], max[1]} ) - : RectangularDomain( {min[0], max[0]}, {min[1], max[1]} ); + return bounds; } //--------------------------------------------------------------------------------------------------------------------- diff --git a/src/atlas/projection/detail/ProjectionImpl.h b/src/atlas/projection/detail/ProjectionImpl.h index d65ff5d68..48594700d 100644 --- a/src/atlas/projection/detail/ProjectionImpl.h +++ b/src/atlas/projection/detail/ProjectionImpl.h @@ -62,6 +62,27 @@ class ProjectionImpl : public util::Object { virtual void hash( eckit::Hash& ) const = 0; + struct BoundLonLat { + operator Domain() const; + void extend( PointLonLat p, PointLonLat eps ); + + bool crossesDateLine( bool ); + bool includesNorthPole( bool ); + bool includesSouthPole( bool ); + + bool crossesDateLine() const { return crossesDateLine_; } + bool includesNorthPole() const { return includesNorthPole_; } + bool includesSouthPole() const { return includesSouthPole_; } + + private: + PointLonLat min_; + PointLonLat max_; + bool crossesDateLine_ = false; + bool includesNorthPole_ = false; + bool includesSouthPole_ = false; + bool first_ = true; + }; + struct Derivate { Derivate( const ProjectionImpl& p, PointXY A, PointXY B, double h ); virtual ~Derivate(); From 5c823cde1fcc35f139da887d50b1130dc07665a7 Mon Sep 17 00:00:00 2001 From: Pedro Maciel Date: Fri, 28 Jun 2019 16:10:58 +0100 Subject: [PATCH 42/86] MIR-4: Grid::boundingBox, Projection::boundingBox --- src/atlas/projection/detail/ProjectionImpl.cc | 45 ++++++++++--------- 1 file changed, 25 insertions(+), 20 deletions(-) diff --git a/src/atlas/projection/detail/ProjectionImpl.cc b/src/atlas/projection/detail/ProjectionImpl.cc index 3e69204f1..754c9233d 100644 --- a/src/atlas/projection/detail/ProjectionImpl.cc +++ b/src/atlas/projection/detail/ProjectionImpl.cc @@ -35,16 +35,18 @@ namespace { template struct DerivateBuilder : public ProjectionImpl::DerivateFactory { DerivateBuilder( const std::string& type ) : DerivateFactory( type ) {} - ProjectionImpl::Derivate* make( const ProjectionImpl& p, PointXY A, PointXY B, double h ) { return new T( p, A, B, h ); } + ProjectionImpl::Derivate* make( const ProjectionImpl& p, PointXY A, PointXY B, double h ) { + return new T( p, A, B, h ); + } }; static pthread_once_t once = PTHREAD_ONCE_INIT; -static eckit::Mutex* mtx = nullptr; +static eckit::Mutex* mtx = nullptr; static std::map* m = nullptr; static void init() { mtx = new eckit::Mutex(); - m = new std::map(); + m = new std::map(); } } // (anonymous namespace) @@ -140,9 +142,9 @@ void ProjectionImpl::BoundLonLat::extend( PointLonLat p, PointLonLat eps ) { max_.lon() = std::min( max_.lon(), min_.lon() + 360. ); ATLAS_ASSERT( min_ < max_ ); - includesSouthPole(eckit::types::is_approximately_equal( min_.lat(), -90. )); - includesNorthPole(eckit::types::is_approximately_equal( max_.lat(), 90. )); - crossesDateLine(eckit::types::is_approximately_equal( max_.lon() - min_.lon(), 360. )); + includesSouthPole( eckit::types::is_approximately_equal( min_.lat(), -90. ) ); + includesNorthPole( eckit::types::is_approximately_equal( max_.lat(), 90. ) ); + crossesDateLine( eckit::types::is_approximately_equal( max_.lon() - min_.lon(), 360. ) ); } // -------------------------------------------------------------------------------------------------------------------- @@ -196,7 +198,9 @@ DerivateBuilder __derivate3( "central" ); const ProjectionImpl* ProjectionImpl::create( const eckit::Parametrisation& p ) { std::string projectionType; - if ( p.get( "type", projectionType ) ) { return ProjectionFactory::build( projectionType, p ); } + if ( p.get( "type", projectionType ) ) { + return ProjectionFactory::build( projectionType, p ); + } // should return error here throw_Exception( "type missing in Params", Here() ); @@ -232,22 +236,23 @@ Domain ProjectionImpl::boundingBox( const Domain& domain ) const { // 2. locate latitude extrema by checking if poles are included (in the un-projected frame) and if not, find extrema // not at the corners by refining iteratively - auto xyz = [=]( const PointXY& p ) -> PointXYZ { - static auto& projection( *this ); - PointXYZ r; - util::Earth::convertSphericalToCartesian( projection.lonlat( p ), r ); - return r; - }; + { + auto xyz = [=]( const PointXY& p ) -> PointXYZ { + PointXYZ r; + util::Earth::convertSphericalToCartesian( this->lonlat( p ), r ); + return r; + }; - using interpolation::element::Quad3D; - using interpolation::method::Ray; - const Quad3D quad( xyz( corners[0] ), xyz( corners[1] ), xyz( corners[2] ), xyz( corners[3] ) ); + using interpolation::element::Quad3D; + using interpolation::method::Ray; + const Quad3D quad( xyz( corners[0] ), xyz( corners[1] ), xyz( corners[2] ), xyz( corners[3] ) ); - PointXY NP{xy( {0., 90.} )}; - PointXY SP{xy( {0., -90.} )}; + PointXY NP{xy( {0., 90.} )}; + PointXY SP{xy( {0., -90.} )}; - bounds.includesNorthPole( quad.intersects( Ray( xyz( NP ) ) ) ); - bounds.includesNorthPole( quad.intersects( Ray( xyz( SP ) ) ) ); + bounds.includesNorthPole( quad.intersects( Ray( xyz( NP ) ) ) ); + bounds.includesNorthPole( quad.intersects( Ray( xyz( SP ) ) ) ); + } for ( size_t i = 0; i < corners.size(); ++i ) { if ( !bounds.includesNorthPole() || !bounds.includesSouthPole() ) { From c0f6e641ec8883b0bbd30533f7c5a69eaf902beb Mon Sep 17 00:00:00 2001 From: Pedro Maciel Date: Fri, 28 Jun 2019 17:29:13 +0100 Subject: [PATCH 43/86] MIR-4: Grid::boundingBox, Projection::boundingBox --- src/atlas/projection/detail/ProjectionImpl.cc | 143 ++++++------------ src/atlas/projection/detail/ProjectionImpl.h | 13 +- 2 files changed, 56 insertions(+), 100 deletions(-) diff --git a/src/atlas/projection/detail/ProjectionImpl.cc b/src/atlas/projection/detail/ProjectionImpl.cc index 754c9233d..a4ec53280 100644 --- a/src/atlas/projection/detail/ProjectionImpl.cc +++ b/src/atlas/projection/detail/ProjectionImpl.cc @@ -10,7 +10,6 @@ #include -#include "eckit/thread/AutoLock.h" #include "eckit/types/FloatCompare.h" #include "eckit/utils/Hash.h" @@ -34,29 +33,60 @@ namespace { template struct DerivateBuilder : public ProjectionImpl::DerivateFactory { - DerivateBuilder( const std::string& type ) : DerivateFactory( type ) {} + using DerivateFactory::DerivateFactory; ProjectionImpl::Derivate* make( const ProjectionImpl& p, PointXY A, PointXY B, double h ) { return new T( p, A, B, h ); } }; -static pthread_once_t once = PTHREAD_ONCE_INIT; -static eckit::Mutex* mtx = nullptr; +struct DerivateForwards final : ProjectionImpl::Derivate { + using Derivate::Derivate; + PointLonLat d( PointXY P ) const override { + PointXY A( xy2lonlat( P ) ); + PointXY B( xy2lonlat( PointXY::add( P, H_ ) ) ); + return PointXY::div( PointXY::sub( B, A ), normH_ ); + } +}; -static std::map* m = nullptr; -static void init() { - mtx = new eckit::Mutex(); - m = new std::map(); -} +struct DerivateBackwards final : ProjectionImpl::Derivate { + using Derivate::Derivate; + PointLonLat d( PointXY P ) const override { + PointXY A( xy2lonlat( PointXY::sub( P, H_ ) ) ); + PointXY B( xy2lonlat( P ) ); + return PointXY::div( PointXY::sub( B, A ), normH_ ); + } +}; + +struct DerivateCentral final : ProjectionImpl::Derivate { + DerivateCentral( const ProjectionImpl& p, PointXY A, PointXY B, double h ) : + Derivate( p, A, B, h ), + H2_{PointXY::mul( H_, 0.5 )} {} + const PointXY H2_; + PointLonLat d( PointXY P ) const override { + PointXY A( xy2lonlat( PointXY::sub( P, H2_ ) ) ); + PointXY B( xy2lonlat( PointXY::add( P, H2_ ) ) ); + return PointXY::div( PointXY::sub( B, A ), normH_ ); + } +}; } // (anonymous namespace) +ProjectionImpl::Derivate::Derivate( const ProjectionImpl& p, PointXY A, PointXY B, double h ) : + projection_( p ), + H_{PointXY::mul( PointXY::normalize( PointXY::sub( B, A ) ), h )}, + normH_( PointXY::norm( H_ ) ) {} + +ProjectionImpl::Derivate::~Derivate() = default; + ProjectionImpl::Derivate* ProjectionImpl::DerivateFactory::build( const std::string& type, const ProjectionImpl& p, PointXY A, PointXY B, double h ) { - pthread_once( &once, init ); - eckit::AutoLock __lock( mtx ); - ATLAS_ASSERT( 0. < h ); + + // force_link + static DerivateBuilder __derivate1( "forwards" ); + static DerivateBuilder __derivate2( "backwards" ); + static DerivateBuilder __derivate3( "central" ); + if ( A.distance2( B ) < h * h ) { struct DerivateDegenerate final : Derivate { using Derivate::Derivate; @@ -65,33 +95,8 @@ ProjectionImpl::Derivate* ProjectionImpl::DerivateFactory::build( const std::str return new DerivateDegenerate( p, A, B, h ); } - auto j = m->find( type ); - if ( j == m->end() ) { - list( Log::error() << "DerivateFactory: unknown '" << type << "', choices are: " ); - throw_Exception( "DerivateFactory: unknown '" + type + "'", Here() ); - } - return ( *j ).second->make( p, A, B, h ); -} - -void ProjectionImpl::DerivateFactory::list( std::ostream& out ) { - pthread_once( &once, init ); - eckit::AutoLock __lock( mtx ); - - const char* sep = ""; - for ( const auto& j : *m ) { - out << sep << j.first; - sep = ", "; - } -} - -ProjectionImpl::DerivateFactory::DerivateFactory( const std::string& type ) { - pthread_once( &once, init ); - eckit::AutoLock __lock( mtx ); - - if ( m->find( type ) != m->end() ) { - throw_Exception( "DerivateFactory: duplicate '" + type + "'", Here() ); - } - ( *m )[type] = this; + auto factory = get( type ); + return factory->make( p, A, B, h); } ProjectionImpl::DerivateFactory::~DerivateFactory() = default; @@ -127,15 +132,12 @@ bool ProjectionImpl::BoundLonLat::includesSouthPole( bool yes ) { void ProjectionImpl::BoundLonLat::extend( PointLonLat p, PointLonLat eps ) { ATLAS_ASSERT( PointLonLat{} < eps ); - if ( first_ ) { - min_ = PointLonLat::sub( p, eps ); - max_ = PointLonLat::add( p, eps ); - first_ = false; - return; - } - min_ = PointLonLat::componentsMin( min_, PointLonLat::sub( p, eps ) ); - max_ = PointLonLat::componentsMax( max_, PointLonLat::add( p, eps ) ); + auto sub = PointLonLat::sub( p, eps ); + auto add = PointLonLat::add( p, eps ); + min_ = first_ ? sub : PointLonLat::componentsMin( min_, sub ); + max_ = first_ ? add : PointLonLat::componentsMax( max_, add ); + first_ = false; min_.lat() = std::max( min_.lat(), -90. ); max_.lat() = std::min( max_.lat(), 90. ); @@ -149,53 +151,6 @@ void ProjectionImpl::BoundLonLat::extend( PointLonLat p, PointLonLat eps ) { // -------------------------------------------------------------------------------------------------------------------- -ProjectionImpl::Derivate::Derivate( const ProjectionImpl& p, PointXY A, PointXY B, double h ) : - projection_( p ), - H_{PointXY::mul( PointXY::normalize( PointXY::sub( B, A ) ), h )}, - normH_( PointXY::norm( H_ ) ) {} - -ProjectionImpl::Derivate::~Derivate() = default; - -namespace { - -struct DerivateForwards final : ProjectionImpl::Derivate { - using Derivate::Derivate; - PointLonLat d( PointXY P ) const override { - PointXY A( xy2lonlat( P ) ); - PointXY B( xy2lonlat( PointXY::add( P, H_ ) ) ); - return PointXY::div( PointXY::sub( B, A ), normH_ ); - } -}; - -struct DerivateBackwards final : ProjectionImpl::Derivate { - using Derivate::Derivate; - PointLonLat d( PointXY P ) const override { - PointXY A( xy2lonlat( PointXY::sub( P, H_ ) ) ); - PointXY B( xy2lonlat( P ) ); - return PointXY::div( PointXY::sub( B, A ), normH_ ); - } -}; - -struct DerivateCentral final : ProjectionImpl::Derivate { - DerivateCentral( const ProjectionImpl& p, PointXY A, PointXY B, double h ) : - Derivate( p, A, B, h ), - H2_{PointXY::mul( H_, 0.5 )} {} - const PointXY H2_; - PointLonLat d( PointXY P ) const override { - PointXY A( xy2lonlat( PointXY::sub( P, H2_ ) ) ); - PointXY B( xy2lonlat( PointXY::add( P, H2_ ) ) ); - return PointXY::div( PointXY::sub( B, A ), normH_ ); - } -}; - -DerivateBuilder __derivate1( "forwards" ); -DerivateBuilder __derivate2( "backwards" ); -DerivateBuilder __derivate3( "central" ); - -} // (anonymous namespace) - -// -------------------------------------------------------------------------------------------------------------------- - const ProjectionImpl* ProjectionImpl::create( const eckit::Parametrisation& p ) { std::string projectionType; if ( p.get( "type", projectionType ) ) { diff --git a/src/atlas/projection/detail/ProjectionImpl.h b/src/atlas/projection/detail/ProjectionImpl.h index 48594700d..7e61edae2 100644 --- a/src/atlas/projection/detail/ProjectionImpl.h +++ b/src/atlas/projection/detail/ProjectionImpl.h @@ -13,6 +13,7 @@ #include #include +#include "atlas/util/Factory.h" #include "atlas/util/Object.h" #include "atlas/util/Point.h" #include "atlas/util/Rotation.h" @@ -98,16 +99,16 @@ class ProjectionImpl : public util::Object { } }; - struct DerivateFactory { + struct DerivateFactory : public util::Factory { + static std::string className() { return "DerivateFactory"; } static ProjectionImpl::Derivate* build( const std::string& type, const ProjectionImpl& p, PointXY A, PointXY B, double h = 0.001 ); - static void list( std::ostream& out ); - protected: - DerivateFactory( const std::string& ); - virtual ProjectionImpl::Derivate* make( const ProjectionImpl& p, PointXY A, PointXY B, double h ) = 0; + using Factory::Factory; virtual ~DerivateFactory(); - };}; + virtual ProjectionImpl::Derivate* make( const ProjectionImpl& p, PointXY A, PointXY B, double h ) = 0; + }; +}; inline PointLonLat ProjectionImpl::lonlat( const PointXY& xy ) const { PointLonLat lonlat( xy ); From 9585221d6ca80adc6c600c9f3a30764265ec224c Mon Sep 17 00:00:00 2001 From: Pedro Maciel Date: Sun, 30 Jun 2019 10:53:07 +0100 Subject: [PATCH 44/86] MIR-4: Grid::boundingBox, Projection::boundingBox --- src/atlas/projection/detail/ProjectionImpl.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/atlas/projection/detail/ProjectionImpl.cc b/src/atlas/projection/detail/ProjectionImpl.cc index a4ec53280..6f0476347 100644 --- a/src/atlas/projection/detail/ProjectionImpl.cc +++ b/src/atlas/projection/detail/ProjectionImpl.cc @@ -206,7 +206,7 @@ Domain ProjectionImpl::boundingBox( const Domain& domain ) const { PointXY SP{xy( {0., -90.} )}; bounds.includesNorthPole( quad.intersects( Ray( xyz( NP ) ) ) ); - bounds.includesNorthPole( quad.intersects( Ray( xyz( SP ) ) ) ); + bounds.includesSouthPole( quad.intersects( Ray( xyz( SP ) ) ) ); } for ( size_t i = 0; i < corners.size(); ++i ) { From 348b0a3330a56b8f6a757e8daa318f3589304278 Mon Sep 17 00:00:00 2001 From: Pedro Maciel Date: Sun, 30 Jun 2019 11:25:31 +0100 Subject: [PATCH 45/86] MIR-4: Grid::boundingBox, Projection::boundingBox --- src/atlas/projection/detail/ProjectionImpl.cc | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/atlas/projection/detail/ProjectionImpl.cc b/src/atlas/projection/detail/ProjectionImpl.cc index 6f0476347..c133bfb54 100644 --- a/src/atlas/projection/detail/ProjectionImpl.cc +++ b/src/atlas/projection/detail/ProjectionImpl.cc @@ -131,7 +131,7 @@ bool ProjectionImpl::BoundLonLat::includesSouthPole( bool yes ) { } void ProjectionImpl::BoundLonLat::extend( PointLonLat p, PointLonLat eps ) { - ATLAS_ASSERT( PointLonLat{} < eps ); + ATLAS_ASSERT( 0. <= eps.lon() && 0. <= eps.lat() ); auto sub = PointLonLat::sub( p, eps ); auto add = PointLonLat::add( p, eps ); @@ -142,7 +142,7 @@ void ProjectionImpl::BoundLonLat::extend( PointLonLat p, PointLonLat eps ) { min_.lat() = std::max( min_.lat(), -90. ); max_.lat() = std::min( max_.lat(), 90. ); max_.lon() = std::min( max_.lon(), min_.lon() + 360. ); - ATLAS_ASSERT( min_ < max_ ); + ATLAS_ASSERT( min_.lon() <= max_.lon() && min_.lat() <= max_.lat() ); includesSouthPole( eckit::types::is_approximately_equal( min_.lat(), -90. ) ); includesNorthPole( eckit::types::is_approximately_equal( max_.lat(), 90. ) ); @@ -161,7 +161,7 @@ const ProjectionImpl* ProjectionImpl::create( const eckit::Parametrisation& p ) throw_Exception( "type missing in Params", Here() ); } -Domain ProjectionImpl::boundingBox( const Domain& domain ) const { +Domain ProjectionImpl::boundingBox(const Domain& domain , double epsLonLat) const { using eckit::types::is_strictly_greater; @@ -172,8 +172,8 @@ Domain ProjectionImpl::boundingBox( const Domain& domain ) const { } RectangularDomain rect( domain ); ATLAS_ASSERT( rect ); + ATLAS_ASSERT( epsLonLat >= 0. ); - constexpr double h = 0.001; constexpr size_t Niter = 100; @@ -184,7 +184,7 @@ Domain ProjectionImpl::boundingBox( const Domain& domain ) const { BoundLonLat bounds; for ( auto& p : corners ) { - bounds.extend( lonlat( p ), PointLonLat{h, h} ); + bounds.extend( lonlat( p ), PointLonLat{epsLonLat, epsLonLat} ); } @@ -236,7 +236,7 @@ Domain ProjectionImpl::boundingBox( const Domain& domain ) const { } // update extrema, extended by 'a small amount' (arbitrary) - bounds.extend( lonlat( PointXY::middle( A, B ) ), PointLonLat{0, h} ); + bounds.extend( lonlat( PointXY::middle( A, B ) ), PointLonLat{0, epsLonLat} ); } } } @@ -271,7 +271,7 @@ Domain ProjectionImpl::boundingBox( const Domain& domain ) const { } // update extrema, extended by 'a small amount' (arbitrary) - bounds.extend( lonlat( PointXY::middle( A, B ) ), PointLonLat{h, 0} ); + bounds.extend( lonlat( PointXY::middle( A, B ) ), PointLonLat{epsLonLat, 0} ); } } } From 90a742867f6e367e35d6226f3d5dc47454973b89 Mon Sep 17 00:00:00 2001 From: Pedro Maciel Date: Sun, 30 Jun 2019 11:31:44 +0100 Subject: [PATCH 46/86] MIR-4: Grid::boundingBox, Projection::boundingBox --- src/atlas/projection/detail/ProjectionImpl.cc | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/atlas/projection/detail/ProjectionImpl.cc b/src/atlas/projection/detail/ProjectionImpl.cc index c133bfb54..27a682fe8 100644 --- a/src/atlas/projection/detail/ProjectionImpl.cc +++ b/src/atlas/projection/detail/ProjectionImpl.cc @@ -161,7 +161,7 @@ const ProjectionImpl* ProjectionImpl::create( const eckit::Parametrisation& p ) throw_Exception( "type missing in Params", Here() ); } -Domain ProjectionImpl::boundingBox(const Domain& domain , double epsLonLat) const { +Domain ProjectionImpl::boundingBox( const Domain& domain ) const { using eckit::types::is_strictly_greater; @@ -172,8 +172,8 @@ Domain ProjectionImpl::boundingBox(const Domain& domain , double epsLonLat) cons } RectangularDomain rect( domain ); ATLAS_ASSERT( rect ); - ATLAS_ASSERT( epsLonLat >= 0. ); + constexpr double h = 0.001; constexpr size_t Niter = 100; @@ -184,7 +184,7 @@ Domain ProjectionImpl::boundingBox(const Domain& domain , double epsLonLat) cons BoundLonLat bounds; for ( auto& p : corners ) { - bounds.extend( lonlat( p ), PointLonLat{epsLonLat, epsLonLat} ); + bounds.extend( lonlat( p ), PointLonLat{h, h} ); } @@ -236,7 +236,7 @@ Domain ProjectionImpl::boundingBox(const Domain& domain , double epsLonLat) cons } // update extrema, extended by 'a small amount' (arbitrary) - bounds.extend( lonlat( PointXY::middle( A, B ) ), PointLonLat{0, epsLonLat} ); + bounds.extend( lonlat( PointXY::middle( A, B ) ), PointLonLat{0, h} ); } } } @@ -271,7 +271,7 @@ Domain ProjectionImpl::boundingBox(const Domain& domain , double epsLonLat) cons } // update extrema, extended by 'a small amount' (arbitrary) - bounds.extend( lonlat( PointXY::middle( A, B ) ), PointLonLat{epsLonLat, 0} ); + bounds.extend( lonlat( PointXY::middle( A, B ) ), PointLonLat{h, 0} ); } } } From 084ecd6ee876c4b8edce33f8bd3f454246c152ee Mon Sep 17 00:00:00 2001 From: Pedro Maciel Date: Tue, 2 Jul 2019 08:54:57 +0100 Subject: [PATCH 47/86] MIR-4: atlas::Grid::boundingBox --- src/atlas/grid/Grid.cc | 4 ++++ src/atlas/grid/Grid.h | 1 + src/atlas/grid/detail/grid/Grid.h | 2 +- src/atlas/grid/detail/grid/Structured.cc | 15 +++++++-------- src/atlas/grid/detail/grid/Structured.h | 4 ++-- src/atlas/grid/detail/grid/Unstructured.cc | 2 +- src/atlas/grid/detail/grid/Unstructured.h | 2 +- 7 files changed, 17 insertions(+), 13 deletions(-) diff --git a/src/atlas/grid/Grid.cc b/src/atlas/grid/Grid.cc index e564c8898..7ad8992d5 100644 --- a/src/atlas/grid/Grid.cc +++ b/src/atlas/grid/Grid.cc @@ -63,6 +63,10 @@ const Grid::Domain& Grid::domain() const { return get()->domain(); } +Grid::Domain Grid::boundingBox() const { + return get()->boundingBox(); +} + std::string Grid::name() const { return get()->name(); } diff --git a/src/atlas/grid/Grid.h b/src/atlas/grid/Grid.h index f6e9f4ab6..ba7bfc1a3 100644 --- a/src/atlas/grid/Grid.h +++ b/src/atlas/grid/Grid.h @@ -73,6 +73,7 @@ class Grid : public util::ObjectHandle { const Projection& projection() const; const Domain& domain() const; + Domain boundingBox() const; std::string name() const; std::string uid() const; diff --git a/src/atlas/grid/detail/grid/Grid.h b/src/atlas/grid/detail/grid/Grid.h index e413ab894..2fddb63aa 100644 --- a/src/atlas/grid/detail/grid/Grid.h +++ b/src/atlas/grid/detail/grid/Grid.h @@ -100,7 +100,7 @@ class Grid : public util::Object { const Domain& domain() const { return domain_; } /// @return parallel/meridian limits containing the grid - virtual Domain boundingBox() = 0; + virtual Domain boundingBox() const = 0; /// @return projection (mapping between geographic coordinates and grid /// coordinates) diff --git a/src/atlas/grid/detail/grid/Structured.cc b/src/atlas/grid/detail/grid/Structured.cc index a509d3584..82b0efa1e 100644 --- a/src/atlas/grid/detail/grid/Structured.cc +++ b/src/atlas/grid/detail/grid/Structured.cc @@ -85,12 +85,11 @@ Structured::Structured( const std::string& name, XSpace xspace, YSpace yspace, P computeTruePeriodicity(); } -void Structured::computeDomain() { - if ( periodic() ) { domain_ = ZonalBandDomain( {yspace().min(), yspace().max()}, xspace().min() ); } - else { - domain_ = RectangularDomain( {xspace().min(), xspace().max()}, {yspace().min(), yspace().max()}, - projection_.units() ); +Domain Structured::computeDomain() const { + if ( periodic() ) { + return ZonalBandDomain( {yspace().min(), yspace().max()}, xspace().min() ); } + return RectangularDomain( {xspace().min(), xspace().max()}, {yspace().min(), yspace().max()}, projection_.units() ); } Structured::~Structured() {} @@ -492,9 +491,9 @@ void Structured::hash( eckit::Hash& h ) const { domain().hash( h ); } -Grid::Domain Structured::boundingBox() { - computeDomain(); - return projection_ ? projection_.boundingBox( domain_ ) : domain_; +Grid::Domain Structured::boundingBox() const { + auto domain = computeDomain(); + return projection_ ? projection_.boundingBox( domain ) : domain; } Grid::Spec Structured::spec() const { diff --git a/src/atlas/grid/detail/grid/Structured.h b/src/atlas/grid/detail/grid/Structured.h index 8cd61a713..d851fd918 100644 --- a/src/atlas/grid/detail/grid/Structured.h +++ b/src/atlas/grid/detail/grid/Structured.h @@ -380,11 +380,11 @@ class Structured : public Grid { virtual void hash( eckit::Hash& ) const override; - virtual Domain boundingBox() override; + virtual Domain boundingBox() const override; void computeTruePeriodicity(); - void computeDomain(); + Domain computeDomain() const; void crop( const Domain& ); diff --git a/src/atlas/grid/detail/grid/Unstructured.cc b/src/atlas/grid/detail/grid/Unstructured.cc index 46de8f3f2..8145ea17b 100644 --- a/src/atlas/grid/detail/grid/Unstructured.cc +++ b/src/atlas/grid/detail/grid/Unstructured.cc @@ -170,7 +170,7 @@ void Unstructured::hash( eckit::Hash& h ) const { projection().hash( h ); } -Grid::Domain Unstructured::boundingBox() { +Grid::Domain Unstructured::boundingBox() const { throw_NotImplemented( "Cannot create boundingBox from Unstructured grid", Here() ); } diff --git a/src/atlas/grid/detail/grid/Unstructured.h b/src/atlas/grid/detail/grid/Unstructured.h index afba744de..b137dbd73 100644 --- a/src/atlas/grid/detail/grid/Unstructured.h +++ b/src/atlas/grid/detail/grid/Unstructured.h @@ -199,7 +199,7 @@ class Unstructured : public Grid { virtual void hash( eckit::Hash& ) const; /// @return parallel/meridian limits containing the grid - virtual Domain boundingBox() override; + virtual Domain boundingBox() const override; protected: /// Storage of coordinate points From e3dea0a67ebab4a44cdeccbe7d31374470b35d57 Mon Sep 17 00:00:00 2001 From: Pedro Maciel Date: Tue, 2 Jul 2019 12:22:13 +0100 Subject: [PATCH 48/86] MIR-4: atlas::grid::detail::grid::Unstructured::boundingBox (for completion) --- src/atlas/grid/detail/grid/Unstructured.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/atlas/grid/detail/grid/Unstructured.cc b/src/atlas/grid/detail/grid/Unstructured.cc index 8145ea17b..798857db2 100644 --- a/src/atlas/grid/detail/grid/Unstructured.cc +++ b/src/atlas/grid/detail/grid/Unstructured.cc @@ -171,7 +171,7 @@ void Unstructured::hash( eckit::Hash& h ) const { } Grid::Domain Unstructured::boundingBox() const { - throw_NotImplemented( "Cannot create boundingBox from Unstructured grid", Here() ); + return projection_ ? projection_.boundingBox( domain_ ) : domain_; } idx_t Unstructured::size() const { From ebd1eb7d0c3396a9a1d830b5f182d69d2ea42e62 Mon Sep 17 00:00:00 2001 From: Pedro Maciel Date: Tue, 2 Jul 2019 19:13:41 +0100 Subject: [PATCH 49/86] ATLAS-240: atlas-grids check boundingBox --- src/apps/atlas-grids.cc | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/apps/atlas-grids.cc b/src/apps/atlas-grids.cc index 958329d3b..252337d39 100644 --- a/src/apps/atlas-grids.cc +++ b/src/apps/atlas-grids.cc @@ -326,6 +326,30 @@ int AtlasGrids::execute( const Args& args ) { else { Log::warning() << "Check for lonlat(last) skipped" << std::endl; } + + std::vector bbox; + if ( config_check.get( "bounding_box(n,w,s,e)", bbox ) && bbox.size() == 4 ) { + RectangularDomain rect = grid.boundingBox(); + if ( ( check_failed = !rect ) ) { + out << "Check failed: cannot calculate bounding box for " << grid.spec() << std::endl; + } + else if ( ( check_failed = !equal( rect.ymax(), bbox[0] ) ) ) { + out << "Check failed: n=" << rect.ymax() << " expected to be " << bbox[0] << std::endl; + } + else if ( ( check_failed = !equal( rect.xmin(), bbox[1] ) ) ) { + out << "Check failed: w=" << rect.xmin() << " expected to be " << bbox[1] << std::endl; + } + else if ( ( check_failed = !equal( rect.ymin(), bbox[2] ) ) ) { + out << "Check failed: s=" << rect.ymin() << " expected to be " << bbox[2] << std::endl; + } + else if ( ( check_failed = !equal( rect.xmax(), bbox[3] ) ) ) { + out << "Check failed: e=" << rect.xmax() << " expected to be " << bbox[3] << std::endl; + } + } + else { + Log::warning() << "Check for bounding_box(n,w,s,e) skipped" << std::endl; + } + if ( check_failed ) return failed(); Log::info() << "SUCCESS: All checks passed" << std::endl; } From d872e4eba51d3bf6c7f53b3d9032e95c7c2daf8d Mon Sep 17 00:00:00 2001 From: Pedro Maciel Date: Tue, 2 Jul 2019 19:14:01 +0100 Subject: [PATCH 50/86] ATLAS-240: atlas-grids check boundingBox test for LAEA (EFAS) --- doc/example-grids/regional_lambert_azimuthal_equal_area_2.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/example-grids/regional_lambert_azimuthal_equal_area_2.yml b/doc/example-grids/regional_lambert_azimuthal_equal_area_2.yml index e144d6456..fa24ae752 100644 --- a/doc/example-grids/regional_lambert_azimuthal_equal_area_2.yml +++ b/doc/example-grids/regional_lambert_azimuthal_equal_area_2.yml @@ -17,4 +17,5 @@ check : size : 950000 lonlat(first) : [-35.034,66.9821] lonlat(last) : [41.2436,23.8962] + bounding_box(n,w,s,e) : [72.647, -35.035, 23.895, 74.144] #uid : 09fcf68cb6f8871668dbef411b45a559 From cc150229fcbb29d1a5a6754c0b0f3148111a0e28 Mon Sep 17 00:00:00 2001 From: Pedro Maciel Date: Tue, 2 Jul 2019 19:16:47 +0100 Subject: [PATCH 51/86] ATLAS-240: atlas-grids check boundingBox test for rotated regular_ll (removed redundant unit tests) --- doc/example-grids/regular_lonlat_2.yml | 21 +++++++++ doc/example-grids/regular_lonlat_3.yml | 21 +++++++++ src/tests/projection/test_bounding_box.cc | 55 ----------------------- 3 files changed, 42 insertions(+), 55 deletions(-) create mode 100644 doc/example-grids/regular_lonlat_2.yml create mode 100644 doc/example-grids/regular_lonlat_3.yml diff --git a/doc/example-grids/regular_lonlat_2.yml b/doc/example-grids/regular_lonlat_2.yml new file mode 100644 index 000000000..17793caf8 --- /dev/null +++ b/doc/example-grids/regular_lonlat_2.yml @@ -0,0 +1,21 @@ +# Regular lonlat, cropped and rotated +type : "regular_lonlat" +nx : 360 +ny : 181 +domain : + type : "rectangular" + units : "degrees" + ymax : 90. + xmin : -10. + ymin : 70. + xmax : 10. +projection : + type : "rotated_lonlat" + south_pole : [22., -40.] + +check: + size : 441 + bounding_box(n,w,s,e) : [60.001, -164.730, 39.999, -151.270] + lonlat(first) : [-158., 40.] + lonlat(last) : [-164.729, 59.547] + diff --git a/doc/example-grids/regular_lonlat_3.yml b/doc/example-grids/regular_lonlat_3.yml new file mode 100644 index 000000000..ca002e2fb --- /dev/null +++ b/doc/example-grids/regular_lonlat_3.yml @@ -0,0 +1,21 @@ +# Regular lonlat, cropped and rotated +type : "regular_lonlat" +nx : 360 +ny : 181 +domain : + type : "rectangular" + units : "degrees" + ymax : -70. + xmin : -10. + ymin : -90. + xmax : 10. +projection : + type : "rotated_lonlat" + south_pole : [22., -40.] + +check: + size : 441 + bounding_box(n,w,s,e) : [-19.999, 18.370, -40.001, 25.630] + lonlat(first) : [18.371, -20.243] + lonlat(last) : [22., -40.] + diff --git a/src/tests/projection/test_bounding_box.cc b/src/tests/projection/test_bounding_box.cc index 65a369a20..1b17b9a3c 100644 --- a/src/tests/projection/test_bounding_box.cc +++ b/src/tests/projection/test_bounding_box.cc @@ -141,22 +141,6 @@ struct test_poles_t { }; -struct test_expected_rotation_t { - const NiNj ninj_; - const Rotation rotation_; - const BoundingBox bbox_; - const BoundingBox rotatedBbox_; - -private: - friend std::ostream& operator<<(std::ostream& out, const test_expected_rotation_t& test) { - return (out << "test:" - << "\n\t" << "NiNj = " << test.ninj_ - << "\n\t" << "Rotation = " << test.rotation_ - << "\n\t" << "BoundingBox = " << test.bbox_ - << "\n\t" << "rotatedBbox = " << test.rotatedBbox_); - } -}; - //----------------------------------------------------------------------------- CASE("MIR-282") { @@ -193,12 +177,6 @@ CASE("MIR-282") { }; - std::vector test_expected_rotations { - { NiNj{21, 21}, Rotation(-40., 22.), BoundingBox{ 90, -10, 70, 10}, BoundingBox{ 60, -164.730, 40, -151.270} }, - { NiNj{21, 21}, Rotation(-40., 22.), BoundingBox{ -70, -10, -90, 10}, BoundingBox{-20, 18.370, -40, 25.630} }, - }; - - SECTION("MIR-282: rotated_ll covering North/South poles") { for (auto& test : test_poles) { Log::info() << test << std::endl; @@ -268,39 +246,6 @@ CASE("MIR-282") { } - SECTION("MIR-309: expected rotations") { - - auto is_approximately_equal = [] (const BoundingBox& a, const BoundingBox& b, double eps) { - auto slightly_bigger = [eps](const BoundingBox& bbox) { - - double n = std::min(90., bbox.north() + eps); - double s = std::max(-90., bbox.south() - eps); - - // periodicity not considered - double w = bbox.west() - eps; - double e = bbox.east() + eps; - - return BoundingBox{n, w, s, e}; - }; - - return slightly_bigger(a).contains(b) && - slightly_bigger(b).contains(a); - }; - - - for (auto& test : test_expected_rotations) { - auto rotated = test.rotation_.rotate(test.bbox_); - Log::info() << test - << "\n\t" "reference:\t" << test.rotatedBbox_ - << "\n\t" "calculated:\t" << rotated - << std::endl; - - static constexpr double eps = 0.0015; - EXPECT(is_approximately_equal(test.rotatedBbox_, rotated, eps)); - } - } - - Log::info().precision(old); } From 56e540759f59e156bcf3b33f9e24adb50bcecc4c Mon Sep 17 00:00:00 2001 From: Pedro Maciel Date: Tue, 2 Jul 2019 19:28:16 +0100 Subject: [PATCH 52/86] ATLAS-240: atlas-grids modernise --- src/apps/atlas-grids.cc | 148 ++++++++++++++++------------------------ 1 file changed, 57 insertions(+), 91 deletions(-) diff --git a/src/apps/atlas-grids.cc b/src/apps/atlas-grids.cc index 252337d39..fba9b34fa 100644 --- a/src/apps/atlas-grids.cc +++ b/src/apps/atlas-grids.cc @@ -28,19 +28,12 @@ #include "atlas/grid.h" #include "atlas/grid/detail/grid/GridFactory.h" -#include "atlas/library/Library.h" #include "atlas/runtime/AtlasTool.h" #include "atlas/runtime/Exception.h" -#include "atlas/runtime/Log.h" - -using namespace atlas; -using namespace atlas::grid; -using eckit::JSON; -using eckit::PathName; //---------------------------------------------------------------------------------------------------------------------- -class AtlasGrids : public AtlasTool { +struct AtlasGrids : public atlas::AtlasTool { virtual bool serial() { return true; } virtual int execute( const Args& args ); virtual std::string briefDescription() { return "Catalogue of available built-in grids"; } @@ -54,78 +47,60 @@ class AtlasGrids : public AtlasTool { " Example values: N80, F40, O24, L32\n"; } -public: AtlasGrids( int argc, char** argv ) : AtlasTool( argc, argv ) { add_option( new SimpleOption( "list", "List all grids. The names are possible values for the GRID argument" ) ); - add_option( new SimpleOption( "info", "List information about GRID" ) ); - add_option( new SimpleOption( "json", "Export json" ) ); - add_option( new SimpleOption( "rtable", "Export IFS rtable" ) ); - add_option( new SimpleOption( "check", "Check grid" ) ); } - -private: - bool list; - std::string key; - bool info; - bool json; - bool rtable; - bool do_run; - bool check; }; //------------------------------------------------------------------------------------------------------ int AtlasGrids::execute( const Args& args ) { - key = ""; - if ( args.count() ) key = args( 0 ); + using namespace atlas; - info = false; - args.get( "info", info ); + std::string key = args.count() ? args( 0 ) : ""; - if ( info && !key.empty() ) do_run = true; + bool info = false; + args.get( "info", info ); - json = false; + bool json = false; args.get( "json", json ); - if ( json && !key.empty() ) do_run = true; - rtable = false; + bool rtable = false; args.get( "rtable", rtable ); - if ( rtable && !key.empty() ) do_run = true; - list = false; + bool check = false; + args.get( "check", check ); + + bool list = false; args.get( "list", list ); - if ( list ) do_run = true; - check = false; - args.get( "check", check ); - if ( check && !key.empty() ) do_run = true; + bool do_run = list || ( !key.empty() && ( info || json || rtable || check ) ); - if ( !key.empty() && do_run == false ) { + if ( !key.empty() && !do_run ) { Log::error() << "Option wrong or missing after '" << key << "'" << std::endl; } + if ( list ) { Log::info() << "usage: atlas-grids GRID [OPTION]... [--help]\n" << std::endl; Log::info() << "Available grids:" << std::endl; - for ( const auto& key : GridFactory::keys() ) { + for ( const auto& key : grid::GridFactory::keys() ) { Log::info() << " -- " << key << std::endl; } } if ( !key.empty() ) { - Grid grid; - PathName spec{key}; - if ( spec.exists() ) { grid = Grid( Grid::Spec{spec} ); } - else { - grid = Grid( key ); - } + eckit::PathName path{key}; + Grid grid = path.exists() ? Grid( Grid::Spec{path} ) : Grid( key ); - if ( !grid ) return failed(); + if ( !grid ) { + return failed(); + } if ( info ) { Log::info() << "Grid " << key << std::endl; @@ -142,6 +117,7 @@ int AtlasGrids::execute( const Args& args ) { Log::info() << " memory footprint per field (dp): " << eckit::Bytes( memsize ) << std::endl; if ( auto structuredgrid = StructuredGrid( grid ) ) { + if ( not grid.projection() ) { double deg, km; @@ -164,9 +140,8 @@ int AtlasGrids::execute( const Args& args ) { Log::info() << " approximate resolution E-W midlat: " << std::setw( 10 ) << std::fixed << deg << " deg " << km << " km " << std::endl; - deg = 360. * std::cos( structuredgrid.y().front() * M_PI / 180. ) / - static_cast( structuredgrid.nx().front() ); - km = deg * 40075. / 360.; + deg = 360. * std::cos( structuredgrid.y().front() * M_PI / 180. ) / static_cast( structuredgrid.nx().front() ); + km = deg * 40075. / 360.; Log::info() << " approximate resolution E-W pole: " << std::setw( 10 ) << std::fixed << deg @@ -174,55 +149,40 @@ int AtlasGrids::execute( const Args& args ) { Log::info() << " spectral truncation -- linear: " << structuredgrid.ny() - 1 << std::endl; Log::info() << " spectral truncation -- quadratic: " - << static_cast( std::floor( 2. / 3. * structuredgrid.ny() + 0.5 ) ) - 1 - << std::endl; + << static_cast( std::floor( 2. / 3. * structuredgrid.ny() + 0.5 ) ) - 1 << std::endl; Log::info() << " spectral truncation -- cubic: " << static_cast( std::floor( 0.5 * structuredgrid.ny() + 0.5 ) ) - 1 << std::endl; } auto precision = Log::info().precision( 3 ); if ( grid.projection().units() == "meters" ) { - Log::info() << " x : [ " << std::setw( 10 ) << std::fixed << structuredgrid.xspace().min() / 1000. - << " , " << std::setw( 10 ) << std::fixed << structuredgrid.xspace().max() / 1000. - << " ] km" << std::endl; - Log::info() << " y : [ " << std::setw( 10 ) << std::fixed << structuredgrid.yspace().min() / 1000. - << " , " << std::setw( 10 ) << std::fixed << structuredgrid.yspace().max() / 1000. - << " ] km" << std::endl; + Log::info() << " x : [ " << std::setw( 10 ) << std::fixed << structuredgrid.xspace().min() / 1000. << " , " + << std::setw( 10 ) << std::fixed << structuredgrid.xspace().max() / 1000. << " ] km" << std::endl; + Log::info() << " y : [ " << std::setw( 10 ) << std::fixed << structuredgrid.yspace().min() / 1000. << " , " + << std::setw( 10 ) << std::fixed << structuredgrid.yspace().max() / 1000. << " ] km" << std::endl; if ( structuredgrid.xspace().nxmax() == structuredgrid.xspace().nxmin() ) { Log::info() << " dx : " << structuredgrid.xspace().dx()[0] / 1000. << " km" << std::endl; } - Log::info() << " dy : " - << std::abs( structuredgrid.yspace()[1] - structuredgrid.yspace()[0] ) / 1000. << " km" + Log::info() << " dy : " << std::abs( structuredgrid.yspace()[1] - structuredgrid.yspace()[0] ) / 1000. << " km" << std::endl; Log::info() << " lonlat(centre) : " - << grid.projection().lonlat( - {0.5 * ( structuredgrid.xspace().max() + structuredgrid.xspace().min() ), - 0.5 * ( structuredgrid.yspace().max() + structuredgrid.yspace().min() )} ) + << grid.projection().lonlat( {0.5 * ( structuredgrid.xspace().max() + structuredgrid.xspace().min() ), + 0.5 * ( structuredgrid.yspace().max() + structuredgrid.yspace().min() )} ) << std::endl; Log::info() << " lonlat(xmin,ymax) : " - << grid.projection().lonlat( - {structuredgrid.xspace().min(), structuredgrid.yspace().max()} ) - << std::endl; + << grid.projection().lonlat( {structuredgrid.xspace().min(), structuredgrid.yspace().max()} ) << std::endl; Log::info() << " lonlat(xmin,ymin) : " - << grid.projection().lonlat( - {structuredgrid.xspace().min(), structuredgrid.yspace().min()} ) - << std::endl; + << grid.projection().lonlat( {structuredgrid.xspace().min(), structuredgrid.yspace().min()} ) << std::endl; Log::info() << " lonlat(xmax,ymin) : " - << grid.projection().lonlat( - {structuredgrid.xspace().max(), structuredgrid.yspace().min()} ) - << std::endl; + << grid.projection().lonlat( {structuredgrid.xspace().max(), structuredgrid.yspace().min()} ) << std::endl; Log::info() << " lonlat(xmax,ymax) : " - << grid.projection().lonlat( - {structuredgrid.xspace().max(), structuredgrid.yspace().max()} ) - << std::endl; + << grid.projection().lonlat( {structuredgrid.xspace().max(), structuredgrid.yspace().max()} ) << std::endl; } if ( grid.projection().units() == "degrees" ) { - Log::info() << " x : [ " << std::setw( 10 ) << std::fixed << structuredgrid.xspace().min() - << " , " << std::setw( 10 ) << std::fixed << structuredgrid.xspace().max() << " ] deg" - << std::endl; - Log::info() << " y : [ " << std::setw( 10 ) << std::fixed << structuredgrid.yspace().min() - << " , " << std::setw( 10 ) << std::fixed << structuredgrid.yspace().max() << " ] deg" - << std::endl; + Log::info() << " x : [ " << std::setw( 10 ) << std::fixed << structuredgrid.xspace().min() << " , " + << std::setw( 10 ) << std::fixed << structuredgrid.xspace().max() << " ] deg" << std::endl; + Log::info() << " y : [ " << std::setw( 10 ) << std::fixed << structuredgrid.yspace().min() << " , " + << std::setw( 10 ) << std::fixed << structuredgrid.yspace().max() << " ] deg" << std::endl; } PointLonLat first_point = *grid.lonlat().begin(); PointLonLat last_point; @@ -234,9 +194,10 @@ int AtlasGrids::execute( const Args& args ) { Log::info().precision( precision ); } } + if ( json ) { std::stringstream stream; - JSON js( stream ); + eckit::JSON js( stream ); js.precision( 16 ); js << grid.spec(); std::cout << stream.str() << std::endl; @@ -246,9 +207,10 @@ int AtlasGrids::execute( const Args& args ) { if ( auto structuredgrid = StructuredGrid( grid ) ) { std::stringstream stream; stream << "&NAMRGRI\n"; - for ( idx_t j = 0; j < structuredgrid.ny(); ++j ) + for ( idx_t j = 0; j < structuredgrid.ny(); ++j ) { stream << " NRGRI(" << std::setfill( '0' ) << std::setw( 5 ) << 1 + j << ")=" << std::setfill( ' ' ) << std::setw( 5 ) << structuredgrid.nx( j ) << ",\n"; + } stream << "/" << std::flush; std::cout << stream.str() << std::endl; } @@ -258,13 +220,15 @@ int AtlasGrids::execute( const Args& args ) { bool check_failed = false; Log::Channel out; out.setStream( Log::error() ); - PathName spec{key}; - if ( not spec.exists() ) { + + eckit::PathName path{key}; + if ( not path.exists() ) { out << "Check failed: " << key << " is not a file" << std::endl; return failed(); } + util::Config config_check; - if ( not util::Config{spec}.get( "check", config_check ) ) { + if ( not util::Config{path}.get( "check", config_check ) ) { out << "Check failed: no \"check\" section in " << key << std::endl; return failed(); } @@ -292,16 +256,15 @@ int AtlasGrids::execute( const Args& args ) { } - auto equal = []( const PointLonLat& p, const std::vector& check ) -> bool { - if ( not eckit::types::is_approximately_equal( p.lon(), check[0], 5.e-4 ) ) return false; - if ( not eckit::types::is_approximately_equal( p.lat(), check[1], 5.e-4 ) ) return false; - return true; + auto equal = []( double a, double b ) { + return eckit::types::is_approximately_equal( a, b, 5.e-4 ); }; std::vector first_point_lonlat; if ( config_check.get( "lonlat(first)", first_point_lonlat ) ) { PointLonLat first_point = *grid.lonlat().begin(); - if ( not equal( first_point, first_point_lonlat ) ) { + if ( not equal( first_point.lon(), first_point_lonlat[0] ) or + not equal( first_point.lat(), first_point_lonlat[1] ) ) { out << "Check failed: lonlat(first) " << first_point << " expected to be " << PointLonLat( first_point_lonlat.data() ) << std::endl; check_failed = true; @@ -317,7 +280,8 @@ int AtlasGrids::execute( const Args& args ) { for ( const auto p : grid.lonlat() ) { last_point = p; } - if ( not equal( last_point, last_point_lonlat ) ) { + if ( not equal( last_point.lon(), last_point_lonlat[0] ) or + not equal( last_point.lat(), last_point_lonlat[1] ) ) { out << "Check failed: lonlat(last) " << last_point << " expected to be " << PointLonLat( last_point_lonlat.data() ) << std::endl; check_failed = true; @@ -350,7 +314,9 @@ int AtlasGrids::execute( const Args& args ) { Log::warning() << "Check for bounding_box(n,w,s,e) skipped" << std::endl; } - if ( check_failed ) return failed(); + if ( check_failed ) { + return failed(); + } Log::info() << "SUCCESS: All checks passed" << std::endl; } } From 5421ca236eb22766367c56cd0b5d0aa57050ec87 Mon Sep 17 00:00:00 2001 From: Pedro Maciel Date: Wed, 3 Jul 2019 09:05:55 +0100 Subject: [PATCH 53/86] ATLAS-240: atlas-grids remove includes --- src/apps/atlas-grids.cc | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/apps/atlas-grids.cc b/src/apps/atlas-grids.cc index fba9b34fa..dbff53ded 100644 --- a/src/apps/atlas-grids.cc +++ b/src/apps/atlas-grids.cc @@ -8,14 +8,11 @@ * nor does it submit to any jurisdiction. */ -#include #include -#include #include #include -#include -#include #include +#include #include #include "eckit/config/Resource.h" @@ -23,13 +20,11 @@ #include "eckit/log/Bytes.h" #include "eckit/log/Log.h" #include "eckit/parser/JSON.h" -#include "eckit/runtime/Main.h" #include "eckit/types/FloatCompare.h" #include "atlas/grid.h" #include "atlas/grid/detail/grid/GridFactory.h" #include "atlas/runtime/AtlasTool.h" -#include "atlas/runtime/Exception.h" //---------------------------------------------------------------------------------------------------------------------- From b71384cda141662824851161ee71fb790fc41ed6 Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Thu, 4 Jul 2019 09:46:26 +0000 Subject: [PATCH 54/86] Fix atlas_test_bounding_box for some platforms --- src/tests/projection/test_bounding_box.cc | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/tests/projection/test_bounding_box.cc b/src/tests/projection/test_bounding_box.cc index 1b17b9a3c..b2cf728b2 100644 --- a/src/tests/projection/test_bounding_box.cc +++ b/src/tests/projection/test_bounding_box.cc @@ -179,7 +179,7 @@ CASE("MIR-282") { SECTION("MIR-282: rotated_ll covering North/South poles") { for (auto& test : test_poles) { - Log::info() << test << std::endl; + Log::info() << '\n' << test << std::endl; const PointLonLat southPole( test.rotation_.south_pole_longitude(), @@ -191,10 +191,13 @@ CASE("MIR-282") { PointLonLat NP{ r.unrotate({0., 90.}) }; PointLonLat SP{ r.unrotate({0., -90.}) }; - bool includesNorthPole = test.bbox_.contains(NP.lat(), NP.lon()); - bool includesSouthPole = test.bbox_.contains(SP.lat(), SP.lon()); + RectangularDomain domain{ test.bbox_ }; + bool includesNorthPole = domain.contains(NP); + bool includesSouthPole = domain.contains(SP); Log::info() << "check:" + << "\n\t" << "NP = " << NP + << "\n\t" << "SP = " << SP << "\n\t" << "includesNorthPole? " << includesNorthPole << "\n\t" << "includesSouthPole? " << includesSouthPole << std::endl; @@ -208,7 +211,7 @@ CASE("MIR-282") { SECTION("MIR-282: rotated_ll contained by cropping") { for (auto& test : test_poles) { - Log::info() << test << std::endl; + Log::info() << '\n' << test << std::endl; double n = test.bbox_.north(); double s = test.bbox_.south(); From f87c86dc44a943e1b47925020bdd645098df15f8 Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Thu, 4 Jul 2019 10:31:14 +0000 Subject: [PATCH 55/86] Fix atlas_fctest_trans_unstructured: initialisation of data missing --- src/tests/trans/fctest_trans_unstructured.F90 | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/tests/trans/fctest_trans_unstructured.F90 b/src/tests/trans/fctest_trans_unstructured.F90 index e15566ee8..5d9fdf559 100644 --- a/src/tests/trans/fctest_trans_unstructured.F90 +++ b/src/tests/trans/fctest_trans_unstructured.F90 @@ -58,7 +58,7 @@ grid = atlas_UnstructuredGrid( xy ) - truncation = 1279 + truncation = 21; trans = atlas_Trans(grid,truncation) @@ -73,12 +73,26 @@ gp_scal_field = atlas_Field(name="gridpoint_scalar",kind=atlas_real(8),shape=[10]) gp_wind_field = atlas_Field(name="gridpoint_wind",kind=atlas_real(8),shape=[10,2]) + call set_zero( sp_scal_field ) + call set_zero( sp_vor_field ) + call set_zero( sp_div_field ) + config = atlas_Config() call config%set("warning",0) ! turn off warnings for unstructured grids call trans%invtrans( sp_scal_field, gp_scal_field, config ) call trans%invtrans_vordiv2wind( sp_vor_field, sp_div_field, gp_wind_field, config ) +contains + + subroutine set_zero( field ) + use, intrinsic :: iso_c_binding + type(atlas_Field) :: field + real(c_double), pointer :: data(:) + call field%data(data) + data(:) = 0. + end subroutine + END_TEST From f25bf252917be7a452e3a1520f4560343e02660e Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Thu, 4 Jul 2019 12:53:42 +0100 Subject: [PATCH 56/86] Revert commit b71384cd and fix by increasing bounding box --- src/tests/projection/test_bounding_box.cc | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/tests/projection/test_bounding_box.cc b/src/tests/projection/test_bounding_box.cc index b2cf728b2..c97f2a3e4 100644 --- a/src/tests/projection/test_bounding_box.cc +++ b/src/tests/projection/test_bounding_box.cc @@ -150,7 +150,7 @@ CASE("MIR-282") { std::vector test_poles { { NiNj{ 124, 118}, Rotation(-35., 0.), BoundingBox{12, -14.5, -17.25, 16.25} }, { NiNj{ 360, 181}, Rotation(-90., 0.), BoundingBox(), true, true }, - { NiNj{ 81, 56}, Rotation(-75., 15.), BoundingBox{75., -35., 20., 45.}, true }, + { NiNj{ 81, 56}, Rotation(-75., 15.), BoundingBox{75.1, -35., 20., 45.}, true }, { NiNj{ 111, 86}, Rotation(-35., 15.), BoundingBox{40., -55., -45., 55.}, true }, { NiNj{ 91, 76}, Rotation(-30., -15.), BoundingBox{35., -40., -40., 50.}, true }, { NiNj{ 101, 81}, Rotation(-25., 0.), BoundingBox{40., -50., -40., 50.}, true }, @@ -191,9 +191,8 @@ CASE("MIR-282") { PointLonLat NP{ r.unrotate({0., 90.}) }; PointLonLat SP{ r.unrotate({0., -90.}) }; - RectangularDomain domain{ test.bbox_ }; - bool includesNorthPole = domain.contains(NP); - bool includesSouthPole = domain.contains(SP); + bool includesNorthPole = test.bbox_.contains(NP.lat(), NP.lon()); + bool includesSouthPole = test.bbox_.contains(SP.lat(), SP.lon()); Log::info() << "check:" << "\n\t" << "NP = " << NP From effcdbae2a25bd9cdb06039aa7d6f148d4a5fc8d Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Fri, 5 Jul 2019 10:37:20 +0100 Subject: [PATCH 57/86] Apply clang-format --- src/apps/atlas-grids.cc | 70 +++++---- src/atlas/grid/detail/grid/Structured.cc | 6 +- src/atlas/projection/Projection.cc | 2 +- src/atlas/projection/Projection.h | 2 +- .../projection/detail/LonLatProjection.cc | 14 +- src/atlas/projection/detail/ProjectionImpl.cc | 30 ++-- src/atlas/projection/detail/ProjectionImpl.h | 2 + src/tests/projection/test_bounding_box.cc | 140 ++++++++---------- 8 files changed, 121 insertions(+), 145 deletions(-) diff --git a/src/apps/atlas-grids.cc b/src/apps/atlas-grids.cc index dbff53ded..60997983d 100644 --- a/src/apps/atlas-grids.cc +++ b/src/apps/atlas-grids.cc @@ -76,9 +76,7 @@ int AtlasGrids::execute( const Args& args ) { bool do_run = list || ( !key.empty() && ( info || json || rtable || check ) ); - if ( !key.empty() && !do_run ) { - Log::error() << "Option wrong or missing after '" << key << "'" << std::endl; - } + if ( !key.empty() && !do_run ) { Log::error() << "Option wrong or missing after '" << key << "'" << std::endl; } if ( list ) { Log::info() << "usage: atlas-grids GRID [OPTION]... [--help]\n" << std::endl; @@ -89,13 +87,10 @@ int AtlasGrids::execute( const Args& args ) { } if ( !key.empty() ) { - eckit::PathName path{key}; Grid grid = path.exists() ? Grid( Grid::Spec{path} ) : Grid( key ); - if ( !grid ) { - return failed(); - } + if ( !grid ) { return failed(); } if ( info ) { Log::info() << "Grid " << key << std::endl; @@ -112,7 +107,6 @@ int AtlasGrids::execute( const Args& args ) { Log::info() << " memory footprint per field (dp): " << eckit::Bytes( memsize ) << std::endl; if ( auto structuredgrid = StructuredGrid( grid ) ) { - if ( not grid.projection() ) { double deg, km; @@ -135,8 +129,9 @@ int AtlasGrids::execute( const Args& args ) { Log::info() << " approximate resolution E-W midlat: " << std::setw( 10 ) << std::fixed << deg << " deg " << km << " km " << std::endl; - deg = 360. * std::cos( structuredgrid.y().front() * M_PI / 180. ) / static_cast( structuredgrid.nx().front() ); - km = deg * 40075. / 360.; + deg = 360. * std::cos( structuredgrid.y().front() * M_PI / 180. ) / + static_cast( structuredgrid.nx().front() ); + km = deg * 40075. / 360.; Log::info() << " approximate resolution E-W pole: " << std::setw( 10 ) << std::fixed << deg @@ -144,40 +139,55 @@ int AtlasGrids::execute( const Args& args ) { Log::info() << " spectral truncation -- linear: " << structuredgrid.ny() - 1 << std::endl; Log::info() << " spectral truncation -- quadratic: " - << static_cast( std::floor( 2. / 3. * structuredgrid.ny() + 0.5 ) ) - 1 << std::endl; + << static_cast( std::floor( 2. / 3. * structuredgrid.ny() + 0.5 ) ) - 1 + << std::endl; Log::info() << " spectral truncation -- cubic: " << static_cast( std::floor( 0.5 * structuredgrid.ny() + 0.5 ) ) - 1 << std::endl; } auto precision = Log::info().precision( 3 ); if ( grid.projection().units() == "meters" ) { - Log::info() << " x : [ " << std::setw( 10 ) << std::fixed << structuredgrid.xspace().min() / 1000. << " , " - << std::setw( 10 ) << std::fixed << structuredgrid.xspace().max() / 1000. << " ] km" << std::endl; - Log::info() << " y : [ " << std::setw( 10 ) << std::fixed << structuredgrid.yspace().min() / 1000. << " , " - << std::setw( 10 ) << std::fixed << structuredgrid.yspace().max() / 1000. << " ] km" << std::endl; + Log::info() << " x : [ " << std::setw( 10 ) << std::fixed << structuredgrid.xspace().min() / 1000. + << " , " << std::setw( 10 ) << std::fixed << structuredgrid.xspace().max() / 1000. + << " ] km" << std::endl; + Log::info() << " y : [ " << std::setw( 10 ) << std::fixed << structuredgrid.yspace().min() / 1000. + << " , " << std::setw( 10 ) << std::fixed << structuredgrid.yspace().max() / 1000. + << " ] km" << std::endl; if ( structuredgrid.xspace().nxmax() == structuredgrid.xspace().nxmin() ) { Log::info() << " dx : " << structuredgrid.xspace().dx()[0] / 1000. << " km" << std::endl; } - Log::info() << " dy : " << std::abs( structuredgrid.yspace()[1] - structuredgrid.yspace()[0] ) / 1000. << " km" + Log::info() << " dy : " + << std::abs( structuredgrid.yspace()[1] - structuredgrid.yspace()[0] ) / 1000. << " km" << std::endl; Log::info() << " lonlat(centre) : " - << grid.projection().lonlat( {0.5 * ( structuredgrid.xspace().max() + structuredgrid.xspace().min() ), - 0.5 * ( structuredgrid.yspace().max() + structuredgrid.yspace().min() )} ) + << grid.projection().lonlat( + {0.5 * ( structuredgrid.xspace().max() + structuredgrid.xspace().min() ), + 0.5 * ( structuredgrid.yspace().max() + structuredgrid.yspace().min() )} ) << std::endl; Log::info() << " lonlat(xmin,ymax) : " - << grid.projection().lonlat( {structuredgrid.xspace().min(), structuredgrid.yspace().max()} ) << std::endl; + << grid.projection().lonlat( + {structuredgrid.xspace().min(), structuredgrid.yspace().max()} ) + << std::endl; Log::info() << " lonlat(xmin,ymin) : " - << grid.projection().lonlat( {structuredgrid.xspace().min(), structuredgrid.yspace().min()} ) << std::endl; + << grid.projection().lonlat( + {structuredgrid.xspace().min(), structuredgrid.yspace().min()} ) + << std::endl; Log::info() << " lonlat(xmax,ymin) : " - << grid.projection().lonlat( {structuredgrid.xspace().max(), structuredgrid.yspace().min()} ) << std::endl; + << grid.projection().lonlat( + {structuredgrid.xspace().max(), structuredgrid.yspace().min()} ) + << std::endl; Log::info() << " lonlat(xmax,ymax) : " - << grid.projection().lonlat( {structuredgrid.xspace().max(), structuredgrid.yspace().max()} ) << std::endl; + << grid.projection().lonlat( + {structuredgrid.xspace().max(), structuredgrid.yspace().max()} ) + << std::endl; } if ( grid.projection().units() == "degrees" ) { - Log::info() << " x : [ " << std::setw( 10 ) << std::fixed << structuredgrid.xspace().min() << " , " - << std::setw( 10 ) << std::fixed << structuredgrid.xspace().max() << " ] deg" << std::endl; - Log::info() << " y : [ " << std::setw( 10 ) << std::fixed << structuredgrid.yspace().min() << " , " - << std::setw( 10 ) << std::fixed << structuredgrid.yspace().max() << " ] deg" << std::endl; + Log::info() << " x : [ " << std::setw( 10 ) << std::fixed << structuredgrid.xspace().min() + << " , " << std::setw( 10 ) << std::fixed << structuredgrid.xspace().max() << " ] deg" + << std::endl; + Log::info() << " y : [ " << std::setw( 10 ) << std::fixed << structuredgrid.yspace().min() + << " , " << std::setw( 10 ) << std::fixed << structuredgrid.yspace().max() << " ] deg" + << std::endl; } PointLonLat first_point = *grid.lonlat().begin(); PointLonLat last_point; @@ -251,9 +261,7 @@ int AtlasGrids::execute( const Args& args ) { } - auto equal = []( double a, double b ) { - return eckit::types::is_approximately_equal( a, b, 5.e-4 ); - }; + auto equal = []( double a, double b ) { return eckit::types::is_approximately_equal( a, b, 5.e-4 ); }; std::vector first_point_lonlat; if ( config_check.get( "lonlat(first)", first_point_lonlat ) ) { @@ -309,9 +317,7 @@ int AtlasGrids::execute( const Args& args ) { Log::warning() << "Check for bounding_box(n,w,s,e) skipped" << std::endl; } - if ( check_failed ) { - return failed(); - } + if ( check_failed ) { return failed(); } Log::info() << "SUCCESS: All checks passed" << std::endl; } } diff --git a/src/atlas/grid/detail/grid/Structured.cc b/src/atlas/grid/detail/grid/Structured.cc index 82b0efa1e..2b5315139 100644 --- a/src/atlas/grid/detail/grid/Structured.cc +++ b/src/atlas/grid/detail/grid/Structured.cc @@ -86,9 +86,7 @@ Structured::Structured( const std::string& name, XSpace xspace, YSpace yspace, P } Domain Structured::computeDomain() const { - if ( periodic() ) { - return ZonalBandDomain( {yspace().min(), yspace().max()}, xspace().min() ); - } + if ( periodic() ) { return ZonalBandDomain( {yspace().min(), yspace().max()}, xspace().min() ); } return RectangularDomain( {xspace().min(), xspace().max()}, {yspace().min(), yspace().max()}, projection_.units() ); } @@ -512,7 +510,7 @@ Grid::Spec Structured::spec() const { return grid_spec; } -// -------------------------------------------------------------------- + // -------------------------------------------------------------------- #if 1 namespace { // anonymous diff --git a/src/atlas/projection/Projection.cc b/src/atlas/projection/Projection.cc index 83d2bc2bd..a8b121af1 100644 --- a/src/atlas/projection/Projection.cc +++ b/src/atlas/projection/Projection.cc @@ -50,7 +50,7 @@ bool atlas::Projection::strictlyRegional() const { return get()->strictlyRegional(); } -Domain Projection::boundingBox( const Domain& domain) const { +Domain Projection::boundingBox( const Domain& domain ) const { return get()->boundingBox( domain ); } diff --git a/src/atlas/projection/Projection.h b/src/atlas/projection/Projection.h index 1dffc3ea4..9960c5657 100644 --- a/src/atlas/projection/Projection.h +++ b/src/atlas/projection/Projection.h @@ -12,8 +12,8 @@ #include -#include "atlas/util/ObjectHandle.h" #include "atlas/domain/Domain.h" +#include "atlas/util/ObjectHandle.h" //--------------------------------------------------------------------------------------------------------------------- diff --git a/src/atlas/projection/detail/LonLatProjection.cc b/src/atlas/projection/detail/LonLatProjection.cc index 36dbda4f5..11abf39b9 100644 --- a/src/atlas/projection/detail/LonLatProjection.cc +++ b/src/atlas/projection/detail/LonLatProjection.cc @@ -48,9 +48,7 @@ Domain LonLatProjectionT::boundingBox( const Domain& domain ) const { // 0. setup - if ( domain.global() ) { - return domain; - } + if ( domain.global() ) { return domain; } RectangularDomain rect( domain ); ATLAS_ASSERT( rect ); @@ -122,9 +120,7 @@ Domain LonLatProjectionT::boundingBox( const Domain& domain ) const { for ( auto lon : {rect.xmin(), rect.xmax()} ) { if ( !bounds.crossesDateLine() ) { for ( auto lat : DL.latitude( lon ) ) { - if ( ( bounds.crossesDateLine( domain.contains( lon, lat ) ) ) ) { - break; - } + if ( ( bounds.crossesDateLine( domain.contains( lon, lat ) ) ) ) { break; } } } } @@ -132,9 +128,7 @@ Domain LonLatProjectionT::boundingBox( const Domain& domain ) const { for ( auto lat : {rect.ymin(), rect.ymax()} ) { if ( !bounds.crossesDateLine() ) { for ( auto lon : DL.longitude( lat ) ) { - if ( ( bounds.crossesDateLine( domain.contains( lon, lat ) ) ) ) { - break; - } + if ( ( bounds.crossesDateLine( domain.contains( lon, lat ) ) ) ) { break; } } } } @@ -197,7 +191,7 @@ template class LonLatProjectionT; namespace { static ProjectionBuilder register_1( LonLatProjection::static_type() ); static ProjectionBuilder register_2( RotatedLonLatProjection::static_type() ); -} +} // namespace // namespace diff --git a/src/atlas/projection/detail/ProjectionImpl.cc b/src/atlas/projection/detail/ProjectionImpl.cc index 27a682fe8..84e3cc71f 100644 --- a/src/atlas/projection/detail/ProjectionImpl.cc +++ b/src/atlas/projection/detail/ProjectionImpl.cc @@ -69,7 +69,7 @@ struct DerivateCentral final : ProjectionImpl::Derivate { } }; -} // (anonymous namespace) +} // namespace ProjectionImpl::Derivate::Derivate( const ProjectionImpl& p, PointXY A, PointXY B, double h ) : projection_( p ), @@ -96,7 +96,7 @@ ProjectionImpl::Derivate* ProjectionImpl::DerivateFactory::build( const std::str } auto factory = get( type ); - return factory->make( p, A, B, h); + return factory->make( p, A, B, h ); } ProjectionImpl::DerivateFactory::~DerivateFactory() = default; @@ -108,24 +108,18 @@ ProjectionImpl::BoundLonLat::operator Domain() const { } bool ProjectionImpl::BoundLonLat::crossesDateLine( bool yes ) { - if ( ( crossesDateLine_ = crossesDateLine_ || yes ) ) { - max_.lon() = min_.lon() + 360.; - } + if ( ( crossesDateLine_ = crossesDateLine_ || yes ) ) { max_.lon() = min_.lon() + 360.; } return crossesDateLine_; } bool ProjectionImpl::BoundLonLat::includesNorthPole( bool yes ) { - if ( ( includesNorthPole_ = includesNorthPole_ || yes ) ) { - max_.lat() = 90.; - } + if ( ( includesNorthPole_ = includesNorthPole_ || yes ) ) { max_.lat() = 90.; } crossesDateLine( includesNorthPole_ ); return includesNorthPole_; } bool ProjectionImpl::BoundLonLat::includesSouthPole( bool yes ) { - if ( ( includesSouthPole_ = includesSouthPole_ || yes ) ) { - min_.lat() = -90.; - } + if ( ( includesSouthPole_ = includesSouthPole_ || yes ) ) { min_.lat() = -90.; } crossesDateLine( includesSouthPole_ ); return includesSouthPole_; } @@ -135,9 +129,9 @@ void ProjectionImpl::BoundLonLat::extend( PointLonLat p, PointLonLat eps ) { auto sub = PointLonLat::sub( p, eps ); auto add = PointLonLat::add( p, eps ); - min_ = first_ ? sub : PointLonLat::componentsMin( min_, sub ); - max_ = first_ ? add : PointLonLat::componentsMax( max_, add ); - first_ = false; + min_ = first_ ? sub : PointLonLat::componentsMin( min_, sub ); + max_ = first_ ? add : PointLonLat::componentsMax( max_, add ); + first_ = false; min_.lat() = std::max( min_.lat(), -90. ); max_.lat() = std::min( max_.lat(), 90. ); @@ -153,9 +147,7 @@ void ProjectionImpl::BoundLonLat::extend( PointLonLat p, PointLonLat eps ) { const ProjectionImpl* ProjectionImpl::create( const eckit::Parametrisation& p ) { std::string projectionType; - if ( p.get( "type", projectionType ) ) { - return ProjectionFactory::build( projectionType, p ); - } + if ( p.get( "type", projectionType ) ) { return ProjectionFactory::build( projectionType, p ); } // should return error here throw_Exception( "type missing in Params", Here() ); @@ -167,9 +159,7 @@ Domain ProjectionImpl::boundingBox( const Domain& domain ) const { // 0. setup - if ( domain.global() ) { - return domain; - } + if ( domain.global() ) { return domain; } RectangularDomain rect( domain ); ATLAS_ASSERT( rect ); diff --git a/src/atlas/projection/detail/ProjectionImpl.h b/src/atlas/projection/detail/ProjectionImpl.h index 7e61edae2..e21eee96e 100644 --- a/src/atlas/projection/detail/ProjectionImpl.h +++ b/src/atlas/projection/detail/ProjectionImpl.h @@ -88,6 +88,7 @@ class ProjectionImpl : public util::Object { Derivate( const ProjectionImpl& p, PointXY A, PointXY B, double h ); virtual ~Derivate(); virtual PointLonLat d( PointXY ) const = 0; + protected: const ProjectionImpl& projection_; const PointXY H_; @@ -103,6 +104,7 @@ class ProjectionImpl : public util::Object { static std::string className() { return "DerivateFactory"; } static ProjectionImpl::Derivate* build( const std::string& type, const ProjectionImpl& p, PointXY A, PointXY B, double h = 0.001 ); + protected: using Factory::Factory; virtual ~DerivateFactory(); diff --git a/src/tests/projection/test_bounding_box.cc b/src/tests/projection/test_bounding_box.cc index c97f2a3e4..fd99d4268 100644 --- a/src/tests/projection/test_bounding_box.cc +++ b/src/tests/projection/test_bounding_box.cc @@ -20,7 +20,6 @@ #include "eckit/types/FloatCompare.h" #include "atlas/domain.h" -#include "atlas/grid.h" #include "atlas/domain/detail/GlobalDomain.h" // FIXME not included by atlas/domain.h #include "atlas/grid.h" #include "atlas/runtime/Log.h" @@ -68,9 +67,7 @@ struct BoundingBox : public std::array { bool otherEmpty = !eckit::types::is_strictly_greater( other.north(), other.south() ) || !eckit::types::is_strictly_greater( other.east(), other.west() ); - if ( otherEmpty ) { - return contains( other.south(), other.west() ); - } + if ( otherEmpty ) { return contains( other.south(), other.west() ); } // check for West/East range (if non-periodic), then other's corners if ( east() - west() < other.east() - other.west() || east() < normalise( other.east(), west() ) ) { @@ -93,7 +90,7 @@ struct Rotation : std::array { config.set( "south_pole", std::vector( {south_pole_longitude(), south_pole_latitude()} ) ); atlas::Projection p( config ); - RectangularDomain before({box.west(), box.east()}, {box.south(), box.north()}); + RectangularDomain before( {box.west(), box.east()}, {box.south(), box.north()} ); Domain after = p.boundingBox( before ); ATLAS_ASSERT( after ); @@ -110,18 +107,13 @@ using NiNj = std::array; struct test_poles_t { public: - - test_poles_t(const NiNj& ninj, - const Rotation& rotation, - const BoundingBox& bbox, - bool includesNorthPole = false, - bool includesSouthPole = false) : - ninj_(ninj), - rotation_(rotation), - bbox_(bbox), - includesNorthPole_(includesNorthPole), - includesSouthPole_(includesSouthPole) { - } + test_poles_t( const NiNj& ninj, const Rotation& rotation, const BoundingBox& bbox, bool includesNorthPole = false, + bool includesSouthPole = false ) : + ninj_( ninj ), + rotation_( rotation ), + bbox_( bbox ), + includesNorthPole_( includesNorthPole ), + includesSouthPole_( includesSouthPole ) {} const NiNj ninj_; const Rotation rotation_; @@ -130,86 +122,84 @@ struct test_poles_t { const bool includesSouthPole_; private: - friend std::ostream& operator<<(std::ostream& out, const test_poles_t& test) { - return (out << "test:" - << "\n\t" << "NiNj = " << test.ninj_ - << "\n\t" << "Rotation = " << test.rotation_ - << "\n\t" << "BoundingBox = " << test.bbox_ - << "\n\t" << "includesNorthPole? " << test.includesNorthPole_ - << "\n\t" << "includesSouthPole? " << test.includesSouthPole_); + friend std::ostream& operator<<( std::ostream& out, const test_poles_t& test ) { + return ( out << "test:" + << "\n\t" + << "NiNj = " << test.ninj_ << "\n\t" + << "Rotation = " << test.rotation_ << "\n\t" + << "BoundingBox = " << test.bbox_ << "\n\t" + << "includesNorthPole? " << test.includesNorthPole_ << "\n\t" + << "includesSouthPole? " << test.includesSouthPole_ ); } }; //----------------------------------------------------------------------------- -CASE("MIR-282") { - auto old = Log::info().precision(16); +CASE( "MIR-282" ) { + auto old = Log::info().precision( 16 ); - std::vector test_poles { - { NiNj{ 124, 118}, Rotation(-35., 0.), BoundingBox{12, -14.5, -17.25, 16.25} }, - { NiNj{ 360, 181}, Rotation(-90., 0.), BoundingBox(), true, true }, - { NiNj{ 81, 56}, Rotation(-75., 15.), BoundingBox{75.1, -35., 20., 45.}, true }, - { NiNj{ 111, 86}, Rotation(-35., 15.), BoundingBox{40., -55., -45., 55.}, true }, - { NiNj{ 91, 76}, Rotation(-30., -15.), BoundingBox{35., -40., -40., 50.}, true }, - { NiNj{ 101, 81}, Rotation(-25., 0.), BoundingBox{40., -50., -40., 50.}, true }, - { NiNj{ 56, 61}, Rotation(-15., 45.), BoundingBox{30., -50., -30., 5.}, true }, - { NiNj{ 96, 91}, Rotation( 0., 80.), BoundingBox{50., -65., -40., 30.}, true }, + std::vector test_poles{ + {NiNj{124, 118}, Rotation( -35., 0. ), BoundingBox{12, -14.5, -17.25, 16.25}}, + {NiNj{360, 181}, Rotation( -90., 0. ), BoundingBox(), true, true}, + {NiNj{81, 56}, Rotation( -75., 15. ), BoundingBox{75.1, -35., 20., 45.}, true}, + {NiNj{111, 86}, Rotation( -35., 15. ), BoundingBox{40., -55., -45., 55.}, true}, + {NiNj{91, 76}, Rotation( -30., -15. ), BoundingBox{35., -40., -40., 50.}, true}, + {NiNj{101, 81}, Rotation( -25., 0. ), BoundingBox{40., -50., -40., 50.}, true}, + {NiNj{56, 61}, Rotation( -15., 45. ), BoundingBox{30., -50., -30., 5.}, true}, + {NiNj{96, 91}, Rotation( 0., 80. ), BoundingBox{50., -65., -40., 30.}, true}, - { NiNj{ 178, 143}, Rotation(-40., 10.), BoundingBox{22.7, -13.6, -5.9, 21.8} }, - { NiNj{ 117, 79}, Rotation(-43., 10.), BoundingBox{ 3.4, -6.8, -4.4, 4.8} }, - { NiNj{ 776, 492}, Rotation(-30., 0.), BoundingBox{18.1, -37.6, -31., 39.9} }, - { NiNj{ 149, 105}, Rotation(-76., 14.), BoundingBox{72., -32., 20., 42.} }, - { NiNj{ 240, 240}, Rotation(-30., -5.), BoundingBox{ 9.875, -15., -20., 14.875} }, + {NiNj{178, 143}, Rotation( -40., 10. ), BoundingBox{22.7, -13.6, -5.9, 21.8}}, + {NiNj{117, 79}, Rotation( -43., 10. ), BoundingBox{3.4, -6.8, -4.4, 4.8}}, + {NiNj{776, 492}, Rotation( -30., 0. ), BoundingBox{18.1, -37.6, -31., 39.9}}, + {NiNj{149, 105}, Rotation( -76., 14. ), BoundingBox{72., -32., 20., 42.}}, + {NiNj{240, 240}, Rotation( -30., -5. ), BoundingBox{9.875, -15., -20., 14.875}}, - { NiNj{ 13, 12}, Rotation(-15., 45.), BoundingBox{27.5, -46.5, -28, 1.5}, true }, - { NiNj{ 321, 370}, Rotation(-15., 45.), BoundingBox{27.5, -46.5, -28, 1.5}, true }, + {NiNj{13, 12}, Rotation( -15., 45. ), BoundingBox{27.5, -46.5, -28, 1.5}, true}, + {NiNj{321, 370}, Rotation( -15., 45. ), BoundingBox{27.5, -46.5, -28, 1.5}, true}, - { NiNj{ 202, 235}, Rotation( 0., 130.), BoundingBox{32.75, -86.75, -37.75, -26.15}, false }, - { NiNj{ 409, 309}, Rotation(-35., 15.), BoundingBox{36., -51., -41., 51.}, true }, + {NiNj{202, 235}, Rotation( 0., 130. ), BoundingBox{32.75, -86.75, -37.75, -26.15}, false}, + {NiNj{409, 309}, Rotation( -35., 15. ), BoundingBox{36., -51., -41., 51.}, true}, - { NiNj{ 171, 6}, Rotation(-35., 160.), BoundingBox{80., 30., 75., 200.} }, - { NiNj{ 81, 11}, Rotation( 30., -30.), BoundingBox{70., 120., 60., 200.} }, - { NiNj{ 261, 66}, Rotation( 45., -120.), BoundingBox{55., -120., -10., 140.} }, + {NiNj{171, 6}, Rotation( -35., 160. ), BoundingBox{80., 30., 75., 200.}}, + {NiNj{81, 11}, Rotation( 30., -30. ), BoundingBox{70., 120., 60., 200.}}, + {NiNj{261, 66}, Rotation( 45., -120. ), BoundingBox{55., -120., -10., 140.}}, - { NiNj{ 4, 4}, Rotation(50., 100.), BoundingBox{10., 70., -20., 100.} }, + {NiNj{4, 4}, Rotation( 50., 100. ), BoundingBox{10., 70., -20., 100.}}, }; - SECTION("MIR-282: rotated_ll covering North/South poles") { - for (auto& test : test_poles) { + SECTION( "MIR-282: rotated_ll covering North/South poles" ) { + for ( auto& test : test_poles ) { Log::info() << '\n' << test << std::endl; - const PointLonLat southPole( - test.rotation_.south_pole_longitude(), - test.rotation_.south_pole_latitude() ); + const PointLonLat southPole( test.rotation_.south_pole_longitude(), test.rotation_.south_pole_latitude() ); - const util::Rotation r(southPole); + const util::Rotation r( southPole ); // check bbox including poles (in the unrotated frame) - PointLonLat NP{ r.unrotate({0., 90.}) }; - PointLonLat SP{ r.unrotate({0., -90.}) }; + PointLonLat NP{r.unrotate( {0., 90.} )}; + PointLonLat SP{r.unrotate( {0., -90.} )}; - bool includesNorthPole = test.bbox_.contains(NP.lat(), NP.lon()); - bool includesSouthPole = test.bbox_.contains(SP.lat(), SP.lon()); + bool includesNorthPole = test.bbox_.contains( NP.lat(), NP.lon() ); + bool includesSouthPole = test.bbox_.contains( SP.lat(), SP.lon() ); Log::info() << "check:" - << "\n\t" << "NP = " << NP - << "\n\t" << "SP = " << SP - << "\n\t" << "includesNorthPole? " << includesNorthPole - << "\n\t" << "includesSouthPole? " << includesSouthPole - << std::endl; - - EXPECT(includesNorthPole == test.includesNorthPole_); - EXPECT(includesSouthPole == test.includesSouthPole_); - + << "\n\t" + << "NP = " << NP << "\n\t" + << "SP = " << SP << "\n\t" + << "includesNorthPole? " << includesNorthPole << "\n\t" + << "includesSouthPole? " << includesSouthPole << std::endl; + + EXPECT( includesNorthPole == test.includesNorthPole_ ); + EXPECT( includesSouthPole == test.includesSouthPole_ ); } } - SECTION("MIR-282: rotated_ll contained by cropping") { - for (auto& test : test_poles) { + SECTION( "MIR-282: rotated_ll contained by cropping" ) { + for ( auto& test : test_poles ) { Log::info() << '\n' << test << std::endl; double n = test.bbox_.north(); @@ -232,13 +222,10 @@ CASE("MIR-282") { Grid g = StructuredGrid( xspace, yspace, rotation, dom ); ATLAS_ASSERT( g ); - BoundingBox crop(test.rotation_.rotate(test.bbox_)); + BoundingBox crop( test.rotation_.rotate( test.bbox_ ) ); Log::info() << "contained by cropping" - << "\n\t " << test.bbox_ - << "\n\t + " << test.rotation_ - << "\n\t = " << crop - << std::endl; + << "\n\t " << test.bbox_ << "\n\t + " << test.rotation_ << "\n\t = " << crop << std::endl; for ( PointLonLat p : g.lonlat() ) { EXPECT( crop.contains( p.lat(), p.lon() ) ); @@ -248,7 +235,7 @@ CASE("MIR-282") { } - Log::info().precision(old); + Log::info().precision( old ); } //----------------------------------------------------------------------------- @@ -257,7 +244,6 @@ CASE("MIR-282") { } // namespace atlas -int main(int argc, char **argv) { +int main( int argc, char** argv ) { return atlas::test::run( argc, argv ); } - From 83da09eb45ccfc396b09da5bac6ca6849ca5b934 Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Thu, 4 Jul 2019 12:37:16 +0100 Subject: [PATCH 58/86] ATLAS-239 Streamable IrregularConnectivity --- src/atlas/mesh/Connectivity.cc | 65 ++++++++++++++- src/atlas/mesh/Connectivity.h | 26 +++++- src/tests/mesh/CMakeLists.txt | 2 +- src/tests/mesh/test_stream_connectivity.cc | 93 ++++++++++++++++++++++ 4 files changed, 180 insertions(+), 6 deletions(-) create mode 100644 src/tests/mesh/test_stream_connectivity.cc diff --git a/src/atlas/mesh/Connectivity.cc b/src/atlas/mesh/Connectivity.cc index 983527fd6..d7b98317c 100644 --- a/src/atlas/mesh/Connectivity.cc +++ b/src/atlas/mesh/Connectivity.cc @@ -11,6 +11,9 @@ #include #include +#include "eckit/io/Buffer.h" +#include "eckit/serialisation/Stream.h" + #include "atlas/array.h" #include "atlas/array/DataType.h" #include "atlas/array/MakeView.h" @@ -19,6 +22,8 @@ #include "atlas/mesh/Connectivity.h" #include "atlas/runtime/Exception.h" +#include "atlas/runtime/Log.h" + #if ATLAS_HAVE_FORTRAN #define FORTRAN_BASE 1 #define TO_FORTRAN +1 @@ -90,6 +95,10 @@ IrregularConnectivityImpl::IrregularConnectivityImpl( const IrregularConnectivit mincols_( other.mincols_ ), ctxt_( nullptr ) {} +IrregularConnectivityImpl::IrregularConnectivityImpl( eckit::Stream& s ) { + decode( s ); +} + //------------------------------------------------------------------------------------------------------ IrregularConnectivityImpl::~IrregularConnectivityImpl() { @@ -164,7 +173,7 @@ void IrregularConnectivityImpl::add( idx_t rows, idx_t cols, const idx_t values[ // ATLAS_ASSERT( displs_] != nullptr ); // ATLAS_ASSERT( data_[_counts_] != nullptr ); displs_.resize( new_rows + 1 ); - counts_.resize( new_rows + 1 ); + counts_.resize( new_rows ); for ( idx_t j = 0; rows_ < new_rows; ++rows_, ++j ) { displs_[rows_ + 1] = displs_[rows_] + cols; @@ -201,7 +210,7 @@ void IrregularConnectivityImpl::add( idx_t rows, const idx_t cols[] ) { new_size += cols[j]; idx_t new_rows = rows_ + rows; displs_.resize( new_rows + 1 ); - counts_.resize( new_rows + 1 ); + counts_.resize( new_rows ); for ( idx_t j = 0; rows_ < new_rows; ++rows_, ++j ) { displs_[rows_ + 1] = displs_[rows_] + cols[j]; @@ -230,7 +239,7 @@ void IrregularConnectivityImpl::add( idx_t rows, idx_t cols ) { // ATLAS_ASSERT( data_[_displs_] != nullptr ); // ATLAS_ASSERT( data_[_counts_] != nullptr ); displs_.resize( new_rows + 1 ); - counts_.resize( new_rows + 1 ); + counts_.resize( new_rows ); for ( idx_t j = 0; rows_ < new_rows; ++rows_, ++j ) { displs_[rows_ + 1] = displs_[rows_] + cols; @@ -343,6 +352,56 @@ void IrregularConnectivityImpl::dump( std::ostream& os ) const { //TODO dump } +eckit::Stream& operator>>( eckit::Stream& s, array::SVector& x ) { + size_t size; + s >> size; + eckit::Buffer buffer( size * sizeof( idx_t ) ); + s >> buffer; + idx_t* data = static_cast( buffer.data() ); + idx_t N = static_cast( size ); + x.resize( N ); + for ( idx_t i = 0; i < N; ++i ) { + x( i ) = data[i]; + } + return s; +} + +eckit::Stream& operator<<( eckit::Stream& s, const array::SVector& x ) { + size_t size = x.size(); + s << size; + eckit::Buffer buffer( reinterpret_cast( x.data() ), size * sizeof( idx_t ) ); + s << buffer; + return s; +} + +void IrregularConnectivityImpl::encode( eckit::Stream& s ) const { + s << name(); + s << owns_; + s << values_; + s << displs_; + s << counts_; + s << missing_value_; + s << rows_; + s << maxcols_; + s << mincols_; +} + + +void IrregularConnectivityImpl::decode( eckit::Stream& s ) { + std::string name; + s >> name; + s >> owns_; + s >> values_; + s >> displs_; + s >> counts_; + s >> missing_value_; + s >> rows_; + s >> maxcols_; + s >> mincols_; + if ( not name.empty() ) rename( name ); + ctxt_ = nullptr; +} + //------------------------------------------------------------------------------------------------------ /* } diff --git a/src/atlas/mesh/Connectivity.h b/src/atlas/mesh/Connectivity.h index 5e2be057a..aaabf7310 100644 --- a/src/atlas/mesh/Connectivity.h +++ b/src/atlas/mesh/Connectivity.h @@ -27,8 +27,6 @@ #include #include -#include "atlas/util/Object.h" - #include "atlas/array.h" #include "atlas/array/ArrayView.h" #include "atlas/array/DataType.h" @@ -37,6 +35,11 @@ #include "atlas/array/Vector.h" #include "atlas/array_fwd.h" #include "atlas/library/config.h" +#include "atlas/util/Object.h" + +namespace eckit { +class Stream; +} namespace atlas { namespace mesh { @@ -188,6 +191,9 @@ class IrregularConnectivityImpl { // it is compiled it for a GPU kernel IrregularConnectivityImpl( const IrregularConnectivityImpl& other ); + /// @brief Construct a mesh from a Stream (serialization) + explicit IrregularConnectivityImpl( eckit::Stream& ); + virtual ~IrregularConnectivityImpl(); //-- Accessors @@ -285,6 +291,22 @@ class IrregularConnectivityImpl { const idx_t* displs() const { return displs_.data(); } const idx_t* counts() const { return counts_.data(); } + /// @brief Serialization to Stream + void encode( eckit::Stream& ) const; + + /// @brief Serialization from Stream + void decode( eckit::Stream& ); + + friend eckit::Stream& operator<<( eckit::Stream& s, const IrregularConnectivityImpl& x ) { + x.encode( s ); + return s; + } + + friend eckit::Stream& operator>>( eckit::Stream& s, IrregularConnectivityImpl& x ) { + x.decode( s ); + return s; + } + private: void on_delete(); void on_update(); diff --git a/src/tests/mesh/CMakeLists.txt b/src/tests/mesh/CMakeLists.txt index 59fc4c6ea..87a3a7778 100644 --- a/src/tests/mesh/CMakeLists.txt +++ b/src/tests/mesh/CMakeLists.txt @@ -88,7 +88,7 @@ ecbuild_add_test( TARGET atlas_test_mesh_node2cell ) -foreach( test connectivity elements ll meshgen3d rgg ) +foreach( test connectivity stream_connectivity elements ll meshgen3d rgg ) ecbuild_add_test( TARGET atlas_test_${test} SOURCES test_${test}.cc LIBS atlas diff --git a/src/tests/mesh/test_stream_connectivity.cc b/src/tests/mesh/test_stream_connectivity.cc new file mode 100644 index 000000000..adc881fd2 --- /dev/null +++ b/src/tests/mesh/test_stream_connectivity.cc @@ -0,0 +1,93 @@ +/* + * (C) Copyright 2013 ECMWF. + * + * This software is licensed under the terms of the Apache Licence Version 2.0 + * which can be obtained at http://www.apache.org/licenses/LICENSE-2.0. + * In applying this licence, ECMWF does not waive the privileges and immunities + * granted to it by virtue of its status as an intergovernmental organisation + * nor does it submit to any jurisdiction. + */ + +#include "eckit/io/ResizableBuffer.h" +#include "eckit/serialisation/ResizableMemoryStream.h" + +#include "atlas/mesh/Connectivity.h" +#include "tests/AtlasTestEnvironment.h" + +using namespace atlas::mesh; + +namespace atlas { +namespace test { + +//----------------------------------------------------------------------------- + +CASE( "test_stream_irregular_connectivity" ) { + eckit::ResizableBuffer b{0}; + eckit::ResizableMemoryStream s{b}; + + // Create stream + { + IrregularConnectivity conn( "bla" ); + + constexpr idx_t vals[4] = {2, 3, 5, 6}; + conn.add( 1, 4, vals, /* fortran-array = */ false ); + + constexpr idx_t vals2[6] = {1, 3, 4, 3, 7, 8}; + conn.add( 2, 3, vals2, /* fortran-array = */ false ); + s << conn; + } + + + s.rewind(); + // Read from stream + { + IrregularConnectivity conn( s ); + EXPECT( conn.rows() == 3 ); + EXPECT( conn.cols( 0 ) == 4 ); + EXPECT( conn.cols( 1 ) == 3 ); + EXPECT( conn.cols( 2 ) == 3 ); + EXPECT( conn( 0, 0 ) == 2 ); + EXPECT( conn( 0, 1 ) == 3 ); + EXPECT( conn( 0, 2 ) == 5 ); + EXPECT( conn( 0, 3 ) == 6 ); + EXPECT( conn( 1, 0 ) == 1 ); + EXPECT( conn( 1, 1 ) == 3 ); + EXPECT( conn( 1, 2 ) == 4 ); + EXPECT( conn( 2, 0 ) == 3 ); + EXPECT( conn( 2, 1 ) == 7 ); + EXPECT( conn( 2, 2 ) == 8 ); + EXPECT( conn.name() == "bla" ); + } + + + s.rewind(); + // Read from stream + { + IrregularConnectivity conn; + s >> conn; + EXPECT( conn.rows() == 3 ); + EXPECT( conn.cols( 0 ) == 4 ); + EXPECT( conn.cols( 1 ) == 3 ); + EXPECT( conn.cols( 2 ) == 3 ); + EXPECT( conn( 0, 0 ) == 2 ); + EXPECT( conn( 0, 1 ) == 3 ); + EXPECT( conn( 0, 2 ) == 5 ); + EXPECT( conn( 0, 3 ) == 6 ); + EXPECT( conn( 1, 0 ) == 1 ); + EXPECT( conn( 1, 1 ) == 3 ); + EXPECT( conn( 1, 2 ) == 4 ); + EXPECT( conn( 2, 0 ) == 3 ); + EXPECT( conn( 2, 1 ) == 7 ); + EXPECT( conn( 2, 2 ) == 8 ); + EXPECT( conn.name() == "bla" ); + } +} + +//----------------------------------------------------------------------------- + +} // namespace test +} // namespace atlas + +int main( int argc, char** argv ) { + return atlas::test::run( argc, argv ); +} From ee72d75bf3a91d3fa78d695656676bd506ae4083 Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Fri, 5 Jul 2019 10:36:30 +0100 Subject: [PATCH 59/86] ATLAS-239 Streamable BlockConnectivity --- src/atlas/mesh/Connectivity.cc | 22 ++++++++++- src/atlas/mesh/Connectivity.h | 20 ++++++++++ src/tests/mesh/test_stream_connectivity.cc | 44 ++++++++++++++++++++++ 3 files changed, 84 insertions(+), 2 deletions(-) diff --git a/src/atlas/mesh/Connectivity.cc b/src/atlas/mesh/Connectivity.cc index d7b98317c..734dda657 100644 --- a/src/atlas/mesh/Connectivity.cc +++ b/src/atlas/mesh/Connectivity.cc @@ -376,7 +376,6 @@ eckit::Stream& operator<<( eckit::Stream& s, const array::SVector& x ) { void IrregularConnectivityImpl::encode( eckit::Stream& s ) const { s << name(); - s << owns_; s << values_; s << displs_; s << counts_; @@ -390,7 +389,6 @@ void IrregularConnectivityImpl::encode( eckit::Stream& s ) const { void IrregularConnectivityImpl::decode( eckit::Stream& s ) { std::string name; s >> name; - s >> owns_; s >> values_; s >> displs_; s >> counts_; @@ -400,6 +398,7 @@ void IrregularConnectivityImpl::decode( eckit::Stream& s ) { s >> mincols_; if ( not name.empty() ) rename( name ); ctxt_ = nullptr; + owns_ = true; } //------------------------------------------------------------------------------------------------------ @@ -660,6 +659,10 @@ BlockConnectivityImpl::BlockConnectivityImpl( idx_t rows, idx_t cols, idx_t valu } } +BlockConnectivityImpl::BlockConnectivityImpl( eckit::Stream& s ) { + decode( s ); +} + //------------------------------------------------------------------------------------------------------ BlockConnectivityImpl::BlockConnectivityImpl( idx_t rows, idx_t cols, idx_t values[], bool /*dummy*/ ) : @@ -707,6 +710,21 @@ void BlockConnectivityImpl::add( idx_t rows, idx_t cols, const idx_t values[], b } } +void BlockConnectivityImpl::encode( eckit::Stream& s ) const { + s << values_; + s << rows_; + s << cols_; + s << missing_value_; +} + +void BlockConnectivityImpl::decode( eckit::Stream& s ) { + owns_ = true; + s >> values_; + s >> rows_; + s >> cols_; + s >> missing_value_; +} + //------------------------------------------------------------------------------------------------------ size_t BlockConnectivityImpl::footprint() const { diff --git a/src/atlas/mesh/Connectivity.h b/src/atlas/mesh/Connectivity.h index aaabf7310..25bbecd9c 100644 --- a/src/atlas/mesh/Connectivity.h +++ b/src/atlas/mesh/Connectivity.h @@ -500,6 +500,9 @@ class BlockConnectivityImpl { BlockConnectivityImpl( BlockConnectivityImpl&& ) = default; BlockConnectivityImpl& operator=( const BlockConnectivityImpl& other ) = default; + /// @brief Construct a mesh from a Stream (serialization) + explicit BlockConnectivityImpl( eckit::Stream& ); + /// @brief Destructor ~BlockConnectivityImpl(); @@ -552,6 +555,23 @@ class BlockConnectivityImpl { bool owns() const { return owns_; } +protected: + /// @brief Serialization to Stream + void encode( eckit::Stream& ) const; + + /// @brief Serialization from Stream + void decode( eckit::Stream& ); + + friend eckit::Stream& operator<<( eckit::Stream& s, const BlockConnectivityImpl& x ) { + x.encode( s ); + return s; + } + + friend eckit::Stream& operator>>( eckit::Stream& s, BlockConnectivityImpl& x ) { + x.decode( s ); + return s; + } + private: bool owns_; array::SVector values_; diff --git a/src/tests/mesh/test_stream_connectivity.cc b/src/tests/mesh/test_stream_connectivity.cc index adc881fd2..ff714e6c6 100644 --- a/src/tests/mesh/test_stream_connectivity.cc +++ b/src/tests/mesh/test_stream_connectivity.cc @@ -85,6 +85,50 @@ CASE( "test_stream_irregular_connectivity" ) { //----------------------------------------------------------------------------- +CASE( "test_stream_block_connectivity" ) { + eckit::ResizableBuffer b{0}; + eckit::ResizableMemoryStream s{b}; + + // Create stream + { + BlockConnectivity conn( 2, 3, {1, 3, 4, 3, 7, 8} ); + s << conn; + } + + + s.rewind(); + // Read from stream + { + BlockConnectivity conn( s ); + EXPECT( conn.rows() == 2 ); + EXPECT( conn.cols() == 3 ); + EXPECT( conn( 0, 0 ) == 1 ); + EXPECT( conn( 0, 1 ) == 3 ); + EXPECT( conn( 0, 2 ) == 4 ); + EXPECT( conn( 1, 0 ) == 3 ); + EXPECT( conn( 1, 1 ) == 7 ); + EXPECT( conn( 1, 2 ) == 8 ); + } + + + s.rewind(); + // Read from stream + { + BlockConnectivity conn; + s >> conn; + EXPECT( conn.rows() == 2 ); + EXPECT( conn.cols() == 3 ); + EXPECT( conn( 0, 0 ) == 1 ); + EXPECT( conn( 0, 1 ) == 3 ); + EXPECT( conn( 0, 2 ) == 4 ); + EXPECT( conn( 1, 0 ) == 3 ); + EXPECT( conn( 1, 1 ) == 7 ); + EXPECT( conn( 1, 2 ) == 8 ); + } +} + +//----------------------------------------------------------------------------- + } // namespace test } // namespace atlas From b4a839c3760491ec3b449d2a1a2597ff0a843d92 Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Fri, 5 Jul 2019 11:05:53 +0100 Subject: [PATCH 60/86] ATLAS-239 Streamable MultiBlockConnectivity --- src/atlas/mesh/Connectivity.cc | 29 ++++++++++++--- src/atlas/mesh/Connectivity.h | 36 +++++++++++++++++-- src/tests/mesh/test_stream_connectivity.cc | 42 ++++++++++++++++++++++ 3 files changed, 101 insertions(+), 6 deletions(-) diff --git a/src/atlas/mesh/Connectivity.cc b/src/atlas/mesh/Connectivity.cc index 734dda657..04db72837 100644 --- a/src/atlas/mesh/Connectivity.cc +++ b/src/atlas/mesh/Connectivity.cc @@ -96,7 +96,7 @@ IrregularConnectivityImpl::IrregularConnectivityImpl( const IrregularConnectivit ctxt_( nullptr ) {} IrregularConnectivityImpl::IrregularConnectivityImpl( eckit::Stream& s ) { - decode( s ); + decode_( s ); } //------------------------------------------------------------------------------------------------------ @@ -374,7 +374,7 @@ eckit::Stream& operator<<( eckit::Stream& s, const array::SVector& x ) { return s; } -void IrregularConnectivityImpl::encode( eckit::Stream& s ) const { +void IrregularConnectivityImpl::encode_( eckit::Stream& s ) const { s << name(); s << values_; s << displs_; @@ -386,7 +386,7 @@ void IrregularConnectivityImpl::encode( eckit::Stream& s ) const { } -void IrregularConnectivityImpl::decode( eckit::Stream& s ) { +void IrregularConnectivityImpl::decode_( eckit::Stream& s ) { std::string name; s >> name; s >> values_; @@ -434,6 +434,10 @@ MultiBlockConnectivityImpl::MultiBlockConnectivityImpl( const std::string& name block_displs_( 0 ) = 0; } +MultiBlockConnectivityImpl::MultiBlockConnectivityImpl( eckit::Stream& s ) : IrregularConnectivityImpl( s ) { + decode_( s ); +} + //------------------------------------------------------------------------------------------------------ MultiBlockConnectivityImpl::~MultiBlockConnectivityImpl() {} @@ -591,7 +595,7 @@ void MultiBlockConnectivityImpl::insert( idx_t position, idx_t rows, const idx_t //------------------------------------------------------------------------------------------------------ void MultiBlockConnectivityImpl::rebuild_block_connectivity() { - block_.resize( blocks_, std::move( BlockConnectivityImpl() ) ); + block_.resize( blocks_, BlockConnectivityImpl() ); for ( idx_t b = 0; b < blocks_; ++b ) { block_[b].rebuild( block_displs_[b + 1] - block_displs_[b], // rows @@ -615,6 +619,23 @@ size_t MultiBlockConnectivityImpl::footprint() const { //------------------------------------------------------------------------------------------------------ +void MultiBlockConnectivityImpl::encode_( eckit::Stream& s ) const { + s << blocks_; + s << block_displs_; + s << block_cols_; +} + +//------------------------------------------------------------------------------------------------------ + +void MultiBlockConnectivityImpl::decode_( eckit::Stream& s ) { + s >> blocks_; + s >> block_displs_; + s >> block_cols_; + rebuild_block_connectivity(); +} + +//------------------------------------------------------------------------------------------------------ + BlockConnectivityImpl::BlockConnectivityImpl() : owns_( true ), values_( 0 ), diff --git a/src/atlas/mesh/Connectivity.h b/src/atlas/mesh/Connectivity.h index 25bbecd9c..56b3fce97 100644 --- a/src/atlas/mesh/Connectivity.h +++ b/src/atlas/mesh/Connectivity.h @@ -286,16 +286,19 @@ class IrregularConnectivityImpl { return os; } + virtual void encode( eckit::Stream& s ) const { encode_( s ); } + virtual void decode( eckit::Stream& s ) { decode_( s ); } + protected: bool owns() { return owns_; } const idx_t* displs() const { return displs_.data(); } const idx_t* counts() const { return counts_.data(); } /// @brief Serialization to Stream - void encode( eckit::Stream& ) const; + void encode_( eckit::Stream& ) const; /// @brief Serialization from Stream - void decode( eckit::Stream& ); + void decode_( eckit::Stream& ); friend eckit::Stream& operator<<( eckit::Stream& s, const IrregularConnectivityImpl& x ) { x.encode( s ); @@ -378,6 +381,9 @@ class MultiBlockConnectivityImpl : public IrregularConnectivityImpl { /// Data is owned MultiBlockConnectivityImpl( const std::string& name = "" ); + /// @brief Construct a mesh from a Stream (serialization) + explicit MultiBlockConnectivityImpl( eckit::Stream& ); + virtual ~MultiBlockConnectivityImpl(); //-- Accessors @@ -439,6 +445,32 @@ class MultiBlockConnectivityImpl : public IrregularConnectivityImpl { virtual size_t footprint() const; + virtual void encode( eckit::Stream& s ) const { + IrregularConnectivityImpl::encode_( s ); + encode_( s ); + } + virtual void decode( eckit::Stream& s ) { + IrregularConnectivityImpl::decode_( s ); + decode_( s ); + } + +protected: + /// @brief Serialization to Stream + void encode_( eckit::Stream& ) const; + + /// @brief Serialization from Stream + void decode_( eckit::Stream& ); + + friend eckit::Stream& operator<<( eckit::Stream& s, const MultiBlockConnectivityImpl& x ) { + x.encode( s ); + return s; + } + + friend eckit::Stream& operator>>( eckit::Stream& s, MultiBlockConnectivityImpl& x ) { + x.decode( s ); + return s; + } + private: void rebuild_block_connectivity(); diff --git a/src/tests/mesh/test_stream_connectivity.cc b/src/tests/mesh/test_stream_connectivity.cc index ff714e6c6..565631e2d 100644 --- a/src/tests/mesh/test_stream_connectivity.cc +++ b/src/tests/mesh/test_stream_connectivity.cc @@ -127,6 +127,48 @@ CASE( "test_stream_block_connectivity" ) { } } +CASE( "test_stream_multiblock_connectivity" ) { + eckit::ResizableBuffer b{0}; + eckit::ResizableMemoryStream s{b}; + + // Create stream + { + MultiBlockConnectivity conn( "mbc" ); + conn.add( BlockConnectivity{3, 5, {3, 7, 1, 4, 5, 6, 4, 56, 8, 4, 1, 3, 76, 4, 3}} ); + conn.add( BlockConnectivity{3, 2, {4, 75, 65, 45, 51, 35}} ); + s << conn; + } + + s.rewind(); + // Read from stream + { + MultiBlockConnectivity conn{s}; + EXPECT( conn.name() == "mbc" ); + EXPECT( conn.blocks() == 2 ); + EXPECT( conn( 3, 1 ) == 75 ); + EXPECT( conn( 4, 1 ) == 45 ); + EXPECT( conn( 5, 0 ) == 51 ); + EXPECT( conn( 1, 0, 1 ) == 75 ); + EXPECT( conn( 1, 1, 1 ) == 45 ); + EXPECT( conn( 1, 2, 0 ) == 51 ); + } + + s.rewind(); + // Read from stream + { + MultiBlockConnectivity conn; + s >> conn; + EXPECT( conn.name() == "mbc" ); + EXPECT( conn.blocks() == 2 ); + EXPECT( conn( 3, 1 ) == 75 ); + EXPECT( conn( 4, 1 ) == 45 ); + EXPECT( conn( 5, 0 ) == 51 ); + EXPECT( conn( 1, 0, 1 ) == 75 ); + EXPECT( conn( 1, 1, 1 ) == 45 ); + EXPECT( conn( 1, 2, 0 ) == 51 ); + } +} + //----------------------------------------------------------------------------- } // namespace test From c9e72c0ab87f64b38ef7ae3d87e477299ab8b167 Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Tue, 9 Jul 2019 09:42:02 +0100 Subject: [PATCH 61/86] Make sure clang-format is at version 5.0.1 --- tools/apply-clang-format.sh | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/tools/apply-clang-format.sh b/tools/apply-clang-format.sh index 4494e5dac..91532fe80 100755 --- a/tools/apply-clang-format.sh +++ b/tools/apply-clang-format.sh @@ -8,6 +8,19 @@ # granted to it by virtue of its status as an intergovernmental organisation nor # does it submit to any jurisdiction. +_REQUIRED_CLANG_VERSION='5.0.1' + +if ! [ -x "$(command -v clang-format)" ]; then + echo 'Error: clang-format is not installed.' >&2 + exit 1 +fi + +if ! [[ $(clang-format --version) =~ ${_REQUIRED_CLANG_VERSION} ]]; then + echo "Error: Require clang-format version: ${_REQUIRED_CLANG_VERSION}" + echo " > $(which clang-format) --version" + echo " $(clang-format --version)" + exit 1 +fi SCRIPTDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" cd $SCRIPTDIR/../src From e66698baf062b2c662d2859b9da29eef756c2713 Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Wed, 10 Jul 2019 13:29:20 +0100 Subject: [PATCH 62/86] Fix atlas-run for serial queues --- tools/atlas-run | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tools/atlas-run b/tools/atlas-run index dbbc82f0d..945c19d65 100755 --- a/tools/atlas-run +++ b/tools/atlas-run @@ -37,7 +37,10 @@ if [ -n "${ATLAS_RUN_NTHREADS}" ]; then export OMP_NUM_THREADS=${ATLAS_RUN_NTHREADS} fi -if command_exists aprun && [[ ${EC_queue:-unset} != "nf" ]] ; then +if command_exists aprun && \ + [[ ${EC_queue:-unset} != "nf" ]] && \ + [[ ${EC_queue:-unset} != "ns" ]] +then LAUNCH="aprun ${ATLAS_RUN_MPI_ARGS}" if [ -z "${ATLAS_RUN_NPROCS}" ]; then LAUNCH="${LAUNCH} -n 1" From aac174bbdc964c2dfcf4811d532dbbee1affbb81 Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Wed, 10 Jul 2019 14:06:01 +0100 Subject: [PATCH 63/86] atlas-run: Set ECKIT_MPI_FORCE=serial when nprocs undefined --- tools/atlas-run | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tools/atlas-run b/tools/atlas-run index 945c19d65..a2d73cce8 100755 --- a/tools/atlas-run +++ b/tools/atlas-run @@ -79,6 +79,10 @@ else fi fi +if [ -z "${ATLAS_RUN_NPROCS}" ]; then + export ECKIT_MPI_FORCE=serial +fi + echo + $LAUNCH "$@" $LAUNCH "$@" From 57103e1f9e728bbdf45f1f8fa96b58b4f7b2a21c Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Wed, 10 Jul 2019 15:39:26 +0100 Subject: [PATCH 64/86] atlas-run: Propagate environment variables to srun --- tools/atlas-run | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/atlas-run b/tools/atlas-run index a2d73cce8..89d7fa242 100755 --- a/tools/atlas-run +++ b/tools/atlas-run @@ -61,6 +61,7 @@ elif command_exists srun ; then else LAUNCH="${LAUNCH} -n ${ATLAS_RUN_NPROCS}" fi + SLURM_EXPORT_ENV=ALL # Required to propagate environment variables to srun'd program else if [[ ${ARCH:-unset} == "cray" ]]; then From a19a27af9913497a7bc808b44b0c340c71cbbc63 Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Wed, 10 Jul 2019 15:42:01 +0000 Subject: [PATCH 65/86] Cosmetic --- src/atlas/trans/ifs/TransIFS.cc | 208 -------------------------------- 1 file changed, 208 deletions(-) diff --git a/src/atlas/trans/ifs/TransIFS.cc b/src/atlas/trans/ifs/TransIFS.cc index 0f7e16355..68f9f4f00 100644 --- a/src/atlas/trans/ifs/TransIFS.cc +++ b/src/atlas/trans/ifs/TransIFS.cc @@ -1527,213 +1527,5 @@ void TransIFS::specnorm( const int nb_fields, const double spectra[], double nor /////////////////////////////////////////////////////////////////////////////// -// Moved to TransInterface -#if 0 - -extern "C" { - -TransIFS* atlas__Trans__new( const Grid::Implementation* grid, int nsmax ) { - ATLAS_ASSERT( grid != nullptr ); - return new TransIFS( Grid( grid ), nsmax ); -} - -void atlas__Trans__delete( TransIFS* This ) { - ATLAS_ASSERT( This != nullptr ); - delete This; -} - -int atlas__Trans__handle( const TransIFS* This ) { - ATLAS_ASSERT( This != nullptr ); - ::Trans_t* t = *This; - return t->handle; -} - -void atlas__Trans__distspec( const TransIFS* t, int nb_fields, int origin[], double global_spectra[], - double spectra[] ) { - ATLAS_ASSERT( t != nullptr ); - struct ::DistSpec_t args = new_distspec( t->trans() ); - args.nfld = nb_fields; - args.rspecg = global_spectra; - args.nfrom = origin; - args.rspec = spectra; - TRANS_CHECK(::trans_distspec( &args ) ); -} - -void atlas__Trans__gathspec( const TransIFS* t, int nb_fields, int destination[], double spectra[], - double global_spectra[] ) { - ATLAS_ASSERT( t != nullptr ); - struct ::GathSpec_t args = new_gathspec( t->trans() ); - args.nfld = nb_fields; - args.rspecg = global_spectra; - args.nto = destination; - args.rspec = spectra; - TRANS_CHECK(::trans_gathspec( &args ) ); -} - -void atlas__Trans__distgrid( const TransIFS* t, int nb_fields, int origin[], double global_fields[], double fields[] ) { - ATLAS_ASSERT( t != nullptr ); - struct ::DistGrid_t args = new_distgrid( t->trans() ); - args.nfld = nb_fields; - args.nfrom = origin; - args.rgpg = global_fields; - args.rgp = fields; - TRANS_CHECK(::trans_distgrid( &args ) ); -} - -void atlas__Trans__gathgrid( const TransIFS* t, int nb_fields, int destination[], double fields[], - double global_fields[] ) { - ATLAS_ASSERT( t = nullptr ); - struct ::GathGrid_t args = new_gathgrid( t->trans() ); - args.nfld = nb_fields; - args.nto = destination; - args.rgp = fields; - args.rgpg = global_fields; - TRANS_CHECK(::trans_gathgrid( &args ) ); -} - -void atlas__Trans__invtrans_scalar( const TransIFS* t, int nb_fields, double scalar_spectra[], - double scalar_fields[] ) { - ATLAS_ASSERT( t != nullptr ); - return t->invtrans( nb_fields, scalar_spectra, scalar_fields ); -} - -void atlas__Trans__invtrans_vordiv2wind( const TransIFS* t, int nb_fields, double vorticity_spectra[], - double divergence_spectra[], double wind_fields[] ) { - ATLAS_ASSERT( t != nullptr ); - return t->invtrans( nb_fields, vorticity_spectra, divergence_spectra, wind_fields ); -} - -void atlas__Trans__dirtrans_scalar( const TransIFS* t, int nb_fields, double scalar_fields[], - double scalar_spectra[] ) { - ATLAS_ASSERT( t != nullptr ); - return t->dirtrans( nb_fields, scalar_fields, scalar_spectra ); -} - -void atlas__Trans__dirtrans_wind2vordiv( const TransIFS* t, int nb_fields, double wind_fields[], - double vorticity_spectra[], double divergence_spectra[] ) { - ATLAS_ASSERT( t != nullptr ); - return t->dirtrans( nb_fields, wind_fields, vorticity_spectra, divergence_spectra ); -} - -void atlas__Trans__specnorm( const TransIFS* t, int nb_fields, double spectra[], double norms[], int rank ) { - ATLAS_ASSERT( t != nullptr ); - return t->specnorm( nb_fields, spectra, norms, rank ); -} - -int atlas__Trans__nspec2( const TransIFS* This ) { - ATLAS_ASSERT( This != nullptr ); - return This->trans()->nspec2; -} - -int atlas__Trans__nspec2g( const TransIFS* This ) { - ATLAS_ASSERT( This != nullptr ); - return This->trans()->nspec2g; -} - -int atlas__Trans__ngptot( const TransIFS* This ) { - ATLAS_ASSERT( This != nullptr ); - return This->trans()->ngptot; -} - -int atlas__Trans__ngptotg( const TransIFS* This ) { - ATLAS_ASSERT( This != nullptr ); - return This->trans()->ngptotg; -} - -int atlas__Trans__truncation( const TransIFS* This ) { - ATLAS_ASSERT( This != nullptr ); - return This->truncation(); -} - -const Grid::Implementation* atlas__Trans__grid( const TransIFS* This ) { - ATLAS_ASSERT( This != nullptr ); - ATLAS_ASSERT( This->grid() ); - return This->grid().get(); -} - -void atlas__Trans__dirtrans_fieldset( const TransIFS* This, const field::FieldSetImpl* gpfields, - field::FieldSetImpl* spfields, const eckit::Configuration* parameters ) { - ATLAS_ASSERT( This != nullptr ); - ATLAS_ASSERT( gpfields ); - ATLAS_ASSERT( spfields ); - ATLAS_ASSERT( parameters ); - FieldSet fspfields( spfields ); - This->dirtrans( gpfields, fspfields, *parameters ); -} - -void atlas__Trans__dirtrans_field( const TransIFS* This, const field::FieldImpl* gpfield, field::FieldImpl* spfield, - const eckit::Configuration* parameters ) { - ATLAS_ASSERT( This != nullptr ); - ATLAS_ASSERT( spfield ); - ATLAS_ASSERT( gpfield ); - ATLAS_ASSERT( parameters ); - Field fspfield( spfield ); - This->dirtrans( gpfield, fspfield, *parameters ); -} - -void atlas__Trans__invtrans_fieldset( const TransIFS* This, const field::FieldSetImpl* spfields, - field::FieldSetImpl* gpfields, const eckit::Configuration* parameters ) { - ATLAS_ASSERT( This != nullptr ); - ATLAS_ASSERT( spfields ); - ATLAS_ASSERT( gpfields ); - ATLAS_ASSERT( parameters ); - FieldSet fgpfields( gpfields ); - This->invtrans( spfields, fgpfields, *parameters ); -} - -void atlas__Trans__invtrans_field( const TransIFS* This, const field::FieldImpl* spfield, field::FieldImpl* gpfield, - const eckit::Configuration* parameters ) { - ATLAS_ASSERT( This != nullptr ); - ATLAS_ASSERT( spfield ); - ATLAS_ASSERT( gpfield ); - ATLAS_ASSERT( parameters ); - Field fgpfield( gpfield ); - This->invtrans( spfield, fgpfield, *parameters ); -} - -void atlas__Trans__dirtrans_wind2vordiv_field( const TransIFS* This, const field::FieldImpl* gpwind, - field::FieldImpl* spvor, field::FieldImpl* spdiv, - const eckit::Configuration* parameters ) { - ATLAS_ASSERT( This != nullptr ); - ATLAS_ASSERT( gpwind ); - ATLAS_ASSERT( spvor ); - ATLAS_ASSERT( spdiv ); - ATLAS_ASSERT( parameters ); - Field fspvor( spvor ); - Field fspdiv( spdiv ); - This->dirtrans_wind2vordiv( gpwind, fspvor, fspdiv, *parameters ); -} - -void atlas__Trans__invtrans_vordiv2wind_field( const TransIFS* This, const field::FieldImpl* spvor, - const field::FieldImpl* spdiv, field::FieldImpl* gpwind, - const eckit::Configuration* parameters ) { - ATLAS_ASSERT( This != nullptr ); - ATLAS_ASSERT( spvor ); - ATLAS_ASSERT( spdiv ); - ATLAS_ASSERT( gpwind ); - ATLAS_ASSERT( parameters ); - Field fgpwind( gpwind ); - This->invtrans_vordiv2wind( spvor, spdiv, fgpwind, *parameters ); -} - -void atlas__Trans__invtrans( const TransIFS* This, int nb_scalar_fields, double scalar_spectra[], int nb_vordiv_fields, - double vorticity_spectra[], double divergence_spectra[], double gp_fields[], - const eckit::Configuration* parameters ) { - ATLAS_ASSERT( This != nullptr ); - This->invtrans( nb_scalar_fields, scalar_spectra, nb_vordiv_fields, vorticity_spectra, divergence_spectra, - gp_fields, *parameters ); -} - -void atlas__Trans__invtrans_grad_field( const TransIFS* This, const field::FieldImpl* spfield, - field::FieldImpl* gpfield, const eckit::Configuration* config ) { - ATLAS_ASSERT( This != nullptr ); - ATLAS_ASSERT( spfield ); - ATLAS_ASSERT( gpfield ); - Field fgpfield( gpfield ); - This->invtrans_grad( spfield, fgpfield, *config ); -} -} -#endif - } // namespace trans } // namespace atlas From 4838f3aba606bae34a98a38a2f0193932573541b Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Wed, 10 Jul 2019 17:06:17 +0100 Subject: [PATCH 66/86] Fix compilation for older gnu 5 --- src/tests/projection/test_bounding_box.cc | 4 +- src/tests/projection/test_projection_LAEA.cc | 63 +++----------------- 2 files changed, 11 insertions(+), 56 deletions(-) diff --git a/src/tests/projection/test_bounding_box.cc b/src/tests/projection/test_bounding_box.cc index fd99d4268..17aecfe58 100644 --- a/src/tests/projection/test_bounding_box.cc +++ b/src/tests/projection/test_bounding_box.cc @@ -49,7 +49,7 @@ double normalise( double weird, double minimum ) { struct BoundingBox : public std::array { - BoundingBox( double n, double w, double s, double e ) : std::array{n, w, s, e} {} + BoundingBox( double n, double w, double s, double e ) : std::array( {n, w, s, e} ) {} BoundingBox() : BoundingBox( 90, 0, -90, 360 ) {} double north() const { return operator[]( 0 ); } @@ -81,7 +81,7 @@ struct BoundingBox : public std::array { struct Rotation : std::array { - Rotation( double lat, double lon ) : std::array{lon, lat} {} + Rotation( double lat, double lon ) : std::array( {lon, lat} ) {} double south_pole_latitude() const { return operator[]( 1 ); } double south_pole_longitude() const { return normalise( operator[]( 0 ), 0. ); } BoundingBox rotate( const BoundingBox& box ) const { diff --git a/src/tests/projection/test_projection_LAEA.cc b/src/tests/projection/test_projection_LAEA.cc index 477f585ac..ae028bd78 100644 --- a/src/tests/projection/test_projection_LAEA.cc +++ b/src/tests/projection/test_projection_LAEA.cc @@ -144,62 +144,17 @@ CASE( "test_grid_creation_from_GRIB" ) { EXPECT( n == g.size() ); } - // Get circumscribed LonLat bounding box ( Could be turned into memberfunction of StructuredGrid ) + // Check if bounding box is correct { - auto regulargrid = RegularGrid( g ); - NormaliseLongitude normalised( find_good_west( regulargrid ) ); - double maxlat = -90.; - double minlat = 90.; - double minlon = 360.; - double maxlon = -360.; - // top - { - idx_t j = 0; - for ( idx_t i = 0; i < regulargrid.nx(); ++i ) { - auto p = regulargrid.lonlat( i, j ); - minlon = std::min( minlon, normalised( p.lon() ) ); - maxlon = std::max( maxlon, normalised( p.lon() ) ); - minlat = std::min( minlat, p.lat() ); - maxlat = std::max( maxlat, p.lat() ); - } - } - // bottom - { - idx_t j = regulargrid.ny() - 1; - for ( idx_t i = 0; i < regulargrid.nx(); ++i ) { - auto p = regulargrid.lonlat( i, j ); - minlon = std::min( minlon, normalised( p.lon() ) ); - maxlon = std::max( maxlon, normalised( p.lon() ) ); - minlat = std::min( minlat, p.lat() ); - maxlat = std::max( maxlat, p.lat() ); - } - } - // left - { - idx_t i = 0; - for ( idx_t j = 0; j < regulargrid.ny(); ++j ) { - auto p = regulargrid.lonlat( i, j ); - minlon = std::min( minlon, normalised( p.lon() ) ); - maxlon = std::max( maxlon, normalised( p.lon() ) ); - minlat = std::min( minlat, p.lat() ); - maxlat = std::max( maxlat, p.lat() ); - } - } - // right - { - idx_t i = regulargrid.nx() - 1; - for ( idx_t j = 0; j < regulargrid.ny(); ++j ) { - auto p = regulargrid.lonlat( i, j ); - minlon = std::min( minlon, normalised( p.lon() ) ); - maxlon = std::max( maxlon, normalised( p.lon() ) ); - minlat = std::min( minlat, p.lat() ); - maxlat = std::max( maxlat, p.lat() ); - } + RectangularDomain bb{g.boundingBox()}; + const double tolerance = 1.e-6; + EXPECT( is_approximately_equal( bb.xmin(), -90.001, tolerance ) ); + EXPECT( is_approximately_equal( bb.xmax(), 41.883045, tolerance ) ); + EXPECT( is_approximately_equal( bb.ymin(), 3.817356, tolerance ) ); + EXPECT( is_approximately_equal( bb.ymax(), 76.041386, tolerance ) ); + for ( PointLonLat p : g.lonlat() ) { + EXPECT( bb.contains( p ) ); } - Log::info() << "n = " << maxlat << std::endl; - Log::info() << "s = " << minlat << std::endl; - Log::info() << "w = " << minlon << std::endl; - Log::info() << "e = " << maxlon << std::endl; } } From 1709329d81ab1603f743b4f1e739ce42b243ef9d Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Thu, 11 Jul 2019 09:44:50 +0000 Subject: [PATCH 67/86] Fix LambertAzimuthalEqualAreaProjection when round-off errors cause asin to become undefined Failing test was atlas_test_projection_LAEA on Cray --- .../LambertAzimuthalEqualAreaProjection.cc | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/atlas/projection/detail/LambertAzimuthalEqualAreaProjection.cc b/src/atlas/projection/detail/LambertAzimuthalEqualAreaProjection.cc index 3668013c0..fb3e6ec4d 100644 --- a/src/atlas/projection/detail/LambertAzimuthalEqualAreaProjection.cc +++ b/src/atlas/projection/detail/LambertAzimuthalEqualAreaProjection.cc @@ -23,7 +23,6 @@ #include "atlas/util/Constants.h" #include "atlas/util/Earth.h" - namespace atlas { namespace projection { namespace detail { @@ -63,7 +62,7 @@ void LambertAzimuthalEqualAreaProjection::xy2lonlat( double crd[] ) const { const double& y = crd[1]; const double rho = std::sqrt( x * x + y * y ); - if ( eckit::types::is_approximately_equal( rho, 0. ) ) { + if ( std::abs( rho ) < 1.e-12 ) { crd[0] = reference_[0]; crd[1] = reference_[1]; return; @@ -74,8 +73,17 @@ void LambertAzimuthalEqualAreaProjection::xy2lonlat( double crd[] ) const { double sin_c = std::sin( c ); double lon_r = lambda0_ + std::atan2( x * sin_c, rho * cos_phi1_ * cos_c - y * sin_phi1_ * sin_c ); - double lat_r = std::asin( cos_c * sin_phi1_ + y * sin_c * cos_phi1_ / rho ); - + double lat_r; + double sin_lat_r = cos_c * sin_phi1_ + y * sin_c * cos_phi1_ / rho; + if ( sin_lat_r > 1. ) { + lat_r = M_PI_2; + } + else if ( sin_lat_r < -1. ) { + lat_r = -M_PI_2; + } + else { + lat_r = std::asin( sin_lat_r ); + } crd[0] = lon_r * util::Constants::radiansToDegrees(); crd[1] = lat_r * util::Constants::radiansToDegrees(); } From f5ef2bfa325b0417a29d459347d16948c226410c Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Thu, 11 Jul 2019 13:12:48 +0000 Subject: [PATCH 68/86] ATLAS-242 Workaround until ATLAS-241 is addressed --- src/atlas/field/detail/FieldInterface.cc | 5 ++ src/atlas/field/detail/FieldInterface.h | 1 + src/atlas/functionspace/Spectral.cc | 17 ++++++ src/atlas_f/field/atlas_Field_module.fypp | 14 +++++ src/tests/functionspace/test_functionspace.cc | 8 ++- src/tests/trans/fctest_trans.F90 | 15 ++++++ src/tests/trans/test_trans.cc | 54 +++++++++++++++++-- tools/atlas-run | 1 + 8 files changed, 110 insertions(+), 5 deletions(-) diff --git a/src/atlas/field/detail/FieldInterface.cc b/src/atlas/field/detail/FieldInterface.cc index a03500dee..ed476d3ee 100644 --- a/src/atlas/field/detail/FieldInterface.cc +++ b/src/atlas/field/detail/FieldInterface.cc @@ -221,6 +221,11 @@ int atlas__Field__dirty( FieldImpl* This ) { return This->dirty(); } +int atlas__Field__contiguous( FieldImpl* This ) { + ATLAS_ASSERT( This != nullptr, "Cannot access uninitialised atlas_Field" ); + return This->array().contiguous(); +} + void atlas__Field__halo_exchange( FieldImpl* This, int on_device ) { ATLAS_ASSERT( This != nullptr, "Cannot halo-exchange uninitialised atlas_Field" ); return This->haloExchange( on_device ); diff --git a/src/atlas/field/detail/FieldInterface.h b/src/atlas/field/detail/FieldInterface.h index 830f654ed..7c0bf190c 100644 --- a/src/atlas/field/detail/FieldInterface.h +++ b/src/atlas/field/detail/FieldInterface.h @@ -63,6 +63,7 @@ void atlas__Field__sync_host_device( FieldImpl* This ); void atlas__Field__set_dirty( FieldImpl* This, int value ); void atlas__Field__halo_exchange( FieldImpl* This, int on_device ); int atlas__Field__dirty( FieldImpl* This ); +int atlas__Field__contiguous( FieldImpl* This ); } //---------------------------------------------------------------------------------------------------------------------- diff --git a/src/atlas/functionspace/Spectral.cc b/src/atlas/functionspace/Spectral.cc index a5d33d258..5b7e2d6fc 100644 --- a/src/atlas/functionspace/Spectral.cc +++ b/src/atlas/functionspace/Spectral.cc @@ -267,6 +267,12 @@ void Spectral::gather( const FieldSet& local_fieldset, FieldSet& global_fieldset nto[i] = root + 1; } + if( not loc.array().contiguous() ) { + throw_Exception( + "Cannot gather field "+loc.name()+ + " using IFS trans library as its data is not contiguous" ); + } + struct ::GathSpec_t args = new_gathspec( *parallelisation_ ); args.nfld = nto.size(); args.rspecg = glb.data(); @@ -316,6 +322,12 @@ void Spectral::scatter( const FieldSet& global_fieldset, FieldSet& local_fieldse nfrom[i] = root + 1; } + if( not loc.array().contiguous() ) { + throw_Exception( + "Cannot scatter field "+glb.name()+ + " using IFS trans library as its data is not contiguous" ); + } + struct ::DistSpec_t args = new_distspec( *parallelisation_ ); args.nfld = int( nfrom.size() ); args.rspecg = glb.data(); @@ -368,6 +380,11 @@ void Spectral::norm( const Field& field, double& norm, int rank ) const { } void Spectral::norm( const Field& field, double norm_per_level[], int rank ) const { #if ATLAS_HAVE_TRANS + if( not field.array().contiguous() ) { + throw_Exception( + "Cannot compute spectral norm of field "+field.name()+ + " using IFS trans library as its data is not contiguous" ); + } struct ::SpecNorm_t args = new_specnorm( *parallelisation_ ); args.nfld = std::max( 1, field.levels() ); args.rspec = field.data(); diff --git a/src/atlas_f/field/atlas_Field_module.fypp b/src/atlas_f/field/atlas_Field_module.fypp index c88073c3d..574c864c0 100644 --- a/src/atlas_f/field/atlas_Field_module.fypp +++ b/src/atlas_f/field/atlas_Field_module.fypp @@ -57,6 +57,7 @@ contains procedure :: levels => Field__levels procedure :: kind => Field__kind generic :: shape => shape_array, shape_idx + procedure :: contiguous procedure :: halo_exchange procedure :: dirty @@ -665,6 +666,19 @@ end function !------------------------------------------------------------------------------- +function contiguous(this) + use atlas_field_c_binding + logical :: contiguous + class(atlas_Field), intent(in) :: this + if( atlas__Field__contiguous(this%CPTR_PGIBUG_A) == 1 ) then + contiguous = .true. + else + contiguous = .false. + endif +end function + +!------------------------------------------------------------------------------- + ATLAS_FINAL subroutine atlas_Field__final_auto(this) type(atlas_Field), intent(inout) :: this #if FCKIT_FINAL_DEBUGGING diff --git a/src/tests/functionspace/test_functionspace.cc b/src/tests/functionspace/test_functionspace.cc index 00659cb19..f46330fb9 100644 --- a/src/tests/functionspace/test_functionspace.cc +++ b/src/tests/functionspace/test_functionspace.cc @@ -608,7 +608,13 @@ CASE( "test_SpectralFunctionSpace_norm" ) { std::vector threeD_norms( threeD_field.levels(), 0. ); spectral_fs.norm( twoD_field, twoD_norm ); - spectral_fs.norm( threeD_field, threeD_norms ); + if( not threeD_field.array().contiguous() ) { + EXPECT_THROWS_AS( spectral_fs.norm( threeD_field, threeD_norms ), eckit::Exception ); + return; + } + else { + EXPECT_NO_THROW( spectral_fs.norm( threeD_field, threeD_norms ) ); + } if ( eckit::mpi::comm().rank() == 0 ) { EXPECT( eckit::types::is_approximately_equal( twoD_norm, diff --git a/src/tests/trans/fctest_trans.F90 b/src/tests/trans/fctest_trans.F90 index f9721082e..6e8778222 100644 --- a/src/tests/trans/fctest_trans.F90 +++ b/src/tests/trans/fctest_trans.F90 @@ -201,6 +201,12 @@ end module fctest_atlas_trans_fixture call trans%invtrans_vordiv2wind(vorfield,divfield,windfield) glb_vorfield = spectral_fs%create_field(name="vorticity",kind=atlas_real(c_double),levels=nlev,global=.true.) + + if( .not. vorfield%contiguous() ) then + call fckit_log%error("No support for gather if fields are not contiguous") + return + endif + call spectral_fs%gather(vorfield,glb_vorfield) call spectral_fs%scatter(glb_vorfield,vorfield) @@ -378,6 +384,10 @@ end module fctest_atlas_trans_fixture do jfld=1,spfields%size() field = spfields%field(jfld) write(msg,*) "spectral field ",field%name(); call atlas_log%info(msg) + if( .not. field%contiguous() ) then + call fckit_log%error("No support for norm if fields are not contiguous") + return + endif call spectral%norm(field,norm) write(msg,*) "norm = ",norm; call atlas_log%info(msg) enddo @@ -437,6 +447,11 @@ end module fctest_atlas_trans_fixture enddo enddo +if( .not. field%contiguous() ) then + call fckit_log%error("No support for gather if fields are not contiguous") + return +endif + fieldg = spectral%create_field(atlas_real(c_double),global=.true.) call spectral%gather(field,fieldg) diff --git a/src/tests/trans/test_trans.cc b/src/tests/trans/test_trans.cc index 0115885da..dc8c2d6c3 100644 --- a/src/tests/trans/test_trans.cc +++ b/src/tests/trans/test_trans.cc @@ -89,6 +89,7 @@ void read_rspecg( Field spec ) { int nb_spectral_coefficients_global = functionspace::Spectral( spec.functionspace() ).nb_spectral_coefficients_global(); auto view = array::make_view( spec ); + ATLAS_ASSERT( view.shape( 0 ) == nb_spectral_coefficients_global ); ATLAS_ASSERT( view.shape( 1 ) >= 2 ); for ( int i = 0; i < nb_spectral_coefficients_global; ++i ) { view( i, 0 ) = ( i == 0 ? 1. : 0. ); // scalar field 1 @@ -100,6 +101,8 @@ void read_rspecg( Field spec ) { //----------------------------------------------------------------------------- +#if 1 + CASE( "test_trans_distribution_matches_atlas" ) { EXPECT( grid::Partitioner::exists( "trans" ) ); @@ -186,6 +189,9 @@ CASE( "test_write_read_cache" ) { } #endif +#endif + +#if 1 CASE( "test_distspec" ) { trans::TransIFS trans( Grid( "F80" ), 159 ); Log::info() << "Trans initialized" << std::endl; @@ -207,6 +213,8 @@ CASE( "test_distspec" ) { trans.gathgrid( nfld, nto.data(), rgp.data(), rgpg.data() ); if ( mpi::comm().rank() == 0 ) { + ATLAS_DEBUG_VAR( specnorms[0] ); + ATLAS_DEBUG_VAR( specnorms[1] ); EXPECT( eckit::types::is_approximately_equal( specnorms[0], 1., 1.e-10 ) ); EXPECT( eckit::types::is_approximately_equal( specnorms[1], 2., 1.e-10 ) ); } @@ -214,6 +222,8 @@ CASE( "test_distspec" ) { Log::info() << "end test_distspec" << std::endl; } +#endif + CASE( "test_distspec_speconly" ) { functionspace::Spectral fs( 159 ); int nfld = 2; @@ -224,16 +234,30 @@ CASE( "test_distspec_speconly" ) { Field dist = fs.createField( glb ); - fs.scatter( glb, dist ); - fs.norm( dist, specnorms ); + if( not dist.array().contiguous() ) { + EXPECT_THROWS_AS( fs.scatter( glb, dist ), eckit::Exception ); + if( mpi::comm().size() == 1 ) { + dist = glb; + EXPECT_THROWS_AS( fs.norm( dist, specnorms ), eckit::Exception ); + } + return; + } + else { + EXPECT_NO_THROW( fs.scatter( glb, dist) ); + EXPECT_NO_THROW( fs.norm( dist, specnorms ) ); + } + if ( mpi::comm().rank() == 0 ) { + ATLAS_DEBUG_VAR( specnorms[0] ); + ATLAS_DEBUG_VAR( specnorms[1] ); EXPECT( eckit::types::is_approximately_equal( specnorms[0], 1., 1.e-10 ) ); EXPECT( eckit::types::is_approximately_equal( specnorms[1], 2., 1.e-10 ) ); } Log::info() << "end test_distspec_only" << std::endl; } +#if 1 CASE( "test_distribution" ) { Grid g( "O80" ); @@ -334,7 +358,17 @@ CASE( "test_nomesh" ) { spg( imag ) = ( n == 0 ? 0 : -m * spectral.truncation() + n ); } ); - EXPECT_NO_THROW( spectral.scatter( spfg, spf ) ); + if( not spf.array().contiguous() ) { + EXPECT_THROWS_AS( spectral.scatter( spfg, spf ), eckit::Exception ); + if( mpi::comm().size() == 1 ) { + spf = spfg; + } + else { + return; + } + } else { + EXPECT_NO_THROW( spectral.scatter( spfg, spf ) ); + } array::ArrayView sp = array::make_view( spf ); @@ -362,7 +396,18 @@ CASE( "test_nomesh" ) { EXPECT_NO_THROW( trans.dirtrans( gpf, spf ) ); - EXPECT_NO_THROW( spectral.gather( spf, spfg ) ); + if( not spf.array().contiguous() ) { + EXPECT_THROWS_AS( spectral.gather( spf, spfg ), eckit::Exception ); + if( mpi::comm().size() == 1 ) { + spfg = spf; + } + else { + return; + } + } + else { + EXPECT_NO_THROW( spectral.gather( spf, spfg ) ); + } spectral.parallel_for( option::global(), [&]( idx_t real, idx_t imag, int n ) { EXPECT( is_approximately_equal( spg( real ), ( n == 0 ? 4. : 0. ), 0.001 ) ); @@ -543,6 +588,7 @@ CASE( "test_trans_VorDivToUV" ) { } } } +#endif //----------------------------------------------------------------------------- diff --git a/tools/atlas-run b/tools/atlas-run index 89d7fa242..abec4c045 100755 --- a/tools/atlas-run +++ b/tools/atlas-run @@ -81,6 +81,7 @@ else fi if [ -z "${ATLAS_RUN_NPROCS}" ]; then + echo + export ECKIT_MPI_FORCE=serial export ECKIT_MPI_FORCE=serial fi From d356ca7e7670aecc4d144f32a7bf90420b1cbb57 Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Thu, 11 Jul 2019 15:30:04 +0100 Subject: [PATCH 69/86] Fix compilation --- src/atlas/field/Field.cc | 4 ++++ src/atlas/field/Field.h | 2 ++ src/atlas/functionspace/Spectral.cc | 21 ++++++++--------- src/atlas/interpolation/method/Method.cc | 4 ++-- .../LambertAzimuthalEqualAreaProjection.cc | 4 +--- src/tests/functionspace/test_functionspace.cc | 2 +- src/tests/trans/test_trans.cc | 23 ++++++++----------- 7 files changed, 29 insertions(+), 31 deletions(-) diff --git a/src/atlas/field/Field.cc b/src/atlas/field/Field.cc index 5b57a50dd..18d8abd71 100644 --- a/src/atlas/field/Field.cc +++ b/src/atlas/field/Field.cc @@ -138,6 +138,10 @@ size_t Field::bytes() const { return get()->bytes(); } +bool Field::contiguous() const { + return array().contiguous(); +} + /// @brief Output information of field plus raw data void Field::dump( std::ostream& os ) const { get()->dump( os ); diff --git a/src/atlas/field/Field.h b/src/atlas/field/Field.h index 0ba7fe451..16a70bee0 100644 --- a/src/atlas/field/Field.h +++ b/src/atlas/field/Field.h @@ -125,6 +125,8 @@ class Field : public util::ObjectHandle { /// @brief Number of bytes occupied by the values of this field size_t bytes() const; + bool contiguous() const; + /// @brief Output information of field friend std::ostream& operator<<( std::ostream& os, const Field& v ); diff --git a/src/atlas/functionspace/Spectral.cc b/src/atlas/functionspace/Spectral.cc index 5b7e2d6fc..b6406e421 100644 --- a/src/atlas/functionspace/Spectral.cc +++ b/src/atlas/functionspace/Spectral.cc @@ -267,10 +267,9 @@ void Spectral::gather( const FieldSet& local_fieldset, FieldSet& global_fieldset nto[i] = root + 1; } - if( not loc.array().contiguous() ) { - throw_Exception( - "Cannot gather field "+loc.name()+ - " using IFS trans library as its data is not contiguous" ); + if ( not loc.contiguous() ) { + throw_Exception( "Cannot gather field " + loc.name() + + " using IFS trans library as its data is not contiguous" ); } struct ::GathSpec_t args = new_gathspec( *parallelisation_ ); @@ -322,10 +321,9 @@ void Spectral::scatter( const FieldSet& global_fieldset, FieldSet& local_fieldse nfrom[i] = root + 1; } - if( not loc.array().contiguous() ) { - throw_Exception( - "Cannot scatter field "+glb.name()+ - " using IFS trans library as its data is not contiguous" ); + if ( not loc.contiguous() ) { + throw_Exception( "Cannot scatter field " + glb.name() + + " using IFS trans library as its data is not contiguous" ); } struct ::DistSpec_t args = new_distspec( *parallelisation_ ); @@ -380,10 +378,9 @@ void Spectral::norm( const Field& field, double& norm, int rank ) const { } void Spectral::norm( const Field& field, double norm_per_level[], int rank ) const { #if ATLAS_HAVE_TRANS - if( not field.array().contiguous() ) { - throw_Exception( - "Cannot compute spectral norm of field "+field.name()+ - " using IFS trans library as its data is not contiguous" ); + if ( not field.contiguous() ) { + throw_Exception( "Cannot compute spectral norm of field " + field.name() + + " using IFS trans library as its data is not contiguous" ); } struct ::SpecNorm_t args = new_specnorm( *parallelisation_ ); args.nfld = std::max( 1, field.levels() ); diff --git a/src/atlas/interpolation/method/Method.cc b/src/atlas/interpolation/method/Method.cc index abccdf9fc..202fd2137 100644 --- a/src/atlas/interpolation/method/Method.cc +++ b/src/atlas/interpolation/method/Method.cc @@ -60,8 +60,8 @@ void Method::interpolate_field_rank1( const Field& src, Field& tgt ) const { throw_NotImplemented( "Only double precision interpolation is currently implemented with eckit backend", Here() ); } - ATLAS_ASSERT( src.array().contiguous() ); - ATLAS_ASSERT( tgt.array().contiguous() ); + ATLAS_ASSERT( src.contiguous() ); + ATLAS_ASSERT( tgt.contiguous() ); eckit::linalg::Vector v_src( array::make_view( src ).data(), src.shape( 0 ) ); eckit::linalg::Vector v_tgt( array::make_view( tgt ).data(), tgt.shape( 0 ) ); diff --git a/src/atlas/projection/detail/LambertAzimuthalEqualAreaProjection.cc b/src/atlas/projection/detail/LambertAzimuthalEqualAreaProjection.cc index fb3e6ec4d..67c7d962c 100644 --- a/src/atlas/projection/detail/LambertAzimuthalEqualAreaProjection.cc +++ b/src/atlas/projection/detail/LambertAzimuthalEqualAreaProjection.cc @@ -75,9 +75,7 @@ void LambertAzimuthalEqualAreaProjection::xy2lonlat( double crd[] ) const { double lon_r = lambda0_ + std::atan2( x * sin_c, rho * cos_phi1_ * cos_c - y * sin_phi1_ * sin_c ); double lat_r; double sin_lat_r = cos_c * sin_phi1_ + y * sin_c * cos_phi1_ / rho; - if ( sin_lat_r > 1. ) { - lat_r = M_PI_2; - } + if ( sin_lat_r > 1. ) { lat_r = M_PI_2; } else if ( sin_lat_r < -1. ) { lat_r = -M_PI_2; } diff --git a/src/tests/functionspace/test_functionspace.cc b/src/tests/functionspace/test_functionspace.cc index f46330fb9..e99b78237 100644 --- a/src/tests/functionspace/test_functionspace.cc +++ b/src/tests/functionspace/test_functionspace.cc @@ -608,7 +608,7 @@ CASE( "test_SpectralFunctionSpace_norm" ) { std::vector threeD_norms( threeD_field.levels(), 0. ); spectral_fs.norm( twoD_field, twoD_norm ); - if( not threeD_field.array().contiguous() ) { + if ( not threeD_field.contiguous() ) { EXPECT_THROWS_AS( spectral_fs.norm( threeD_field, threeD_norms ), eckit::Exception ); return; } diff --git a/src/tests/trans/test_trans.cc b/src/tests/trans/test_trans.cc index dc8c2d6c3..6256f7bc4 100644 --- a/src/tests/trans/test_trans.cc +++ b/src/tests/trans/test_trans.cc @@ -99,7 +99,7 @@ void read_rspecg( Field spec ) { Log::info() << "read_rspecg ... done" << std::endl; } -//----------------------------------------------------------------------------- + //----------------------------------------------------------------------------- #if 1 @@ -234,16 +234,16 @@ CASE( "test_distspec_speconly" ) { Field dist = fs.createField( glb ); - if( not dist.array().contiguous() ) { + if ( not dist.contiguous() ) { EXPECT_THROWS_AS( fs.scatter( glb, dist ), eckit::Exception ); - if( mpi::comm().size() == 1 ) { + if ( mpi::comm().size() == 1 ) { dist = glb; EXPECT_THROWS_AS( fs.norm( dist, specnorms ), eckit::Exception ); } return; } else { - EXPECT_NO_THROW( fs.scatter( glb, dist) ); + EXPECT_NO_THROW( fs.scatter( glb, dist ) ); EXPECT_NO_THROW( fs.norm( dist, specnorms ) ); } @@ -358,15 +358,14 @@ CASE( "test_nomesh" ) { spg( imag ) = ( n == 0 ? 0 : -m * spectral.truncation() + n ); } ); - if( not spf.array().contiguous() ) { + if ( not spf.contiguous() ) { EXPECT_THROWS_AS( spectral.scatter( spfg, spf ), eckit::Exception ); - if( mpi::comm().size() == 1 ) { - spf = spfg; - } + if ( mpi::comm().size() == 1 ) { spf = spfg; } else { return; } - } else { + } + else { EXPECT_NO_THROW( spectral.scatter( spfg, spf ) ); } @@ -396,11 +395,9 @@ CASE( "test_nomesh" ) { EXPECT_NO_THROW( trans.dirtrans( gpf, spf ) ); - if( not spf.array().contiguous() ) { + if ( not spf.contiguous() ) { EXPECT_THROWS_AS( spectral.gather( spf, spfg ), eckit::Exception ); - if( mpi::comm().size() == 1 ) { - spfg = spf; - } + if ( mpi::comm().size() == 1 ) { spfg = spf; } else { return; } From d07385d3f979c62f8d10b9251a4b91352ab0d0c4 Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Thu, 11 Jul 2019 16:28:31 +0100 Subject: [PATCH 70/86] Fix missing override keywords in Unstructured --- src/atlas/grid/detail/grid/Unstructured.h | 26 +++++++++++------------ 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/atlas/grid/detail/grid/Unstructured.h b/src/atlas/grid/detail/grid/Unstructured.h index b137dbd73..a476a41e5 100644 --- a/src/atlas/grid/detail/grid/Unstructured.h +++ b/src/atlas/grid/detail/grid/Unstructured.h @@ -150,8 +150,8 @@ class Unstructured : public Grid { public: // methods static std::string static_type() { return "unstructured"; } - virtual std::string name() const; - virtual std::string type() const { return static_type(); } + virtual std::string name() const override; + virtual std::string type() const override { return static_type(); } /// Constructor converting any Grid with domain to an unstructured grid Unstructured( const Grid&, Domain ); @@ -171,32 +171,32 @@ class Unstructured : public Grid { /// Constructor from initializer list Unstructured( std::initializer_list ); - virtual ~Unstructured(); + virtual ~Unstructured() override; - virtual idx_t size() const; + virtual idx_t size() const override; - virtual Spec spec() const; + virtual Spec spec() const override; PointXY xy( idx_t n ) const { return ( *points_ )[n]; } PointLonLat lonlat( idx_t n ) const { return projection_.lonlat( ( *points_ )[n] ); } - virtual IteratorXY* xy_begin() const { return new IteratorXY( *this ); } - virtual IteratorXY* xy_end() const { return new IteratorXY( *this, false ); } - virtual IteratorLonLat* lonlat_begin() const { return new IteratorLonLat( *this ); } - virtual IteratorLonLat* lonlat_end() const { return new IteratorLonLat( *this, false ); } - virtual IteratorXYPredicated* xy_begin( IteratorXY::Predicate p ) const { + virtual IteratorXY* xy_begin() const override { return new IteratorXY( *this ); } + virtual IteratorXY* xy_end() const override { return new IteratorXY( *this, false ); } + virtual IteratorLonLat* lonlat_begin() const override { return new IteratorLonLat( *this ); } + virtual IteratorLonLat* lonlat_end() const override { return new IteratorLonLat( *this, false ); } + virtual IteratorXYPredicated* xy_begin( IteratorXY::Predicate p ) const override { return new IteratorXYPredicated( *this, p ); } - virtual IteratorXYPredicated* xy_end( IteratorXY::Predicate p ) const { + virtual IteratorXYPredicated* xy_end( IteratorXY::Predicate p ) const override { return new IteratorXYPredicated( *this, p, false ); } private: // methods - virtual void print( std::ostream& ) const; + virtual void print( std::ostream& ) const override; /// Hash of the lonlat array - virtual void hash( eckit::Hash& ) const; + virtual void hash( eckit::Hash& ) const override; /// @return parallel/meridian limits containing the grid virtual Domain boundingBox() const override; From 38331175b624c262bb861ee6b2c3242607a849ce Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Thu, 11 Jul 2019 16:12:33 +0100 Subject: [PATCH 71/86] travis: enable more CI builds --- .travis.yml | 36 ++++++++++++++++-------------------- 1 file changed, 16 insertions(+), 20 deletions(-) diff --git a/.travis.yml b/.travis.yml index 4adb31759..48007cd9c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -75,26 +75,22 @@ matrix: - cgal - fftw - ################################## - # KNOWN TO FAIL, so comment - ################################## - - # - os: osx - # env: - # - CACHE_NAME=osx-clang-mpich - # - CXX_COMPILER='clang++' C_COMPILER='clang' Fortran_COMPILER='gfortran' - # - MPI=mpich - # osx_image: xcode9 - - # - os: linux - # compiler: gcc - # env: - # - CACHE_NAME=linux-pgi-openmpi - # - CXX_COMPILER='pgc++' C_COMPILER='pgcc' Fortran_COMPILER='pgfortran' - # - MPI='openmpi' - # - PGI_VERSION="CommunityEdition" - # - ECKIT_CMAKE_OPTIONS="-DRT_LIB=/usr/lib/x86_64-linux-gnu/librt.so -DCURSES_LIBRARY=/usr/lib/x86_64-linux-gnu/libcurses.so" - # - ATLAS_CMAKE_OPTIONS="-DCMAKE_BUILD_TYPE=DEBUG -DENABLE_FORTRAN=OFF" # Fortran tests known to be broken with pgi/17.10 + - os: osx + env: + - CACHE_NAME=osx-clang-mpich + - CXX_COMPILER='clang++' C_COMPILER='clang' Fortran_COMPILER='gfortran' + - MPI=mpich + osx_image: xcode9 + + - os: linux + compiler: gcc + env: + - CACHE_NAME=linux-pgi-openmpi + - CXX_COMPILER='pgc++' C_COMPILER='pgcc' Fortran_COMPILER='pgfortran' + - MPI='openmpi' + - PGI_VERSION="CommunityEdition" + - ECKIT_CMAKE_OPTIONS="-DENABLE_ECKIT-395=OFF -DRT_LIB=/usr/lib/x86_64-linux-gnu/librt.so -DCURSES_LIBRARY=/usr/lib/x86_64-linux-gnu/libcurses.so" + - ATLAS_CMAKE_OPTIONS="-DCMAKE_BUILD_TYPE=DEBUG" before_install: From 935842d819e13fd2383a71fb8fe386ac42a3fb56 Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Fri, 12 Jul 2019 10:18:00 +0100 Subject: [PATCH 72/86] ATLAS-240 rename {Grid,Projection}::boundingBox() to {Grid,Projection}::lonlatBoundingBox() and add RectangularLonLatDomain --- src/apps/atlas-grids.cc | 20 ++++++------- src/atlas/domain/Domain.cc | 6 ++-- src/atlas/domain/Domain.h | 29 +++++++++++++++---- src/atlas/domain/detail/RectangularDomain.h | 10 +++++++ src/atlas/domain/detail/ZonalBandDomain.cc | 2 +- src/atlas/domain/detail/ZonalBandDomain.h | 2 +- src/atlas/grid/Grid.cc | 4 +-- src/atlas/grid/Grid.h | 2 +- src/atlas/grid/detail/grid/Grid.h | 2 +- src/atlas/grid/detail/grid/Structured.cc | 4 +-- src/atlas/grid/detail/grid/Structured.h | 2 +- src/atlas/grid/detail/grid/Unstructured.cc | 4 +-- src/atlas/grid/detail/grid/Unstructured.h | 2 +- src/atlas/projection/Projection.cc | 4 +-- src/atlas/projection/Projection.h | 2 +- .../LambertAzimuthalEqualAreaProjection.h | 2 +- .../projection/detail/LambertProjection.h | 2 +- .../projection/detail/LonLatProjection.cc | 4 +-- .../projection/detail/LonLatProjection.h | 2 +- .../projection/detail/MercatorProjection.h | 2 +- src/atlas/projection/detail/ProjectionImpl.cc | 6 ++-- src/atlas/projection/detail/ProjectionImpl.h | 5 ++-- .../projection/detail/SchmidtProjection.h | 2 +- src/tests/projection/test_bounding_box.cc | 6 ++-- src/tests/projection/test_projection_LAEA.cc | 10 +++---- 25 files changed, 83 insertions(+), 53 deletions(-) diff --git a/src/apps/atlas-grids.cc b/src/apps/atlas-grids.cc index 60997983d..77fd53a97 100644 --- a/src/apps/atlas-grids.cc +++ b/src/apps/atlas-grids.cc @@ -296,21 +296,21 @@ int AtlasGrids::execute( const Args& args ) { std::vector bbox; if ( config_check.get( "bounding_box(n,w,s,e)", bbox ) && bbox.size() == 4 ) { - RectangularDomain rect = grid.boundingBox(); - if ( ( check_failed = !rect ) ) { + auto bb = grid.lonlatBoundingBox(); + if ( ( check_failed = !bb ) ) { out << "Check failed: cannot calculate bounding box for " << grid.spec() << std::endl; } - else if ( ( check_failed = !equal( rect.ymax(), bbox[0] ) ) ) { - out << "Check failed: n=" << rect.ymax() << " expected to be " << bbox[0] << std::endl; + else if ( ( check_failed = !equal( bb.north(), bbox[0] ) ) ) { + out << "Check failed: n=" << bb.north() << " expected to be " << bbox[0] << std::endl; } - else if ( ( check_failed = !equal( rect.xmin(), bbox[1] ) ) ) { - out << "Check failed: w=" << rect.xmin() << " expected to be " << bbox[1] << std::endl; + else if ( ( check_failed = !equal( bb.west(), bbox[1] ) ) ) { + out << "Check failed: w=" << bb.west() << " expected to be " << bbox[1] << std::endl; } - else if ( ( check_failed = !equal( rect.ymin(), bbox[2] ) ) ) { - out << "Check failed: s=" << rect.ymin() << " expected to be " << bbox[2] << std::endl; + else if ( ( check_failed = !equal( bb.south(), bbox[2] ) ) ) { + out << "Check failed: s=" << bb.south() << " expected to be " << bbox[2] << std::endl; } - else if ( ( check_failed = !equal( rect.xmax(), bbox[3] ) ) ) { - out << "Check failed: e=" << rect.xmax() << " expected to be " << bbox[3] << std::endl; + else if ( ( check_failed = !equal( bb.east(), bbox[3] ) ) ) { + out << "Check failed: e=" << bb.east() << " expected to be " << bbox[3] << std::endl; } } else { diff --git a/src/atlas/domain/Domain.cc b/src/atlas/domain/Domain.cc index 268533d2a..351c79e00 100644 --- a/src/atlas/domain/Domain.cc +++ b/src/atlas/domain/Domain.cc @@ -62,17 +62,17 @@ double RectangularDomain::ymax() const { } ZonalBandDomain::ZonalBandDomain( const Interval& y ) : - RectangularDomain( ( ZD::is_global( y ) ) ? new atlas::domain::GlobalDomain() + RectangularLonLatDomain( ( ZD::is_global( y ) ) ? new atlas::domain::GlobalDomain() : new atlas::domain::ZonalBandDomain( y ) ), domain_( dynamic_cast( get() ) ) {} ZonalBandDomain::ZonalBandDomain( const Interval& y, const double& west ) : - RectangularDomain( ( ZD::is_global( y ) ) ? new atlas::domain::GlobalDomain( west ) + RectangularLonLatDomain( ( ZD::is_global( y ) ) ? new atlas::domain::GlobalDomain( west ) : new atlas::domain::ZonalBandDomain( y, west ) ), domain_( dynamic_cast( get() ) ) {} ZonalBandDomain::ZonalBandDomain( const Domain& domain ) : - RectangularDomain( domain ), + RectangularLonLatDomain( domain ), domain_( dynamic_cast( get() ) ) {} GlobalDomain::GlobalDomain( const double& west ) : diff --git a/src/atlas/domain/Domain.h b/src/atlas/domain/Domain.h index 50dccff4a..10241692c 100644 --- a/src/atlas/domain/Domain.h +++ b/src/atlas/domain/Domain.h @@ -90,6 +90,7 @@ class Domain : public util::ObjectHandle { namespace domain { class RectangularDomain; +class RectangularLonLatDomain; } class RectangularDomain : public Domain { @@ -102,7 +103,7 @@ class RectangularDomain : public Domain { RectangularDomain( const Domain& ); - operator bool() { return domain_; } + operator bool() const { return domain_; } /// Checks if the x-value is contained in the domain bool contains_x( double x ) const; @@ -123,21 +124,39 @@ class RectangularDomain : public Domain { //--------------------------------------------------------------------------------------------------------------------- +class RectangularLonLatDomain : public RectangularDomain { +public: + using RectangularDomain::RectangularDomain; + RectangularLonLatDomain( const Interval& x, const Interval& y ) : + RectangularDomain( x, y, "degrees" ) {} + RectangularLonLatDomain( const double& north, const double& west, const double& south, const double& east) : + RectangularLonLatDomain( {west,east},{south,north} ) {} + + operator bool() const { return RectangularDomain::operator bool() && units() == "degrees"; } + + double west() const { return xmin(); } + double east() const { return xmax(); } + double north() const { return ymax(); } + double south() const { return ymin(); } +}; + +//--------------------------------------------------------------------------------------------------------------------- + namespace domain { class ZonalBandDomain; } -class ZonalBandDomain : public RectangularDomain { +class ZonalBandDomain : public RectangularLonLatDomain { public: using Interval = std::array; public: - using RectangularDomain::RectangularDomain; + using RectangularLonLatDomain::RectangularLonLatDomain; ZonalBandDomain( const Interval& y, const double& west ); ZonalBandDomain( const Interval& y ); ZonalBandDomain( const Domain& ); - operator bool() { return domain_; } + operator bool() const { return domain_; } private: const ::atlas::domain::ZonalBandDomain* domain_; @@ -156,7 +175,7 @@ class GlobalDomain : public ZonalBandDomain { GlobalDomain(); GlobalDomain( const Domain& ); - operator bool() { return domain_; } + operator bool() const { return domain_; } private: const ::atlas::domain::GlobalDomain* domain_; diff --git a/src/atlas/domain/detail/RectangularDomain.h b/src/atlas/domain/detail/RectangularDomain.h index cccacfd80..23974cf11 100644 --- a/src/atlas/domain/detail/RectangularDomain.h +++ b/src/atlas/domain/detail/RectangularDomain.h @@ -75,5 +75,15 @@ class RectangularDomain : public Domain { bool unit_degrees_; }; +class RectangularLonLatDomain : public RectangularDomain { +public: + RectangularLonLatDomain( const eckit::Parametrisation& config ) : RectangularDomain( config ) {} + RectangularLonLatDomain( const Interval& x, const Interval& y ) : RectangularDomain(x,y,"degrees") {} + double north() const { return ymax(); } + double south() const { return ymin(); } + double west() const { return xmin(); } + double east() const { return xmax(); } +}; + } // namespace domain } // namespace atlas diff --git a/src/atlas/domain/detail/ZonalBandDomain.cc b/src/atlas/domain/detail/ZonalBandDomain.cc index 902e5c84f..6612bd785 100644 --- a/src/atlas/domain/detail/ZonalBandDomain.cc +++ b/src/atlas/domain/detail/ZonalBandDomain.cc @@ -60,7 +60,7 @@ ZonalBandDomain::ZonalBandDomain( const eckit::Parametrisation& params ) : ZonalBandDomain::ZonalBandDomain( const Interval& interval_y ) : ZonalBandDomain( interval_y, /*west*/ 0. ) {} ZonalBandDomain::ZonalBandDomain( const Interval& interval_y, const double west ) : - RectangularDomain( {west, west + 360.}, interval_y, units_ ) { + RectangularLonLatDomain( {west, west + 360.}, interval_y ) { global_ = _is_global( ymin(), ymax() ); ymin_tol_ = ymin() - 1.e-6; ymax_tol_ = ymax() + 1.e-6; diff --git a/src/atlas/domain/detail/ZonalBandDomain.h b/src/atlas/domain/detail/ZonalBandDomain.h index 4e8494edc..f37aa2ab6 100644 --- a/src/atlas/domain/detail/ZonalBandDomain.h +++ b/src/atlas/domain/detail/ZonalBandDomain.h @@ -23,7 +23,7 @@ class ZonalBandDomain; namespace atlas { namespace domain { -class ZonalBandDomain : public atlas::domain::RectangularDomain { +class ZonalBandDomain : public atlas::domain::RectangularLonLatDomain { protected: static constexpr char units_[] = "degrees"; diff --git a/src/atlas/grid/Grid.cc b/src/atlas/grid/Grid.cc index 7ad8992d5..ab7eeb803 100644 --- a/src/atlas/grid/Grid.cc +++ b/src/atlas/grid/Grid.cc @@ -63,8 +63,8 @@ const Grid::Domain& Grid::domain() const { return get()->domain(); } -Grid::Domain Grid::boundingBox() const { - return get()->boundingBox(); +RectangularLonLatDomain Grid::lonlatBoundingBox() const { + return get()->lonlatBoundingBox(); } std::string Grid::name() const { diff --git a/src/atlas/grid/Grid.h b/src/atlas/grid/Grid.h index ba7bfc1a3..92aec02c3 100644 --- a/src/atlas/grid/Grid.h +++ b/src/atlas/grid/Grid.h @@ -73,7 +73,7 @@ class Grid : public util::ObjectHandle { const Projection& projection() const; const Domain& domain() const; - Domain boundingBox() const; + RectangularLonLatDomain lonlatBoundingBox() const; std::string name() const; std::string uid() const; diff --git a/src/atlas/grid/detail/grid/Grid.h b/src/atlas/grid/detail/grid/Grid.h index 2fddb63aa..a6a0def9b 100644 --- a/src/atlas/grid/detail/grid/Grid.h +++ b/src/atlas/grid/detail/grid/Grid.h @@ -100,7 +100,7 @@ class Grid : public util::Object { const Domain& domain() const { return domain_; } /// @return parallel/meridian limits containing the grid - virtual Domain boundingBox() const = 0; + virtual RectangularLonLatDomain lonlatBoundingBox() const = 0; /// @return projection (mapping between geographic coordinates and grid /// coordinates) diff --git a/src/atlas/grid/detail/grid/Structured.cc b/src/atlas/grid/detail/grid/Structured.cc index 2b5315139..344abe200 100644 --- a/src/atlas/grid/detail/grid/Structured.cc +++ b/src/atlas/grid/detail/grid/Structured.cc @@ -489,9 +489,9 @@ void Structured::hash( eckit::Hash& h ) const { domain().hash( h ); } -Grid::Domain Structured::boundingBox() const { +RectangularLonLatDomain Structured::lonlatBoundingBox() const { auto domain = computeDomain(); - return projection_ ? projection_.boundingBox( domain ) : domain; + return projection_ ? projection_.lonlatBoundingBox( domain ) : domain; } Grid::Spec Structured::spec() const { diff --git a/src/atlas/grid/detail/grid/Structured.h b/src/atlas/grid/detail/grid/Structured.h index d851fd918..3ff4e0f9d 100644 --- a/src/atlas/grid/detail/grid/Structured.h +++ b/src/atlas/grid/detail/grid/Structured.h @@ -380,7 +380,7 @@ class Structured : public Grid { virtual void hash( eckit::Hash& ) const override; - virtual Domain boundingBox() const override; + virtual RectangularLonLatDomain lonlatBoundingBox() const override; void computeTruePeriodicity(); diff --git a/src/atlas/grid/detail/grid/Unstructured.cc b/src/atlas/grid/detail/grid/Unstructured.cc index 798857db2..8027ffaa8 100644 --- a/src/atlas/grid/detail/grid/Unstructured.cc +++ b/src/atlas/grid/detail/grid/Unstructured.cc @@ -170,8 +170,8 @@ void Unstructured::hash( eckit::Hash& h ) const { projection().hash( h ); } -Grid::Domain Unstructured::boundingBox() const { - return projection_ ? projection_.boundingBox( domain_ ) : domain_; +RectangularLonLatDomain Unstructured::lonlatBoundingBox() const { + return projection_ ? projection_.lonlatBoundingBox( domain_ ) : domain_; } idx_t Unstructured::size() const { diff --git a/src/atlas/grid/detail/grid/Unstructured.h b/src/atlas/grid/detail/grid/Unstructured.h index a476a41e5..267906cfd 100644 --- a/src/atlas/grid/detail/grid/Unstructured.h +++ b/src/atlas/grid/detail/grid/Unstructured.h @@ -199,7 +199,7 @@ class Unstructured : public Grid { virtual void hash( eckit::Hash& ) const override; /// @return parallel/meridian limits containing the grid - virtual Domain boundingBox() const override; + virtual RectangularLonLatDomain lonlatBoundingBox() const override; protected: /// Storage of coordinate points diff --git a/src/atlas/projection/Projection.cc b/src/atlas/projection/Projection.cc index a8b121af1..f01e8b4c9 100644 --- a/src/atlas/projection/Projection.cc +++ b/src/atlas/projection/Projection.cc @@ -50,8 +50,8 @@ bool atlas::Projection::strictlyRegional() const { return get()->strictlyRegional(); } -Domain Projection::boundingBox( const Domain& domain ) const { - return get()->boundingBox( domain ); +RectangularLonLatDomain Projection::lonlatBoundingBox( const Domain& domain ) const { + return get()->lonlatBoundingBox( domain ); } Projection::Spec atlas::Projection::spec() const { diff --git a/src/atlas/projection/Projection.h b/src/atlas/projection/Projection.h index 9960c5657..8a43a8c4e 100644 --- a/src/atlas/projection/Projection.h +++ b/src/atlas/projection/Projection.h @@ -58,7 +58,7 @@ class Projection : public util::ObjectHandle PointXY xy( const PointLonLat& ) const; bool strictlyRegional() const; - Domain boundingBox( const Domain& ) const; + RectangularLonLatDomain lonlatBoundingBox( const Domain& ) const; Spec spec() const; diff --git a/src/atlas/projection/detail/LambertAzimuthalEqualAreaProjection.h b/src/atlas/projection/detail/LambertAzimuthalEqualAreaProjection.h index 9ead0b432..3df614b61 100644 --- a/src/atlas/projection/detail/LambertAzimuthalEqualAreaProjection.h +++ b/src/atlas/projection/detail/LambertAzimuthalEqualAreaProjection.h @@ -31,7 +31,7 @@ class LambertAzimuthalEqualAreaProjection final : public ProjectionImpl { void lonlat2xy( double crd[] ) const override; bool strictlyRegional() const override { return true; } - Domain boundingBox( const Domain& domain ) const override { return ProjectionImpl::boundingBox( domain ); } + RectangularLonLatDomain lonlatBoundingBox( const Domain& domain ) const override { return ProjectionImpl::lonlatBoundingBox( domain ); } // specification Spec spec() const override; diff --git a/src/atlas/projection/detail/LambertProjection.h b/src/atlas/projection/detail/LambertProjection.h index b697c132e..3d248b5d4 100644 --- a/src/atlas/projection/detail/LambertProjection.h +++ b/src/atlas/projection/detail/LambertProjection.h @@ -31,7 +31,7 @@ class LambertProjection final : public ProjectionImpl { void lonlat2xy( double crd[] ) const override; bool strictlyRegional() const override { return true; } - Domain boundingBox( const Domain& domain ) const override { return ProjectionImpl::boundingBox( domain ); } + RectangularLonLatDomain lonlatBoundingBox( const Domain& domain ) const override { return ProjectionImpl::lonlatBoundingBox( domain ); } // specification Spec spec() const override; diff --git a/src/atlas/projection/detail/LonLatProjection.cc b/src/atlas/projection/detail/LonLatProjection.cc index 11abf39b9..c7c306c36 100644 --- a/src/atlas/projection/detail/LonLatProjection.cc +++ b/src/atlas/projection/detail/LonLatProjection.cc @@ -37,12 +37,12 @@ template <> void LonLatProjectionT::lonlat2xy( double[] ) const {} template <> -Domain LonLatProjectionT::boundingBox( const Domain& domain ) const { +RectangularLonLatDomain LonLatProjectionT::lonlatBoundingBox( const Domain& domain ) const { return domain; } template -Domain LonLatProjectionT::boundingBox( const Domain& domain ) const { +RectangularLonLatDomain LonLatProjectionT::lonlatBoundingBox( const Domain& domain ) const { using eckit::types::is_strictly_greater; diff --git a/src/atlas/projection/detail/LonLatProjection.h b/src/atlas/projection/detail/LonLatProjection.h index e450e9803..204e04165 100644 --- a/src/atlas/projection/detail/LonLatProjection.h +++ b/src/atlas/projection/detail/LonLatProjection.h @@ -42,7 +42,7 @@ class LonLatProjectionT final : public ProjectionImpl { void lonlat2xy( double crd[] ) const override { rotation_.unrotate( crd ); } bool strictlyRegional() const override { return false; } - Domain boundingBox( const Domain& ) const override; + RectangularLonLatDomain lonlatBoundingBox( const Domain& ) const override; // specification Spec spec() const override; diff --git a/src/atlas/projection/detail/MercatorProjection.h b/src/atlas/projection/detail/MercatorProjection.h index aaa3515af..9cde218b3 100644 --- a/src/atlas/projection/detail/MercatorProjection.h +++ b/src/atlas/projection/detail/MercatorProjection.h @@ -32,7 +32,7 @@ class MercatorProjectionT final : public ProjectionImpl { void lonlat2xy( double crd[] ) const override; bool strictlyRegional() const override { return true; } // Mercator projection cannot be used for global grids - Domain boundingBox( const Domain& domain ) const override { return ProjectionImpl::boundingBox( domain ); } + RectangularLonLatDomain lonlatBoundingBox( const Domain& domain ) const override { return ProjectionImpl::lonlatBoundingBox( domain ); } // specification Spec spec() const override; diff --git a/src/atlas/projection/detail/ProjectionImpl.cc b/src/atlas/projection/detail/ProjectionImpl.cc index 84e3cc71f..7a9f1481b 100644 --- a/src/atlas/projection/detail/ProjectionImpl.cc +++ b/src/atlas/projection/detail/ProjectionImpl.cc @@ -103,8 +103,8 @@ ProjectionImpl::DerivateFactory::~DerivateFactory() = default; // -------------------------------------------------------------------------------------------------------------------- -ProjectionImpl::BoundLonLat::operator Domain() const { - return RectangularDomain( {min_[0], max_[0]}, {min_[1], max_[1]}, "degrees" ); +ProjectionImpl::BoundLonLat::operator RectangularLonLatDomain() const { + return RectangularLonLatDomain( {min_[0], max_[0]}, {min_[1], max_[1]} ); } bool ProjectionImpl::BoundLonLat::crossesDateLine( bool yes ) { @@ -153,7 +153,7 @@ const ProjectionImpl* ProjectionImpl::create( const eckit::Parametrisation& p ) throw_Exception( "type missing in Params", Here() ); } -Domain ProjectionImpl::boundingBox( const Domain& domain ) const { +RectangularLonLatDomain ProjectionImpl::lonlatBoundingBox( const Domain& domain ) const { using eckit::types::is_strictly_greater; diff --git a/src/atlas/projection/detail/ProjectionImpl.h b/src/atlas/projection/detail/ProjectionImpl.h index e21eee96e..220ae640d 100644 --- a/src/atlas/projection/detail/ProjectionImpl.h +++ b/src/atlas/projection/detail/ProjectionImpl.h @@ -25,6 +25,7 @@ class Hash; namespace atlas { class Domain; +class RectangularLonLatDomain; namespace util { class Config; } @@ -53,7 +54,7 @@ class ProjectionImpl : public util::Object { PointXY xy( const PointLonLat& ) const; virtual bool strictlyRegional() const = 0; - virtual Domain boundingBox( const Domain& ) const = 0; + virtual RectangularLonLatDomain lonlatBoundingBox( const Domain& ) const = 0; virtual Spec spec() const = 0; @@ -64,7 +65,7 @@ class ProjectionImpl : public util::Object { virtual void hash( eckit::Hash& ) const = 0; struct BoundLonLat { - operator Domain() const; + operator RectangularLonLatDomain() const; void extend( PointLonLat p, PointLonLat eps ); bool crossesDateLine( bool ); diff --git a/src/atlas/projection/detail/SchmidtProjection.h b/src/atlas/projection/detail/SchmidtProjection.h index c00ba31ff..bd4e33528 100644 --- a/src/atlas/projection/detail/SchmidtProjection.h +++ b/src/atlas/projection/detail/SchmidtProjection.h @@ -33,7 +33,7 @@ class SchmidtProjectionT final : public ProjectionImpl { void lonlat2xy( double crd[] ) const override; bool strictlyRegional() const override { return false; } // schmidt is global grid - Domain boundingBox( const Domain& domain ) const override { return ProjectionImpl::boundingBox( domain ); } + RectangularLonLatDomain lonlatBoundingBox( const Domain& domain ) const override { return ProjectionImpl::lonlatBoundingBox( domain ); } // specification Spec spec() const override; diff --git a/src/tests/projection/test_bounding_box.cc b/src/tests/projection/test_bounding_box.cc index 17aecfe58..7e8770870 100644 --- a/src/tests/projection/test_bounding_box.cc +++ b/src/tests/projection/test_bounding_box.cc @@ -91,13 +91,13 @@ struct Rotation : std::array { atlas::Projection p( config ); RectangularDomain before( {box.west(), box.east()}, {box.south(), box.north()} ); - Domain after = p.boundingBox( before ); + Domain after = p.lonlatBoundingBox( before ); ATLAS_ASSERT( after ); - RectangularDomain r( after ); + RectangularLonLatDomain r( after ); ATLAS_ASSERT( r ); - return {r.ymax(), r.xmin(), r.ymin(), r.xmax()}; + return {r.north(), r.west(), r.south(), r.east()}; } }; diff --git a/src/tests/projection/test_projection_LAEA.cc b/src/tests/projection/test_projection_LAEA.cc index ae028bd78..ccd89be76 100644 --- a/src/tests/projection/test_projection_LAEA.cc +++ b/src/tests/projection/test_projection_LAEA.cc @@ -146,12 +146,12 @@ CASE( "test_grid_creation_from_GRIB" ) { // Check if bounding box is correct { - RectangularDomain bb{g.boundingBox()}; + RectangularLonLatDomain bb{g.lonlatBoundingBox()}; const double tolerance = 1.e-6; - EXPECT( is_approximately_equal( bb.xmin(), -90.001, tolerance ) ); - EXPECT( is_approximately_equal( bb.xmax(), 41.883045, tolerance ) ); - EXPECT( is_approximately_equal( bb.ymin(), 3.817356, tolerance ) ); - EXPECT( is_approximately_equal( bb.ymax(), 76.041386, tolerance ) ); + EXPECT( is_approximately_equal( bb.west(), -90.001, tolerance ) ); + EXPECT( is_approximately_equal( bb.east(), 41.883045, tolerance ) ); + EXPECT( is_approximately_equal( bb.south(), 3.817356, tolerance ) ); + EXPECT( is_approximately_equal( bb.north(), 76.041386, tolerance ) ); for ( PointLonLat p : g.lonlat() ) { EXPECT( bb.contains( p ) ); } From 13550291961941eb85cfd22962b959e69f8d2c6e Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Fri, 12 Jul 2019 10:56:35 +0100 Subject: [PATCH 73/86] For fussy compilers --- src/atlas/grid/Spacing.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/atlas/grid/Spacing.h b/src/atlas/grid/Spacing.h index 94aa6943d..f8d65ef55 100644 --- a/src/atlas/grid/Spacing.h +++ b/src/atlas/grid/Spacing.h @@ -77,6 +77,7 @@ class LinearSpacing : public Spacing { public: using Spacing::Spacing; + LinearSpacing() = default; LinearSpacing( double start, double stop, long N, bool endpoint = true ); LinearSpacing( const Interval&, long N, bool endpoint = true ); }; @@ -86,6 +87,7 @@ class LinearSpacing : public Spacing { class GaussianSpacing : public Spacing { public: using Spacing::Spacing; + GaussianSpacing() = default; GaussianSpacing( long N ); }; From 40a0d8b72e2b60c497bcb17cc21a5c141c9a6ce2 Mon Sep 17 00:00:00 2001 From: Pedro Maciel Date: Fri, 12 Jul 2019 13:05:07 +0100 Subject: [PATCH 74/86] ATLAS-240, MIR-4, MIR-77, MIR-385, MIR-386: use atlas/util/CoordinateEnums.h --- .../LambertAzimuthalEqualAreaProjection.cc | 50 ++++++++----------- 1 file changed, 22 insertions(+), 28 deletions(-) diff --git a/src/atlas/projection/detail/LambertAzimuthalEqualAreaProjection.cc b/src/atlas/projection/detail/LambertAzimuthalEqualAreaProjection.cc index 67c7d962c..7430171c6 100644 --- a/src/atlas/projection/detail/LambertAzimuthalEqualAreaProjection.cc +++ b/src/atlas/projection/detail/LambertAzimuthalEqualAreaProjection.cc @@ -21,6 +21,7 @@ #include "atlas/runtime/Exception.h" #include "atlas/util/Config.h" #include "atlas/util/Constants.h" +#include "atlas/util/CoordinateEnums.h" #include "atlas/util/Earth.h" namespace atlas { @@ -30,41 +31,41 @@ namespace detail { LambertAzimuthalEqualAreaProjection::LambertAzimuthalEqualAreaProjection( const eckit::Parametrisation& params ) : radius_( util::Earth::radius() ) { - if ( !params.get( "radius", radius_ ) ) radius_ = util::Earth::radius(); - ATLAS_ASSERT( params.get( "central_longitude", reference_[0] ) ); - ATLAS_ASSERT( params.get( "standard_parallel", reference_[1] ) ); + ATLAS_ASSERT( params.get( "central_longitude", reference_[LON] ) ); + ATLAS_ASSERT( params.get( "standard_parallel", reference_[LAT] ) ); + params.get( "radius", radius_ = util::Earth::radius() ); - lambda0_ = util::Constants::degreesToRadians() * reference_[0]; - phi1_ = util::Constants::degreesToRadians() * reference_[1]; + lambda0_ = util::Constants::degreesToRadians() * reference_[LON]; + phi1_ = util::Constants::degreesToRadians() * reference_[LAT]; sin_phi1_ = std::sin( phi1_ ); cos_phi1_ = std::cos( phi1_ ); } void LambertAzimuthalEqualAreaProjection::lonlat2xy( double crd[] ) const { - double dlambda = util::Constants::degreesToRadians() * ( crd[0] - reference_.lon() ); + double dlambda = util::Constants::degreesToRadians() * ( crd[LON] - reference_.lon() ); double cos_dlambda = std::cos( dlambda ); double sin_dlambda = std::sin( dlambda ); - double phi = util::Constants::degreesToRadians() * crd[1]; + double phi = util::Constants::degreesToRadians() * crd[LAT]; double sin_phi = std::sin( phi ); double cos_phi = std::cos( phi ); double kp = radius_ * std::sqrt( 2. / ( 1. + sin_phi1_ * sin_phi + cos_phi1_ * cos_phi * cos_dlambda ) ); - crd[0] = kp * cos_phi * sin_dlambda; - crd[1] = kp * ( cos_phi1_ * sin_phi - sin_phi1_ * cos_phi * cos_dlambda ); + crd[XX] = kp * cos_phi * sin_dlambda; + crd[YY] = kp * ( cos_phi1_ * sin_phi - sin_phi1_ * cos_phi * cos_dlambda ); } void LambertAzimuthalEqualAreaProjection::xy2lonlat( double crd[] ) const { - const double& x = crd[0]; - const double& y = crd[1]; + const double& x = crd[XX]; + const double& y = crd[YY]; const double rho = std::sqrt( x * x + y * y ); if ( std::abs( rho ) < 1.e-12 ) { - crd[0] = reference_[0]; - crd[1] = reference_[1]; + crd[LON] = reference_[LON]; + crd[LAT] = reference_[LAT]; return; } @@ -72,26 +73,19 @@ void LambertAzimuthalEqualAreaProjection::xy2lonlat( double crd[] ) const { double cos_c = std::cos( c ); double sin_c = std::sin( c ); - double lon_r = lambda0_ + std::atan2( x * sin_c, rho * cos_phi1_ * cos_c - y * sin_phi1_ * sin_c ); - double lat_r; + double lon_r = lambda0_ + std::atan2( x * sin_c, rho * cos_phi1_ * cos_c - y * sin_phi1_ * sin_c ); double sin_lat_r = cos_c * sin_phi1_ + y * sin_c * cos_phi1_ / rho; - if ( sin_lat_r > 1. ) { lat_r = M_PI_2; } - else if ( sin_lat_r < -1. ) { - lat_r = -M_PI_2; - } - else { - lat_r = std::asin( sin_lat_r ); - } - crd[0] = lon_r * util::Constants::radiansToDegrees(); - crd[1] = lat_r * util::Constants::radiansToDegrees(); + + crd[LON] = lon_r * util::Constants::radiansToDegrees(); + crd[LAT] = sin_lat_r > 1 ? 90 : sin_lat_r < -1 ? -90 : util::Constants::radiansToDegrees() * std::asin( sin_lat_r ); } LambertAzimuthalEqualAreaProjection::Spec LambertAzimuthalEqualAreaProjection::spec() const { Spec proj; proj.set( "type", static_type() ); - proj.set( "central_longitude", reference_[0] ); - proj.set( "standard_parallel", reference_[1] ); + proj.set( "central_longitude", reference_[LON] ); + proj.set( "standard_parallel", reference_[LAT] ); proj.set( "radius", radius_ ); return proj; @@ -101,8 +95,8 @@ LambertAzimuthalEqualAreaProjection::Spec LambertAzimuthalEqualAreaProjection::s void LambertAzimuthalEqualAreaProjection::hash( eckit::Hash& h ) const { h.add( static_type() ); h.add( radius_ ); - h.add( reference_[0] ); - h.add( reference_[1] ); + h.add( reference_[LON] ); + h.add( reference_[LAT] ); } From 0791832526dd6a24e61f2580948335863678a98f Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Fri, 12 Jul 2019 14:24:52 +0100 Subject: [PATCH 75/86] Apply clang-format --- src/atlas/domain/Domain.cc | 4 ++-- src/atlas/domain/Domain.h | 9 ++++----- src/atlas/domain/detail/RectangularDomain.h | 2 +- .../detail/LambertAzimuthalEqualAreaProjection.h | 4 +++- src/atlas/projection/detail/LambertProjection.h | 4 +++- src/atlas/projection/detail/MercatorProjection.h | 4 +++- src/atlas/projection/detail/ProjectionImpl.h | 2 +- src/atlas/projection/detail/SchmidtProjection.h | 4 +++- 8 files changed, 20 insertions(+), 13 deletions(-) diff --git a/src/atlas/domain/Domain.cc b/src/atlas/domain/Domain.cc index 351c79e00..c3cd1fcc8 100644 --- a/src/atlas/domain/Domain.cc +++ b/src/atlas/domain/Domain.cc @@ -63,12 +63,12 @@ double RectangularDomain::ymax() const { ZonalBandDomain::ZonalBandDomain( const Interval& y ) : RectangularLonLatDomain( ( ZD::is_global( y ) ) ? new atlas::domain::GlobalDomain() - : new atlas::domain::ZonalBandDomain( y ) ), + : new atlas::domain::ZonalBandDomain( y ) ), domain_( dynamic_cast( get() ) ) {} ZonalBandDomain::ZonalBandDomain( const Interval& y, const double& west ) : RectangularLonLatDomain( ( ZD::is_global( y ) ) ? new atlas::domain::GlobalDomain( west ) - : new atlas::domain::ZonalBandDomain( y, west ) ), + : new atlas::domain::ZonalBandDomain( y, west ) ), domain_( dynamic_cast( get() ) ) {} ZonalBandDomain::ZonalBandDomain( const Domain& domain ) : diff --git a/src/atlas/domain/Domain.h b/src/atlas/domain/Domain.h index 10241692c..d77f832ff 100644 --- a/src/atlas/domain/Domain.h +++ b/src/atlas/domain/Domain.h @@ -91,7 +91,7 @@ class Domain : public util::ObjectHandle { namespace domain { class RectangularDomain; class RectangularLonLatDomain; -} +} // namespace domain class RectangularDomain : public Domain { public: @@ -127,10 +127,9 @@ class RectangularDomain : public Domain { class RectangularLonLatDomain : public RectangularDomain { public: using RectangularDomain::RectangularDomain; - RectangularLonLatDomain( const Interval& x, const Interval& y ) : - RectangularDomain( x, y, "degrees" ) {} - RectangularLonLatDomain( const double& north, const double& west, const double& south, const double& east) : - RectangularLonLatDomain( {west,east},{south,north} ) {} + RectangularLonLatDomain( const Interval& x, const Interval& y ) : RectangularDomain( x, y, "degrees" ) {} + RectangularLonLatDomain( const double& north, const double& west, const double& south, const double& east ) : + RectangularLonLatDomain( {west, east}, {south, north} ) {} operator bool() const { return RectangularDomain::operator bool() && units() == "degrees"; } diff --git a/src/atlas/domain/detail/RectangularDomain.h b/src/atlas/domain/detail/RectangularDomain.h index 23974cf11..8573fcad5 100644 --- a/src/atlas/domain/detail/RectangularDomain.h +++ b/src/atlas/domain/detail/RectangularDomain.h @@ -78,7 +78,7 @@ class RectangularDomain : public Domain { class RectangularLonLatDomain : public RectangularDomain { public: RectangularLonLatDomain( const eckit::Parametrisation& config ) : RectangularDomain( config ) {} - RectangularLonLatDomain( const Interval& x, const Interval& y ) : RectangularDomain(x,y,"degrees") {} + RectangularLonLatDomain( const Interval& x, const Interval& y ) : RectangularDomain( x, y, "degrees" ) {} double north() const { return ymax(); } double south() const { return ymin(); } double west() const { return xmin(); } diff --git a/src/atlas/projection/detail/LambertAzimuthalEqualAreaProjection.h b/src/atlas/projection/detail/LambertAzimuthalEqualAreaProjection.h index 3df614b61..095ffc7af 100644 --- a/src/atlas/projection/detail/LambertAzimuthalEqualAreaProjection.h +++ b/src/atlas/projection/detail/LambertAzimuthalEqualAreaProjection.h @@ -31,7 +31,9 @@ class LambertAzimuthalEqualAreaProjection final : public ProjectionImpl { void lonlat2xy( double crd[] ) const override; bool strictlyRegional() const override { return true; } - RectangularLonLatDomain lonlatBoundingBox( const Domain& domain ) const override { return ProjectionImpl::lonlatBoundingBox( domain ); } + RectangularLonLatDomain lonlatBoundingBox( const Domain& domain ) const override { + return ProjectionImpl::lonlatBoundingBox( domain ); + } // specification Spec spec() const override; diff --git a/src/atlas/projection/detail/LambertProjection.h b/src/atlas/projection/detail/LambertProjection.h index 3d248b5d4..e24b9d7bf 100644 --- a/src/atlas/projection/detail/LambertProjection.h +++ b/src/atlas/projection/detail/LambertProjection.h @@ -31,7 +31,9 @@ class LambertProjection final : public ProjectionImpl { void lonlat2xy( double crd[] ) const override; bool strictlyRegional() const override { return true; } - RectangularLonLatDomain lonlatBoundingBox( const Domain& domain ) const override { return ProjectionImpl::lonlatBoundingBox( domain ); } + RectangularLonLatDomain lonlatBoundingBox( const Domain& domain ) const override { + return ProjectionImpl::lonlatBoundingBox( domain ); + } // specification Spec spec() const override; diff --git a/src/atlas/projection/detail/MercatorProjection.h b/src/atlas/projection/detail/MercatorProjection.h index 9cde218b3..62ee6082b 100644 --- a/src/atlas/projection/detail/MercatorProjection.h +++ b/src/atlas/projection/detail/MercatorProjection.h @@ -32,7 +32,9 @@ class MercatorProjectionT final : public ProjectionImpl { void lonlat2xy( double crd[] ) const override; bool strictlyRegional() const override { return true; } // Mercator projection cannot be used for global grids - RectangularLonLatDomain lonlatBoundingBox( const Domain& domain ) const override { return ProjectionImpl::lonlatBoundingBox( domain ); } + RectangularLonLatDomain lonlatBoundingBox( const Domain& domain ) const override { + return ProjectionImpl::lonlatBoundingBox( domain ); + } // specification Spec spec() const override; diff --git a/src/atlas/projection/detail/ProjectionImpl.h b/src/atlas/projection/detail/ProjectionImpl.h index 220ae640d..d9f7c58a4 100644 --- a/src/atlas/projection/detail/ProjectionImpl.h +++ b/src/atlas/projection/detail/ProjectionImpl.h @@ -53,7 +53,7 @@ class ProjectionImpl : public util::Object { PointLonLat lonlat( const PointXY& ) const; PointXY xy( const PointLonLat& ) const; - virtual bool strictlyRegional() const = 0; + virtual bool strictlyRegional() const = 0; virtual RectangularLonLatDomain lonlatBoundingBox( const Domain& ) const = 0; virtual Spec spec() const = 0; diff --git a/src/atlas/projection/detail/SchmidtProjection.h b/src/atlas/projection/detail/SchmidtProjection.h index bd4e33528..3e5e93932 100644 --- a/src/atlas/projection/detail/SchmidtProjection.h +++ b/src/atlas/projection/detail/SchmidtProjection.h @@ -33,7 +33,9 @@ class SchmidtProjectionT final : public ProjectionImpl { void lonlat2xy( double crd[] ) const override; bool strictlyRegional() const override { return false; } // schmidt is global grid - RectangularLonLatDomain lonlatBoundingBox( const Domain& domain ) const override { return ProjectionImpl::lonlatBoundingBox( domain ); } + RectangularLonLatDomain lonlatBoundingBox( const Domain& domain ) const override { + return ProjectionImpl::lonlatBoundingBox( domain ); + } // specification Spec spec() const override; From df096f326453e3fc5fed85f8fd728bea49f211b5 Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Fri, 12 Jul 2019 14:19:40 +0100 Subject: [PATCH 76/86] Fix overwriting of Domain --- src/atlas/grid/detail/grid/Structured.cc | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/atlas/grid/detail/grid/Structured.cc b/src/atlas/grid/detail/grid/Structured.cc index 344abe200..d5fd494db 100644 --- a/src/atlas/grid/detail/grid/Structured.cc +++ b/src/atlas/grid/detail/grid/Structured.cc @@ -437,7 +437,9 @@ void Structured::crop( const Domain& dom ) { throw_Exception( errmsg.str(), Here() ); } } - domain_ = RectangularDomain( {xspace_.min(), xspace_.max()}, {yspace_.min(), yspace_.max()}, projection_.units() ); + domain_ = + dom ? dom + : RectangularDomain( {xspace_.min(), xspace_.max()}, {yspace_.min(), yspace_.max()}, projection_.units() ); } void Structured::computeTruePeriodicity() { @@ -490,8 +492,7 @@ void Structured::hash( eckit::Hash& h ) const { } RectangularLonLatDomain Structured::lonlatBoundingBox() const { - auto domain = computeDomain(); - return projection_ ? projection_.lonlatBoundingBox( domain ) : domain; + return projection_ ? projection_.lonlatBoundingBox( computeDomain() ) : domain(); } Grid::Spec Structured::spec() const { From 8dce1a8cbe2723086ee87a50d4d33cf57f9f89a2 Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Wed, 26 Jun 2019 14:12:21 +0100 Subject: [PATCH 77/86] ATLAS-237 Crossplatform grid hashes --- doc/example-grids/classic_gaussian_1.yml | 2 +- doc/example-grids/classic_gaussian_2.yml | 2 +- doc/example-grids/classic_gaussian_3.yml | 2 +- .../cropped_classic_gaussian_1.yml | 2 +- .../cropped_classic_gaussian_2.yml | 2 +- .../cropped_shifted_lonlat_1.yml | 2 +- doc/example-grids/custom_structured_1.yml | 2 +- doc/example-grids/custom_structured_2.yml | 2 +- doc/example-grids/custom_structured_3.yml | 2 +- doc/example-grids/custom_structured_4.yml | 2 +- doc/example-grids/custom_structured_5.yml | 2 +- doc/example-grids/custom_structured_6.yml | 2 +- doc/example-grids/custom_structured_7.yml | 2 +- doc/example-grids/octahedral_gaussian_1.yml | 2 +- doc/example-grids/octahedral_gaussian_2.yml | 2 +- doc/example-grids/octahedral_gaussian_3.yml | 2 +- doc/example-grids/octahedral_gaussian_4.yml | 2 +- doc/example-grids/regional_lambert_1.yml | 2 +- doc/example-grids/regional_lambert_2.yml | 2 +- ...egional_lambert_azimuthal_equal_area_1.yml | 2 +- ...egional_lambert_azimuthal_equal_area_2.yml | 2 +- doc/example-grids/regional_lonlat_1.yml | 2 +- .../regional_rotated_mercator_1.yml | 2 +- doc/example-grids/regular_gaussian_1.yml | 2 +- doc/example-grids/regular_gaussian_2.yml | 2 +- doc/example-grids/regular_gaussian_3.yml | 2 +- doc/example-grids/regular_gaussian_4.yml | 2 +- doc/example-grids/regular_lonlat_1.yml | 2 +- doc/example-grids/update_uid.py | 66 +++++++++++++++++++ doc/example-grids/zonal_band_1.yml | 2 +- doc/example-grids/zonal_band_2.yml | 2 +- doc/example-grids/zonal_band_3.yml | 2 +- src/atlas/domain/detail/RectangularDomain.cc | 10 ++- src/atlas/grid/detail/grid/Regional.cc | 1 - src/atlas/grid/detail/grid/Structured.cc | 23 +++++-- src/tests/grid/test_grid_hash.cc | 8 +-- 36 files changed, 126 insertions(+), 44 deletions(-) create mode 100755 doc/example-grids/update_uid.py diff --git a/doc/example-grids/classic_gaussian_1.yml b/doc/example-grids/classic_gaussian_1.yml index 2e393e6a7..2e82eac16 100644 --- a/doc/example-grids/classic_gaussian_1.yml +++ b/doc/example-grids/classic_gaussian_1.yml @@ -6,4 +6,4 @@ check : size : 1688 lonlat(first) : [0,85.7606] lonlat(last) : [342,-85.7606] - #uid : 7ad37fdbeaf287838c9396a5b857ccc7 + uid : 49cbbc2cde26050896e000d1e0f5fb7b diff --git a/doc/example-grids/classic_gaussian_2.yml b/doc/example-grids/classic_gaussian_2.yml index 5570620a3..ff8a3efdd 100644 --- a/doc/example-grids/classic_gaussian_2.yml +++ b/doc/example-grids/classic_gaussian_2.yml @@ -12,4 +12,4 @@ check : size : 1688 lonlat(first) : [3,44.8796] lonlat(last) : [-172.453,-54.9736] - #uid : f0caeff347f57954191e8e1d7b3a05b6 + uid : 64d609c6ee4b036b209047aef97a10eb diff --git a/doc/example-grids/classic_gaussian_3.yml b/doc/example-grids/classic_gaussian_3.yml index e37519c37..5f3313a0b 100644 --- a/doc/example-grids/classic_gaussian_3.yml +++ b/doc/example-grids/classic_gaussian_3.yml @@ -7,4 +7,4 @@ check : size : 1688 lonlat(first) : [0,85.7606] lonlat(last) : [342,-85.7606] - #uid : 7ad37fdbeaf287838c9396a5b857ccc7 + uid : 49cbbc2cde26050896e000d1e0f5fb7b diff --git a/doc/example-grids/cropped_classic_gaussian_1.yml b/doc/example-grids/cropped_classic_gaussian_1.yml index 760e6d8ea..5aefd105b 100644 --- a/doc/example-grids/cropped_classic_gaussian_1.yml +++ b/doc/example-grids/cropped_classic_gaussian_1.yml @@ -13,4 +13,4 @@ check : size : 332 lonlat(first) : [0,85.7606] lonlat(last) : [354,47.0696] - #uid : 6e7924fd98acefc8b163941796739636 + uid : 7f87a4865eb08403c179c6488c2eeeca diff --git a/doc/example-grids/cropped_classic_gaussian_2.yml b/doc/example-grids/cropped_classic_gaussian_2.yml index 2a28d5925..67440ca66 100644 --- a/doc/example-grids/cropped_classic_gaussian_2.yml +++ b/doc/example-grids/cropped_classic_gaussian_2.yml @@ -16,4 +16,4 @@ check : size : 144 lonlat(first) : [48.4615,41.5325] lonlat(last) : [90,-41.5325] - #uid : a6bef73fef7e852af21a61421d425583 + uid : e55a302d0bb56f50523e6bc2d28c4234 diff --git a/doc/example-grids/cropped_shifted_lonlat_1.yml b/doc/example-grids/cropped_shifted_lonlat_1.yml index bf6943270..cf480d6e0 100644 --- a/doc/example-grids/cropped_shifted_lonlat_1.yml +++ b/doc/example-grids/cropped_shifted_lonlat_1.yml @@ -11,4 +11,4 @@ check : size : 4140 lonlat(first) : [1,89] lonlat(last) : [359,45] - #uid : 9ada69c9f3b78c1bd81e8883df522d0a + uid : a1426cb32c8694d07d997cd224805947 diff --git a/doc/example-grids/custom_structured_1.yml b/doc/example-grids/custom_structured_1.yml index 7112fe560..90fb9e62b 100644 --- a/doc/example-grids/custom_structured_1.yml +++ b/doc/example-grids/custom_structured_1.yml @@ -9,4 +9,4 @@ check : size : 144 lonlat(first) : [0,90] lonlat(last) : [337.5,-90] - #uid : 302566694eed4568a78d3904e9eca6a6 + uid : 714c5d2db88b5eefdf8f789e8012f0aa diff --git a/doc/example-grids/custom_structured_2.yml b/doc/example-grids/custom_structured_2.yml index 697a5b047..6b07a94b7 100644 --- a/doc/example-grids/custom_structured_2.yml +++ b/doc/example-grids/custom_structured_2.yml @@ -9,4 +9,4 @@ check : size : 128 lonlat(first) : [0,73.7992] lonlat(last) : [337.5,-73.7992] - #uid : 1afa743f953ef3b1c628163029a8d612 + uid : 4db8793a3e589a0f497cbe84ff34e5b8 diff --git a/doc/example-grids/custom_structured_3.yml b/doc/example-grids/custom_structured_3.yml index db4b618a5..cc3c7edb3 100644 --- a/doc/example-grids/custom_structured_3.yml +++ b/doc/example-grids/custom_structured_3.yml @@ -17,4 +17,4 @@ check : size : 208 lonlat(first) : [0,73.7992] lonlat(last) : [342,-73.7992] - #uid : 662bfa00f7e6e928b2ffeb10726604ef + uid : 238a876f8ddaf43100fe643f1283f78a diff --git a/doc/example-grids/custom_structured_4.yml b/doc/example-grids/custom_structured_4.yml index 58d1af821..d31c44fa5 100644 --- a/doc/example-grids/custom_structured_4.yml +++ b/doc/example-grids/custom_structured_4.yml @@ -19,4 +19,4 @@ check : size : 208 lonlat(first) : [0,73.7992] lonlat(last) : [342,-73.7992] - #uid : 662bfa00f7e6e928b2ffeb10726604ef + uid : 238a876f8ddaf43100fe643f1283f78a diff --git a/doc/example-grids/custom_structured_5.yml b/doc/example-grids/custom_structured_5.yml index 869d7e8fd..366a2bdb9 100644 --- a/doc/example-grids/custom_structured_5.yml +++ b/doc/example-grids/custom_structured_5.yml @@ -10,4 +10,4 @@ check : size : 144 lonlat(first) : [3,40] lonlat(last) : [-177,-40] - #uid : 7f70607c136c64cc9c756ea5addc261e + uid : d55211f27c4a8c6ce94ea67f0c706e22 diff --git a/doc/example-grids/custom_structured_6.yml b/doc/example-grids/custom_structured_6.yml index 138769ff1..184a2b125 100644 --- a/doc/example-grids/custom_structured_6.yml +++ b/doc/example-grids/custom_structured_6.yml @@ -20,4 +20,4 @@ check: size : 128 lonlat(first) : [0,73.7992] lonlat(last) : [326.25,-73.7992] - #uid : e975c4aa4103780e461407a20d1b5a62 + uid : d5944053929a124fd786c2121ba3d064 diff --git a/doc/example-grids/custom_structured_7.yml b/doc/example-grids/custom_structured_7.yml index 762fd6a59..cc964b25d 100644 --- a/doc/example-grids/custom_structured_7.yml +++ b/doc/example-grids/custom_structured_7.yml @@ -9,4 +9,4 @@ check : size : 72 lonlat(first) : [0,75] lonlat(last) : [330,-75] - #uid : 088f8c4b8acca09987e4b8c0b0dad2c3 + uid : 76839204fa9d69232192dedc19ecef08 diff --git a/doc/example-grids/octahedral_gaussian_1.yml b/doc/example-grids/octahedral_gaussian_1.yml index 59a2710ea..86f153520 100644 --- a/doc/example-grids/octahedral_gaussian_1.yml +++ b/doc/example-grids/octahedral_gaussian_1.yml @@ -8,4 +8,4 @@ check : size : 1600 lonlat(first) : [0,85.7606] lonlat(last) : [342,-85.7606] - #uid : 00b0d36c51c046c2cce8fe51e37bdc63 + uid : 957667adfecf4f2394e4ec9bb0b25569 diff --git a/doc/example-grids/octahedral_gaussian_2.yml b/doc/example-grids/octahedral_gaussian_2.yml index a4baff8ca..83c0f887d 100644 --- a/doc/example-grids/octahedral_gaussian_2.yml +++ b/doc/example-grids/octahedral_gaussian_2.yml @@ -9,4 +9,4 @@ check : size : 1600 lonlat(first) : [3,45.9397] lonlat(last) : [-165.776,-62.6128] - #uid : 4978cdc0774cb3a27407591e79b4188c + uid : 20308244515b7c78e22709ebaa842246 diff --git a/doc/example-grids/octahedral_gaussian_3.yml b/doc/example-grids/octahedral_gaussian_3.yml index cb8fd9cc0..78ca9ce89 100644 --- a/doc/example-grids/octahedral_gaussian_3.yml +++ b/doc/example-grids/octahedral_gaussian_3.yml @@ -7,4 +7,4 @@ check : size : 1600 lonlat(first) : [0,85.7606] lonlat(last) : [342,-85.7606] - #uid : 00b0d36c51c046c2cce8fe51e37bdc63 + uid : 957667adfecf4f2394e4ec9bb0b25569 diff --git a/doc/example-grids/octahedral_gaussian_4.yml b/doc/example-grids/octahedral_gaussian_4.yml index 9c50c1e51..8bbf9f3ab 100644 --- a/doc/example-grids/octahedral_gaussian_4.yml +++ b/doc/example-grids/octahedral_gaussian_4.yml @@ -8,4 +8,4 @@ check : size : 1600 lonlat(first) : [3,45.9397] lonlat(last) : [-165.776,-62.6128] - #uid : 4978cdc0774cb3a27407591e79b4188c + uid : 20308244515b7c78e22709ebaa842246 diff --git a/doc/example-grids/regional_lambert_1.yml b/doc/example-grids/regional_lambert_1.yml index fe71ef461..a14493a4a 100644 --- a/doc/example-grids/regional_lambert_1.yml +++ b/doc/example-grids/regional_lambert_1.yml @@ -15,4 +15,4 @@ check : size : 2000 lonlat(first) : [-10.3173,40.22] lonlat(last) : [24.4368,57.2335] - #uid : 0ab14f4f37966a6760d0f5ee9176ad48 + uid : 1cb0b7c8f91617c3b6065d72b85c65c4 diff --git a/doc/example-grids/regional_lambert_2.yml b/doc/example-grids/regional_lambert_2.yml index 20f8dd009..6e73b4746 100644 --- a/doc/example-grids/regional_lambert_2.yml +++ b/doc/example-grids/regional_lambert_2.yml @@ -15,4 +15,4 @@ check : size : 151987 lonlat(first) : [-126.138,16.281] lonlat(last) : [-57.3811,55.4813] - #uid : cc3b50fa2a333cb749324321af25a15b + uid : ec98b263e57286710aeb4131a614b5f9 diff --git a/doc/example-grids/regional_lambert_azimuthal_equal_area_1.yml b/doc/example-grids/regional_lambert_azimuthal_equal_area_1.yml index f9f33534e..c1614676a 100644 --- a/doc/example-grids/regional_lambert_azimuthal_equal_area_1.yml +++ b/doc/example-grids/regional_lambert_azimuthal_equal_area_1.yml @@ -15,4 +15,4 @@ check : size : 2000 lonlat(first) : [-10.4643,40.1877] lonlat(last) : [24.6228,57.1968] - #uid : 7f71ee81a94c8cf92a2280e8a7828a32 + uid : 16663e1f4f3deb724712dd2698008915 diff --git a/doc/example-grids/regional_lambert_azimuthal_equal_area_2.yml b/doc/example-grids/regional_lambert_azimuthal_equal_area_2.yml index fa24ae752..48a72cb50 100644 --- a/doc/example-grids/regional_lambert_azimuthal_equal_area_2.yml +++ b/doc/example-grids/regional_lambert_azimuthal_equal_area_2.yml @@ -18,4 +18,4 @@ check : lonlat(first) : [-35.034,66.9821] lonlat(last) : [41.2436,23.8962] bounding_box(n,w,s,e) : [72.647, -35.035, 23.895, 74.144] - #uid : 09fcf68cb6f8871668dbef411b45a559 + uid : a87b2f233e26156d01c05a9ef2466721 diff --git a/doc/example-grids/regional_lonlat_1.yml b/doc/example-grids/regional_lonlat_1.yml index b64c99056..b4bd24e63 100644 --- a/doc/example-grids/regional_lonlat_1.yml +++ b/doc/example-grids/regional_lonlat_1.yml @@ -12,4 +12,4 @@ check : size : 875 lonlat(first) : [100,-50] lonlat(last) : [170,-10] - #uid : 4e4386c0a0f4aafc12fd45843aee9071 + uid : 3c64a36ae3357c0d8f1148fc0e983cfb diff --git a/doc/example-grids/regional_rotated_mercator_1.yml b/doc/example-grids/regional_rotated_mercator_1.yml index a2b5a6b17..cff16b3ab 100644 --- a/doc/example-grids/regional_rotated_mercator_1.yml +++ b/doc/example-grids/regional_rotated_mercator_1.yml @@ -14,4 +14,4 @@ check : size : 2000 lonlat(first) : [-10.319,40.2109] lonlat(last) : [24.4206,57.2263] - #uid : 06b876b7f9968628a11910e8e9a381bf + uid : 340321ee9855b47bbaadb581d2c86238 diff --git a/doc/example-grids/regular_gaussian_1.yml b/doc/example-grids/regular_gaussian_1.yml index 75dfd21b0..57c53442d 100644 --- a/doc/example-grids/regular_gaussian_1.yml +++ b/doc/example-grids/regular_gaussian_1.yml @@ -8,4 +8,4 @@ check : size : 128 lonlat(first) : [0,73.7992] lonlat(last) : [337.5,-73.7992] - #uid : 1afa743f953ef3b1c628163029a8d612 + uid : 4db8793a3e589a0f497cbe84ff34e5b8 diff --git a/doc/example-grids/regular_gaussian_2.yml b/doc/example-grids/regular_gaussian_2.yml index 865caae8c..d8f86440e 100644 --- a/doc/example-grids/regular_gaussian_2.yml +++ b/doc/example-grids/regular_gaussian_2.yml @@ -12,4 +12,4 @@ check : size : 128 lonlat(first) : [3,38.8589] lonlat(last) : [-135.011,-72.4668] - #uid : f744facfd6b8ae49384ed48b0495d6dd + uid : d179fd0b56811242a1a0a8e83dade6a1 diff --git a/doc/example-grids/regular_gaussian_3.yml b/doc/example-grids/regular_gaussian_3.yml index c6141345e..d1f437aef 100644 --- a/doc/example-grids/regular_gaussian_3.yml +++ b/doc/example-grids/regular_gaussian_3.yml @@ -6,4 +6,4 @@ check: size : 128 lonlat(first) : [0,73.7992] lonlat(last) : [337.5,-73.7992] - #uid : 1afa743f953ef3b1c628163029a8d612 + uid : 4db8793a3e589a0f497cbe84ff34e5b8 diff --git a/doc/example-grids/regular_gaussian_4.yml b/doc/example-grids/regular_gaussian_4.yml index af4f6dac9..afb1bfc1a 100644 --- a/doc/example-grids/regular_gaussian_4.yml +++ b/doc/example-grids/regular_gaussian_4.yml @@ -9,4 +9,4 @@ check : size : 2560 lonlat(first) : [-180,81.6506] lonlat(last) : [177.75,-81.6506] - #uid : a5362eb4649fce5d8ccf149cf59cabf4 + uid : 8e729027737aece8db5883e3a475d5cb diff --git a/doc/example-grids/regular_lonlat_1.yml b/doc/example-grids/regular_lonlat_1.yml index 8cf088dee..52258f3af 100644 --- a/doc/example-grids/regular_lonlat_1.yml +++ b/doc/example-grids/regular_lonlat_1.yml @@ -8,4 +8,4 @@ check: size : 8320 lonlat(first) : [0,90] lonlat(last) : [357.188,-90] - #uid : a5b356177b3ca2f1e65843756d64de76 + uid : f109da5924c5998453cdb7d5854ebd1a diff --git a/doc/example-grids/update_uid.py b/doc/example-grids/update_uid.py new file mode 100755 index 000000000..53923cb2b --- /dev/null +++ b/doc/example-grids/update_uid.py @@ -0,0 +1,66 @@ +#!/usr/bin/env python + +# +# This script checks all example-grids and updates the uid to a newly calculated uid +# The only argument to this script is the path to the "atlas-grids" executable +# +# !!! WARNING !!! +# Execution overwrites existing ".yml" files in the same directory as this script! +# + +def run_program_get_error(file): + import os + from subprocess import check_output, CalledProcessError + + command = [program, file, '--check' ] + + from subprocess import Popen, PIPE + + p = Popen(command, stdout=PIPE, stderr=PIPE) + output, error = p.communicate() + if p.returncode != 0: + return str(error.strip(),'ascii') + return None + + +def process_file( file, newfile ): + + import string + print( "File: " , file ) + + f = open(file,"r+") + text = f.read() + f.close() + + line = run_program_get_error( file ) + if line: + print( line ) + import re + replace = re.match( r"Check failed: grid uid (.*) expected to be (.*)$", line ).group(1) + uid = re.findall( r"^ uid : (.*)$", text, re.MULTILINE)[0] + print("Search/Replace ",uid, " to ", replace ) + newtext = text.replace( uid, replace ) + else: + print( "Nothing to replace, copy-only" ) + newtext = text + + print( "New file: ", newfile) + f = open(newfile,"w") + f.write(newtext) + f.close() + + +import sys +program = sys.argv[1] + +print( "Updating uids of grids with program [",program,"]") + +import os +directory = os.path.dirname(os.path.realpath(__file__)) + +for root, dirs, files in os.walk(directory): + for file in files: + if file.endswith('.yml'): + file = root+"/"+file + newfile = file + process_file(file,newfile) diff --git a/doc/example-grids/zonal_band_1.yml b/doc/example-grids/zonal_band_1.yml index 4c1ac85af..49b3be6a4 100644 --- a/doc/example-grids/zonal_band_1.yml +++ b/doc/example-grids/zonal_band_1.yml @@ -9,4 +9,4 @@ check: size : 15 lonlat(first) : [0,70] lonlat(last) : [288,30] - #uid : 5dc6e5c29625c95e86afe4efaae17dd7 + uid : 7f1b0971ad5d9f581e2d35914d916a67 diff --git a/doc/example-grids/zonal_band_2.yml b/doc/example-grids/zonal_band_2.yml index 5ee4d06e8..96ed44aa9 100644 --- a/doc/example-grids/zonal_band_2.yml +++ b/doc/example-grids/zonal_band_2.yml @@ -9,4 +9,4 @@ check: size : 252 lonlat(first) : [0,30] lonlat(last) : [350,90] - #uid : ebf1b438a0a770f7fb20fd41885ae086 + uid : 639a6a6b1d29ba4b6523a044eb9b4677 diff --git a/doc/example-grids/zonal_band_3.yml b/doc/example-grids/zonal_band_3.yml index ba9c9a8b5..992da285e 100644 --- a/doc/example-grids/zonal_band_3.yml +++ b/doc/example-grids/zonal_band_3.yml @@ -8,4 +8,4 @@ check: size : 684 lonlat(first) : [0,-90] lonlat(last) : [350,90] - #uid : ae584da2de497b8065c63f73115b08f1 + uid : f1689a410168f86c048e6fa374bac498 diff --git a/src/atlas/domain/detail/RectangularDomain.cc b/src/atlas/domain/detail/RectangularDomain.cc index 306d5a546..baf6653c3 100644 --- a/src/atlas/domain/detail/RectangularDomain.cc +++ b/src/atlas/domain/detail/RectangularDomain.cc @@ -11,6 +11,8 @@ #include #include +#include "eckit/utils/Hash.h" + #include "atlas/domain/detail/DomainFactory.h" #include "atlas/domain/detail/RectangularDomain.h" #include "atlas/runtime/Exception.h" @@ -109,7 +111,13 @@ void RectangularDomain::print( std::ostream& os ) const { } void RectangularDomain::hash( eckit::Hash& h ) const { - spec().hash( h ); + auto add_double = [&]( const double& x ) { h.add( std::round( x * 1.e8 ) ); }; + h.add( type() ); + h.add( units() ); + add_double( xmin() ); + add_double( xmax() ); + add_double( ymin() ); + add_double( ymax() ); } bool RectangularDomain::containsNorthPole() const { diff --git a/src/atlas/grid/detail/grid/Regional.cc b/src/atlas/grid/detail/grid/Regional.cc index 06d20bec7..60cfa9f0c 100644 --- a/src/atlas/grid/detail/grid/Regional.cc +++ b/src/atlas/grid/detail/grid/Regional.cc @@ -273,7 +273,6 @@ static class regional : public GridBuilder { bool with_endpoint = true; XSpace xspace( {x.min, x.max}, std::vector( y.N, x.N ), with_endpoint ); - return new StructuredGrid::grid_t( xspace, yspace, projection, domain( config ) ); } diff --git a/src/atlas/grid/detail/grid/Structured.cc b/src/atlas/grid/detail/grid/Structured.cc index d5fd494db..e45f1bc08 100644 --- a/src/atlas/grid/detail/grid/Structured.cc +++ b/src/atlas/grid/detail/grid/Structured.cc @@ -474,15 +474,24 @@ std::string Structured::type() const { } void Structured::hash( eckit::Hash& h ) const { - h.add( y().data(), sizeof( double ) * y().size() ); + auto add_double = [&]( const double& x ) { h.add( std::round( x * 1.e8 ) ); }; + auto add_double_vector = [&]( const std::vector& xvec ) { + for ( auto& x : xvec ) { + add_double( x ); + } + }; + auto add_long = [&]( const idx_t& x ) { h.add( long( x ) ); }; + auto add_long_vector = [&]( const std::vector& xvec ) { + for ( auto& x : xvec ) { + add_long( x ); + } + }; - // We can use nx() directly, but it could change the hash - std::vector hashed_nx( nx().begin(), nx().end() ); - h.add( hashed_nx.data(), sizeof( long ) * ny() ); + add_double_vector( y() ); + add_long_vector( nx() ); - // also add lonmin and lonmax - h.add( xmin_.data(), sizeof( double ) * xmin_.size() ); - h.add( dx_.data(), sizeof( double ) * dx_.size() ); + add_double_vector( xmin_ ); + add_double_vector( dx_ ); // also add projection information projection().hash( h ); diff --git a/src/tests/grid/test_grid_hash.cc b/src/tests/grid/test_grid_hash.cc index 8b70287fc..ce6f2d950 100644 --- a/src/tests/grid/test_grid_hash.cc +++ b/src/tests/grid/test_grid_hash.cc @@ -29,10 +29,10 @@ namespace test { CASE( "test_global" ) { auto grids = { - std::make_tuple( Grid( "O32" ), "79599ee4825339e0ebbcd427d79d0177" ), - std::make_tuple( Grid( "O32", Domain() ), "79599ee4825339e0ebbcd427d79d0177" ), - std::make_tuple( Grid( "O32", RectangularDomain( {0, 360}, {90, -90} ) ), "79599ee4825339e0ebbcd427d79d0177" ), - std::make_tuple( Grid( "O32", ZonalBandDomain( {90, -90} ) ), "79599ee4825339e0ebbcd427d79d0177" ), + std::make_tuple( Grid( "O32" ), "e8d76a652ea937615276383aba43c912" ), + std::make_tuple( Grid( "O32", Domain() ), "e8d76a652ea937615276383aba43c912" ), + std::make_tuple( Grid( "O32", RectangularDomain( {0, 360}, {90, -90} ) ), "e8d76a652ea937615276383aba43c912" ), + std::make_tuple( Grid( "O32", ZonalBandDomain( {90, -90} ) ), "e8d76a652ea937615276383aba43c912" ), }; int c{0}; From 7f41566c897646cb307858c8c48cd4df5a8c0f07 Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Fri, 12 Jul 2019 14:20:03 +0100 Subject: [PATCH 78/86] ATLAS-237 Enforce more checks in the example-grids --- doc/example-grids/classic_gaussian_1.yml | 1 + doc/example-grids/classic_gaussian_2.yml | 1 + doc/example-grids/classic_gaussian_3.yml | 1 + .../cropped_classic_gaussian_1.yml | 1 + .../cropped_classic_gaussian_2.yml | 1 + doc/example-grids/cropped_shifted_lonlat_1.yml | 1 + doc/example-grids/custom_structured_1.yml | 1 + doc/example-grids/custom_structured_2.yml | 1 + doc/example-grids/custom_structured_3.yml | 1 + doc/example-grids/custom_structured_4.yml | 1 + doc/example-grids/custom_structured_5.yml | 1 + doc/example-grids/custom_structured_6.yml | 1 + doc/example-grids/custom_structured_7.yml | 1 + doc/example-grids/octahedral_gaussian_1.yml | 1 + doc/example-grids/octahedral_gaussian_2.yml | 1 + doc/example-grids/octahedral_gaussian_3.yml | 1 + doc/example-grids/octahedral_gaussian_4.yml | 1 + doc/example-grids/regional_lambert_1.yml | 1 + doc/example-grids/regional_lambert_2.yml | 1 + .../regional_lambert_azimuthal_equal_area_1.yml | 1 + doc/example-grids/regional_lonlat_1.yml | 1 + .../regional_rotated_mercator_1.yml | 1 + doc/example-grids/regular_gaussian_1.yml | 1 + doc/example-grids/regular_gaussian_2.yml | 1 + doc/example-grids/regular_gaussian_3.yml | 1 + doc/example-grids/regular_gaussian_4.yml | 1 + doc/example-grids/regular_lonlat_1.yml | 1 + doc/example-grids/unstructured_1.yml | 1 + doc/example-grids/zonal_band_1.yml | 1 + doc/example-grids/zonal_band_2.yml | 1 + doc/example-grids/zonal_band_3.yml | 1 + src/apps/atlas-grids.cc | 17 +++++++++++++++++ src/tests/grid/CMakeLists.txt | 2 +- 33 files changed, 49 insertions(+), 1 deletion(-) diff --git a/doc/example-grids/classic_gaussian_1.yml b/doc/example-grids/classic_gaussian_1.yml index 2e82eac16..93399501a 100644 --- a/doc/example-grids/classic_gaussian_1.yml +++ b/doc/example-grids/classic_gaussian_1.yml @@ -7,3 +7,4 @@ check : lonlat(first) : [0,85.7606] lonlat(last) : [342,-85.7606] uid : 49cbbc2cde26050896e000d1e0f5fb7b + bounding_box(n,w,s,e) : [90,0,-90,360] diff --git a/doc/example-grids/classic_gaussian_2.yml b/doc/example-grids/classic_gaussian_2.yml index ff8a3efdd..a9c6b4165 100644 --- a/doc/example-grids/classic_gaussian_2.yml +++ b/doc/example-grids/classic_gaussian_2.yml @@ -13,3 +13,4 @@ check : lonlat(first) : [3,44.8796] lonlat(last) : [-172.453,-54.9736] uid : 64d609c6ee4b036b209047aef97a10eb + bounding_box(n,w,s,e) : [90,0,-90,360] diff --git a/doc/example-grids/classic_gaussian_3.yml b/doc/example-grids/classic_gaussian_3.yml index 5f3313a0b..7199ff429 100644 --- a/doc/example-grids/classic_gaussian_3.yml +++ b/doc/example-grids/classic_gaussian_3.yml @@ -8,3 +8,4 @@ check : lonlat(first) : [0,85.7606] lonlat(last) : [342,-85.7606] uid : 49cbbc2cde26050896e000d1e0f5fb7b + bounding_box(n,w,s,e) : [90,0,-90,360] diff --git a/doc/example-grids/cropped_classic_gaussian_1.yml b/doc/example-grids/cropped_classic_gaussian_1.yml index 5aefd105b..1e6c2983c 100644 --- a/doc/example-grids/cropped_classic_gaussian_1.yml +++ b/doc/example-grids/cropped_classic_gaussian_1.yml @@ -14,3 +14,4 @@ check : lonlat(first) : [0,85.7606] lonlat(last) : [354,47.0696] uid : 7f87a4865eb08403c179c6488c2eeeca + bounding_box(n,w,s,e) : [90,0,45,360] diff --git a/doc/example-grids/cropped_classic_gaussian_2.yml b/doc/example-grids/cropped_classic_gaussian_2.yml index 67440ca66..1b119119f 100644 --- a/doc/example-grids/cropped_classic_gaussian_2.yml +++ b/doc/example-grids/cropped_classic_gaussian_2.yml @@ -17,3 +17,4 @@ check : lonlat(first) : [48.4615,41.5325] lonlat(last) : [90,-41.5325] uid : e55a302d0bb56f50523e6bc2d28c4234 + bounding_box(n,w,s,e) : [45,45,-45,90] diff --git a/doc/example-grids/cropped_shifted_lonlat_1.yml b/doc/example-grids/cropped_shifted_lonlat_1.yml index cf480d6e0..6d8f5ecdc 100644 --- a/doc/example-grids/cropped_shifted_lonlat_1.yml +++ b/doc/example-grids/cropped_shifted_lonlat_1.yml @@ -12,3 +12,4 @@ check : lonlat(first) : [1,89] lonlat(last) : [359,45] uid : a1426cb32c8694d07d997cd224805947 + bounding_box(n,w,s,e) : [90,0,45,360] diff --git a/doc/example-grids/custom_structured_1.yml b/doc/example-grids/custom_structured_1.yml index 90fb9e62b..a68752b84 100644 --- a/doc/example-grids/custom_structured_1.yml +++ b/doc/example-grids/custom_structured_1.yml @@ -10,3 +10,4 @@ check : lonlat(first) : [0,90] lonlat(last) : [337.5,-90] uid : 714c5d2db88b5eefdf8f789e8012f0aa + bounding_box(n,w,s,e) : [90,0,-90,360] diff --git a/doc/example-grids/custom_structured_2.yml b/doc/example-grids/custom_structured_2.yml index 6b07a94b7..8f4f92404 100644 --- a/doc/example-grids/custom_structured_2.yml +++ b/doc/example-grids/custom_structured_2.yml @@ -10,3 +10,4 @@ check : lonlat(first) : [0,73.7992] lonlat(last) : [337.5,-73.7992] uid : 4db8793a3e589a0f497cbe84ff34e5b8 + bounding_box(n,w,s,e) : [90,0,-90,360] diff --git a/doc/example-grids/custom_structured_3.yml b/doc/example-grids/custom_structured_3.yml index cc3c7edb3..34479f64d 100644 --- a/doc/example-grids/custom_structured_3.yml +++ b/doc/example-grids/custom_structured_3.yml @@ -18,3 +18,4 @@ check : lonlat(first) : [0,73.7992] lonlat(last) : [342,-73.7992] uid : 238a876f8ddaf43100fe643f1283f78a + bounding_box(n,w,s,e) : [90,0,-90,360] diff --git a/doc/example-grids/custom_structured_4.yml b/doc/example-grids/custom_structured_4.yml index d31c44fa5..1e6bcb917 100644 --- a/doc/example-grids/custom_structured_4.yml +++ b/doc/example-grids/custom_structured_4.yml @@ -20,3 +20,4 @@ check : lonlat(first) : [0,73.7992] lonlat(last) : [342,-73.7992] uid : 238a876f8ddaf43100fe643f1283f78a + bounding_box(n,w,s,e) : [90,0,-90,360] diff --git a/doc/example-grids/custom_structured_5.yml b/doc/example-grids/custom_structured_5.yml index 366a2bdb9..6dc221daa 100644 --- a/doc/example-grids/custom_structured_5.yml +++ b/doc/example-grids/custom_structured_5.yml @@ -11,3 +11,4 @@ check : lonlat(first) : [3,40] lonlat(last) : [-177,-40] uid : d55211f27c4a8c6ce94ea67f0c706e22 + bounding_box(n,w,s,e) : [90,0,-90,360] diff --git a/doc/example-grids/custom_structured_6.yml b/doc/example-grids/custom_structured_6.yml index 184a2b125..c517612a1 100644 --- a/doc/example-grids/custom_structured_6.yml +++ b/doc/example-grids/custom_structured_6.yml @@ -21,3 +21,4 @@ check: lonlat(first) : [0,73.7992] lonlat(last) : [326.25,-73.7992] uid : d5944053929a124fd786c2121ba3d064 + bounding_box(n,w,s,e) : [90,-11.25,-90,360] diff --git a/doc/example-grids/custom_structured_7.yml b/doc/example-grids/custom_structured_7.yml index cc964b25d..6c7a4c90d 100644 --- a/doc/example-grids/custom_structured_7.yml +++ b/doc/example-grids/custom_structured_7.yml @@ -10,3 +10,4 @@ check : lonlat(first) : [0,75] lonlat(last) : [330,-75] uid : 76839204fa9d69232192dedc19ecef08 + bounding_box(n,w,s,e) : [90,0,-90,360] diff --git a/doc/example-grids/octahedral_gaussian_1.yml b/doc/example-grids/octahedral_gaussian_1.yml index 86f153520..fdaef07e5 100644 --- a/doc/example-grids/octahedral_gaussian_1.yml +++ b/doc/example-grids/octahedral_gaussian_1.yml @@ -9,3 +9,4 @@ check : lonlat(first) : [0,85.7606] lonlat(last) : [342,-85.7606] uid : 957667adfecf4f2394e4ec9bb0b25569 + bounding_box(n,w,s,e) : [90,0,-90,360] diff --git a/doc/example-grids/octahedral_gaussian_2.yml b/doc/example-grids/octahedral_gaussian_2.yml index 83c0f887d..0b8354d23 100644 --- a/doc/example-grids/octahedral_gaussian_2.yml +++ b/doc/example-grids/octahedral_gaussian_2.yml @@ -10,3 +10,4 @@ check : lonlat(first) : [3,45.9397] lonlat(last) : [-165.776,-62.6128] uid : 20308244515b7c78e22709ebaa842246 + bounding_box(n,w,s,e) : [90,0,-90,360] diff --git a/doc/example-grids/octahedral_gaussian_3.yml b/doc/example-grids/octahedral_gaussian_3.yml index 78ca9ce89..50a06742e 100644 --- a/doc/example-grids/octahedral_gaussian_3.yml +++ b/doc/example-grids/octahedral_gaussian_3.yml @@ -8,3 +8,4 @@ check : lonlat(first) : [0,85.7606] lonlat(last) : [342,-85.7606] uid : 957667adfecf4f2394e4ec9bb0b25569 + bounding_box(n,w,s,e) : [90,0,-90,360] diff --git a/doc/example-grids/octahedral_gaussian_4.yml b/doc/example-grids/octahedral_gaussian_4.yml index 8bbf9f3ab..5ea110afe 100644 --- a/doc/example-grids/octahedral_gaussian_4.yml +++ b/doc/example-grids/octahedral_gaussian_4.yml @@ -9,3 +9,4 @@ check : lonlat(first) : [3,45.9397] lonlat(last) : [-165.776,-62.6128] uid : 20308244515b7c78e22709ebaa842246 + bounding_box(n,w,s,e) : [90,0,-90,360] diff --git a/doc/example-grids/regional_lambert_1.yml b/doc/example-grids/regional_lambert_1.yml index a14493a4a..53a680403 100644 --- a/doc/example-grids/regional_lambert_1.yml +++ b/doc/example-grids/regional_lambert_1.yml @@ -16,3 +16,4 @@ check : lonlat(first) : [-10.3173,40.22] lonlat(last) : [24.4368,57.2335] uid : 1cb0b7c8f91617c3b6065d72b85c65c4 + bounding_box(n,w,s,e) : [58.7333,-16.4378,40.219,24.4378] diff --git a/doc/example-grids/regional_lambert_2.yml b/doc/example-grids/regional_lambert_2.yml index 6e73b4746..c82c5fda5 100644 --- a/doc/example-grids/regional_lambert_2.yml +++ b/doc/example-grids/regional_lambert_2.yml @@ -16,3 +16,4 @@ check : lonlat(first) : [-126.138,16.281] lonlat(last) : [-57.3811,55.4813] uid : ec98b263e57286710aeb4131a614b5f9 + bounding_box(n,w,s,e) : [58.3664,-139.857,16.28,-57.3801] diff --git a/doc/example-grids/regional_lambert_azimuthal_equal_area_1.yml b/doc/example-grids/regional_lambert_azimuthal_equal_area_1.yml index c1614676a..cc2fe5da2 100644 --- a/doc/example-grids/regional_lambert_azimuthal_equal_area_1.yml +++ b/doc/example-grids/regional_lambert_azimuthal_equal_area_1.yml @@ -16,3 +16,4 @@ check : lonlat(first) : [-10.4643,40.1877] lonlat(last) : [24.6228,57.1968] uid : 16663e1f4f3deb724712dd2698008915 + bounding_box(n,w,s,e) : [58.7776,-16.6238,40.1867,24.6238] diff --git a/doc/example-grids/regional_lonlat_1.yml b/doc/example-grids/regional_lonlat_1.yml index b4bd24e63..1ac19b896 100644 --- a/doc/example-grids/regional_lonlat_1.yml +++ b/doc/example-grids/regional_lonlat_1.yml @@ -13,3 +13,4 @@ check : lonlat(first) : [100,-50] lonlat(last) : [170,-10] uid : 3c64a36ae3357c0d8f1148fc0e983cfb + bounding_box(n,w,s,e) : [-10,100,-50,170] diff --git a/doc/example-grids/regional_rotated_mercator_1.yml b/doc/example-grids/regional_rotated_mercator_1.yml index cff16b3ab..57bb6bc2c 100644 --- a/doc/example-grids/regional_rotated_mercator_1.yml +++ b/doc/example-grids/regional_rotated_mercator_1.yml @@ -15,3 +15,4 @@ check : lonlat(first) : [-10.319,40.2109] lonlat(last) : [24.4206,57.2263] uid : 340321ee9855b47bbaadb581d2c86238 + bounding_box(n,w,s,e) : [58.735,-16.4216,40.2099,24.4216] diff --git a/doc/example-grids/regular_gaussian_1.yml b/doc/example-grids/regular_gaussian_1.yml index 57c53442d..722bd9216 100644 --- a/doc/example-grids/regular_gaussian_1.yml +++ b/doc/example-grids/regular_gaussian_1.yml @@ -9,3 +9,4 @@ check : lonlat(first) : [0,73.7992] lonlat(last) : [337.5,-73.7992] uid : 4db8793a3e589a0f497cbe84ff34e5b8 + bounding_box(n,w,s,e) : [90,0,-90,360] diff --git a/doc/example-grids/regular_gaussian_2.yml b/doc/example-grids/regular_gaussian_2.yml index d8f86440e..b7cf9d110 100644 --- a/doc/example-grids/regular_gaussian_2.yml +++ b/doc/example-grids/regular_gaussian_2.yml @@ -13,3 +13,4 @@ check : lonlat(first) : [3,38.8589] lonlat(last) : [-135.011,-72.4668] uid : d179fd0b56811242a1a0a8e83dade6a1 + bounding_box(n,w,s,e) : [90,0,-90,360] diff --git a/doc/example-grids/regular_gaussian_3.yml b/doc/example-grids/regular_gaussian_3.yml index d1f437aef..3065d3b5b 100644 --- a/doc/example-grids/regular_gaussian_3.yml +++ b/doc/example-grids/regular_gaussian_3.yml @@ -7,3 +7,4 @@ check: lonlat(first) : [0,73.7992] lonlat(last) : [337.5,-73.7992] uid : 4db8793a3e589a0f497cbe84ff34e5b8 + bounding_box(n,w,s,e) : [90,0,-90,360] diff --git a/doc/example-grids/regular_gaussian_4.yml b/doc/example-grids/regular_gaussian_4.yml index afb1bfc1a..384dd01be 100644 --- a/doc/example-grids/regular_gaussian_4.yml +++ b/doc/example-grids/regular_gaussian_4.yml @@ -10,3 +10,4 @@ check : lonlat(first) : [-180,81.6506] lonlat(last) : [177.75,-81.6506] uid : 8e729027737aece8db5883e3a475d5cb + bounding_box(n,w,s,e) : [90,-180,-90,180] diff --git a/doc/example-grids/regular_lonlat_1.yml b/doc/example-grids/regular_lonlat_1.yml index 52258f3af..82b0489ac 100644 --- a/doc/example-grids/regular_lonlat_1.yml +++ b/doc/example-grids/regular_lonlat_1.yml @@ -9,3 +9,4 @@ check: lonlat(first) : [0,90] lonlat(last) : [357.188,-90] uid : f109da5924c5998453cdb7d5854ebd1a + bounding_box(n,w,s,e) : [90,0,-90,360] diff --git a/doc/example-grids/unstructured_1.yml b/doc/example-grids/unstructured_1.yml index 2df89a218..cf85e8055 100644 --- a/doc/example-grids/unstructured_1.yml +++ b/doc/example-grids/unstructured_1.yml @@ -12,3 +12,4 @@ check : lonlat(first) : [0,90] lonlat(last) : [180,90] uid : b704ab522505497c6d622f27c429bffe + bounding_box(n,w,s,e) : [90,0,-90,360] diff --git a/doc/example-grids/zonal_band_1.yml b/doc/example-grids/zonal_band_1.yml index 49b3be6a4..322bb4352 100644 --- a/doc/example-grids/zonal_band_1.yml +++ b/doc/example-grids/zonal_band_1.yml @@ -10,3 +10,4 @@ check: lonlat(first) : [0,70] lonlat(last) : [288,30] uid : 7f1b0971ad5d9f581e2d35914d916a67 + bounding_box(n,w,s,e) : [70,0,30,360] diff --git a/doc/example-grids/zonal_band_2.yml b/doc/example-grids/zonal_band_2.yml index 96ed44aa9..34340dffb 100644 --- a/doc/example-grids/zonal_band_2.yml +++ b/doc/example-grids/zonal_band_2.yml @@ -10,3 +10,4 @@ check: lonlat(first) : [0,30] lonlat(last) : [350,90] uid : 639a6a6b1d29ba4b6523a044eb9b4677 + bounding_box(n,w,s,e) : [90,0,30,360] diff --git a/doc/example-grids/zonal_band_3.yml b/doc/example-grids/zonal_band_3.yml index 992da285e..3b9991e57 100644 --- a/doc/example-grids/zonal_band_3.yml +++ b/doc/example-grids/zonal_band_3.yml @@ -9,3 +9,4 @@ check: lonlat(first) : [0,-90] lonlat(last) : [350,90] uid : f1689a410168f86c048e6fa374bac498 + bounding_box(n,w,s,e) : [90,0,-90,360] diff --git a/src/apps/atlas-grids.cc b/src/apps/atlas-grids.cc index 77fd53a97..17c6bba0c 100644 --- a/src/apps/atlas-grids.cc +++ b/src/apps/atlas-grids.cc @@ -49,6 +49,8 @@ struct AtlasGrids : public atlas::AtlasTool { add_option( new SimpleOption( "json", "Export json" ) ); add_option( new SimpleOption( "rtable", "Export IFS rtable" ) ); add_option( new SimpleOption( "check", "Check grid" ) ); + add_option( new SimpleOption( "check-uid", "Check grid uid required" ) ); + add_option( new SimpleOption( "check-boundingbox", "Check grid bounding_box(n,w,s,e) required" ) ); } }; @@ -71,6 +73,12 @@ int AtlasGrids::execute( const Args& args ) { bool check = false; args.get( "check", check ); + bool check_uid = false; + args.get( "check-uid", check_uid ); + + bool check_bbox = false; + args.get( "check-boundingbox", check_bbox ); + bool list = false; args.get( "list", list ); @@ -256,6 +264,10 @@ int AtlasGrids::execute( const Args& args ) { check_failed = true; } } + else if ( check_uid && uid.empty() ) { + out << "Check failed: grid uid " << grid.uid() << " was not encoded in the check" << std::endl; + check_failed = true; + } else { Log::warning() << "Check for uid skipped" << std::endl; } @@ -313,6 +325,11 @@ int AtlasGrids::execute( const Args& args ) { out << "Check failed: e=" << bb.east() << " expected to be " << bbox[3] << std::endl; } } + else if ( check_bbox && bbox.size() != 4 ) { + out << "Check failed: grid bounding_box(n,w,s,e) " << grid.lonlatBoundingBox() + << " was not encoded in the check" << std::endl; + check_failed = true; + } else { Log::warning() << "Check for bounding_box(n,w,s,e) skipped" << std::endl; } diff --git a/src/tests/grid/CMakeLists.txt b/src/tests/grid/CMakeLists.txt index 622f28652..31ed56be0 100644 --- a/src/tests/grid/CMakeLists.txt +++ b/src/tests/grid/CMakeLists.txt @@ -38,7 +38,7 @@ foreach( grid ${grids} ) set( test_name atlas_test_grid_${grid_name} ) ecbuild_add_test( TARGET ${test_name} COMMAND atlas-grids - ARGS ${grid} --check + ARGS ${grid} --check --check-uid --check-boundingbox ENVIRONMENT ${ATLAS_TEST_ENVIRONMENT} ) endforeach() From 5576f28a0ebf63e4d0f35fd7bc0c733cd5cdcd13 Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Fri, 12 Jul 2019 14:56:41 +0100 Subject: [PATCH 79/86] Update to clang-format 7.0.1 --- src/atlas/array/gridtools/GridToolsArray.cc | 2 +- .../array/gridtools/GridToolsArrayHelpers.h | 12 ++-- .../array/gridtools/GridToolsMakeView.cc | 2 +- src/atlas/functionspace/Spectral.cc | 20 +++--- src/atlas/grid/detail/grid/Structured.cc | 2 +- src/atlas/library/Library.cc | 4 +- src/atlas/mesh/actions/BuildEdges.cc | 2 +- src/atlas/mesh/actions/BuildHalo.cc | 2 +- .../actions/BuildNode2CellConnectivity.cc | 2 +- .../detail/StructuredMeshGenerator.cc | 6 +- src/atlas/parallel/mpi/Statistics.h | 2 +- src/atlas/runtime/AtlasTool.cc | 6 +- src/atlas/runtime/Trace.h | 4 +- src/atlas/trans/ifs/TransIFS.cc | 68 +++++++++---------- src/atlas/trans/ifs/VorDivToUVIFS.cc | 2 +- src/atlas/trans/local/TransLocal.cc | 2 +- src/tests/AtlasTestEnvironment.h | 4 +- src/tests/functionspace/test_stencil.cc | 2 +- src/tests/trans/test_trans.cc | 2 +- src/tests/trans/test_transgeneral.cc | 2 +- src/tests/util/test_indexview.cc | 4 +- tools/apply-clang-format.sh | 2 +- 22 files changed, 77 insertions(+), 77 deletions(-) diff --git a/src/atlas/array/gridtools/GridToolsArray.cc b/src/atlas/array/gridtools/GridToolsArray.cc index 6da313159..a31ab6e2e 100644 --- a/src/atlas/array/gridtools/GridToolsArray.cc +++ b/src/atlas/array/gridtools/GridToolsArray.cc @@ -46,7 +46,7 @@ template using UintSequence = ::gridtools::make_gt_integer_sequence; template class Storage, typename StorageInfo> -static Array* wrap_array(::gridtools::data_store, StorageInfo>* ds, const ArraySpec& spec ) { +static Array* wrap_array( ::gridtools::data_store, StorageInfo>* ds, const ArraySpec& spec ) { assert( ds ); using data_store_t = typename std::remove_pointer::type; ArrayDataStore* data_store = new GridToolsDataStore( ds ); diff --git a/src/atlas/array/gridtools/GridToolsArrayHelpers.h b/src/atlas/array/gridtools/GridToolsArrayHelpers.h index c058163cb..0b3909f63 100644 --- a/src/atlas/array/gridtools/GridToolsArrayHelpers.h +++ b/src/atlas/array/gridtools/GridToolsArrayHelpers.h @@ -119,7 +119,7 @@ struct get_stride_component { template ATLAS_HOST_DEVICE constexpr static Value apply( StorageInfoPtr a ) { - static_assert( (::gridtools::is_storage_info::type>::value ), + static_assert( ( ::gridtools::is_storage_info::type>::value ), "Error: not a storage_info" ); return a->template stride(); } @@ -135,7 +135,7 @@ struct get_shape_component { template ATLAS_HOST_DEVICE constexpr static Value apply( StorageInfoPtr a ) { - static_assert( (::gridtools::is_storage_info::type>::value ), + static_assert( ( ::gridtools::is_storage_info::type>::value ), "Error: not a storage_info" ); return a->template total_length(); } @@ -165,7 +165,7 @@ typename gt_storage_t::type::value>::t typedef gridtools::storage_traits::data_store_t data_store_t; data_store_t* ds; - if (::gridtools::accumulate(::gridtools::multiplies(), dims... ) == 0 ) { ds = new data_store_t(); } + if ( ::gridtools::accumulate( ::gridtools::multiplies(), dims... ) == 0 ) { ds = new data_store_t(); } else { storage_info_ty si( dims... ); ds = new data_store_t( si ); @@ -201,7 +201,7 @@ constexpr idx_t zero( idx_t ) { } template -ArrayStrides make_null_strides(::gridtools::gt_integer_sequence ) { +ArrayStrides make_null_strides( ::gridtools::gt_integer_sequence ) { return make_strides( zero( Is )... ); } @@ -232,7 +232,7 @@ struct my_apply_gt_integer_sequence<::gridtools::gt_integer_sequence ArraySpec ATLAS_HOST make_spec( DataStore* gt_data_store_ptr, Dims... dims ) { - static_assert( (::gridtools::is_data_store::value ), "Internal Error: passing a non GT data store" ); + static_assert( ( ::gridtools::is_data_store::value ), "Internal Error: passing a non GT data store" ); if ( gt_data_store_ptr->valid() ) { auto storage_info_ptr = gt_data_store_ptr->get_storage_info_ptr().get(); @@ -251,7 +251,7 @@ ArraySpec ATLAS_HOST make_spec( DataStore* gt_data_store_ptr, Dims... dims ) { } else { return ArraySpec( make_shape( {dims...} ), - make_null_strides(::gridtools::make_gt_integer_sequence() ) ); + make_null_strides( ::gridtools::make_gt_integer_sequence() ) ); } } #endif diff --git a/src/atlas/array/gridtools/GridToolsMakeView.cc b/src/atlas/array/gridtools/GridToolsMakeView.cc index b6115a5dd..33bcb416a 100644 --- a/src/atlas/array/gridtools/GridToolsMakeView.cc +++ b/src/atlas/array/gridtools/GridToolsMakeView.cc @@ -89,7 +89,7 @@ IndexView make_host_indexview( const Array& array ) { data_store_t* ds = reinterpret_cast( const_cast( array.storage() ) ); - return IndexView(::gridtools::make_host_view<::gridtools::access_mode::ReadWrite>( *ds ) ); + return IndexView( ::gridtools::make_host_view<::gridtools::access_mode::ReadWrite>( *ds ) ); } // -------------------------------------------------------------------------------------------- diff --git a/src/atlas/functionspace/Spectral.cc b/src/atlas/functionspace/Spectral.cc index b6406e421..fc83d8b81 100644 --- a/src/atlas/functionspace/Spectral.cc +++ b/src/atlas/functionspace/Spectral.cc @@ -48,14 +48,14 @@ class Spectral::Parallelisation { Parallelisation( const std::shared_ptr<::Trans_t> other ) : trans_( other ) {} Parallelisation( int truncation ) { - trans_ = std::shared_ptr<::Trans_t>( new ::Trans_t, [](::Trans_t* p ) { - TRANS_CHECK(::trans_delete( p ) ); + trans_ = std::shared_ptr<::Trans_t>( new ::Trans_t, []( ::Trans_t* p ) { + TRANS_CHECK( ::trans_delete( p ) ); delete p; } ); - TRANS_CHECK(::trans_new( trans_.get() ) ); - TRANS_CHECK(::trans_set_trunc( trans_.get(), truncation ) ); - TRANS_CHECK(::trans_use_mpi( mpi::comm().size() > 1 ) ); - TRANS_CHECK(::trans_setup( trans_.get() ) ); + TRANS_CHECK( ::trans_new( trans_.get() ) ); + TRANS_CHECK( ::trans_set_trunc( trans_.get(), truncation ) ); + TRANS_CHECK( ::trans_use_mpi( mpi::comm().size() > 1 ) ); + TRANS_CHECK( ::trans_setup( trans_.get() ) ); } int nb_spectral_coefficients_global() const { return trans_->nspec2g; } @@ -277,7 +277,7 @@ void Spectral::gather( const FieldSet& local_fieldset, FieldSet& global_fieldset args.rspecg = glb.data(); args.nto = nto.data(); args.rspec = loc.data(); - TRANS_CHECK(::trans_gathspec( &args ) ); + TRANS_CHECK( ::trans_gathspec( &args ) ); #else throw_Exception( @@ -331,7 +331,7 @@ void Spectral::scatter( const FieldSet& global_fieldset, FieldSet& local_fieldse args.rspecg = glb.data(); args.nfrom = nfrom.data(); args.rspec = loc.data(); - TRANS_CHECK(::trans_distspec( &args ) ); + TRANS_CHECK( ::trans_distspec( &args ) ); glb.metadata().broadcast( loc.metadata(), root ); loc.metadata().set( "global", false ); @@ -369,7 +369,7 @@ void Spectral::norm( const Field& field, double& norm, int rank ) const { args.rspec = field.data(); args.rnorm = &norm; args.nmaster = rank + 1; - TRANS_CHECK(::trans_specnorm( &args ) ); + TRANS_CHECK( ::trans_specnorm( &args ) ); #else throw_Exception( "Cannot compute spectral norms because Atlas has not " @@ -387,7 +387,7 @@ void Spectral::norm( const Field& field, double norm_per_level[], int rank ) con args.rspec = field.data(); args.rnorm = norm_per_level; args.nmaster = rank + 1; - TRANS_CHECK(::trans_specnorm( &args ) ); + TRANS_CHECK( ::trans_specnorm( &args ) ); #else throw_Exception( "Cannot compute spectral norms because Atlas has not " diff --git a/src/atlas/grid/detail/grid/Structured.cc b/src/atlas/grid/detail/grid/Structured.cc index e45f1bc08..1884741e4 100644 --- a/src/atlas/grid/detail/grid/Structured.cc +++ b/src/atlas/grid/detail/grid/Structured.cc @@ -520,7 +520,7 @@ Grid::Spec Structured::spec() const { return grid_spec; } - // -------------------------------------------------------------------- +// -------------------------------------------------------------------- #if 1 namespace { // anonymous diff --git a/src/atlas/library/Library.cc b/src/atlas/library/Library.cc index 5d705eec9..5afb51bcc 100644 --- a/src/atlas/library/Library.cc +++ b/src/atlas/library/Library.cc @@ -55,12 +55,12 @@ std::string str( const eckit::system::Library& lib ) { } bool getEnv( const std::string& env, bool default_value ) { - if (::getenv( env.c_str() ) ) { return eckit::Translator()(::getenv( env.c_str() ) ); } + if ( ::getenv( env.c_str() ) ) { return eckit::Translator()( ::getenv( env.c_str() ) ); } return default_value; } int getEnv( const std::string& env, int default_value ) { - if (::getenv( env.c_str() ) ) { return eckit::Translator()(::getenv( env.c_str() ) ); } + if ( ::getenv( env.c_str() ) ) { return eckit::Translator()( ::getenv( env.c_str() ) ); } return default_value; } diff --git a/src/atlas/mesh/actions/BuildEdges.cc b/src/atlas/mesh/actions/BuildEdges.cc index b114b1f86..43babbc58 100644 --- a/src/atlas/mesh/actions/BuildEdges.cc +++ b/src/atlas/mesh/actions/BuildEdges.cc @@ -38,8 +38,8 @@ using atlas::mesh::detail::accumulate_facets_ordered_by_halo; using Topology = atlas::mesh::Nodes::Topology; -using atlas::util::UniqueLonLat; using atlas::util::microdeg; +using atlas::util::UniqueLonLat; namespace atlas { namespace mesh { diff --git a/src/atlas/mesh/actions/BuildHalo.cc b/src/atlas/mesh/actions/BuildHalo.cc index 6c5568d3f..94a8aae7d 100644 --- a/src/atlas/mesh/actions/BuildHalo.cc +++ b/src/atlas/mesh/actions/BuildHalo.cc @@ -49,9 +49,9 @@ using atlas::mesh::detail::accumulate_facets; using atlas::util::LonLatMicroDeg; +using atlas::util::microdeg; using atlas::util::PeriodicTransform; using atlas::util::UniqueLonLat; -using atlas::util::microdeg; using Topology = atlas::mesh::Nodes::Topology; namespace atlas { diff --git a/src/atlas/mesh/actions/BuildNode2CellConnectivity.cc b/src/atlas/mesh/actions/BuildNode2CellConnectivity.cc index 16dcfd26e..6049e468a 100644 --- a/src/atlas/mesh/actions/BuildNode2CellConnectivity.cc +++ b/src/atlas/mesh/actions/BuildNode2CellConnectivity.cc @@ -41,8 +41,8 @@ using atlas::mesh::detail::accumulate_facets_ordered_by_halo; using Topology = atlas::mesh::Nodes::Topology; -using atlas::util::UniqueLonLat; using atlas::util::microdeg; +using atlas::util::UniqueLonLat; namespace atlas { namespace mesh { diff --git a/src/atlas/meshgenerator/detail/StructuredMeshGenerator.cc b/src/atlas/meshgenerator/detail/StructuredMeshGenerator.cc index f9745f6e1..d89dbb037 100644 --- a/src/atlas/meshgenerator/detail/StructuredMeshGenerator.cc +++ b/src/atlas/meshgenerator/detail/StructuredMeshGenerator.cc @@ -469,9 +469,9 @@ We need to connect to next region else throw_Exception( "Should not try to make a quadrilateral!", Here() ); } - // ------------------------------------------------ - // END RULES - // ------------------------------------------------ + // ------------------------------------------------ + // END RULES + // ------------------------------------------------ #if DEBUG_OUTPUT ATLAS_DEBUG_VAR( jelem ); diff --git a/src/atlas/parallel/mpi/Statistics.h b/src/atlas/parallel/mpi/Statistics.h index 8b8d7a422..4f30f7f16 100644 --- a/src/atlas/parallel/mpi/Statistics.h +++ b/src/atlas/parallel/mpi/Statistics.h @@ -22,7 +22,7 @@ #include "atlas/util/detail/BlackMagic.h" #undef ATLAS_TRACE_MPI -#define ATLAS_TRACE_MPI( ... ) ATLAS_TRACE_MPI_(::atlas::mpi::Trace, Here(), __VA_ARGS__ ) +#define ATLAS_TRACE_MPI( ... ) ATLAS_TRACE_MPI_( ::atlas::mpi::Trace, Here(), __VA_ARGS__ ) #define ATLAS_TRACE_MPI_( Type, location, operation, ... ) \ __ATLAS_TYPE_SCOPE( Type, location, __ATLAS_TRACE_MPI_ENUM( operation ) __ATLAS_COMMA_ARGS( __VA_ARGS__ ) ) diff --git a/src/atlas/runtime/AtlasTool.cc b/src/atlas/runtime/AtlasTool.cc index 9f177c6c0..8c08cdcfb 100644 --- a/src/atlas/runtime/AtlasTool.cc +++ b/src/atlas/runtime/AtlasTool.cc @@ -73,17 +73,17 @@ void debug_reset() { } bool getEnv( const std::string& env, bool default_value ) { - if (::getenv( env.c_str() ) ) { return eckit::Translator()(::getenv( env.c_str() ) ); } + if ( ::getenv( env.c_str() ) ) { return eckit::Translator()( ::getenv( env.c_str() ) ); } return default_value; } int getEnv( const std::string& env, int default_value ) { - if (::getenv( env.c_str() ) ) { return eckit::Translator()(::getenv( env.c_str() ) ); } + if ( ::getenv( env.c_str() ) ) { return eckit::Translator()( ::getenv( env.c_str() ) ); } return default_value; } std::string getEnv( const std::string& env, const std::string& default_value ) { - if (::getenv( env.c_str() ) ) { return ::getenv( env.c_str() ); } + if ( ::getenv( env.c_str() ) ) { return ::getenv( env.c_str() ); } return default_value; } diff --git a/src/atlas/runtime/Trace.h b/src/atlas/runtime/Trace.h index cc86528b0..cef4e8507 100644 --- a/src/atlas/runtime/Trace.h +++ b/src/atlas/runtime/Trace.h @@ -79,8 +79,8 @@ class Trace : public runtime::trace::TraceT { #undef ATLAS_TRACE #undef ATLAS_TRACE_SCOPE -#define ATLAS_TRACE( ... ) __ATLAS_TYPE(::atlas::Trace, Here() __ATLAS_COMMA_ARGS( __VA_ARGS__ ) ) -#define ATLAS_TRACE_SCOPE( ... ) __ATLAS_TYPE_SCOPE(::atlas::Trace, Here() __ATLAS_COMMA_ARGS( __VA_ARGS__ ) ) +#define ATLAS_TRACE( ... ) __ATLAS_TYPE( ::atlas::Trace, Here() __ATLAS_COMMA_ARGS( __VA_ARGS__ ) ) +#define ATLAS_TRACE_SCOPE( ... ) __ATLAS_TYPE_SCOPE( ::atlas::Trace, Here() __ATLAS_COMMA_ARGS( __VA_ARGS__ ) ) #endif diff --git a/src/atlas/trans/ifs/TransIFS.cc b/src/atlas/trans/ifs/TransIFS.cc index 68f9f4f00..191cc277b 100644 --- a/src/atlas/trans/ifs/TransIFS.cc +++ b/src/atlas/trans/ifs/TransIFS.cc @@ -257,7 +257,7 @@ void TransIFS::invtrans( const int nb_scalar_fields, const double scalar_spectra args.lvordivgp = params.vorticity_divergence_fields(); args.nproma = params.nproma(); args.ngpblks = params.ngpblks(); - TRANS_CHECK(::trans_invtrans( &args ) ); + TRANS_CHECK( ::trans_invtrans( &args ) ); } /////////////////////////////////////////////////////////////////////////////// @@ -288,7 +288,7 @@ void TransIFS::dirtrans( const int nb_fields, const double scalar_fields[], doub args.lglobal = params.global(); args.nproma = params.nproma(); args.ngpblks = params.ngpblks(); - TRANS_CHECK(::trans_dirtrans( &args ) ); + TRANS_CHECK( ::trans_dirtrans( &args ) ); } /////////////////////////////////////////////////////////////////////////////// @@ -305,7 +305,7 @@ void TransIFS::dirtrans( const int nb_fields, const double wind_fields[], double args.lglobal = params.global(); args.nproma = params.nproma(); args.ngpblks = params.ngpblks(); - TRANS_CHECK(::trans_dirtrans( &args ) ); + TRANS_CHECK( ::trans_dirtrans( &args ) ); } } // namespace trans @@ -868,7 +868,7 @@ const functionspace::Spectral& TransIFS::spectral() const { } void TransIFS::ctor( const Grid& grid, long truncation, const eckit::Configuration& config ) { - trans_ = std::shared_ptr<::Trans_t>( new ::Trans_t, [](::Trans_t* p ) { + trans_ = std::shared_ptr<::Trans_t>( new ::Trans_t, []( ::Trans_t* p ) { ::trans_delete( p ); delete p; } ); @@ -891,12 +891,12 @@ void TransIFS::ctor_rgg( const long nlat, const idx_t pl[], long truncation, con std::vector nloen( nlat ); for ( long jlat = 0; jlat < nlat; ++jlat ) nloen[jlat] = pl[jlat]; - TRANS_CHECK(::trans_new( trans_.get() ) ); - TRANS_CHECK(::trans_use_mpi( mpi::comm().size() > 1 ) ); - TRANS_CHECK(::trans_set_resol( trans_.get(), nlat, nloen.data() ) ); - if ( truncation >= 0 ) TRANS_CHECK(::trans_set_trunc( trans_.get(), truncation ) ); + TRANS_CHECK( ::trans_new( trans_.get() ) ); + TRANS_CHECK( ::trans_use_mpi( mpi::comm().size() > 1 ) ); + TRANS_CHECK( ::trans_set_resol( trans_.get(), nlat, nloen.data() ) ); + if ( truncation >= 0 ) TRANS_CHECK( ::trans_set_trunc( trans_.get(), truncation ) ); - TRANS_CHECK(::trans_set_cache( trans_.get(), cache_, cachesize_ ) ); + TRANS_CHECK( ::trans_set_cache( trans_.get(), cache_, cachesize_ ) ); if ( p.read_legendre().size() && mpi::comm().size() == 1 ) { eckit::PathName file( p.read_legendre() ); @@ -905,26 +905,26 @@ void TransIFS::ctor_rgg( const long nlat, const idx_t pl[], long truncation, con msg << "File " << file << " doesn't exist"; throw_CantOpenFile( msg.str(), Here() ); } - TRANS_CHECK(::trans_set_read( trans_.get(), file.asString().c_str() ) ); + TRANS_CHECK( ::trans_set_read( trans_.get(), file.asString().c_str() ) ); } if ( p.write_legendre().size() && mpi::comm().size() == 1 ) { eckit::PathName file( p.write_legendre() ); - TRANS_CHECK(::trans_set_write( trans_.get(), file.asString().c_str() ) ); + TRANS_CHECK( ::trans_set_write( trans_.get(), file.asString().c_str() ) ); } trans_->fft = p.fft(); trans_->lsplit = p.split_latitudes(); trans_->flt = p.flt(); - ATLAS_TRACE_SCOPE( "trans_setup" ) { TRANS_CHECK(::trans_setup( trans_.get() ) ); } + ATLAS_TRACE_SCOPE( "trans_setup" ) { TRANS_CHECK( ::trans_setup( trans_.get() ) ); } } void TransIFS::ctor_lonlat( const long nlon, const long nlat, long truncation, const eckit::Configuration& config ) { TransParameters p( *this, config ); - TRANS_CHECK(::trans_new( trans_.get() ) ); - TRANS_CHECK(::trans_use_mpi( mpi::comm().size() > 1 ) ); - TRANS_CHECK(::trans_set_resol_lonlat( trans_.get(), nlon, nlat ) ); - if ( truncation >= 0 ) TRANS_CHECK(::trans_set_trunc( trans_.get(), truncation ) ); - TRANS_CHECK(::trans_set_cache( trans_.get(), cache_, cachesize_ ) ); + TRANS_CHECK( ::trans_new( trans_.get() ) ); + TRANS_CHECK( ::trans_use_mpi( mpi::comm().size() > 1 ) ); + TRANS_CHECK( ::trans_set_resol_lonlat( trans_.get(), nlon, nlat ) ); + if ( truncation >= 0 ) TRANS_CHECK( ::trans_set_trunc( trans_.get(), truncation ) ); + TRANS_CHECK( ::trans_set_cache( trans_.get(), cache_, cachesize_ ) ); if ( p.read_legendre().size() && mpi::comm().size() == 1 ) { eckit::PathName file( p.read_legendre() ); @@ -933,18 +933,18 @@ void TransIFS::ctor_lonlat( const long nlon, const long nlat, long truncation, c msg << "File " << file << " doesn't exist"; throw_CantOpenFile( msg.str(), Here() ); } - TRANS_CHECK(::trans_set_read( trans_.get(), file.asString().c_str() ) ); + TRANS_CHECK( ::trans_set_read( trans_.get(), file.asString().c_str() ) ); } if ( p.write_legendre().size() && mpi::comm().size() == 1 ) { eckit::PathName file( p.write_legendre() ); - TRANS_CHECK(::trans_set_write( trans_.get(), file.asString().c_str() ) ); + TRANS_CHECK( ::trans_set_write( trans_.get(), file.asString().c_str() ) ); } trans_->fft = p.fft(); trans_->lsplit = p.split_latitudes(); trans_->flt = p.flt(); - TRANS_CHECK(::trans_setup( trans_.get() ) ); + TRANS_CHECK( ::trans_setup( trans_.get() ) ); } // -------------------------------------------------------------------------------------------- @@ -991,7 +991,7 @@ void TransIFS::__dirtrans( const functionspace::NodeColumns& gp, const FieldSet& transform.nscalar = nfld; transform.rgp = rgp.data(); transform.rspscalar = rsp.data(); - TRANS_CHECK(::trans_dirtrans( &transform ) ); + TRANS_CHECK( ::trans_dirtrans( &transform ) ); } // Unpack the spectral fields @@ -1039,7 +1039,7 @@ void TransIFS::__dirtrans( const StructuredColumns& gp, const Field& gpfield, co transform.rspscalar = rsp.data(); transform.ngpblks = ngptot(); transform.nproma = 1; - TRANS_CHECK(::trans_dirtrans( &transform ) ); + TRANS_CHECK( ::trans_dirtrans( &transform ) ); } // Unpack spectral @@ -1085,7 +1085,7 @@ void TransIFS::__dirtrans( const StructuredColumns& gp, const FieldSet& gpfields transform.rgp = rgp.data(); transform.rspscalar = rsp.data(); - TRANS_CHECK(::trans_dirtrans( &transform ) ); + TRANS_CHECK( ::trans_dirtrans( &transform ) ); } // Unpack the spectral fields @@ -1144,7 +1144,7 @@ void TransIFS::__invtrans_grad( const Spectral& sp, const FieldSet& spfields, co transform.rspscalar = rsp.data(); transform.lscalarders = true; - TRANS_CHECK(::trans_invtrans( &transform ) ); + TRANS_CHECK( ::trans_invtrans( &transform ) ); } // Unpack the gridpoint fields @@ -1229,7 +1229,7 @@ void TransIFS::__invtrans( const Spectral& sp, const FieldSet& spfields, const f transform.nscalar = nfld; transform.rgp = rgp.data(); transform.rspscalar = rsp.data(); - TRANS_CHECK(::trans_invtrans( &transform ) ); + TRANS_CHECK( ::trans_invtrans( &transform ) ); } // Unpack the gridpoint fields @@ -1277,7 +1277,7 @@ void TransIFS::__invtrans( const functionspace::Spectral& sp, const Field& spfie transform.rspscalar = rsp.data(); transform.ngpblks = ngptot(); transform.nproma = 1; - TRANS_CHECK(::trans_invtrans( &transform ) ); + TRANS_CHECK( ::trans_invtrans( &transform ) ); } // Unpack gridpoint fields @@ -1330,7 +1330,7 @@ void TransIFS::__invtrans( const functionspace::Spectral& sp, const FieldSet& sp transform.rgp = rgp.data(); transform.rspscalar = rsp.data(); - TRANS_CHECK(::trans_invtrans( &transform ) ); + TRANS_CHECK( ::trans_invtrans( &transform ) ); } // Unpack the gridpoint fields @@ -1393,7 +1393,7 @@ void TransIFS::__dirtrans_wind2vordiv( const functionspace::NodeColumns& gp, con ATLAS_ASSERT( transform.rspvor ); ATLAS_ASSERT( transform.rspdiv ); - TRANS_CHECK(::trans_dirtrans( &transform ) ); + TRANS_CHECK( ::trans_dirtrans( &transform ) ); } // Pack spectral fields @@ -1455,7 +1455,7 @@ void TransIFS::__invtrans_vordiv2wind( const Spectral& sp, const Field& spvor, c ATLAS_ASSERT( transform.rspvor ); ATLAS_ASSERT( transform.rspdiv ); - TRANS_CHECK(::trans_invtrans( &transform ) ); + TRANS_CHECK( ::trans_invtrans( &transform ) ); } // Unpack the gridpoint fields @@ -1475,7 +1475,7 @@ void TransIFS::distspec( const int nb_fields, const int origin[], const double g args.rspecg = global_spectra; args.nfrom = origin; args.rspec = spectra; - TRANS_CHECK(::trans_distspec( &args ) ); + TRANS_CHECK( ::trans_distspec( &args ) ); } ///////////////////////////////////////////////////////////////////////////// @@ -1487,7 +1487,7 @@ void TransIFS::gathspec( const int nb_fields, const int destination[], const dou args.rspecg = global_spectra; args.nto = destination; args.rspec = spectra; - TRANS_CHECK(::trans_gathspec( &args ) ); + TRANS_CHECK( ::trans_gathspec( &args ) ); } ///////////////////////////////////////////////////////////////////////////// @@ -1499,7 +1499,7 @@ void TransIFS::distgrid( const int nb_fields, const int origin[], const double g args.nfrom = origin; args.rgpg = global_fields; args.rgp = fields; - TRANS_CHECK(::trans_distgrid( &args ) ); + TRANS_CHECK( ::trans_distgrid( &args ) ); } ///////////////////////////////////////////////////////////////////////////// @@ -1511,7 +1511,7 @@ void TransIFS::gathgrid( const int nb_fields, const int destination[], const dou args.nto = destination; args.rgp = fields; args.rgpg = global_fields; - TRANS_CHECK(::trans_gathgrid( &args ) ); + TRANS_CHECK( ::trans_gathgrid( &args ) ); } /////////////////////////////////////////////////////////////////////////////// @@ -1522,7 +1522,7 @@ void TransIFS::specnorm( const int nb_fields, const double spectra[], double nor args.rspec = spectra; args.rnorm = norms; args.nmaster = rank + 1; - TRANS_CHECK(::trans_specnorm( &args ) ); + TRANS_CHECK( ::trans_specnorm( &args ) ); } /////////////////////////////////////////////////////////////////////////////// diff --git a/src/atlas/trans/ifs/VorDivToUVIFS.cc b/src/atlas/trans/ifs/VorDivToUVIFS.cc index 374adcce3..7adcaccf7 100644 --- a/src/atlas/trans/ifs/VorDivToUVIFS.cc +++ b/src/atlas/trans/ifs/VorDivToUVIFS.cc @@ -49,7 +49,7 @@ void VorDivToUVIFS::execute( const int nb_coeff, const int nb_fields, const doub vordiv_to_UV.nfld = nb_fields; vordiv_to_UV.ncoeff = nb_coeff; vordiv_to_UV.nsmax = truncation_; - TRANS_CHECK(::trans_vordiv_to_UV( &vordiv_to_UV ) ); + TRANS_CHECK( ::trans_vordiv_to_UV( &vordiv_to_UV ) ); } VorDivToUVIFS::VorDivToUVIFS( const int truncation, const eckit::Configuration& ) : truncation_( truncation ) {} diff --git a/src/atlas/trans/local/TransLocal.cc b/src/atlas/trans/local/TransLocal.cc index 81d158412..1b70daec0 100644 --- a/src/atlas/trans/local/TransLocal.cc +++ b/src/atlas/trans/local/TransLocal.cc @@ -587,7 +587,7 @@ TransLocal::TransLocal( const Cache& cache, const Grid& grid, const Domain& doma // write.close(); // } } - // other FFT implementations should be added with #elif statements + // other FFT implementations should be added with #elif statements #else useFFT_ = false; // no FFT implemented => default to dgemm std::string file_path = TransParameters( config ).write_fft(); diff --git a/src/tests/AtlasTestEnvironment.h b/src/tests/AtlasTestEnvironment.h index 779d1aab5..04e6a9721 100644 --- a/src/tests/AtlasTestEnvironment.h +++ b/src/tests/AtlasTestEnvironment.h @@ -150,12 +150,12 @@ void debug_reset() { } bool getEnv( const std::string& env, bool default_value ) { - if (::getenv( env.c_str() ) ) { return eckit::Translator()(::getenv( env.c_str() ) ); } + if ( ::getenv( env.c_str() ) ) { return eckit::Translator()( ::getenv( env.c_str() ) ); } return default_value; } int getEnv( const std::string& env, int default_value ) { - if (::getenv( env.c_str() ) ) { return eckit::Translator()(::getenv( env.c_str() ) ); } + if ( ::getenv( env.c_str() ) ) { return eckit::Translator()( ::getenv( env.c_str() ) ); } return default_value; } diff --git a/src/tests/functionspace/test_stencil.cc b/src/tests/functionspace/test_stencil.cc index 3a593063a..086160642 100644 --- a/src/tests/functionspace/test_stencil.cc +++ b/src/tests/functionspace/test_stencil.cc @@ -233,7 +233,7 @@ CASE( "test vertical stencil" ) { } } - //----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- #if 1 CASE( "ifs method to find nearest grid point" ) { diff --git a/src/tests/trans/test_trans.cc b/src/tests/trans/test_trans.cc index 6256f7bc4..a78b7eb33 100644 --- a/src/tests/trans/test_trans.cc +++ b/src/tests/trans/test_trans.cc @@ -99,7 +99,7 @@ void read_rspecg( Field spec ) { Log::info() << "read_rspecg ... done" << std::endl; } - //----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- #if 1 diff --git a/src/tests/trans/test_transgeneral.cc b/src/tests/trans/test_transgeneral.cc index 01ba01753..b4b78ff1e 100644 --- a/src/tests/trans/test_transgeneral.cc +++ b/src/tests/trans/test_transgeneral.cc @@ -1319,7 +1319,7 @@ CASE( "test_trans_unstructured" ) { } #endif - //----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- #if 0 CASE( "test_trans_fourier_truncation" ) { diff --git a/src/tests/util/test_indexview.cc b/src/tests/util/test_indexview.cc index c62cfa00c..dcd7ebb20 100644 --- a/src/tests/util/test_indexview.cc +++ b/src/tests/util/test_indexview.cc @@ -38,9 +38,9 @@ std::string pos( Iterator& it ) { return ss.str(); } - //----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- - /* +/* CASE( "test_array" ) { array::ArrayT _array (3,1,4); diff --git a/tools/apply-clang-format.sh b/tools/apply-clang-format.sh index 91532fe80..4b01a8162 100755 --- a/tools/apply-clang-format.sh +++ b/tools/apply-clang-format.sh @@ -8,7 +8,7 @@ # granted to it by virtue of its status as an intergovernmental organisation nor # does it submit to any jurisdiction. -_REQUIRED_CLANG_VERSION='5.0.1' +_REQUIRED_CLANG_VERSION='7.0.1' if ! [ -x "$(command -v clang-format)" ]; then echo 'Error: clang-format is not installed.' >&2 From 56f8b7d4fb441b647bb1e4a9718d28e96e9b9ff0 Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Fri, 12 Jul 2019 15:01:02 +0100 Subject: [PATCH 80/86] clang-format: AllowShortBlocksOnASingleLine -> false, AllowShortIfStatementsOnASingleLine -> false --- .clang-format | 25 ++- src/apps/atlas-benchmark.cc | 18 +- src/apps/atlas-gaussian-latitudes.cc | 12 +- src/apps/atlas-gmsh-extract.cc | 30 ++- src/apps/atlas-grids.cc | 12 +- src/apps/atlas-loadbalance.cc | 18 +- src/apps/atlas-meshgen.cc | 20 +- src/atlas/array/ArraySpec.cc | 10 +- src/atlas/array/LocalView.h | 4 +- src/atlas/array/SVector.h | 6 +- src/atlas/array/Table.cc | 10 +- src/atlas/array/Vector.h | 6 +- src/atlas/array/gridtools/GridToolsArray.cc | 13 +- .../array/gridtools/GridToolsArrayHelpers.h | 4 +- src/atlas/array/helpers/ArrayInitializer.h | 4 +- src/atlas/array/helpers/ArrayWriter.h | 3 +- src/atlas/array/native/NativeArray.cc | 10 +- src/atlas/array/native/NativeArrayView.h | 4 +- src/atlas/array/native/NativeIndexView.h | 4 +- src/atlas/domain/detail/Domain.cc | 4 +- src/atlas/domain/detail/GlobalDomain.cc | 4 +- src/atlas/domain/detail/RectangularDomain.cc | 27 ++- src/atlas/domain/detail/ZonalBandDomain.cc | 10 +- src/atlas/field/FieldCreatorArraySpec.cc | 7 +- src/atlas/field/FieldCreatorIFS.cc | 7 +- src/atlas/field/FieldSet.cc | 4 +- src/atlas/field/FieldSet.h | 6 +- src/atlas/field/State.cc | 3 +- src/atlas/field/detail/FieldImpl.cc | 6 +- src/atlas/functionspace/EdgeColumns.cc | 32 +++- src/atlas/functionspace/NodeColumns.cc | 40 ++-- src/atlas/functionspace/Spectral.cc | 25 ++- src/atlas/functionspace/StructuredColumns.cc | 56 ++++-- src/atlas/functionspace/StructuredColumns.h | 12 +- .../detail/NodeColumns_FieldStatistics.cc | 48 +++-- .../detail/StructuredColumns_setup.cc | 24 ++- src/atlas/grid/Grid.cc | 3 +- src/atlas/grid/Partitioner.cc | 3 +- src/atlas/grid/StencilComputer.cc | 16 +- src/atlas/grid/StencilComputer.h | 4 +- .../detail/distribution/DistributionImpl.cc | 11 +- src/atlas/grid/detail/grid/Gaussian.cc | 8 +- src/atlas/grid/detail/grid/Grid.cc | 24 ++- src/atlas/grid/detail/grid/GridBuilder.cc | 28 ++- src/atlas/grid/detail/grid/LonLat.cc | 8 +- src/atlas/grid/detail/grid/Regional.cc | 72 ++++--- src/atlas/grid/detail/grid/Structured.cc | 58 ++++-- src/atlas/grid/detail/grid/Structured.h | 3 +- src/atlas/grid/detail/grid/Unstructured.cc | 31 ++- src/atlas/grid/detail/grid/Unstructured.h | 6 +- .../partitioner/CheckerboardPartitioner.cc | 25 ++- .../partitioner/EqualRegionsPartitioner.cc | 27 ++- .../detail/partitioner/TransPartitioner.cc | 6 +- .../grid/detail/spacing/CustomSpacing.cc | 4 +- src/atlas/grid/detail/spacing/FocusSpacing.cc | 16 +- .../grid/detail/spacing/GaussianSpacing.cc | 7 +- src/atlas/grid/detail/spacing/Spacing.cc | 4 +- .../grid/detail/spacing/gaussian/Latitudes.cc | 6 +- src/atlas/interpolation/element/Quad3D.cc | 3 +- src/atlas/interpolation/element/Quad3D.h | 12 +- src/atlas/interpolation/element/Triag3D.cc | 16 +- src/atlas/interpolation/element/Triag3D.h | 9 +- src/atlas/interpolation/method/Method.cc | 23 ++- .../interpolation/method/fe/FiniteElement.cc | 31 ++- .../method/knn/KNearestNeighbours.cc | 4 +- .../method/knn/NearestNeighbour.cc | 4 +- .../method/structured/kernels/Cubic3DKernel.h | 24 ++- .../kernels/CubicHorizontalKernel.h | 24 ++- .../structured/kernels/CubicVerticalKernel.h | 4 +- .../structured/kernels/QuasiCubic3DKernel.h | 24 ++- .../kernels/QuasiCubicHorizontalKernel.h | 24 ++- src/atlas/library/Library.cc | 48 +++-- src/atlas/mesh/Connectivity.cc | 18 +- src/atlas/mesh/Elements.cc | 3 +- src/atlas/mesh/Nodes.cc | 3 +- src/atlas/mesh/PartitionPolygon.cc | 4 +- src/atlas/mesh/actions/BuildCellCentres.cc | 8 +- src/atlas/mesh/actions/BuildConvexHull3D.cc | 3 +- src/atlas/mesh/actions/BuildDualMesh.cc | 6 +- src/atlas/mesh/actions/BuildEdges.cc | 25 ++- src/atlas/mesh/actions/BuildHalo.cc | 53 ++++-- src/atlas/mesh/actions/BuildParallelFields.cc | 70 +++++-- src/atlas/mesh/actions/BuildStatistics.cc | 9 +- src/atlas/mesh/actions/ExtendNodesGlobal.cc | 7 +- .../mesh/actions/WriteLoadBalanceReport.cc | 4 +- src/atlas/mesh/detail/AccumulateFacets.cc | 22 ++- src/atlas/mesh/detail/MeshImpl.cc | 77 +++++--- src/atlas/mesh/detail/PartitionGraph.cc | 15 +- .../detail/RegularMeshGenerator.cc | 22 ++- .../detail/StructuredMeshGenerator.cc | 163 +++++++++++----- src/atlas/numerics/fvm/Method.cc | 6 +- src/atlas/numerics/fvm/Nabla.cc | 16 +- src/atlas/option/Options.cc | 4 +- src/atlas/output/Gmsh.cc | 7 +- src/atlas/output/Output.cc | 4 +- src/atlas/output/detail/GmshIO.cc | 69 ++++--- src/atlas/output/detail/PointCloudIO.cc | 45 +++-- src/atlas/parallel/Checksum.h | 4 +- src/atlas/parallel/GatherScatter.cc | 9 +- src/atlas/parallel/GatherScatter.h | 14 +- src/atlas/parallel/HaloExchange.cc | 9 +- src/atlas/parallel/HaloExchange.h | 12 +- src/atlas/parallel/omp/omp.cc | 30 ++- .../projection/detail/LambertProjection.cc | 23 ++- .../projection/detail/LonLatProjection.cc | 12 +- .../projection/detail/MercatorProjection.cc | 10 +- src/atlas/projection/detail/ProjectionImpl.cc | 20 +- .../projection/detail/SchmidtProjection.cc | 3 +- src/atlas/runtime/AtlasTool.cc | 68 ++++--- src/atlas/runtime/Exception.h | 8 +- src/atlas/runtime/trace/Barriers.cc | 4 +- src/atlas/runtime/trace/CallStack.cc | 3 +- src/atlas/runtime/trace/Logging.cc | 12 +- src/atlas/runtime/trace/Nesting.h | 6 +- src/atlas/runtime/trace/Timings.cc | 22 ++- src/atlas/runtime/trace/TraceT.h | 4 +- src/atlas/trans/Cache.cc | 8 +- src/atlas/trans/detail/TransFactory.cc | 12 +- .../trans/ifs/LegendreCacheCreatorIFS.cc | 16 +- src/atlas/trans/ifs/TransIFS.cc | 79 +++++--- .../trans/local/LegendreCacheCreatorLocal.cc | 6 +- src/atlas/trans/local/LegendrePolynomials.cc | 3 +- src/atlas/trans/local/TransLocal.cc | 112 ++++++++--- src/atlas/trans/local/VorDivToUVLocal.cc | 4 +- src/atlas/util/Allocate.cc | 9 +- src/atlas/util/Config.cc | 38 ++-- src/atlas/util/Factory.cc | 8 +- src/atlas/util/LonLatMicroDeg.h | 6 +- src/atlas/util/LonLatPolygon.cc | 4 +- src/atlas/util/Metadata.cc | 8 +- src/atlas/util/Metadata.h | 3 +- src/atlas/util/ObjectHandle.cc | 7 +- src/atlas/util/ObjectHandle.h | 12 +- src/atlas/util/Polygon.cc | 8 +- src/atlas/util/Rotation.cc | 17 +- src/atlas/util/SphericalPolygon.cc | 8 +- src/atlas/util/detail/Debug.h | 21 ++- src/atlas_f/internals/atlas_read_file.cc | 4 +- .../atlas-benchmark-ifs-setup.cc | 6 +- .../atlas-benchmark-sorting.cc | 10 +- .../atlas-grid-distribution.cc | 9 +- src/sandbox/interpolation/PartitionedMesh.cc | 4 +- .../atlas-parallel-interpolation.cc | 16 +- src/tests/AtlasTestEnvironment.h | 28 ++- src/tests/acceptance_tests/atest_mgrids.cc | 12 +- src/tests/array/test_array.cc | 6 +- src/tests/functionspace/test_functionspace.cc | 24 ++- src/tests/functionspace/test_reduced_halo.cc | 8 +- src/tests/functionspace/test_stencil.cc | 4 +- src/tests/grid/test_grid_hash.cc | 4 +- src/tests/grid/test_grid_ptr.cc | 3 +- src/tests/grid/test_state.cc | 12 +- .../CubicInterpolationPrototype.h | 8 +- .../test_interpolation_cubic_prototype.cc | 19 +- .../test_interpolation_structured2D.cc | 4 +- src/tests/io/test_pointcloud_io.cc | 3 +- src/tests/mesh/test_distmesh.cc | 8 +- src/tests/mesh/test_halo.cc | 4 +- src/tests/mesh/test_parfields.cc | 25 ++- src/tests/mesh/test_rgg.cc | 4 +- src/tests/mesh/test_shapefunctions.cc | 56 ++++-- src/tests/numerics/test_fvm_nabla.cc | 4 +- src/tests/projection/FindGoodWest.h | 6 +- src/tests/projection/test_bounding_box.cc | 4 +- src/tests/projection/test_rotation.cc | 6 +- src/tests/runtime/test_trace.cc | 4 +- src/tests/trans/test_trans.cc | 11 +- src/tests/trans/test_trans_invtrans_grad.cc | 3 +- src/tests/trans/test_trans_localcache.cc | 7 +- src/tests/trans/test_transgeneral.cc | 177 ++++++++++++------ src/tests/util/test_metadata.cc | 17 +- 171 files changed, 2111 insertions(+), 882 deletions(-) diff --git a/.clang-format b/.clang-format index 24bfb9984..29688b683 100644 --- a/.clang-format +++ b/.clang-format @@ -8,18 +8,18 @@ AlignEscapedNewlines: Left AlignOperands: true AlignTrailingComments: true AllowAllParametersOfDeclarationOnNextLine: true -AllowShortBlocksOnASingleLine: true +AllowShortBlocksOnASingleLine: false AllowShortCaseLabelsOnASingleLine: false AllowShortFunctionsOnASingleLine: Inline -AllowShortIfStatementsOnASingleLine: true +AllowShortIfStatementsOnASingleLine: false AllowShortLoopsOnASingleLine: false AlwaysBreakAfterDefinitionReturnType: None AlwaysBreakAfterReturnType: None AlwaysBreakBeforeMultilineStrings: true -AlwaysBreakTemplateDeclarations: true +AlwaysBreakTemplateDeclarations: Yes BinPackArguments: true BinPackParameters: true -BraceWrapping: +BraceWrapping: AfterClass: false AfterControlStatement: false AfterEnum: true @@ -28,6 +28,7 @@ BraceWrapping: AfterObjCDeclaration: false AfterStruct: false AfterUnion: false + AfterExternBlock: false BeforeCatch: true BeforeElse: true IndentBraces: false @@ -37,6 +38,7 @@ BraceWrapping: BreakBeforeBinaryOperators: None BreakBeforeBraces: Custom BreakBeforeInheritanceComma: false +BreakInheritanceList: BeforeColon BreakBeforeTernaryOperators: true BreakConstructorInitializersBeforeComma: false BreakConstructorInitializers: AfterColon @@ -53,11 +55,12 @@ DerivePointerAlignment: false DisableFormat: false ExperimentalAutoDetectBinPacking: false FixNamespaceComments: true -ForEachMacros: +ForEachMacros: - foreach - Q_FOREACH - BOOST_FOREACH -IncludeCategories: +IncludeBlocks: Preserve +IncludeCategories: - Regex: '^<.*\.h>' Priority: 1 - Regex: '^<.*' @@ -66,7 +69,8 @@ IncludeCategories: Priority: 3 IncludeIsMainRegex: '([-_](test|unittest))?$' IndentCaseLabels: true -IndentWidth: 4 +IndentPPDirectives: None +IndentWidth: 4 IndentWrappedFunctionNames: false JavaScriptQuotes: Leave JavaScriptWrapImports: true @@ -75,6 +79,7 @@ MacroBlockBegin: '' MacroBlockEnd: '' MaxEmptyLinesToKeep: 2 NamespaceIndentation: None +ObjCBinPackProtocolList: Auto ObjCBlockIndentWidth: 2 ObjCSpaceAfterProperty: false ObjCSpaceBeforeProtocolList: false @@ -83,6 +88,7 @@ PenaltyBreakBeforeFirstCallParameter: 1 PenaltyBreakComment: 300 PenaltyBreakFirstLessLess: 120 PenaltyBreakString: 1000 +PenaltyBreakTemplateDeclaration: 10 PenaltyExcessCharacter: 1000000 PenaltyReturnTypeOnItsOwnLine: 200 PointerAlignment: Left @@ -92,7 +98,11 @@ SortUsingDeclarations: true SpaceAfterCStyleCast: false SpaceAfterTemplateKeyword: true SpaceBeforeAssignmentOperators: true +SpaceBeforeCpp11BracedList: false +SpaceBeforeCtorInitializerColon: true +SpaceBeforeInheritanceColon: true SpaceBeforeParens: ControlStatements +SpaceBeforeRangeBasedForLoopColon: true SpaceInEmptyParentheses: false SpacesBeforeTrailingComments: 2 SpacesInAngles: false @@ -104,3 +114,4 @@ Standard: Auto TabWidth: 4 UseTab: Never ... + diff --git a/src/apps/atlas-benchmark.cc b/src/apps/atlas-benchmark.cc index 3595d6964..cd282f80a 100644 --- a/src/apps/atlas-benchmark.cc +++ b/src/apps/atlas-benchmark.cc @@ -99,8 +99,10 @@ struct TimerStats { } void update( Trace& timer ) { double t = timer.elapsed(); - if ( min < 0 ) min = t; - if ( max < 0 ) max = t; + if ( min < 0 ) + min = t; + if ( max < 0 ) + max = t; min = std::min( min, t ); max = std::max( max, t ); avg = ( avg * cnt + t ) / ( cnt + 1 ); @@ -198,7 +200,8 @@ int AtlasBenchmark::execute( const Args& args ) { iteration_timer = TimerStats( "iteration" ); haloexchange_timer = TimerStats( "halo-exchange" ); - if ( omp_threads > 0 ) atlas_omp_set_num_threads( omp_threads ); + if ( omp_threads > 0 ) + atlas_omp_set_num_threads( omp_threads ); Log::info() << "atlas-benchmark\n" << endl; Log::info() << Library::instance().information() << endl; @@ -231,7 +234,8 @@ int AtlasBenchmark::execute( const Args& args ) { ++tic; } if ( iter == niter - 1 ) { - if ( tic < 51 ) Log::info() << '*'; + if ( tic < 51 ) + Log::info() << '*'; Log::info() << endl; } } @@ -367,7 +371,8 @@ void AtlasBenchmark::setup() { vector tmp( nedges ); int c( 0 ); for ( idx_t jedge = 0; jedge < nedges; ++jedge ) { - if ( is_pole_edge( jedge ) ) tmp[c++] = jedge; + if ( is_pole_edge( jedge ) ) + tmp[c++] = jedge; } pole_edges.reserve( c ); for ( idx_t jedge = 0; jedge < c; ++jedge ) @@ -448,7 +453,8 @@ void AtlasBenchmark::iteration() { grad( jnode, 0, ZZ ) = ( field( jnode, 1 ) - field( jnode, 0 ) ) * dzi; grad( jnode, nlev - 1, ZZ ) = ( field( jnode, nlev - 2 ) - field( jnode, nlev - 1 ) ) * dzi; } - if ( nlev == 1 ) grad( jnode, 0, ZZ ) = 0.; + if ( nlev == 1 ) + grad( jnode, 0, ZZ ) = 0.; } compute.stop(); diff --git a/src/apps/atlas-gaussian-latitudes.cc b/src/apps/atlas-gaussian-latitudes.cc index 6cc899623..7ab774ecd 100644 --- a/src/apps/atlas-gaussian-latitudes.cc +++ b/src/apps/atlas-gaussian-latitudes.cc @@ -80,7 +80,8 @@ class AtlasGaussianLatitudes : public eckit::Tool { format = Resource( "--format", std::string( "table" ) ); - if ( N > 0 ) do_run = true; + if ( N > 0 ) + do_run = true; if ( do_run == false ) { if ( help ) @@ -101,7 +102,8 @@ class AtlasGaussianLatitudes : public eckit::Tool { //------------------------------------------------------------------------------ void AtlasGaussianLatitudes::run() { - if ( !do_run ) return; + if ( !do_run ) + return; GaussianSpacing lats( 2 * N ); @@ -116,8 +118,10 @@ void AtlasGaussianLatitudes::run() { std::cout << "double lat[] = {" << std::endl; for ( int jlat = 0; jlat < end; ++jlat ) { std::cout << std::setw( 16 ) << std::setprecision( 12 ) << std::fixed << lats[jlat]; - if ( jlat != end - 1 ) std::cout << ","; - if ( ( compact && ( jlat + 1 ) % 5 == 0 ) || !compact || jlat == end - 1 ) std::cout << std::endl; + if ( jlat != end - 1 ) + std::cout << ","; + if ( ( compact && ( jlat + 1 ) % 5 == 0 ) || !compact || jlat == end - 1 ) + std::cout << std::endl; } std::cout << "};" << std::endl; } diff --git a/src/apps/atlas-gmsh-extract.cc b/src/apps/atlas-gmsh-extract.cc index 6a1c1032c..d556352a3 100644 --- a/src/apps/atlas-gmsh-extract.cc +++ b/src/apps/atlas-gmsh-extract.cc @@ -101,13 +101,15 @@ class gmsh_extract : public eckit::Tool { if ( std::string( argv[i] ) == "-i" ) { for ( int j = i + 1; j < argc; ++j ) { std::string in_file( argv[j] ); - if ( in_file[0] == '-' ) break; + if ( in_file[0] == '-' ) + break; in_files.push_back( in_file ); } } } - if ( in_files.empty() ) throw_Exception( "missing input filename, parameter -i\n" + help_str, Here() ); + if ( in_files.empty() ) + throw_Exception( "missing input filename, parameter -i\n" + help_str, Here() ); } private: @@ -121,7 +123,8 @@ class gmsh_extract : public eckit::Tool { //------------------------------------------------------------------------------------------------------ void gmsh_extract::run() { - if ( !do_run ) return; + if ( !do_run ) + return; atlas::Library::instance().initialise( argc(), argv() ); Log::debug() << "Command line:" << std::endl; for ( int i = 0; i < argc(); ++i ) @@ -131,7 +134,8 @@ void gmsh_extract::run() { std::ofstream out_file; if ( !out_filename.empty() ) { out_file.open( out_filename.c_str(), std::ios::out | std::ios::binary ); - if ( !out_file.is_open() ) throw_CantOpenFile( out_filename ); + if ( !out_file.is_open() ) + throw_CantOpenFile( out_filename ); } std::ostream& out = out_filename.empty() ? std::cout : out_file; @@ -146,13 +150,15 @@ void gmsh_extract::run() { std::ifstream in_file; in_file.open( gmsh_file.localPath(), std::ios::in | std::ios::binary ); - if ( !in_file.is_open() ) throw_CantOpenFile( gmsh_file ); + if ( !in_file.is_open() ) + throw_CantOpenFile( gmsh_file ); std::string line; std::string ctxt = ""; while ( true ) { std::getline( in_file, line ); - if ( in_file.eof() ) break; + if ( in_file.eof() ) + break; if ( line == "$MeshFormat" ) { out << line << "\n"; std::getline( in_file, line ); @@ -161,9 +167,12 @@ void gmsh_extract::run() { out << line << "\n"; std::getline( in_file, line ); } - if ( line == "$NodeData" ) ctxt = "NodeData"; - if ( line == "$ElementData" ) ctxt = "ElementData"; - if ( line == "$ElementNodeData" ) ctxt = "ElementNodeData"; + if ( line == "$NodeData" ) + ctxt = "NodeData"; + if ( line == "$ElementData" ) + ctxt = "ElementData"; + if ( line == "$ElementNodeData" ) + ctxt = "ElementNodeData"; if ( !ctxt.empty() ) { std::string end_ctxt = "$End" + ctxt; @@ -209,7 +218,8 @@ void gmsh_extract::run() { } } } - if ( !out_filename.empty() ) out_file.close(); + if ( !out_filename.empty() ) + out_file.close(); atlas::Library::instance().finalise(); } diff --git a/src/apps/atlas-grids.cc b/src/apps/atlas-grids.cc index 17c6bba0c..5a76e2483 100644 --- a/src/apps/atlas-grids.cc +++ b/src/apps/atlas-grids.cc @@ -84,7 +84,9 @@ int AtlasGrids::execute( const Args& args ) { bool do_run = list || ( !key.empty() && ( info || json || rtable || check ) ); - if ( !key.empty() && !do_run ) { Log::error() << "Option wrong or missing after '" << key << "'" << std::endl; } + if ( !key.empty() && !do_run ) { + Log::error() << "Option wrong or missing after '" << key << "'" << std::endl; + } if ( list ) { Log::info() << "usage: atlas-grids GRID [OPTION]... [--help]\n" << std::endl; @@ -98,7 +100,9 @@ int AtlasGrids::execute( const Args& args ) { eckit::PathName path{key}; Grid grid = path.exists() ? Grid( Grid::Spec{path} ) : Grid( key ); - if ( !grid ) { return failed(); } + if ( !grid ) { + return failed(); + } if ( info ) { Log::info() << "Grid " << key << std::endl; @@ -334,7 +338,9 @@ int AtlasGrids::execute( const Args& args ) { Log::warning() << "Check for bounding_box(n,w,s,e) skipped" << std::endl; } - if ( check_failed ) { return failed(); } + if ( check_failed ) { + return failed(); + } Log::info() << "SUCCESS: All checks passed" << std::endl; } } diff --git a/src/apps/atlas-loadbalance.cc b/src/apps/atlas-loadbalance.cc index d337619a5..f6039571e 100644 --- a/src/apps/atlas-loadbalance.cc +++ b/src/apps/atlas-loadbalance.cc @@ -77,7 +77,9 @@ class AtlasLoadbalance : public eckit::Tool { key = ""; for ( int i = 0; i < argc; ++i ) { - if ( i == 1 && argv[i][0] != '-' ) { key = std::string( argv[i] ); } + if ( i == 1 && argv[i][0] != '-' ) { + key = std::string( argv[i] ); + } } halo = Resource( "--halo", 1 ); @@ -95,7 +97,8 @@ class AtlasLoadbalance : public eckit::Tool { //------------------------------------------------------------------------------------------------------ void AtlasLoadbalance::run() { - if ( !do_run ) return; + if ( !do_run ) + return; StructuredGrid grid; try { @@ -104,18 +107,23 @@ void AtlasLoadbalance::run() { catch ( eckit::Exception& err ) { } - if ( !grid ) return; + if ( !grid ) + return; MeshGenerator meshgenerator( "structured" ); Mesh mesh = meshgenerator.generate( grid ); functionspace::NodeColumns nodes( mesh, option::halo( halo ) ); - if ( output.size() ) { write_load_balance_report( mesh, output ); } + if ( output.size() ) { + write_load_balance_report( mesh, output ); + } else { std::stringstream s; write_load_balance_report( mesh, s ); - if ( mpi::comm().rank() == 0 ) { std::cout << s.str() << std::endl; } + if ( mpi::comm().rank() == 0 ) { + std::cout << s.str() << std::endl; + } } atlas::Library::instance().finalise(); } diff --git a/src/apps/atlas-meshgen.cc b/src/apps/atlas-meshgen.cc index 548c5692a..c2bc0eec5 100644 --- a/src/apps/atlas-meshgen.cc +++ b/src/apps/atlas-meshgen.cc @@ -138,7 +138,8 @@ int Meshgen2Gmsh::execute( const Args& args ) { args.get( "binary", binary ); std::string path_in_str = ""; - if ( args.get( "grid.json", path_in_str ) ) path_in = path_in_str; + if ( args.get( "grid.json", path_in_str ) ) + path_in = path_in_str; if ( args.count() ) path_out = args( 0 ); @@ -151,7 +152,8 @@ int Meshgen2Gmsh::execute( const Args& args ) { return failed(); } - if ( edges ) halo = std::max( halo, 1l ); + if ( edges ) + halo = std::max( halo, 1l ); StructuredGrid grid; if ( key.size() ) { @@ -174,7 +176,8 @@ int Meshgen2Gmsh::execute( const Args& args ) { Log::error() << "No grid specified." << std::endl; } - if ( !grid ) return failed(); + if ( !grid ) + return failed(); Log::debug() << "Domain: " << grid.domain() << std::endl; Log::debug() << "Periodic: " << grid.periodic() << std::endl; @@ -183,7 +186,8 @@ int Meshgen2Gmsh::execute( const Args& args ) { std::string Implementationype = ( RegularGrid( grid ) ? "regular" : "structured" ); args.get( "generator", Implementationype ); eckit::LocalConfiguration meshgenerator_config( args ); - if ( mpi::comm().size() > 1 || edges ) meshgenerator_config.set( "3d", false ); + if ( mpi::comm().size() > 1 || edges ) + meshgenerator_config.set( "3d", false ); MeshGenerator meshgenerator( Implementationype, meshgenerator_config ); @@ -197,7 +201,9 @@ int Meshgen2Gmsh::execute( const Args& args ) { throw e; } - if ( grid.projection().units() == "degrees" ) { functionspace::NodeColumns nodes_fs( mesh, option::halo( halo ) ); } + if ( grid.projection().units() == "degrees" ) { + functionspace::NodeColumns nodes_fs( mesh, option::halo( halo ) ); + } else { Log::warning() << "Not yet implemented: building halo's with projections " "not defined in degrees" @@ -212,7 +218,9 @@ int Meshgen2Gmsh::execute( const Args& args ) { build_median_dual_mesh( mesh ); } - if ( stats ) { build_statistics( mesh ); } + if ( stats ) { + build_statistics( mesh ); + } bool torus = false; args.get( "torus", torus ); diff --git a/src/atlas/array/ArraySpec.cc b/src/atlas/array/ArraySpec.cc index b78529ac3..b39d5aa04 100644 --- a/src/atlas/array/ArraySpec.cc +++ b/src/atlas/array/ArraySpec.cc @@ -22,7 +22,8 @@ idx_t compute_allocated_size( idx_t size, idx_t alignment ) { idx_t div = size / alignment; idx_t mod = size % alignment; idx_t _allocated_size = div * alignment; - if ( mod > 0 ) _allocated_size += alignment; + if ( mod > 0 ) + _allocated_size += alignment; return _allocated_size; } } // namespace @@ -32,7 +33,8 @@ ArraySpec::ArraySpec() : size_(), rank_(), allocated_size_(), contiguous_( true ArraySpec::ArraySpec( const ArrayShape& shape ) : ArraySpec( shape, ArrayAlignment() ) {} ArraySpec::ArraySpec( const ArrayShape& shape, ArrayAlignment&& alignment ) { - if ( int( alignment ) > 1 ) ATLAS_NOTIMPLEMENTED; // innermost dimension needs to be padded + if ( int( alignment ) > 1 ) + ATLAS_NOTIMPLEMENTED; // innermost dimension needs to be padded rank_ = static_cast( shape.size() ); size_ = 1; @@ -98,7 +100,9 @@ ArraySpec::ArraySpec( const ArrayShape& shape, const ArrayStrides& strides, cons strides_[j] = strides[j]; layout_[j] = layout[j]; size_ *= shape_[j]; - if ( layout_[j] != idx_t( j ) ) { default_layout_ = false; } + if ( layout_[j] != idx_t( j ) ) { + default_layout_ = false; + } } allocated_size_ = compute_allocated_size( shape_[layout_[0]] * strides_[layout_[0]], alignment ); contiguous_ = ( size_ == allocated_size_ ); diff --git a/src/atlas/array/LocalView.h b/src/atlas/array/LocalView.h index 1d8c37cc5..abe29e459 100644 --- a/src/atlas/array/LocalView.h +++ b/src/atlas/array/LocalView.h @@ -209,7 +209,9 @@ class LocalView { template void check_bounds_part( Int idx, Ints... next_idx ) const { - if ( idx_t( idx ) >= shape_[Dim] ) { throw_OutOfRange( "LocalView", array_dim(), idx, shape_[Dim] ); } + if ( idx_t( idx ) >= shape_[Dim] ) { + throw_OutOfRange( "LocalView", array_dim(), idx, shape_[Dim] ); + } check_bounds_part( next_idx... ); } diff --git a/src/atlas/array/SVector.h b/src/atlas/array/SVector.h index 89041bf2e..78635def1 100644 --- a/src/atlas/array/SVector.h +++ b/src/atlas/array/SVector.h @@ -59,7 +59,8 @@ class SVector { ATLAS_HOST_DEVICE ~SVector() { #ifndef __CUDA_ARCH__ - if ( !externally_allocated_ ) util::delete_managedmem( data_ ); + if ( !externally_allocated_ ) + util::delete_managedmem( data_ ); #endif } @@ -114,7 +115,8 @@ class SVector { idx_t size() const { return size_; } void resize_impl( idx_t N ) { - if ( N == size_ ) return; + if ( N == size_ ) + return; T* d_ = nullptr; util::allocate_managedmem( d_, N ); diff --git a/src/atlas/array/Table.cc b/src/atlas/array/Table.cc index abf59e35f..9f9f3ac79 100644 --- a/src/atlas/array/Table.cc +++ b/src/atlas/array/Table.cc @@ -172,7 +172,8 @@ void Table::add( size_t rows, size_t cols, const idx_t values[], bool fortran_ar ATLAS_ASSERT( owns_, "HybridConnectivity must be owned to be resized directly" ); size_t old_size = size(); - if ( rows_ == 0 ) old_size = 0; + if ( rows_ == 0 ) + old_size = 0; size_t new_size = old_size + rows * cols; size_t new_rows = rows_ + rows; @@ -217,7 +218,8 @@ void Table::add( size_t rows, size_t cols ) { ATLAS_ASSERT( owns_, "HybridConnectivity must be owned to be resized directly" ); size_t old_size = size(); - if ( rows_ == 0 ) old_size = 0; + if ( rows_ == 0 ) + old_size = 0; size_t new_size = old_size + rows * cols; size_t new_rows = rows_ + rows; @@ -281,7 +283,9 @@ void Table::insert( size_t position, size_t rows, const size_t cols[] ) { size_t position_displs = displs_( position ); if ( rows_ == 0 ) { - if ( position > 1 ) { insert_counts_and_displs( position - 1, rows ); } + if ( position > 1 ) { + insert_counts_and_displs( position - 1, rows ); + } } else { insert_counts_and_displs( position, rows ); diff --git a/src/atlas/array/Vector.h b/src/atlas/array/Vector.h index ceddb2cda..a412a9816 100644 --- a/src/atlas/array/Vector.h +++ b/src/atlas/array/Vector.h @@ -33,13 +33,15 @@ class Vector { void resize_impl( idx_t N ) { ATLAS_ASSERT( not data_gpu_, "we can not resize a vector after has been cloned to device" ); ATLAS_ASSERT( N >= size_ ); - if ( N == size_ ) return; + if ( N == size_ ) + return; T* d_ = new T[N]; for ( idx_t c = 0; c < size_; ++c ) { d_[c] = data_[c]; } - if ( data_ ) delete[] data_; + if ( data_ ) + delete[] data_; data_ = d_; } diff --git a/src/atlas/array/gridtools/GridToolsArray.cc b/src/atlas/array/gridtools/GridToolsArray.cc index a31ab6e2e..12884958b 100644 --- a/src/atlas/array/gridtools/GridToolsArray.cc +++ b/src/atlas/array/gridtools/GridToolsArray.cc @@ -167,7 +167,8 @@ class ArrayT_impl { throw_Exception( err.str(), Here() ); } - if ( array_.valid() ) array_.syncHostDevice(); + if ( array_.valid() ) + array_.syncHostDevice(); Array* resized = Array::create( ArrayShape{(idx_t)c...} ); @@ -346,10 +347,13 @@ void ArrayT::insert( idx_t idx1, idx_t size1 ) { // if( hostNeedsUpdate() ) { // cloneFromDevice(); //} - if ( not hasDefaultLayout() ) ATLAS_NOTIMPLEMENTED; + if ( not hasDefaultLayout() ) + ATLAS_NOTIMPLEMENTED; ArrayShape nshape = shape(); - if ( idx1 > nshape[0] ) { throw_Exception( "can not insert into an array at a position beyond its size", Here() ); } + if ( idx1 > nshape[0] ) { + throw_Exception( "can not insert into an array at a position beyond its size", Here() ); + } nshape[0] += size1; Array* resized = Array::create( nshape ); @@ -495,7 +499,8 @@ ArrayT::ArrayT( const ArrayShape& shape, const ArrayLayout& layout ) { template ArrayT::ArrayT( const ArraySpec& spec ) { - if ( not spec.contiguous() ) ATLAS_NOTIMPLEMENTED; + if ( not spec.contiguous() ) + ATLAS_NOTIMPLEMENTED; ArrayT_impl( *this ).construct( spec.shape(), spec.layout() ); } diff --git a/src/atlas/array/gridtools/GridToolsArrayHelpers.h b/src/atlas/array/gridtools/GridToolsArrayHelpers.h index 0b3909f63..2fdf7e90e 100644 --- a/src/atlas/array/gridtools/GridToolsArrayHelpers.h +++ b/src/atlas/array/gridtools/GridToolsArrayHelpers.h @@ -165,7 +165,9 @@ typename gt_storage_t::type::value>::t typedef gridtools::storage_traits::data_store_t data_store_t; data_store_t* ds; - if ( ::gridtools::accumulate( ::gridtools::multiplies(), dims... ) == 0 ) { ds = new data_store_t(); } + if ( ::gridtools::accumulate( ::gridtools::multiplies(), dims... ) == 0 ) { + ds = new data_store_t(); + } else { storage_info_ty si( dims... ); ds = new data_store_t( si ); diff --git a/src/atlas/array/helpers/ArrayInitializer.h b/src/atlas/array/helpers/ArrayInitializer.h index f99596471..150551bcb 100644 --- a/src/atlas/array/helpers/ArrayInitializer.h +++ b/src/atlas/array/helpers/ArrayInitializer.h @@ -101,7 +101,9 @@ struct array_initializer_partitioned_val_impl { DimIndexPair... idxs ) { for ( idx_t i = 0; i < orig.shape( Dim ); ++i ) { idx_t displ = i; - if ( Dim == PartDim && i >= pos ) { displ += offset; } + if ( Dim == PartDim && i >= pos ) { + displ += offset; + } std::pair pair_idx{i, displ}; array_initializer_partitioned_val_impl::apply( std::move( orig ), std::move( dest ), pos, offset, idxs..., pair_idx ); diff --git a/src/atlas/array/helpers/ArrayWriter.h b/src/atlas/array/helpers/ArrayWriter.h index 97d4aa173..6f44745fb 100644 --- a/src/atlas/array/helpers/ArrayWriter.h +++ b/src/atlas/array/helpers/ArrayWriter.h @@ -33,7 +33,8 @@ struct array_writer_impl { static void apply( View& arr, std::ostream& out, DimIndex... idxs ) { for ( idx_t i = 0; i < arr.shape( Dim ); ++i ) { array_writer_impl::apply( arr, out, idxs..., i ); - if ( i < arr.shape( Dim ) - 1 ) out << " "; + if ( i < arr.shape( Dim ) - 1 ) + out << " "; } } }; diff --git a/src/atlas/array/native/NativeArray.cc b/src/atlas/array/native/NativeArray.cc index 242f0d67f..6223dbcf1 100644 --- a/src/atlas/array/native/NativeArray.cc +++ b/src/atlas/array/native/NativeArray.cc @@ -134,7 +134,8 @@ ArrayT::ArrayT( const ArrayShape& shape, const ArrayLayout& layout ) { template ArrayT::ArrayT( const ArraySpec& spec ) { - if ( not spec.contiguous() ) ATLAS_NOTIMPLEMENTED; + if ( not spec.contiguous() ) + ATLAS_NOTIMPLEMENTED; spec_ = spec; data_store_ = std::unique_ptr( new native::DataStore( spec_.size() ) ); } @@ -188,7 +189,9 @@ void ArrayT::resize( const ArrayShape& _shape ) { template void ArrayT::insert( idx_t idx1, idx_t size1 ) { ArrayShape nshape = shape(); - if ( idx1 > nshape[0] ) { throw_Exception( "Cannot insert into an array at a position beyond its size", Here() ); } + if ( idx1 > nshape[0] ) { + throw_Exception( "Cannot insert into an array at a position beyond its size", Here() ); + } nshape[0] += size1; Array* resized = Array::create( nshape ); @@ -264,7 +267,8 @@ template size_t ArrayT::footprint() const { size_t size = sizeof( *this ); size += bytes(); - if ( not contiguous() ) ATLAS_NOTIMPLEMENTED; + if ( not contiguous() ) + ATLAS_NOTIMPLEMENTED; return size; } diff --git a/src/atlas/array/native/NativeArrayView.h b/src/atlas/array/native/NativeArrayView.h index 5b0b7acdd..014ad1345 100644 --- a/src/atlas/array/native/NativeArrayView.h +++ b/src/atlas/array/native/NativeArrayView.h @@ -229,7 +229,9 @@ class ArrayView { template void check_bounds_part( Int idx, Ints... next_idx ) const { - if ( idx_t( idx ) >= shape_[Dim] ) { throw_OutOfRange( "ArrayView", array_dim(), idx, shape_[Dim] ); } + if ( idx_t( idx ) >= shape_[Dim] ) { + throw_OutOfRange( "ArrayView", array_dim(), idx, shape_[Dim] ); + } check_bounds_part( next_idx... ); } diff --git a/src/atlas/array/native/NativeIndexView.h b/src/atlas/array/native/NativeIndexView.h index 7036dbee5..2b1a68110 100644 --- a/src/atlas/array/native/NativeIndexView.h +++ b/src/atlas/array/native/NativeIndexView.h @@ -172,7 +172,9 @@ class IndexView { template void check_bounds_part( Int idx, Ints... next_idx ) const { - if ( idx_t( idx ) >= shape_[Dim] ) { throw_OutOfRange( "IndexView", array_dim(), idx, shape_[Dim] ); } + if ( idx_t( idx ) >= shape_[Dim] ) { + throw_OutOfRange( "IndexView", array_dim(), idx, shape_[Dim] ); + } check_bounds_part( next_idx... ); } diff --git a/src/atlas/domain/detail/Domain.cc b/src/atlas/domain/detail/Domain.cc index 0caa806e4..74f712aae 100644 --- a/src/atlas/domain/detail/Domain.cc +++ b/src/atlas/domain/detail/Domain.cc @@ -25,7 +25,9 @@ const Domain* Domain::create() { const Domain* Domain::create( const eckit::Parametrisation& p ) { std::string domain_type; - if ( p.get( "type", domain_type ) ) { return DomainFactory::build( domain_type, p ); } + if ( p.get( "type", domain_type ) ) { + return DomainFactory::build( domain_type, p ); + } // should return error here throw_Exception( "type missing in Params", Here() ); diff --git a/src/atlas/domain/detail/GlobalDomain.cc b/src/atlas/domain/detail/GlobalDomain.cc index b7eeffc01..e6739bae0 100644 --- a/src/atlas/domain/detail/GlobalDomain.cc +++ b/src/atlas/domain/detail/GlobalDomain.cc @@ -40,7 +40,9 @@ GlobalDomain::GlobalDomain( const eckit::Parametrisation& params ) : GlobalDomai GlobalDomain::Spec GlobalDomain::spec() const { Spec domain_spec; domain_spec.set( "type", type() ); - if ( xmin() != 0. ) { domain_spec.set( "west", xmin() ); } + if ( xmin() != 0. ) { + domain_spec.set( "west", xmin() ); + } return domain_spec; } diff --git a/src/atlas/domain/detail/RectangularDomain.cc b/src/atlas/domain/detail/RectangularDomain.cc index baf6653c3..d0adceb82 100644 --- a/src/atlas/domain/detail/RectangularDomain.cc +++ b/src/atlas/domain/detail/RectangularDomain.cc @@ -27,9 +27,11 @@ namespace { static std::array get_interval_x( const eckit::Parametrisation& params ) { double xmin, xmax; - if ( !params.get( "xmin", xmin ) ) throw_Exception( "xmin missing in Params", Here() ); + if ( !params.get( "xmin", xmin ) ) + throw_Exception( "xmin missing in Params", Here() ); - if ( !params.get( "xmax", xmax ) ) throw_Exception( "xmax missing in Params", Here() ); + if ( !params.get( "xmax", xmax ) ) + throw_Exception( "xmax missing in Params", Here() ); return {xmin, xmax}; } @@ -37,30 +39,35 @@ static std::array get_interval_x( const eckit::Parametrisation& param static std::array get_interval_y( const eckit::Parametrisation& params ) { double ymin, ymax; - if ( !params.get( "ymin", ymin ) ) throw_Exception( "ymin missing in Params", Here() ); + if ( !params.get( "ymin", ymin ) ) + throw_Exception( "ymin missing in Params", Here() ); - if ( !params.get( "ymax", ymax ) ) throw_Exception( "ymax missing in Params", Here() ); + if ( !params.get( "ymax", ymax ) ) + throw_Exception( "ymax missing in Params", Here() ); return {ymin, ymax}; } static std::string get_units( const eckit::Parametrisation& params ) { std::string units; - if ( !params.get( "units", units ) ) throw_Exception( "units missing in Params", Here() ); + if ( !params.get( "units", units ) ) + throw_Exception( "units missing in Params", Here() ); return units; } } // namespace bool RectangularDomain::is_global( const Interval& x, const Interval& y, const std::string& units ) { - if ( units != "degrees" ) return false; + if ( units != "degrees" ) + return false; const double eps = 1.e-12; return std::abs( ( x[1] - x[0] ) - 360. ) < eps && std::abs( std::abs( y[1] - y[0] ) - 180. ) < eps; } bool RectangularDomain::is_zonal_band( const Interval& x, const std::string& units ) { - if ( units != "degrees" ) return false; + if ( units != "degrees" ) + return false; const double eps = 1.e-12; return std::abs( ( x[1] - x[0] ) - 360. ) < eps; @@ -78,8 +85,10 @@ RectangularDomain::RectangularDomain( const Interval& x, const Interval& y, cons unit_degrees_ = ( units_ == "degrees" ) ? true : false; // Make sure xmax>=xmin and ymax>=ymin - if ( xmin_ > xmax_ ) std::swap( xmin_, xmax_ ); - if ( ymin_ > ymax_ ) std::swap( ymin_, ymax_ ); + if ( xmin_ > xmax_ ) + std::swap( xmin_, xmax_ ); + if ( ymin_ > ymax_ ) + std::swap( ymin_, ymax_ ); global_ = is_global( {xmin_, xmax_}, {ymin_, ymax_}, units_ ); const double tol = 1.e-6; diff --git a/src/atlas/domain/detail/ZonalBandDomain.cc b/src/atlas/domain/detail/ZonalBandDomain.cc index 6612bd785..a0364d26b 100644 --- a/src/atlas/domain/detail/ZonalBandDomain.cc +++ b/src/atlas/domain/detail/ZonalBandDomain.cc @@ -27,9 +27,11 @@ static bool _is_global( double ymin, double ymax ) { static std::array get_interval_y( const eckit::Parametrisation& params ) { double ymin, ymax; - if ( !params.get( "ymin", ymin ) ) throw_Exception( "ymin missing in Params", Here() ); + if ( !params.get( "ymin", ymin ) ) + throw_Exception( "ymin missing in Params", Here() ); - if ( !params.get( "ymax", ymax ) ) throw_Exception( "ymax missing in Params", Here() ); + if ( !params.get( "ymax", ymax ) ) + throw_Exception( "ymax missing in Params", Here() ); return {ymin, ymax}; } @@ -75,7 +77,9 @@ ZonalBandDomain::Spec ZonalBandDomain::spec() const { domain_spec.set( "type", type() ); domain_spec.set( "ymin", ymin() ); domain_spec.set( "ymax", ymax() ); - if ( xmin() != 0. ) { domain_spec.set( "west", xmin() ); } + if ( xmin() != 0. ) { + domain_spec.set( "west", xmin() ); + } return domain_spec; } diff --git a/src/atlas/field/FieldCreatorArraySpec.cc b/src/atlas/field/FieldCreatorArraySpec.cc index 1c7dca179..af642c682 100644 --- a/src/atlas/field/FieldCreatorArraySpec.cc +++ b/src/atlas/field/FieldCreatorArraySpec.cc @@ -24,7 +24,8 @@ namespace field { FieldImpl* FieldCreatorArraySpec::createField( const eckit::Parametrisation& params ) const { std::vector shape; - if ( !params.get( "shape", shape ) ) throw_Exception( "Could not find parameter 'shape' in Parametrisation" ); + if ( !params.get( "shape", shape ) ) + throw_Exception( "Could not find parameter 'shape' in Parametrisation" ); std::vector s( shape.size() ); @@ -37,7 +38,9 @@ FieldImpl* FieldCreatorArraySpec::createField( const eckit::Parametrisation& par array::DataType datatype = array::DataType::create(); std::string datatype_str; - if ( params.get( "datatype", datatype_str ) ) { datatype = array::DataType( datatype_str ); } + if ( params.get( "datatype", datatype_str ) ) { + datatype = array::DataType( datatype_str ); + } else { array::DataType::kind_t kind( array::DataType::kind() ); params.get( "kind", kind ); diff --git a/src/atlas/field/FieldCreatorIFS.cc b/src/atlas/field/FieldCreatorIFS.cc index 652c1a69c..5871c3577 100644 --- a/src/atlas/field/FieldCreatorIFS.cc +++ b/src/atlas/field/FieldCreatorIFS.cc @@ -32,14 +32,17 @@ FieldImpl* FieldCreatorIFS::createField( const eckit::Parametrisation& params ) size_t nproma = 1; size_t nlev = 1; - if ( !params.get( "ngptot", ngptot ) ) throw_Exception( "Could not find parameter 'ngptot' in Parametrisation" ); + if ( !params.get( "ngptot", ngptot ) ) + throw_Exception( "Could not find parameter 'ngptot' in Parametrisation" ); params.get( "nproma", nproma ); params.get( "nlev", nlev ); params.get( "nvar", nvar ); array::DataType datatype = array::DataType::create(); std::string datatype_str; - if ( params.get( "datatype", datatype_str ) ) { datatype = array::DataType( datatype_str ); } + if ( params.get( "datatype", datatype_str ) ) { + datatype = array::DataType( datatype_str ); + } else { array::DataType::kind_t kind( array::DataType::kind() ); params.get( "kind", kind ); diff --git a/src/atlas/field/FieldSet.cc b/src/atlas/field/FieldSet.cc index 83da1add6..8777ff331 100644 --- a/src/atlas/field/FieldSet.cc +++ b/src/atlas/field/FieldSet.cc @@ -28,7 +28,9 @@ void FieldSetImpl::clear() { } Field FieldSetImpl::add( const Field& field ) { - if ( field.name().size() ) { index_[field.name()] = size(); } + if ( field.name().size() ) { + index_[field.name()] = size(); + } else { std::stringstream name; name << name_ << "[" << size() << "]"; diff --git a/src/atlas/field/FieldSet.h b/src/atlas/field/FieldSet.h index f73f1686f..f1474e88c 100644 --- a/src/atlas/field/FieldSet.h +++ b/src/atlas/field/FieldSet.h @@ -58,11 +58,13 @@ class FieldSetImpl : public util::Object { Field& operator[]( const std::string& name ) { return field( name ); } const Field& field( const idx_t& i ) const { - if ( i >= size() ) throw_OutOfRange( "fieldset", i, size(), Here() ); + if ( i >= size() ) + throw_OutOfRange( "fieldset", i, size(), Here() ); return fields_[i]; } Field& field( const idx_t& i ) { - if ( i >= size() ) throw_OutOfRange( "fieldset", i, size(), Here() ); + if ( i >= size() ) + throw_OutOfRange( "fieldset", i, size(), Here() ); return fields_[i]; } diff --git a/src/atlas/field/State.cc b/src/atlas/field/State.cc index 80de91240..e26754708 100644 --- a/src/atlas/field/State.cc +++ b/src/atlas/field/State.cc @@ -123,7 +123,8 @@ Field& State::field( const idx_t idx ) { std::vector State::field_names() const { std::vector ret; - if ( fields_.size() ) ret.reserve( fields_.size() ); + if ( fields_.size() ) + ret.reserve( fields_.size() ); for ( FieldMap::const_iterator it = fields_.begin(); it != fields_.end(); ++it ) { ret.push_back( it->first ); diff --git a/src/atlas/field/detail/FieldImpl.cc b/src/atlas/field/detail/FieldImpl.cc index a9e5eb3ba..820215be6 100644 --- a/src/atlas/field/detail/FieldImpl.cc +++ b/src/atlas/field/detail/FieldImpl.cc @@ -64,7 +64,8 @@ FieldImpl::FieldImpl( const std::string& name, array::Array* array ) : functions FieldImpl::~FieldImpl() { array_->detach(); - if ( array_->owners() == 0 ) delete array_; + if ( array_->owners() == 0 ) + delete array_; delete functionspace_; } @@ -96,7 +97,8 @@ std::string vector_to_str( const std::vector& t ) { std::stringstream s; s << '['; for ( size_t i = 0; i < t.size(); i++ ) { - if ( i != 0 ) s << ','; + if ( i != 0 ) + s << ','; s << t[i]; } s << ']'; diff --git a/src/atlas/functionspace/EdgeColumns.cc b/src/atlas/functionspace/EdgeColumns.cc index 41bc5462c..38d7314e5 100644 --- a/src/atlas/functionspace/EdgeColumns.cc +++ b/src/atlas/functionspace/EdgeColumns.cc @@ -50,7 +50,9 @@ template array::LocalView make_leveled_view( const Field& field ) { using namespace array; if ( field.levels() ) { - if ( field.variables() ) { return make_view( field ).slice( Range::all(), Range::all(), Range::all() ); } + if ( field.variables() ) { + return make_view( field ).slice( Range::all(), Range::all(), Range::all() ); + } else { return make_view( field ).slice( Range::all(), Range::all(), Range::dummy() ); } @@ -207,7 +209,8 @@ idx_t EdgeColumns::config_size( const eckit::Configuration& config ) const { array::DataType EdgeColumns::config_datatype( const eckit::Configuration& config ) const { array::DataType::kind_t kind; - if ( !config.get( "datatype", kind ) ) throw_Exception( "datatype missing", Here() ); + if ( !config.get( "datatype", kind ) ) + throw_Exception( "datatype missing", Here() ); return array::DataType( kind ); } @@ -230,11 +233,13 @@ array::ArrayShape EdgeColumns::config_shape( const eckit::Configuration& config idx_t levels( nb_levels_ ); config.get( "levels", levels ); - if ( levels > 0 ) shape.push_back( levels ); + if ( levels > 0 ) + shape.push_back( levels ); idx_t variables( 0 ); config.get( "variables", variables ); - if ( variables > 0 ) shape.push_back( variables ); + if ( variables > 0 ) + shape.push_back( variables ); return shape; } @@ -245,7 +250,9 @@ EdgeColumns::EdgeColumns( const Mesh& mesh, const eckit::Configuration& config ) nb_levels_( config.getInt( "levels", 0 ) ), nb_edges_( 0 ) { ATLAS_TRACE(); - if ( config.has( "halo" ) ) { halo_ = mesh::Halo( config.getInt( "halo" ) ); } + if ( config.has( "halo" ) ) { + halo_ = mesh::Halo( config.getInt( "halo" ) ); + } else { halo_ = mesh::Halo( mesh_ ); } @@ -290,7 +297,8 @@ idx_t EdgeColumns::nb_edges() const { } idx_t EdgeColumns::nb_edges_global() const { - if ( nb_edges_global_ >= 0 ) return nb_edges_global_; + if ( nb_edges_global_ >= 0 ) + return nb_edges_global_; nb_edges_global_ = gather().glb_dof(); return nb_edges_global_; } @@ -332,7 +340,8 @@ void EdgeColumns::haloExchange( const Field& field, bool on_device ) const { haloExchange( fieldset, on_device ); } const parallel::HaloExchange& EdgeColumns::halo_exchange() const { - if ( halo_exchange_ ) return *halo_exchange_; + if ( halo_exchange_ ) + return *halo_exchange_; halo_exchange_ = EdgeColumnsHaloExchangeCache::instance().get_or_create( mesh_ ); return *halo_exchange_; } @@ -379,12 +388,14 @@ void EdgeColumns::gather( const Field& local, Field& global ) const { gather( local_fields, global_fields ); } const parallel::GatherScatter& EdgeColumns::gather() const { - if ( gather_scatter_ ) return *gather_scatter_; + if ( gather_scatter_ ) + return *gather_scatter_; gather_scatter_ = EdgeColumnsGatherScatterCache::instance().get_or_create( mesh_ ); return *gather_scatter_; } const parallel::GatherScatter& EdgeColumns::scatter() const { - if ( gather_scatter_ ) return *gather_scatter_; + if ( gather_scatter_ ) + return *gather_scatter_; gather_scatter_ = EdgeColumnsGatherScatterCache::instance().get_or_create( mesh_ ); return *gather_scatter_; } @@ -497,7 +508,8 @@ std::string EdgeColumns::checksum( const Field& field ) const { } const parallel::Checksum& EdgeColumns::checksum() const { - if ( checksum_ ) return *checksum_; + if ( checksum_ ) + return *checksum_; checksum_ = EdgeColumnsChecksumCache::instance().get_or_create( mesh_ ); return *checksum_; } diff --git a/src/atlas/functionspace/NodeColumns.cc b/src/atlas/functionspace/NodeColumns.cc index 8cec105ae..1a26cedd8 100644 --- a/src/atlas/functionspace/NodeColumns.cc +++ b/src/atlas/functionspace/NodeColumns.cc @@ -49,7 +49,9 @@ template array::LocalView make_leveled_view( const Field& field ) { using namespace array; if ( field.levels() ) { - if ( field.variables() ) { return make_view( field ).slice( Range::all(), Range::all(), Range::all() ); } + if ( field.variables() ) { + return make_view( field ).slice( Range::all(), Range::all(), Range::all() ); + } else { return make_view( field ).slice( Range::all(), Range::all(), Range::dummy() ); } @@ -204,7 +206,9 @@ NodeColumns::NodeColumns( Mesh mesh, const eckit::Configuration& config ) : nb_levels_( config.getInt( "levels", 0 ) ), nb_nodes_( 0 ) { ATLAS_TRACE(); - if ( config.has( "halo" ) ) { halo_ = mesh::Halo( config.getInt( "halo" ) ); } + if ( config.has( "halo" ) ) { + halo_ = mesh::Halo( config.getInt( "halo" ) ); + } else { halo_ = mesh::Halo( mesh ); } @@ -221,7 +225,9 @@ NodeColumns::NodeColumns( Mesh mesh, const eckit::Configuration& config ) : if ( !nb_nodes_ ) { std::stringstream ss; ss << "nb_nodes_including_halo[" << halo_.size() << "]"; - if ( !mesh_.metadata().get( ss.str(), nb_nodes_ ) ) { nb_nodes_ = mesh_.nodes().size(); } + if ( !mesh_.metadata().get( ss.str(), nb_nodes_ ) ) { + nb_nodes_ = mesh_.nodes().size(); + } } } @@ -236,8 +242,11 @@ idx_t NodeColumns::nb_nodes() const { } idx_t NodeColumns::nb_nodes_global() const { - if ( nb_nodes_global_ >= 0 ) return nb_nodes_global_; - if ( Grid grid = mesh().grid() ) { nb_nodes_global_ = grid.size(); } + if ( nb_nodes_global_ >= 0 ) + return nb_nodes_global_; + if ( Grid grid = mesh().grid() ) { + nb_nodes_global_ = grid.size(); + } else { nb_nodes_global_ = gather().glb_dof(); } @@ -282,7 +291,8 @@ void NodeColumns::set_field_metadata( const eckit::Configuration& config, Field& array::DataType NodeColumns::config_datatype( const eckit::Configuration& config ) const { array::DataType::kind_t kind; - if ( !config.get( "datatype", kind ) ) throw_Exception( "datatype missing", Here() ); + if ( !config.get( "datatype", kind ) ) + throw_Exception( "datatype missing", Here() ); return array::DataType( kind ); } @@ -305,11 +315,13 @@ array::ArrayShape NodeColumns::config_shape( const eckit::Configuration& config idx_t levels( nb_levels_ ); config.get( "levels", levels ); - if ( levels > 0 ) shape.push_back( levels ); + if ( levels > 0 ) + shape.push_back( levels ); idx_t variables( 0 ); config.get( "variables", variables ); - if ( variables > 0 ) shape.push_back( variables ); + if ( variables > 0 ) + shape.push_back( variables ); return shape; } @@ -382,7 +394,8 @@ void NodeColumns::haloExchange( const Field& field, bool on_device ) const { haloExchange( fieldset, on_device ); } const parallel::HaloExchange& NodeColumns::halo_exchange() const { - if ( halo_exchange_ ) return *halo_exchange_; + if ( halo_exchange_ ) + return *halo_exchange_; halo_exchange_ = NodeColumnsHaloExchangeCache::instance().get_or_create( mesh_, halo_.size() ); return *halo_exchange_; } @@ -430,12 +443,14 @@ void NodeColumns::gather( const Field& local, Field& global ) const { gather( local_fields, global_fields ); } const parallel::GatherScatter& NodeColumns::gather() const { - if ( gather_scatter_ ) return *gather_scatter_; + if ( gather_scatter_ ) + return *gather_scatter_; gather_scatter_ = NodeColumnsGatherScatterCache::instance().get_or_create( mesh_ ); return *gather_scatter_; } const parallel::GatherScatter& NodeColumns::scatter() const { - if ( gather_scatter_ ) return *gather_scatter_; + if ( gather_scatter_ ) + return *gather_scatter_; gather_scatter_ = NodeColumnsGatherScatterCache::instance().get_or_create( mesh_ ); return *gather_scatter_; } @@ -528,7 +543,8 @@ std::string NodeColumns::checksum( const Field& field ) const { } const parallel::Checksum& NodeColumns::checksum() const { - if ( checksum_ ) return *checksum_; + if ( checksum_ ) + return *checksum_; checksum_ = NodeColumnsChecksumCache::instance().get_or_create( mesh_ ); return *checksum_; } diff --git a/src/atlas/functionspace/Spectral.cc b/src/atlas/functionspace/Spectral.cc index fc83d8b81..d0c16827c 100644 --- a/src/atlas/functionspace/Spectral.cc +++ b/src/atlas/functionspace/Spectral.cc @@ -64,17 +64,20 @@ class Spectral::Parallelisation { int nump() const { return trans_->nump; } array::LocalView nvalue() const { - if ( trans_->nvalue == nullptr ) ::trans_inquire( trans_.get(), "nvalue" ); + if ( trans_->nvalue == nullptr ) + ::trans_inquire( trans_.get(), "nvalue" ); return array::LocalView( trans_->nvalue, array::make_shape( trans_->nspec2 ) ); } array::LocalView nmyms() const { - if ( trans_->nmyms == nullptr ) ::trans_inquire( trans_.get(), "nmyms" ); + if ( trans_->nmyms == nullptr ) + ::trans_inquire( trans_.get(), "nmyms" ); return array::LocalView( trans_->nmyms, array::make_shape( nump() ) ); } array::LocalView nasm0() const { - if ( trans_->nasm0 == nullptr ) ::trans_inquire( trans_.get(), "nasm0" ); + if ( trans_->nasm0 == nullptr ) + ::trans_inquire( trans_.get(), "nasm0" ); return array::LocalView( trans_->nasm0, array::make_shape( trans_->nsmax + 1 ) ); } @@ -177,7 +180,9 @@ Spectral::Spectral( const trans::Trans& trans, const eckit::Configuration& confi parallelisation_( [&trans, this]() -> Parallelisation* { #if ATLAS_HAVE_TRANS const auto* trans_ifs = dynamic_cast( trans.get() ); - if ( trans_ifs ) { return new Parallelisation( trans_ifs->trans_ ); } + if ( trans_ifs ) { + return new Parallelisation( trans_ifs->trans_ ); + } #endif return new Parallelisation( truncation_ ); }() ) { @@ -206,7 +211,8 @@ idx_t Spectral::nb_spectral_coefficients_global() const { array::DataType Spectral::config_datatype( const eckit::Configuration& config ) const { array::DataType::kind_t kind; - if ( !config.get( "datatype", kind ) ) throw_Exception( "datatype missing", Here() ); + if ( !config.get( "datatype", kind ) ) + throw_Exception( "datatype missing", Here() ); return array::DataType( kind ); } @@ -229,7 +235,8 @@ Field Spectral::createField( const eckit::Configuration& options ) const { array_shape.push_back( nb_spec_coeffs ); idx_t levels = config_levels( options ); - if ( levels ) array_shape.push_back( levels ); + if ( levels ) + array_shape.push_back( levels ); Field field = Field( config_name( options ), config_datatype( options ), array_shape ); @@ -259,7 +266,8 @@ void Spectral::gather( const FieldSet& local_fieldset, FieldSet& global_fieldset idx_t rank = static_cast( mpi::comm().rank() ); glb.metadata().get( "owner", root ); ATLAS_ASSERT( loc.shape( 0 ) == nb_spectral_coefficients() ); - if ( rank == root ) ATLAS_ASSERT( glb.shape( 0 ) == nb_spectral_coefficients_global() ); + if ( rank == root ) + ATLAS_ASSERT( glb.shape( 0 ) == nb_spectral_coefficients_global() ); std::vector nto( 1, root + 1 ); if ( loc.rank() > 1 ) { nto.resize( loc.stride( 0 ) ); @@ -313,7 +321,8 @@ void Spectral::scatter( const FieldSet& global_fieldset, FieldSet& local_fieldse glb.metadata().get( "owner", root ); ATLAS_ASSERT( loc.shape( 0 ) == nb_spectral_coefficients() ); - if ( rank == root ) ATLAS_ASSERT( glb.shape( 0 ) == nb_spectral_coefficients_global() ); + if ( rank == root ) + ATLAS_ASSERT( glb.shape( 0 ) == nb_spectral_coefficients_global() ); std::vector nfrom( 1, root + 1 ); if ( loc.rank() > 1 ) { nfrom.resize( loc.stride( 0 ) ); diff --git a/src/atlas/functionspace/StructuredColumns.cc b/src/atlas/functionspace/StructuredColumns.cc index 6f8d58392..3550ecc8d 100644 --- a/src/atlas/functionspace/StructuredColumns.cc +++ b/src/atlas/functionspace/StructuredColumns.cc @@ -47,7 +47,9 @@ template array::LocalView make_leveled_view( const Field& field ) { using namespace array; if ( field.levels() ) { - if ( field.variables() ) { return make_view( field ).slice( Range::all(), Range::all(), Range::all() ); } + if ( field.variables() ) { + return make_view( field ).slice( Range::all(), Range::all(), Range::all() ); + } else { return make_view( field ).slice( Range::all(), Range::all(), Range::dummy() ); } @@ -192,25 +194,30 @@ class StructuredColumnsChecksumCache : public util::Cache 0 ) shape.push_back( levels ); + if ( levels > 0 ) + shape.push_back( levels ); idx_t variables( 0 ); config.get( "variables", variables ); - if ( variables > 0 ) shape.push_back( variables ); + if ( variables > 0 ) + shape.push_back( variables ); return shape; } @@ -365,7 +377,9 @@ StructuredColumns::StructuredColumns( const Grid& grid, const Vertical& vertical grid_( new StructuredGrid( grid ) ) { grid::Partitioner partitioner( p ); if ( not partitioner ) { - if ( grid_->domain().global() ) { partitioner = grid::Partitioner( "equal_regions" ); } + if ( grid_->domain().global() ) { + partitioner = grid::Partitioner( "equal_regions" ); + } else { partitioner = grid::Partitioner( "checkerboard" ); } @@ -561,7 +575,9 @@ struct FixupHaloForVectors { template void apply( Field& field ) { std::string type = field.metadata().getString( "type", "scalar" ); - if ( type == "vector " ) { ATLAS_NOTIMPLEMENTED; } + if ( type == "vector " ) { + ATLAS_NOTIMPLEMENTED; + } } }; @@ -684,12 +700,18 @@ void StructuredColumns::haloExchange( const Field& field, bool ) const { size_t StructuredColumns::footprint() const { size_t size = sizeof( *this ); size += ij2gp_.footprint(); - if ( field_xy_ ) size += field_xy_.footprint(); - if ( field_partition_ ) size += field_partition_.footprint(); - if ( field_global_index_ ) size += field_global_index_.footprint(); - if ( field_remote_index_ ) size += field_remote_index_.footprint(); - if ( field_index_i_ ) size += field_index_i_.footprint(); - if ( field_index_j_ ) size += field_index_j_.footprint(); + if ( field_xy_ ) + size += field_xy_.footprint(); + if ( field_partition_ ) + size += field_partition_.footprint(); + if ( field_global_index_ ) + size += field_global_index_.footprint(); + if ( field_remote_index_ ) + size += field_remote_index_.footprint(); + if ( field_index_i_ ) + size += field_index_i_.footprint(); + if ( field_index_j_ ) + size += field_index_j_.footprint(); return size; } diff --git a/src/atlas/functionspace/StructuredColumns.h b/src/atlas/functionspace/StructuredColumns.h index c61de4a7d..cd9d1e70d 100644 --- a/src/atlas/functionspace/StructuredColumns.h +++ b/src/atlas/functionspace/StructuredColumns.h @@ -137,7 +137,9 @@ class StructuredColumns : public FunctionSpaceImpl { Field partition() const { return field_partition_; } Field global_index() const { return field_global_index_; } Field remote_index() const { - if ( not field_remote_index_ ) { create_remote_index(); } + if ( not field_remote_index_ ) { + create_remote_index(); + } return field_remote_index_; } Field index_i() const { return field_index_i_; } @@ -164,8 +166,12 @@ class StructuredColumns : public FunctionSpaceImpl { void check_bounds( idx_t i, idx_t j ) const { #if ATLAS_ARRAYVIEW_BOUNDS_CHECKING - if ( j < j_begin_halo() || j >= j_end_halo() ) { throw_outofbounds( i, j ); } - if ( i < i_begin_halo( j ) || i >= i_end_halo( j ) ) { throw_outofbounds( i, j ); } + if ( j < j_begin_halo() || j >= j_end_halo() ) { + throw_outofbounds( i, j ); + } + if ( i < i_begin_halo( j ) || i >= i_end_halo( j ) ) { + throw_outofbounds( i, j ); + } #endif } [[noreturn]] void throw_outofbounds( idx_t i, idx_t j ) const; diff --git a/src/atlas/functionspace/detail/NodeColumns_FieldStatistics.cc b/src/atlas/functionspace/detail/NodeColumns_FieldStatistics.cc index b0daae9ed..b653694a9 100644 --- a/src/atlas/functionspace/detail/NodeColumns_FieldStatistics.cc +++ b/src/atlas/functionspace/detail/NodeColumns_FieldStatistics.cc @@ -39,7 +39,9 @@ template array::LocalView make_leveled_view( const Field& field ) { using namespace array; if ( field.levels() ) { - if ( field.variables() ) { return make_view( field ).slice( Range::all(), Range::all(), Range::all() ); } + if ( field.variables() ) { + return make_view( field ).slice( Range::all(), Range::all(), Range::all() ); + } else { return make_view( field ).slice( Range::all(), Range::all(), Range::dummy() ); } @@ -112,7 +114,9 @@ void dispatch_sum( const NodeColumns& fs, const Field& field, T& result, idx_t& template void sum( const NodeColumns& fs, const Field& field, T& result, idx_t& N ) { - if ( field.datatype() == array::DataType::kind() ) { return dispatch_sum( fs, field, result, N ); } + if ( field.datatype() == array::DataType::kind() ) { + return dispatch_sum( fs, field, result, N ); + } else { switch ( field.datatype().kind() ) { case array::DataType::KIND_INT32: { @@ -180,7 +184,9 @@ void dispatch_sum( const NodeColumns& fs, const Field& field, std::vector& re template void sum( const NodeColumns& fs, const Field& field, std::vector& result, idx_t& N ) { - if ( field.datatype() == array::DataType::kind() ) { return dispatch_sum( fs, field, result, N ); } + if ( field.datatype() == array::DataType::kind() ) { + return dispatch_sum( fs, field, result, N ); + } else { switch ( field.datatype().kind() ) { case array::DataType::KIND_INT32: { @@ -271,7 +277,9 @@ void dispatch_sum_per_level( const NodeColumns& fs, const Field& field, Field& s } void sum_per_level( const NodeColumns& fs, const Field& field, Field& sum, idx_t& N ) { - if ( field.datatype() != sum.datatype() ) { throw_Exception( "Field and sum are not of same datatype.", Here() ); } + if ( field.datatype() != sum.datatype() ) { + throw_Exception( "Field and sum are not of same datatype.", Here() ); + } switch ( field.datatype().kind() ) { case array::DataType::KIND_INT32: return dispatch_sum_per_level( fs, field, sum, N ); @@ -508,7 +516,9 @@ void dispatch_order_independent_sum_per_level( const NodeColumns& fs, const Fiel } void order_independent_sum_per_level( const NodeColumns& fs, const Field& field, Field& sum, idx_t& N ) { - if ( field.datatype() != sum.datatype() ) { throw_Exception( "Field and sum are not of same datatype.", Here() ); } + if ( field.datatype() != sum.datatype() ) { + throw_Exception( "Field and sum are not of same datatype.", Here() ); + } switch ( field.datatype().kind() ) { case array::DataType::KIND_INT32: return dispatch_order_independent_sum_per_level( fs, field, sum, N ); @@ -551,7 +561,9 @@ void dispatch_minimum( const NodeColumns& fs, const Field& field, std::vector template void minimum( const NodeColumns& fs, const Field& field, std::vector& min ) { - if ( field.datatype() == array::DataType::kind() ) { return dispatch_minimum( fs, field, min ); } + if ( field.datatype() == array::DataType::kind() ) { + return dispatch_minimum( fs, field, min ); + } else { switch ( field.datatype().kind() ) { case array::DataType::KIND_INT32: { @@ -611,7 +623,9 @@ void dispatch_maximum( const NodeColumns& fs, const Field& field, std::vector template void maximum( const NodeColumns& fs, const Field& field, std::vector& max ) { - if ( field.datatype() == array::DataType::kind() ) { return dispatch_maximum( fs, field, max ); } + if ( field.datatype() == array::DataType::kind() ) { + return dispatch_maximum( fs, field, max ); + } else { switch ( field.datatype().kind() ) { case array::DataType::KIND_INT32: { @@ -703,7 +717,9 @@ void dispatch_minimum_per_level( const NodeColumns& fs, const Field& field, Fiel } void minimum_per_level( const NodeColumns& fs, const Field& field, Field& min ) { - if ( field.datatype() != min.datatype() ) { throw_Exception( "Field and min are not of same datatype.", Here() ); } + if ( field.datatype() != min.datatype() ) { + throw_Exception( "Field and min are not of same datatype.", Here() ); + } switch ( field.datatype().kind() ) { case array::DataType::KIND_INT32: return dispatch_minimum_per_level( fs, field, min ); @@ -764,7 +780,9 @@ void dispatch_maximum_per_level( const NodeColumns& fs, const Field& field, Fiel } void maximum_per_level( const NodeColumns& fs, const Field& field, Field& max ) { - if ( field.datatype() != max.datatype() ) { throw_Exception( "Field and max are not of same datatype.", Here() ); } + if ( field.datatype() != max.datatype() ) { + throw_Exception( "Field and max are not of same datatype.", Here() ); + } switch ( field.datatype().kind() ) { case array::DataType::KIND_INT32: return dispatch_maximum_per_level( fs, field, max ); @@ -1112,7 +1130,9 @@ void dispatch_minimum_and_location_per_level( const NodeColumns& fs, const Field } void minimum_and_location_per_level( const NodeColumns& fs, const Field& field, Field& min, Field& glb_idx ) { - if ( field.datatype() != min.datatype() ) { throw_Exception( "Field and min are not of same datatype.", Here() ); } + if ( field.datatype() != min.datatype() ) { + throw_Exception( "Field and min are not of same datatype.", Here() ); + } if ( glb_idx.datatype() != array::DataType::kind() ) { throw_Exception( "glb_idx Field is not of correct datatype", Here() ); } @@ -1210,7 +1230,9 @@ void dispatch_maximum_and_location_per_level( const NodeColumns& fs, const Field } void maximum_and_location_per_level( const NodeColumns& fs, const Field& field, Field& max, Field& glb_idx ) { - if ( field.datatype() != max.datatype() ) { throw_Exception( "Field and max are not of same datatype.", Here() ); } + if ( field.datatype() != max.datatype() ) { + throw_Exception( "Field and max are not of same datatype.", Here() ); + } if ( glb_idx.datatype() != array::DataType::kind() ) { throw_Exception( "glb_idx Field is not of correct datatype", Here() ); } @@ -1254,7 +1276,9 @@ void dispatch_mean_per_level( const NodeColumns& fs, const Field& field, Field& } void mean_per_level( const NodeColumns& fs, const Field& field, Field& mean, idx_t& N ) { - if ( field.datatype() != mean.datatype() ) { throw_Exception( "Field and sum are not of same datatype.", Here() ); } + if ( field.datatype() != mean.datatype() ) { + throw_Exception( "Field and sum are not of same datatype.", Here() ); + } switch ( field.datatype().kind() ) { case array::DataType::KIND_INT32: return dispatch_mean_per_level( fs, field, mean, N ); diff --git a/src/atlas/functionspace/detail/StructuredColumns_setup.cc b/src/atlas/functionspace/detail/StructuredColumns_setup.cc index 449a879e8..1749d792f 100644 --- a/src/atlas/functionspace/detail/StructuredColumns_setup.cc +++ b/src/atlas/functionspace/detail/StructuredColumns_setup.cc @@ -81,7 +81,9 @@ struct GridPointSet { void StructuredColumns::setup( const grid::Distribution& distribution, const eckit::Configuration& config ) { ATLAS_TRACE( "Generating StructuredColumns..." ); bool periodic_points = config.getInt( "periodic_points", false ); - if ( not( *grid_ ) ) { throw_Exception( "Grid is not a grid::Structured type", Here() ); } + if ( not( *grid_ ) ) { + throw_Exception( "Grid is not a grid::Structured type", Here() ); + } const eckit::mpi::Comm& comm = mpi::comm(); @@ -134,12 +136,16 @@ void StructuredColumns::setup( const grid::Distribution& distribution, const eck std::function compute_j; compute_j = [this, &compute_j]( idx_t j ) -> idx_t { - if ( j < 0 ) { j = ( grid_->y( 0 ) == 90. ) ? -j : -j - 1; } + if ( j < 0 ) { + j = ( grid_->y( 0 ) == 90. ) ? -j : -j - 1; + } else if ( j >= grid_->ny() ) { idx_t jlast = grid_->ny() - 1; j = ( grid_->y( jlast ) == -90. ) ? jlast - 1 - ( j - grid_->ny() ) : jlast - ( j - grid_->ny() ); } - if ( j < 0 or j >= grid_->ny() ) { j = compute_j( j ); } + if ( j < 0 or j >= grid_->ny() ) { + j = compute_j( j ); + } return j; }; @@ -219,14 +225,18 @@ void StructuredColumns::setup( const grid::Distribution& distribution, const eck for ( idx_t j = j_begin_; j < j_end_; ++j ) { for ( idx_t i : {i_begin_[j], i_end_[j] - 1} ) { // Following line only, increases periodic halo on the east side by 1 - if ( periodic_points && i == grid_->nx( j ) - 1 ) { ++i; } + if ( periodic_points && i == grid_->nx( j ) - 1 ) { + ++i; + } double x = grid_->x( i, j ); double x_next = grid_->x( i + 1, j ); double x_prev = grid_->x( i - 1, j ); for ( idx_t jj = j - halo; jj <= j + halo; ++jj ) { idx_t last = grid_->nx( compute_j( jj ) ) - 1; - if ( i == grid_->nx( j ) ) { ++last; } + if ( i == grid_->nx( j ) ) { + ++last; + } jmin = std::min( jmin, jj ); jmax = std::max( jmax, jj ); @@ -350,7 +360,9 @@ void StructuredColumns::setup( const grid::Distribution& distribution, const eck for ( const GridPoint& gp : gridpoints ) { xy( gp.r, XX ) = compute_x( gp.i, gp.j ); - if ( gp.j >= 0 && gp.j < grid_->ny() ) { xy( gp.r, YY ) = grid_->y( gp.j ); } + if ( gp.j >= 0 && gp.j < grid_->ny() ) { + xy( gp.r, YY ) = grid_->y( gp.j ); + } else { xy( gp.r, YY ) = compute_y( gp.j ); } diff --git a/src/atlas/grid/Grid.cc b/src/atlas/grid/Grid.cc index ab7eeb803..bfe4b33ac 100644 --- a/src/atlas/grid/Grid.cc +++ b/src/atlas/grid/Grid.cc @@ -39,7 +39,8 @@ Grid::IterateLonLat Grid::lonlat() const { Grid::Grid( const std::string& shortname, const Domain& domain ) : Handle( [&] { Config config; - if ( domain ) config.set( "domain", domain.spec() ); + if ( domain ) + config.set( "domain", domain.spec() ); return Grid::Implementation::create( shortname, config ); }() ) {} diff --git a/src/atlas/grid/Partitioner.cc b/src/atlas/grid/Partitioner.cc index f5b67cc6c..16db5488d 100644 --- a/src/atlas/grid/Partitioner.cc +++ b/src/atlas/grid/Partitioner.cc @@ -38,7 +38,8 @@ namespace { detail::partitioner::Partitioner* partitioner_from_config( const Partitioner::Config& config ) { std::string type; long partitions = mpi::comm().size(); - if ( not config.get( "type", type ) ) throw_Exception( "'type' missing in configuration for Partitioner", Here() ); + if ( not config.get( "type", type ) ) + throw_Exception( "'type' missing in configuration for Partitioner", Here() ); config.get( "partitions", partitions ); return Factory::build( type, partitions ); } diff --git a/src/atlas/grid/StencilComputer.cc b/src/atlas/grid/StencilComputer.cc index c1ac3c90b..c33a66e24 100644 --- a/src/atlas/grid/StencilComputer.cc +++ b/src/atlas/grid/StencilComputer.cc @@ -21,7 +21,9 @@ ComputeLower::ComputeLower( const Vertical& z ) { constexpr double tol = 1.e-12; ATLAS_ASSERT( dz > 0 ); for ( idx_t jlev = 0; jlev < nlev_; ++jlev ) { - if ( jlev + 1 < nlev_ ) { dz = std::min( dz, z[jlev + 1] - z[jlev] ); } + if ( jlev + 1 < nlev_ ) { + dz = std::min( dz, z[jlev + 1] - z[jlev] ); + } z_[jlev] = z[jlev] - tol; } @@ -32,14 +34,18 @@ ComputeLower::ComputeLower( const Vertical& z ) { idx_t iref = 0; for ( idx_t jlevaux = 0; jlevaux <= nlevaux_; ++jlevaux ) { - if ( iref + 1 < nlev_ && jlevaux * dzaux >= z[iref + 1] ) { ++iref; } + if ( iref + 1 < nlev_ && jlevaux * dzaux >= z[iref + 1] ) { + ++iref; + } nvaux_[jlevaux] = iref; } } ComputeNorth::ComputeNorth( const StructuredGrid& grid, idx_t halo ) { ATLAS_ASSERT( grid ); - if ( not grid.domain().global() ) { throw_NotImplemented( "Only implemented for global grids", Here() ); } + if ( not grid.domain().global() ) { + throw_NotImplemented( "Only implemented for global grids", Here() ); + } halo_ = halo; ny_ = grid.ny(); y_.resize( ny_ + 2 * halo_ ); @@ -63,7 +69,9 @@ ComputeNorth::ComputeNorth( const StructuredGrid& grid, idx_t halo ) { ComputeWest::ComputeWest( const StructuredGrid& grid, idx_t halo ) { ATLAS_ASSERT( grid ); - if ( not grid.domain().global() ) { throw_NotImplemented( "Only implemented for global grids", Here() ); } + if ( not grid.domain().global() ) { + throw_NotImplemented( "Only implemented for global grids", Here() ); + } halo_ = halo; idx_t north_pole_included = 90. - std::abs( grid.y().front() ) < tol(); idx_t south_pole_included = 90. - std::abs( grid.y().back() ) < tol(); diff --git a/src/atlas/grid/StencilComputer.h b/src/atlas/grid/StencilComputer.h index 1fd7c9792..8d3d6168b 100644 --- a/src/atlas/grid/StencilComputer.h +++ b/src/atlas/grid/StencilComputer.h @@ -64,7 +64,9 @@ class ComputeLower { ATLAS_ASSERT( idx < static_cast( nvaux_.size() ) && idx >= 0 ); #endif idx = nvaux_[idx]; - if ( idx < nlev_ - 1 && z > z_[idx + 1] ) { ++idx; } + if ( idx < nlev_ - 1 && z > z_[idx + 1] ) { + ++idx; + } return idx; } }; diff --git a/src/atlas/grid/detail/distribution/DistributionImpl.cc b/src/atlas/grid/detail/distribution/DistributionImpl.cc index 60c30f6aa..0a569cd9a 100644 --- a/src/atlas/grid/detail/distribution/DistributionImpl.cc +++ b/src/atlas/grid/detail/distribution/DistributionImpl.cc @@ -22,8 +22,12 @@ namespace grid { namespace { std::string distribution_type( int N, const Partitioner& p = Partitioner() ) { - if ( N == 1 ) { return "serial"; } - if ( not p ) { return "custom"; } + if ( N == 1 ) { + return "serial"; + } + if ( not p ) { + return "custom"; + } return p.type(); } } // namespace @@ -68,7 +72,8 @@ void DistributionImpl::print( std::ostream& s ) const { s << "Distribution( " << "type: " << type_ << ", nbPoints: " << part_.size() << ", nbPartitions: " << nb_pts_.size() << ", parts : ["; for ( idx_t i = 0, size = static_cast( part_.size() ); i < size; i++ ) { - if ( i != 0 ) s << ','; + if ( i != 0 ) + s << ','; s << part_[i]; } s << ']'; diff --git a/src/atlas/grid/detail/grid/Gaussian.cc b/src/atlas/grid/detail/grid/Gaussian.cc index dbaf517d5..96902c577 100644 --- a/src/atlas/grid/detail/grid/Gaussian.cc +++ b/src/atlas/grid/detail/grid/Gaussian.cc @@ -28,13 +28,17 @@ static eckit::Translator to_int; static Projection projection( const Grid::Config& grid ) { Grid::Config config; - if ( grid.get( "projection", config ) ) { return Projection( config ); } + if ( grid.get( "projection", config ) ) { + return Projection( config ); + } return Projection(); } static Domain domain( const Grid::Config& grid ) { Grid::Config config; - if ( grid.get( "domain", config ) ) { return Domain( config ); } + if ( grid.get( "domain", config ) ) { + return Domain( config ); + } return Domain(); } diff --git a/src/atlas/grid/detail/grid/Grid.cc b/src/atlas/grid/detail/grid/Grid.cc index b16c29eaa..a29db3a49 100644 --- a/src/atlas/grid/detail/grid/Grid.cc +++ b/src/atlas/grid/detail/grid/Grid.cc @@ -37,7 +37,9 @@ static void checkSizeOfPoint() { const Grid* Grid::create( const Config& config ) { std::string name; - if ( config.get( "name", name ) ) { return create( name, config ); } + if ( config.get( "name", name ) ) { + return create( name, config ); + } std::string type; if ( config.get( "type", type ) ) { @@ -48,9 +50,15 @@ const Grid* Grid::create( const Config& config ) { } } - if ( name.size() ) { Log::info() << "name provided: " << name << std::endl; } - if ( type.size() ) { Log::info() << "type provided: " << type << std::endl; } - if ( name.empty() && type.empty() ) { throw_Exception( "no name or type in configuration", Here() ); } + if ( name.size() ) { + Log::info() << "name provided: " << name << std::endl; + } + if ( type.size() ) { + Log::info() << "type provided: " << type << std::endl; + } + if ( name.empty() && type.empty() ) { + throw_Exception( "no name or type in configuration", Here() ); + } else { throw_Exception( "name or type in configuration don't exist", Here() ); } @@ -64,7 +72,9 @@ const Grid* Grid::create( const std::string& name, const Grid::Config& config ) const GridBuilder::Registry& registry = GridBuilder::nameRegistry(); for ( GridBuilder::Registry::const_iterator it = registry.begin(); it != registry.end(); ++it ) { const Grid* grid = it->second->create( name, config ); - if ( grid ) { return grid; } + if ( grid ) { + return grid; + } } // Throw exception @@ -100,7 +110,9 @@ Grid::~Grid() { } Grid::uid_t Grid::uid() const { - if ( uid_.empty() ) { uid_ = hash(); } + if ( uid_.empty() ) { + uid_ = hash(); + } return uid_; } diff --git a/src/atlas/grid/detail/grid/GridBuilder.cc b/src/atlas/grid/detail/grid/GridBuilder.cc index 3cb02aeec..923403003 100644 --- a/src/atlas/grid/detail/grid/GridBuilder.cc +++ b/src/atlas/grid/detail/grid/GridBuilder.cc @@ -35,7 +35,8 @@ size_t regex_count_parens( const std::string& string ) { last_was_backslash = true; continue; } - if ( *step == ')' && !last_was_backslash ) out++; + if ( *step == ')' && !last_was_backslash ) + out++; last_was_backslash = false; } return out; @@ -45,12 +46,14 @@ int regex_match_impl( const std::string& string, const std::string& regex, std:: bool use_substr, bool use_case ) { regex_t re; size_t matchcount = 0; - if ( use_substr ) matchcount = regex_count_parens( regex ); + if ( use_substr ) + matchcount = regex_count_parens( regex ); regmatch_t result[matchcount + 1]; int compiled_ok = !regcomp( &re, regex.c_str(), REG_EXTENDED + ( use_case ? 0 : REG_ICASE ) + ( use_substr ? 0 : REG_NOSUB ) ); - if ( !compiled_ok ) Log::error() << "This regular expression didn't compile: \"" << regex << "\"" << std::endl; + if ( !compiled_ok ) + Log::error() << "This regular expression didn't compile: \"" << regex << "\"" << std::endl; ATLAS_ASSERT( compiled_ok ); @@ -185,11 +188,19 @@ const Grid::Implementation* GridBuilder::create( const Grid::Config& config ) co } std::string type; - if ( config.get( "type", type ) && GridFactory::has( type ) ) { return GridFactory::build( type, config ); } + if ( config.get( "type", type ) && GridFactory::has( type ) ) { + return GridFactory::build( type, config ); + } - if ( name.size() ) { Log::error() << "name provided: " << name << std::endl; } - if ( type.size() ) { Log::error() << "type provided: " << type << std::endl; } - if ( name.empty() && type.empty() ) { throw_Exception( "no name or type in configuration", Here() ); } + if ( name.size() ) { + Log::error() << "name provided: " << name << std::endl; + } + if ( type.size() ) { + Log::error() << "type provided: " << type << std::endl; + } + if ( name.empty() && type.empty() ) { + throw_Exception( "no name or type in configuration", Here() ); + } else { throw_Exception( "name or type in configuration don't exist", Here() ); } @@ -198,7 +209,8 @@ const Grid::Implementation* GridBuilder::create( const Grid::Config& config ) co bool GridBuilder::match( const std::string& string, std::vector& matches, int& id ) const { id = 0; for ( const std::string& name : names_ ) { - if ( Regex( name ).match( string, matches ) ) return true; + if ( Regex( name ).match( string, matches ) ) + return true; ++id; } return false; diff --git a/src/atlas/grid/detail/grid/LonLat.cc b/src/atlas/grid/detail/grid/LonLat.cc index 5b8faebad..31c7c5ace 100644 --- a/src/atlas/grid/detail/grid/LonLat.cc +++ b/src/atlas/grid/detail/grid/LonLat.cc @@ -27,7 +27,9 @@ static eckit::Translator to_int; static Domain domain( const Grid::Config& grid ) { Grid::Config config; - if ( grid.get( "domain", config ) ) { return Domain( config ); } + if ( grid.get( "domain", config ) ) { + return Domain( config ); + } return Domain(); } @@ -76,7 +78,9 @@ StructuredGrid::grid_t* create_lonlat( long nlon, long nlat, Shift shift, Projection projection; Grid::Config config_projection; - if ( config.get( "projection", config_projection ) ) { projection = Projection( config_projection ); } + if ( config.get( "projection", config_projection ) ) { + projection = Projection( config_projection ); + } std::string name; diff --git a/src/atlas/grid/detail/grid/Regional.cc b/src/atlas/grid/detail/grid/Regional.cc index 60cfa9f0c..0673463ac 100644 --- a/src/atlas/grid/detail/grid/Regional.cc +++ b/src/atlas/grid/detail/grid/Regional.cc @@ -25,7 +25,9 @@ namespace { // anonymous static Domain domain( const Grid::Config& grid ) { Grid::Config config; - if ( grid.get( "domain", config ) ) { return Domain( config ); } + if ( grid.get( "domain", config ) ) { + return Domain( config ); + } return Domain(); } @@ -64,7 +66,8 @@ struct Parse_llc_step : ConfigParser { valid = config.get( "nx", x.N ) && config.get( "ny", y.N ) && config.get( "dx", x.step ) && config.get( "dy", y.step ) && config.get( "lonlat(centre)", centre_lonlat ); - if ( not valid ) return; + if ( not valid ) + return; double centre[] = {centre_lonlat[0], centre_lonlat[1]}; p.lonlat2xy( centre ); @@ -84,7 +87,8 @@ struct Parse_bounds_xy : ConfigParser { valid = config.get( "nx", x.N ) && config.get( "ny", y.N ) && config.get( "xmin", x.min ) && config.get( "xmax", x.max ) && config.get( "ymin", y.min ) && config.get( "ymax", y.max ); - if ( not valid ) return; + if ( not valid ) + return; x.step = step( x.min, x.max, x.N ); y.step = step( y.min, y.max, y.N ); @@ -113,7 +117,8 @@ struct Parse_bounds_lonlat : ConfigParser { } } - if ( not valid ) return; + if ( not valid ) + return; x.step = step( x.min, x.max, x.N ); y.step = step( y.min, y.max, y.N ); @@ -128,7 +133,8 @@ struct Parse_ll00_ll11 : ConfigParser { config.get( "lonlat(xmin,ymin)", sw ) // includes rotation && config.get( "lonlat(xmax,ymax)", ne ); // includes rotation - if ( not valid ) return; + if ( not valid ) + return; p.lonlat2xy( sw.data() ); p.lonlat2xy( ne.data() ); @@ -148,7 +154,8 @@ struct Parse_xy01_step : ConfigParser { config.get( "dy", y.step ) && config.get( "xmin", x.min ) && config.get( "ymax", y.max ); // includes rotation - if ( not valid ) return; + if ( not valid ) + return; x.max = x.min + x.step * ( x.N - 1 ); y.min = y.max - y.step * ( y.N - 1 ); @@ -161,7 +168,8 @@ struct Parse_ll00_step : ConfigParser { valid = config.get( "nx", x.N ) && config.get( "ny", y.N ) && config.get( "dx", x.step ) && config.get( "dy", y.step ) && config.get( "lonlat(xmin,ymin)", sw ); // includes rotation - if ( not valid ) return; + if ( not valid ) + return; p.lonlat2xy( sw.data() ); x.min = sw[0]; @@ -177,7 +185,8 @@ struct Parse_xy00_step : ConfigParser { valid = config.get( "nx", x.N ) && config.get( "ny", y.N ) && config.get( "dx", x.step ) && config.get( "dy", y.step ) && config.get( "xmin", x.min ) && config.get( "ymin", y.min ); - if ( not valid ) return; + if ( not valid ) + return; x.max = x.min + x.step * ( x.N - 1 ); y.max = y.min + y.step * ( y.N - 1 ); @@ -191,7 +200,8 @@ struct Parse_ll01_step : ConfigParser { // This resembles GRIB input for "lambe valid = config.get( "nx", x.N ) && config.get( "ny", y.N ) && config.get( "dx", x.step ) && config.get( "dy", y.step ) && config.get( "lonlat(xmin,ymax)", nw ); // includes rotation - if ( not valid ) return; + if ( not valid ) + return; p.lonlat2xy( nw.data() ); x.min = nw[0]; @@ -216,26 +226,34 @@ bool ConfigParser::parse( const Projection& projection, const Grid::Config& conf bool ConfigParser::parse( const Projection& projection, const Grid::Config& config, Parsed& x, Parsed& y ) { // bounding box using 4 variables (any projection allowed) - if ( ConfigParser::parse( projection, config, x, y ) ) return true; + if ( ConfigParser::parse( projection, config, x, y ) ) + return true; // centre of domain and increments (any projection allowed) - if ( ConfigParser::parse( projection, config, x, y ) ) return true; + if ( ConfigParser::parse( projection, config, x, y ) ) + return true; // top-left of domain and increments (any projection allowed) - if ( ConfigParser::parse( projection, config, x, y ) ) return true; - if ( ConfigParser::parse( projection, config, x, y ) ) return true; + if ( ConfigParser::parse( projection, config, x, y ) ) + return true; + if ( ConfigParser::parse( projection, config, x, y ) ) + return true; // bottom-left of domain and increments (any projection allowed) - if ( ConfigParser::parse( projection, config, x, y ) ) return true; - if ( ConfigParser::parse( projection, config, x, y ) ) return true; + if ( ConfigParser::parse( projection, config, x, y ) ) + return true; + if ( ConfigParser::parse( projection, config, x, y ) ) + return true; // bounding box using two points defined in lonlat (any projection allowed) - if ( ConfigParser::parse( projection, config, x, y ) ) return true; + if ( ConfigParser::parse( projection, config, x, y ) ) + return true; //-------- From here on, projection must be (rotated) lonlat --------// // bounding box using 4 variables (south west north east) - if ( ConfigParser::parse( projection, config, x, y ) ) return true; + if ( ConfigParser::parse( projection, config, x, y ) ) + return true; return false; } @@ -259,7 +277,9 @@ static class regional : public GridBuilder { Projection projection; { util::Config config_proj; - if ( config.get( "projection", config_proj ) ) { projection = Projection( config_proj ); } + if ( config.get( "projection", config_proj ) ) { + projection = Projection( config_proj ); + } } // Read grid configuration @@ -299,7 +319,9 @@ static class zonal_band : public GridBuilder { Projection projection; { util::Config config_proj; - if ( config.get( "projection", config_proj ) ) { projection = Projection( config_proj ); } + if ( config.get( "projection", config_proj ) ) { + projection = Projection( config_proj ); + } } ATLAS_ASSERT( projection.units() == "degrees" ); @@ -307,10 +329,14 @@ static class zonal_band : public GridBuilder { // Read grid configuration ConfigParser::Parsed y; long nx; - if ( not config.get( "nx", nx ) ) throw_Exception( "Parameter 'nx' missing in configuration", Here() ); - if ( not config.get( "ny", y.N ) ) throw_Exception( "Parameter 'ny' missing in configuration", Here() ); - if ( not( config.get( "ymin", y.min ) or config.get( "south", y.min ) ) ) y.min = -90.; - if ( not( config.get( "ymax", y.max ) or config.get( "north", y.max ) ) ) y.max = 90.; + if ( not config.get( "nx", nx ) ) + throw_Exception( "Parameter 'nx' missing in configuration", Here() ); + if ( not config.get( "ny", y.N ) ) + throw_Exception( "Parameter 'ny' missing in configuration", Here() ); + if ( not( config.get( "ymin", y.min ) or config.get( "south", y.min ) ) ) + y.min = -90.; + if ( not( config.get( "ymax", y.max ) or config.get( "north", y.max ) ) ) + y.max = 90.; YSpace yspace = config.getInt( "y_numbering", -1 ) < 0 ? LinearSpacing( y.max, y.min, y.N, true ) : LinearSpacing( y.min, y.max, y.N, true ); diff --git a/src/atlas/grid/detail/grid/Structured.cc b/src/atlas/grid/detail/grid/Structured.cc index 1884741e4..41996fd31 100644 --- a/src/atlas/grid/detail/grid/Structured.cc +++ b/src/atlas/grid/detail/grid/Structured.cc @@ -86,7 +86,9 @@ Structured::Structured( const std::string& name, XSpace xspace, YSpace yspace, P } Domain Structured::computeDomain() const { - if ( periodic() ) { return ZonalBandDomain( {yspace().min(), yspace().max()}, xspace().min() ); } + if ( periodic() ) { + return ZonalBandDomain( {yspace().min(), yspace().max()}, xspace().min() ); + } return RectangularDomain( {xspace().min(), xspace().max()}, {yspace().min(), yspace().max()}, projection_.units() ); } @@ -137,10 +139,14 @@ Structured::XSpace::Implementation::Implementation( const Config& config ) { std::max( v_N.size(), std::max( v_start.size(), std::max( v_end.size(), std::max( v_length.size(), 1ul ) ) ) ); reserve( ny ); - if ( not v_N.empty() ) ATLAS_ASSERT( static_cast( v_N.size() ) == ny ); - if ( not v_start.empty() ) ATLAS_ASSERT( static_cast( v_start.size() ) == ny ); - if ( not v_end.empty() ) ATLAS_ASSERT( static_cast( v_end.size() ) == ny ); - if ( not v_length.empty() ) ATLAS_ASSERT( static_cast( v_length.size() ) == ny ); + if ( not v_N.empty() ) + ATLAS_ASSERT( static_cast( v_N.size() ) == ny ); + if ( not v_start.empty() ) + ATLAS_ASSERT( static_cast( v_start.size() ) == ny ); + if ( not v_end.empty() ) + ATLAS_ASSERT( static_cast( v_end.size() ) == ny ); + if ( not v_length.empty() ) + ATLAS_ASSERT( static_cast( v_length.size() ) == ny ); nxmin_ = std::numeric_limits::max(); nxmax_ = 0; @@ -148,10 +154,14 @@ Structured::XSpace::Implementation::Implementation( const Config& config ) { max_ = -std::numeric_limits::max(); for ( idx_t j = 0; j < ny; ++j ) { - if ( not v_N.empty() ) config_xspace.set( "N", v_N[j] ); - if ( not v_start.empty() ) config_xspace.set( "start", v_start[j] ); - if ( not v_end.empty() ) config_xspace.set( "end", v_end[j] ); - if ( not v_length.empty() ) config_xspace.set( "length", v_length[j] ); + if ( not v_N.empty() ) + config_xspace.set( "N", v_N[j] ); + if ( not v_start.empty() ) + config_xspace.set( "start", v_start[j] ); + if ( not v_end.empty() ) + config_xspace.set( "end", v_end[j] ); + if ( not v_length.empty() ) + config_xspace.set( "length", v_length[j] ); spacing::LinearSpacing::Params xspace( config_xspace ); xmin_.push_back( xspace.start ); xmax_.push_back( xspace.end ); @@ -295,15 +305,21 @@ Grid::Spec Structured::XSpace::Implementation::spec() const { bool endpoint = std::abs( ( xmax - xmin ) - ( nx - 1 ) * dx ) < 1.e-10; spec.set( "type", "linear" ); - if ( same_xmin ) { spec.set( "start", xmin ); } + if ( same_xmin ) { + spec.set( "start", xmin ); + } else { spec.set( "start[]", xmin_ ); } - if ( same_xmax ) { spec.set( "end", xmax ); } + if ( same_xmax ) { + spec.set( "end", xmax ); + } else { spec.set( "end[]", xmax_ ); } - if ( same_nx ) { spec.set( "N", nx ); } + if ( same_nx ) { + spec.set( "N", nx ); + } else { spec.set( "N[]", nx_ ); } @@ -320,7 +336,9 @@ class Normalise { normalise_( domain.xmin() ) {} double operator()( double x ) const { - if ( degrees_ ) { x = normalise_( x ); } + if ( degrees_ ) { + x = normalise_( x ); + } return x; } @@ -548,13 +566,17 @@ static class structured : public GridBuilder { Domain domain; Config config_proj; - if ( config.get( "projection", config_proj ) ) projection = Projection( config_proj ); + if ( config.get( "projection", config_proj ) ) + projection = Projection( config_proj ); Config config_domain; - if ( config.get( "domain", config_domain ) ) { domain = Domain( config_domain ); } + if ( config.get( "domain", config_domain ) ) { + domain = Domain( config_domain ); + } Config config_yspace; - if ( not config.get( "yspace", config_yspace ) ) throw_Exception( "yspace missing in configuration", Here() ); + if ( not config.get( "yspace", config_yspace ) ) + throw_Exception( "yspace missing in configuration", Here() ); yspace = Spacing( config_yspace ); XSpace xspace; @@ -562,7 +584,9 @@ static class structured : public GridBuilder { Config config_xspace; std::vector config_xspace_list; - if ( config.get( "xspace[]", config_xspace_list ) ) { xspace = XSpace( config_xspace_list ); } + if ( config.get( "xspace[]", config_xspace_list ) ) { + xspace = XSpace( config_xspace_list ); + } else if ( config.get( "xspace", config_xspace ) ) { xspace = XSpace( config_xspace ); } diff --git a/src/atlas/grid/detail/grid/Structured.h b/src/atlas/grid/detail/grid/Structured.h index 3ff4e0f9d..5fe2f2c10 100644 --- a/src/atlas/grid/detail/grid/Structured.h +++ b/src/atlas/grid/detail/grid/Structured.h @@ -111,7 +111,8 @@ class Structured : public Grid { i_ = 0; } ++n_; - if ( n_ == size_ ) return *this; + if ( n_ == size_ ) + return *this; } while ( not p_( n_ ) ); return *this; } diff --git a/src/atlas/grid/detail/grid/Unstructured.cc b/src/atlas/grid/detail/grid/Unstructured.cc index 8027ffaa8..83222dfec 100644 --- a/src/atlas/grid/detail/grid/Unstructured.cc +++ b/src/atlas/grid/detail/grid/Unstructured.cc @@ -64,7 +64,9 @@ class Normalise { normalise_( domain.xmin(), domain.xmax() ) {} double operator()( double x ) const { - if ( degrees_ ) { x = normalise_( x ); } + if ( degrees_ ) { + x = normalise_( x ); + } return x; } @@ -79,19 +81,25 @@ Unstructured::Unstructured( const Grid& grid, Domain domain ) : Grid() { domain_ = domain; points_.reset( new std::vector ); points_->reserve( grid.size() ); - if ( not domain_ ) { domain_ = GlobalDomain(); } + if ( not domain_ ) { + domain_ = GlobalDomain(); + } atlas::grid::IteratorXY it( grid.xy_begin() ); PointXY p; if ( RectangularDomain( domain_ ) ) { auto normalise = Normalise( RectangularDomain( domain_ ) ); while ( it.next( p ) ) { p.x() = normalise( p.x() ); - if ( domain_.contains( p ) ) { points_->emplace_back( p ); } + if ( domain_.contains( p ) ) { + points_->emplace_back( p ); + } } } else if ( ZonalBandDomain( domain_ ) ) { while ( it.next( p ) ) { - if ( domain_.contains( p ) ) { points_->emplace_back( p ); } + if ( domain_.contains( p ) ) { + points_->emplace_back( p ); + } } } else { @@ -104,7 +112,9 @@ Unstructured::Unstructured( const Grid& grid, Domain domain ) : Grid() { Unstructured::Unstructured( const util::Config& config ) : Grid() { util::Config config_domain; - if ( not config.get( "domain", config_domain ) ) { config_domain.set( "type", "global" ); } + if ( not config.get( "domain", config_domain ) ) { + config_domain.set( "type", "global" ); + } domain_ = Domain( config_domain ); std::vector xy; if ( config.get( "xy", xy ) ) { @@ -118,8 +128,12 @@ Unstructured::Unstructured( const util::Config& config ) : Grid() { else { std::vector x; std::vector y; - if ( not config.get( "x", x ) ) { throw_Exception( "x missing from configuration" ); } - if ( not config.get( "y", y ) ) { throw_Exception( "y missing from configuration" ); } + if ( not config.get( "x", x ) ) { + throw_Exception( "x missing from configuration" ); + } + if ( not config.get( "y", y ) ) { + throw_Exception( "y missing from configuration" ); + } ATLAS_ASSERT( x.size() == y.size() ); points_.reset( new std::vector ); points_->reserve( x.size() ); @@ -180,7 +194,8 @@ idx_t Unstructured::size() const { } Grid::Spec Unstructured::spec() const { - if ( cached_spec_ ) return *cached_spec_; + if ( cached_spec_ ) + return *cached_spec_; cached_spec_.reset( new Grid::Spec ); diff --git a/src/atlas/grid/detail/grid/Unstructured.h b/src/atlas/grid/detail/grid/Unstructured.h index 267906cfd..ad863f76c 100644 --- a/src/atlas/grid/detail/grid/Unstructured.h +++ b/src/atlas/grid/detail/grid/Unstructured.h @@ -79,7 +79,8 @@ class Unstructured : public Grid { p_( p ), size_( static_cast( grid_.points_->size() ) ), n_( begin ? 0 : size_ ) { - if ( begin ) {} + if ( begin ) { + } } virtual bool next( PointXY& xy ); @@ -89,7 +90,8 @@ class Unstructured : public Grid { virtual const Grid::IteratorXY& operator++() { do { ++n_; - if ( n_ == size_ ) return *this; + if ( n_ == size_ ) + return *this; } while ( not p_( n_ ) ); return *this; } diff --git a/src/atlas/grid/detail/partitioner/CheckerboardPartitioner.cc b/src/atlas/grid/detail/partitioner/CheckerboardPartitioner.cc index edfef30f7..539a7b9a8 100644 --- a/src/atlas/grid/detail/partitioner/CheckerboardPartitioner.cc +++ b/src/atlas/grid/detail/partitioner/CheckerboardPartitioner.cc @@ -54,7 +54,8 @@ CheckerboardPartitioner::CheckerboardPartitioner( int N, int nbands, bool checke CheckerboardPartitioner::Checkerboard CheckerboardPartitioner::checkerboard( const Grid& grid ) const { // grid dimensions const RegularGrid rg( grid ); - if ( !rg ) throw_Exception( "Checkerboard Partitioner only works for Regular grids.", Here() ); + if ( !rg ) + throw_Exception( "Checkerboard Partitioner only works for Regular grids.", Here() ); Checkerboard cb; @@ -62,13 +63,17 @@ CheckerboardPartitioner::Checkerboard CheckerboardPartitioner::checkerboard( con cb.ny = rg.ny(); idx_t nparts = nb_partitions(); - if ( nbands_ > 0 ) { cb.nbands = nbands_; } + if ( nbands_ > 0 ) { + cb.nbands = nbands_; + } else { // default number of bands double zz = std::sqrt( (double)( nparts * cb.ny ) / cb.nx ); // aim at +/-square regions cb.nbands = (idx_t)zz + 0.5; - if ( cb.nbands < 1 ) cb.nbands = 1; // at least one band - if ( cb.nbands > nparts ) cb.nbands = nparts; // not more bands than procs + if ( cb.nbands < 1 ) + cb.nbands = 1; // at least one band + if ( cb.nbands > nparts ) + cb.nbands = nparts; // not more bands than procs // true checkerboard means nbands must divide nparts if ( checkerboard_ ) { @@ -85,16 +90,20 @@ CheckerboardPartitioner::Checkerboard CheckerboardPartitioner::checkerboard( con bool compare_Y_X( const CheckerboardPartitioner::NodeInt& node1, const CheckerboardPartitioner::NodeInt& node2 ) { // comparison of two locations; X1 < X2 if it's to the south, then to the // east. - if ( node1.y < node2.y ) return true; - if ( node1.y == node2.y ) return ( node1.x < node2.x ); + if ( node1.y < node2.y ) + return true; + if ( node1.y == node2.y ) + return ( node1.x < node2.x ); return false; } bool compare_X_Y( const CheckerboardPartitioner::NodeInt& node1, const CheckerboardPartitioner::NodeInt& node2 ) { // comparison of two locations; X1 < X2 if it's to the east, then to the // south. - if ( node1.x < node2.x ) return true; - if ( node1.x == node2.x ) return ( node1.y < node2.y ); + if ( node1.x < node2.x ) + return true; + if ( node1.x == node2.x ) + return ( node1.y < node2.y ); return false; } diff --git a/src/atlas/grid/detail/partitioner/EqualRegionsPartitioner.cc b/src/atlas/grid/detail/partitioner/EqualRegionsPartitioner.cc index 3e4d69910..cb3ab01e2 100644 --- a/src/atlas/grid/detail/partitioner/EqualRegionsPartitioner.cc +++ b/src/atlas/grid/detail/partitioner/EqualRegionsPartitioner.cc @@ -123,9 +123,12 @@ double polar_colat( int N ) { // Given N, determine the colatitude of the North polar spherical cap. // double polar_c( 0 ); - if ( N == 1 ) polar_c = M_PI; - if ( N == 2 ) polar_c = 0.5 * M_PI; - if ( N > 2 ) polar_c = sradius_of_cap( area_of_ideal_region( N ) ); + if ( N == 1 ) + polar_c = M_PI; + if ( N == 2 ) + polar_c = 0.5 * M_PI; + if ( N > 2 ) + polar_c = sradius_of_cap( area_of_ideal_region( N ) ); return polar_c; } @@ -446,14 +449,18 @@ void EqualRegionsPartitioner::where( int partition, int& band, int& sector ) con } bool compare_NS_WE( const EqualRegionsPartitioner::NodeInt& node1, const EqualRegionsPartitioner::NodeInt& node2 ) { - if ( node1.y > node2.y ) return true; - if ( node1.y == node2.y ) return ( node1.x < node2.x ); + if ( node1.y > node2.y ) + return true; + if ( node1.y == node2.y ) + return ( node1.x < node2.x ); return false; } bool compare_WE_NS( const EqualRegionsPartitioner::NodeInt& node1, const EqualRegionsPartitioner::NodeInt& node2 ) { - if ( node1.x < node2.x ) return true; - if ( node1.x == node2.x ) return ( node1.y > node2.y ); + if ( node1.x < node2.x ) + return true; + if ( node1.x == node2.x ) + return ( node1.y > node2.y ); return false; } @@ -579,7 +586,8 @@ void EqualRegionsPartitioner::partition( const Grid& grid, int part[] ) const { for ( int w = 0; w < nb_workers; ++w ) { int w_begin = w * grid.size() / N_; int w_end = ( w + 1 ) * grid.size() / N_; - if ( w == nb_workers - 1 ) w_end = grid.size(); + if ( w == nb_workers - 1 ) + w_end = grid.size(); size_t w_size = w_end - w_begin; int work_rank = std::min( w, mpi_size - 1 ); @@ -636,7 +644,8 @@ void EqualRegionsPartitioner::partition( const Grid& grid, int part[] ) const { for ( int w = 0; w < nb_workers; ++w ) { int w_begin = w * grid.size() / N_; int w_end = ( w + 1 ) * grid.size() / N_; - if ( w == nb_workers - 1 ) w_end = grid.size(); + if ( w == nb_workers - 1 ) + w_end = grid.size(); if ( w != 0 ) { std::inplace_merge( nodes.begin(), nodes.begin() + w_begin, nodes.begin() + w_end, compare_NS_WE ); diff --git a/src/atlas/grid/detail/partitioner/TransPartitioner.cc b/src/atlas/grid/detail/partitioner/TransPartitioner.cc index 8d1f1c695..40bbc65c4 100644 --- a/src/atlas/grid/detail/partitioner/TransPartitioner.cc +++ b/src/atlas/grid/detail/partitioner/TransPartitioner.cc @@ -48,7 +48,8 @@ void TransPartitioner::partition( const Grid& grid, int part[] ) const { ATLAS_TRACE( "TransPartitioner::partition" ); StructuredGrid g( grid ); - if ( not g ) throw_Exception( "Grid is not a grid::Structured type. Cannot partition using IFS trans", Here() ); + if ( not g ) + throw_Exception( "Grid is not a grid::Structured type. Cannot partition using IFS trans", Here() ); trans::TransIFS t( grid ); if ( nb_partitions() != idx_t( t.nproc() ) ) { @@ -90,7 +91,8 @@ void TransPartitioner::partition( const Grid& grid, int part[] ) const { int igl = nptrfrstlat( ja ) + jgl - nfrstlat( ja ); for ( int jl = nsta( jb, igl ) - 1; jl < nsta( jb, igl ) + nonl( jb, igl ) - 1; ++jl ) { idx_t ind = iglobal[jgl * nlonmax + jl] - 1; - if ( ind >= grid.size() ) throw_OutOfRange( "part", ind, grid.size(), Here() ); + if ( ind >= grid.size() ) + throw_OutOfRange( "part", ind, grid.size(), Here() ); part[ind] = iproc; } } diff --git a/src/atlas/grid/detail/spacing/CustomSpacing.cc b/src/atlas/grid/detail/spacing/CustomSpacing.cc index f668a4c80..070fe164b 100644 --- a/src/atlas/grid/detail/spacing/CustomSpacing.cc +++ b/src/atlas/grid/detail/spacing/CustomSpacing.cc @@ -31,7 +31,9 @@ CustomSpacing::CustomSpacing( const eckit::Parametrisation& params ) { params.get( "values", x_ ); size_t N; - if ( params.get( "N", N ) ) { ATLAS_ASSERT( x_.size() == N ); } + if ( params.get( "N", N ) ) { + ATLAS_ASSERT( x_.size() == N ); + } N = x_.size(); std::vector interval; diff --git a/src/atlas/grid/detail/spacing/FocusSpacing.cc b/src/atlas/grid/detail/spacing/FocusSpacing.cc index d2179f477..f661dc8e3 100644 --- a/src/atlas/grid/detail/spacing/FocusSpacing.cc +++ b/src/atlas/grid/detail/spacing/FocusSpacing.cc @@ -26,15 +26,21 @@ FocusSpacing::FocusSpacing( const eckit::Parametrisation& params ) { long N; // retrieve xmin, xmax and N from params - if ( !params.get( "start", xmin ) ) throw_Exception( "start missing in Params", Here() ); - if ( !params.get( "end", xmax ) ) throw_Exception( "end missing in Params", Here() ); - if ( !params.get( "N", N ) ) throw_Exception( "N missing in Params", Here() ); + if ( !params.get( "start", xmin ) ) + throw_Exception( "start missing in Params", Here() ); + if ( !params.get( "end", xmax ) ) + throw_Exception( "end missing in Params", Here() ); + if ( !params.get( "N", N ) ) + throw_Exception( "N missing in Params", Here() ); // additional parameters for focus spacing - if ( !params.get( "focus_factor", focus_factor_ ) ) throw_Exception( "focus_factor missing in Params", Here() ); + if ( !params.get( "focus_factor", focus_factor_ ) ) + throw_Exception( "focus_factor missing in Params", Here() ); x_.resize( N ); - if ( N == 1 ) { x_[0] = 0.5 * ( xmin + xmax ); } + if ( N == 1 ) { + x_[0] = 0.5 * ( xmin + xmax ); + } else { const double midpoint = 0.5 * ( xmin + xmax ); const double d2 = 2. / double( N - 1 ); diff --git a/src/atlas/grid/detail/spacing/GaussianSpacing.cc b/src/atlas/grid/detail/spacing/GaussianSpacing.cc index a081d845a..13112ff06 100644 --- a/src/atlas/grid/detail/spacing/GaussianSpacing.cc +++ b/src/atlas/grid/detail/spacing/GaussianSpacing.cc @@ -34,7 +34,8 @@ GaussianSpacing::GaussianSpacing( long N ) { GaussianSpacing::GaussianSpacing( const eckit::Parametrisation& params ) { // retrieve N from params long N; - if ( !params.get( "N", N ) ) throw_Exception( "N missing in Params", Here() ); + if ( !params.get( "N", N ) ) + throw_Exception( "N missing in Params", Here() ); // perform checks ATLAS_ASSERT( N % 2 == 0 ); @@ -55,7 +56,9 @@ GaussianSpacing::GaussianSpacing( const eckit::Parametrisation& params ) { start = interval[0]; end = interval[1]; } - if ( start != 90. && end != -90. ) { ATLAS_NOTIMPLEMENTED; } + if ( start != 90. && end != -90. ) { + ATLAS_NOTIMPLEMENTED; + } min_ = std::min( start, end ); max_ = std::max( start, end ); diff --git a/src/atlas/grid/detail/spacing/Spacing.cc b/src/atlas/grid/detail/spacing/Spacing.cc index 5ae41fc6f..72b1a1ae6 100644 --- a/src/atlas/grid/detail/spacing/Spacing.cc +++ b/src/atlas/grid/detail/spacing/Spacing.cc @@ -20,7 +20,9 @@ namespace spacing { const Spacing* Spacing::create( const eckit::Parametrisation& params ) { std::string spacingType; - if ( not params.get( "type", spacingType ) ) { throw_Exception( "type missing in configuration", Here() ); } + if ( not params.get( "type", spacingType ) ) { + throw_Exception( "type missing in configuration", Here() ); + } return SpacingFactory::build( spacingType, params ); } diff --git a/src/atlas/grid/detail/spacing/gaussian/Latitudes.cc b/src/atlas/grid/detail/spacing/gaussian/Latitudes.cc index 145d60e21..02b5ecdde 100644 --- a/src/atlas/grid/detail/spacing/gaussian/Latitudes.cc +++ b/src/atlas/grid/detail/spacing/gaussian/Latitudes.cc @@ -113,7 +113,8 @@ void legpol_newton_iteration( int kn, const double pfn[], double px, double& pxn zdlx = px; zdlk = 0.; - if ( kodd == 0 ) zdlk = 0.5 * pfn[0]; + if ( kodd == 0 ) + zdlk = 0.5 * pfn[0]; zdlxn = 0.; zdlldn = 0.; ik = 1; @@ -214,7 +215,8 @@ void legpol_quadrature( const int kn, const double pfn[], double& pl, double& pw legpol_weight( kn, pfn, zx, zw ); break; } - if ( std::abs( pmod ) <= zeps * 1000. ) iflag = 1; + if ( std::abs( pmod ) <= zeps * 1000. ) + iflag = 1; } if ( iflag != 1 ) { std::stringstream s; diff --git a/src/atlas/interpolation/element/Quad3D.cc b/src/atlas/interpolation/element/Quad3D.cc index e946cb41e..621db2d99 100644 --- a/src/atlas/interpolation/element/Quad3D.cc +++ b/src/atlas/interpolation/element/Quad3D.cc @@ -27,7 +27,8 @@ method::Intersect Quad3D::intersects( const method::Ray& r, double edgeEpsilon, Triag3D T013( v00, v10, v01 ); isect = T013.intersects( r, edgeEpsilon, epsilon ); - if ( isect ) return isect; + if ( isect ) + return isect; Triag3D T231( v11, v01, v10 ); isect = T231.intersects( r, edgeEpsilon, epsilon ); diff --git a/src/atlas/interpolation/element/Quad3D.h b/src/atlas/interpolation/element/Quad3D.h index abd304914..6a5a1cb06 100644 --- a/src/atlas/interpolation/element/Quad3D.h +++ b/src/atlas/interpolation/element/Quad3D.h @@ -53,10 +53,14 @@ class Quad3D { } const Vector3D& p( int i ) { - if ( i == 0 ) return v00; - if ( i == 1 ) return v10; - if ( i == 2 ) return v11; - if ( i == 3 ) return v01; + if ( i == 0 ) + return v00; + if ( i == 1 ) + return v10; + if ( i == 2 ) + return v11; + if ( i == 3 ) + return v01; throw_OutOfRange( "Quad3D::p(i)", i, 4, Here() ); } diff --git a/src/atlas/interpolation/element/Triag3D.cc b/src/atlas/interpolation/element/Triag3D.cc index 2b90b01cf..ba12abaf8 100644 --- a/src/atlas/interpolation/element/Triag3D.cc +++ b/src/atlas/interpolation/element/Triag3D.cc @@ -30,7 +30,9 @@ method::Intersect Triag3D::intersects( const method::Ray& r, double edgeEpsilon, // ray is parallel to triangle (check?) const double det = edge1.dot( pvec ); - if ( fabs( det ) < epsilon ) { return isect.fail(); } + if ( fabs( det ) < epsilon ) { + return isect.fail(); + } const double invDet = 1. / det; @@ -45,7 +47,9 @@ method::Intersect Triag3D::intersects( const method::Ray& r, double edgeEpsilon, if ( w < 0 ) { // check if far outside of triangle, in respect to diagonal edge - if ( w < -edgeEpsilon ) { return isect.fail(); } + if ( w < -edgeEpsilon ) { + return isect.fail(); + } // snap to diagonal edge // Note: we may still be to the left of vertical edge or below the @@ -62,7 +66,9 @@ method::Intersect Triag3D::intersects( const method::Ray& r, double edgeEpsilon, // snap to lower/upper left corners isect.u = 0; - if ( isect.v < 0 ) { isect.v = 0; } + if ( isect.v < 0 ) { + isect.v = 0; + } else if ( isect.v > 1 ) { isect.v = 1; } @@ -76,7 +82,9 @@ method::Intersect Triag3D::intersects( const method::Ray& r, double edgeEpsilon, // snap to lower left/right corners isect.v = 0; - if ( isect.u < 0 ) { isect.u = 0; } + if ( isect.u < 0 ) { + isect.u = 0; + } else if ( isect.u > 1 ) { isect.u = 1; } diff --git a/src/atlas/interpolation/element/Triag3D.h b/src/atlas/interpolation/element/Triag3D.h index fa4c6769c..051a7c837 100644 --- a/src/atlas/interpolation/element/Triag3D.h +++ b/src/atlas/interpolation/element/Triag3D.h @@ -54,9 +54,12 @@ class Triag3D { } const Vector3D& p( int i ) { - if ( i == 0 ) return v0; - if ( i == 1 ) return v1; - if ( i == 2 ) return v2; + if ( i == 0 ) + return v0; + if ( i == 1 ) + return v1; + if ( i == 2 ) + return v2; throw_OutOfRange( "Triag3D::p(i)", i, 3, Here() ); } diff --git a/src/atlas/interpolation/method/Method.cc b/src/atlas/interpolation/method/Method.cc index 202fd2137..b5fe2c43d 100644 --- a/src/atlas/interpolation/method/Method.cc +++ b/src/atlas/interpolation/method/Method.cc @@ -43,9 +43,15 @@ void Method::check_compatibility( const Field& src, const Field& tgt ) const { template void Method::interpolate_field( const Field& src, Field& tgt ) const { check_compatibility( src, tgt ); - if ( src.rank() == 1 ) { interpolate_field_rank1( src, tgt ); } - if ( src.rank() == 2 ) { interpolate_field_rank2( src, tgt ); } - if ( src.rank() == 3 ) { interpolate_field_rank3( src, tgt ); } + if ( src.rank() == 1 ) { + interpolate_field_rank1( src, tgt ); + } + if ( src.rank() == 2 ) { + interpolate_field_rank2( src, tgt ); + } + if ( src.rank() == 3 ) { + interpolate_field_rank3( src, tgt ); + } } template @@ -169,8 +175,12 @@ void Method::execute( const Field& src, Field& tgt ) const { ATLAS_TRACE( "atlas::interpolation::method::Method::execute()" ); - if ( src.datatype().kind() == array::DataType::KIND_REAL64 ) { interpolate_field( src, tgt ); } - if ( src.datatype().kind() == array::DataType::KIND_REAL32 ) { interpolate_field( src, tgt ); } + if ( src.datatype().kind() == array::DataType::KIND_REAL64 ) { + interpolate_field( src, tgt ); + } + if ( src.datatype().kind() == array::DataType::KIND_REAL32 ) { + interpolate_field( src, tgt ); + } tgt.set_dirty(); } @@ -196,7 +206,8 @@ void Method::haloExchange( const FieldSet& fields ) const { } } void Method::haloExchange( const Field& field ) const { - if ( field.dirty() ) source().haloExchange( field ); + if ( field.dirty() ) + source().haloExchange( field ); } } // namespace interpolation diff --git a/src/atlas/interpolation/method/fe/FiniteElement.cc b/src/atlas/interpolation/method/fe/FiniteElement.cc index 4f83f8176..957396b35 100644 --- a/src/atlas/interpolation/method/fe/FiniteElement.cc +++ b/src/atlas/interpolation/method/fe/FiniteElement.cc @@ -56,7 +56,9 @@ static const double parametricEpsilon = 1e-15; void FiniteElement::setup( const Grid& source, const Grid& target ) { - if ( mpi::comm().size() > 1 ) { ATLAS_NOTIMPLEMENTED; } + if ( mpi::comm().size() > 1 ) { + ATLAS_NOTIMPLEMENTED; + } auto functionspace = []( const Grid& grid ) { Mesh mesh; if ( StructuredGrid{grid} ) { @@ -120,7 +122,8 @@ struct Stencil { void FiniteElement::print( std::ostream& out ) const { functionspace::NodeColumns src( source_ ); functionspace::NodeColumns tgt( target_ ); - if ( not tgt ) ATLAS_NOTIMPLEMENTED; + if ( not tgt ) + ATLAS_NOTIMPLEMENTED; auto gidx_src = array::make_view( src.nodes().global_index() ); ATLAS_ASSERT( tgt.nodes().size() == idx_t( matrix_.rows() ) ); @@ -236,7 +239,9 @@ void FiniteElement::setup( const FunctionSpace& source ) { eckit::ProgressTimer progress( "Computing interpolation weights", out_npts, "point", double( 5 ), Log::debug() ); for ( idx_t ip = 0; ip < out_npts; ++ip, ++progress ) { - if ( out_ghosts( ip ) ) { continue; } + if ( out_ghosts( ip ) ) { + continue; + } PointXYZ p{( *ocoords_ )( ip, 0 ), ( *ocoords_ )( ip, 1 ), ( *ocoords_ )( ip, 2 )}; // lookup point @@ -435,9 +440,13 @@ Method::Triplets FiniteElement::projectPointToElements( size_t ip, const ElemInd w[2] = is.v; if ( on_triag_edge() ) { - if ( on_single_point() ) { triplets.emplace_back( ip, idx[single_point], w[single_point] ); } + if ( on_single_point() ) { + triplets.emplace_back( ip, idx[single_point], w[single_point] ); + } else { - if ( ( *igidx_ )( idx[edge.idx[1]] ) < ( *igidx_ )( idx[edge.idx[0]] ) ) { edge.swap(); } + if ( ( *igidx_ )( idx[edge.idx[1]] ) < ( *igidx_ )( idx[edge.idx[0]] ) ) { + edge.swap(); + } interpolate_edge( triag.p( edge.idx[0] ), triag.p( edge.idx[1] ) ); for ( size_t i = 0; i < 2; ++i ) { triplets.emplace_back( ip, idx[edge.idx[i]], w[edge.idx[i]] ); @@ -476,9 +485,13 @@ Method::Triplets FiniteElement::projectPointToElements( size_t ip, const ElemInd w[3] = ( 1. - is.u ) * is.v; if ( on_quad_edge() ) { - if ( on_single_point() ) { triplets.emplace_back( ip, idx[single_point], w[single_point] ); } + if ( on_single_point() ) { + triplets.emplace_back( ip, idx[single_point], w[single_point] ); + } else { - if ( ( *igidx_ )( idx[edge.idx[1]] ) < ( *igidx_ )( idx[edge.idx[0]] ) ) { edge.swap(); } + if ( ( *igidx_ )( idx[edge.idx[1]] ) < ( *igidx_ )( idx[edge.idx[0]] ) ) { + edge.swap(); + } interpolate_edge( quad.p( edge.idx[0] ), quad.p( edge.idx[1] ) ); for ( size_t i = 0; i < 2; ++i ) { triplets.emplace_back( ip, idx[edge.idx[i]], w[edge.idx[i]] ); @@ -496,7 +509,9 @@ Method::Triplets FiniteElement::projectPointToElements( size_t ip, const ElemInd } // loop over nearest elements - if ( !triplets.empty() ) { normalise( triplets ); } + if ( !triplets.empty() ) { + normalise( triplets ); + } return triplets; } diff --git a/src/atlas/interpolation/method/knn/KNearestNeighbours.cc b/src/atlas/interpolation/method/knn/KNearestNeighbours.cc index b6d2c3dbb..a2450308c 100644 --- a/src/atlas/interpolation/method/knn/KNearestNeighbours.cc +++ b/src/atlas/interpolation/method/knn/KNearestNeighbours.cc @@ -43,7 +43,9 @@ KNearestNeighbours::KNearestNeighbours( const Method::Config& config ) : KNeares } void KNearestNeighbours::setup( const Grid& source, const Grid& target ) { - if ( mpi::comm().size() > 1 ) { ATLAS_NOTIMPLEMENTED; } + if ( mpi::comm().size() > 1 ) { + ATLAS_NOTIMPLEMENTED; + } auto functionspace = []( const Grid& grid ) -> FunctionSpace { Mesh mesh; if ( StructuredGrid( grid ) ) { diff --git a/src/atlas/interpolation/method/knn/NearestNeighbour.cc b/src/atlas/interpolation/method/knn/NearestNeighbour.cc index 6beae9844..b2dd2d993 100644 --- a/src/atlas/interpolation/method/knn/NearestNeighbour.cc +++ b/src/atlas/interpolation/method/knn/NearestNeighbour.cc @@ -34,7 +34,9 @@ MethodBuilder __builder( "nearest-neighbour" ); } // namespace void NearestNeighbour::setup( const Grid& source, const Grid& target ) { - if ( mpi::comm().size() > 1 ) { ATLAS_NOTIMPLEMENTED; } + if ( mpi::comm().size() > 1 ) { + ATLAS_NOTIMPLEMENTED; + } auto functionspace = []( const Grid& grid ) -> FunctionSpace { Mesh mesh; if ( StructuredGrid( grid ) ) { diff --git a/src/atlas/interpolation/method/structured/kernels/Cubic3DKernel.h b/src/atlas/interpolation/method/structured/kernels/Cubic3DKernel.h index bb60058ad..a00e4d2fe 100644 --- a/src/atlas/interpolation/method/structured/kernels/Cubic3DKernel.h +++ b/src/atlas/interpolation/method/structured/kernels/Cubic3DKernel.h @@ -112,7 +112,9 @@ class Cubic3DKernel { } } - if ( limiter_ ) { limit_scalar( output, index, stencil, input ); } + if ( limiter_ ) { + limit_scalar( output, index, stencil, input ); + } return output; } @@ -129,7 +131,9 @@ class Cubic3DKernel { // x x x x idx_t k = stencil.k_interval(); idx_t k1, k2; - if ( k < 0 ) { k1 = k2 = 0; } + if ( k < 0 ) { + k1 = k2 = 0; + } else if ( k > 2 ) { k1 = k2 = 3; } @@ -153,7 +157,9 @@ class Cubic3DKernel { minval = std::min( minval, f2 ); } } - if ( output < minval ) { output = minval; } + if ( output < minval ) { + output = minval; + } else if ( output > maxval ) { output = maxval; } @@ -216,7 +222,9 @@ class Cubic3DKernel { } } - if ( limiter_ ) { limit_vars( index, stencil, input, output, nvar ); } + if ( limiter_ ) { + limit_vars( index, stencil, input, output, nvar ); + } } template @@ -234,7 +242,9 @@ class Cubic3DKernel { const idx_t k = stencil.k_interval(); idx_t k1, k2; - if ( k < 0 ) { k1 = k2 = stencil.k( 0 ); } + if ( k < 0 ) { + k1 = k2 = stencil.k( 0 ); + } else if ( k > 2 ) { k1 = k2 = stencil.k( 3 ); } @@ -260,7 +270,9 @@ class Cubic3DKernel { minval = std::min( minval, f2 ); } } - if ( limited < minval ) { limited = minval; } + if ( limited < minval ) { + limited = minval; + } else if ( limited > maxval ) { limited = maxval; } diff --git a/src/atlas/interpolation/method/structured/kernels/CubicHorizontalKernel.h b/src/atlas/interpolation/method/structured/kernels/CubicHorizontalKernel.h index 270508517..ff82d1128 100644 --- a/src/atlas/interpolation/method/structured/kernels/CubicHorizontalKernel.h +++ b/src/atlas/interpolation/method/structured/kernels/CubicHorizontalKernel.h @@ -140,7 +140,9 @@ class CubicHorizontalKernel { } } - if ( limiter_ ) { limit( output, index, input ); } + if ( limiter_ ) { + limit( output, index, input ); + } return output; } @@ -164,7 +166,9 @@ class CubicHorizontalKernel { minval = std::min( minval, val ); } } - if ( output < minval ) { output = minval; } + if ( output < minval ) { + output = minval; + } else if ( output > maxval ) { output = maxval; } @@ -189,7 +193,9 @@ class CubicHorizontalKernel { } } - if ( limiter_ ) { limit( index, input, output, r ); } + if ( limiter_ ) { + limit( index, input, output, r ); + } } template @@ -212,7 +218,9 @@ class CubicHorizontalKernel { minval = std::min( minval, val ); } } - if ( output( r ) < minval ) { output( r ) = minval; } + if ( output( r ) < minval ) { + output( r ) = minval; + } else if ( output( r ) > maxval ) { output( r ) = maxval; } @@ -242,7 +250,9 @@ class CubicHorizontalKernel { } } - if ( limiter_ ) { limit( index, input, output, r ); } + if ( limiter_ ) { + limit( index, input, output, r ); + } } template @@ -266,7 +276,9 @@ class CubicHorizontalKernel { minval = std::min( minval, val ); } } - if ( output( r, k ) < minval ) { output( r, k ) = minval; } + if ( output( r, k ) < minval ) { + output( r, k ) = minval; + } else if ( output( r, k ) > maxval ) { output( r, k ) = maxval; } diff --git a/src/atlas/interpolation/method/structured/kernels/CubicVerticalKernel.h b/src/atlas/interpolation/method/structured/kernels/CubicVerticalKernel.h index 291f9d153..081d9d21b 100644 --- a/src/atlas/interpolation/method/structured/kernels/CubicVerticalKernel.h +++ b/src/atlas/interpolation/method/structured/kernels/CubicVerticalKernel.h @@ -149,7 +149,9 @@ class CubicVerticalKernel { if ( limiter_ ) { idx_t k = stencil.k_interval(); idx_t k1, k2; - if ( k < 0 ) { k1 = k2 = 0; } + if ( k < 0 ) { + k1 = k2 = 0; + } else if ( k > 2 ) { k1 = k2 = 3; } diff --git a/src/atlas/interpolation/method/structured/kernels/QuasiCubic3DKernel.h b/src/atlas/interpolation/method/structured/kernels/QuasiCubic3DKernel.h index 140e93a36..ba65f9fd9 100644 --- a/src/atlas/interpolation/method/structured/kernels/QuasiCubic3DKernel.h +++ b/src/atlas/interpolation/method/structured/kernels/QuasiCubic3DKernel.h @@ -198,7 +198,9 @@ class QuasiCubic3DKernel { } - if ( limiter_ ) { limit_scalar( output, index, stencil, input ); } + if ( limiter_ ) { + limit_scalar( output, index, stencil, input ); + } return output; } @@ -215,7 +217,9 @@ class QuasiCubic3DKernel { // x x x x idx_t k = stencil.k_interval(); idx_t k1, k2; - if ( k < 0 ) { k1 = k2 = 0; } + if ( k < 0 ) { + k1 = k2 = 0; + } else if ( k > 2 ) { k1 = k2 = 3; } @@ -239,7 +243,9 @@ class QuasiCubic3DKernel { minval = std::min( minval, f2 ); } } - if ( output < minval ) { output = minval; } + if ( output < minval ) { + output = minval; + } else if ( output > maxval ) { output = maxval; } @@ -350,7 +356,9 @@ class QuasiCubic3DKernel { } - if ( limiter_ ) { limit_vars( index, stencil, input, output, nvar ); } + if ( limiter_ ) { + limit_vars( index, stencil, input, output, nvar ); + } } template @@ -368,7 +376,9 @@ class QuasiCubic3DKernel { const idx_t k = stencil.k_interval(); idx_t k1, k2; - if ( k < 0 ) { k1 = k2 = stencil.k( 0 ); } + if ( k < 0 ) { + k1 = k2 = stencil.k( 0 ); + } else if ( k > 2 ) { k1 = k2 = stencil.k( 3 ); } @@ -394,7 +404,9 @@ class QuasiCubic3DKernel { minval = std::min( minval, f2 ); } } - if ( limited < minval ) { limited = minval; } + if ( limited < minval ) { + limited = minval; + } else if ( limited > maxval ) { limited = maxval; } diff --git a/src/atlas/interpolation/method/structured/kernels/QuasiCubicHorizontalKernel.h b/src/atlas/interpolation/method/structured/kernels/QuasiCubicHorizontalKernel.h index d4b081a16..6ec8644e6 100644 --- a/src/atlas/interpolation/method/structured/kernels/QuasiCubicHorizontalKernel.h +++ b/src/atlas/interpolation/method/structured/kernels/QuasiCubicHorizontalKernel.h @@ -166,7 +166,9 @@ class QuasiCubicHorizontalKernel { } } - if ( limiter_ ) { limit( output, index, input ); } + if ( limiter_ ) { + limit( output, index, input ); + } return output; } @@ -190,7 +192,9 @@ class QuasiCubicHorizontalKernel { minval = std::min( minval, val ); } } - if ( output < minval ) { output = minval; } + if ( output < minval ) { + output = minval; + } else if ( output > maxval ) { output = maxval; } @@ -227,7 +231,9 @@ class QuasiCubicHorizontalKernel { } } - if ( limiter_ ) { limit( index, input, output, r ); } + if ( limiter_ ) { + limit( index, input, output, r ); + } } template @@ -250,7 +256,9 @@ class QuasiCubicHorizontalKernel { minval = std::min( minval, val ); } } - if ( output( r ) < minval ) { output( r ) = minval; } + if ( output( r ) < minval ) { + output( r ) = minval; + } else if ( output( r ) > maxval ) { output( r ) = maxval; } @@ -293,7 +301,9 @@ class QuasiCubicHorizontalKernel { } } - if ( limiter_ ) { limit( index, input, output, r ); } + if ( limiter_ ) { + limit( index, input, output, r ); + } } template @@ -317,7 +327,9 @@ class QuasiCubicHorizontalKernel { minval = std::min( minval, val ); } } - if ( output( r, k ) < minval ) { output( r, k ) = minval; } + if ( output( r, k ) < minval ) { + output( r, k ) = minval; + } else if ( output( r, k ) > maxval ) { output( r, k ) = maxval; } diff --git a/src/atlas/library/Library.cc b/src/atlas/library/Library.cc index 5afb51bcc..794d2e434 100644 --- a/src/atlas/library/Library.cc +++ b/src/atlas/library/Library.cc @@ -50,17 +50,23 @@ std::string str( const eckit::system::Library& lib ) { std::string gitsha1 = lib.gitsha1(); std::stringstream ss; ss << lib.name() << " version (" << lib.version() << "),"; - if ( lib.gitsha1() != "not available" ) { ss << " git-sha1 " << lib.gitsha1( 7 ); } + if ( lib.gitsha1() != "not available" ) { + ss << " git-sha1 " << lib.gitsha1( 7 ); + } return ss.str(); } bool getEnv( const std::string& env, bool default_value ) { - if ( ::getenv( env.c_str() ) ) { return eckit::Translator()( ::getenv( env.c_str() ) ); } + if ( ::getenv( env.c_str() ) ) { + return eckit::Translator()( ::getenv( env.c_str() ) ); + } return default_value; } int getEnv( const std::string& env, int default_value ) { - if ( ::getenv( env.c_str() ) ) { return eckit::Translator()( ::getenv( env.c_str() ) ); } + if ( ::getenv( env.c_str() ) ) { + return eckit::Translator()( ::getenv( env.c_str() ) ); + } return default_value; } @@ -124,9 +130,12 @@ void Library::initialise( const eckit::Parametrisation& config ) { config.get( "trace.report", trace_report_ ); } - if ( not debug_ ) debug_channel_.reset(); - if ( not trace_ ) trace_channel_.reset(); - if ( not info_ ) info_channel_.reset(); + if ( not debug_ ) + debug_channel_.reset(); + if ( not trace_ ) + trace_channel_.reset(); + if ( not info_ ) + info_channel_.reset(); // Summary if ( getEnv( "ATLAS_LOG_RANK", 0 ) == int( mpi::comm().rank() ) ) { @@ -156,7 +165,9 @@ void Library::initialise() { } void Library::finalise() { - if ( ATLAS_HAVE_TRACE && trace_report_ ) { Log::info() << atlas::Trace::report() << std::endl; } + if ( ATLAS_HAVE_TRACE && trace_report_ ) { + Log::info() << atlas::Trace::report() << std::endl; + } if ( getEnv( "ATLAS_FINALISES_MPI", false ) ) { Log::debug() << "ATLAS_FINALISES_MPI is set: calling eckit::mpi::finaliseAllComms()" << std::endl; @@ -174,7 +185,9 @@ void Library::finalise() { } eckit::Channel& Library::infoChannel() const { - if ( info_ ) { return eckit::Log::info(); } + if ( info_ ) { + return eckit::Log::info(); + } else if ( !info_channel_ ) { info_channel_.reset( new eckit::Channel() ); } @@ -182,7 +195,8 @@ eckit::Channel& Library::infoChannel() const { } eckit::Channel& Library::traceChannel() const { - if ( trace_channel_ ) return *trace_channel_; + if ( trace_channel_ ) + return *trace_channel_; if ( trace_ ) { trace_channel_.reset( new eckit::Channel( new eckit::PrefixTarget( "ATLAS_TRACE", new eckit::OStreamTarget( eckit::Log::info() ) ) ) ); @@ -194,8 +208,12 @@ eckit::Channel& Library::traceChannel() const { } eckit::Channel& Library::debugChannel() const { - if ( debug_channel_ ) { return *debug_channel_; } - if ( debug_ ) { debug_channel_.reset( new eckit::Channel( new eckit::PrefixTarget( "ATLAS_DEBUG" ) ) ); } + if ( debug_channel_ ) { + return *debug_channel_; + } + if ( debug_ ) { + debug_channel_.reset( new eckit::Channel( new eckit::PrefixTarget( "ATLAS_DEBUG" ) ) ); + } else { debug_channel_.reset( new eckit::Channel() ); } @@ -267,8 +285,12 @@ void Library::Information::print( std::ostream& out ) const { out << " Dependencies: " << "\n"; - if ( Library::exists( "eckit" ) ) { out << " " << str( Library::lookup( "eckit" ) ) << '\n'; } - if ( Library::exists( "fckit" ) ) { out << " " << str( Library::lookup( "fckit" ) ) << '\n'; } + if ( Library::exists( "eckit" ) ) { + out << " " << str( Library::lookup( "eckit" ) ) << '\n'; + } + if ( Library::exists( "fckit" ) ) { + out << " " << str( Library::lookup( "fckit" ) ) << '\n'; + } #if ATLAS_HAVE_TRANS out << " transi version (" << transi_version() << "), " diff --git a/src/atlas/mesh/Connectivity.cc b/src/atlas/mesh/Connectivity.cc index 04db72837..b4b0720fd 100644 --- a/src/atlas/mesh/Connectivity.cc +++ b/src/atlas/mesh/Connectivity.cc @@ -133,13 +133,15 @@ void IrregularConnectivityImpl::clear() { //------------------------------------------------------------------------------------------------------ void IrregularConnectivityImpl::on_delete() { - if ( ctxt_ && callback_delete_ ) callback_delete_( ctxt_ ); + if ( ctxt_ && callback_delete_ ) + callback_delete_( ctxt_ ); } //------------------------------------------------------------------------------------------------------ void IrregularConnectivityImpl::on_update() { - if ( ctxt_ && callback_update_ ) callback_update_( ctxt_ ); + if ( ctxt_ && callback_update_ ) + callback_update_( ctxt_ ); } void IrregularConnectivityImpl::resize( idx_t old_size, idx_t new_size, bool initialize, const idx_t values[], @@ -164,7 +166,8 @@ void IrregularConnectivityImpl::add( idx_t rows, idx_t cols, const idx_t values[ ATLAS_ASSERT( owns_, "Connectivity must be owned to be resized directly" ); idx_t old_size = values_.size(); - if ( rows_ == 0 ) old_size = 0; + if ( rows_ == 0 ) + old_size = 0; idx_t new_size = old_size + rows * cols; idx_t new_rows = rows_ + rows; @@ -230,7 +233,8 @@ void IrregularConnectivityImpl::add( idx_t rows, idx_t cols ) { ATLAS_ASSERT( owns_, "Connectivity must be owned to be resized directly" ); idx_t old_size = values_.size(); - if ( rows_ == 0 ) old_size = 0; + if ( rows_ == 0 ) + old_size = 0; idx_t new_size = old_size + rows * cols; idx_t new_rows = rows_ + rows; @@ -396,7 +400,8 @@ void IrregularConnectivityImpl::decode_( eckit::Stream& s ) { s >> rows_; s >> maxcols_; s >> mincols_; - if ( not name.empty() ) rename( name ); + if ( not name.empty() ) + rename( name ); ctxt_ = nullptr; owns_ = true; } @@ -750,7 +755,8 @@ void BlockConnectivityImpl::decode( eckit::Stream& s ) { size_t BlockConnectivityImpl::footprint() const { size_t size = sizeof( *this ); - if ( owns() ) size += values_.footprint(); + if ( owns() ) + size += values_.footprint(); return size; } diff --git a/src/atlas/mesh/Elements.cc b/src/atlas/mesh/Elements.cc index dcd309512..050d3f151 100644 --- a/src/atlas/mesh/Elements.cc +++ b/src/atlas/mesh/Elements.cc @@ -51,7 +51,8 @@ Elements::Elements( ElementType* element_type, idx_t nb_elements, const idx_t no } Elements::~Elements() { - if ( owns_ ) delete hybrid_elements_; + if ( owns_ ) + delete hybrid_elements_; } const std::string& Elements::name() const { diff --git a/src/atlas/mesh/Nodes.cc b/src/atlas/mesh/Nodes.cc index 76d72f433..fcfad654d 100644 --- a/src/atlas/mesh/Nodes.cc +++ b/src/atlas/mesh/Nodes.cc @@ -133,7 +133,8 @@ void Nodes::print( std::ostream& os ) const { os << "\t fields=\n"; for ( idx_t i = 0; i < nb_fields(); ++i ) { os << "\t\t" << field( i ); - if ( i != nb_fields() - 1 ) os << ","; + if ( i != nb_fields() - 1 ) + os << ","; os << "\n"; } os << "]"; diff --git a/src/atlas/mesh/PartitionPolygon.cc b/src/atlas/mesh/PartitionPolygon.cc index b42b5447b..6f256383f 100644 --- a/src/atlas/mesh/PartitionPolygon.cc +++ b/src/atlas/mesh/PartitionPolygon.cc @@ -45,7 +45,9 @@ util::Polygon::edge_set_t compute_edges( const detail::MeshImpl& mesh, idx_t hal if ( patch( j ) == 0 && field_halo( j ) <= halo ) { for ( idx_t k = 0; k < nb_nodes; ++k ) { util::Polygon::edge_t edge( conn( j, k ), conn( j, ( k + 1 ) % nb_nodes ) ); - if ( !edges.erase( edge.reverse() ) ) { edges.insert( edge ); } + if ( !edges.erase( edge.reverse() ) ) { + edges.insert( edge ); + } } } } diff --git a/src/atlas/mesh/actions/BuildCellCentres.cc b/src/atlas/mesh/actions/BuildCellCentres.cc index 59bdd99f2..9d26cc5b1 100644 --- a/src/atlas/mesh/actions/BuildCellCentres.cc +++ b/src/atlas/mesh/actions/BuildCellCentres.cc @@ -50,7 +50,9 @@ Field& BuildCellCentres::operator()( Mesh& mesh ) const { array::ArrayView coords = array::make_view( nodes.field( "xyz" ) ); idx_t firstVirtualPoint = std::numeric_limits::max(); - if ( nodes.metadata().has( "NbRealPts" ) ) { firstVirtualPoint = nodes.metadata().get( "NbRealPts" ); } + if ( nodes.metadata().has( "NbRealPts" ) ) { + firstVirtualPoint = nodes.metadata().get( "NbRealPts" ); + } idx_t nb_cells = mesh.cells().size(); auto centroids = array::make_view( mesh.cells().field( field_name_ ) ); @@ -81,7 +83,9 @@ Field& BuildCellCentres::operator()( Mesh& mesh ) const { } idx_t nb_unique_nodes = idx_t( nb_cell_nodes ) - nb_equal_nodes; - if ( nb_unique_nodes < 3 ) { continue; } + if ( nb_unique_nodes < 3 ) { + continue; + } if ( flatten_virtual_elements_ ) { // calculate centroid by averaging coordinates (uses only "real" nodes) diff --git a/src/atlas/mesh/actions/BuildConvexHull3D.cc b/src/atlas/mesh/actions/BuildConvexHull3D.cc index 031e51b1d..8cd6b114d 100644 --- a/src/atlas/mesh/actions/BuildConvexHull3D.cc +++ b/src/atlas/mesh/actions/BuildConvexHull3D.cc @@ -180,7 +180,8 @@ static void cgal_polyhedron_to_atlas_mesh( Mesh& mesh, Polyhedron_3& poly, Point void BuildConvexHull3D::operator()( Mesh& mesh ) const { // don't tesselate meshes already with triags or quads - if ( mesh.cells().size() ) return; + if ( mesh.cells().size() ) + return; ATLAS_TRACE(); diff --git a/src/atlas/mesh/actions/BuildDualMesh.cc b/src/atlas/mesh/actions/BuildDualMesh.cc index b13f88adb..2b56c48ca 100644 --- a/src/atlas/mesh/actions/BuildDualMesh.cc +++ b/src/atlas/mesh/actions/BuildDualMesh.cc @@ -180,7 +180,8 @@ void add_median_dual_volume_contribution_cells( const mesh::HybridElements& cell for ( idx_t jcell = 0; jcell < nb_cells; ++jcell ) { idx_t icell = ordering[jcell].i; - if ( patch( icell ) ) continue; + if ( patch( icell ) ) + continue; double x0 = cell_centroids( icell, XX ); double y0 = cell_centroids( icell, YY ); @@ -370,7 +371,8 @@ void make_dual_normals_outward( Mesh& mesh ) { void build_brick_dual_mesh( const Grid& grid, Mesh& mesh ) { auto g = StructuredGrid( grid ); if ( g ) { - if ( mpi::comm().size() != 1 ) throw_Exception( "Cannot build_brick_dual_mesh with more than 1 task", Here() ); + if ( mpi::comm().size() != 1 ) + throw_Exception( "Cannot build_brick_dual_mesh with more than 1 task", Here() ); mesh::Nodes& nodes = mesh.nodes(); array::ArrayView xy = array::make_view( nodes.xy() ); diff --git a/src/atlas/mesh/actions/BuildEdges.cc b/src/atlas/mesh/actions/BuildEdges.cc index 43babbc58..5299b8eb8 100644 --- a/src/atlas/mesh/actions/BuildEdges.cc +++ b/src/atlas/mesh/actions/BuildEdges.cc @@ -129,7 +129,8 @@ void build_element_to_edge_connectivity( Mesh& mesh ) { }; for ( idx_t jcell = 0; jcell < mesh.cells().size(); ++jcell ) { - if ( patch( jcell ) ) continue; + if ( patch( jcell ) ) + continue; for ( idx_t jcol = 0; jcol < cell_edge_connectivity.cols( jcell ); ++jcol ) { if ( cell_edge_connectivity( jcell, jcol ) == cell_edge_connectivity.missing_value() ) { const array::ArrayView gidx = array::make_view( mesh.nodes().global_index() ); @@ -225,7 +226,9 @@ class AccumulatePoleEdges { // Collect all nodes closest to poles for ( idx_t node = 0; node < nb_nodes; ++node ) { - if ( std::abs( xy( node, YY ) - max[YY] ) < tol ) { pole_nodes[NORTH].insert( node ); } + if ( std::abs( xy( node, YY ) - max[YY] ) < tol ) { + pole_nodes[NORTH].insert( node ); + } else if ( std::abs( xy( node, YY ) - min[YY] ) < tol ) { pole_nodes[SOUTH].insert( node ); } @@ -310,7 +313,9 @@ void accumulate_pole_edges( mesh::Nodes& nodes, std::vector& pole_edge_no // Collect all nodes closest to poles std::vector> pole_nodes( 2 ); for ( idx_t node = 0; node < nb_nodes; ++node ) { - if ( std::abs( xy( node, YY ) - max[YY] ) < tol ) { pole_nodes[NORTH].insert( node ); } + if ( std::abs( xy( node, YY ) - max[YY] ) < tol ) { + pole_nodes[NORTH].insert( node ); + } else if ( std::abs( xy( node, YY ) - min[YY] ) < tol ) { pole_nodes[SOUTH].insert( node ); } @@ -404,7 +409,9 @@ void build_edges( Mesh& mesh, const eckit::Configuration& config ) { bool pole_edges{false}; if ( StructuredGrid grid = mesh.grid() ) { - if ( Domain domain = grid.domain() ) { pole_edges = domain.global(); } + if ( Domain domain = grid.domain() ) { + pole_edges = domain.global(); + } } config.get( "pole_edges", pole_edges ); @@ -431,7 +438,9 @@ void build_edges( Mesh& mesh, const eckit::Configuration& config ) { nb_inner_edges, missing_value, edge_halo_offsets ); std::shared_ptr pole_edge_accumulator; - if ( pole_edges ) { pole_edge_accumulator = std::make_shared( nodes ); } + if ( pole_edges ) { + pole_edge_accumulator = std::make_shared( nodes ); + } for ( int halo = 0; halo <= mesh_halo; ++halo ) { edge_start = edge_end; @@ -558,12 +567,14 @@ void build_edges( Mesh& mesh, const eckit::Configuration& config ) { int nb_edges = mesh.edges().size(); for ( int jedge = 0; jedge < nb_edges; ++jedge ) { nb_edges_including_halo[edge_halo( jedge )] = jedge + 1; - if ( jedge > 0 ) ATLAS_ASSERT( edge_halo( jedge ) >= edge_halo( jedge - 1 ) ); + if ( jedge > 0 ) + ATLAS_ASSERT( edge_halo( jedge ) >= edge_halo( jedge - 1 ) ); } } for ( int i = 0; i <= max_halo; ++i ) { - if ( i > 0 ) ATLAS_ASSERT( nb_edges_including_halo[i] > nb_edges_including_halo[i - 1] ); + if ( i > 0 ) + ATLAS_ASSERT( nb_edges_including_halo[i] > nb_edges_including_halo[i - 1] ); std::stringstream ss; ss << "nb_edges_including_halo[" << i << "]"; mesh.metadata().set( ss.str(), nb_edges_including_halo[i] ); diff --git a/src/atlas/mesh/actions/BuildHalo.cc b/src/atlas/mesh/actions/BuildHalo.cc index 94a8aae7d..f7d74c235 100644 --- a/src/atlas/mesh/actions/BuildHalo.cc +++ b/src/atlas/mesh/actions/BuildHalo.cc @@ -158,7 +158,9 @@ void make_nodes_global_index_human_readable( const mesh::actions::BuildHalo& bui gidx_t gid = glb_idx_max + 1; const idx_t nb_node_sort = static_cast( node_sort.size() ); for ( idx_t jnode = 0; jnode < nb_node_sort; ++jnode ) { - if ( jnode > 0 && node_sort[jnode].g != node_sort[jnode - 1].g ) { ++gid; } + if ( jnode > 0 && node_sort[jnode].g != node_sort[jnode - 1].g ) { + ++gid; + } int inode = node_sort[jnode].i; glb_idx_gathered[inode] = gid; } @@ -254,7 +256,9 @@ void make_cells_global_index_human_readable( const mesh::actions::BuildHalo& bui gidx_t gid = glb_idx_max + 1; for ( idx_t jcell = 0; jcell < glb_nb_cells; ++jcell ) { - if ( jcell > 0 && cell_sort[jcell].g != cell_sort[jcell - 1].g ) { ++gid; } + if ( jcell > 0 && cell_sort[jcell].g != cell_sort[jcell - 1].g ) { + ++gid; + } idx_t icell = cell_sort[jcell].i; glb_idx_gathered[icell] = gid; } @@ -380,7 +384,8 @@ std::vector filter_nodes( std::vector nodes, const Predicate& predicat std::vector filtered; filtered.reserve( nodes.size() ); for ( int inode : nodes ) { - if ( predicate( inode ) ) filtered.push_back( inode ); + if ( predicate( inode ) ) + filtered.push_back( inode ); } return filtered; } @@ -398,7 +403,8 @@ class Notification { std::string str() const { std::stringstream stream; for ( size_t jnote = 0; jnote < notes.size(); ++jnote ) { - if ( jnote > 0 ) stream << "\n"; + if ( jnote > 0 ) + stream << "\n"; stream << notes[jnote]; } return stream.str(); @@ -440,7 +446,8 @@ void build_lookup_uid2node( Mesh& mesh, Uid2Node& uid2node ) { notes.add_error( msg.str() ); } } - if ( notes.error() ) throw_Exception( notes.str(), Here() ); + if ( notes.error() ) + throw_Exception( notes.str(), Here() ); } void accumulate_elements( const Mesh& mesh, const mpi::BufferView& request_node_uid, const Uid2Node& uid2node, @@ -462,10 +469,14 @@ void accumulate_elements( const Mesh& mesh, const mpi::BufferView& reques idx_t inode = -1; // search and get node index for uid Uid2Node::const_iterator found = uid2node.find( uid ); - if ( found != uid2node.end() ) { inode = found->second; } + if ( found != uid2node.end() ) { + inode = found->second; + } if ( inode != -1 && inode < nb_nodes ) { for ( const idx_t e : node2elem[inode] ) { - if ( elem_part( e ) == mpi_rank ) { found_elements_set.insert( e ); } + if ( elem_part( e ) == mpi_rank ) { + found_elements_set.insert( e ); + } } } } @@ -821,7 +832,9 @@ class BuildHaloHelper { const idx_t nb_nodes_on_part = static_cast( buf.node_glb_idx[jpart].size() ); for ( idx_t n = 0; n < nb_nodes_on_part; ++n ) { double crd[] = {buf.node_xy[jpart][n * 2 + XX], buf.node_xy[jpart][n * 2 + YY]}; - if ( not node_already_exists( util::unique_lonlat( crd ) ) ) { rfn_idx[jpart].push_back( n ); } + if ( not node_already_exists( util::unique_lonlat( crd ) ) ) { + rfn_idx[jpart].push_back( n ); + } } nb_new_nodes += rfn_idx[jpart].size(); } @@ -951,7 +964,8 @@ class BuildHaloHelper { // Add new elements BlockConnectivity& node_connectivity = elements.node_connectivity(); - if ( nb_elements_of_type[t] == 0 ) continue; + if ( nb_elements_of_type[t] == 0 ) + continue; idx_t old_size = elements.size(); idx_t new_elems_pos = elements.add( nb_elements_of_type[t] ); @@ -1073,9 +1087,11 @@ void gather_bdry_nodes( const BuildHaloHelper& helper, const std::vector& void increase_halo_interior( BuildHaloHelper& helper ) { helper.update(); - if ( helper.node_to_elem.size() == 0 ) build_lookup_node2elem( helper.mesh, helper.node_to_elem ); + if ( helper.node_to_elem.size() == 0 ) + build_lookup_node2elem( helper.mesh, helper.node_to_elem ); - if ( helper.uid2node.size() == 0 ) build_lookup_uid2node( helper.mesh, helper.uid2node ); + if ( helper.uid2node.size() == 0 ) + build_lookup_uid2node( helper.mesh, helper.uid2node ); // All buffers needed to move elements and nodes BuildHaloHelper::Buffers sendmesh( helper.mesh ); @@ -1140,8 +1156,10 @@ class PeriodicPoints { } bool operator()( int j ) const { - if ( j >= N_ ) return false; - if ( Topology::check( flags_( j ), flag_ ) ) return true; + if ( j >= N_ ) + return false; + if ( Topology::check( flags_( j ), flag_ ) ) + return true; return false; } @@ -1153,7 +1171,8 @@ class PeriodicPoints { friend std::ostream& operator<<( std::ostream& os, const PeriodicPoints& periodic_points ) { os << "["; for ( idx_t j = 0; j < periodic_points.flags_.shape( 0 ); ++j ) { - if ( periodic_points( j ) ) os << " " << j + 1; + if ( periodic_points( j ) ) + os << " " << j + 1; } os << " ]"; return os; @@ -1177,7 +1196,8 @@ void increase_halo_periodic( BuildHaloHelper& helper, const PeriodicPoints& peri // 1) Find boundary nodes of this partition: - if ( !helper.bdry_nodes.size() ) accumulate_partition_bdry_nodes( helper.mesh, helper.halosize, helper.bdry_nodes ); + if ( !helper.bdry_nodes.size() ) + accumulate_partition_bdry_nodes( helper.mesh, helper.halosize, helper.bdry_nodes ); std::vector bdry_nodes = filter_nodes( helper.bdry_nodes, periodic_points ); const idx_t nb_bdry_nodes = static_cast( bdry_nodes.size() ); @@ -1244,7 +1264,8 @@ void BuildHalo::operator()( int nb_elems ) { int halo = 0; mesh_.metadata().get( "halo", halo ); - if ( halo == nb_elems ) return; + if ( halo == nb_elems ) + return; ATLAS_TRACE( "Increasing mesh halo" ); diff --git a/src/atlas/mesh/actions/BuildParallelFields.cc b/src/atlas/mesh/actions/BuildParallelFields.cc index c6a80acc2..8a2eceff5 100644 --- a/src/atlas/mesh/actions/BuildParallelFields.cc +++ b/src/atlas/mesh/actions/BuildParallelFields.cc @@ -134,7 +134,9 @@ Field& build_nodes_global_idx( mesh::Nodes& nodes ) { UniqueLonLat compute_uid( nodes ); for ( idx_t jnode = 0; jnode < glb_idx.shape( 0 ); ++jnode ) { - if ( glb_idx( jnode ) <= 0 ) { glb_idx( jnode ) = compute_uid( jnode ); } + if ( glb_idx( jnode ) <= 0 ) { + glb_idx( jnode ) = compute_uid( jnode ); + } } return nodes.global_index(); } @@ -170,7 +172,9 @@ void renumber_nodes_glb_idx( mesh::Nodes& nodes ) { */ int nb_nodes = glb_idx.shape( 0 ); for ( int jnode = 0; jnode < nb_nodes; ++jnode ) { - if ( glb_idx( jnode ) <= 0 ) { glb_idx( jnode ) = compute_uid( jnode ); } + if ( glb_idx( jnode ) <= 0 ) { + glb_idx( jnode ) = compute_uid( jnode ); + } } // 1) Gather all global indices, together with location @@ -213,7 +217,9 @@ void renumber_nodes_glb_idx( mesh::Nodes& nodes ) { uid_t gid = 0; const idx_t nb_sorted_nodes = static_cast( node_sort.size() ); for ( idx_t jnode = 0; jnode < nb_sorted_nodes; ++jnode ) { - if ( jnode == 0 ) { ++gid; } + if ( jnode == 0 ) { + ++gid; + } else if ( node_sort[jnode].g != node_sort[jnode - 1].g ) { ++gid; } @@ -363,23 +369,37 @@ Field& build_edges_partition( Mesh& mesh ) { return Topology::check( flags( ip1 ), flag ) && Topology::check( flags( ip2 ), flag ); }; auto domain_bdry = [&]( idx_t jedge ) { - if ( check_flags( jedge, Topology::BC | Topology::NORTH ) ) { return true; } - if ( check_flags( jedge, Topology::BC | Topology::SOUTH ) ) { return true; } - if ( check_flags( jedge, Topology::BC | Topology::WEST ) ) { return true; } - if ( check_flags( jedge, Topology::BC | Topology::EAST ) ) { return true; } + if ( check_flags( jedge, Topology::BC | Topology::NORTH ) ) { + return true; + } + if ( check_flags( jedge, Topology::BC | Topology::SOUTH ) ) { + return true; + } + if ( check_flags( jedge, Topology::BC | Topology::WEST ) ) { + return true; + } + if ( check_flags( jedge, Topology::BC | Topology::EAST ) ) { + return true; + } return false; }; auto periodic_east = [&]( idx_t jedge ) { - if ( check_flags( jedge, Topology::PERIODIC | Topology::EAST ) ) { return true; } + if ( check_flags( jedge, Topology::PERIODIC | Topology::EAST ) ) { + return true; + } return false; }; auto periodic_west = [&]( idx_t jedge ) { - if ( check_flags( jedge, Topology::PERIODIC | Topology::WEST ) ) { return true; } + if ( check_flags( jedge, Topology::PERIODIC | Topology::WEST ) ) { + return true; + } return false; }; auto periodic_west_bdry = [&]( idx_t jedge ) { - if ( check_flags( jedge, Topology::PERIODIC | Topology::WEST | Topology::BC ) ) { return true; } + if ( check_flags( jedge, Topology::PERIODIC | Topology::WEST | Topology::BC ) ) { + return true; + } return false; }; @@ -395,7 +415,9 @@ Field& build_edges_partition( Mesh& mesh ) { PeriodicTransform transform_periodic_west( +360. ); UniqueLonLat _compute_uid( mesh ); auto compute_uid = [&]( idx_t jedge ) -> gidx_t { - if ( periodic_east( jedge ) ) { return -_compute_uid( edge_nodes.row( jedge ), transform_periodic_east ); } + if ( periodic_east( jedge ) ) { + return -_compute_uid( edge_nodes.row( jedge ), transform_periodic_east ); + } else if ( periodic_west_bdry( jedge ) ) { return _compute_uid( edge_nodes.row( jedge ) ); } @@ -463,7 +485,9 @@ Field& build_edges_partition( Mesh& mesh ) { ATLAS_NOTIMPLEMENTED; } else if ( elem2 == missing ) { - if ( pn1 == pn2 ) { p = pn1; } + if ( pn1 == pn2 ) { + p = pn1; + } else if ( periodic_east( jedge ) ) { #ifdef DEBUGGING_PARFIELDS if ( FIND_EDGE( jedge ) ) @@ -539,7 +563,8 @@ Field& build_edges_partition( Mesh& mesh ) { if ( global_to_local.count( master_gidx ) ) { idx_t iedge = global_to_local[master_gidx]; #ifdef DEBUGGING_PARFIELDS - if ( FIND_GIDX( master_gidx ) ) std::cout << "[" << mypart << "] found " << EDGE( iedge ) << std::endl; + if ( FIND_GIDX( master_gidx ) ) + std::cout << "[" << mypart << "] found " << EDGE( iedge ) << std::endl; #endif if ( not is_bdry_edge( master_gidx ) ) { send_gidx[p].push_back( gidx ); @@ -683,7 +708,8 @@ Field& build_edges_partition( Mesh& mesh ) { } } mpi::comm().allReduceInPlace( insane, eckit::mpi::max() ); - if ( insane && eckit::mpi::comm().rank() == 0 ) throw_Exception( "Sanity check failed", Here() ); + if ( insane && eckit::mpi::comm().rank() == 0 ) + throw_Exception( "Sanity check failed", Here() ); //#ifdef DEBUGGING_PARFIELDS // if( OWNED_EDGE(jedge) ) @@ -742,7 +768,9 @@ Field& build_edges_remote_idx( Mesh& mesh ) { int ip2 = edge_nodes( jedge, 1 ); centroid[XX] = 0.5 * ( xy( ip1, XX ) + xy( ip2, XX ) ); centroid[YY] = 0.5 * ( xy( ip1, YY ) + xy( ip2, YY ) ); - if ( has_pole_edges && is_pole_edge( jedge ) ) { centroid[YY] = centroid[YY] > 0 ? 90. : -90.; } + if ( has_pole_edges && is_pole_edge( jedge ) ) { + centroid[YY] = centroid[YY] > 0 ? 90. : -90.; + } bool needed( false ); @@ -770,7 +798,9 @@ Field& build_edges_remote_idx( Mesh& mesh ) { edge_ridx( jedge ) = jedge; #ifdef DEBUGGING_PARFIELDS - if ( FIND_EDGE( jedge ) ) { ATLAS_DEBUG( "Found " << EDGE( jedge ) ); } + if ( FIND_EDGE( jedge ) ) { + ATLAS_DEBUG( "Found " << EDGE( jedge ) ); + } #endif } else // All ghost edges PLUS the periodic edges identified edges above @@ -876,7 +906,9 @@ Field& build_edges_global_idx( Mesh& mesh ) { if ( edge_gidx( jedge ) <= 0 ) { centroid[XX] = 0.5 * ( xy( edge_nodes( jedge, 0 ), XX ) + xy( edge_nodes( jedge, 1 ), XX ) ); centroid[YY] = 0.5 * ( xy( edge_nodes( jedge, 0 ), YY ) + xy( edge_nodes( jedge, 1 ), YY ) ); - if ( has_pole_edges && is_pole_edge( jedge ) ) { centroid[YY] = centroid[YY] > 0 ? 90. : -90.; } + if ( has_pole_edges && is_pole_edge( jedge ) ) { + centroid[YY] = centroid[YY] > 0 ? 90. : -90.; + } edge_gidx( jedge ) = util::unique_lonlat( centroid ); } } @@ -924,7 +956,9 @@ Field& build_edges_global_idx( Mesh& mesh ) { // Assume edge gid start uid_t gid( 0 ); for ( size_t jedge = 0; jedge < edge_sort.size(); ++jedge ) { - if ( jedge == 0 ) { ++gid; } + if ( jedge == 0 ) { + ++gid; + } else if ( edge_sort[jedge].g != edge_sort[jedge - 1].g ) { ++gid; } diff --git a/src/atlas/mesh/actions/BuildStatistics.cc b/src/atlas/mesh/actions/BuildStatistics.cc index bf3a87955..a34d0b042 100644 --- a/src/atlas/mesh/actions/BuildStatistics.cc +++ b/src/atlas/mesh/actions/BuildStatistics.cc @@ -147,7 +147,8 @@ void build_statistics( Mesh& mesh ) { // Cell statistics { - if ( mpi::comm().size() == 1 ) ofs.open( stats_path.localPath(), std::ofstream::app ); + if ( mpi::comm().size() == 1 ) + ofs.open( stats_path.localPath(), std::ofstream::app ); array::ArrayView rho = array::make_view( mesh.cells().add( Field( "stats_rho", array::make_datatype(), array::make_shape( mesh.cells().size() ) ) ) ); @@ -197,7 +198,8 @@ void build_statistics( Mesh& mesh ) { } } } - if ( mpi::comm().size() == 1 ) ofs.close(); + if ( mpi::comm().size() == 1 ) + ofs.close(); } eckit::PathName dual_stats_path( "dual_stats.txt" ); @@ -226,7 +228,8 @@ void build_statistics( Mesh& mesh ) { } } } - if ( mpi::comm().size() == 1 ) ofs.close(); + if ( mpi::comm().size() == 1 ) + ofs.close(); } // ------------------------------------------------------------------ diff --git a/src/atlas/mesh/actions/ExtendNodesGlobal.cc b/src/atlas/mesh/actions/ExtendNodesGlobal.cc index eeb556825..80bdc5e1d 100644 --- a/src/atlas/mesh/actions/ExtendNodesGlobal.cc +++ b/src/atlas/mesh/actions/ExtendNodesGlobal.cc @@ -27,7 +27,8 @@ namespace actions { ExtendNodesGlobal::ExtendNodesGlobal( const std::string& gridname ) : gridname_( gridname ) {} void ExtendNodesGlobal::operator()( const Grid& grid, Mesh& mesh ) const { - if ( grid.domain().global() ) return; // don't add virtual points to global domains + if ( grid.domain().global() ) + return; // don't add virtual points to global domains Grid O16( "O16" ); @@ -39,7 +40,9 @@ void ExtendNodesGlobal::operator()( const Grid& grid, Mesh& mesh ) const { for ( const PointLonLat& lonlat : O16.lonlat() ) { PointXY xy = grid.projection().xy( lonlat ); - if ( not grid.domain().contains( xy ) ) { extended_pts.push_back( xy ); } + if ( not grid.domain().contains( xy ) ) { + extended_pts.push_back( xy ); + } } mesh::Nodes& nodes = mesh.nodes(); diff --git a/src/atlas/mesh/actions/WriteLoadBalanceReport.cc b/src/atlas/mesh/actions/WriteLoadBalanceReport.cc index 838d0f7e7..7c3497a92 100644 --- a/src/atlas/mesh/actions/WriteLoadBalanceReport.cc +++ b/src/atlas/mesh/actions/WriteLoadBalanceReport.cc @@ -37,7 +37,9 @@ void write_load_balance_report( const Mesh& mesh, const std::string& filename ) write_load_balance_report( mesh, ofs ); - if ( mpi::comm().rank() == 0 ) { ofs.close(); } + if ( mpi::comm().rank() == 0 ) { + ofs.close(); + } } void write_load_balance_report( const Mesh& mesh, std::ostream& ofs ) { diff --git a/src/atlas/mesh/detail/AccumulateFacets.cc b/src/atlas/mesh/detail/AccumulateFacets.cc index 6ad19c8c6..3d488047f 100644 --- a/src/atlas/mesh/detail/AccumulateFacets.cc +++ b/src/atlas/mesh/detail/AccumulateFacets.cc @@ -31,8 +31,12 @@ void accumulate_facets( const mesh::HybridElements& cells, const mesh::Nodes& no } nb_facets = 0; nb_inner_facets = 0; - if ( connectivity_facet_to_elem.size() == 0 ) { connectivity_facet_to_elem.reserve( 6 * cells.size() ); } - if ( facet_nodes_data.size() == 0 ) { facet_nodes_data.reserve( 6 * cells.size() ); } + if ( connectivity_facet_to_elem.size() == 0 ) { + connectivity_facet_to_elem.reserve( 6 * cells.size() ); + } + if ( facet_nodes_data.size() == 0 ) { + facet_nodes_data.reserve( 6 * cells.size() ); + } for ( idx_t t = 0; t < cells.nb_types(); ++t ) { const mesh::Elements& elements = cells.elements( t ); const mesh::BlockConnectivity& elem_nodes = elements.node_connectivity(); @@ -77,7 +81,8 @@ void accumulate_facets( const mesh::HybridElements& cells, const mesh::Nodes& no std::vector facet_nodes( nb_nodes_in_facet ); for ( idx_t e = 0; e < nb_elems; ++e ) { - if ( patch( e ) ) continue; + if ( patch( e ) ) + continue; for ( idx_t f = 0; f < nb_facets_in_elem; ++f ) { bool found_face = false; @@ -130,8 +135,12 @@ void accumulate_facets_in_range( std::vector& range, const mesh::H idx_t& nb_inner_facets, idx_t& missing_value, std::vector>& node_to_facet ) { ATLAS_TRACE(); - if ( connectivity_facet_to_elem.size() == 0 ) { connectivity_facet_to_elem.reserve( 6 * cells.size() ); } - if ( facet_nodes_data.size() == 0 ) { facet_nodes_data.reserve( 6 * cells.size() ); } + if ( connectivity_facet_to_elem.size() == 0 ) { + connectivity_facet_to_elem.reserve( 6 * cells.size() ); + } + if ( facet_nodes_data.size() == 0 ) { + facet_nodes_data.reserve( 6 * cells.size() ); + } for ( idx_t t = 0; t < cells.nb_types(); ++t ) { const mesh::Elements& elements = cells.elements( t ); const mesh::BlockConnectivity& elem_nodes = elements.node_connectivity(); @@ -178,7 +187,8 @@ void accumulate_facets_in_range( std::vector& range, const mesh::H const idx_t e_end = range[t].end(); for ( idx_t e = e_start; e < e_end; ++e ) { - if ( patch( e ) ) continue; + if ( patch( e ) ) + continue; for ( idx_t f = 0; f < nb_facets_in_elem; ++f ) { bool found_face = false; diff --git a/src/atlas/mesh/detail/MeshImpl.cc b/src/atlas/mesh/detail/MeshImpl.cc index 85813234d..0dc9ea6f0 100644 --- a/src/atlas/mesh/detail/MeshImpl.cc +++ b/src/atlas/mesh/detail/MeshImpl.cc @@ -54,14 +54,21 @@ size_t MeshImpl::footprint() const { size_t size = sizeof( *this ); size += metadata_.footprint(); - if ( nodes_ ) size += nodes_->footprint(); - if ( cells_ ) size += cells_->footprint(); - if ( facets_ ) size += facets_->footprint(); - if ( ridges_ ) size += ridges_->footprint(); - if ( peaks_ ) size += peaks_->footprint(); - if ( partition_graph_ ) size += partition_graph_->footprint(); + if ( nodes_ ) + size += nodes_->footprint(); + if ( cells_ ) + size += cells_->footprint(); + if ( facets_ ) + size += facets_->footprint(); + if ( ridges_ ) + size += ridges_->footprint(); + if ( peaks_ ) + size += peaks_->footprint(); + if ( partition_graph_ ) + size += partition_graph_->footprint(); for ( const auto& polygon : polygons_ ) { - if ( polygon ) size += polygon->footprint(); + if ( polygon ) + size += polygon->footprint(); } return size; @@ -92,7 +99,8 @@ void MeshImpl::setProjection( const Projection& projection ) { void MeshImpl::setGrid( const Grid& grid ) { grid_.reset( new Grid( grid ) ); - if ( not projection_ ) projection_ = grid_->projection(); + if ( not projection_ ) + projection_ = grid_->projection(); } idx_t MeshImpl::nb_partitions() const { @@ -104,31 +112,48 @@ idx_t MeshImpl::partition() const { } void MeshImpl::cloneToDevice() const { - if ( nodes_ ) nodes_->cloneToDevice(); - if ( cells_ ) cells_->cloneToDevice(); - if ( facets_ ) facets_->cloneToDevice(); - if ( ridges_ ) ridges_->cloneToDevice(); - if ( peaks_ ) peaks_->cloneToDevice(); + if ( nodes_ ) + nodes_->cloneToDevice(); + if ( cells_ ) + cells_->cloneToDevice(); + if ( facets_ ) + facets_->cloneToDevice(); + if ( ridges_ ) + ridges_->cloneToDevice(); + if ( peaks_ ) + peaks_->cloneToDevice(); } void MeshImpl::cloneFromDevice() const { - if ( nodes_ ) nodes_->cloneFromDevice(); - if ( cells_ ) cells_->cloneFromDevice(); - if ( facets_ ) facets_->cloneFromDevice(); - if ( ridges_ ) ridges_->cloneFromDevice(); - if ( peaks_ ) peaks_->cloneFromDevice(); + if ( nodes_ ) + nodes_->cloneFromDevice(); + if ( cells_ ) + cells_->cloneFromDevice(); + if ( facets_ ) + facets_->cloneFromDevice(); + if ( ridges_ ) + ridges_->cloneFromDevice(); + if ( peaks_ ) + peaks_->cloneFromDevice(); } void MeshImpl::syncHostDevice() const { - if ( nodes_ ) nodes_->syncHostDevice(); - if ( cells_ ) cells_->syncHostDevice(); - if ( facets_ ) facets_->syncHostDevice(); - if ( ridges_ ) ridges_->syncHostDevice(); - if ( peaks_ ) peaks_->syncHostDevice(); + if ( nodes_ ) + nodes_->syncHostDevice(); + if ( cells_ ) + cells_->syncHostDevice(); + if ( facets_ ) + facets_->syncHostDevice(); + if ( ridges_ ) + ridges_->syncHostDevice(); + if ( peaks_ ) + peaks_->syncHostDevice(); } const PartitionGraph& MeshImpl::partitionGraph() const { - if ( not partition_graph_ ) { partition_graph_.reset( build_partition_graph( *this ) ); } + if ( not partition_graph_ ) { + partition_graph_.reset( build_partition_graph( *this ) ); + } return *partition_graph_; } @@ -137,7 +162,9 @@ PartitionGraph::Neighbours MeshImpl::nearestNeighbourPartitions() const { } const PartitionPolygon& MeshImpl::polygon( idx_t halo ) const { - if ( halo >= static_cast( polygons_.size() ) ) { polygons_.resize( halo + 1 ); } + if ( halo >= static_cast( polygons_.size() ) ) { + polygons_.resize( halo + 1 ); + } if ( not polygons_[halo] ) { int mesh_halo = 0; metadata().get( "halo", mesh_halo ); diff --git a/src/atlas/mesh/detail/PartitionGraph.cc b/src/atlas/mesh/detail/PartitionGraph.cc index 0eb027663..aed76a67f 100644 --- a/src/atlas/mesh/detail/PartitionGraph.cc +++ b/src/atlas/mesh/detail/PartitionGraph.cc @@ -63,8 +63,12 @@ PartitionGraph* build_partition_graph( const MeshImpl& mesh ) { for ( const PolygonXY& _polygon : polygons ) { for ( const PointXY& pxy : _polygon ) { PointLonLat pll = pxy; - if ( eckit::types::is_strictly_greater( 0., pll.lon() ) ) { pll.lon() += 360.; } - if ( eckit::types::is_approximately_greater_or_equal( pll.lon(), 360. ) ) { pll.lon() -= 360.; } + if ( eckit::types::is_strictly_greater( 0., pll.lon() ) ) { + pll.lon() += 360.; + } + if ( eckit::types::is_approximately_greater_or_equal( pll.lon(), 360. ) ) { + pll.lon() -= 360.; + } uidx_t uid = util::unique_lonlat( pll.data() ); uid_2_parts[uid].insert( jpart ); } @@ -75,7 +79,9 @@ PartitionGraph* build_partition_graph( const MeshImpl& mesh ) { const std::set& parts = u2p.second; for ( idx_t jpart : parts ) { for ( idx_t ipart : parts ) { - if ( jpart != ipart ) { graph[jpart].insert( ipart ); } + if ( jpart != ipart ) { + graph[jpart].insert( ipart ); + } } } } @@ -126,7 +132,8 @@ PartitionGraph::PartitionGraph( idx_t values[], idx_t rows, idx_t displs[], idx_ for ( idx_t neighbour : nearestNeighbours( jpart ) ) { bool found( false ); for ( idx_t nextneighbour : nearestNeighbours( neighbour ) ) { - if ( nextneighbour == jpart ) found = true; + if ( nextneighbour == jpart ) + found = true; } if ( not found ) { values_.insert( values_.begin() + displs_[neighbour] + counts_[neighbour], jpart ); diff --git a/src/atlas/meshgenerator/detail/RegularMeshGenerator.cc b/src/atlas/meshgenerator/detail/RegularMeshGenerator.cc index b47b0c26b..2e947d5ea 100644 --- a/src/atlas/meshgenerator/detail/RegularMeshGenerator.cc +++ b/src/atlas/meshgenerator/detail/RegularMeshGenerator.cc @@ -49,10 +49,12 @@ RegularMeshGenerator::RegularMeshGenerator( const eckit::Parametrisation& p ) { // options copied from Structured MeshGenerator size_t nb_parts; - if ( p.get( "nb_parts", nb_parts ) ) options.set( "nb_parts", nb_parts ); + if ( p.get( "nb_parts", nb_parts ) ) + options.set( "nb_parts", nb_parts ); size_t part; - if ( p.get( "part", part ) ) options.set( "part", part ); + if ( p.get( "part", part ) ) + options.set( "part", part ); std::string partitioner; if ( p.get( "partitioner", partitioner ) ) { @@ -66,10 +68,12 @@ RegularMeshGenerator::RegularMeshGenerator( const eckit::Parametrisation& p ) { // options specifically for this MeshGenerator bool periodic_x; - if ( p.get( "periodic_x", periodic_x ) ) options.set( "periodic_x", periodic_x ); + if ( p.get( "periodic_x", periodic_x ) ) + options.set( "periodic_x", periodic_x ); bool periodic_y; - if ( p.get( "periodic_y", periodic_y ) ) options.set( "periodic_y", periodic_y ); + if ( p.get( "periodic_y", periodic_y ) ) + options.set( "periodic_y", periodic_y ); bool biperiodic; if ( p.get( "biperiodic", biperiodic ) ) { @@ -102,7 +106,8 @@ void RegularMeshGenerator::generate( const Grid& grid, Mesh& mesh ) const { ATLAS_ASSERT( !mesh.generated() ); const RegularGrid rg = RegularGrid( grid ); - if ( !rg ) throw_Exception( "RegularMeshGenerator can only work with a Regular grid", Here() ); + if ( !rg ) + throw_Exception( "RegularMeshGenerator can only work with a Regular grid", Here() ); size_t nb_parts = options.get( "nb_parts" ); @@ -126,7 +131,8 @@ void RegularMeshGenerator::hash( eckit::Hash& h ) const { void RegularMeshGenerator::generate( const Grid& grid, const grid::Distribution& distribution, Mesh& mesh ) const { const auto rg = RegularGrid( grid ); - if ( !rg ) throw_Exception( "Grid could not be cast to a Regular", Here() ); + if ( !rg ) + throw_Exception( "Grid could not be cast to a Regular", Here() ); ATLAS_ASSERT( !mesh.generated() ); @@ -415,7 +421,9 @@ void RegularMeshGenerator::generate_mesh( const RegularGrid& rg, const std::vect // node properties if ( is_node_SR[ii] ) { // set node counter - if ( is_ghost_SR[ii] ) { inode = inode_ghost++; } + if ( is_ghost_SR[ii] ) { + inode = inode_ghost++; + } else { inode = inode_nonghost++; } diff --git a/src/atlas/meshgenerator/detail/StructuredMeshGenerator.cc b/src/atlas/meshgenerator/detail/StructuredMeshGenerator.cc index d89dbb037..c4f95b0ce 100644 --- a/src/atlas/meshgenerator/detail/StructuredMeshGenerator.cc +++ b/src/atlas/meshgenerator/detail/StructuredMeshGenerator.cc @@ -68,13 +68,16 @@ StructuredMeshGenerator::StructuredMeshGenerator( const eckit::Parametrisation& configure_defaults(); bool include_pole; - if ( p.get( "include_pole", include_pole ) ) options.set( "include_pole", include_pole ); + if ( p.get( "include_pole", include_pole ) ) + options.set( "include_pole", include_pole ); bool patch_pole; - if ( p.get( "patch_pole", patch_pole ) ) options.set( "patch_pole", patch_pole ); + if ( p.get( "patch_pole", patch_pole ) ) + options.set( "patch_pole", patch_pole ); bool unique_pole; - if ( p.get( "unique_pole", unique_pole ) ) options.set( "unique_pole", unique_pole ); + if ( p.get( "unique_pole", unique_pole ) ) + options.set( "unique_pole", unique_pole ); bool force_include_pole; if ( p.get( "force_include_north_pole", force_include_pole ) ) @@ -87,19 +90,24 @@ StructuredMeshGenerator::StructuredMeshGenerator( const eckit::Parametrisation& options.set( "3d", three_dimensional ); size_t nb_parts; - if ( p.get( "nb_parts", nb_parts ) ) options.set( "nb_parts", nb_parts ); + if ( p.get( "nb_parts", nb_parts ) ) + options.set( "nb_parts", nb_parts ); size_t part; - if ( p.get( "part", part ) ) options.set( "part", part ); + if ( p.get( "part", part ) ) + options.set( "part", part ); double angle; - if ( p.get( "angle", angle ) ) options.set( "angle", angle ); + if ( p.get( "angle", angle ) ) + options.set( "angle", angle ); bool triangulate; - if ( p.get( "triangulate", triangulate ) ) options.set( "triangulate", triangulate ); + if ( p.get( "triangulate", triangulate ) ) + options.set( "triangulate", triangulate ); bool ghost_at_end; - if ( p.get( "ghost_at_end", ghost_at_end ) ) options.set( "ghost_at_end", ghost_at_end ); + if ( p.get( "ghost_at_end", ghost_at_end ) ) + options.set( "ghost_at_end", ghost_at_end ); std::string partitioner; if ( grid::Partitioner::exists( "trans" ) ) @@ -162,7 +170,8 @@ void StructuredMeshGenerator::generate( const Grid& grid, Mesh& mesh ) const { ATLAS_ASSERT( !mesh.generated() ); const StructuredGrid rg = StructuredGrid( grid ); - if ( !rg ) throw_Exception( "Structured can only work with a Structured", Here() ); + if ( !rg ) + throw_Exception( "Structured can only work with a Structured", Here() ); idx_t nb_parts = options.get( "nb_parts" ); @@ -188,7 +197,8 @@ void StructuredMeshGenerator::generate( const Grid& grid, const grid::Distributi ATLAS_TRACE(); const StructuredGrid rg = StructuredGrid( grid ); - if ( !rg ) throw_Exception( "Grid could not be cast to a Structured", Here() ); + if ( !rg ) + throw_Exception( "Grid could not be cast to a Structured", Here() ); ATLAS_ASSERT( !mesh.generated() ); @@ -279,8 +289,10 @@ Find min and max latitudes used by this part. /* We need to connect to next region */ - if ( lat_north - 1 >= 0 && rg.nx( lat_north - 1 ) > 0 ) --lat_north; - if ( idx_t( lat_south + 1 ) <= rg.ny() - 1 && rg.nx( lat_south + 1 ) > 0 ) ++lat_south; + if ( lat_north - 1 >= 0 && rg.nx( lat_north - 1 ) > 0 ) + --lat_north; + if ( idx_t( lat_south + 1 ) <= rg.ny() - 1 && rg.nx( lat_south + 1 ) > 0 ) + ++lat_south; region.lat_begin.resize( rg.ny(), -1 ); region.lat_end.resize( rg.ny(), -1 ); region.nb_lat_elems.resize( rg.ny(), 0 ); @@ -322,11 +334,13 @@ We need to connect to next region beginN = 0; endN = rg.nx( latN ) - ( periodic_east_west ? 0 : 1 ); - if ( eckit::types::is_approximately_equal( yN, 90. ) && unique_pole ) endN = beginN; + if ( eckit::types::is_approximately_equal( yN, 90. ) && unique_pole ) + endN = beginN; beginS = 0; endS = rg.nx( latS ) - ( periodic_east_west ? 0 : 1 ); - if ( eckit::types::is_approximately_equal( yS, -90. ) && unique_pole ) endS = beginS; + if ( eckit::types::is_approximately_equal( yS, -90. ) && unique_pole ) + endS = beginS; ipN1 = beginN; ipS1 = beginS; @@ -342,7 +356,8 @@ We need to connect to next region #endif while ( true ) { - if ( ipN1 == endN && ipS1 == endS ) break; + if ( ipN1 == endN && ipS1 == endS ) + break; #if DEBUG_OUTPUT Log::info() << "-------\n"; @@ -383,10 +398,14 @@ We need to connect to next region xS1 = rg.x( ipS1, latS ) * to_rad; xS2 = rg.x( ipS2, latS ) * to_rad; - if ( stagger && ( latN + 1 ) % 2 == 0 ) xN1 += M_PI / static_cast( rg.nx( latN ) ); - if ( stagger && ( latN + 1 ) % 2 == 0 ) xN2 += M_PI / static_cast( rg.nx( latN ) ); - if ( stagger && ( latS + 1 ) % 2 == 0 ) xS1 += M_PI / static_cast( rg.nx( latS ) ); - if ( stagger && ( latS + 1 ) % 2 == 0 ) xS2 += M_PI / static_cast( rg.nx( latS ) ); + if ( stagger && ( latN + 1 ) % 2 == 0 ) + xN1 += M_PI / static_cast( rg.nx( latN ) ); + if ( stagger && ( latN + 1 ) % 2 == 0 ) + xN2 += M_PI / static_cast( rg.nx( latN ) ); + if ( stagger && ( latS + 1 ) % 2 == 0 ) + xS1 += M_PI / static_cast( rg.nx( latS ) ); + if ( stagger && ( latS + 1 ) % 2 == 0 ) + xS2 += M_PI / static_cast( rg.nx( latS ) ); #if DEBUG_OUTPUT Log::info() << "-------\n"; @@ -429,13 +448,17 @@ We need to connect to next region try_make_triangle_down = ( jlat + ipN1 + 1 ) % 2; } else if ( dN1S2 < dS1N2 ) { - if ( ipS1 != ipS2 ) { try_make_triangle_up = true; } + if ( ipS1 != ipS2 ) { + try_make_triangle_up = true; + } else { try_make_triangle_down = true; } } else if ( dN1S2 > dS1N2 ) { - if ( ipN1 != ipN2 ) { try_make_triangle_down = true; } + if ( ipN1 != ipN2 ) { + try_make_triangle_down = true; + } else { try_make_triangle_up = true; } @@ -462,7 +485,9 @@ We need to connect to next region // dN2S2 = std::abs(xN2-xS2); // Log::info() << " dN1S2 " << dN1S2 << " dS1N2 " << dS1N2 << " // dN2S2 " << dN2S2 << std::endl; - if ( ( dN1S2 <= dS1N2 ) && ( ipS1 != ipS2 ) ) { try_make_triangle_up = true; } + if ( ( dN1S2 <= dS1N2 ) && ( ipS1 != ipS2 ) ) { + try_make_triangle_up = true; + } else if ( ( dN1S2 >= dS1N2 ) && ( ipN1 != ipN2 ) ) { try_make_triangle_down = true; } @@ -496,11 +521,13 @@ We need to connect to next region pcnts[j] = std::count( np.begin(), np.end(), np[j] ); if ( pcnts[0] > 2 ) { // 3 or more of pN1 pE = pN1; - if ( latS == rg.ny() - 1 ) pE = pS1; + if ( latS == rg.ny() - 1 ) + pE = pS1; } else if ( pcnts[2] > 2 ) { // 3 or more of pS1 pE = pS1; - if ( latN == 0 ) pE = pN1; + if ( latN == 0 ) + pE = pN1; } else { std::array::iterator p_max = std::max_element( pcnts.begin(), pcnts.end() ); @@ -509,7 +536,8 @@ We need to connect to next region } else { // 3 or 4 points don't belong to mypart pE = pN1; - if ( latS == rg.ny() - 1 ) pE = pS1; + if ( latS == rg.ny() - 1 ) + pE = pS1; } } add_quad = ( pE == mypart ); @@ -518,8 +546,10 @@ We need to connect to next region ++jelem; ++nelems; - if ( region.lat_begin.at( latN ) == -1 ) region.lat_begin.at( latN ) = ipN1; - if ( region.lat_begin.at( latS ) == -1 ) region.lat_begin.at( latS ) = ipS1; + if ( region.lat_begin.at( latN ) == -1 ) + region.lat_begin.at( latN ) = ipN1; + if ( region.lat_begin.at( latS ) == -1 ) + region.lat_begin.at( latS ) = ipS1; region.lat_begin.at( latN ) = std::min( region.lat_begin.at( latN ), ipN1 ); region.lat_begin.at( latS ) = std::min( region.lat_begin.at( latS ), ipS1 ); region.lat_end.at( latN ) = std::max( region.lat_end.at( latN ), ipN2 ); @@ -546,7 +576,8 @@ We need to connect to next region elem( 3 ) = ipN2; pE = pN1; - if ( latS == rg.ny() - 1 ) pE = pS1; + if ( latS == rg.ny() - 1 ) + pE = pS1; add_triag = ( mypart == pE ); if ( add_triag ) { @@ -554,8 +585,10 @@ We need to connect to next region ++jelem; ++nelems; - if ( region.lat_begin.at( latN ) == -1 ) region.lat_begin.at( latN ) = ipN1; - if ( region.lat_begin.at( latS ) == -1 ) region.lat_begin.at( latS ) = ipS1; + if ( region.lat_begin.at( latN ) == -1 ) + region.lat_begin.at( latN ) = ipN1; + if ( region.lat_begin.at( latS ) == -1 ) + region.lat_begin.at( latS ) = ipS1; region.lat_begin.at( latN ) = std::min( region.lat_begin.at( latN ), ipN1 ); region.lat_begin.at( latS ) = std::min( region.lat_begin.at( latS ), ipS1 ); region.lat_end.at( latN ) = std::max( region.lat_end.at( latN ), ipN2 ); @@ -583,13 +616,17 @@ We need to connect to next region elem( 3 ) = -1; if ( pS1 == pE && pN1 != pE ) { - if ( xN1 < 0.5 * ( xS1 + xS2 ) ) { pE = pN1; } // else pE of previous element + if ( xN1 < 0.5 * ( xS1 + xS2 ) ) { + pE = pN1; + } // else pE of previous element } else { pE = pN1; } - if ( ipN1 == rg.nx( latN ) ) pE = pS1; - if ( latS == rg.ny() - 1 ) pE = pS1; + if ( ipN1 == rg.nx( latN ) ) + pE = pS1; + if ( latS == rg.ny() - 1 ) + pE = pS1; add_triag = ( mypart == pE ); @@ -598,8 +635,10 @@ We need to connect to next region ++jelem; ++nelems; - if ( region.lat_begin.at( latN ) == -1 ) region.lat_begin.at( latN ) = ipN1; - if ( region.lat_begin.at( latS ) == -1 ) region.lat_begin.at( latS ) = ipS1; + if ( region.lat_begin.at( latN ) == -1 ) + region.lat_begin.at( latN ) = ipN1; + if ( region.lat_begin.at( latS ) == -1 ) + region.lat_begin.at( latS ) = ipS1; region.lat_begin.at( latN ) = std::min( region.lat_begin.at( latN ), ipN1 ); region.lat_begin.at( latS ) = std::min( region.lat_begin.at( latS ), ipS1 ); region.lat_end.at( latN ) = std::max( region.lat_end.at( latN ), ipN1 ); @@ -623,14 +662,20 @@ We need to connect to next region #if DEBUG_OUTPUT ATLAS_DEBUG_VAR( region.nb_lat_elems.at( jlat ) ); #endif - if ( region.nb_lat_elems.at( jlat ) == 0 && latN == region.north ) { ++region.north; } - if ( region.nb_lat_elems.at( jlat ) == 0 && latS == region.south ) { --region.south; } + if ( region.nb_lat_elems.at( jlat ) == 0 && latN == region.north ) { + ++region.north; + } + if ( region.nb_lat_elems.at( jlat ) == 0 && latS == region.south ) { + --region.south; + } // region.lat_end.at(latN) = std::min(region.lat_end.at(latN), // int(rg.nx(latN)-1)); // region.lat_end.at(latS) = std::min(region.lat_end.at(latS), // int(rg.nx(latS)-1)); - if ( yN == 90 && unique_pole ) region.lat_end.at( latN ) = rg.nx( latN ) - 1; - if ( yS == -90 && unique_pole ) region.lat_end.at( latS ) = rg.nx( latS ) - 1; + if ( yN == 90 && unique_pole ) + region.lat_end.at( latN ) = rg.nx( latN ) - 1; + if ( yS == -90 && unique_pole ) + region.lat_end.at( latS ) = rg.nx( latS ) - 1; if ( region.nb_lat_elems.at( jlat ) > 0 ) { region.lat_end.at( latN ) = std::max( region.lat_end.at( latN ), region.lat_begin.at( latN ) ); @@ -744,7 +789,8 @@ void StructuredMeshGenerator::generate_mesh( const StructuredGrid& rg, const std size_t node_numbering_size = nnodes; if ( remove_periodic_ghost_points ) { for ( idx_t jlat = 0; jlat < rg.ny(); ++jlat ) { - if ( region.lat_end[jlat] >= rg.nx( jlat ) ) --nnodes; + if ( region.lat_end[jlat] >= rg.nx( jlat ) ) + --nnodes; } } ATLAS_ASSERT( nnodes >= nnewnodes ); @@ -784,7 +830,9 @@ void StructuredMeshGenerator::generate_mesh( const StructuredGrid& rg, const std } else { for ( idx_t jlat = 0; jlat < rg.ny(); ++jlat ) { - if ( rg.nx( jlat ) > 0 ) { periodic_glb.at( jlat ) = offset_glb.at( jlat ) + rg.nx( jlat ) - 1; } + if ( rg.nx( jlat ) > 0 ) { + periodic_glb.at( jlat ) = offset_glb.at( jlat ) + rg.nx( jlat ) - 1; + } } } int max_glb_idx = n; @@ -883,7 +931,8 @@ void StructuredMeshGenerator::generate_mesh( const StructuredGrid& rg, const std double x = rg.x( jlon, jlat ); // std::cout << "jlat = " << jlat << "; jlon = " << jlon << "; x = " << // x << std::endl; - if ( stagger && ( jlat + 1 ) % 2 == 0 ) x += 180. / static_cast( rg.nx( jlat ) ); + if ( stagger && ( jlat + 1 ) % 2 == 0 ) + x += 180. / static_cast( rg.nx( jlat ) ); xy( inode, XX ) = x; xy( inode, YY ) = y; @@ -919,7 +968,8 @@ void StructuredMeshGenerator::generate_mesh( const StructuredGrid& rg, const std idx_t inode = node_numbering.at( jnode ); // int inode_left = node_numbering.at(jnode-1); double x = rg.x( rg.nx( jlat ), jlat ); - if ( stagger && ( jlat + 1 ) % 2 == 0 ) x += 180. / static_cast( rg.nx( jlat ) ); + if ( stagger && ( jlat + 1 ) % 2 == 0 ) + x += 180. / static_cast( rg.nx( jlat ) ); xy( inode, XX ) = x; xy( inode, YY ) = y; @@ -1046,8 +1096,10 @@ void StructuredMeshGenerator::generate_mesh( const StructuredGrid& rg, const std quad_nodes[3] = node_numbering.at( offset_loc.at( ilatN ) + elem( 3 ) - region.lat_begin.at( jlatN ) ); if ( three_dimensional && periodic_east_west ) { - if ( elem( 2 ) == rg.nx( jlatS ) ) quad_nodes[2] = node_numbering.at( offset_loc.at( ilatS ) ); - if ( elem( 3 ) == rg.nx( jlatN ) ) quad_nodes[3] = node_numbering.at( offset_loc.at( ilatN ) ); + if ( elem( 2 ) == rg.nx( jlatS ) ) + quad_nodes[2] = node_numbering.at( offset_loc.at( ilatS ) ); + if ( elem( 3 ) == rg.nx( jlatN ) ) + quad_nodes[3] = node_numbering.at( offset_loc.at( ilatN ) ); } jcell = quad_begin + jquad++; @@ -1066,8 +1118,10 @@ void StructuredMeshGenerator::generate_mesh( const StructuredGrid& rg, const std triag_nodes[2] = node_numbering.at( offset_loc.at( ilatS ) + elem( 2 ) - region.lat_begin.at( jlatS ) ); if ( three_dimensional && periodic_east_west ) { - if ( elem( 0 ) == rg.nx( jlatN ) ) triag_nodes[0] = node_numbering.at( offset_loc.at( ilatN ) ); - if ( elem( 2 ) == rg.nx( jlatS ) ) triag_nodes[2] = node_numbering.at( offset_loc.at( ilatS ) ); + if ( elem( 0 ) == rg.nx( jlatN ) ) + triag_nodes[0] = node_numbering.at( offset_loc.at( ilatN ) ); + if ( elem( 2 ) == rg.nx( jlatS ) ) + triag_nodes[2] = node_numbering.at( offset_loc.at( ilatS ) ); } } else // This is a triangle pointing down @@ -1079,8 +1133,10 @@ void StructuredMeshGenerator::generate_mesh( const StructuredGrid& rg, const std triag_nodes[2] = node_numbering.at( offset_loc.at( ilatN ) + elem( 3 ) - region.lat_begin.at( jlatN ) ); if ( three_dimensional && periodic_east_west ) { - if ( elem( 1 ) == rg.nx( jlatS ) ) triag_nodes[1] = node_numbering.at( offset_loc.at( ilatS ) ); - if ( elem( 3 ) == rg.nx( jlatN ) ) triag_nodes[2] = node_numbering.at( offset_loc.at( ilatN ) ); + if ( elem( 1 ) == rg.nx( jlatS ) ) + triag_nodes[1] = node_numbering.at( offset_loc.at( ilatS ) ); + if ( elem( 3 ) == rg.nx( jlatN ) ) + triag_nodes[2] = node_numbering.at( offset_loc.at( ilatN ) ); } } jcell = triag_begin + jtriag++; @@ -1098,7 +1154,8 @@ void StructuredMeshGenerator::generate_mesh( const StructuredGrid& rg, const std for ( idx_t ip2 = 0; ip2 < nlon; ++ip2 ) { jcell = triag_begin + jtriag++; idx_t ip3 = ip2 + 1; - if ( three_dimensional && ip3 == rg.nx( 0 ) ) ip3 = 0; + if ( three_dimensional && ip3 == rg.nx( 0 ) ) + ip3 = 0; triag_nodes[0] = node_numbering.at( jnorth + ip1 ); triag_nodes[1] = node_numbering.at( offset_loc.at( ilat ) + ip2 ); triag_nodes[2] = node_numbering.at( offset_loc.at( ilat ) + ip3 ); @@ -1139,7 +1196,8 @@ void StructuredMeshGenerator::generate_mesh( const StructuredGrid& rg, const std cells_part( jcell ) = mypart; Topology::set( cells_flags( jcell ), Topology::PATCH ); - if ( jbackward == jforward + 2 ) break; + if ( jbackward == jforward + 2 ) + break; if ( forward ) { ++jforward; @@ -1202,7 +1260,8 @@ void StructuredMeshGenerator::generate_mesh( const StructuredGrid& rg, const std cells_part( jcell ) = mypart; Topology::set( cells_flags( jcell ), Topology::PATCH ); - if ( jbackward == jforward + 2 ) break; + if ( jbackward == jforward + 2 ) + break; if ( forward ) { ++jforward; diff --git a/src/atlas/numerics/fvm/Method.cc b/src/atlas/numerics/fvm/Method.cc index 76204a930..2e8dfb156 100644 --- a/src/atlas/numerics/fvm/Method.cc +++ b/src/atlas/numerics/fvm/Method.cc @@ -75,7 +75,8 @@ void Method::setup() { ATLAS_TRACE( "fvm::Method::setup " ); util::Config config; config.set( "halo", halo_.size() ); - if ( levels_ ) config.set( "levels", levels_ ); + if ( levels_ ) + config.set( "levels", levels_ ); node_columns_ = functionspace::NodeColumns( mesh(), config ); edge_columns_ = functionspace::EdgeColumns( mesh(), config ); @@ -108,7 +109,8 @@ void Method::setup() { node2edge_sign( jnode, jedge ) = 1.; else { node2edge_sign( jnode, jedge ) = -1.; - if ( is_pole_edge( iedge ) ) node2edge_sign( jnode, jedge ) = 1.; + if ( is_pole_edge( iedge ) ) + node2edge_sign( jnode, jedge ) = 1.; } } } diff --git a/src/atlas/numerics/fvm/Nabla.cc b/src/atlas/numerics/fvm/Nabla.cc index 045b5b749..e77f0d8b2 100644 --- a/src/atlas/numerics/fvm/Nabla.cc +++ b/src/atlas/numerics/fvm/Nabla.cc @@ -39,7 +39,8 @@ static NablaBuilder __fvm_nabla( "fvm" ); Nabla::Nabla( const numerics::Method& method, const eckit::Parametrisation& p ) : atlas::numerics::NablaImpl( method, p ) { fvm_ = dynamic_cast( &method ); - if ( !fvm_ ) throw_Exception( "atlas::numerics::fvm::Nabla needs a atlas::numerics::fvm::Method", Here() ); + if ( !fvm_ ) + throw_Exception( "atlas::numerics::fvm::Nabla needs a atlas::numerics::fvm::Method", Here() ); Log::debug() << "Nabla constructed for method " << fvm_->name() << " with " << fvm_->node_columns().nb_nodes_global() << " nodes total" << std::endl; fvm_->attach(); @@ -60,7 +61,8 @@ void Nabla::setup() { std::vector tmp( nedges ); idx_t c( 0 ); for ( idx_t jedge = 0; jedge < nedges; ++jedge ) { - if ( is_pole_edge( jedge ) ) tmp[c++] = jedge; + if ( is_pole_edge( jedge ) ) + tmp[c++] = jedge; } pole_edges_.clear(); pole_edges_.reserve( c ); @@ -69,7 +71,9 @@ void Nabla::setup() { } void Nabla::gradient( const Field& field, Field& grad_field ) const { - if ( field.variables() > 1 ) { return gradient_of_vector( field, grad_field ); } + if ( field.variables() > 1 ) { + return gradient_of_vector( field, grad_field ); + } else { return gradient_of_scalar( field, grad_field ); } @@ -350,7 +354,8 @@ void Nabla::curl( const Field& vector_field, Field& curl_field ) const { const idx_t nnodes = fvm_->node_columns().nb_nodes(); const idx_t nedges = fvm_->edge_columns().nb_edges(); const idx_t nlev = vector_field.levels(); - if ( curl_field.levels() != nlev ) throw_AssertionFailed( "curl field should have same number of levels", Here() ); + if ( curl_field.levels() != nlev ) + throw_AssertionFailed( "curl field should have same number of levels", Here() ); const auto vector = vector_field.levels() @@ -425,7 +430,8 @@ void Nabla::laplacian( const Field& scalar, Field& lapl ) const { Field grad( fvm_->node_columns().createField( option::name( "grad" ) | option::levels( scalar.levels() ) | option::variables( 2 ) ) ); gradient( scalar, grad ); - if ( fvm_->node_columns().halo().size() < 2 ) fvm_->node_columns().haloExchange( grad ); + if ( fvm_->node_columns().halo().size() < 2 ) + fvm_->node_columns().haloExchange( grad ); divergence( grad, lapl ); } diff --git a/src/atlas/option/Options.cc b/src/atlas/option/Options.cc index 922f9dd97..d9b2472d3 100644 --- a/src/atlas/option/Options.cc +++ b/src/atlas/option/Options.cc @@ -65,7 +65,9 @@ radius::radius( double _radius ) { } radius::radius( const std::string& key ) { - if ( key == "Earth" ) { set( "radius", util::Earth::radius() ); } + if ( key == "Earth" ) { + set( "radius", util::Earth::radius() ); + } else { ATLAS_NOTIMPLEMENTED; } diff --git a/src/atlas/output/Gmsh.cc b/src/atlas/output/Gmsh.cc index d977ebb7b..5e56bab83 100644 --- a/src/atlas/output/Gmsh.cc +++ b/src/atlas/output/Gmsh.cc @@ -51,7 +51,9 @@ GmshFileStream::GmshFileStream( const PathName& file_path, const char* mode, int else if ( std::string( mode ) == "a" ) omode = std::ios_base::app; - if ( part < 0 || mpi::comm().size() == 1 ) { std::ofstream::open( file_path.localPath(), omode ); } + if ( part < 0 || mpi::comm().size() == 1 ) { + std::ofstream::open( file_path.localPath(), omode ); + } else { if ( mpi::comm().rank() == 0 ) { PathName par_path( file_path ); @@ -122,7 +124,8 @@ std::ios_base::openmode openmode( const Gmsh::Configuration& c ) { omode = std::ios_base::out; else if ( std::string( c.openmode ) == "a" ) omode = std::ios_base::app; - if ( c.binary ) omode |= std::ios::binary; + if ( c.binary ) + omode |= std::ios::binary; return omode; } diff --git a/src/atlas/output/Output.cc b/src/atlas/output/Output.cc index 8837ad2e6..c9d5e7f6a 100644 --- a/src/atlas/output/Output.cc +++ b/src/atlas/output/Output.cc @@ -78,7 +78,9 @@ OutputFactory::OutputFactory( const std::string& name ) : name_( name ) { pthread_once( &once, init ); eckit::AutoLock lock( local_mutex ); - if ( m->find( name ) != m->end() ) { throw_Exception( "Duplicate OutputFactory entry " + name ); } + if ( m->find( name ) != m->end() ) { + throw_Exception( "Duplicate OutputFactory entry " + name ); + } ( *m )[name] = this; } diff --git a/src/atlas/output/detail/GmshIO.cc b/src/atlas/output/detail/GmshIO.cc index 7c2874301..45bdedf32 100644 --- a/src/atlas/output/detail/GmshIO.cc +++ b/src/atlas/output/detail/GmshIO.cc @@ -54,7 +54,9 @@ class GmshFile : public std::ofstream { int part = static_cast( mpi::comm().rank() ) ) { PathName par_path( file_path ); int mpi_size = static_cast( mpi::comm().size() ); - if ( atlas::mpi::comm().size() == 1 || part == -1 ) { std::ofstream::open( par_path.localPath(), mode ); } + if ( atlas::mpi::comm().size() == 1 || part == -1 ) { + std::ofstream::open( par_path.localPath(), mode ); + } else { if ( atlas::mpi::comm().rank() == 0 ) { PathName par_path( file_path ); @@ -108,13 +110,17 @@ template array::LocalView make_level_view( const Field& field, int ndata, int jlev ) { using namespace array; if ( field.levels() ) { - if ( field.variables() ) { return make_view( field ).slice( Range::to( ndata ), jlev, Range::all() ); } + if ( field.variables() ) { + return make_view( field ).slice( Range::to( ndata ), jlev, Range::all() ); + } else { return make_view( field ).slice( Range::to( ndata ), jlev, Range::dummy() ); } } else { - if ( field.variables() ) { return make_view( field ).slice( Range::to( ndata ), Range::all() ); } + if ( field.variables() ) { + return make_view( field ).slice( Range::to( ndata ), Range::all() ); + } else { return make_view( field ).slice( Range::to( ndata ), Range::dummy() ); } @@ -318,7 +324,9 @@ void write_field_nodes( const Metadata& gmsh_options, const functionspace::Struc int jlev = lev[ilev]; char field_lev[6] = {0, 0, 0, 0, 0, 0}; - if ( field.levels() ) { print_field_lev( field_lev, jlev ); } + if ( field.levels() ) { + print_field_lev( field_lev, jlev ); + } out << "$NodeData\n"; out << "1\n"; @@ -510,9 +518,12 @@ Mesh GmshIO::read( const PathName& file_path ) const { namespace { mesh::ElementType* make_element_type( int type ) { - if ( type == QUAD ) return new mesh::temporary::Quadrilateral(); - if ( type == TRIAG ) return new mesh::temporary::Triangle(); - if ( type == LINE ) return new mesh::temporary::Line(); + if ( type == QUAD ) + return new mesh::temporary::Quadrilateral(); + if ( type == TRIAG ) + return new mesh::temporary::Triangle(); + if ( type == LINE ) + return new mesh::temporary::Line(); throw_Exception( "Element type not supported", Here() ); } } // namespace @@ -520,7 +531,8 @@ mesh::ElementType* make_element_type( int type ) { void GmshIO::read( const PathName& file_path, Mesh& mesh ) const { std::ifstream file; file.open( file_path.localPath(), std::ios::in | std::ios::binary ); - if ( !file.is_open() ) throw_CantOpenFile( file_path ); + if ( !file.is_open() ) + throw_CantOpenFile( file_path ); std::string line; @@ -752,7 +764,8 @@ void GmshIO::write( const Mesh& mesh, const PathName& file_path ) const { bool binary = !options.get( "ascii" ); openmode mode = std::ios::out; - if ( binary ) mode = std::ios::out | std::ios::binary; + if ( binary ) + mode = std::ios::out | std::ios::binary; GmshFile file( file_path, mode, part ); // Header @@ -780,15 +793,18 @@ void GmshIO::write( const Mesh& mesh, const PathName& file_path ) const { file << g << " " << xyz[XX] << " " << xyz[YY] << " " << xyz[ZZ] << "\n"; } } - if ( binary ) file << "\n"; + if ( binary ) + file << "\n"; file << "$EndNodes\n"; // Elements file << "$Elements\n"; { std::vector grouped_elements; - if ( options.get( "elements" ) ) grouped_elements.push_back( &mesh.cells() ); - if ( options.get( "edges" ) ) grouped_elements.push_back( &mesh.edges() ); + if ( options.get( "elements" ) ) + grouped_elements.push_back( &mesh.cells() ); + if ( options.get( "edges" ) ) + grouped_elements.push_back( &mesh.edges() ); idx_t nb_elements( 0 ); for ( const mesh::HybridElements* hybrid : grouped_elements ) { @@ -799,12 +815,16 @@ void GmshIO::write( const Mesh& mesh, const PathName& file_path ) const { return mesh::Nodes::Topology::check( hybrid_flags( e ), mesh::Nodes::Topology::PATCH ); }; auto exclude = [&]( idx_t e ) { - if ( !include_ghost && hybrid_halo( e ) ) return true; - if ( !include_patch && hybrid_patch( e ) ) return true; + if ( !include_ghost && hybrid_halo( e ) ) + return true; + if ( !include_patch && hybrid_patch( e ) ) + return true; return false; }; for ( idx_t e = 0; e < hybrid->size(); ++e ) { - if ( exclude( e ) ) { --nb_elements; } + if ( exclude( e ) ) { + --nb_elements; + } } } @@ -834,7 +854,8 @@ void GmshIO::write( const Mesh& mesh, const PathName& file_path ) const { idx_t nb_elems = elements.size(); if ( !include_ghost ) { for ( idx_t elem = 0; elem < elements.size(); ++elem ) { - if ( elems_halo( elem ) ) --nb_elems; + if ( elems_halo( elem ) ) + --nb_elems; } } @@ -875,7 +896,8 @@ void GmshIO::write( const Mesh& mesh, const PathName& file_path ) const { } } } - if ( binary ) file << "\n"; + if ( binary ) + file << "\n"; file << "$EndElements\n"; file << std::flush; @@ -973,12 +995,15 @@ void GmshIO::write_delegate( const FieldSet& fieldset, const functionspace::Node const PathName& file_path, openmode mode ) const { bool is_new_file = ( mode != std::ios_base::app || !file_path.exists() ); bool binary( !options.get( "ascii" ) ); - if ( binary ) mode |= std::ios_base::binary; + if ( binary ) + mode |= std::ios_base::binary; bool gather = options.has( "gather" ) ? options.get( "gather" ) : false; GmshFile file( file_path, mode, gather ? -1 : int( atlas::mpi::comm().rank() ) ); // Header - if ( is_new_file ) { write_header_ascii( file ); } + if ( is_new_file ) { + write_header_ascii( file ); + } // field::Fields for ( idx_t field_idx = 0; field_idx < fieldset.size(); ++field_idx ) { @@ -1010,14 +1035,16 @@ void GmshIO::write_delegate( const FieldSet& fieldset, const functionspace::Stru bool is_new_file = ( mode != std::ios_base::app || !file_path.exists() ); bool binary( !options.get( "ascii" ) ); - if ( binary ) mode |= std::ios_base::binary; + if ( binary ) + mode |= std::ios_base::binary; bool gather = options.has( "gather" ) ? options.get( "gather" ) : false; GmshFile file( file_path, mode, gather ? -1 : int( atlas::mpi::comm().rank() ) ); // Header - if ( is_new_file ) write_header_ascii( file ); + if ( is_new_file ) + write_header_ascii( file ); // field::Fields for ( idx_t field_idx = 0; field_idx < fieldset.size(); ++field_idx ) { diff --git a/src/atlas/output/detail/PointCloudIO.cc b/src/atlas/output/detail/PointCloudIO.cc index d5b64d2ee..9653a819e 100644 --- a/src/atlas/output/detail/PointCloudIO.cc +++ b/src/atlas/output/detail/PointCloudIO.cc @@ -43,7 +43,8 @@ std::string sanitize_field_name( const std::string& s ) { std::replace_if( r.begin(), r.end(), ::isspace, '_' ); r.erase( r.find_last_not_of( '_' ) + 1 ); r.erase( 0, r.find_first_not_of( '_' ) ); - if ( !r.length() ) r = "_"; + if ( !r.length() ) + r = "_"; return r; } @@ -70,7 +71,8 @@ Mesh PointCloudIO::read( const eckit::PathName& path, std::vector& // open file and read all of header & data std::ifstream f( path.asString().c_str() ); - if ( !f.is_open() ) throw_CantOpenFile( path.asString() ); + if ( !f.is_open() ) + throw_CantOpenFile( path.asString() ); // header, part 1: // determine number of rows/columns @@ -85,8 +87,10 @@ Mesh PointCloudIO::read( const eckit::PathName& path, std::vector& << ")"; throw_Exception( errmsg.str(), Here() ); } - if ( nb_pts == 0 ) throw_AssertionFailed( msg + " invalid number of points (failed: nb_pts>0)" ); - if ( nb_columns < 2 ) throw_AssertionFailed( msg + " invalid number of columns (failed: nb_columns>=2)" ); + if ( nb_pts == 0 ) + throw_AssertionFailed( msg + " invalid number of points (failed: nb_pts>0)" ); + if ( nb_columns < 2 ) + throw_AssertionFailed( msg + " invalid number of columns (failed: nb_columns>=2)" ); mesh.nodes().resize( static_cast( nb_pts ) ); @@ -172,7 +176,8 @@ void PointCloudIO::write( const eckit::PathName& path, const Mesh& mesh ) { const mesh::Nodes& nodes = mesh.nodes(); const array::ArrayView lonlat = array::make_view( nodes.lonlat() ); - if ( !lonlat.size() ) throw_Exception( msg + "invalid number of points (failed: nb_pts>0)" ); + if ( !lonlat.size() ) + throw_Exception( msg + "invalid number of points (failed: nb_pts>0)" ); // get the fields (sanitized) names and values // (bypasses fields ("lonlat"|"lonlat") as shape(1)!=1) @@ -190,7 +195,8 @@ void PointCloudIO::write( const eckit::PathName& path, const Mesh& mesh ) { } std::ofstream f( path.asString().c_str() ); - if ( !f.is_open() ) throw_CantOpenFile( path.asString() ); + if ( !f.is_open() ) + throw_CantOpenFile( path.asString() ); const size_t Npts = lonlat.shape( 0 ); const size_t Nfld = vfvalues.size(); @@ -225,7 +231,8 @@ void PointCloudIO::write( const eckit::PathName& path, const FieldSet& fieldset, ATLAS_ASSERT( fieldset.size() ); array::ArrayView lonlat = array::make_view( function_space.nodes().xy() ); - if ( !lonlat.size() ) throw_Exception( msg + "invalid number of points (failed: nb_pts>0)" ); + if ( !lonlat.size() ) + throw_Exception( msg + "invalid number of points (failed: nb_pts>0)" ); // get the fields (sanitized) names and values // (bypasses fields ("lonlat"|"lonlat") as shape(1)!=1) @@ -242,7 +249,8 @@ void PointCloudIO::write( const eckit::PathName& path, const FieldSet& fieldset, } std::ofstream f( path.asString().c_str() ); - if ( !f.is_open() ) throw_CantOpenFile( path.asString() ); + if ( !f.is_open() ) + throw_CantOpenFile( path.asString() ); const size_t Npts = lonlat.shape( 0 ), Nfld = vfvalues.size(); // header @@ -268,7 +276,8 @@ void PointCloudIO::write( const eckit::PathName& path, const std::vector const std::string msg( "PointCloudIO::write: " ); const size_t Npts( lon.size() ), Nfld( vfvalues.size() ); - if ( Npts != lat.size() ) throw_Exception( msg + "number of points inconsistent (failed: #lon == #lat)" ); + if ( Npts != lat.size() ) + throw_Exception( msg + "number of points inconsistent (failed: #lon == #lat)" ); if ( Nfld != vfnames.size() ) throw_Exception( msg + "number of fields inconsistent (failed: #vfvalues == #vfnames)" ); for ( size_t j = 0; j < Nfld; ++j ) @@ -296,7 +306,8 @@ void PointCloudIO::write( const eckit::PathName& path, const std::vector "#lon == #lat == #*vfvalues[])" ); std::ofstream f( path.asString().c_str() ); - if ( !f.is_open() ) throw_CantOpenFile( path.asString() ); + if ( !f.is_open() ) + throw_CantOpenFile( path.asString() ); // header f << "PointCloudIO\t" << Npts << '\t' << ( 2 + Nfld ) << "\tlon\tlat"; @@ -323,12 +334,16 @@ void PointCloudIO::write( const eckit::PathName& path, const int& nb_pts, const const std::string msg( "PointCloudIO::write: " ); const size_t Npts( nb_pts > 0 ? nb_pts : 0 ), Nfld( nb_fld > 0 && afvalues && afnames ? nb_fld : 0 ); - if ( !Npts ) throw_Exception( msg + "invalid number of points (nb_nodes)" ); - if ( !lon ) throw_Exception( msg + "invalid array describing longitude (lon)" ); - if ( !lat ) throw_Exception( msg + "invalid array describing latitude (lat)" ); + if ( !Npts ) + throw_Exception( msg + "invalid number of points (nb_nodes)" ); + if ( !lon ) + throw_Exception( msg + "invalid array describing longitude (lon)" ); + if ( !lat ) + throw_Exception( msg + "invalid array describing latitude (lat)" ); std::ofstream f( path.asString().c_str() ); - if ( !f.is_open() ) throw_CantOpenFile( path.asString() ); + if ( !f.is_open() ) + throw_CantOpenFile( path.asString() ); // header f << "PointCloudIO\t" << Npts << '\t' << ( 2 + Nfld ) << "\tlon\tlat"; diff --git a/src/atlas/parallel/Checksum.h b/src/atlas/parallel/Checksum.h index 3fb0c27b8..95b61b657 100644 --- a/src/atlas/parallel/Checksum.h +++ b/src/atlas/parallel/Checksum.h @@ -84,7 +84,9 @@ std::string Checksum::execute( const DATA_TYPE data[], const int var_strides[], const int var_rank ) const { size_t root = 0; - if ( !is_setup_ ) { throw_Exception( "Checksum was not setup", Here() ); } + if ( !is_setup_ ) { + throw_Exception( "Checksum was not setup", Here() ); + } std::vector local_checksums( parsize_ ); int var_size = var_extents[0] * var_strides[0]; diff --git a/src/atlas/parallel/GatherScatter.cc b/src/atlas/parallel/GatherScatter.cc index 701ea53d0..d3d46a76a 100644 --- a/src/atlas/parallel/GatherScatter.cc +++ b/src/atlas/parallel/GatherScatter.cc @@ -34,8 +34,10 @@ struct IsGhostPoint { } bool operator()( idx_t idx ) { - if ( part_[idx] != mypart_ ) return true; - if ( ridx_[idx] != base_ + idx ) return true; + if ( part_[idx] != mypart_ ) + return true; + if ( ridx_[idx] != base_ + idx ) + return true; return false; } int mypart_; @@ -153,7 +155,8 @@ void GatherScatter::setup( const int part[], const idx_t remote_idx[], const int idx_t jproc = node.p; glbmap_[glbdispls_[jproc] + idx[jproc]] = n++; - if ( jproc == myproc ) locmap_[idx[jproc]] = node.i; + if ( jproc == myproc ) + locmap_[idx[jproc]] = node.i; ++idx[jproc]; } diff --git a/src/atlas/parallel/GatherScatter.h b/src/atlas/parallel/GatherScatter.h index 1191a1d76..74731736d 100644 --- a/src/atlas/parallel/GatherScatter.h +++ b/src/atlas/parallel/GatherScatter.h @@ -224,7 +224,9 @@ class GatherScatter : public util::Object { template void GatherScatter::gather( parallel::Field lfields[], parallel::Field gfields[], idx_t nb_fields, const idx_t root ) const { - if ( !is_setup_ ) { throw_Exception( "GatherScatter was not setup", Here() ); } + if ( !is_setup_ ) { + throw_Exception( "GatherScatter was not setup", Here() ); + } for ( idx_t jfield = 0; jfield < nb_fields; ++jfield ) { const idx_t lvar_size = @@ -254,7 +256,8 @@ void GatherScatter::gather( parallel::Field lfields[], parallel ATLAS_TRACE_MPI( GATHER ) { mpi::comm().gatherv( loc_buffer, glb_buffer, glb_counts, glb_displs, root ); } /// Unpack - if ( myproc == root ) unpack_recv_buffer( glbmap_, glb_buffer.data(), gfields[jfield] ); + if ( myproc == root ) + unpack_recv_buffer( glbmap_, glb_buffer.data(), gfields[jfield] ); } } @@ -270,7 +273,9 @@ void GatherScatter::gather( const DATA_TYPE ldata[], const idx_t lvar_strides[], template void GatherScatter::scatter( parallel::Field gfields[], parallel::Field lfields[], const idx_t nb_fields, const idx_t root ) const { - if ( !is_setup_ ) { throw_Exception( "GatherScatter was not setup", Here() ); } + if ( !is_setup_ ) { + throw_Exception( "GatherScatter was not setup", Here() ); + } for ( idx_t jfield = 0; jfield < nb_fields; ++jfield ) { const int lvar_size = @@ -292,7 +297,8 @@ void GatherScatter::scatter( parallel::Field gfields[], paralle } /// Pack - if ( myproc == root ) pack_send_buffer( gfields[jfield], glbmap_, glb_buffer.data() ); + if ( myproc == root ) + pack_send_buffer( gfields[jfield], glbmap_, glb_buffer.data() ); /// Scatter diff --git a/src/atlas/parallel/HaloExchange.cc b/src/atlas/parallel/HaloExchange.cc index 48397f91c..9766b6ef0 100644 --- a/src/atlas/parallel/HaloExchange.cc +++ b/src/atlas/parallel/HaloExchange.cc @@ -33,8 +33,10 @@ struct IsGhostPoint { } bool operator()( idx_t idx ) { - if ( part_[idx] != mypart_ ) return true; - if ( ridx_[idx] != base_ + idx ) return true; + if ( part_[idx] != mypart_ ) + return true; + if ( ridx_[idx] != base_ + idx ) + return true; return false; } int mypart_; @@ -74,7 +76,8 @@ void HaloExchange::setup( const int part[], const idx_t remote_idx[], const int IsGhostPoint is_ghost( part, remote_idx, base, parsize_ ); for ( int jj = 0; jj < parsize_; ++jj ) { - if ( is_ghost( jj ) ) ++recvcounts_[part[jj]]; + if ( is_ghost( jj ) ) + ++recvcounts_[part[jj]]; } recvcnt_ = std::accumulate( recvcounts_.begin(), recvcounts_.end(), 0 ); diff --git a/src/atlas/parallel/HaloExchange.h b/src/atlas/parallel/HaloExchange.h index 48a46fd62..5120d7d44 100644 --- a/src/atlas/parallel/HaloExchange.h +++ b/src/atlas/parallel/HaloExchange.h @@ -104,7 +104,9 @@ class HaloExchange : public util::Object { template void HaloExchange::execute( array::Array& field, bool on_device ) const { - if ( !is_setup_ ) { throw_Exception( "HaloExchange was not setup", Here() ); } + if ( !is_setup_ ) { + throw_Exception( "HaloExchange was not setup", Here() ); + } ATLAS_TRACE( "HaloExchange", {"halo-exchange"} ); @@ -161,7 +163,9 @@ void HaloExchange::execute( array::Array& field, bool on_device ) const { /// Wait for receiving to finish ATLAS_TRACE_MPI( WAIT, "mpi-wait receive" ) { for ( int jproc = 0; jproc < nproc; ++jproc ) { - if ( recvcounts_[jproc] > 0 ) { mpi::comm().wait( recv_req[jproc] ); } + if ( recvcounts_[jproc] > 0 ) { + mpi::comm().wait( recv_req[jproc] ); + } } } @@ -171,7 +175,9 @@ void HaloExchange::execute( array::Array& field, bool on_device ) const { /// Wait for sending to finish ATLAS_TRACE_MPI( WAIT, "mpi-wait send" ) { for ( int jproc = 0; jproc < nproc; ++jproc ) { - if ( sendcounts_[jproc] > 0 ) { mpi::comm().wait( send_req[jproc] ); } + if ( sendcounts_[jproc] > 0 ) { + mpi::comm().wait( send_req[jproc] ); + } } } } diff --git a/src/atlas/parallel/omp/omp.cc b/src/atlas/parallel/omp/omp.cc index fa409d3de..f00db559d 100644 --- a/src/atlas/parallel/omp/omp.cc +++ b/src/atlas/parallel/omp/omp.cc @@ -42,67 +42,77 @@ extern "C" { void atlas_omp_set_num_threads( int num_threads ) { #if ATLAS_HAVE_OMP - if ( omp_set_num_threads ) omp_set_num_threads( num_threads ); + if ( omp_set_num_threads ) + omp_set_num_threads( num_threads ); #endif } int atlas_omp_get_num_threads( void ) { #if ATLAS_HAVE_OMP - if ( omp_get_num_threads ) return omp_get_num_threads(); + if ( omp_get_num_threads ) + return omp_get_num_threads(); #endif return 1; } int atlas_omp_get_max_threads( void ) { #if ATLAS_HAVE_OMP - if ( omp_get_max_threads ) return omp_get_max_threads(); + if ( omp_get_max_threads ) + return omp_get_max_threads(); #endif return 1; } int atlas_omp_get_thread_num( void ) { #if ATLAS_HAVE_OMP - if ( omp_get_thread_num ) return omp_get_thread_num(); + if ( omp_get_thread_num ) + return omp_get_thread_num(); #endif return 0; } int atlas_omp_get_num_procs( void ) { #if ATLAS_HAVE_OMP - if ( omp_get_num_procs ) return omp_get_num_procs(); + if ( omp_get_num_procs ) + return omp_get_num_procs(); #endif return 1; } int atlas_omp_in_parallel( void ) { #if ATLAS_HAVE_OMP - if ( omp_in_parallel ) return omp_in_parallel(); + if ( omp_in_parallel ) + return omp_in_parallel(); #endif return 0; } void atlas_omp_set_dynamic( int dynamic_threads ) { #if ATLAS_HAVE_OMP - if ( omp_set_dynamic ) omp_set_dynamic( dynamic_threads ); + if ( omp_set_dynamic ) + omp_set_dynamic( dynamic_threads ); #endif } int atlas_omp_get_dynamic( void ) { #if ATLAS_HAVE_OMP - if ( omp_get_dynamic ) return omp_get_dynamic(); + if ( omp_get_dynamic ) + return omp_get_dynamic(); #endif return 0; } void atlas_omp_set_nested( int nested ) { #if ATLAS_HAVE_OMP - if ( omp_set_nested ) omp_set_nested( nested ); + if ( omp_set_nested ) + omp_set_nested( nested ); #endif } int atlas_omp_get_nested( void ) { #if ATLAS_HAVE_OMP - if ( omp_get_nested ) return omp_get_nested(); + if ( omp_get_nested ) + return omp_get_nested(); #endif return 0; } diff --git a/src/atlas/projection/detail/LambertProjection.cc b/src/atlas/projection/detail/LambertProjection.cc index f579e204f..744819f87 100644 --- a/src/atlas/projection/detail/LambertProjection.cc +++ b/src/atlas/projection/detail/LambertProjection.cc @@ -44,12 +44,16 @@ namespace detail { // constructors LambertProjection::LambertProjection( const eckit::Parametrisation& params ) { // check presence of radius - if ( !params.get( "radius", radius_ ) ) radius_ = util::Earth::radius(); + if ( !params.get( "radius", radius_ ) ) + radius_ = util::Earth::radius(); // check presence of lat1 and lat2 - if ( !params.get( "latitude1", lat1_ ) ) throw_Exception( "latitude1 missing in Params", Here() ); - if ( !params.get( "latitude2", lat2_ ) ) lat2_ = lat1_; + if ( !params.get( "latitude1", lat1_ ) ) + throw_Exception( "latitude1 missing in Params", Here() ); + if ( !params.get( "latitude2", lat2_ ) ) + lat2_ = lat1_; // check presence of lon0 - if ( !params.get( "longitude0", lon0_ ) ) throw_Exception( "longitude0 missing in Params", Here() ); + if ( !params.get( "longitude0", lon0_ ) ) + throw_Exception( "longitude0 missing in Params", Here() ); setup(); } @@ -57,7 +61,9 @@ LambertProjection::LambertProjection( const eckit::Parametrisation& params ) { void LambertProjection::setup() { // setup (derived) constants is_tangent_ = std::equal_to()( lat1_, lat2_ ); - if ( is_tangent_ ) { n_ = std::sin( D2R( lat1_ ) ); } + if ( is_tangent_ ) { + n_ = std::sin( D2R( lat1_ ) ); + } else { n_ = std::log( std::cos( D2R( lat1_ ) ) / std::cos( D2R( lat2_ ) ) ) / std::log( std::tan( D2R( 45 + lat2_ * 0.5 ) ) / std::tan( D2R( 45. + lat1_ * 0.5 ) ) ); @@ -88,7 +94,9 @@ void LambertProjection::xy2lonlat( double crd[] ) const { crd[0] = theta * inv_n_ + lon0_; // latitude - if ( rho == 0. ) { crd[1] = sign_ * 90.; } + if ( rho == 0. ) { + crd[1] = sign_ * 90.; + } else { crd[1] = 2. * R2D( std::atan( std::pow( radius_ * F_ / rho, inv_n_ ) ) ) - 90.; } @@ -101,7 +109,8 @@ LambertProjection::Spec LambertProjection::spec() const { proj_spec.set( "latitude1", lat1_ ); proj_spec.set( "latitude2", lat2_ ); proj_spec.set( "longitude0", lon0_ ); - if ( std::not_equal_to()( radius_, util::Earth::radius() ) ) proj_spec.set( "radius", radius_ ); + if ( std::not_equal_to()( radius_, util::Earth::radius() ) ) + proj_spec.set( "radius", radius_ ); return proj_spec; } diff --git a/src/atlas/projection/detail/LonLatProjection.cc b/src/atlas/projection/detail/LonLatProjection.cc index c7c306c36..09eae7c0f 100644 --- a/src/atlas/projection/detail/LonLatProjection.cc +++ b/src/atlas/projection/detail/LonLatProjection.cc @@ -48,7 +48,9 @@ RectangularLonLatDomain LonLatProjectionT::lonlatBoundingBox( const Do // 0. setup - if ( domain.global() ) { return domain; } + if ( domain.global() ) { + return domain; + } RectangularDomain rect( domain ); ATLAS_ASSERT( rect ); @@ -120,7 +122,9 @@ RectangularLonLatDomain LonLatProjectionT::lonlatBoundingBox( const Do for ( auto lon : {rect.xmin(), rect.xmax()} ) { if ( !bounds.crossesDateLine() ) { for ( auto lat : DL.latitude( lon ) ) { - if ( ( bounds.crossesDateLine( domain.contains( lon, lat ) ) ) ) { break; } + if ( ( bounds.crossesDateLine( domain.contains( lon, lat ) ) ) ) { + break; + } } } } @@ -128,7 +132,9 @@ RectangularLonLatDomain LonLatProjectionT::lonlatBoundingBox( const Do for ( auto lat : {rect.ymin(), rect.ymax()} ) { if ( !bounds.crossesDateLine() ) { for ( auto lon : DL.longitude( lat ) ) { - if ( ( bounds.crossesDateLine( domain.contains( lon, lat ) ) ) ) { break; } + if ( ( bounds.crossesDateLine( domain.contains( lon, lat ) ) ) ) { + break; + } } } } diff --git a/src/atlas/projection/detail/MercatorProjection.cc b/src/atlas/projection/detail/MercatorProjection.cc index 92602299b..37a821d92 100644 --- a/src/atlas/projection/detail/MercatorProjection.cc +++ b/src/atlas/projection/detail/MercatorProjection.cc @@ -47,9 +47,11 @@ MercatorProjectionT::MercatorProjectionT( const eckit::Parametrisation ProjectionImpl(), rotation_( params ) { // check presence of radius - if ( !params.get( "radius", radius_ ) ) radius_ = util::Earth::radius(); + if ( !params.get( "radius", radius_ ) ) + radius_ = util::Earth::radius(); // check presence of lon0 - if ( !params.get( "longitude0", lon0_ ) ) lon0_ = 0.0; + if ( !params.get( "longitude0", lon0_ ) ) + lon0_ = 0.0; inv_radius_ = 1. / radius_; } @@ -80,7 +82,9 @@ typename MercatorProjectionT::Spec MercatorProjectionT::spec Spec proj_spec; proj_spec.set( "type", static_type() ); proj_spec.set( "longitude0", lon0_ ); - if ( std::not_equal_to()( radius_, util::Earth::radius() ) ) { proj_spec.set( "radius", radius_ ); } + if ( std::not_equal_to()( radius_, util::Earth::radius() ) ) { + proj_spec.set( "radius", radius_ ); + } rotation_.spec( proj_spec ); return proj_spec; } diff --git a/src/atlas/projection/detail/ProjectionImpl.cc b/src/atlas/projection/detail/ProjectionImpl.cc index 7a9f1481b..bfee72f2b 100644 --- a/src/atlas/projection/detail/ProjectionImpl.cc +++ b/src/atlas/projection/detail/ProjectionImpl.cc @@ -108,18 +108,24 @@ ProjectionImpl::BoundLonLat::operator RectangularLonLatDomain() const { } bool ProjectionImpl::BoundLonLat::crossesDateLine( bool yes ) { - if ( ( crossesDateLine_ = crossesDateLine_ || yes ) ) { max_.lon() = min_.lon() + 360.; } + if ( ( crossesDateLine_ = crossesDateLine_ || yes ) ) { + max_.lon() = min_.lon() + 360.; + } return crossesDateLine_; } bool ProjectionImpl::BoundLonLat::includesNorthPole( bool yes ) { - if ( ( includesNorthPole_ = includesNorthPole_ || yes ) ) { max_.lat() = 90.; } + if ( ( includesNorthPole_ = includesNorthPole_ || yes ) ) { + max_.lat() = 90.; + } crossesDateLine( includesNorthPole_ ); return includesNorthPole_; } bool ProjectionImpl::BoundLonLat::includesSouthPole( bool yes ) { - if ( ( includesSouthPole_ = includesSouthPole_ || yes ) ) { min_.lat() = -90.; } + if ( ( includesSouthPole_ = includesSouthPole_ || yes ) ) { + min_.lat() = -90.; + } crossesDateLine( includesSouthPole_ ); return includesSouthPole_; } @@ -147,7 +153,9 @@ void ProjectionImpl::BoundLonLat::extend( PointLonLat p, PointLonLat eps ) { const ProjectionImpl* ProjectionImpl::create( const eckit::Parametrisation& p ) { std::string projectionType; - if ( p.get( "type", projectionType ) ) { return ProjectionFactory::build( projectionType, p ); } + if ( p.get( "type", projectionType ) ) { + return ProjectionFactory::build( projectionType, p ); + } // should return error here throw_Exception( "type missing in Params", Here() ); @@ -159,7 +167,9 @@ RectangularLonLatDomain ProjectionImpl::lonlatBoundingBox( const Domain& domain // 0. setup - if ( domain.global() ) { return domain; } + if ( domain.global() ) { + return domain; + } RectangularDomain rect( domain ); ATLAS_ASSERT( rect ); diff --git a/src/atlas/projection/detail/SchmidtProjection.cc b/src/atlas/projection/detail/SchmidtProjection.cc index 186ce9adc..8b9240063 100644 --- a/src/atlas/projection/detail/SchmidtProjection.cc +++ b/src/atlas/projection/detail/SchmidtProjection.cc @@ -37,7 +37,8 @@ template SchmidtProjectionT::SchmidtProjectionT( const eckit::Parametrisation& params ) : ProjectionImpl(), rotation_( params ) { - if ( !params.get( "stretching_factor", c_ ) ) throw_Exception( "stretching_factor missing in Params", Here() ); + if ( !params.get( "stretching_factor", c_ ) ) + throw_Exception( "stretching_factor missing in Params", Here() ); } // constructor diff --git a/src/atlas/runtime/AtlasTool.cc b/src/atlas/runtime/AtlasTool.cc index 8c08cdcfb..a63bbebed 100644 --- a/src/atlas/runtime/AtlasTool.cc +++ b/src/atlas/runtime/AtlasTool.cc @@ -51,7 +51,8 @@ void debug_addTarget( eckit::LogTarget* target ) { lib.debugChannel().addTarget( new eckit::PrefixTarget( debug_prefix( libname ), target ) ); } } - if ( eckit::Log::debug() ) eckit::Log::debug().addTarget( target ); + if ( eckit::Log::debug() ) + eckit::Log::debug().addTarget( target ); } void debug_setTarget( eckit::LogTarget* target ) { @@ -61,29 +62,39 @@ void debug_setTarget( eckit::LogTarget* target ) { lib.debugChannel().setTarget( new eckit::PrefixTarget( debug_prefix( libname ), target ) ); } } - if ( eckit::Log::debug() ) eckit::Log::debug().setTarget( target ); + if ( eckit::Log::debug() ) + eckit::Log::debug().setTarget( target ); } void debug_reset() { for ( std::string libname : eckit::system::Library::list() ) { const eckit::system::Library& lib = eckit::system::Library::lookup( libname ); - if ( lib.debug() ) { lib.debugChannel().reset(); } + if ( lib.debug() ) { + lib.debugChannel().reset(); + } } - if ( eckit::Log::debug() ) eckit::Log::debug().reset(); + if ( eckit::Log::debug() ) + eckit::Log::debug().reset(); } bool getEnv( const std::string& env, bool default_value ) { - if ( ::getenv( env.c_str() ) ) { return eckit::Translator()( ::getenv( env.c_str() ) ); } + if ( ::getenv( env.c_str() ) ) { + return eckit::Translator()( ::getenv( env.c_str() ) ); + } return default_value; } int getEnv( const std::string& env, int default_value ) { - if ( ::getenv( env.c_str() ) ) { return eckit::Translator()( ::getenv( env.c_str() ) ); } + if ( ::getenv( env.c_str() ) ) { + return eckit::Translator()( ::getenv( env.c_str() ) ); + } return default_value; } std::string getEnv( const std::string& env, const std::string& default_value ) { - if ( ::getenv( env.c_str() ) ) { return ::getenv( env.c_str() ); } + if ( ::getenv( env.c_str() ) ) { + return ::getenv( env.c_str() ); + } return default_value; } @@ -205,7 +216,8 @@ void atlas::AtlasTool::add_option( eckit::option::Option* option ) { void atlas::AtlasTool::help( std::ostream& out ) { out << "NAME\n" << indent() << name(); std::string brief = briefDescription(); - if ( brief.size() ) out << " - " << brief << '\n'; + if ( brief.size() ) + out << " - " << brief << '\n'; std::string usg = usage(); if ( usg.size() ) { @@ -228,7 +240,8 @@ void atlas::AtlasTool::help( std::ostream& out ) { bool atlas::AtlasTool::handle_help() { for ( int i = 1; i < argc(); ++i ) { if ( argv( i ) == "--help" || argv( i ) == "-h" ) { - if ( taskID() == 0 ) help( std::cout ); + if ( taskID() == 0 ) + help( std::cout ); return true; } } @@ -239,7 +252,9 @@ atlas::AtlasTool::AtlasTool( int argc, char** argv ) : eckit::Tool( argc, argv ) eckit::LibEcKit::instance().setAbortHandler( [] { std::cerr << "[" << atlas::mpi::comm().rank() << "] " << "calling MPI_Abort"; - if ( not use_logfile and mpi::comm().size() > 1 ) { std::cerr << ", logfile: " << logfile_name; } + if ( not use_logfile and mpi::comm().size() > 1 ) { + std::cerr << ", logfile: " << logfile_name; + } std::cerr << std::endl; std::this_thread::sleep_for( std::chrono::milliseconds( 3000 ) ); atlas::mpi::comm().abort( 1 ); @@ -257,10 +272,12 @@ atlas::AtlasTool::AtlasTool( int argc, char** argv ) : eckit::Tool( argc, argv ) int atlas::AtlasTool::start() { try { - if ( handle_help() ) return success(); + if ( handle_help() ) + return success(); if ( argc() - 1 < minimumPositionalArguments() ) { - if ( taskID() == 0 ) std::cout << "Usage: " << usage() << std::endl; + if ( taskID() == 0 ) + std::cout << "Usage: " << usage() << std::endl; return failed(); } Options opts = options_; @@ -314,23 +331,32 @@ void atlas::AtlasTool::setupLogging() { eckit::LogTarget* logfile = new eckit::FileTarget( logfile_name ); if ( int( mpi::comm().rank() ) == log_rank ) { - if ( Log::info() ) Log::info().addTarget( logfile ); - if ( Log::warning() ) Log::warning().addTarget( logfile ); - if ( Log::error() ) Log::error().addTarget( logfile ); + if ( Log::info() ) + Log::info().addTarget( logfile ); + if ( Log::warning() ) + Log::warning().addTarget( logfile ); + if ( Log::error() ) + Log::error().addTarget( logfile ); debug_addTarget( logfile ); } else { - if ( Log::info() ) Log::info().setTarget( logfile ); - if ( Log::warning() ) Log::warning().setTarget( logfile ); - if ( Log::error() ) Log::error().setTarget( logfile ); + if ( Log::info() ) + Log::info().setTarget( logfile ); + if ( Log::warning() ) + Log::warning().setTarget( logfile ); + if ( Log::error() ) + Log::error().setTarget( logfile ); debug_setTarget( logfile ); } } else { if ( int( mpi::comm().rank() ) != log_rank ) { - if ( Log::info() ) Log::info().reset(); - if ( Log::warning() ) Log::warning().reset(); - if ( Log::error() ) Log::error().reset(); + if ( Log::info() ) + Log::info().reset(); + if ( Log::warning() ) + Log::warning().reset(); + if ( Log::error() ) + Log::error().reset(); debug_reset(); } } diff --git a/src/atlas/runtime/Exception.h b/src/atlas/runtime/Exception.h index 5d477fd2a..163784e96 100644 --- a/src/atlas/runtime/Exception.h +++ b/src/atlas/runtime/Exception.h @@ -35,10 +35,14 @@ namespace atlas { namespace detail { inline void Assert( bool success, const char* code, const char* file, int line, const char* func ) { - if ( not success ) { throw_AssertionFailed( code, eckit::CodeLocation( file, line, func ) ); } + if ( not success ) { + throw_AssertionFailed( code, eckit::CodeLocation( file, line, func ) ); + } } inline void Assert( bool success, const char* code, const char* msg, const char* file, int line, const char* func ) { - if ( not success ) { throw_AssertionFailed( code, msg, eckit::CodeLocation( file, line, func ) ); } + if ( not success ) { + throw_AssertionFailed( code, msg, eckit::CodeLocation( file, line, func ) ); + } } } // namespace detail } // namespace atlas diff --git a/src/atlas/runtime/trace/Barriers.cc b/src/atlas/runtime/trace/Barriers.cc index 7df95a173..a7e4b970d 100644 --- a/src/atlas/runtime/trace/Barriers.cc +++ b/src/atlas/runtime/trace/Barriers.cc @@ -42,7 +42,9 @@ class BarriersState { std::string report() const { std::stringstream out; double time = stopwatch_.elapsed(); - if ( time ) { out << "Total time spent in mpi barriers due to load imbalance : " << time << "s" << std::endl; } + if ( time ) { + out << "Total time spent in mpi barriers due to load imbalance : " << time << "s" << std::endl; + } return out.str(); } }; diff --git a/src/atlas/runtime/trace/CallStack.cc b/src/atlas/runtime/trace/CallStack.cc index cc73a7c5d..e06b6c965 100644 --- a/src/atlas/runtime/trace/CallStack.cc +++ b/src/atlas/runtime/trace/CallStack.cc @@ -27,7 +27,8 @@ void CallStack::pop_front() { } size_t CallStack::hash() const { - if ( hash_ ) return hash_; + if ( hash_ ) + return hash_; for ( auto h : stack_ ) { hash_ ^= ( h << 1 ); } diff --git a/src/atlas/runtime/trace/Logging.cc b/src/atlas/runtime/trace/Logging.cc index eec7701c1..3d4d3baf4 100644 --- a/src/atlas/runtime/trace/Logging.cc +++ b/src/atlas/runtime/trace/Logging.cc @@ -51,7 +51,8 @@ class LoggingState { void set( std::ostream& channel ) { channel_ = &channel; } void set( bool state ) { - if ( state == false ) channel_ = &empty_channel(); + if ( state == false ) + channel_ = &empty_channel(); } }; @@ -78,11 +79,13 @@ bool Logging::enabled() { } void Logging::start( const std::string& title ) { - if ( enabled() ) channel() << title << " ..." << std::endl; + if ( enabled() ) + channel() << title << " ..." << std::endl; } void Logging::stop( const std::string& title, double seconds ) { - if ( enabled() ) channel() << title << " ... done : " << seconds << "s" << std::endl; + if ( enabled() ) + channel() << title << " ... done : " << seconds << "s" << std::endl; } //----------------------------------------------------------------------------------------------------------- @@ -93,7 +96,8 @@ std::ostream& NoLogging::channel() { //----------------------------------------------------------------------------------------------------------- void LoggingResult::stop( const std::string& title, double seconds ) { - if ( enabled() ) channel() << title << " : " << seconds << "s" << std::endl; + if ( enabled() ) + channel() << title << " : " << seconds << "s" << std::endl; } //----------------------------------------------------------------------------------------------------------- diff --git a/src/atlas/runtime/trace/Nesting.h b/src/atlas/runtime/trace/Nesting.h index c2ec44fa7..14bcd20b2 100644 --- a/src/atlas/runtime/trace/Nesting.h +++ b/src/atlas/runtime/trace/Nesting.h @@ -34,11 +34,13 @@ class CurrentCallStack { } operator CallStack() const { return stack_; } CallStack& push( const CodeLocation& loc, const std::string& id ) { - if ( Control::enabled() ) stack_.push_front( loc, id ); + if ( Control::enabled() ) + stack_.push_front( loc, id ); return stack_; } void pop() { - if ( Control::enabled() ) stack_.pop_front(); + if ( Control::enabled() ) + stack_.pop_front(); } }; diff --git a/src/atlas/runtime/trace/Timings.cc b/src/atlas/runtime/trace/Timings.cc index 58e63f5eb..8d8588bcc 100644 --- a/src/atlas/runtime/trace/Timings.cc +++ b/src/atlas/runtime/trace/Timings.cc @@ -166,15 +166,20 @@ void TimingsRegistry::report( std::ostream& out, const eckit::Configuration& con std::set excluded_timers( excluded_timers_vector.begin(), excluded_timers_vector.end() ); auto excluded = [&]( size_t i ) -> bool { - if ( depth and nest_[i] > depth ) return true; + if ( depth and nest_[i] > depth ) + return true; return excluded_timers.count( i ); }; std::vector excluded_nest_stored( size() ); long excluded_nest = size(); for ( size_t j = 0; j < size(); ++j ) { - if ( nest_[j] > excluded_nest ) { excluded_timers.insert( j ); } - if ( not excluded( j ) ) { excluded_nest = nest_[j] + 1; } + if ( nest_[j] > excluded_nest ) { + excluded_timers.insert( j ); + } + if ( not excluded( j ) ) { + excluded_nest = nest_[j] + 1; + } else { excluded_nest = std::min( excluded_nest, nest_[j] ); } @@ -183,7 +188,8 @@ void TimingsRegistry::report( std::ostream& out, const eckit::Configuration& con for ( auto& label : include_back ) { auto timers = labels_[label]; for ( size_t j : timers ) { - if ( nest_[j] == excluded_nest_stored[j] ) excluded_timers.erase( j ); + if ( nest_[j] == excluded_nest_stored[j] ) + excluded_timers.erase( j ); } } @@ -205,7 +211,9 @@ void TimingsRegistry::report( std::ostream& out, const eckit::Configuration& con } } size_t max_count_length = digits( max_count ); - if ( header ) { max_count_length = std::max( std::string( "cnt" ).size(), max_count_length ); } + if ( header ) { + max_count_length = std::max( std::string( "cnt" ).size(), max_count_length ); + } size_t max_digits_before_decimal = digits_before_decimal( max_seconds ); auto print_time = [max_digits_before_decimal, decimals]( double x ) -> std::string { @@ -260,7 +268,9 @@ void TimingsRegistry::report( std::ostream& out, const eckit::Configuration& con auto next_it = next_stack.rbegin(); for ( size_t i = 0; this_it != this_stack.rend() && next_it != next_stack.rend(); ++i, ++this_it, ++next_it ) { - if ( *this_it == *next_it ) { active[i] = active[i] or false; } + if ( *this_it == *next_it ) { + active[i] = active[i] or false; + } else { active[i] = true; } diff --git a/src/atlas/runtime/trace/TraceT.h b/src/atlas/runtime/trace/TraceT.h index cc9d2abed..17c595244 100644 --- a/src/atlas/runtime/trace/TraceT.h +++ b/src/atlas/runtime/trace/TraceT.h @@ -150,7 +150,9 @@ template inline void TraceT::start() { if ( Control::enabled() ) { running_ = true; - if ( not callstack_ ) { callstack_ = CurrentCallStack::instance().push( loc_, title_ ); } + if ( not callstack_ ) { + callstack_ = CurrentCallStack::instance().push( loc_, title_ ); + } registerTimer(); Tracing::start( title_ ); barrier(); diff --git a/src/atlas/trans/Cache.cc b/src/atlas/trans/Cache.cc index 1b18c76ce..5bd96586e 100644 --- a/src/atlas/trans/Cache.cc +++ b/src/atlas/trans/Cache.cc @@ -80,11 +80,15 @@ Cache::~Cache() {} TransCache::TransCache( const Trans& trans ) : Cache( trans.get() ) {} TransCacheOwnedMemoryEntry::TransCacheOwnedMemoryEntry( size_t size ) : size_( size ) { - if ( size_ ) { data_ = std::malloc( size_ ); } + if ( size_ ) { + data_ = std::malloc( size_ ); + } } TransCacheOwnedMemoryEntry::~TransCacheOwnedMemoryEntry() { - if ( size_ ) { std::free( data_ ); } + if ( size_ ) { + std::free( data_ ); + } } } // namespace trans diff --git a/src/atlas/trans/detail/TransFactory.cc b/src/atlas/trans/detail/TransFactory.cc index dbb480e6d..bcd5c29dc 100644 --- a/src/atlas/trans/detail/TransFactory.cc +++ b/src/atlas/trans/detail/TransFactory.cc @@ -104,7 +104,9 @@ class TransBackend { } void add( const std::string& backend ) { lock_guard lock( mutex_ ); - if ( backends_.find( backend ) == backends_.end() ) { backends_[backend] = 1; } + if ( backends_.find( backend ) == backends_.end() ) { + backends_[backend] = 1; + } else { ++backends_[backend]; } @@ -112,7 +114,9 @@ class TransBackend { void remove( const std::string& backend ) { lock_guard lock( mutex_ ); --backends_[backend]; - if ( backends_[backend] == 0 ) { backends_.erase( backend ); } + if ( backends_[backend] == 0 ) { + backends_.erase( backend ); + } } void backend( const std::string& backend ) { @@ -123,7 +127,9 @@ class TransBackend { void config( const eckit::Configuration& config ) { std::string type = default_options_.getString( "type" ); default_options_ = config; - if ( not config.has( "type" ) ) { default_options_.set( "type", type ); } + if ( not config.has( "type" ) ) { + default_options_.set( "type", type ); + } } const eckit::Configuration& config() { return default_options_; } diff --git a/src/atlas/trans/ifs/LegendreCacheCreatorIFS.cc b/src/atlas/trans/ifs/LegendreCacheCreatorIFS.cc index bc42d8da1..db44fde10 100644 --- a/src/atlas/trans/ifs/LegendreCacheCreatorIFS.cc +++ b/src/atlas/trans/ifs/LegendreCacheCreatorIFS.cc @@ -58,7 +58,9 @@ std::string LegendreCacheCreatorIFS::uid() const { std::ostringstream stream; stream << "ifs-T" << truncation_ << "-"; if ( GaussianGrid( grid_ ) ) { - if ( RegularGaussianGrid( grid_ ) ) { stream << "RegularGaussianN" << GaussianGrid( grid_ ).N(); } + if ( RegularGaussianGrid( grid_ ) ) { + stream << "RegularGaussianN" << GaussianGrid( grid_ ).N(); + } else { stream << "ReducedGaussianN" << GaussianGrid( grid_ ).N() << "-PL"; stream << hash( grid_ ); @@ -66,7 +68,9 @@ std::string LegendreCacheCreatorIFS::uid() const { } else if ( RegularLonLatGrid( grid_ ) ) { auto g = RegularLonLatGrid( grid_ ); - if ( g.standard() || g.shifted() ) { stream << ( g.standard() ? "L" : "S" ) << g.nx() << "x" << g.ny(); } + if ( g.standard() || g.shifted() ) { + stream << ( g.standard() ? "L" : "S" ) << g.nx() << "x" << g.ny(); + } else { // We cannot make more assumptions on reusability for different grids stream << "grid-" << hash( grid_ ); @@ -85,10 +89,14 @@ std::string LegendreCacheCreatorIFS::uid() const { LegendreCacheCreatorIFS::~LegendreCacheCreatorIFS() {} bool LegendreCacheCreatorIFS::supported() const { - if ( GaussianGrid( grid_ ) ) { return true; } + if ( GaussianGrid( grid_ ) ) { + return true; + } else if ( RegularLonLatGrid( grid_ ) ) { auto g = RegularLonLatGrid( grid_ ); - if ( g.standard() || g.shifted() ) { return true; } + if ( g.standard() || g.shifted() ) { + return true; + } } return false; } diff --git a/src/atlas/trans/ifs/TransIFS.cc b/src/atlas/trans/ifs/TransIFS.cc index 191cc277b..28b1be16d 100644 --- a/src/atlas/trans/ifs/TransIFS.cc +++ b/src/atlas/trans/ifs/TransIFS.cc @@ -90,7 +90,8 @@ namespace { std::string fieldset_functionspace( const FieldSet& fields ) { std::string functionspace( "undefined" ); for ( idx_t jfld = 0; jfld < fields.size(); ++jfld ) { - if ( functionspace == "undefined" ) functionspace = fields[jfld].functionspace().type(); + if ( functionspace == "undefined" ) + functionspace = fields[jfld].functionspace().type(); if ( fields[jfld].functionspace().type() != functionspace ) { throw_Exception( ": fielset has fields with different functionspaces", Here() ); } @@ -368,7 +369,8 @@ struct PackNodeColumns { } void pack_3( const Field& field, idx_t components ) { const ArrayView gpfield = make_view( field ); - if ( not components ) components = gpfield.shape( 2 ); + if ( not components ) + components = gpfield.shape( 2 ); for ( idx_t jcomp = 0; jcomp < components; ++jcomp ) { for ( idx_t jlev = 0; jlev < gpfield.shape( 1 ); ++jlev ) { idx_t n = 0; @@ -525,7 +527,8 @@ struct UnpackNodeColumns { } void unpack_3( Field& field, idx_t components ) { ArrayView gpfield = make_view( field ); - if ( not components ) components = gpfield.shape( 2 ); + if ( not components ) + components = gpfield.shape( 2 ); for ( idx_t jcomp = 0; jcomp < components; ++jcomp ) { for ( idx_t jlev = 0; jlev < gpfield.shape( 1 ); ++jlev ) { idx_t n = 0; @@ -735,93 +738,109 @@ const int* atlas::trans::TransIFS::n_regions( int& size ) const { const int* atlas::trans::TransIFS::nfrstlat( int& size ) const { size = trans_->n_regions_NS; - if ( trans_->nfrstlat == nullptr ) ::trans_inquire( trans_.get(), "nfrstlat" ); + if ( trans_->nfrstlat == nullptr ) + ::trans_inquire( trans_.get(), "nfrstlat" ); return trans_->nfrstlat; } const int* atlas::trans::TransIFS::nlstlat( int& size ) const { size = trans_->n_regions_NS; - if ( trans_->nlstlat == nullptr ) ::trans_inquire( trans_.get(), "nlstlat" ); + if ( trans_->nlstlat == nullptr ) + ::trans_inquire( trans_.get(), "nlstlat" ); return trans_->nlstlat; } const int* atlas::trans::TransIFS::nptrfrstlat( int& size ) const { size = trans_->n_regions_NS; - if ( trans_->nptrfrstlat == nullptr ) ::trans_inquire( trans_.get(), "nptrfrstlat" ); + if ( trans_->nptrfrstlat == nullptr ) + ::trans_inquire( trans_.get(), "nptrfrstlat" ); return trans_->nptrfrstlat; } const int* atlas::trans::TransIFS::nsta( int& sizef2, int& sizef1 ) const { sizef1 = trans_->ndgl + trans_->n_regions_NS - 1; sizef2 = trans_->n_regions_EW; - if ( trans_->nsta == nullptr ) ::trans_inquire( trans_.get(), "nsta" ); + if ( trans_->nsta == nullptr ) + ::trans_inquire( trans_.get(), "nsta" ); return trans_->nsta; } const int* atlas::trans::TransIFS::nonl( int& sizef2, int& sizef1 ) const { sizef1 = trans_->ndgl + trans_->n_regions_NS - 1; sizef2 = trans_->n_regions_EW; - if ( trans_->nonl == nullptr ) ::trans_inquire( trans_.get(), "nonl" ); + if ( trans_->nonl == nullptr ) + ::trans_inquire( trans_.get(), "nonl" ); return trans_->nonl; } const int* atlas::trans::TransIFS::nmyms( int& size ) const { size = trans_->nump; - if ( trans_->nmyms == nullptr ) ::trans_inquire( trans_.get(), "nmyms" ); + if ( trans_->nmyms == nullptr ) + ::trans_inquire( trans_.get(), "nmyms" ); return trans_->nmyms; } const int* atlas::trans::TransIFS::nasm0( int& size ) const { size = trans_->nsmax + 1; // +1 because zeroth wave included - if ( trans_->nasm0 == nullptr ) ::trans_inquire( trans_.get(), "nasm0" ); + if ( trans_->nasm0 == nullptr ) + ::trans_inquire( trans_.get(), "nasm0" ); return trans_->nasm0; } const int* atlas::trans::TransIFS::nvalue( int& size ) const { size = trans_->nspec2; - if ( trans_->nvalue == nullptr ) ::trans_inquire( trans_.get(), "nvalue" ); + if ( trans_->nvalue == nullptr ) + ::trans_inquire( trans_.get(), "nvalue" ); return trans_->nvalue; } array::LocalView atlas::trans::TransIFS::nvalue() const { - if ( trans_->nvalue == nullptr ) ::trans_inquire( trans_.get(), "nvalue" ); + if ( trans_->nvalue == nullptr ) + ::trans_inquire( trans_.get(), "nvalue" ); return array::LocalView( trans_->nvalue, array::make_shape( trans_->nspec2 ) ); } array::LocalView atlas::trans::TransIFS::nasm0() const { - if ( trans_->nasm0 == nullptr ) ::trans_inquire( trans_.get(), "nasm0" ); + if ( trans_->nasm0 == nullptr ) + ::trans_inquire( trans_.get(), "nasm0" ); return array::LocalView( trans_->nasm0, array::make_shape( trans_->nsmax + 1 ) ); } array::LocalView atlas::trans::TransIFS::nmyms() const { - if ( trans_->nmyms == nullptr ) ::trans_inquire( trans_.get(), "nmyms" ); + if ( trans_->nmyms == nullptr ) + ::trans_inquire( trans_.get(), "nmyms" ); return array::LocalView( trans_->nmyms, array::make_shape( trans_->nump ) ); } array::LocalView atlas::trans::TransIFS::nonl() const { - if ( trans_->nonl == nullptr ) ::trans_inquire( trans_.get(), "nonl" ); + if ( trans_->nonl == nullptr ) + ::trans_inquire( trans_.get(), "nonl" ); return array::LocalView( trans_->nonl, array::make_shape( trans_->n_regions_EW, trans_->ndgl + trans_->n_regions_NS - 1 ) ); } array::LocalView atlas::trans::TransIFS::nsta() const { - if ( trans_->nsta == nullptr ) ::trans_inquire( trans_.get(), "nsta" ); + if ( trans_->nsta == nullptr ) + ::trans_inquire( trans_.get(), "nsta" ); return array::LocalView( trans_->nsta, array::make_shape( trans_->n_regions_EW, trans_->ndgl + trans_->n_regions_NS - 1 ) ); } array::LocalView atlas::trans::TransIFS::nptrfrstlat() const { - if ( trans_->nptrfrstlat == nullptr ) ::trans_inquire( trans_.get(), "nptrfrstlat" ); + if ( trans_->nptrfrstlat == nullptr ) + ::trans_inquire( trans_.get(), "nptrfrstlat" ); return array::LocalView( trans_->nptrfrstlat, array::make_shape( trans_->n_regions_NS ) ); } array::LocalView atlas::trans::TransIFS::nlstlat() const { - if ( trans_->nlstlat == nullptr ) ::trans_inquire( trans_.get(), "nlstlat" ); + if ( trans_->nlstlat == nullptr ) + ::trans_inquire( trans_.get(), "nlstlat" ); return array::LocalView( trans_->nlstlat, array::make_shape( trans_->n_regions_NS ) ); } array::LocalView atlas::trans::TransIFS::nfrstlat() const { - if ( trans_->nfrstlat == nullptr ) ::trans_inquire( trans_.get(), "nfrstlat" ); + if ( trans_->nfrstlat == nullptr ) + ::trans_inquire( trans_.get(), "nfrstlat" ); return array::LocalView( trans_->nfrstlat, array::make_shape( trans_->n_regions_NS ) ); } @@ -863,7 +882,9 @@ size_t TransIFS::nb_spectral_coefficients_global() const { } const functionspace::Spectral& TransIFS::spectral() const { - if ( not spectral_ ) { spectral_ = functionspace::Spectral( Trans( this ) ); } + if ( not spectral_ ) { + spectral_ = functionspace::Spectral( Trans( this ) ); + } return spectral_; } @@ -894,7 +915,8 @@ void TransIFS::ctor_rgg( const long nlat, const idx_t pl[], long truncation, con TRANS_CHECK( ::trans_new( trans_.get() ) ); TRANS_CHECK( ::trans_use_mpi( mpi::comm().size() > 1 ) ); TRANS_CHECK( ::trans_set_resol( trans_.get(), nlat, nloen.data() ) ); - if ( truncation >= 0 ) TRANS_CHECK( ::trans_set_trunc( trans_.get(), truncation ) ); + if ( truncation >= 0 ) + TRANS_CHECK( ::trans_set_trunc( trans_.get(), truncation ) ); TRANS_CHECK( ::trans_set_cache( trans_.get(), cache_, cachesize_ ) ); @@ -923,7 +945,8 @@ void TransIFS::ctor_lonlat( const long nlon, const long nlat, long truncation, c TRANS_CHECK( ::trans_new( trans_.get() ) ); TRANS_CHECK( ::trans_use_mpi( mpi::comm().size() > 1 ) ); TRANS_CHECK( ::trans_set_resol_lonlat( trans_.get(), nlon, nlat ) ); - if ( truncation >= 0 ) TRANS_CHECK( ::trans_set_trunc( trans_.get(), truncation ) ); + if ( truncation >= 0 ) + TRANS_CHECK( ::trans_set_trunc( trans_.get(), truncation ) ); TRANS_CHECK( ::trans_set_cache( trans_.get(), cache_, cachesize_ ) ); if ( p.read_legendre().size() && mpi::comm().size() == 1 ) { @@ -1365,8 +1388,10 @@ void TransIFS::__dirtrans_wind2vordiv( const functionspace::NodeColumns& gp, con throw_Exception( msg.str(), Here() ); } - if ( spvor.size() == 0 ) throw_Exception( "dirtrans: spectral vorticity field is empty." ); - if ( spdiv.size() == 0 ) throw_Exception( "dirtrans: spectral divergence field is empty." ); + if ( spvor.size() == 0 ) + throw_Exception( "dirtrans: spectral vorticity field is empty." ); + if ( spdiv.size() == 0 ) + throw_Exception( "dirtrans: spectral divergence field is empty." ); // Arrays Trans expects std::vector rgp( 2 * nfld * ngptot() ); @@ -1428,8 +1453,10 @@ void TransIFS::__invtrans_vordiv2wind( const Spectral& sp, const Field& spvor, c ATLAS_ASSERT( spvor.rank() == 2 ); ATLAS_ASSERT( spdiv.rank() == 2 ); - if ( spvor.size() == 0 ) throw_Exception( "invtrans: spectral vorticity field is empty." ); - if ( spdiv.size() == 0 ) throw_Exception( "invtrans: spectral divergence field is empty." ); + if ( spvor.size() == 0 ) + throw_Exception( "invtrans: spectral vorticity field is empty." ); + if ( spdiv.size() == 0 ) + throw_Exception( "invtrans: spectral divergence field is empty." ); // Arrays Trans expects std::vector rgp( 2 * nfld * ngptot() ); diff --git a/src/atlas/trans/local/LegendreCacheCreatorLocal.cc b/src/atlas/trans/local/LegendreCacheCreatorLocal.cc index 6e7231a83..57ee617d8 100644 --- a/src/atlas/trans/local/LegendreCacheCreatorLocal.cc +++ b/src/atlas/trans/local/LegendreCacheCreatorLocal.cc @@ -120,8 +120,10 @@ LegendreCacheCreatorLocal::LegendreCacheCreatorLocal( const Grid& grid, int trun config_( config ) {} bool LegendreCacheCreatorLocal::supported() const { - if ( not StructuredGrid( grid_ ) ) return false; - if ( grid_.projection() ) return false; + if ( not StructuredGrid( grid_ ) ) + return false; + if ( grid_.projection() ) + return false; return true; } diff --git a/src/atlas/trans/local/LegendrePolynomials.cc b/src/atlas/trans/local/LegendrePolynomials.cc index ac6a523c4..3b3d9fb76 100644 --- a/src/atlas/trans/local/LegendrePolynomials.cc +++ b/src/atlas/trans/local/LegendrePolynomials.cc @@ -124,7 +124,8 @@ void compute_legendre_polynomials_lat( const int trc, // truncation (in) double sq = std::sqrt( ( 2. * jn + 1. ) / ( 2. * jn ) ); legpol[idxmn( jn, jn )] = legpol[idxmn( jn - 1, jn - 1 )] * zdlsita * sq; - if ( std::abs( legpol[idxmn( jn, jn )] ) < zdls ) legpol[idxmn( jn, jn )] = 0.0; + if ( std::abs( legpol[idxmn( jn, jn )] ) < zdls ) + legpol[idxmn( jn, jn )] = 0.0; } // --------------------------------------------- diff --git a/src/atlas/trans/local/TransLocal.cc b/src/atlas/trans/local/TransLocal.cc index 1b70daec0..ddbf815eb 100644 --- a/src/atlas/trans/local/TransLocal.cc +++ b/src/atlas/trans/local/TransLocal.cc @@ -188,7 +188,9 @@ void alloc_aligned( double*& ptr, size_t n ) { const size_t alignment = 64 * sizeof( double ); size_t bytes = sizeof( double ) * n; int err = posix_memalign( (void**)&ptr, alignment, bytes ); - if ( err ) { throw_AllocationFailed( bytes, Here() ); } + if ( err ) { + throw_AllocationFailed( bytes, Here() ); + } } void free_aligned( double*& ptr ) { @@ -320,7 +322,9 @@ TransLocal::TransLocal( const Cache& cache, const Grid& grid, const Domain& doma nlatsNH_++; nlatsSH_++; } - if ( nlatsNH_ >= nlatsSH_ ) { nlatsLegDomain_ = nlatsNH_; } + if ( nlatsNH_ >= nlatsSH_ ) { + nlatsLegDomain_ = nlatsNH_; + } else { nlatsLegDomain_ = nlatsSH_; } @@ -358,11 +362,15 @@ TransLocal::TransLocal( const Cache& cache, const Grid& grid, const Domain& doma jlonMin_[0] = 0; jlatMin_ = 0; nlatsGlobal_ = gs_global.ny(); - if ( grid_.domain().global() ) { Log::debug() << "Global grid with " << nlats << " latitudes." << std::endl; } + if ( grid_.domain().global() ) { + Log::debug() << "Global grid with " << nlats << " latitudes." << std::endl; + } else { Log::debug() << "Grid has " << nlats << " latitudes. Global grid has " << nlatsGlobal_ << std::endl; } - if ( useGlobalLeg ) { nlatsLeg_ = ( nlatsGlobal_ + 1 ) / 2; } + if ( useGlobalLeg ) { + nlatsLeg_ = ( nlatsGlobal_ + 1 ) / 2; + } else { nlatsLeg_ = nlatsLegDomain_; nlatsLegReduced_ = nlatsLeg_; @@ -375,12 +383,18 @@ TransLocal::TransLocal( const Cache& cache, const Grid& grid, const Domain& doma } //Log::info() << std::endl; int jlatMinLeg_ = jlatMin_; - if ( nlatsNH_ < nlatsSH_ ) { jlatMinLeg_ += nlatsNH_ - nlatsSH_; }; + if ( nlatsNH_ < nlatsSH_ ) { + jlatMinLeg_ += nlatsNH_ - nlatsSH_; + }; if ( jlatMin_ >= ( nlatsGlobal_ + 1 ) / 2 ) { jlatMinLeg_ -= 2 * ( jlatMin_ - ( nlatsGlobal_ + 1 ) / 2 ); - if ( nlatsGlobal_ % 2 == 1 ) { jlatMinLeg_--; } + if ( nlatsGlobal_ % 2 == 1 ) { + jlatMinLeg_--; + } }; - if ( useGlobalLeg ) { nlatsLegReduced_ = jlatMinLeg_ + nlatsLegDomain_; } + if ( useGlobalLeg ) { + nlatsLegReduced_ = jlatMinLeg_ + nlatsLegDomain_; + } // reduce truncation towards the pole for reduced meshes: nlat0_.resize( truncation_ + 1 ); @@ -397,7 +411,9 @@ TransLocal::TransLocal( const Cache& cache, const Grid& grid, const Domain& doma RegularGrid( gs_global ) ); nmen = std::max( nmen0, nmen ); int ndgluj = nlatsLeg_ - std::min( nlatsLeg_, nlatsLeg_ + jlatMinLeg_ - jlat ); - if ( useGlobalLeg ) { ndgluj = std::max( jlatMinLeg_, jlat ); } + if ( useGlobalLeg ) { + ndgluj = std::max( jlatMinLeg_, jlat ); + } for ( int j = nmen0 + 1; j <= nmen; j++ ) { nlat0_[j] = ndgluj; } @@ -414,17 +430,23 @@ TransLocal::TransLocal( const Cache& cache, const Grid& grid, const Domain& doma // compute longitudinal location of domain within global grid for using FFT: auto wrapAngle = [&]( double angle ) { double result = std::fmod( angle, 360. ); - if ( result < 0. ) { result += 360.; } + if ( result < 0. ) { + result += 360.; + } return result; }; if ( useFFT_ ) { double lonmin = wrapAngle( g.x( 0, 0 ) ); - if ( nlonsMax < fft_threshold * nlonsMaxGlobal_ ) { useFFT_ = false; } + if ( nlonsMax < fft_threshold * nlonsMaxGlobal_ ) { + useFFT_ = false; + } else { // need to use FFT with cropped grid if ( RegularGrid( gridGlobal_ ) ) { for ( idx_t jlon = 0; jlon < nlonsMaxGlobal_; ++jlon ) { - if ( gs_global.x( jlon, 0 ) < lonmin ) { jlonMin_[0]++; } + if ( gs_global.x( jlon, 0 ) < lonmin ) { + jlonMin_[0]++; + } } } else { @@ -435,7 +457,9 @@ TransLocal::TransLocal( const Cache& cache, const Grid& grid, const Domain& doma nlonsGlobal_[jlat] = gs_global.nx( jlat + jlatMin_ ); jlonMin_[jlat] = 0; for ( idx_t jlon = 0; jlon < nlonsGlobal_[jlat]; ++jlon ) { - if ( gs_global.x( jlon, jlat + jlatMin_ ) < lonmin ) { jlonMin_[jlat]++; } + if ( gs_global.x( jlon, jlat + jlatMin_ ) < lonmin ) { + jlonMin_[jlat]++; + } } } } @@ -447,16 +471,24 @@ TransLocal::TransLocal( const Cache& cache, const Grid& grid, const Domain& doma if ( nlatsNH_ >= nlatsSH_ || useGlobalLeg ) { for ( idx_t j = 0; j < nlatsLeg_; ++j ) { double lat = gsLeg.y( j ); - if ( lat > latPole ) { lat = latPole; } - if ( lat < -latPole ) { lat = -latPole; } + if ( lat > latPole ) { + lat = latPole; + } + if ( lat < -latPole ) { + lat = -latPole; + } lats[j] = lat * util::Constants::degreesToRadians(); } } else { for ( idx_t j = nlats - 1, idx = 0; idx < nlatsLeg_; --j, ++idx ) { double lat = gsLeg.y( j ); - if ( lat > latPole ) { lat = latPole; } - if ( lat < -latPole ) { lat = -latPole; } + if ( lat > latPole ) { + lat = latPole; + } + if ( lat < -latPole ) { + lat = -latPole; + } lats[idx] = -lat * util::Constants::degreesToRadians(); } } @@ -611,7 +643,9 @@ TransLocal::TransLocal( const Cache& cache, const Grid& grid, const Domain& doma int idx = 0; for ( int jm = 0; jm < truncation_ + 1; jm++ ) { double factor = 1.; - if ( jm > 0 ) { factor = 2.; } + if ( jm > 0 ) { + factor = 2.; + } for ( int jlon = 0; jlon < nlonsMax; jlon++ ) { fourier_[idx++] = +std::cos( jm * lons[jlon] ) * factor; // real part } @@ -627,7 +661,9 @@ TransLocal::TransLocal( const Cache& cache, const Grid& grid, const Domain& doma for ( int jlon = 0; jlon < nlonsMax; jlon++ ) { double factor = 1.; for ( int jm = 0; jm < truncation_ + 1; jm++ ) { - if ( jm > 0 ) { factor = 2.; } + if ( jm > 0 ) { + factor = 2.; + } fourier_[idx++] = +std::cos( jm * lons[jlon] ) * factor; // real part fourier_[idx++] = -std::sin( jm * lons[jlon] ) * factor; // imaginary part } @@ -703,14 +739,18 @@ TransLocal::~TransLocal() { } } else { - if ( unstruct_precomp_ ) { free_aligned( legendre_, "Legendre coeffs." ); } + if ( unstruct_precomp_ ) { + free_aligned( legendre_, "Legendre coeffs." ); + } } } // -------------------------------------------------------------------------------------------------------------------- const functionspace::Spectral& TransLocal::spectral() const { - if ( not spectral_ ) { spectral_ = functionspace::Spectral( Trans( this ) ); } + if ( not spectral_ ) { + spectral_ = functionspace::Spectral( Trans( this ) ); + } return spectral_; } @@ -839,13 +879,17 @@ void TransLocal::invtrans_legendre( const int truncation, const int nlats, const for ( int jfld = 0; jfld < nb_fields; jfld++ ) { idx = jfld + nb_fields * ( imag + 2 * ( jn - jm ) ); if ( jn <= truncation && jm < truncation ) { - if ( ( jn - jm ) % 2 == 0 ) { scalar_sym[is++] = scalar_spectra[idx + ioff]; } + if ( ( jn - jm ) % 2 == 0 ) { + scalar_sym[is++] = scalar_spectra[idx + ioff]; + } else { scalar_asym[ia++] = scalar_spectra[idx + ioff]; } } else { - if ( ( jn - jm ) % 2 == 0 ) { scalar_sym[is++] = 0.; } + if ( ( jn - jm ) % 2 == 0 ) { + scalar_sym[is++] = 0.; + } else { scalar_asym[ia++] = 0.; } @@ -981,7 +1025,9 @@ void TransLocal::invtrans_fourier_regular( const int nlats, const int nlons, con for ( int jlat = 0; jlat < nlats; jlat++ ) { for ( int jlon = 0; jlon < nlons; jlon++ ) { int j = jlon + jlonMin_[0]; - if ( j >= nlonsMaxGlobal_ ) { j -= nlonsMaxGlobal_; } + if ( j >= nlonsMaxGlobal_ ) { + j -= nlonsMaxGlobal_; + } gp_fields[jlon + nlons * ( jlat + nlats * jfld )] = fftw_->out[j + nlonsMaxGlobal_ * jlat]; } } @@ -1068,12 +1114,16 @@ void TransLocal::invtrans_fourier_reduced( const int nlats, const StructuredGrid //Log::info() << std::endl; //Log::info() << jlat << "out:" << std::endl; int jplan = nlatsLegDomain_ - nlatsNH_ + jlat; - if ( jplan >= nlatsLegDomain_ ) { jplan = nlats - 1 + nlatsLegDomain_ - nlatsSH_ - jlat; }; + if ( jplan >= nlatsLegDomain_ ) { + jplan = nlats - 1 + nlatsLegDomain_ - nlatsSH_ - jlat; + }; //ASSERT( jplan < nlatsLeg_ && jplan >= 0 ); fftw_execute_dft_c2r( fftw_->plans[jplan], fftw_->in, fftw_->out ); for ( int jlon = 0; jlon < g.nx( jlat ); jlon++ ) { int j = jlon + jlonMin_[jlat]; - if ( j >= nlonsGlobal_[jlat] ) { j -= nlonsGlobal_[jlat]; } + if ( j >= nlonsGlobal_[jlat] ) { + j -= nlonsGlobal_[jlat]; + } //Log::info() << fftw_->out[j] << " "; ATLAS_ASSERT( j < nlonsMaxGlobal_ ); gp_fields[jgp++] = fftw_->out[j]; @@ -1337,8 +1387,12 @@ void TransLocal::invtrans_uv( const int truncation, const int nb_scalar_fields, std::vector coslatinvs( nlats ); for ( idx_t j = 0; j < nlats; ++j ) { double lat = g.y( j ); - if ( lat > latPole ) { lat = latPole; } - if ( lat < -latPole ) { lat = -latPole; } + if ( lat > latPole ) { + lat = latPole; + } + if ( lat < -latPole ) { + lat = -latPole; + } double coslat = std::cos( lat * util::Constants::degreesToRadians() ); coslatinvs[j] = 1. / coslat; //Log::info() << "lat=" << g.y( j ) << " coslat=" << coslat << std::endl; @@ -1386,7 +1440,9 @@ void extend_truncation( const int old_truncation, const int nb_fields, const dou for ( int n = m; n <= old_truncation + 1; n++ ) { // total wavenumber for ( int imag = 0; imag < 2; imag++ ) { // imaginary/real part for ( int jfld = 0; jfld < nb_fields; jfld++ ) { // field - if ( m == old_truncation + 1 || n == old_truncation + 1 ) { new_spectra[k++] = 0.; } + if ( m == old_truncation + 1 || n == old_truncation + 1 ) { + new_spectra[k++] = 0.; + } else { new_spectra[k++] = old_spectra[k_old++]; } diff --git a/src/atlas/trans/local/VorDivToUVLocal.cc b/src/atlas/trans/local/VorDivToUVLocal.cc index 56bf78c99..8f2bcbe43 100644 --- a/src/atlas/trans/local/VorDivToUVLocal.cc +++ b/src/atlas/trans/local/VorDivToUVLocal.cc @@ -100,7 +100,9 @@ void vd2uv( const int truncation, // truncation int ij = truncation + 3 - jn; if ( jn >= 0 ) { zlapin[ij] = rlapin[jn]; - if ( jn < km ) { zepsnm[ij] = 0.; } + if ( jn < km ) { + zepsnm[ij] = 0.; + } else { zepsnm[ij] = repsnm[jn + ( 2 * truncation - km + 5 ) * km / 2]; } diff --git a/src/atlas/util/Allocate.cc b/src/atlas/util/Allocate.cc index 8d2136381..3d85081fb 100644 --- a/src/atlas/util/Allocate.cc +++ b/src/atlas/util/Allocate.cc @@ -29,7 +29,8 @@ namespace detail { void allocate_cudamanaged( void** ptr, size_t size ) { #if ATLAS_GRIDTOOLS_STORAGE_BACKEND_CUDA cudaError_t err = cudaMallocManaged( ptr, size ); - if ( err != cudaSuccess ) throw_AssertionFailed( "failed to allocate GPU memory", Here() ); + if ( err != cudaSuccess ) + throw_AssertionFailed( "failed to allocate GPU memory", Here() ); #else *ptr = malloc( size ); #endif @@ -38,11 +39,13 @@ void allocate_cudamanaged( void** ptr, size_t size ) { void deallocate_cudamanaged( void* ptr ) { #if ATLAS_GRIDTOOLS_STORAGE_BACKEND_CUDA cudaError_t err = cudaDeviceSynchronize(); - if ( err != cudaSuccess ) throw_AssertionFailed( "failed to synchronize memory", Here() ); + if ( err != cudaSuccess ) + throw_AssertionFailed( "failed to synchronize memory", Here() ); err = cudaFree( ptr ); // The following throws an invalid device memory - if ( err != cudaSuccess ) throw_AssertionFailed( "failed to free GPU memory", Here() ); + if ( err != cudaSuccess ) + throw_AssertionFailed( "failed to free GPU memory", Here() ); #else free( ptr ); #endif diff --git a/src/atlas/util/Config.cc b/src/atlas/util/Config.cc index 8240b2639..6d3b9e8af 100644 --- a/src/atlas/util/Config.cc +++ b/src/atlas/util/Config.cc @@ -37,9 +37,13 @@ static eckit::Value yaml_from_stream( std::istream& stream ) { } static eckit::Value yaml_from_path( const eckit::PathName& path ) { - if ( !path.exists() ) { throw_Exception( "File " + std::string( path ) + " does not exist." ); } + if ( !path.exists() ) { + throw_Exception( "File " + std::string( path ) + " does not exist." ); + } std::ifstream file( path.localPath() ); - if ( !file.is_open() ) { throw_Exception( "Unable to open json file " + std::string( path ), Here() ); } + if ( !file.is_open() ) { + throw_Exception( "Unable to open json file " + std::string( path ), Here() ); + } eckit::Value value = yaml_from_stream( file ); file.close(); return value; @@ -175,7 +179,8 @@ void atlas__Config__set_array_double( Config* This, const char* name, double val int atlas__Config__get_config( Config* This, const char* name, Config* value ) { ATLAS_ASSERT( This != nullptr, "Cannot access uninitialised atlas_Config" ); - if ( !This->get( std::string( name ), *value ) ) return false; + if ( !This->get( std::string( name ), *value ) ) + return false; return true; } @@ -183,7 +188,8 @@ int atlas__Config__get_config_list( Config* This, const char* name, Config**& va ATLAS_ASSERT( This != nullptr, "Cannot access uninitialised atlas_Config" ); value = nullptr; std::vector vector; - if ( !This->get( std::string( name ), vector ) ) return false; + if ( !This->get( std::string( name ), vector ) ) + return false; size = vector.size(); value = new Config*[size]; allocated = true; @@ -196,26 +202,30 @@ int atlas__Config__get_config_list( Config* This, const char* name, Config**& va int atlas__Config__get_int( Config* This, const char* name, int& value ) { ATLAS_ASSERT( This != nullptr, "Cannot access uninitialised atlas_Config" ); long long_value = value; - if ( !This->get( std::string( name ), long_value ) ) return false; + if ( !This->get( std::string( name ), long_value ) ) + return false; ATLAS_ASSERT( int( long_value ) == long_value ); value = long_value; return true; } int atlas__Config__get_long( Config* This, const char* name, long& value ) { ATLAS_ASSERT( This != nullptr, "Cannot access uninitialised atlas_Config" ); - if ( !This->get( std::string( name ), value ) ) return false; + if ( !This->get( std::string( name ), value ) ) + return false; return true; } int atlas__Config__get_float( Config* This, const char* name, float& value ) { ATLAS_ASSERT( This != nullptr, "Cannot access uninitialised atlas_Config" ); double double_value; - if ( !This->get( std::string( name ), double_value ) ) return false; + if ( !This->get( std::string( name ), double_value ) ) + return false; value = static_cast( double_value ); return true; } int atlas__Config__get_double( Config* This, const char* name, double& value ) { ATLAS_ASSERT( This != nullptr, "Cannot access uninitialised atlas_Config" ); - if ( !This->get( std::string( name ), value ) ) return false; + if ( !This->get( std::string( name ), value ) ) + return false; return true; } int atlas__Config__get_string( Config* This, const char* name, char*& value, int& size, int& allocated ) { @@ -234,7 +244,8 @@ int atlas__Config__get_string( Config* This, const char* name, char*& value, int int atlas__Config__get_array_int( Config* This, const char* name, int*& value, int& size, int& allocated ) { ATLAS_ASSERT( This != nullptr, "Cannot access uninitialised atlas_Config" ); std::vector v; - if ( !This->get( std::string( name ), v ) ) return false; + if ( !This->get( std::string( name ), v ) ) + return false; size = v.size(); value = new int[size]; for ( size_t j = 0; j < v.size(); ++j ) { @@ -247,7 +258,8 @@ int atlas__Config__get_array_int( Config* This, const char* name, int*& value, i int atlas__Config__get_array_long( Config* This, const char* name, long*& value, int& size, int& allocated ) { ATLAS_ASSERT( This != nullptr, "Cannot access uninitialised atlas_Config" ); std::vector v; - if ( !This->get( std::string( name ), v ) ) return false; + if ( !This->get( std::string( name ), v ) ) + return false; size = v.size(); value = new long[size]; for ( size_t j = 0; j < v.size(); ++j ) @@ -258,7 +270,8 @@ int atlas__Config__get_array_long( Config* This, const char* name, long*& value, int atlas__Config__get_array_float( Config* This, const char* name, float*& value, int& size, int& allocated ) { ATLAS_ASSERT( This != nullptr, "Cannot access uninitialised atlas_Config" ); std::vector v; - if ( !This->get( std::string( name ), v ) ) return false; + if ( !This->get( std::string( name ), v ) ) + return false; size = v.size(); value = new float[size]; for ( size_t j = 0; j < v.size(); ++j ) { @@ -270,7 +283,8 @@ int atlas__Config__get_array_float( Config* This, const char* name, float*& valu int atlas__Config__get_array_double( Config* This, const char* name, double*& value, int& size, int& allocated ) { ATLAS_ASSERT( This != nullptr, "Cannot access uninitialised atlas_Config" ); std::vector v; - if ( !This->get( std::string( name ), v ) ) return false; + if ( !This->get( std::string( name ), v ) ) + return false; size = v.size(); value = new double[size]; for ( size_t j = 0; j < v.size(); ++j ) diff --git a/src/atlas/util/Factory.cc b/src/atlas/util/Factory.cc index ef6516644..a9252edff 100644 --- a/src/atlas/util/Factory.cc +++ b/src/atlas/util/Factory.cc @@ -97,11 +97,15 @@ void FactoryRegistry::list( std::ostream& out ) const { FactoryBase::FactoryBase( FactoryRegistry& registry, const std::string& builder ) : registry_( registry ), builder_( builder ) { - if ( not builder_.empty() ) { registry_.add( builder, this ); } + if ( not builder_.empty() ) { + registry_.add( builder, this ); + } } FactoryBase::~FactoryBase() { - if ( not builder_.empty() ) { registry_.remove( builder_ ); } + if ( not builder_.empty() ) { + registry_.remove( builder_ ); + } } //---------------------------------------------------------------------------------------------------------------------- diff --git a/src/atlas/util/LonLatMicroDeg.h b/src/atlas/util/LonLatMicroDeg.h index a9d689349..832677af9 100644 --- a/src/atlas/util/LonLatMicroDeg.h +++ b/src/atlas/util/LonLatMicroDeg.h @@ -80,8 +80,10 @@ class LonLatMicroDeg { // ------------------------------------------------------------------------------------ inline bool LonLatMicroDeg::operator<( const LonLatMicroDeg& other ) const { - if ( p_[LAT] > other.p_[LAT] ) return true; - if ( p_[LAT] == other.p_[LAT] ) return ( p_[LON] < other.p_[LON] ); + if ( p_[LAT] > other.p_[LAT] ) + return true; + if ( p_[LAT] == other.p_[LAT] ) + return ( p_[LON] < other.p_[LON] ); return false; } diff --git a/src/atlas/util/LonLatPolygon.cc b/src/atlas/util/LonLatPolygon.cc index 4cca4f1d1..d4c3a02ad 100644 --- a/src/atlas/util/LonLatPolygon.cc +++ b/src/atlas/util/LonLatPolygon.cc @@ -65,7 +65,9 @@ bool LonLatPolygon::contains( const PointLonLat& P ) const { if ( APB != BPA ) { const double side = cross_product_analog( P, A, B ); - if ( APB && side > 0 ) { ++wn; } + if ( APB && side > 0 ) { + ++wn; + } else if ( BPA && side < 0 ) { --wn; } diff --git a/src/atlas/util/Metadata.cc b/src/atlas/util/Metadata.cc index e4c3357db..36a628fec 100644 --- a/src/atlas/util/Metadata.cc +++ b/src/atlas/util/Metadata.cc @@ -69,7 +69,9 @@ void Metadata::broadcast( Metadata& dest, const size_t root ) { ATLAS_TRACE_MPI( BROADCAST ) { atlas::mpi::comm().broadcast( buffer_size, root ); } - if ( atlas::mpi::comm().rank() != root ) { buffer.resize( buffer_size ); } + if ( atlas::mpi::comm().rank() != root ) { + buffer.resize( buffer_size ); + } ATLAS_TRACE_MPI( BROADCAST ) { atlas::mpi::comm().broadcast( buffer.begin(), buffer.end(), root ); } @@ -101,7 +103,9 @@ void Metadata::broadcast( Metadata& dest, const size_t root ) const { ATLAS_TRACE_MPI( BROADCAST ) { atlas::mpi::comm().broadcast( buffer_size, root ); } - if ( atlas::mpi::comm().rank() != root ) { buffer.resize( buffer_size ); } + if ( atlas::mpi::comm().rank() != root ) { + buffer.resize( buffer_size ); + } ATLAS_TRACE_MPI( BROADCAST ) { atlas::mpi::comm().broadcast( buffer.begin(), buffer.end(), root ); } diff --git a/src/atlas/util/Metadata.h b/src/atlas/util/Metadata.h index be62406ea..7fc6c179f 100644 --- a/src/atlas/util/Metadata.h +++ b/src/atlas/util/Metadata.h @@ -38,7 +38,8 @@ class Metadata : public eckit::LocalConfiguration { template ValueT get( const std::string& name ) const { ValueT value; - if ( not eckit::LocalConfiguration::get( name, value ) ) throw_not_found( name ); + if ( not eckit::LocalConfiguration::get( name, value ) ) + throw_not_found( name ); return value; } diff --git a/src/atlas/util/ObjectHandle.cc b/src/atlas/util/ObjectHandle.cc index 15f6d0d53..2ef7e418f 100644 --- a/src/atlas/util/ObjectHandle.cc +++ b/src/atlas/util/ObjectHandle.cc @@ -43,7 +43,9 @@ void ObjectHandleBase::assign( const ObjectHandleBase& other ) { } void ObjectHandleBase::assign( const Object* other ) { - if ( object_ ) { release(); } + if ( object_ ) { + release(); + } object_ = const_cast( other ); @@ -52,7 +54,8 @@ void ObjectHandleBase::assign( const Object* other ) { void ObjectHandleBase::attach() { - if ( !null() ) object_->attach(); + if ( !null() ) + object_->attach(); } // ------------------------------------------------------------------ diff --git a/src/atlas/util/ObjectHandle.h b/src/atlas/util/ObjectHandle.h index 975847314..c6309a268 100644 --- a/src/atlas/util/ObjectHandle.h +++ b/src/atlas/util/ObjectHandle.h @@ -21,18 +21,24 @@ class ObjectHandleBase { ObjectHandleBase( const Object* object ) : object_( const_cast( object ) ) { attach(); } virtual ~ObjectHandleBase() { - if ( object_ ) { release(); } + if ( object_ ) { + release(); + } } const ObjectHandleBase& operator=( const ObjectHandleBase& other ) { - if ( object_ != other.object_ ) { assign( other ); } + if ( object_ != other.object_ ) { + assign( other ); + } return *this; } operator bool() const { return object_ != nullptr; } void reset( const Object* other ) { - if ( object_ != other ) { assign( other ); } + if ( object_ != other ) { + assign( other ); + } } int owners() const; diff --git a/src/atlas/util/Polygon.cc b/src/atlas/util/Polygon.cc index d578ecd41..9daa14c14 100644 --- a/src/atlas/util/Polygon.cc +++ b/src/atlas/util/Polygon.cc @@ -44,7 +44,9 @@ Polygon::Polygon( const Polygon::edge_set_t& edges ) { // get external edges by attempting to remove reversed edges, if any edge_set_t extEdges; for ( const edge_t& e : edges ) { - if ( !extEdges.erase( e.reverse() ) ) { extEdges.insert( e ); } + if ( !extEdges.erase( e.reverse() ) ) { + extEdges.insert( e ); + } } ATLAS_ASSERT( extEdges.size() >= 2 ); @@ -72,7 +74,9 @@ Polygon::operator bool() const { } Polygon& Polygon::operator+=( const Polygon& other ) { - if ( empty() ) { return operator=( other ); } + if ( empty() ) { + return operator=( other ); + } // polygon can have multiple cycles, but must be connected graphs // Note: a 'cycle' is handled by repeating the indices, excluding (repeated) diff --git a/src/atlas/util/Rotation.cc b/src/atlas/util/Rotation.cc index daa5b589c..b8b630594 100644 --- a/src/atlas/util/Rotation.cc +++ b/src/atlas/util/Rotation.cc @@ -126,7 +126,8 @@ void Rotation::precompute() { Rotation::Rotation( const PointLonLat& south_pole, double rotation_angle ) { spole_ = south_pole; npole_ = PointLonLat( spole_.lon() - 180., spole_.lat() + 180. ); - if ( npole_.lat() > 90 ) npole_.lon() += 180.; + if ( npole_.lat() > 90 ) + npole_.lon() += 180.; angle_ = wrap_angle( rotation_angle ); precompute(); @@ -142,12 +143,14 @@ Rotation::Rotation( const eckit::Parametrisation& p ) { if ( p.get( "north_pole", pole ) ) { npole_ = PointLonLat( pole.data() ); spole_ = PointLonLat( npole_.lon() + 180., npole_.lat() - 180. ); - if ( spole_.lat() < -90 ) spole_.lon() -= 180.; + if ( spole_.lat() < -90 ) + spole_.lon() -= 180.; } else if ( p.get( "south_pole", pole ) ) { spole_ = PointLonLat( pole.data() ); npole_ = PointLonLat( spole_.lon() - 180., spole_.lat() + 180. ); - if ( npole_.lat() > 90 ) npole_.lon() += 180.; + if ( npole_.lat() > 90 ) + npole_.lon() += 180.; } precompute(); @@ -162,7 +165,9 @@ inline PointXYZ rotate_geocentric( const PointXYZ& p, const RotationMatrix& R ) } void Rotation::rotate( double crd[] ) const { - if ( !rotated_ ) { return; } + if ( !rotated_ ) { + return; + } if ( !rotation_angle_only_ ) { const PointLonLat L( wrap_latitude( {crd[LON], crd[LAT]} ) ); @@ -181,7 +186,9 @@ void Rotation::rotate( double crd[] ) const { } void Rotation::unrotate( double crd[] ) const { - if ( !rotated_ ) { return; } + if ( !rotated_ ) { + return; + } crd[LON] += angle_; diff --git a/src/atlas/util/SphericalPolygon.cc b/src/atlas/util/SphericalPolygon.cc index 4c8ef3e80..9a9c0d962 100644 --- a/src/atlas/util/SphericalPolygon.cc +++ b/src/atlas/util/SphericalPolygon.cc @@ -35,7 +35,9 @@ bool SphericalPolygon::contains( const PointLonLat& P ) const { ATLAS_ASSERT( coordinates_.size() >= 2 ); // check first bounding box - if ( coordinatesMax_.lon() <= P.lon() || P.lon() < coordinatesMin_.lon() ) { return false; } + if ( coordinatesMax_.lon() <= P.lon() || P.lon() < coordinatesMin_.lon() ) { + return false; + } // winding number int wn = 0; @@ -61,7 +63,9 @@ bool SphericalPolygon::contains( const PointLonLat& P ) const { }(); ATLAS_ASSERT( !std::isnan( lat ) ); - if ( is_approximately_equal( P.lat(), lat ) ) { return true; } + if ( is_approximately_equal( P.lat(), lat ) ) { + return true; + } wn += ( P.lat() > lat ? -1 : 1 ) * ( APB ? -1 : 1 ); } diff --git a/src/atlas/util/detail/Debug.h b/src/atlas/util/detail/Debug.h index a29d85881..23a3112b5 100644 --- a/src/atlas/util/detail/Debug.h +++ b/src/atlas/util/detail/Debug.h @@ -48,7 +48,8 @@ inline bool is_node_global_index( gidx_t x ) { static std::vector v = eckit::Resource>( "$ATLAS_DEBUG_NODE_GLOBAL_INDEX", std::vector() ); for ( gidx_t g : v ) { - if ( x == g ) return true; + if ( x == g ) + return true; } return false; } @@ -57,7 +58,8 @@ inline bool is_edge_global_index( gidx_t x ) { static std::vector v = eckit::Resource>( "$ATLAS_DEBUG_EDGE_GLOBAL_INDEX", std::vector() ); for ( gidx_t g : v ) { - if ( x == g ) return true; + if ( x == g ) + return true; } return false; } @@ -66,7 +68,8 @@ inline bool is_cell_global_index( gidx_t x ) { static std::vector v = eckit::Resource>( "$ATLAS_DEBUG_CELL_GLOBAL_INDEX", std::vector() ); for ( gidx_t g : v ) { - if ( x == g ) return true; + if ( x == g ) + return true; } return false; } @@ -75,7 +78,8 @@ inline bool is_node_uid( gidx_t x ) { static std::vector v = eckit::Resource>( "$ATLAS_DEBUG_NODE_UID", std::vector() ); for ( gidx_t g : v ) { - if ( x == g ) return true; + if ( x == g ) + return true; } return false; } @@ -84,7 +88,8 @@ inline bool is_cell_uid( gidx_t x ) { static std::vector v = eckit::Resource>( "$ATLAS_DEBUG_CELL_UID", std::vector() ); for ( gidx_t g : v ) { - if ( x == g ) return true; + if ( x == g ) + return true; } return false; } @@ -98,7 +103,8 @@ inline int is_mpi_rank() { static std::vector v = eckit::Resource>( "$ATLAS_DEBUG_MPI_RANK", std::vector() ); static int r = mpi::comm().rank(); for ( long g : v ) { - if ( r == g ) return true; + if ( r == g ) + return true; } return false; } @@ -106,7 +112,8 @@ inline int is_mpi_rank() { inline int is_mpi_rank( int x ) { static std::vector v = eckit::Resource>( "$ATLAS_DEBUG_MPI_RANK", std::vector() ); for ( long g : v ) { - if ( x == g ) return true; + if ( x == g ) + return true; } return false; } diff --git a/src/atlas_f/internals/atlas_read_file.cc b/src/atlas_f/internals/atlas_read_file.cc index cd34f2398..c0aeb8e72 100644 --- a/src/atlas_f/internals/atlas_read_file.cc +++ b/src/atlas_f/internals/atlas_read_file.cc @@ -24,7 +24,9 @@ void read_file( const eckit::PathName& p, std::ostream& out ) { if ( p.exists() ) { std::ifstream in; in.open( p.asString().c_str() ); - if ( !in ) { throw_CantOpenFile( p.asString(), Here() ); } + if ( !in ) { + throw_CantOpenFile( p.asString(), Here() ); + } else { out << in.rdbuf(); in.close(); diff --git a/src/sandbox/benchmark_ifs_setup/atlas-benchmark-ifs-setup.cc b/src/sandbox/benchmark_ifs_setup/atlas-benchmark-ifs-setup.cc index 788ae8a39..e8c45e06c 100644 --- a/src/sandbox/benchmark_ifs_setup/atlas-benchmark-ifs-setup.cc +++ b/src/sandbox/benchmark_ifs_setup/atlas-benchmark-ifs-setup.cc @@ -81,7 +81,8 @@ int Tool::execute( const Args& args ) { args.get( "grid", key ); std::string path_in_str = ""; - if ( args.get( "grid", path_in_str ) ) path_in = path_in_str; + if ( args.get( "grid", path_in_str ) ) + path_in = path_in_str; StructuredGrid grid; if ( key.size() ) { @@ -95,7 +96,8 @@ int Tool::execute( const Args& args ) { Log::error() << "No grid specified." << std::endl; } - if ( !grid ) return failed(); + if ( !grid ) + return failed(); size_t halo = args.getLong( "halo", halo_default() ); diff --git a/src/sandbox/benchmark_sorting/atlas-benchmark-sorting.cc b/src/sandbox/benchmark_sorting/atlas-benchmark-sorting.cc index 54239ead6..9ead95443 100644 --- a/src/sandbox/benchmark_sorting/atlas-benchmark-sorting.cc +++ b/src/sandbox/benchmark_sorting/atlas-benchmark-sorting.cc @@ -148,7 +148,9 @@ void make_nodes_global_index_human_readable( const mesh::actions::BuildHalo& bui gidx_t gid = glb_idx_max; for ( size_t jnode = 0; jnode < node_sort.size(); ++jnode ) { - if ( jnode == 0 ) { ++gid; } + if ( jnode == 0 ) { + ++gid; + } else if ( node_sort[jnode].g != node_sort[jnode - 1].g ) { ++gid; } @@ -208,7 +210,8 @@ int Tool::execute( const Args& args ) { args.get( "grid", key ); std::string path_in_str = ""; - if ( args.get( "grid", path_in_str ) ) path_in = path_in_str; + if ( args.get( "grid", path_in_str ) ) + path_in = path_in_str; StructuredGrid grid; if ( key.size() ) { @@ -222,7 +225,8 @@ int Tool::execute( const Args& args ) { Log::error() << "No grid specified." << std::endl; } - if ( !grid ) return failed(); + if ( !grid ) + return failed(); Log::debug() << "Domain: " << grid.domain() << std::endl; Log::debug() << "Periodic: " << grid.periodic() << std::endl; diff --git a/src/sandbox/grid_distribution/atlas-grid-distribution.cc b/src/sandbox/grid_distribution/atlas-grid-distribution.cc index ea6f24eba..072a7c44b 100644 --- a/src/sandbox/grid_distribution/atlas-grid-distribution.cc +++ b/src/sandbox/grid_distribution/atlas-grid-distribution.cc @@ -73,7 +73,8 @@ int Tool::execute( const Args& args ) { args.get( "grid.name", key ); std::string path_in_str = ""; - if ( args.get( "grid.json", path_in_str ) ) path_in = path_in_str; + if ( args.get( "grid.json", path_in_str ) ) + path_in = path_in_str; StructuredGrid grid; if ( key.size() ) { @@ -96,13 +97,15 @@ int Tool::execute( const Args& args ) { Log::error() << "No grid specified." << std::endl; } - if ( !grid ) return failed(); + if ( !grid ) + return failed(); Log::debug() << "Domain: " << grid.domain() << std::endl; Log::debug() << "Periodic: " << grid.periodic() << std::endl; std::string partitioner_type; - if ( not args.get( "partitioner", partitioner_type ) ) partitioner_type = "equal_regions"; + if ( not args.get( "partitioner", partitioner_type ) ) + partitioner_type = "equal_regions"; long N = mpi::comm().size(); args.get( "partitions", N ); diff --git a/src/sandbox/interpolation/PartitionedMesh.cc b/src/sandbox/interpolation/PartitionedMesh.cc index 57b221fa2..094e51c9f 100644 --- a/src/sandbox/interpolation/PartitionedMesh.cc +++ b/src/sandbox/interpolation/PartitionedMesh.cc @@ -37,7 +37,9 @@ void PartitionedMesh::writeGmsh( const std::string& fileName, const FieldSet& fi output::Gmsh out( fileName, output_config ); out.write( mesh_ ); - if ( not fields.empty() ) { out.write( fields ); } + if ( not fields.empty() ) { + out.write( fields ); + } } void PartitionedMesh::partition( const Grid& grid ) { diff --git a/src/sandbox/interpolation/atlas-parallel-interpolation.cc b/src/sandbox/interpolation/atlas-parallel-interpolation.cc index 3d342ec37..a79df2f5f 100644 --- a/src/sandbox/interpolation/atlas-parallel-interpolation.cc +++ b/src/sandbox/interpolation/atlas-parallel-interpolation.cc @@ -38,7 +38,9 @@ auto vortex_rollup = []( double lon, double lat, double t ) { const double rho = 3. * std::sqrt( 1. - sqr( std::cos( lat ) ) * sqr( std::sin( lon - Omega * t ) ) ); double omega = 0.; double a = util::Earth::radius(); - if ( rho != 0. ) { omega = 0.5 * 3 * std::sqrt( 3 ) * a * Omega * sqr( sech( rho ) ) * std::tanh( rho ) / rho; } + if ( rho != 0. ) { + omega = 0.5 * 3 * std::sqrt( 3 ) * a * Omega * sqr( sech( rho ) ) * std::tanh( rho ) / rho; + } double q = 1. - std::tanh( 0.2 * rho * std::sin( lambda_prime - omega / a * t ) ); return q; }; @@ -111,13 +113,17 @@ int AtlasParallelInterpolation::execute( const AtlasTool::Args& args ) { idx_t log_rank = 0; args.get( "log-rank", log_rank ); - if ( idx_t( eckit::mpi::comm().rank() ) != log_rank ) { Log::reset(); } + if ( idx_t( eckit::mpi::comm().rank() ) != log_rank ) { + Log::reset(); + } std::string interpolation_method = "finite-element"; args.get( "method", interpolation_method ); - if ( args.get( "backend", option ) ) { eckit::linalg::LinearAlgebra::backend( option ); } + if ( args.get( "backend", option ) ) { + eckit::linalg::LinearAlgebra::backend( option ); + } // Generate and partition source & target mesh // source mesh is partitioned on its own, the target mesh uses @@ -194,7 +200,9 @@ int AtlasParallelInterpolation::execute( const AtlasTool::Args& args ) { Interpolation( option::type( backward_interpolation_method ), tgt_functionspace, src_functionspace ); } - if ( args.getBool( "forward-interpolator-output", false ) ) { interpolator_forward.print( Log::info() ); } + if ( args.getBool( "forward-interpolator-output", false ) ) { + interpolator_forward.print( Log::info() ); + } // Create source FunctionSpace and fields diff --git a/src/tests/AtlasTestEnvironment.h b/src/tests/AtlasTestEnvironment.h index 04e6a9721..76bb532a3 100644 --- a/src/tests/AtlasTestEnvironment.h +++ b/src/tests/AtlasTestEnvironment.h @@ -77,7 +77,8 @@ using eckit::types::is_approximately_equal; if ( ( _num_subsections - 1 ) == _subsection ) { \ atlas::Log::info() << "Running section \"" << _test_subsection << "\" ..." << std::endl; \ } \ - if ( ( _num_subsections - 1 ) == _subsection ) ATLAS_TRACE_SCOPE( _test_subsection ) + if ( ( _num_subsections - 1 ) == _subsection ) \ + ATLAS_TRACE_SCOPE( _test_subsection ) #ifndef SETUP #define SETUP( name ) @@ -97,7 +98,9 @@ static int barrier_timeout( double seconds ) { watch.start(); std::this_thread::sleep_for( std::chrono::milliseconds( 100 ) ); watch.stop(); - if ( watch.elapsed() > seconds ) { return 1; } + if ( watch.elapsed() > seconds ) { + return 1; + } } return 0; } @@ -128,7 +131,8 @@ void debug_addTarget( eckit::LogTarget* target ) { lib.debugChannel().addTarget( new eckit::PrefixTarget( debug_prefix( libname ), target ) ); } } - if ( eckit::Log::debug() ) eckit::Log::debug().addTarget( target ); + if ( eckit::Log::debug() ) + eckit::Log::debug().addTarget( target ); } void debug_setTarget( eckit::LogTarget* target ) { @@ -138,24 +142,32 @@ void debug_setTarget( eckit::LogTarget* target ) { lib.debugChannel().setTarget( new eckit::PrefixTarget( debug_prefix( libname ), target ) ); } } - if ( eckit::Log::debug() ) eckit::Log::debug().setTarget( target ); + if ( eckit::Log::debug() ) + eckit::Log::debug().setTarget( target ); } void debug_reset() { for ( std::string libname : eckit::system::Library::list() ) { const eckit::system::Library& lib = eckit::system::Library::lookup( libname ); - if ( lib.debug() ) { lib.debugChannel().reset(); } + if ( lib.debug() ) { + lib.debugChannel().reset(); + } } - if ( eckit::Log::debug() ) eckit::Log::debug().reset(); + if ( eckit::Log::debug() ) + eckit::Log::debug().reset(); } bool getEnv( const std::string& env, bool default_value ) { - if ( ::getenv( env.c_str() ) ) { return eckit::Translator()( ::getenv( env.c_str() ) ); } + if ( ::getenv( env.c_str() ) ) { + return eckit::Translator()( ::getenv( env.c_str() ) ); + } return default_value; } int getEnv( const std::string& env, int default_value ) { - if ( ::getenv( env.c_str() ) ) { return eckit::Translator()( ::getenv( env.c_str() ) ); } + if ( ::getenv( env.c_str() ) ) { + return eckit::Translator()( ::getenv( env.c_str() ) ); + } return default_value; } diff --git a/src/tests/acceptance_tests/atest_mgrids.cc b/src/tests/acceptance_tests/atest_mgrids.cc index 9702a62dc..027057d83 100644 --- a/src/tests/acceptance_tests/atest_mgrids.cc +++ b/src/tests/acceptance_tests/atest_mgrids.cc @@ -107,7 +107,9 @@ int Program::execute( const Args& args ) { Log::Channel checksums; checksums.addStream( Log::info() ); - if ( mpi::comm().rank() == 0 ) { checksums.addFile( checksum_filepath ); } + if ( mpi::comm().rank() == 0 ) { + checksums.addFile( checksum_filepath ); + } checksums << "Field A checksum before interpolation AtoB: " << fsA.checksum( fieldA ) << std::endl; @@ -185,7 +187,9 @@ int Program::execute( const Args& args ) { // Gmsh output if ( args.getBool( "gmsh", false ) ) { - if ( not meshB ) { meshB = meshgenerator.generate( gridB, distB ); } + if ( not meshB ) { + meshB = meshgenerator.generate( gridB, distB ); + } auto gmshA = output::Gmsh( displayName() + "_meshA.msh", ghost ); gmshA.write( meshA ); @@ -218,7 +222,9 @@ double vortex_rollup( double lon, double lat, double t, double mean ) { const double rho = 3. * std::sqrt( 1. - sqr( std::cos( lat ) ) * sqr( std::sin( lon - Omega * t ) ) ); double omega = 0.; double a = util::Earth::radius(); - if ( rho != 0. ) { omega = 0.5 * 3 * std::sqrt( 3 ) * a * Omega * sqr( sech( rho ) ) * std::tanh( rho ) / rho; } + if ( rho != 0. ) { + omega = 0.5 * 3 * std::sqrt( 3 ) * a * Omega * sqr( sech( rho ) ) * std::tanh( rho ) / rho; + } double q = mean - std::tanh( 0.2 * rho * std::sin( lambda_prime - omega / a * t ) ); return q; }; diff --git a/src/tests/array/test_array.cc b/src/tests/array/test_array.cc index 4bf6394f1..c8b1c91d2 100644 --- a/src/tests/array/test_array.cc +++ b/src/tests/array/test_array.cc @@ -255,7 +255,8 @@ CASE( "test_copy_gt_ctr" ) { ATLAS_DEBUG_VAR( dims[0] ); ATLAS_DEBUG_VAR( dims[1] ); EXPECT( dims[0] == 3 ); - if ( NOT_PADDED ) EXPECT( dims[1] == 2 ); + if ( NOT_PADDED ) + EXPECT( dims[1] == 2 ); delete ds; } #endif @@ -542,7 +543,8 @@ CASE( "test_valid" ) { CASE( "test_wrap" ) { array::ArrayT arr_t( 3, 2 ); EXPECT( arr_t.shape( 0 ) == 3 ); - if ( NOT_PADDED ) EXPECT( arr_t.stride( 0 ) == 2 ); + if ( NOT_PADDED ) + EXPECT( arr_t.stride( 0 ) == 2 ); EXPECT( arr_t.shape( 1 ) == 2 ); EXPECT( arr_t.stride( 1 ) == 1 ); EXPECT( arr_t.rank() == 2 ); diff --git a/src/tests/functionspace/test_functionspace.cc b/src/tests/functionspace/test_functionspace.cc index e99b78237..35354db05 100644 --- a/src/tests/functionspace/test_functionspace.cc +++ b/src/tests/functionspace/test_functionspace.cc @@ -45,7 +45,9 @@ CASE( "test_functionspace_NodeColumns_no_halo" ) { array::ArrayView ghost = array::make_view( mesh.nodes().ghost() ); const size_t nb_nodes = mesh.nodes().size(); for ( size_t j = 0; j < nb_nodes; ++j ) { - if ( ghost( j ) ) { value( j ) = -1; } + if ( ghost( j ) ) { + value( j ) = -1; + } else { value( j ) = 1; } @@ -178,7 +180,8 @@ CASE( "test_functionspace_NodeColumns" ) { // glb_field->dump( Log::info() ); - if ( mpi::comm().rank() == root ) glb_field.metadata().set( "test_broadcast", 123 ); + if ( mpi::comm().rank() == root ) + glb_field.metadata().set( "test_broadcast", 123 ); arr.assign( -1 ); nodes_fs.scatter( glb_field, field ); @@ -553,7 +556,8 @@ CASE( "test_SpectralFunctionSpace_trans_global" ) { EXPECT( surface_scalar_field.name() == std::string( "scalar" ) ); - if ( eckit::mpi::comm().rank() == 0 ) EXPECT( surface_scalar_field.size() == nspec2g ); + if ( eckit::mpi::comm().rank() == 0 ) + EXPECT( surface_scalar_field.size() == nspec2g ); EXPECT( surface_scalar_field.rank() == 1 ); @@ -563,12 +567,16 @@ CASE( "test_SpectralFunctionSpace_trans_global" ) { auto surface_scalar = array::make_view( surface_scalar_field ); - if ( eckit::mpi::comm().rank() == 0 ) { EXPECT( surface_scalar.shape( 0 ) == nspec2g ); } + if ( eckit::mpi::comm().rank() == 0 ) { + EXPECT( surface_scalar.shape( 0 ) == nspec2g ); + } Field columns_scalar_field = spectral_fs.createField( option::name( "scalar" ) | option::global() ); EXPECT( columns_scalar_field.name() == std::string( "scalar" ) ); - if ( eckit::mpi::comm().rank() == 0 ) { EXPECT( columns_scalar_field.size() == nspec2g * nb_levels ); } + if ( eckit::mpi::comm().rank() == 0 ) { + EXPECT( columns_scalar_field.size() == nspec2g * nb_levels ); + } else { EXPECT( columns_scalar_field.size() == 0 ); } @@ -595,12 +603,14 @@ CASE( "test_SpectralFunctionSpace_norm" ) { { auto twoD = array::make_view( twoD_field ); twoD.assign( 0. ); - if ( mpi::comm().rank() == 0 ) twoD( 0 ) = 1.; + if ( mpi::comm().rank() == 0 ) + twoD( 0 ) = 1.; auto threeD = array::make_view( threeD_field ); threeD.assign( 0. ); for ( size_t jlev = 0; jlev < nb_levels; ++jlev ) { - if ( mpi::comm().rank() == 0 ) threeD( 0, jlev ) = jlev; + if ( mpi::comm().rank() == 0 ) + threeD( 0, jlev ) = jlev; } } diff --git a/src/tests/functionspace/test_reduced_halo.cc b/src/tests/functionspace/test_reduced_halo.cc index 5b2652186..992886ad5 100644 --- a/src/tests/functionspace/test_reduced_halo.cc +++ b/src/tests/functionspace/test_reduced_halo.cc @@ -52,7 +52,9 @@ CASE( "halo nodes" ) { for ( int h : ( reduce ? reversed( halos ) : halos ) ) { NodeColumns fs( mesh, option::halo( h ) ); - if ( mpi::comm().size() == 1 ) { EXPECT( fs.nb_nodes() == nodes[h] ); } + if ( mpi::comm().size() == 1 ) { + EXPECT( fs.nb_nodes() == nodes[h] ); + } } } } @@ -76,7 +78,9 @@ CASE( "halo edges" ) { for ( int h : ( reduce ? reversed( halos ) : halos ) ) { EdgeColumns fs( mesh, option::halo( h ) | option::pole_edges( with_pole_edges ) ); - if ( mpi::comm().size() == 1 ) { EXPECT( fs.nb_edges() == edges[h] + pole_edges ); } + if ( mpi::comm().size() == 1 ) { + EXPECT( fs.nb_edges() == edges[h] + pole_edges ); + } } } } diff --git a/src/tests/functionspace/test_stencil.cc b/src/tests/functionspace/test_stencil.cc index 086160642..49754987f 100644 --- a/src/tests/functionspace/test_stencil.cc +++ b/src/tests/functionspace/test_stencil.cc @@ -216,7 +216,9 @@ CASE( "test vertical stencil" ) { Log::info() << stencil.k( k ) << "[" << vertical[stencil.k( k )] << "] "; } Log::info() << " interval = " << stencil.k_interval() << std::endl; - if ( p < vertical[0] ) { EXPECT( stencil.k_interval() == -1 ); } + if ( p < vertical[0] ) { + EXPECT( stencil.k_interval() == -1 ); + } else if ( p < vertical[1] ) { EXPECT( stencil.k_interval() == 0 ); } diff --git a/src/tests/grid/test_grid_hash.cc b/src/tests/grid/test_grid_hash.cc index ce6f2d950..d94f6463c 100644 --- a/src/tests/grid/test_grid_hash.cc +++ b/src/tests/grid/test_grid_hash.cc @@ -42,7 +42,9 @@ CASE( "test_global" ) { SECTION( "grid: " + std::to_string( c ) ) { Hash h; grid.hash( h ); - if ( hash.empty() ) { Log::info() << "grid " << c << " hash = " << std::string( h ) << std::endl; } + if ( hash.empty() ) { + Log::info() << "grid " << c << " hash = " << std::string( h ) << std::endl; + } EXPECT( std::string( h ) == hash ); } c++; diff --git a/src/tests/grid/test_grid_ptr.cc b/src/tests/grid/test_grid_ptr.cc index eaf68f2db..902b7d732 100644 --- a/src/tests/grid/test_grid_ptr.cc +++ b/src/tests/grid/test_grid_ptr.cc @@ -187,7 +187,8 @@ CASE( "test_iterator_with_predicate" ) { auto filter = []( long n ) { bool b = ( n >= 5 && n < 10 ); - if ( b ) Log::debug() << "n = " << n << std::endl; + if ( b ) + Log::debug() << "n = " << n << std::endl; return b; }; diff --git a/src/tests/grid/test_state.cc b/src/tests/grid/test_state.cc index c9b2955f9..fa91a235b 100644 --- a/src/tests/grid/test_state.cc +++ b/src/tests/grid/test_state.cc @@ -48,7 +48,9 @@ class MyStateGenerator : public StateGenerator { // --- Implementation (in .cc file) void MyStateGenerator::generate( State& state, const eckit::Parametrisation& p ) const { const util::Config* params = dynamic_cast( &p ); - if ( !params ) { throw_Exception( "Parametrisation has to be of atlas::util::Config type" ); } + if ( !params ) { + throw_Exception( "Parametrisation has to be of atlas::util::Config type" ); + } util::Config geometry; if ( !params->get( "geometry", geometry ) ) { @@ -58,10 +60,14 @@ void MyStateGenerator::generate( State& state, const eckit::Parametrisation& p ) std::string grid_uid; if ( geometry.get( "grid", grid_uid ) ) { Grid grid( grid_uid ); - if ( !geometry.has( "ngptot" ) ) { geometry.set( "ngptot", grid.size() ); } + if ( !geometry.has( "ngptot" ) ) { + geometry.set( "ngptot", grid.size() ); + } } - if ( !geometry.has( "ngptot" ) ) { throw_Exception( "Could not find 'ngptot' in Parametrisation" ); } + if ( !geometry.has( "ngptot" ) ) { + throw_Exception( "Could not find 'ngptot' in Parametrisation" ); + } std::vector fields; if ( params->get( "fields", fields ) ) { diff --git a/src/tests/interpolation/CubicInterpolationPrototype.h b/src/tests/interpolation/CubicInterpolationPrototype.h index 545d8687d..28780b573 100644 --- a/src/tests/interpolation/CubicInterpolationPrototype.h +++ b/src/tests/interpolation/CubicInterpolationPrototype.h @@ -157,7 +157,9 @@ class CubicVerticalInterpolation { if ( limiter_ ) { idx_t k = stencil.k_interval(); idx_t k1, k2; - if ( k < 0 ) { k1 = k2 = 0; } + if ( k < 0 ) { + k1 = k2 = 0; + } else if ( k > 2 ) { k1 = k2 = 3; } @@ -272,7 +274,9 @@ class CubicHorizontalInterpolation { } } - if ( limiter_ ) { limit( output, index, input ); } + if ( limiter_ ) { + limit( output, index, input ); + } } template diff --git a/src/tests/interpolation/test_interpolation_cubic_prototype.cc b/src/tests/interpolation/test_interpolation_cubic_prototype.cc index 3808f3053..0109304c9 100644 --- a/src/tests/interpolation/test_interpolation_cubic_prototype.cc +++ b/src/tests/interpolation/test_interpolation_cubic_prototype.cc @@ -135,9 +135,12 @@ CASE( "test horizontal cubic interpolation" ) { //----------------------------------------------------------------------------- bool operator==( const eckit::linalg::Triplet& t1, const eckit::linalg::Triplet& t2 ) { - if ( t1.row() != t2.row() ) return false; - if ( t1.col() != t2.col() ) return false; - if ( !is_approximately_equal( t1.value(), t2.value() ) ) return false; + if ( t1.row() != t2.row() ) + return false; + if ( t1.col() != t2.col() ) + return false; + if ( !is_approximately_equal( t1.value(), t2.value() ) ) + return false; return true; } @@ -145,9 +148,11 @@ bool operator!=( const eckit::linalg::Triplet& t1, const eckit::linalg::Triplet& return !( t1 == t2 ); } bool operator==( const std::vector& t1, const std::vector& t2 ) { - if ( t1.size() != t2.size() ) return false; + if ( t1.size() != t2.size() ) + return false; for ( size_t i = 0; i < t1.size(); ++i ) { - if ( t1[i] != t2[i] ) return false; + if ( t1[i] != t2[i] ) + return false; } return true; } @@ -155,7 +160,9 @@ std::ostream& operator<<( std::ostream& out, const LocalView& array ) out << "{ "; for ( idx_t i = 0; i < array.size(); ++i ) { out << array( i ); - if ( i < array.size() - 1 ) { out << ","; } + if ( i < array.size() - 1 ) { + out << ","; + } out << " "; } out << "}"; diff --git a/src/tests/interpolation/test_interpolation_structured2D.cc b/src/tests/interpolation/test_interpolation_structured2D.cc index 2a766cc50..177418385 100644 --- a/src/tests/interpolation/test_interpolation_structured2D.cc +++ b/src/tests/interpolation/test_interpolation_structured2D.cc @@ -133,7 +133,9 @@ double vortex_rollup( double lon, double lat, double t ) { const double rho = 3. * std::sqrt( 1. - sqr( std::cos( lat ) ) * sqr( std::sin( lon - Omega * t ) ) ); double omega = 0.; double a = util::Earth::radius(); - if ( rho != 0. ) { omega = 0.5 * 3 * std::sqrt( 3 ) * a * Omega * sqr( sech( rho ) ) * std::tanh( rho ) / rho; } + if ( rho != 0. ) { + omega = 0.5 * 3 * std::sqrt( 3 ) * a * Omega * sqr( sech( rho ) ) * std::tanh( rho ) / rho; + } double q = 1. - std::tanh( 0.2 * rho * std::sin( lambda_prime - omega / a * t ) ); return q; }; diff --git a/src/tests/io/test_pointcloud_io.cc b/src/tests/io/test_pointcloud_io.cc index 29cbe9106..110a70d6d 100644 --- a/src/tests/io/test_pointcloud_io.cc +++ b/src/tests/io/test_pointcloud_io.cc @@ -69,7 +69,8 @@ const std::vector fnames( test_arrays::fnames, test_arrays::fnames } // namespace test_vectors bool test_write_file( const std::string& file_path, const size_t& nb_pts, const size_t& nb_columns ) { - if ( !nb_pts ) return false; + if ( !nb_pts ) + return false; std::ofstream f( file_path.c_str() ); return ( f && f << "PointCloudIO " << nb_pts << " " << nb_columns << " lon lat f_1 " diff --git a/src/tests/mesh/test_distmesh.cc b/src/tests/mesh/test_distmesh.cc index 3cb896f1c..5ff6f3fa2 100644 --- a/src/tests/mesh/test_distmesh.cc +++ b/src/tests/mesh/test_distmesh.cc @@ -52,7 +52,9 @@ double dual_volume( Mesh& mesh ) { double area = 0; for ( idx_t node = 0; node < nb_nodes; ++node ) { - if ( !is_ghost_node( node ) ) { area += dual_volumes( node ); } + if ( !is_ghost_node( node ) ) { + area += dual_volumes( node ); + } } ATLAS_TRACE_MPI( ALLREDUCE ) { mpi::comm().allReduceInPlace( area, eckit::mpi::sum() ); } @@ -94,7 +96,9 @@ CASE( "test_distribute_t63" ) { double computed_dual_volume = test::dual_volume( m ); EXPECT( eckit::types::is_approximately_equal( computed_dual_volume, 360. * 180., 0.0001 ) ); double difference = 360. * 180. - computed_dual_volume; - if ( difference > 1e-8 ) { std::cout << "difference = " << difference << std::endl; } + if ( difference > 1e-8 ) { + std::cout << "difference = " << difference << std::endl; + } Gmsh( "dist.msh" ).write( m ); diff --git a/src/tests/mesh/test_halo.cc b/src/tests/mesh/test_halo.cc index e6ab04457..bff82541a 100644 --- a/src/tests/mesh/test_halo.cc +++ b/src/tests/mesh/test_halo.cc @@ -49,7 +49,9 @@ double dual_volume( Mesh& mesh ) { array::ArrayView dual_volumes = array::make_view( nodes.field( "dual_volumes" ) ); double area = 0; for ( int node = 0; node < nb_nodes; ++node ) { - if ( !is_ghost_node( node ) ) { area += dual_volumes( node ); } + if ( !is_ghost_node( node ) ) { + area += dual_volumes( node ); + } } ATLAS_TRACE_MPI( ALLREDUCE ) { mpi::comm().allReduceInPlace( area, eckit::mpi::sum() ); } diff --git a/src/tests/mesh/test_parfields.cc b/src/tests/mesh/test_parfields.cc index dfd2460be..95b7631ae 100644 --- a/src/tests/mesh/test_parfields.cc +++ b/src/tests/mesh/test_parfields.cc @@ -49,8 +49,10 @@ class IsGhost { mypart_( mpi::comm().rank() ) {} bool operator()( idx_t idx ) const { - if ( part_( idx ) != mypart_ ) return true; - if ( ridx_( idx ) != idx ) return true; + if ( part_( idx ) != mypart_ ) + return true; + if ( ridx_( idx ) != idx ) + return true; return false; } @@ -202,26 +204,31 @@ CASE( "test2" ) { idx_t nb_ghost = 0; for ( idx_t jnode = 0; jnode < nodes.size(); ++jnode ) { - if ( is_ghost( jnode ) ) ++nb_ghost; + if ( is_ghost( jnode ) ) + ++nb_ghost; } ATLAS_DEBUG_VAR( nb_ghost ); - if ( mpi::comm().rank() == 0 ) EXPECT( nb_ghost == 128 ); // South boundary of Northern hemisphere - if ( mpi::comm().rank() == 1 ) EXPECT( nb_ghost == 0 ); // Southern hemisphere has no ghosts + if ( mpi::comm().rank() == 0 ) + EXPECT( nb_ghost == 128 ); // South boundary of Northern hemisphere + if ( mpi::comm().rank() == 1 ) + EXPECT( nb_ghost == 0 ); // Southern hemisphere has no ghosts mesh::actions::build_periodic_boundaries( m ); int nb_periodic = -nb_ghost; for ( idx_t jnode = 0; jnode < nodes.size(); ++jnode ) { - if ( is_ghost( jnode ) ) ++nb_periodic; + if ( is_ghost( jnode ) ) + ++nb_periodic; } ATLAS_DEBUG_VAR( nb_periodic ); if ( mpi::comm().rank() == 0 ) - EXPECT( nb_periodic == 33 ); // Periodic East boundary of Northern hemisphere - // (plus one point south) - if ( mpi::comm().rank() == 1 ) EXPECT( nb_periodic == 32 ); // Periodic East boundary of Southern hemisphere + EXPECT( nb_periodic == 33 ); // Periodic East boundary of Northern hemisphere + // (plus one point south) + if ( mpi::comm().rank() == 1 ) + EXPECT( nb_periodic == 32 ); // Periodic East boundary of Southern hemisphere Gmsh( "periodic.msh", util::Config( "info", true ) ).write( m ); } diff --git a/src/tests/mesh/test_rgg.cc b/src/tests/mesh/test_rgg.cc index cdbd43c44..b383980e3 100644 --- a/src/tests/mesh/test_rgg.cc +++ b/src/tests/mesh/test_rgg.cc @@ -401,7 +401,9 @@ ASSERT(0); } for ( size_t gid = 1; gid <= all_owned.size(); ++gid ) { - if ( all_owned[gid - 1] == -1 ) { Log::error() << "node " << gid << " is not owned by anyone" << std::endl; } + if ( all_owned[gid - 1] == -1 ) { + Log::error() << "node " << gid << " is not owned by anyone" << std::endl; + } } EXPECT( nb_owned == grid.size() ); diff --git a/src/tests/mesh/test_shapefunctions.cc b/src/tests/mesh/test_shapefunctions.cc index 823ae51bf..97c5e9027 100644 --- a/src/tests/mesh/test_shapefunctions.cc +++ b/src/tests/mesh/test_shapefunctions.cc @@ -100,7 +100,8 @@ class Polynomial { public: Polynomial& add( const monomial_type& mononomial ) { - if ( mononomial.coeff != 0 ) mononomials_.push_back( mononomial ); + if ( mononomial.coeff != 0 ) + mononomials_.push_back( mononomial ); return *this; } @@ -169,7 +170,9 @@ class Polynomial { static std::vector curl( const std::vector& pvec ) { std::vector p( 3 ); - if ( NDIM == 2 ) { p[2] = pvec[1].deriv( 0 ) - pvec[0].deriv( 1 ); } + if ( NDIM == 2 ) { + p[2] = pvec[1].deriv( 0 ) - pvec[0].deriv( 1 ); + } if ( NDIM == 3 ) { p[0] = pvec[2].deriv( 1 ) - pvec[1].deriv( 2 ); p[1] = pvec[0].deriv( 2 ) - pvec[2].deriv( 0 ); @@ -215,7 +218,9 @@ class Polynomial { } } for ( size_t j = 0; j < other.mononomials_.size(); ++j ) { - if ( !matched[j] ) { add( other.mononomials_[j] ); } + if ( !matched[j] ) { + add( other.mononomials_[j] ); + } } return *this; } @@ -421,7 +426,8 @@ class NewFunctionSpace { /// @brief Set the total number of nodes in FunctionSpace void set_nb_nodes( int nb_nodes ) { nb_nodes_ = nb_nodes; - if ( nproma_ == 0 ) nproma_ = 1; + if ( nproma_ == 0 ) + nproma_ = 1; ATLAS_ASSERT( nb_nodes_ % nproma_ == 0 ); nblk_ = nb_nodes_ / nproma_; } @@ -441,12 +447,18 @@ class NewFunctionSpace { /// @brief Add elements const ElementType& add_elements( const std::string& element_type, int nelem ) { - if ( element_type == "Polygon" ) element_types_.push_back( ElementType::Ptr( new Polygon() ) ); - if ( element_type == "QuadP1" ) element_types_.push_back( ElementType::Ptr( new QuadP1 ) ); - if ( element_type == "TriagP1" ) element_types_.push_back( ElementType::Ptr( new TriagP1 ) ); - if ( element_type == "LineP0" ) element_types_.push_back( ElementType::Ptr( new LineP0 ) ); - if ( element_type == "LineP1" ) element_types_.push_back( ElementType::Ptr( new LineP1 ) ); - if ( element_type == "LineP2" ) element_types_.push_back( ElementType::Ptr( new LineP2 ) ); + if ( element_type == "Polygon" ) + element_types_.push_back( ElementType::Ptr( new Polygon() ) ); + if ( element_type == "QuadP1" ) + element_types_.push_back( ElementType::Ptr( new QuadP1 ) ); + if ( element_type == "TriagP1" ) + element_types_.push_back( ElementType::Ptr( new TriagP1 ) ); + if ( element_type == "LineP0" ) + element_types_.push_back( ElementType::Ptr( new LineP0 ) ); + if ( element_type == "LineP1" ) + element_types_.push_back( ElementType::Ptr( new LineP1 ) ); + if ( element_type == "LineP2" ) + element_types_.push_back( ElementType::Ptr( new LineP2 ) ); index_[element_type] = nelem_per_type_.size(); nelem_per_type_.push_back( nelem ); @@ -475,13 +487,20 @@ class NewFunctionSpace { int idx7 = IDX_NOTUSED ) { atlas::array::ArrayShape shape; shape.reserve( 7 ); - if ( idx1 != IDX_NOTUSED ) shape.push_back( range( idx1 ) ); - if ( idx2 != IDX_NOTUSED ) shape.push_back( range( idx2 ) ); - if ( idx3 != IDX_NOTUSED ) shape.push_back( range( idx3 ) ); - if ( idx4 != IDX_NOTUSED ) shape.push_back( range( idx4 ) ); - if ( idx5 != IDX_NOTUSED ) shape.push_back( range( idx5 ) ); - if ( idx6 != IDX_NOTUSED ) shape.push_back( range( idx6 ) ); - if ( idx7 != IDX_NOTUSED ) shape.push_back( range( idx7 ) ); + if ( idx1 != IDX_NOTUSED ) + shape.push_back( range( idx1 ) ); + if ( idx2 != IDX_NOTUSED ) + shape.push_back( range( idx2 ) ); + if ( idx3 != IDX_NOTUSED ) + shape.push_back( range( idx3 ) ); + if ( idx4 != IDX_NOTUSED ) + shape.push_back( range( idx4 ) ); + if ( idx5 != IDX_NOTUSED ) + shape.push_back( range( idx5 ) ); + if ( idx6 != IDX_NOTUSED ) + shape.push_back( range( idx6 ) ); + if ( idx7 != IDX_NOTUSED ) + shape.push_back( range( idx7 ) ); atlas::array::ArrayT field( shape ); return field; } @@ -498,7 +517,8 @@ class NewFunctionSpace { case IDX_NPROMA: return nproma(); default: - if ( idx_type >= 0 ) return idx_type; + if ( idx_type >= 0 ) + return idx_type; } throw_Exception( "idx_type not recognized" ); return 0; diff --git a/src/tests/numerics/test_fvm_nabla.cc b/src/tests/numerics/test_fvm_nabla.cc index 0238dea07..7b568a2e7 100644 --- a/src/tests/numerics/test_fvm_nabla.cc +++ b/src/tests/numerics/test_fvm_nabla.cc @@ -50,7 +50,9 @@ double dual_volume( const Mesh& mesh ) { const array::ArrayView is_ghost = array::make_view( nodes.ghost() ); double area = 0; for ( int node = 0; node < nb_nodes; ++node ) { - if ( !is_ghost( node ) ) { area += dual_volumes( node ); } + if ( !is_ghost( node ) ) { + area += dual_volumes( node ); + } } mpi::comm().allReduceInPlace( area, eckit::mpi::sum() ); diff --git a/src/tests/projection/FindGoodWest.h b/src/tests/projection/FindGoodWest.h index 740d31c51..016a7895f 100644 --- a/src/tests/projection/FindGoodWest.h +++ b/src/tests/projection/FindGoodWest.h @@ -111,7 +111,8 @@ struct WestFinder { auto top_bottom = std::array{0, grid.ny() - 1}; for ( idx_t j : top_bottom ) { for ( idx_t i = 0; i < grid.nx( j ); ++i ) { - if ( !in_bounds( i, j ) ) return false; + if ( !in_bounds( i, j ) ) + return false; } } } @@ -120,7 +121,8 @@ struct WestFinder { for ( idx_t j = 0; j < grid.ny(); ++j ) { auto left_right = std::array{0, grid.nx( j ) - 1}; for ( idx_t i : left_right ) { - if ( !in_bounds( i, j ) ) return false; + if ( !in_bounds( i, j ) ) + return false; } } } diff --git a/src/tests/projection/test_bounding_box.cc b/src/tests/projection/test_bounding_box.cc index 7e8770870..16f82907f 100644 --- a/src/tests/projection/test_bounding_box.cc +++ b/src/tests/projection/test_bounding_box.cc @@ -67,7 +67,9 @@ struct BoundingBox : public std::array { bool otherEmpty = !eckit::types::is_strictly_greater( other.north(), other.south() ) || !eckit::types::is_strictly_greater( other.east(), other.west() ); - if ( otherEmpty ) { return contains( other.south(), other.west() ); } + if ( otherEmpty ) { + return contains( other.south(), other.west() ); + } // check for West/East range (if non-periodic), then other's corners if ( east() - west() < other.east() - other.west() || east() < normalise( other.east(), west() ) ) { diff --git a/src/tests/projection/test_rotation.cc b/src/tests/projection/test_rotation.cc index c869d5cc2..407fcc3a7 100644 --- a/src/tests/projection/test_rotation.cc +++ b/src/tests/projection/test_rotation.cc @@ -88,7 +88,8 @@ class MagicsRotation { double PXROT = std::acos( ZCXROT ) * r2d; - if ( ZSXROT < 0.0 ) PXROT = -PXROT; + if ( ZSXROT < 0.0 ) + PXROT = -PXROT; return PointLonLat( PXROT, PYROT ); } @@ -110,7 +111,8 @@ class MagicsRotation { ZCXMXC = std::max( std::min( ZCXMXC, +1.0 ), -1.0 ); double ZSXMXC = cos_lat * sin_lat / ZCYREG; double ZXMXC = std::acos( ZCXMXC ) * r2d; - if ( ZSXMXC < 0.0 ) ZXMXC = -ZXMXC; + if ( ZSXMXC < 0.0 ) + ZXMXC = -ZXMXC; double PXREG = ZXMXC + south_pole_.lon(); return PointLonLat( PXREG, PYREG ); diff --git a/src/tests/runtime/test_trace.cc b/src/tests/runtime/test_trace.cc index f67e2226e..bcb347f08 100644 --- a/src/tests/runtime/test_trace.cc +++ b/src/tests/runtime/test_trace.cc @@ -45,7 +45,9 @@ CASE( "test trace OpenMP" ) { auto trace = Trace( Here(), "loop" ); if ( ATLAS_HAVE_OMP ) { trace.stop(); - if ( atlas_omp_get_thread_num() > 0 ) { EXPECT( trace.elapsed() == 0. ); } + if ( atlas_omp_get_thread_num() > 0 ) { + EXPECT( trace.elapsed() == 0. ); + } else { EXPECT( trace.elapsed() != 0. ); } diff --git a/src/tests/trans/test_trans.cc b/src/tests/trans/test_trans.cc index a78b7eb33..75693a9f3 100644 --- a/src/tests/trans/test_trans.cc +++ b/src/tests/trans/test_trans.cc @@ -54,7 +54,8 @@ namespace test { struct AtlasTransEnvironment : public AtlasTestEnvironment { AtlasTransEnvironment( int argc, char* argv[] ) : AtlasTestEnvironment( argc, argv ) { - if ( mpi::comm().size() == 1 ) trans_use_mpi( false ); + if ( mpi::comm().size() == 1 ) + trans_use_mpi( false ); trans_init(); } @@ -360,7 +361,9 @@ CASE( "test_nomesh" ) { if ( not spf.contiguous() ) { EXPECT_THROWS_AS( spectral.scatter( spfg, spf ), eckit::Exception ); - if ( mpi::comm().size() == 1 ) { spf = spfg; } + if ( mpi::comm().size() == 1 ) { + spf = spfg; + } else { return; } @@ -397,7 +400,9 @@ CASE( "test_nomesh" ) { if ( not spf.contiguous() ) { EXPECT_THROWS_AS( spectral.gather( spf, spfg ), eckit::Exception ); - if ( mpi::comm().size() == 1 ) { spfg = spf; } + if ( mpi::comm().size() == 1 ) { + spfg = spf; + } else { return; } diff --git a/src/tests/trans/test_trans_invtrans_grad.cc b/src/tests/trans/test_trans_invtrans_grad.cc index 52e994cea..f464ac88b 100644 --- a/src/tests/trans/test_trans_invtrans_grad.cc +++ b/src/tests/trans/test_trans_invtrans_grad.cc @@ -43,7 +43,8 @@ namespace test { struct AtlasTransEnvironment : public AtlasTestEnvironment { AtlasTransEnvironment( int argc, char* argv[] ) : AtlasTestEnvironment( argc, argv ) { - if ( mpi::comm().size() == 1 ) trans_use_mpi( false ); + if ( mpi::comm().size() == 1 ) + trans_use_mpi( false ); trans_init(); } diff --git a/src/tests/trans/test_trans_localcache.cc b/src/tests/trans/test_trans_localcache.cc index 636e01461..699177c7e 100644 --- a/src/tests/trans/test_trans_localcache.cc +++ b/src/tests/trans/test_trans_localcache.cc @@ -46,7 +46,8 @@ using LinearSpacing = grid::LinearSpacing; eckit::PathName CacheFile( const std::string& path ) { eckit::PathName cachefile( path ); - if ( cachefile.exists() ) cachefile.unlink(); + if ( cachefile.exists() ) + cachefile.unlink(); return cachefile; } @@ -111,7 +112,9 @@ CASE( "test_global_grids" ) { EXPECT( cache_creator.supported() ); auto cachefile = CacheFile( "leg_" + cache_creator.uid() + ".bin" ); cache_creator.create( cachefile ); - if ( GaussianGrid( grid ) ) { EXPECT( hash( cachefile ) == F_cache_hash ); } + if ( GaussianGrid( grid ) ) { + EXPECT( hash( cachefile ) == F_cache_hash ); + } ATLAS_TRACE_SCOPE( "create without cache" ) Trans( grid, truncation ); diff --git a/src/tests/trans/test_transgeneral.cc b/src/tests/trans/test_transgeneral.cc index b4b78ff1e..9bb5e076d 100644 --- a/src/tests/trans/test_transgeneral.cc +++ b/src/tests/trans/test_transgeneral.cc @@ -87,8 +87,11 @@ double sphericalharmonics_analytic_point( double a = util::Earth::radius(); // Fourier part of the spherical harmonics: double rft = 1.; - if ( m > 0 ) rft *= 2.; // the famous factor 2 that noone really understands - if ( imag == 0 ) { rft *= loncos; } + if ( m > 0 ) + rft *= 2.; // the famous factor 2 that noone really understands + if ( imag == 0 ) { + rft *= loncos; + } else { rft *= -lonsin; } @@ -105,36 +108,60 @@ double sphericalharmonics_analytic_point( // scalar: if ( ivar_in == 2 ) { if ( ivar_out == 2 ) { - if ( m == 0 && n == 0 ) return rft; - if ( m == 0 && n == 1 ) return std::sqrt( 3. ) * latsin * rft; - if ( m == 0 && n == 2 ) return std::sqrt( 5. ) / 2. * ( 3. * latsin * latsin - 1. ) * rft; // sign? + if ( m == 0 && n == 0 ) + return rft; + if ( m == 0 && n == 1 ) + return std::sqrt( 3. ) * latsin * rft; + if ( m == 0 && n == 2 ) + return std::sqrt( 5. ) / 2. * ( 3. * latsin * latsin - 1. ) * rft; // sign? if ( m == 0 && n == 3 ) return std::sqrt( 7. ) / 2. * ( 5. * latsin * latsin - 3. ) * latsin * rft; // sign? - if ( m == 1 && n == 1 ) return std::sqrt( 3. / 2. ) * latcos * rft; // sign? - if ( m == 1 && n == 2 ) return std::sqrt( 15. / 2. ) * latsin * latcos * rft; // sign? + if ( m == 1 && n == 1 ) + return std::sqrt( 3. / 2. ) * latcos * rft; // sign? + if ( m == 1 && n == 2 ) + return std::sqrt( 15. / 2. ) * latsin * latcos * rft; // sign? if ( m == 1 && n == 3 ) return std::sqrt( 21. ) / 4. * latcos * ( 5. * latsin * latsin - 1. ) * rft; // sign? - if ( m == 2 && n == 2 ) return std::sqrt( 15. / 2. ) / 2. * latcos * latcos * rft; - if ( m == 2 && n == 3 ) return std::sqrt( 105. / 2. ) / 2. * latcos * latcos * latsin * rft; - if ( m == 3 && n == 3 ) return std::sqrt( 35. ) / 4. * latcos * latcos * latcos * rft; // sign? - if ( m == 4 && n == 4 ) return ( 3 * std::sqrt( 17.5 ) * std::pow( latcos, 4 ) ) / 8. * rft; - if ( m == 5 && n == 5 ) return ( 3 * std::sqrt( 77 ) * std::pow( latcos, 5 ) ) / 16. * rft; - if ( m == 6 && n == 6 ) return ( std::sqrt( 3003 ) * std::pow( latcos, 6 ) ) / 32. * rft; - if ( m == 7 && n == 7 ) return ( 3 * std::sqrt( 357.5 ) * std::pow( latcos, 7 ) ) / 32. * rft; - if ( m == 8 && n == 8 ) return ( 3 * std::sqrt( 6077.5 ) * std::pow( latcos, 8 ) ) / 128. * rft; - if ( m == 9 && n == 9 ) return ( std::sqrt( 230945 ) * std::pow( latcos, 9 ) ) / 256. * rft; - if ( m == 10 && n == 10 ) return ( std::sqrt( 969969 ) * std::pow( latcos, 10 ) ) / 512. * rft; - if ( m == 11 && n == 11 ) return ( std::sqrt( 1.0140585e6 ) * std::pow( latcos, 11 ) ) / 512. * rft; - if ( m == 12 && n == 12 ) return ( 5 * std::sqrt( 676039 ) * std::pow( latcos, 12 ) ) / 2048. * rft; - if ( m == 13 && n == 13 ) return ( 15 * std::sqrt( 78004.5 ) * std::pow( latcos, 13 ) ) / 2048. * rft; - if ( m == 14 && n == 14 ) return ( 15 * std::sqrt( 323161.5 ) * std::pow( latcos, 14 ) ) / 4096. * rft; - if ( m == 15 && n == 15 ) return ( 3 * std::sqrt( 33393355 ) * std::pow( latcos, 15 ) ) / 8192. * rft; - if ( m == 16 && n == 16 ) return ( 3 * std::sqrt( 5.509903575e8 ) * std::pow( latcos, 16 ) ) / 32768. * rft; - if ( m == 17 && n == 17 ) return ( 15 * std::sqrt( 90751353 ) * std::pow( latcos, 17 ) ) / 65536. * rft; - if ( m == 18 && n == 18 ) return ( 5 * std::sqrt( 3357800061 ) * std::pow( latcos, 18 ) ) / 131072. * rft; + if ( m == 2 && n == 2 ) + return std::sqrt( 15. / 2. ) / 2. * latcos * latcos * rft; + if ( m == 2 && n == 3 ) + return std::sqrt( 105. / 2. ) / 2. * latcos * latcos * latsin * rft; + if ( m == 3 && n == 3 ) + return std::sqrt( 35. ) / 4. * latcos * latcos * latcos * rft; // sign? + if ( m == 4 && n == 4 ) + return ( 3 * std::sqrt( 17.5 ) * std::pow( latcos, 4 ) ) / 8. * rft; + if ( m == 5 && n == 5 ) + return ( 3 * std::sqrt( 77 ) * std::pow( latcos, 5 ) ) / 16. * rft; + if ( m == 6 && n == 6 ) + return ( std::sqrt( 3003 ) * std::pow( latcos, 6 ) ) / 32. * rft; + if ( m == 7 && n == 7 ) + return ( 3 * std::sqrt( 357.5 ) * std::pow( latcos, 7 ) ) / 32. * rft; + if ( m == 8 && n == 8 ) + return ( 3 * std::sqrt( 6077.5 ) * std::pow( latcos, 8 ) ) / 128. * rft; + if ( m == 9 && n == 9 ) + return ( std::sqrt( 230945 ) * std::pow( latcos, 9 ) ) / 256. * rft; + if ( m == 10 && n == 10 ) + return ( std::sqrt( 969969 ) * std::pow( latcos, 10 ) ) / 512. * rft; + if ( m == 11 && n == 11 ) + return ( std::sqrt( 1.0140585e6 ) * std::pow( latcos, 11 ) ) / 512. * rft; + if ( m == 12 && n == 12 ) + return ( 5 * std::sqrt( 676039 ) * std::pow( latcos, 12 ) ) / 2048. * rft; + if ( m == 13 && n == 13 ) + return ( 15 * std::sqrt( 78004.5 ) * std::pow( latcos, 13 ) ) / 2048. * rft; + if ( m == 14 && n == 14 ) + return ( 15 * std::sqrt( 323161.5 ) * std::pow( latcos, 14 ) ) / 4096. * rft; + if ( m == 15 && n == 15 ) + return ( 3 * std::sqrt( 33393355 ) * std::pow( latcos, 15 ) ) / 8192. * rft; + if ( m == 16 && n == 16 ) + return ( 3 * std::sqrt( 5.509903575e8 ) * std::pow( latcos, 16 ) ) / 32768. * rft; + if ( m == 17 && n == 17 ) + return ( 15 * std::sqrt( 90751353 ) * std::pow( latcos, 17 ) ) / 65536. * rft; + if ( m == 18 && n == 18 ) + return ( 5 * std::sqrt( 3357800061 ) * std::pow( latcos, 18 ) ) / 131072. * rft; if ( m == 19 && n == 19 ) return ( 15 * std::sqrt( 3.829070245e8 ) * std::pow( latcos, 19 ) ) / 131072. * rft; - if ( m == 20 && n == 20 ) return ( 3 * std::sqrt( 156991880045 ) * std::pow( latcos, 20 ) ) / 524288. * rft; + if ( m == 20 && n == 20 ) + return ( 3 * std::sqrt( 156991880045 ) * std::pow( latcos, 20 ) ) / 524288. * rft; if ( m == 21 && n == 21 ) return ( std::sqrt( 1.4465680375575e12 ) * std::pow( latcos, 21 ) ) / 524288. * rft; if ( m == 22 && n == 22 ) @@ -202,25 +229,34 @@ double sphericalharmonics_analytic_point( // vorticity: if ( ivar_in == 0 ) { if ( ivar_out == 0 ) { // u: - if ( m == 0 && n == 0 ) return 0.; + if ( m == 0 && n == 0 ) + return 0.; if ( m == 0 && n == 1 ) { - if ( imag == 0 ) { return std::sqrt( 3. ) * a / 2. * latcos; } + if ( imag == 0 ) { + return std::sqrt( 3. ) * a / 2. * latcos; + } else { return 0.; } } if ( m == 1 && n == 1 ) { - if ( imag == 0 ) { return -a * std::sqrt( 3. / 2. ) * loncos * latsin; } + if ( imag == 0 ) { + return -a * std::sqrt( 3. / 2. ) * loncos * latsin; + } else { return a * std::sqrt( 3. / 2. ) * lonsin * latsin; } } } else if ( ivar_out == 1 ) { // v: - if ( m == 0 && n == 0 ) return 0.; - if ( m == 0 && n == 1 ) return 0.; + if ( m == 0 && n == 0 ) + return 0.; + if ( m == 0 && n == 1 ) + return 0.; if ( m == 1 && n == 1 ) { - if ( imag == 0 ) { return a * std::sqrt( 3. / 2. ) * lonsin; } + if ( imag == 0 ) { + return a * std::sqrt( 3. / 2. ) * lonsin; + } else { return a * std::sqrt( 3. / 2. ) * loncos; } @@ -234,25 +270,34 @@ double sphericalharmonics_analytic_point( // divergence: if ( ivar_in == 1 ) { if ( ivar_out == 0 ) { // u: - if ( m == 0 && n == 0 ) return 0.; - if ( m == 0 && n == 1 ) return 0.; + if ( m == 0 && n == 0 ) + return 0.; + if ( m == 0 && n == 1 ) + return 0.; if ( m == 1 && n == 1 ) { - if ( imag == 0 ) { return a * std::sqrt( 3. / 2. ) * lonsin; } + if ( imag == 0 ) { + return a * std::sqrt( 3. / 2. ) * lonsin; + } else { return a * std::sqrt( 3. / 2. ) * loncos; } } } else if ( ivar_out == 1 ) { // v: - if ( m == 0 && n == 0 ) return 0.; + if ( m == 0 && n == 0 ) + return 0.; if ( m == 0 && n == 1 ) { - if ( imag == 0 ) { return -std::sqrt( 3. ) * a / 2. * latcos; } + if ( imag == 0 ) { + return -std::sqrt( 3. ) * a / 2. * latcos; + } else { return 0.; } } if ( m == 1 && n == 1 ) { - if ( imag == 0 ) { return a * std::sqrt( 3. / 2. ) * loncos * latsin; } + if ( imag == 0 ) { + return a * std::sqrt( 3. / 2. ) * loncos * latsin; + } else { return -a * std::sqrt( 3. / 2. ) * lonsin * latsin; // sign? } @@ -313,7 +358,9 @@ void spectral_transform_grid_analytic( gs_global = StructuredGrid( gridGlobal ); int nlatsGlobal = gs_global.ny(); for ( int jlat = 0; jlat < nlatsGlobal; jlat++ ) { - if ( gs_global.y( jlat ) > g.y( 0 ) ) { jlatMin++; }; + if ( gs_global.y( jlat ) > g.y( 0 ) ) { + jlatMin++; + }; } } @@ -369,7 +416,9 @@ double compute_rms( const size_t N, // length of the arrays rms += diff * diff; rmax = std::max( rmax, std::abs( array2[idx] ) ); } - if ( rmax == 0. ) { rms = 0.; } + if ( rmax == 0. ) { + rms = 0.; + } else { rms = std::sqrt( rms / N ) / rmax; } @@ -440,9 +489,12 @@ CASE( "test_trans_vordiv_with_translib" ) { vor[j] = 0.; div[j] = 0.; } - if ( ivar_in == 0 ) vor[k * nb_vordiv + jfld] = 1.; - if ( ivar_in == 1 ) div[k * nb_vordiv + jfld] = 1.; - if ( ivar_in == 2 ) sp[k * nb_scalar + jfld] = 1.; + if ( ivar_in == 0 ) + vor[k * nb_vordiv + jfld] = 1.; + if ( ivar_in == 1 ) + div[k * nb_vordiv + jfld] = 1.; + if ( ivar_in == 2 ) + sp[k * nb_scalar + jfld] = 1.; for ( int j = 0; j < nb_all * g.size(); j++ ) { gp[j] = 0.; @@ -642,7 +694,8 @@ CASE( "test_trans_domain" ) { int trc = 63; //Log::info() << "rgp1:" << std::endl; - if ( eckit::PathName( "legcache.bin" ).exists() ) eckit::PathName( "legcache.bin" ).unlink(); + if ( eckit::PathName( "legcache.bin" ).exists() ) + eckit::PathName( "legcache.bin" ).unlink(); Trace t1( Here(), "translocal1 construction" ); trans::Trans transLocal1( global_grid, g1.domain(), trc, option::type( "local" ) | option::write_legendre( "legcache.bin" ) ); @@ -707,9 +760,12 @@ CASE( "test_trans_domain" ) { vor[j] = 0.; div[j] = 0.; } - if ( ivar_in == 0 ) vor[k * nb_vordiv + jfld] = 1.; - if ( ivar_in == 1 ) div[k * nb_vordiv + jfld] = 1.; - if ( ivar_in == 2 ) sp[k * nb_scalar + jfld] = 1.; + if ( ivar_in == 0 ) + vor[k * nb_vordiv + jfld] = 1.; + if ( ivar_in == 1 ) + div[k * nb_vordiv + jfld] = 1.; + if ( ivar_in == 2 ) + sp[k * nb_scalar + jfld] = 1.; for ( int j = 0; j < nb_all * g1.size(); j++ ) { rgp1[j] = 0.; @@ -887,9 +943,12 @@ CASE( "test_trans_pole" ) { vor[j] = 0.; div[j] = 0.; } - if ( ivar_in == 0 ) vor[k * nb_vordiv + jfld] = 1.; - if ( ivar_in == 1 ) div[k * nb_vordiv + jfld] = 1.; - if ( ivar_in == 2 ) sp[k * nb_scalar + jfld] = 1.; + if ( ivar_in == 0 ) + vor[k * nb_vordiv + jfld] = 1.; + if ( ivar_in == 1 ) + div[k * nb_vordiv + jfld] = 1.; + if ( ivar_in == 2 ) + sp[k * nb_scalar + jfld] = 1.; for ( int j = 0; j < nb_all * g1.size(); j++ ) { rgp1[j] = 0.; @@ -1072,9 +1131,12 @@ CASE( "test_trans_southpole" ) { vor[j] = 0.; div[j] = 0.; } - if ( ivar_in == 0 ) vor[k * nb_vordiv + jfld] = 1.; - if ( ivar_in == 1 ) div[k * nb_vordiv + jfld] = 1.; - if ( ivar_in == 2 ) sp[k * nb_scalar + jfld] = 1.; + if ( ivar_in == 0 ) + vor[k * nb_vordiv + jfld] = 1.; + if ( ivar_in == 1 ) + div[k * nb_vordiv + jfld] = 1.; + if ( ivar_in == 2 ) + sp[k * nb_scalar + jfld] = 1.; for ( int j = 0; j < nb_all * g1.size(); j++ ) { rgp1[j] = 0.; @@ -1243,9 +1305,12 @@ CASE( "test_trans_unstructured" ) { vor[j] = 0.; div[j] = 0.; } - if ( ivar_in == 0 ) vor[k * nb_vordiv + jfld] = 1.; - if ( ivar_in == 1 ) div[k * nb_vordiv + jfld] = 1.; - if ( ivar_in == 2 ) sp[k * nb_scalar + jfld] = 1.; + if ( ivar_in == 0 ) + vor[k * nb_vordiv + jfld] = 1.; + if ( ivar_in == 1 ) + div[k * nb_vordiv + jfld] = 1.; + if ( ivar_in == 2 ) + sp[k * nb_scalar + jfld] = 1.; for ( int j = 0; j < nb_all * g.size(); j++ ) { gp[j] = 0.; diff --git a/src/tests/util/test_metadata.cc b/src/tests/util/test_metadata.cc index 4730eac5c..88df0f974 100644 --- a/src/tests/util/test_metadata.cc +++ b/src/tests/util/test_metadata.cc @@ -25,13 +25,16 @@ namespace test { CASE( "test_broadcast_to_self" ) { Metadata metadata; - if ( mpi::comm().rank() == 0 ) { metadata.set( "paramID", 128 ); } + if ( mpi::comm().rank() == 0 ) { + metadata.set( "paramID", 128 ); + } // broadcast metadata.broadcast(); EXPECT( metadata.has( "paramID" ) ); - if ( metadata.has( "paramID" ) ) EXPECT( metadata.get( "paramID" ) == 128 ); + if ( metadata.has( "paramID" ) ) + EXPECT( metadata.get( "paramID" ) == 128 ); } // ----------------------------------------------------------------------------- @@ -39,7 +42,9 @@ CASE( "test_broadcast_to_self" ) { CASE( "test_broadcast_to_other" ) { size_t root = 0; Metadata global; - if ( mpi::comm().rank() == root ) { global.set( "paramID", 128 ); } + if ( mpi::comm().rank() == root ) { + global.set( "paramID", 128 ); + } Metadata local; @@ -47,9 +52,11 @@ CASE( "test_broadcast_to_other" ) { global.broadcast( local ); EXPECT( local.has( "paramID" ) ); - if ( local.has( "paramID" ) ) EXPECT( local.get( "paramID" ) == 128 ); + if ( local.has( "paramID" ) ) + EXPECT( local.get( "paramID" ) == 128 ); - if ( mpi::comm().rank() != root ) EXPECT( !global.has( "paramID" ) ); + if ( mpi::comm().rank() != root ) + EXPECT( !global.has( "paramID" ) ); } //----------------------------------------------------------------------------- From 73840341152587232225ece76ad499290e5554c5 Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Fri, 12 Jul 2019 16:01:25 +0100 Subject: [PATCH 81/86] Apply clang-tidy fix 'readability-braces-around-statements' --- CMakeLists.txt | 13 + src/apps/atlas-benchmark.cc | 39 ++- src/apps/atlas-gaussian-latitudes.cc | 21 +- src/apps/atlas-gmsh-extract.cc | 33 ++- src/apps/atlas-loadbalance.cc | 6 +- src/apps/atlas-meshgen.cc | 24 +- src/apps/atlas.cc | 3 +- src/atlas/array/ArraySpec.cc | 6 +- src/atlas/array/LocalView.cc | 3 +- src/atlas/array/native/NativeArray.cc | 12 +- src/atlas/array/native/NativeIndexView.cc | 3 +- src/atlas/domain/detail/RectangularDomain.cc | 27 +- src/atlas/domain/detail/ZonalBandDomain.cc | 6 +- src/atlas/field/FieldCreator.cc | 6 +- src/atlas/field/FieldCreatorArraySpec.cc | 9 +- src/atlas/field/FieldCreatorIFS.cc | 9 +- src/atlas/field/FieldSet.cc | 3 +- src/atlas/field/State.cc | 9 +- src/atlas/field/detail/FieldImpl.cc | 9 +- src/atlas/functionspace/EdgeColumns.cc | 63 +++-- src/atlas/functionspace/NodeColumns.cc | 51 ++-- src/atlas/functionspace/Spectral.cc | 6 +- src/atlas/functionspace/StructuredColumns.cc | 75 ++++-- .../detail/NodeColumnsInterface.cc | 46 ++-- .../detail/NodeColumns_FieldStatistics.cc | 42 ++-- src/atlas/grid/Grid.cc | 3 +- src/atlas/grid/Partitioner.cc | 3 +- src/atlas/grid/Vertical.cc | 9 +- .../detail/distribution/DistributionImpl.cc | 6 +- src/atlas/grid/detail/grid/GridBuilder.cc | 12 +- src/atlas/grid/detail/grid/LonLat.cc | 12 +- src/atlas/grid/detail/grid/Regional.cc | 66 +++-- src/atlas/grid/detail/grid/Structured.cc | 30 ++- src/atlas/grid/detail/grid/Unstructured.cc | 3 +- .../partitioner/CheckerboardPartitioner.cc | 42 ++-- .../partitioner/EqualRegionsPartitioner.cc | 51 ++-- .../grid/detail/partitioner/Partitioner.cc | 6 +- .../grid/detail/pl/classic_gaussian/N.cc | 6 +- src/atlas/grid/detail/spacing/FocusSpacing.cc | 12 +- .../grid/detail/spacing/GaussianSpacing.cc | 3 +- .../grid/detail/spacing/LinearSpacing.cc | 18 +- .../grid/detail/spacing/gaussian/Latitudes.cc | 6 +- src/atlas/grid/detail/spacing/gaussian/N.cc | 3 +- src/atlas/interpolation/element/Quad3D.cc | 3 +- src/atlas/interpolation/method/Method.cc | 12 +- src/atlas/interpolation/method/PointSet.cc | 15 +- .../interpolation/method/fe/FiniteElement.cc | 3 +- src/atlas/library/Library.cc | 12 +- src/atlas/mesh/Connectivity.cc | 33 ++- src/atlas/mesh/Elements.cc | 3 +- src/atlas/mesh/HybridElements.cc | 9 +- src/atlas/mesh/Nodes.cc | 3 +- src/atlas/mesh/actions/BuildConvexHull3D.cc | 9 +- src/atlas/mesh/actions/BuildDualMesh.cc | 36 ++- src/atlas/mesh/actions/BuildEdges.cc | 30 ++- src/atlas/mesh/actions/BuildHalo.cc | 54 ++-- .../actions/BuildNode2CellConnectivity.cc | 3 +- src/atlas/mesh/actions/BuildParallelFields.cc | 12 +- src/atlas/mesh/actions/BuildStatistics.cc | 12 +- src/atlas/mesh/actions/ExtendNodesGlobal.cc | 3 +- .../mesh/actions/WriteLoadBalanceReport.cc | 12 +- src/atlas/mesh/detail/AccumulateFacets.cc | 6 +- src/atlas/mesh/detail/MeshImpl.cc | 78 ++++-- src/atlas/mesh/detail/PartitionGraph.cc | 3 +- .../detail/RegularMeshGenerator.cc | 24 +- .../detail/StructuredMeshGenerator.cc | 208 ++++++++++------ src/atlas/numerics/Nabla.cc | 3 +- src/atlas/numerics/fvm/Method.cc | 9 +- src/atlas/numerics/fvm/Nabla.cc | 24 +- src/atlas/output/Gmsh.cc | 15 +- src/atlas/output/Output.cc | 6 +- src/atlas/output/detail/GmshIO.cc | 141 +++++++---- src/atlas/output/detail/PointCloudIO.cc | 84 ++++--- src/atlas/parallel/GatherScatter.cc | 9 +- src/atlas/parallel/HaloExchange.cc | 18 +- src/atlas/parallel/omp/omp.cc | 30 ++- .../projection/detail/LambertProjection.cc | 15 +- .../projection/detail/MercatorProjection.cc | 6 +- .../projection/detail/SchmidtProjection.cc | 3 +- src/atlas/runtime/AtlasTool.cc | 57 +++-- src/atlas/runtime/trace/CallStack.cc | 3 +- src/atlas/runtime/trace/Logging.cc | 12 +- src/atlas/runtime/trace/Timings.cc | 27 +- src/atlas/trans/LegendreCacheCreator.cc | 3 +- src/atlas/trans/VorDivToUV.cc | 3 +- .../trans/local/LegendreCacheCreatorLocal.cc | 6 +- src/atlas/trans/local/LegendrePolynomials.cc | 3 +- src/atlas/util/Config.cc | 39 ++- src/atlas/util/Metadata.cc | 9 +- src/atlas/util/ObjectHandle.cc | 3 +- src/atlas/util/Rotation.cc | 9 +- src/atlas_f/internals/Library.cc | 6 +- .../atlas-benchmark-ifs-setup.cc | 6 +- .../atlas-benchmark-sorting.cc | 15 +- .../atlas-grid-distribution.cc | 9 +- src/tests/array/test_array.cc | 3 +- src/tests/functionspace/test_functionspace.cc | 3 +- src/tests/grid/test_grid_ptr.cc | 3 +- .../test_interpolation_cubic_prototype.cc | 15 +- src/tests/io/test_pointcloud_io.cc | 3 +- src/tests/mesh/test_parfields.cc | 26 +- src/tests/mesh/test_rgg.cc | 6 +- src/tests/numerics/test_fvm_nabla.cc | 3 +- src/tests/projection/test_rotation.cc | 6 +- src/tests/trans/test_trans_localcache.cc | 3 +- src/tests/trans/test_transgeneral.cc | 231 ++++++++++++------ src/tests/util/test_indexview.cc | 3 +- src/tests/util/test_metadata.cc | 9 +- 108 files changed, 1526 insertions(+), 759 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 82d387245..4461d3e34 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -257,6 +257,19 @@ endif() set( MIR_NEEDS_TRANSI TRUE CACHE BOOL "Deprecated" INTERNAL ) include(CompileFlags) + +find_program (CLANG_TIDY_EXE NAMES "clang-tidy" ) +if( CLANG_TIDY_EXE ) + message(STATUS "Found clang-tidy: ${CLANG_TIDY_EXE}") +endif() +ecbuild_add_option( FEATURE CLANG_TIDY + DESCRIPTION "Use clang-tidy" + CONDITION CLANG_TIDY_EXE ) +if (HAVE_CLANG_TIDY) + set(CLANG_TIDY_CHECKS "-*,readability-braces-around-statements,redundant-string-init") + set(CMAKE_CXX_CLANG_TIDY "${CLANG_TIDY_EXE};-checks=${CLANG_TIDY_CHECKS};-header-filter='${CMAKE_SOURCE_DIR}/*'") +endif() + add_subdirectory( src ) ################################################################################ diff --git a/src/apps/atlas-benchmark.cc b/src/apps/atlas-benchmark.cc index cd282f80a..6a80de61b 100644 --- a/src/apps/atlas-benchmark.cc +++ b/src/apps/atlas-benchmark.cc @@ -99,10 +99,12 @@ struct TimerStats { } void update( Trace& timer ) { double t = timer.elapsed(); - if ( min < 0 ) + if ( min < 0 ) { min = t; - if ( max < 0 ) + } + if ( max < 0 ) { max = t; + } min = std::min( min, t ); max = std::max( max, t ); avg = ( avg * cnt + t ) / ( cnt + 1 ); @@ -200,8 +202,9 @@ int AtlasBenchmark::execute( const Args& args ) { iteration_timer = TimerStats( "iteration" ); haloexchange_timer = TimerStats( "halo-exchange" ); - if ( omp_threads > 0 ) + if ( omp_threads > 0 ) { atlas_omp_set_num_threads( omp_threads ); + } Log::info() << "atlas-benchmark\n" << endl; Log::info() << Library::instance().information() << endl; @@ -234,8 +237,9 @@ int AtlasBenchmark::execute( const Args& args ) { ++tic; } if ( iter == niter - 1 ) { - if ( tic < 51 ) + if ( tic < 51 ) { Log::info() << '*'; + } Log::info() << endl; } } @@ -254,8 +258,9 @@ int AtlasBenchmark::execute( const Args& args ) { util::Config report_config; report_config.set( "indent", 4 ); - if ( not args.getBool( "details", false ) ) + if ( not args.getBool( "details", false ) ) { report_config.set( "exclude", std::vector{"halo-exchange", "atlas-benchmark-setup/*"} ); + } Log::info() << timer.report( report_config ) << std::endl; Log::info() << endl; @@ -287,8 +292,9 @@ void AtlasBenchmark::initial_condition( const Field& field, const double& beta ) double Ux = pvel * ( std::cos( beta ) + std::tan( y ) * std::cos( x ) * std::sin( beta ) ) * radius * std::cos( y ); double Uy = -pvel * std::sin( x ) * std::sin( beta ) * radius; - for ( idx_t jlev = 0; jlev < field.levels(); ++jlev ) + for ( idx_t jlev = 0; jlev < field.levels(); ++jlev ) { var( jnode, jlev ) = std::sqrt( Ux * Ux + Uy * Uy ); + } } } @@ -358,10 +364,12 @@ void AtlasBenchmark::setup() { for ( idx_t jedge = 0; jedge < node2edge.cols( jnode ); ++jedge ) { idx_t iedge = node2edge( jnode, jedge ); idx_t ip1 = edge2node( iedge, 0 ); - if ( jnode == ip1 ) + if ( jnode == ip1 ) { node2edge_sign( jnode, jedge ) = 1.; - else + } + else { node2edge_sign( jnode, jedge ) = -1.; + } } } @@ -371,12 +379,14 @@ void AtlasBenchmark::setup() { vector tmp( nedges ); int c( 0 ); for ( idx_t jedge = 0; jedge < nedges; ++jedge ) { - if ( is_pole_edge( jedge ) ) + if ( is_pole_edge( jedge ) ) { tmp[c++] = jedge; + } } pole_edges.reserve( c ); - for ( idx_t jedge = 0; jedge < c; ++jedge ) + for ( idx_t jedge = 0; jedge < c; ++jedge ) { pole_edges.push_back( tmp[jedge] ); + } auto flags = array::make_view( mesh.nodes().flags() ); is_ghost.reserve( nnodes ); @@ -436,8 +446,9 @@ void AtlasBenchmark::iteration() { idx_t iedge = pole_edges[jedge]; idx_t ip2 = edge2node( iedge, 1 ); // correct for wrong Y-derivatives in previous loop - for ( idx_t jlev = 0; jlev < nlev; ++jlev ) + for ( idx_t jlev = 0; jlev < nlev; ++jlev ) { grad( ip2, jlev, LAT ) += 2. * avgS( iedge, jlev, LAT ) / V( ip2 ); + } } double dzi = 1. / dz; @@ -453,8 +464,9 @@ void AtlasBenchmark::iteration() { grad( jnode, 0, ZZ ) = ( field( jnode, 1 ) - field( jnode, 0 ) ) * dzi; grad( jnode, nlev - 1, ZZ ) = ( field( jnode, nlev - 2 ) - field( jnode, nlev - 1 ) ) * dzi; } - if ( nlev == 1 ) + if ( nlev == 1 ) { grad( jnode, 0, ZZ ) = 0.; + } } compute.stop(); @@ -482,8 +494,9 @@ void AtlasBenchmark::iteration() { template DATA_TYPE vecnorm( const DATA_TYPE vec[], size_t size ) { DATA_TYPE norm = 0; - for ( size_t j = 0; j < size; ++j ) + for ( size_t j = 0; j < size; ++j ) { norm += vec[j] * vec[j]; + } return norm; } diff --git a/src/apps/atlas-gaussian-latitudes.cc b/src/apps/atlas-gaussian-latitudes.cc index 7ab774ecd..6d18d50b3 100644 --- a/src/apps/atlas-gaussian-latitudes.cc +++ b/src/apps/atlas-gaussian-latitudes.cc @@ -80,14 +80,17 @@ class AtlasGaussianLatitudes : public eckit::Tool { format = Resource( "--format", std::string( "table" ) ); - if ( N > 0 ) + if ( N > 0 ) { do_run = true; + } if ( do_run == false ) { - if ( help ) + if ( help ) { Log::info() << help_str << std::endl; - else + } + else { Log::info() << "usage: atlas-gaussian-latitudes [--help] [-N] [OPTION]..." << std::endl; + } } } @@ -102,26 +105,30 @@ class AtlasGaussianLatitudes : public eckit::Tool { //------------------------------------------------------------------------------ void AtlasGaussianLatitudes::run() { - if ( !do_run ) + if ( !do_run ) { return; + } GaussianSpacing lats( 2 * N ); int end = full ? 2 * N : N; if ( format == "table" ) { - for ( int jlat = 0; jlat < end; ++jlat ) + for ( int jlat = 0; jlat < end; ++jlat ) { std::cout << std::setw( 4 ) << jlat + 1 << std::setw( 17 ) << std::setprecision( 12 ) << std::fixed << lats[jlat] << std::endl; + } } if ( format == "C" ) { std::cout << "double lat[] = {" << std::endl; for ( int jlat = 0; jlat < end; ++jlat ) { std::cout << std::setw( 16 ) << std::setprecision( 12 ) << std::fixed << lats[jlat]; - if ( jlat != end - 1 ) + if ( jlat != end - 1 ) { std::cout << ","; - if ( ( compact && ( jlat + 1 ) % 5 == 0 ) || !compact || jlat == end - 1 ) + } + if ( ( compact && ( jlat + 1 ) % 5 == 0 ) || !compact || jlat == end - 1 ) { std::cout << std::endl; + } } std::cout << "};" << std::endl; } diff --git a/src/apps/atlas-gmsh-extract.cc b/src/apps/atlas-gmsh-extract.cc index d556352a3..ed367fca9 100644 --- a/src/apps/atlas-gmsh-extract.cc +++ b/src/apps/atlas-gmsh-extract.cc @@ -101,15 +101,17 @@ class gmsh_extract : public eckit::Tool { if ( std::string( argv[i] ) == "-i" ) { for ( int j = i + 1; j < argc; ++j ) { std::string in_file( argv[j] ); - if ( in_file[0] == '-' ) + if ( in_file[0] == '-' ) { break; + } in_files.push_back( in_file ); } } } - if ( in_files.empty() ) + if ( in_files.empty() ) { throw_Exception( "missing input filename, parameter -i\n" + help_str, Here() ); + } } private: @@ -123,19 +125,22 @@ class gmsh_extract : public eckit::Tool { //------------------------------------------------------------------------------------------------------ void gmsh_extract::run() { - if ( !do_run ) + if ( !do_run ) { return; + } atlas::Library::instance().initialise( argc(), argv() ); Log::debug() << "Command line:" << std::endl; - for ( int i = 0; i < argc(); ++i ) + for ( int i = 0; i < argc(); ++i ) { Log::debug() << argv( i ) << std::endl; + } Log::debug() << Translator, std::string>()( in_files ) << std::endl; std::ofstream out_file; if ( !out_filename.empty() ) { out_file.open( out_filename.c_str(), std::ios::out | std::ios::binary ); - if ( !out_file.is_open() ) + if ( !out_file.is_open() ) { throw_CantOpenFile( out_filename ); + } } std::ostream& out = out_filename.empty() ? std::cout : out_file; @@ -150,15 +155,17 @@ void gmsh_extract::run() { std::ifstream in_file; in_file.open( gmsh_file.localPath(), std::ios::in | std::ios::binary ); - if ( !in_file.is_open() ) + if ( !in_file.is_open() ) { throw_CantOpenFile( gmsh_file ); + } std::string line; std::string ctxt = ""; while ( true ) { std::getline( in_file, line ); - if ( in_file.eof() ) + if ( in_file.eof() ) { break; + } if ( line == "$MeshFormat" ) { out << line << "\n"; std::getline( in_file, line ); @@ -167,12 +174,15 @@ void gmsh_extract::run() { out << line << "\n"; std::getline( in_file, line ); } - if ( line == "$NodeData" ) + if ( line == "$NodeData" ) { ctxt = "NodeData"; - if ( line == "$ElementData" ) + } + if ( line == "$ElementData" ) { ctxt = "ElementData"; - if ( line == "$ElementNodeData" ) + } + if ( line == "$ElementNodeData" ) { ctxt = "ElementNodeData"; + } if ( !ctxt.empty() ) { std::string end_ctxt = "$End" + ctxt; @@ -218,8 +228,9 @@ void gmsh_extract::run() { } } } - if ( !out_filename.empty() ) + if ( !out_filename.empty() ) { out_file.close(); + } atlas::Library::instance().finalise(); } diff --git a/src/apps/atlas-loadbalance.cc b/src/apps/atlas-loadbalance.cc index f6039571e..8df6a73b6 100644 --- a/src/apps/atlas-loadbalance.cc +++ b/src/apps/atlas-loadbalance.cc @@ -97,8 +97,9 @@ class AtlasLoadbalance : public eckit::Tool { //------------------------------------------------------------------------------------------------------ void AtlasLoadbalance::run() { - if ( !do_run ) + if ( !do_run ) { return; + } StructuredGrid grid; try { @@ -107,8 +108,9 @@ void AtlasLoadbalance::run() { catch ( eckit::Exception& err ) { } - if ( !grid ) + if ( !grid ) { return; + } MeshGenerator meshgenerator( "structured" ); Mesh mesh = meshgenerator.generate( grid ); diff --git a/src/apps/atlas-meshgen.cc b/src/apps/atlas-meshgen.cc index c2bc0eec5..ac4a70403 100644 --- a/src/apps/atlas-meshgen.cc +++ b/src/apps/atlas-meshgen.cc @@ -138,13 +138,16 @@ int Meshgen2Gmsh::execute( const Args& args ) { args.get( "binary", binary ); std::string path_in_str = ""; - if ( args.get( "grid.json", path_in_str ) ) + if ( args.get( "grid.json", path_in_str ) ) { path_in = path_in_str; + } - if ( args.count() ) + if ( args.count() ) { path_out = args( 0 ); - else + } + else { path_out = "mesh.msh"; + } if ( path_in_str.empty() && key.empty() ) { Log::warning() << "missing argument --grid.name or --grid.json" << std::endl; @@ -152,8 +155,9 @@ int Meshgen2Gmsh::execute( const Args& args ) { return failed(); } - if ( edges ) + if ( edges ) { halo = std::max( halo, 1l ); + } StructuredGrid grid; if ( key.size() ) { @@ -176,8 +180,9 @@ int Meshgen2Gmsh::execute( const Args& args ) { Log::error() << "No grid specified." << std::endl; } - if ( !grid ) + if ( !grid ) { return failed(); + } Log::debug() << "Domain: " << grid.domain() << std::endl; Log::debug() << "Periodic: " << grid.periodic() << std::endl; @@ -186,8 +191,9 @@ int Meshgen2Gmsh::execute( const Args& args ) { std::string Implementationype = ( RegularGrid( grid ) ? "regular" : "structured" ); args.get( "generator", Implementationype ); eckit::LocalConfiguration meshgenerator_config( args ); - if ( mpi::comm().size() > 1 || edges ) + if ( mpi::comm().size() > 1 || edges ) { meshgenerator_config.set( "3d", false ); + } MeshGenerator meshgenerator( Implementationype, meshgenerator_config ); @@ -212,10 +218,12 @@ int Meshgen2Gmsh::execute( const Args& args ) { } if ( edges && grid.projection().units() == "degrees" ) { functionspace::EdgeColumns edges_fs( mesh, option::halo( halo ) ); - if ( brick ) + if ( brick ) { build_brick_dual_mesh( grid, mesh ); - else + } + else { build_median_dual_mesh( mesh ); + } } if ( stats ) { diff --git a/src/apps/atlas.cc b/src/apps/atlas.cc index 0ca8a3860..319ad38d0 100644 --- a/src/apps/atlas.cc +++ b/src/apps/atlas.cc @@ -69,8 +69,9 @@ void Version::run() { << std::endl; return; } - else + else { Log::info() << "usage: atlas [--help] [--version] [--git] [--info]" << std::endl; + } } } // namespace atlas diff --git a/src/atlas/array/ArraySpec.cc b/src/atlas/array/ArraySpec.cc index b39d5aa04..b90708394 100644 --- a/src/atlas/array/ArraySpec.cc +++ b/src/atlas/array/ArraySpec.cc @@ -22,8 +22,9 @@ idx_t compute_allocated_size( idx_t size, idx_t alignment ) { idx_t div = size / alignment; idx_t mod = size % alignment; idx_t _allocated_size = div * alignment; - if ( mod > 0 ) + if ( mod > 0 ) { _allocated_size += alignment; + } return _allocated_size; } } // namespace @@ -33,8 +34,9 @@ ArraySpec::ArraySpec() : size_(), rank_(), allocated_size_(), contiguous_( true ArraySpec::ArraySpec( const ArrayShape& shape ) : ArraySpec( shape, ArrayAlignment() ) {} ArraySpec::ArraySpec( const ArrayShape& shape, ArrayAlignment&& alignment ) { - if ( int( alignment ) > 1 ) + if ( int( alignment ) > 1 ) { ATLAS_NOTIMPLEMENTED; // innermost dimension needs to be padded + } rank_ = static_cast( shape.size() ); size_ = 1; diff --git a/src/atlas/array/LocalView.cc b/src/atlas/array/LocalView.cc index 53288daef..855deedef 100644 --- a/src/atlas/array/LocalView.cc +++ b/src/atlas/array/LocalView.cc @@ -35,8 +35,9 @@ void LocalView::dump( std::ostream& os ) const { const value_type* data_ = data(); os << "size: " << size() << " , values: "; os << "[ "; - for ( idx_t j = 0; j < size(); ++j ) + for ( idx_t j = 0; j < size(); ++j ) { os << data_[j] << " "; + } os << "]"; } diff --git a/src/atlas/array/native/NativeArray.cc b/src/atlas/array/native/NativeArray.cc index 6223dbcf1..8ab381ce5 100644 --- a/src/atlas/array/native/NativeArray.cc +++ b/src/atlas/array/native/NativeArray.cc @@ -118,8 +118,9 @@ template ArrayT::ArrayT( const ArrayShape& shape ) { ATLAS_ASSERT( shape.size() > 0 ); idx_t size = 1; - for ( size_t j = 0; j < shape.size(); ++j ) + for ( size_t j = 0; j < shape.size(); ++j ) { size *= shape[j]; + } data_store_ = std::unique_ptr( new native::DataStore( size ) ); spec_ = ArraySpec( shape ); } @@ -128,14 +129,16 @@ template ArrayT::ArrayT( const ArrayShape& shape, const ArrayLayout& layout ) { spec_ = ArraySpec( shape ); data_store_ = std::unique_ptr( new native::DataStore( spec_.size() ) ); - for ( size_t j = 0; j < layout.size(); ++j ) + for ( size_t j = 0; j < layout.size(); ++j ) { ATLAS_ASSERT( spec_.layout()[j] == layout[j] ); + } } template ArrayT::ArrayT( const ArraySpec& spec ) { - if ( not spec.contiguous() ) + if ( not spec.contiguous() ) { ATLAS_NOTIMPLEMENTED; + } spec_ = spec; data_store_ = std::unique_ptr( new native::DataStore( spec_.size() ) ); } @@ -267,8 +270,9 @@ template size_t ArrayT::footprint() const { size_t size = sizeof( *this ); size += bytes(); - if ( not contiguous() ) + if ( not contiguous() ) { ATLAS_NOTIMPLEMENTED; + } return size; } diff --git a/src/atlas/array/native/NativeIndexView.cc b/src/atlas/array/native/NativeIndexView.cc index 2aac81e51..485901b84 100644 --- a/src/atlas/array/native/NativeIndexView.cc +++ b/src/atlas/array/native/NativeIndexView.cc @@ -29,8 +29,9 @@ template void IndexView::dump( std::ostream& os ) const { os << "size: " << size() << " , values: "; os << "[ "; - for ( idx_t j = 0; j < size(); ++j ) + for ( idx_t j = 0; j < size(); ++j ) { os << ( *this )( j ) << " "; + } os << "]" << std::endl; } diff --git a/src/atlas/domain/detail/RectangularDomain.cc b/src/atlas/domain/detail/RectangularDomain.cc index d0adceb82..bb2aeb4a2 100644 --- a/src/atlas/domain/detail/RectangularDomain.cc +++ b/src/atlas/domain/detail/RectangularDomain.cc @@ -27,11 +27,13 @@ namespace { static std::array get_interval_x( const eckit::Parametrisation& params ) { double xmin, xmax; - if ( !params.get( "xmin", xmin ) ) + if ( !params.get( "xmin", xmin ) ) { throw_Exception( "xmin missing in Params", Here() ); + } - if ( !params.get( "xmax", xmax ) ) + if ( !params.get( "xmax", xmax ) ) { throw_Exception( "xmax missing in Params", Here() ); + } return {xmin, xmax}; } @@ -39,35 +41,40 @@ static std::array get_interval_x( const eckit::Parametrisation& param static std::array get_interval_y( const eckit::Parametrisation& params ) { double ymin, ymax; - if ( !params.get( "ymin", ymin ) ) + if ( !params.get( "ymin", ymin ) ) { throw_Exception( "ymin missing in Params", Here() ); + } - if ( !params.get( "ymax", ymax ) ) + if ( !params.get( "ymax", ymax ) ) { throw_Exception( "ymax missing in Params", Here() ); + } return {ymin, ymax}; } static std::string get_units( const eckit::Parametrisation& params ) { std::string units; - if ( !params.get( "units", units ) ) + if ( !params.get( "units", units ) ) { throw_Exception( "units missing in Params", Here() ); + } return units; } } // namespace bool RectangularDomain::is_global( const Interval& x, const Interval& y, const std::string& units ) { - if ( units != "degrees" ) + if ( units != "degrees" ) { return false; + } const double eps = 1.e-12; return std::abs( ( x[1] - x[0] ) - 360. ) < eps && std::abs( std::abs( y[1] - y[0] ) - 180. ) < eps; } bool RectangularDomain::is_zonal_band( const Interval& x, const std::string& units ) { - if ( units != "degrees" ) + if ( units != "degrees" ) { return false; + } const double eps = 1.e-12; return std::abs( ( x[1] - x[0] ) - 360. ) < eps; @@ -85,10 +92,12 @@ RectangularDomain::RectangularDomain( const Interval& x, const Interval& y, cons unit_degrees_ = ( units_ == "degrees" ) ? true : false; // Make sure xmax>=xmin and ymax>=ymin - if ( xmin_ > xmax_ ) + if ( xmin_ > xmax_ ) { std::swap( xmin_, xmax_ ); - if ( ymin_ > ymax_ ) + } + if ( ymin_ > ymax_ ) { std::swap( ymin_, ymax_ ); + } global_ = is_global( {xmin_, xmax_}, {ymin_, ymax_}, units_ ); const double tol = 1.e-6; diff --git a/src/atlas/domain/detail/ZonalBandDomain.cc b/src/atlas/domain/detail/ZonalBandDomain.cc index a0364d26b..fd38dcbc0 100644 --- a/src/atlas/domain/detail/ZonalBandDomain.cc +++ b/src/atlas/domain/detail/ZonalBandDomain.cc @@ -27,11 +27,13 @@ static bool _is_global( double ymin, double ymax ) { static std::array get_interval_y( const eckit::Parametrisation& params ) { double ymin, ymax; - if ( !params.get( "ymin", ymin ) ) + if ( !params.get( "ymin", ymin ) ) { throw_Exception( "ymin missing in Params", Here() ); + } - if ( !params.get( "ymax", ymax ) ) + if ( !params.get( "ymax", ymax ) ) { throw_Exception( "ymax missing in Params", Here() ); + } return {ymin, ymax}; } diff --git a/src/atlas/field/FieldCreator.cc b/src/atlas/field/FieldCreator.cc index b9faf4bb5..e5cb95090 100644 --- a/src/atlas/field/FieldCreator.cc +++ b/src/atlas/field/FieldCreator.cc @@ -102,8 +102,9 @@ FieldCreator* FieldCreatorFactory::build( const std::string& name ) { if ( j == m->end() ) { Log::error() << "No FieldCreatorFactory for [" << name << "]" << '\n'; Log::error() << "FieldCreatorFactories are:" << '\n'; - for ( j = m->begin(); j != m->end(); ++j ) + for ( j = m->begin(); j != m->end(); ++j ) { Log::error() << " " << ( *j ).first << '\n'; + } throw_Exception( std::string( "No FieldCreatorFactory called " ) + name ); } @@ -122,8 +123,9 @@ FieldCreator* FieldCreatorFactory::build( const std::string& name, const eckit:: if ( j == m->end() ) { Log::error() << "No FieldCreatorFactory for [" << name << "]" << '\n'; Log::error() << "FieldCreatorFactories are:" << '\n'; - for ( j = m->begin(); j != m->end(); ++j ) + for ( j = m->begin(); j != m->end(); ++j ) { Log::error() << " " << ( *j ).first << '\n'; + } throw_Exception( std::string( "No FieldCreatorFactory called " ) + name ); } diff --git a/src/atlas/field/FieldCreatorArraySpec.cc b/src/atlas/field/FieldCreatorArraySpec.cc index af642c682..83aa66b04 100644 --- a/src/atlas/field/FieldCreatorArraySpec.cc +++ b/src/atlas/field/FieldCreatorArraySpec.cc @@ -24,17 +24,20 @@ namespace field { FieldImpl* FieldCreatorArraySpec::createField( const eckit::Parametrisation& params ) const { std::vector shape; - if ( !params.get( "shape", shape ) ) + if ( !params.get( "shape", shape ) ) { throw_Exception( "Could not find parameter 'shape' in Parametrisation" ); + } std::vector s( shape.size() ); bool fortran( false ); params.get( "fortran", fortran ); - if ( fortran ) + if ( fortran ) { std::reverse_copy( shape.begin(), shape.end(), s.begin() ); - else + } + else { s.assign( shape.begin(), shape.end() ); + } array::DataType datatype = array::DataType::create(); std::string datatype_str; diff --git a/src/atlas/field/FieldCreatorIFS.cc b/src/atlas/field/FieldCreatorIFS.cc index 5871c3577..ce7e33a4a 100644 --- a/src/atlas/field/FieldCreatorIFS.cc +++ b/src/atlas/field/FieldCreatorIFS.cc @@ -32,8 +32,9 @@ FieldImpl* FieldCreatorIFS::createField( const eckit::Parametrisation& params ) size_t nproma = 1; size_t nlev = 1; - if ( !params.get( "ngptot", ngptot ) ) + if ( !params.get( "ngptot", ngptot ) ) { throw_Exception( "Could not find parameter 'ngptot' in Parametrisation" ); + } params.get( "nproma", nproma ); params.get( "nlev", nlev ); params.get( "nvar", nvar ); @@ -59,10 +60,12 @@ FieldImpl* FieldCreatorIFS::createField( const eckit::Parametrisation& params ) array::ArrayShape s; bool fortran( false ); params.get( "fortran", fortran ); - if ( fortran ) + if ( fortran ) { s = array::make_shape( nproma, nlev, nvar, nblk ); - else + } + else { s = array::make_shape( nblk, nvar, nlev, nproma ); + } std::string name; params.get( "name", name ); diff --git a/src/atlas/field/FieldSet.cc b/src/atlas/field/FieldSet.cc index 8777ff331..6a53950fb 100644 --- a/src/atlas/field/FieldSet.cc +++ b/src/atlas/field/FieldSet.cc @@ -68,8 +68,9 @@ void FieldSetImpl::set_dirty( bool value ) const { std::vector FieldSetImpl::field_names() const { std::vector ret; - for ( const_iterator field = cbegin(); field != cend(); ++field ) + for ( const_iterator field = cbegin(); field != cend(); ++field ) { ret.push_back( field->name() ); + } return ret; } diff --git a/src/atlas/field/State.cc b/src/atlas/field/State.cc index e26754708..15257fac6 100644 --- a/src/atlas/field/State.cc +++ b/src/atlas/field/State.cc @@ -112,8 +112,9 @@ const Field& State::field( const idx_t idx ) const { throw_AssertionFailed( msg.str(), Here() ); } FieldMap::const_iterator it = fields_.begin(); - for ( idx_t i = 0; i < idx; ++i ) + for ( idx_t i = 0; i < idx; ++i ) { ++it; + } return it->second; } @@ -123,8 +124,9 @@ Field& State::field( const idx_t idx ) { std::vector State::field_names() const { std::vector ret; - if ( fields_.size() ) + if ( fields_.size() ) { ret.reserve( fields_.size() ); + } for ( FieldMap::const_iterator it = fields_.begin(); it != fields_.end(); ++it ) { ret.push_back( it->first ); @@ -161,8 +163,9 @@ StateGenerator* StateGeneratorFactory::build( const std::string& name, const eck if ( j == m->end() ) { Log::error() << "No StateGeneratorFactory for [" << name << "]" << std::endl; Log::error() << "StateFactories are:" << std::endl; - for ( j = m->begin(); j != m->end(); ++j ) + for ( j = m->begin(); j != m->end(); ++j ) { Log::error() << " " << ( *j ).first << std::endl; + } throw_Exception( std::string( "No StateGeneratorFactory called " ) + name, Here() ); } diff --git a/src/atlas/field/detail/FieldImpl.cc b/src/atlas/field/detail/FieldImpl.cc index 820215be6..f0cf99542 100644 --- a/src/atlas/field/detail/FieldImpl.cc +++ b/src/atlas/field/detail/FieldImpl.cc @@ -29,10 +29,11 @@ FieldImpl* FieldImpl::create( const eckit::Parametrisation& params ) { std::unique_ptr creator( field::FieldCreatorFactory::build( creator_factory, params ) ); return creator->createField( params ); } - else + else { throw_Exception( "Could not find parameter 'creator' " "in Parametrisation for call to FieldImpl::create()" ); + } } FieldImpl* FieldImpl::create( const std::string& name, array::DataType datatype, const array::ArrayShape& shape ) { @@ -64,8 +65,9 @@ FieldImpl::FieldImpl( const std::string& name, array::Array* array ) : functions FieldImpl::~FieldImpl() { array_->detach(); - if ( array_->owners() == 0 ) + if ( array_->owners() == 0 ) { delete array_; + } delete functionspace_; } @@ -97,8 +99,9 @@ std::string vector_to_str( const std::vector& t ) { std::stringstream s; s << '['; for ( size_t i = 0; i < t.size(); i++ ) { - if ( i != 0 ) + if ( i != 0 ) { s << ','; + } s << t[i]; } s << ']'; diff --git a/src/atlas/functionspace/EdgeColumns.cc b/src/atlas/functionspace/EdgeColumns.cc index 38d7314e5..ff8abcae8 100644 --- a/src/atlas/functionspace/EdgeColumns.cc +++ b/src/atlas/functionspace/EdgeColumns.cc @@ -209,8 +209,9 @@ idx_t EdgeColumns::config_size( const eckit::Configuration& config ) const { array::DataType EdgeColumns::config_datatype( const eckit::Configuration& config ) const { array::DataType::kind_t kind; - if ( !config.get( "datatype", kind ) ) + if ( !config.get( "datatype", kind ) ) { throw_Exception( "datatype missing", Here() ); + } return array::DataType( kind ); } @@ -233,13 +234,15 @@ array::ArrayShape EdgeColumns::config_shape( const eckit::Configuration& config idx_t levels( nb_levels_ ); config.get( "levels", levels ); - if ( levels > 0 ) + if ( levels > 0 ) { shape.push_back( levels ); + } idx_t variables( 0 ); config.get( "variables", variables ); - if ( variables > 0 ) + if ( variables > 0 ) { shape.push_back( variables ); + } return shape; } @@ -297,8 +300,9 @@ idx_t EdgeColumns::nb_edges() const { } idx_t EdgeColumns::nb_edges_global() const { - if ( nb_edges_global_ >= 0 ) + if ( nb_edges_global_ >= 0 ) { return nb_edges_global_; + } nb_edges_global_ = gather().glb_dof(); return nb_edges_global_; } @@ -329,8 +333,9 @@ void EdgeColumns::haloExchange( const FieldSet& fieldset, bool on_device ) const else if ( field.datatype() == array::DataType::kind() ) { halo_exchange().execute( field.array(), on_device ); } - else + else { throw_Exception( "datatype not supported", Here() ); + } field.set_dirty( false ); } } @@ -340,8 +345,9 @@ void EdgeColumns::haloExchange( const Field& field, bool on_device ) const { haloExchange( fieldset, on_device ); } const parallel::HaloExchange& EdgeColumns::halo_exchange() const { - if ( halo_exchange_ ) + if ( halo_exchange_ ) { return *halo_exchange_; + } halo_exchange_ = EdgeColumnsHaloExchangeCache::instance().get_or_create( mesh_ ); return *halo_exchange_; } @@ -375,8 +381,9 @@ void EdgeColumns::gather( const FieldSet& local_fieldset, FieldSet& global_field parallel::Field glb_field( make_leveled_view( glb ) ); gather().gather( &loc_field, &glb_field, nb_fields, root ); } - else + else { throw_Exception( "datatype not supported", Here() ); + } } } @@ -388,14 +395,16 @@ void EdgeColumns::gather( const Field& local, Field& global ) const { gather( local_fields, global_fields ); } const parallel::GatherScatter& EdgeColumns::gather() const { - if ( gather_scatter_ ) + if ( gather_scatter_ ) { return *gather_scatter_; + } gather_scatter_ = EdgeColumnsGatherScatterCache::instance().get_or_create( mesh_ ); return *gather_scatter_; } const parallel::GatherScatter& EdgeColumns::scatter() const { - if ( gather_scatter_ ) + if ( gather_scatter_ ) { return *gather_scatter_; + } gather_scatter_ = EdgeColumnsGatherScatterCache::instance().get_or_create( mesh_ ); return *gather_scatter_; } @@ -430,8 +439,9 @@ void EdgeColumns::scatter( const FieldSet& global_fieldset, FieldSet& local_fiel parallel::Field loc_field( make_leveled_view( loc ) ); scatter().scatter( &glb_field, &loc_field, nb_fields, root ); } - else + else { throw_Exception( "datatype not supported", Here() ); + } glb.metadata().broadcast( loc.metadata(), root ); loc.metadata().set( "global", false ); @@ -454,8 +464,9 @@ std::string checksum_3d_field( const parallel::Checksum& checksum, const Field& for ( idx_t n = 0; n < values.shape( 0 ); ++n ) { for ( idx_t j = 0; j < surface.shape( 1 ); ++j ) { surface( n, j ) = 0.; - for ( idx_t l = 0; l < values.shape( 1 ); ++l ) + for ( idx_t l = 0; l < values.shape( 1 ); ++l ) { surface( n, j ) += values( n, l, j ); + } } } return checksum.execute( surface.data(), surface_field.stride( 0 ) ); @@ -473,31 +484,40 @@ std::string EdgeColumns::checksum( const FieldSet& fieldset ) const { for ( idx_t f = 0; f < fieldset.size(); ++f ) { const Field& field = fieldset[f]; if ( field.datatype() == array::DataType::kind() ) { - if ( field.levels() ) + if ( field.levels() ) { md5 << checksum_3d_field( checksum(), field ); - else + } + else { md5 << checksum_2d_field( checksum(), field ); + } } else if ( field.datatype() == array::DataType::kind() ) { - if ( field.levels() ) + if ( field.levels() ) { md5 << checksum_3d_field( checksum(), field ); - else + } + else { md5 << checksum_2d_field( checksum(), field ); + } } else if ( field.datatype() == array::DataType::kind() ) { - if ( field.levels() ) + if ( field.levels() ) { md5 << checksum_3d_field( checksum(), field ); - else + } + else { md5 << checksum_2d_field( checksum(), field ); + } } else if ( field.datatype() == array::DataType::kind() ) { - if ( field.levels() ) + if ( field.levels() ) { md5 << checksum_3d_field( checksum(), field ); - else + } + else { md5 << checksum_2d_field( checksum(), field ); + } } - else + else { throw_Exception( "datatype not supported", Here() ); + } } return md5; } @@ -508,8 +528,9 @@ std::string EdgeColumns::checksum( const Field& field ) const { } const parallel::Checksum& EdgeColumns::checksum() const { - if ( checksum_ ) + if ( checksum_ ) { return *checksum_; + } checksum_ = EdgeColumnsChecksumCache::instance().get_or_create( mesh_ ); return *checksum_; } diff --git a/src/atlas/functionspace/NodeColumns.cc b/src/atlas/functionspace/NodeColumns.cc index 1a26cedd8..cdd2e5f2a 100644 --- a/src/atlas/functionspace/NodeColumns.cc +++ b/src/atlas/functionspace/NodeColumns.cc @@ -242,8 +242,9 @@ idx_t NodeColumns::nb_nodes() const { } idx_t NodeColumns::nb_nodes_global() const { - if ( nb_nodes_global_ >= 0 ) + if ( nb_nodes_global_ >= 0 ) { return nb_nodes_global_; + } if ( Grid grid = mesh().grid() ) { nb_nodes_global_ = grid.size(); } @@ -291,8 +292,9 @@ void NodeColumns::set_field_metadata( const eckit::Configuration& config, Field& array::DataType NodeColumns::config_datatype( const eckit::Configuration& config ) const { array::DataType::kind_t kind; - if ( !config.get( "datatype", kind ) ) + if ( !config.get( "datatype", kind ) ) { throw_Exception( "datatype missing", Here() ); + } return array::DataType( kind ); } @@ -315,13 +317,15 @@ array::ArrayShape NodeColumns::config_shape( const eckit::Configuration& config idx_t levels( nb_levels_ ); config.get( "levels", levels ); - if ( levels > 0 ) + if ( levels > 0 ) { shape.push_back( levels ); + } idx_t variables( 0 ); config.get( "variables", variables ); - if ( variables > 0 ) + if ( variables > 0 ) { shape.push_back( variables ); + } return shape; } @@ -360,8 +364,9 @@ void dispatch_haloExchange( Field& field, const parallel::HaloExchange& halo_exc else if ( field.datatype() == array::DataType::kind() ) { halo_exchange.template execute( field.array(), on_device ); } - else + else { throw_Exception( "datatype not supported", Here() ); + } field.set_dirty( false ); } } // namespace @@ -394,8 +399,9 @@ void NodeColumns::haloExchange( const Field& field, bool on_device ) const { haloExchange( fieldset, on_device ); } const parallel::HaloExchange& NodeColumns::halo_exchange() const { - if ( halo_exchange_ ) + if ( halo_exchange_ ) { return *halo_exchange_; + } halo_exchange_ = NodeColumnsHaloExchangeCache::instance().get_or_create( mesh_, halo_.size() ); return *halo_exchange_; } @@ -430,8 +436,9 @@ void NodeColumns::gather( const FieldSet& local_fieldset, FieldSet& global_field parallel::Field glb_field( make_leveled_view( glb ) ); gather().gather( &loc_field, &glb_field, nb_fields, root ); } - else + else { throw_Exception( "datatype not supported", Here() ); + } } } @@ -443,14 +450,16 @@ void NodeColumns::gather( const Field& local, Field& global ) const { gather( local_fields, global_fields ); } const parallel::GatherScatter& NodeColumns::gather() const { - if ( gather_scatter_ ) + if ( gather_scatter_ ) { return *gather_scatter_; + } gather_scatter_ = NodeColumnsGatherScatterCache::instance().get_or_create( mesh_ ); return *gather_scatter_; } const parallel::GatherScatter& NodeColumns::scatter() const { - if ( gather_scatter_ ) + if ( gather_scatter_ ) { return *gather_scatter_; + } gather_scatter_ = NodeColumnsGatherScatterCache::instance().get_or_create( mesh_ ); return *gather_scatter_; } @@ -485,8 +494,9 @@ void NodeColumns::scatter( const FieldSet& global_fieldset, FieldSet& local_fiel parallel::Field loc_field( make_leveled_view( loc ) ); scatter().scatter( &glb_field, &loc_field, nb_fields, root ); } - else + else { throw_Exception( "datatype not supported", Here() ); + } glb.metadata().broadcast( loc.metadata(), root ); loc.metadata().set( "global", false ); @@ -511,8 +521,9 @@ std::string checksum_3d_field( const parallel::Checksum& checksum, const Field& atlas_omp_for( idx_t n = 0; n < npts; ++n ) { for ( idx_t j = 0; j < surface.shape( 1 ); ++j ) { surface( n, j ) = 0.; - for ( idx_t l = 0; l < values.shape( 1 ); ++l ) + for ( idx_t l = 0; l < values.shape( 1 ); ++l ) { surface( n, j ) += values( n, l, j ); + } } } return checksum.execute( surface.data(), surface_field.stride( 0 ) ); @@ -523,16 +534,21 @@ std::string NodeColumns::checksum( const FieldSet& fieldset ) const { eckit::MD5 md5; for ( idx_t f = 0; f < fieldset.size(); ++f ) { const Field& field = fieldset[f]; - if ( field.datatype() == array::DataType::kind() ) + if ( field.datatype() == array::DataType::kind() ) { md5 << checksum_3d_field( checksum(), field ); - else if ( field.datatype() == array::DataType::kind() ) + } + else if ( field.datatype() == array::DataType::kind() ) { md5 << checksum_3d_field( checksum(), field ); - else if ( field.datatype() == array::DataType::kind() ) + } + else if ( field.datatype() == array::DataType::kind() ) { md5 << checksum_3d_field( checksum(), field ); - else if ( field.datatype() == array::DataType::kind() ) + } + else if ( field.datatype() == array::DataType::kind() ) { md5 << checksum_3d_field( checksum(), field ); - else + } + else { throw_Exception( "datatype not supported", Here() ); + } } return md5; } @@ -543,8 +559,9 @@ std::string NodeColumns::checksum( const Field& field ) const { } const parallel::Checksum& NodeColumns::checksum() const { - if ( checksum_ ) + if ( checksum_ ) { return *checksum_; + } checksum_ = NodeColumnsChecksumCache::instance().get_or_create( mesh_ ); return *checksum_; } diff --git a/src/atlas/functionspace/Spectral.cc b/src/atlas/functionspace/Spectral.cc index d0c16827c..c176bca21 100644 --- a/src/atlas/functionspace/Spectral.cc +++ b/src/atlas/functionspace/Spectral.cc @@ -211,8 +211,9 @@ idx_t Spectral::nb_spectral_coefficients_global() const { array::DataType Spectral::config_datatype( const eckit::Configuration& config ) const { array::DataType::kind_t kind; - if ( !config.get( "datatype", kind ) ) + if ( !config.get( "datatype", kind ) ) { throw_Exception( "datatype missing", Here() ); + } return array::DataType( kind ); } @@ -235,8 +236,9 @@ Field Spectral::createField( const eckit::Configuration& options ) const { array_shape.push_back( nb_spec_coeffs ); idx_t levels = config_levels( options ); - if ( levels ) + if ( levels ) { array_shape.push_back( levels ); + } Field field = Field( config_name( options ), config_datatype( options ), array_shape ); diff --git a/src/atlas/functionspace/StructuredColumns.cc b/src/atlas/functionspace/StructuredColumns.cc index 3550ecc8d..94e13637e 100644 --- a/src/atlas/functionspace/StructuredColumns.cc +++ b/src/atlas/functionspace/StructuredColumns.cc @@ -73,8 +73,9 @@ std::string checksum_3d_field( const parallel::Checksum& checksum, const Field& atlas_omp_for( idx_t n = 0; n < npts; ++n ) { for ( idx_t j = 0; j < surface.shape( 1 ); ++j ) { surface( n, j ) = 0.; - for ( idx_t l = 0; l < values.shape( 1 ); ++l ) + for ( idx_t l = 0; l < values.shape( 1 ); ++l ) { surface( n, j ) += values( n, l, j ); + } } } return checksum.execute( surface.data(), surface_field.stride( 0 ) ); @@ -202,22 +203,25 @@ const parallel::GatherScatter& StructuredColumns::gather() const { } const parallel::GatherScatter& StructuredColumns::scatter() const { - if ( gather_scatter_ ) + if ( gather_scatter_ ) { return *gather_scatter_; + } gather_scatter_ = StructuredColumnsGatherScatterCache::instance().get_or_create( *this ); return *gather_scatter_; } const parallel::Checksum& StructuredColumns::checksum() const { - if ( checksum_ ) + if ( checksum_ ) { return *checksum_; + } checksum_ = StructuredColumnsChecksumCache::instance().get_or_create( *this ); return *checksum_; } const parallel::HaloExchange& StructuredColumns::halo_exchange() const { - if ( halo_exchange_ ) + if ( halo_exchange_ ) { return *halo_exchange_; + } halo_exchange_ = StructuredColumnsHaloExchangeCache::instance().get_or_create( *this ); return *halo_exchange_; } @@ -250,8 +254,9 @@ void StructuredColumns::set_field_metadata( const eckit::Configuration& config, array::DataType StructuredColumns::config_datatype( const eckit::Configuration& config ) const { array::DataType::kind_t kind; - if ( !config.get( "datatype", kind ) ) + if ( !config.get( "datatype", kind ) ) { throw_Exception( "datatype missing", Here() ); + } return array::DataType( kind ); } @@ -274,13 +279,15 @@ array::ArrayShape StructuredColumns::config_shape( const eckit::Configuration& c idx_t levels( nb_levels_ ); config.get( "levels", levels ); - if ( levels > 0 ) + if ( levels > 0 ) { shape.push_back( levels ); + } idx_t variables( 0 ); config.get( "variables", variables ); - if ( variables > 0 ) + if ( variables > 0 ) { shape.push_back( variables ); + } return shape; } @@ -295,10 +302,12 @@ void StructuredColumns::Map2to1::print( std::ostream& out ) const { out << std::setw( 4 ) << j << " : "; for ( idx_t i = i_min_; i <= i_max_; ++i ) { idx_t v = operator()( i, j ); - if ( v == missing() ) + if ( v == missing() ) { out << std::setw( 6 ) << "X"; - else + } + else { out << std::setw( 6 ) << v; + } } out << '\n'; } @@ -307,10 +316,12 @@ void StructuredColumns::Map2to1::print( std::ostream& out ) const { void StructuredColumns::IndexRange::print( std::ostream& out ) const { for ( idx_t i = min_; i <= max_; ++i ) { idx_t v = operator()( i ); - if ( v == missing() ) + if ( v == missing() ) { out << std::setw( 4 ) << "X"; - else + } + else { out << std::setw( 4 ) << v; + } } out << '\n'; } @@ -467,8 +478,9 @@ void StructuredColumns::gather( const FieldSet& local_fieldset, FieldSet& global parallel::Field glb_field( make_leveled_view( glb ) ); gather().gather( &loc_field, &glb_field, nb_fields, root ); } - else + else { throw_Exception( "datatype not supported", Here() ); + } } } // ---------------------------------------------------------------------------- @@ -518,8 +530,9 @@ void StructuredColumns::scatter( const FieldSet& global_fieldset, FieldSet& loca parallel::Field loc_field( make_leveled_view( loc ) ); scatter().scatter( &glb_field, &loc_field, nb_fields, root ); } - else + else { throw_Exception( "datatype not supported", Here() ); + } glb.metadata().broadcast( loc.metadata(), root ); loc.metadata().set( "global", false ); @@ -543,16 +556,21 @@ std::string StructuredColumns::checksum( const FieldSet& fieldset ) const { eckit::MD5 md5; for ( idx_t f = 0; f < fieldset.size(); ++f ) { const Field& field = fieldset[f]; - if ( field.datatype() == array::DataType::kind() ) + if ( field.datatype() == array::DataType::kind() ) { md5 << checksum_3d_field( checksum(), field ); - else if ( field.datatype() == array::DataType::kind() ) + } + else if ( field.datatype() == array::DataType::kind() ) { md5 << checksum_3d_field( checksum(), field ); - else if ( field.datatype() == array::DataType::kind() ) + } + else if ( field.datatype() == array::DataType::kind() ) { md5 << checksum_3d_field( checksum(), field ); - else if ( field.datatype() == array::DataType::kind() ) + } + else if ( field.datatype() == array::DataType::kind() ) { md5 << checksum_3d_field( checksum(), field ); - else + } + else { throw_Exception( "datatype not supported", Here() ); + } } return md5; } @@ -663,8 +681,9 @@ void dispatch_haloExchange( Field& field, const parallel::HaloExchange& halo_exc halo_exchange.template execute( field.array(), false ); fixup_halos.template apply( field ); } - else + else { throw_Exception( "datatype not supported", Here() ); + } field.set_dirty( false ); } } // namespace @@ -700,18 +719,24 @@ void StructuredColumns::haloExchange( const Field& field, bool ) const { size_t StructuredColumns::footprint() const { size_t size = sizeof( *this ); size += ij2gp_.footprint(); - if ( field_xy_ ) + if ( field_xy_ ) { size += field_xy_.footprint(); - if ( field_partition_ ) + } + if ( field_partition_ ) { size += field_partition_.footprint(); - if ( field_global_index_ ) + } + if ( field_global_index_ ) { size += field_global_index_.footprint(); - if ( field_remote_index_ ) + } + if ( field_remote_index_ ) { size += field_remote_index_.footprint(); - if ( field_index_i_ ) + } + if ( field_index_i_ ) { size += field_index_i_.footprint(); - if ( field_index_j_ ) + } + if ( field_index_j_ ) { size += field_index_j_.footprint(); + } return size; } diff --git a/src/atlas/functionspace/detail/NodeColumnsInterface.cc b/src/atlas/functionspace/detail/NodeColumnsInterface.cc index 906341fb3..1e0b0b38e 100644 --- a/src/atlas/functionspace/detail/NodeColumnsInterface.cc +++ b/src/atlas/functionspace/detail/NodeColumnsInterface.cc @@ -191,8 +191,9 @@ void atlas__NodesFunctionSpace__sum_arr_double( const NodeColumns* This, const f This->orderIndependentSum( field, sumvec, idx_t_N ); size = sumvec.size(); sum = new double[size]; - for ( idx_t j = 0; j < (idx_t)size; ++j ) + for ( idx_t j = 0; j < (idx_t)size; ++j ) { sum[j] = sumvec[j]; + } N = idx_t_N; } @@ -205,8 +206,9 @@ void atlas__NodesFunctionSpace__sum_arr_float( const NodeColumns* This, const fi This->orderIndependentSum( field, sumvec, idx_t_N ); size = sumvec.size(); sum = new float[size]; - for ( idx_t j = 0; j < (idx_t)size; ++j ) + for ( idx_t j = 0; j < (idx_t)size; ++j ) { sum[j] = sumvec[j]; + } N = idx_t_N; } @@ -219,8 +221,9 @@ void atlas__NodesFunctionSpace__sum_arr_long( const NodeColumns* This, const fie This->orderIndependentSum( field, sumvec, idx_t_N ); size = sumvec.size(); sum = new long[size]; - for ( idx_t j = 0; j < (idx_t)size; ++j ) + for ( idx_t j = 0; j < (idx_t)size; ++j ) { sum[j] = sumvec[j]; + } N = idx_t_N; } @@ -233,8 +236,9 @@ void atlas__NodesFunctionSpace__sum_arr_int( const NodeColumns* This, const fiel This->orderIndependentSum( field, sumvec, idx_t_N ); size = sumvec.size(); sum = new int[size]; - for ( idx_t j = 0; j < (idx_t)size; ++j ) + for ( idx_t j = 0; j < (idx_t)size; ++j ) { sum[j] = sumvec[j]; + } N = idx_t_N; } @@ -274,8 +278,9 @@ void atlas__NodesFunctionSpace__oisum_arr_double( const NodeColumns* This, const This->orderIndependentSum( field, sumvec, idx_t_N ); size = sumvec.size(); sum = new double[size]; - for ( idx_t j = 0; j < (idx_t)size; ++j ) + for ( idx_t j = 0; j < (idx_t)size; ++j ) { sum[j] = sumvec[j]; + } N = idx_t_N; } @@ -288,8 +293,9 @@ void atlas__NodesFunctionSpace__oisum_arr_float( const NodeColumns* This, const This->orderIndependentSum( field, sumvec, idx_t_N ); size = sumvec.size(); sum = new float[size]; - for ( idx_t j = 0; j < (idx_t)size; ++j ) + for ( idx_t j = 0; j < (idx_t)size; ++j ) { sum[j] = sumvec[j]; + } N = idx_t_N; } @@ -360,8 +366,9 @@ void atlas__NodesFunctionSpace__min_arr_double( const NodeColumns* This, const f This->minimum( field, minvec ); size = minvec.size(); minimum = new double[size]; - for ( idx_t j = 0; j < (idx_t)size; ++j ) + for ( idx_t j = 0; j < (idx_t)size; ++j ) { minimum[j] = minvec[j]; + } } void atlas__NodesFunctionSpace__min_arr_float( const NodeColumns* This, const field::FieldImpl* field, float*& minimum, @@ -372,8 +379,9 @@ void atlas__NodesFunctionSpace__min_arr_float( const NodeColumns* This, const fi This->minimum( field, minvec ); size = minvec.size(); minimum = new float[size]; - for ( idx_t j = 0; j < (idx_t)size; ++j ) + for ( idx_t j = 0; j < (idx_t)size; ++j ) { minimum[j] = minvec[j]; + } } void atlas__NodesFunctionSpace__min_arr_long( const NodeColumns* This, const field::FieldImpl* field, long*& minimum, @@ -384,9 +392,9 @@ void atlas__NodesFunctionSpace__min_arr_long( const NodeColumns* This, const fie This->minimum( field, minvec ); size = minvec.size(); minimum = new long[size]; - for ( idx_t j = 0; j < (idx_t)size; ++j ) + for ( idx_t j = 0; j < (idx_t)size; ++j ) { minimum[j] = minvec[j]; - ; + }; } void atlas__NodesFunctionSpace__min_arr_int( const NodeColumns* This, const field::FieldImpl* field, int*& minimum, @@ -397,8 +405,9 @@ void atlas__NodesFunctionSpace__min_arr_int( const NodeColumns* This, const fiel This->minimum( field, minvec ); size = minvec.size(); minimum = new int[size]; - for ( idx_t j = 0; j < (idx_t)size; ++j ) + for ( idx_t j = 0; j < (idx_t)size; ++j ) { minimum[j] = minvec[j]; + } } void atlas__NodesFunctionSpace__max_arr_double( const NodeColumns* This, const field::FieldImpl* field, @@ -422,8 +431,9 @@ void atlas__NodesFunctionSpace__max_arr_float( const NodeColumns* This, const fi This->maximum( field, maxvec ); size = maxvec.size(); maximum = new float[size]; - for ( idx_t j = 0; j < (idx_t)size; ++j ) + for ( idx_t j = 0; j < (idx_t)size; ++j ) { maximum[j] = maxvec[j]; + } } void atlas__NodesFunctionSpace__max_arr_long( const NodeColumns* This, const field::FieldImpl* field, long*& maximum, @@ -434,8 +444,9 @@ void atlas__NodesFunctionSpace__max_arr_long( const NodeColumns* This, const fie This->maximum( field, maxvec ); size = maxvec.size(); maximum = new long[size]; - for ( idx_t j = 0; j < (idx_t)size; ++j ) + for ( idx_t j = 0; j < (idx_t)size; ++j ) { maximum[j] = maxvec[j]; + } } void atlas__NodesFunctionSpace__max_arr_int( const NodeColumns* This, const field::FieldImpl* field, int*& maximum, @@ -446,8 +457,9 @@ void atlas__NodesFunctionSpace__max_arr_int( const NodeColumns* This, const fiel This->maximum( field, maxvec ); size = maxvec.size(); maximum = new int[size]; - for ( idx_t j = 0; j < (idx_t)size; ++j ) + for ( idx_t j = 0; j < (idx_t)size; ++j ) { maximum[j] = maxvec[j]; + } } void atlas__NodesFunctionSpace__minloc_double( const NodeColumns* This, const field::FieldImpl* field, double& minimum, @@ -686,8 +698,9 @@ void atlas__NodesFunctionSpace__mean_arr_double( const NodeColumns* This, const This->mean( field, meanvec, idx_t_N ); size = meanvec.size(); mean = new double[size]; - for ( idx_t j = 0; j < (idx_t)size; ++j ) + for ( idx_t j = 0; j < (idx_t)size; ++j ) { mean[j] = meanvec[j]; + } N = idx_t_N; } @@ -700,8 +713,9 @@ void atlas__NodesFunctionSpace__mean_arr_float( const NodeColumns* This, const f This->mean( field, meanvec, idx_t_N ); size = meanvec.size(); mean = new float[size]; - for ( idx_t j = 0; j < (idx_t)size; ++j ) + for ( idx_t j = 0; j < (idx_t)size; ++j ) { mean[j] = meanvec[j]; + } N = idx_t_N; } diff --git a/src/atlas/functionspace/detail/NodeColumns_FieldStatistics.cc b/src/atlas/functionspace/detail/NodeColumns_FieldStatistics.cc index b653694a9..9c1e604ed 100644 --- a/src/atlas/functionspace/detail/NodeColumns_FieldStatistics.cc +++ b/src/atlas/functionspace/detail/NodeColumns_FieldStatistics.cc @@ -59,28 +59,34 @@ array::LocalView make_leveled_view( const Field& field ) { template array::LocalView make_leveled_scalar_view( const Field& field ) { using namespace array; - if ( field.levels() ) + if ( field.levels() ) { return make_view( field ).slice( Range::all(), Range::all() ); - else + } + else { return make_view( field ).slice( Range::all(), Range::dummy() ); + } } template array::LocalView make_surface_view( const Field& field ) { using namespace array; - if ( field.variables() ) + if ( field.variables() ) { return make_view( field ).slice( Range::all(), Range::all() ); - else + } + else { return make_view( field ).slice( Range::all(), Range::dummy() ); + } } template array::LocalView make_per_level_view( const Field& field ) { using namespace array; - if ( field.rank() == 2 ) + if ( field.rank() == 2 ) { return make_view( field ).slice( Range::all(), Range::all() ); - else + } + else { return make_view( field ).slice( Range::all(), Range::dummy() ); + } } } // namespace @@ -103,8 +109,9 @@ void dispatch_sum( const NodeColumns& fs, const Field& field, T& result, idx_t& atlas_omp_pragma( omp parallel for default(shared) reduction(+:local_sum) ) for( idx_t n=0; n( field ); @@ -374,8 +382,9 @@ void dispatch_order_independent_sum_2d( const NodeColumns& fs, const Field& fiel idx_t& N ) { idx_t nvar = field.variables(); result.resize( nvar ); - for ( idx_t j = 0; j < nvar; ++j ) + for ( idx_t j = 0; j < nvar; ++j ) { result[j] = 0.; + } Field global = fs.createField( field, option::name( "global" ) | option::global() ); fs.gather( field, global ); if ( mpi::comm().rank() == 0 ) { @@ -466,8 +475,9 @@ template void dispatch_order_independent_sum_per_level( const NodeColumns& fs, const Field& field, Field& sumfield, idx_t& N ) { array::ArrayShape shape; shape.reserve( field.rank() - 1 ); - for ( idx_t j = 1; j < field.rank(); ++j ) + for ( idx_t j = 1; j < field.rank(); ++j ) { shape.push_back( field.shape( j ) ); + } sumfield.resize( shape ); auto sum = make_per_level_view( sumfield ); @@ -676,8 +686,9 @@ template void dispatch_minimum_per_level( const NodeColumns& fs, const Field& field, Field& min_field ) { array::ArrayShape shape; shape.reserve( field.rank() - 1 ); - for ( idx_t j = 1; j < field.rank(); ++j ) + for ( idx_t j = 1; j < field.rank(); ++j ) { shape.push_back( field.shape( j ) ); + } min_field.resize( shape ); auto min = make_per_level_view( min_field ); @@ -738,8 +749,9 @@ template void dispatch_maximum_per_level( const NodeColumns& fs, const Field& field, Field& max_field ) { array::ArrayShape shape; shape.reserve( field.rank() - 1 ); - for ( idx_t j = 1; j < field.rank(); ++j ) + for ( idx_t j = 1; j < field.rank(); ++j ) { shape.push_back( field.shape( j ) ); + } max_field.resize( shape ); auto max = make_per_level_view( max_field ); @@ -1057,8 +1069,9 @@ void dispatch_minimum_and_location_per_level( const NodeColumns& fs, const Field const array::LocalView arr = make_leveled_view( field ); array::ArrayShape shape; shape.reserve( field.rank() - 1 ); - for ( idx_t j = 1; j < field.rank(); ++j ) + for ( idx_t j = 1; j < field.rank(); ++j ) { shape.push_back( field.shape( j ) ); + } min_field.resize( shape ); glb_idx_field.resize( shape ); const idx_t nvar = arr.shape( 2 ); @@ -1156,8 +1169,9 @@ void dispatch_maximum_and_location_per_level( const NodeColumns& fs, const Field const array::LocalView arr = make_leveled_view( field ); array::ArrayShape shape; shape.reserve( field.rank() - 1 ); - for ( idx_t j = 1; j < field.rank(); ++j ) + for ( idx_t j = 1; j < field.rank(); ++j ) { shape.push_back( field.shape( j ) ); + } max_field.resize( shape ); glb_idx_field.resize( shape ); const idx_t nvar = arr.shape( 2 ); diff --git a/src/atlas/grid/Grid.cc b/src/atlas/grid/Grid.cc index bfe4b33ac..f6371c0b8 100644 --- a/src/atlas/grid/Grid.cc +++ b/src/atlas/grid/Grid.cc @@ -39,8 +39,9 @@ Grid::IterateLonLat Grid::lonlat() const { Grid::Grid( const std::string& shortname, const Domain& domain ) : Handle( [&] { Config config; - if ( domain ) + if ( domain ) { config.set( "domain", domain.spec() ); + } return Grid::Implementation::create( shortname, config ); }() ) {} diff --git a/src/atlas/grid/Partitioner.cc b/src/atlas/grid/Partitioner.cc index 16db5488d..8938d67e9 100644 --- a/src/atlas/grid/Partitioner.cc +++ b/src/atlas/grid/Partitioner.cc @@ -38,8 +38,9 @@ namespace { detail::partitioner::Partitioner* partitioner_from_config( const Partitioner::Config& config ) { std::string type; long partitions = mpi::comm().size(); - if ( not config.get( "type", type ) ) + if ( not config.get( "type", type ) ) { throw_Exception( "'type' missing in configuration for Partitioner", Here() ); + } config.get( "partitions", partitions ); return Factory::build( type, partitions ); } diff --git a/src/atlas/grid/Vertical.cc b/src/atlas/grid/Vertical.cc index 0f847df05..912033d35 100644 --- a/src/atlas/grid/Vertical.cc +++ b/src/atlas/grid/Vertical.cc @@ -25,12 +25,15 @@ std::vector linspace( double start, double end, idx_t N, bool endpoint ) x_.resize( N ); double step; - if ( endpoint && N > 1 ) + if ( endpoint && N > 1 ) { step = ( end - start ) / double( N - 1 ); - else if ( N > 0 ) + } + else if ( N > 0 ) { step = ( end - start ) / double( N ); - else + } + else { step = 0.; + } for ( idx_t i = 0; i < N; ++i ) { x_[i] = start + i * step; diff --git a/src/atlas/grid/detail/distribution/DistributionImpl.cc b/src/atlas/grid/detail/distribution/DistributionImpl.cc index 0a569cd9a..2e0663586 100644 --- a/src/atlas/grid/detail/distribution/DistributionImpl.cc +++ b/src/atlas/grid/detail/distribution/DistributionImpl.cc @@ -45,8 +45,9 @@ DistributionImpl::DistributionImpl( const Grid& grid, const Partitioner& partiti partitioner.partition( grid, part_.data() ); nb_partitions_ = partitioner.nb_partitions(); nb_pts_.resize( nb_partitions_, 0 ); - for ( idx_t j = 0, size = static_cast( part_.size() ); j < size; ++j ) + for ( idx_t j = 0, size = static_cast( part_.size() ); j < size; ++j ) { ++nb_pts_[part_[j]]; + } max_pts_ = *std::max_element( nb_pts_.begin(), nb_pts_.end() ); min_pts_ = *std::min_element( nb_pts_.begin(), nb_pts_.end() ); type_ = distribution_type( nb_partitions_, partitioner ); @@ -72,8 +73,9 @@ void DistributionImpl::print( std::ostream& s ) const { s << "Distribution( " << "type: " << type_ << ", nbPoints: " << part_.size() << ", nbPartitions: " << nb_pts_.size() << ", parts : ["; for ( idx_t i = 0, size = static_cast( part_.size() ); i < size; i++ ) { - if ( i != 0 ) + if ( i != 0 ) { s << ','; + } s << part_[i]; } s << ']'; diff --git a/src/atlas/grid/detail/grid/GridBuilder.cc b/src/atlas/grid/detail/grid/GridBuilder.cc index 923403003..2844e92e8 100644 --- a/src/atlas/grid/detail/grid/GridBuilder.cc +++ b/src/atlas/grid/detail/grid/GridBuilder.cc @@ -35,8 +35,9 @@ size_t regex_count_parens( const std::string& string ) { last_was_backslash = true; continue; } - if ( *step == ')' && !last_was_backslash ) + if ( *step == ')' && !last_was_backslash ) { out++; + } last_was_backslash = false; } return out; @@ -46,14 +47,16 @@ int regex_match_impl( const std::string& string, const std::string& regex, std:: bool use_substr, bool use_case ) { regex_t re; size_t matchcount = 0; - if ( use_substr ) + if ( use_substr ) { matchcount = regex_count_parens( regex ); + } regmatch_t result[matchcount + 1]; int compiled_ok = !regcomp( &re, regex.c_str(), REG_EXTENDED + ( use_case ? 0 : REG_ICASE ) + ( use_substr ? 0 : REG_NOSUB ) ); - if ( !compiled_ok ) + if ( !compiled_ok ) { Log::error() << "This regular expression didn't compile: \"" << regex << "\"" << std::endl; + } ATLAS_ASSERT( compiled_ok ); @@ -209,8 +212,9 @@ const Grid::Implementation* GridBuilder::create( const Grid::Config& config ) co bool GridBuilder::match( const std::string& string, std::vector& matches, int& id ) const { id = 0; for ( const std::string& name : names_ ) { - if ( Regex( name ).match( string, matches ) ) + if ( Regex( name ).match( string, matches ) ) { return true; + } ++id; } return false; diff --git a/src/atlas/grid/detail/grid/LonLat.cc b/src/atlas/grid/detail/grid/LonLat.cc index 31c7c5ace..ef1649fb3 100644 --- a/src/atlas/grid/detail/grid/LonLat.cc +++ b/src/atlas/grid/detail/grid/LonLat.cc @@ -84,14 +84,18 @@ StructuredGrid::grid_t* create_lonlat( long nlon, long nlat, Shift shift, std::string name; - if ( shifted_x and shifted_y ) + if ( shifted_x and shifted_y ) { name = "S"; - else if ( shifted_x and not shifted_y ) + } + else if ( shifted_x and not shifted_y ) { name = "Slon"; - else if ( not shifted_x and shifted_y ) + } + else if ( not shifted_x and shifted_y ) { name = "Slat"; - else + } + else { name = "L"; + } name += std::to_string( nlon ) + "x" + std::to_string( nlat ); diff --git a/src/atlas/grid/detail/grid/Regional.cc b/src/atlas/grid/detail/grid/Regional.cc index 0673463ac..63e111b13 100644 --- a/src/atlas/grid/detail/grid/Regional.cc +++ b/src/atlas/grid/detail/grid/Regional.cc @@ -47,10 +47,12 @@ struct ConfigParser { double step( double min, double max, long N, bool endpoint = true ) { double l = max - min; - if ( endpoint && N > 1 ) + if ( endpoint && N > 1 ) { return l / double( N - 1 ); - else + } + else { return l / double( N ); + } } static bool parse( const Projection&, const Grid::Config&, Parsed& x, Parsed& y ); @@ -66,8 +68,9 @@ struct Parse_llc_step : ConfigParser { valid = config.get( "nx", x.N ) && config.get( "ny", y.N ) && config.get( "dx", x.step ) && config.get( "dy", y.step ) && config.get( "lonlat(centre)", centre_lonlat ); - if ( not valid ) + if ( not valid ) { return; + } double centre[] = {centre_lonlat[0], centre_lonlat[1]}; p.lonlat2xy( centre ); @@ -87,8 +90,9 @@ struct Parse_bounds_xy : ConfigParser { valid = config.get( "nx", x.N ) && config.get( "ny", y.N ) && config.get( "xmin", x.min ) && config.get( "xmax", x.max ) && config.get( "ymin", y.min ) && config.get( "ymax", y.max ); - if ( not valid ) + if ( not valid ) { return; + } x.step = step( x.min, x.max, x.N ); y.step = step( y.min, y.max, y.N ); @@ -117,8 +121,9 @@ struct Parse_bounds_lonlat : ConfigParser { } } - if ( not valid ) + if ( not valid ) { return; + } x.step = step( x.min, x.max, x.N ); y.step = step( y.min, y.max, y.N ); @@ -133,8 +138,9 @@ struct Parse_ll00_ll11 : ConfigParser { config.get( "lonlat(xmin,ymin)", sw ) // includes rotation && config.get( "lonlat(xmax,ymax)", ne ); // includes rotation - if ( not valid ) + if ( not valid ) { return; + } p.lonlat2xy( sw.data() ); p.lonlat2xy( ne.data() ); @@ -154,8 +160,9 @@ struct Parse_xy01_step : ConfigParser { config.get( "dy", y.step ) && config.get( "xmin", x.min ) && config.get( "ymax", y.max ); // includes rotation - if ( not valid ) + if ( not valid ) { return; + } x.max = x.min + x.step * ( x.N - 1 ); y.min = y.max - y.step * ( y.N - 1 ); @@ -168,8 +175,9 @@ struct Parse_ll00_step : ConfigParser { valid = config.get( "nx", x.N ) && config.get( "ny", y.N ) && config.get( "dx", x.step ) && config.get( "dy", y.step ) && config.get( "lonlat(xmin,ymin)", sw ); // includes rotation - if ( not valid ) + if ( not valid ) { return; + } p.lonlat2xy( sw.data() ); x.min = sw[0]; @@ -185,8 +193,9 @@ struct Parse_xy00_step : ConfigParser { valid = config.get( "nx", x.N ) && config.get( "ny", y.N ) && config.get( "dx", x.step ) && config.get( "dy", y.step ) && config.get( "xmin", x.min ) && config.get( "ymin", y.min ); - if ( not valid ) + if ( not valid ) { return; + } x.max = x.min + x.step * ( x.N - 1 ); y.max = y.min + y.step * ( y.N - 1 ); @@ -200,8 +209,9 @@ struct Parse_ll01_step : ConfigParser { // This resembles GRIB input for "lambe valid = config.get( "nx", x.N ) && config.get( "ny", y.N ) && config.get( "dx", x.step ) && config.get( "dy", y.step ) && config.get( "lonlat(xmin,ymax)", nw ); // includes rotation - if ( not valid ) + if ( not valid ) { return; + } p.lonlat2xy( nw.data() ); x.min = nw[0]; @@ -226,34 +236,42 @@ bool ConfigParser::parse( const Projection& projection, const Grid::Config& conf bool ConfigParser::parse( const Projection& projection, const Grid::Config& config, Parsed& x, Parsed& y ) { // bounding box using 4 variables (any projection allowed) - if ( ConfigParser::parse( projection, config, x, y ) ) + if ( ConfigParser::parse( projection, config, x, y ) ) { return true; + } // centre of domain and increments (any projection allowed) - if ( ConfigParser::parse( projection, config, x, y ) ) + if ( ConfigParser::parse( projection, config, x, y ) ) { return true; + } // top-left of domain and increments (any projection allowed) - if ( ConfigParser::parse( projection, config, x, y ) ) + if ( ConfigParser::parse( projection, config, x, y ) ) { return true; - if ( ConfigParser::parse( projection, config, x, y ) ) + } + if ( ConfigParser::parse( projection, config, x, y ) ) { return true; + } // bottom-left of domain and increments (any projection allowed) - if ( ConfigParser::parse( projection, config, x, y ) ) + if ( ConfigParser::parse( projection, config, x, y ) ) { return true; - if ( ConfigParser::parse( projection, config, x, y ) ) + } + if ( ConfigParser::parse( projection, config, x, y ) ) { return true; + } // bounding box using two points defined in lonlat (any projection allowed) - if ( ConfigParser::parse( projection, config, x, y ) ) + if ( ConfigParser::parse( projection, config, x, y ) ) { return true; + } //-------- From here on, projection must be (rotated) lonlat --------// // bounding box using 4 variables (south west north east) - if ( ConfigParser::parse( projection, config, x, y ) ) + if ( ConfigParser::parse( projection, config, x, y ) ) { return true; + } return false; } @@ -329,14 +347,18 @@ static class zonal_band : public GridBuilder { // Read grid configuration ConfigParser::Parsed y; long nx; - if ( not config.get( "nx", nx ) ) + if ( not config.get( "nx", nx ) ) { throw_Exception( "Parameter 'nx' missing in configuration", Here() ); - if ( not config.get( "ny", y.N ) ) + } + if ( not config.get( "ny", y.N ) ) { throw_Exception( "Parameter 'ny' missing in configuration", Here() ); - if ( not( config.get( "ymin", y.min ) or config.get( "south", y.min ) ) ) + } + if ( not( config.get( "ymin", y.min ) or config.get( "south", y.min ) ) ) { y.min = -90.; - if ( not( config.get( "ymax", y.max ) or config.get( "north", y.max ) ) ) + } + if ( not( config.get( "ymax", y.max ) or config.get( "north", y.max ) ) ) { y.max = 90.; + } YSpace yspace = config.getInt( "y_numbering", -1 ) < 0 ? LinearSpacing( y.max, y.min, y.N, true ) : LinearSpacing( y.min, y.max, y.N, true ); diff --git a/src/atlas/grid/detail/grid/Structured.cc b/src/atlas/grid/detail/grid/Structured.cc index 41996fd31..2094cf5ce 100644 --- a/src/atlas/grid/detail/grid/Structured.cc +++ b/src/atlas/grid/detail/grid/Structured.cc @@ -139,14 +139,18 @@ Structured::XSpace::Implementation::Implementation( const Config& config ) { std::max( v_N.size(), std::max( v_start.size(), std::max( v_end.size(), std::max( v_length.size(), 1ul ) ) ) ); reserve( ny ); - if ( not v_N.empty() ) + if ( not v_N.empty() ) { ATLAS_ASSERT( static_cast( v_N.size() ) == ny ); - if ( not v_start.empty() ) + } + if ( not v_start.empty() ) { ATLAS_ASSERT( static_cast( v_start.size() ) == ny ); - if ( not v_end.empty() ) + } + if ( not v_end.empty() ) { ATLAS_ASSERT( static_cast( v_end.size() ) == ny ); - if ( not v_length.empty() ) + } + if ( not v_length.empty() ) { ATLAS_ASSERT( static_cast( v_length.size() ) == ny ); + } nxmin_ = std::numeric_limits::max(); nxmax_ = 0; @@ -154,14 +158,18 @@ Structured::XSpace::Implementation::Implementation( const Config& config ) { max_ = -std::numeric_limits::max(); for ( idx_t j = 0; j < ny; ++j ) { - if ( not v_N.empty() ) + if ( not v_N.empty() ) { config_xspace.set( "N", v_N[j] ); - if ( not v_start.empty() ) + } + if ( not v_start.empty() ) { config_xspace.set( "start", v_start[j] ); - if ( not v_end.empty() ) + } + if ( not v_end.empty() ) { config_xspace.set( "end", v_end[j] ); - if ( not v_length.empty() ) + } + if ( not v_length.empty() ) { config_xspace.set( "length", v_length[j] ); + } spacing::LinearSpacing::Params xspace( config_xspace ); xmin_.push_back( xspace.start ); xmax_.push_back( xspace.end ); @@ -566,8 +574,9 @@ static class structured : public GridBuilder { Domain domain; Config config_proj; - if ( config.get( "projection", config_proj ) ) + if ( config.get( "projection", config_proj ) ) { projection = Projection( config_proj ); + } Config config_domain; if ( config.get( "domain", config_domain ) ) { @@ -575,8 +584,9 @@ static class structured : public GridBuilder { } Config config_yspace; - if ( not config.get( "yspace", config_yspace ) ) + if ( not config.get( "yspace", config_yspace ) ) { throw_Exception( "yspace missing in configuration", Here() ); + } yspace = Spacing( config_yspace ); XSpace xspace; diff --git a/src/atlas/grid/detail/grid/Unstructured.cc b/src/atlas/grid/detail/grid/Unstructured.cc index 83222dfec..ff33951c2 100644 --- a/src/atlas/grid/detail/grid/Unstructured.cc +++ b/src/atlas/grid/detail/grid/Unstructured.cc @@ -194,8 +194,9 @@ idx_t Unstructured::size() const { } Grid::Spec Unstructured::spec() const { - if ( cached_spec_ ) + if ( cached_spec_ ) { return *cached_spec_; + } cached_spec_.reset( new Grid::Spec ); diff --git a/src/atlas/grid/detail/partitioner/CheckerboardPartitioner.cc b/src/atlas/grid/detail/partitioner/CheckerboardPartitioner.cc index 539a7b9a8..6e84a15c9 100644 --- a/src/atlas/grid/detail/partitioner/CheckerboardPartitioner.cc +++ b/src/atlas/grid/detail/partitioner/CheckerboardPartitioner.cc @@ -54,8 +54,9 @@ CheckerboardPartitioner::CheckerboardPartitioner( int N, int nbands, bool checke CheckerboardPartitioner::Checkerboard CheckerboardPartitioner::checkerboard( const Grid& grid ) const { // grid dimensions const RegularGrid rg( grid ); - if ( !rg ) + if ( !rg ) { throw_Exception( "Checkerboard Partitioner only works for Regular grids.", Here() ); + } Checkerboard cb; @@ -70,19 +71,23 @@ CheckerboardPartitioner::Checkerboard CheckerboardPartitioner::checkerboard( con // default number of bands double zz = std::sqrt( (double)( nparts * cb.ny ) / cb.nx ); // aim at +/-square regions cb.nbands = (idx_t)zz + 0.5; - if ( cb.nbands < 1 ) + if ( cb.nbands < 1 ) { cb.nbands = 1; // at least one band - if ( cb.nbands > nparts ) + } + if ( cb.nbands > nparts ) { cb.nbands = nparts; // not more bands than procs + } // true checkerboard means nbands must divide nparts if ( checkerboard_ ) { - while ( nparts % cb.nbands != 0 ) + while ( nparts % cb.nbands != 0 ) { cb.nbands--; + } } } - if ( checkerboard_ && nparts % cb.nbands != 0 ) + if ( checkerboard_ && nparts % cb.nbands != 0 ) { throw_Exception( "number of bands doesn't divide number of partitions", Here() ); + } return cb; } @@ -90,20 +95,24 @@ CheckerboardPartitioner::Checkerboard CheckerboardPartitioner::checkerboard( con bool compare_Y_X( const CheckerboardPartitioner::NodeInt& node1, const CheckerboardPartitioner::NodeInt& node2 ) { // comparison of two locations; X1 < X2 if it's to the south, then to the // east. - if ( node1.y < node2.y ) + if ( node1.y < node2.y ) { return true; - if ( node1.y == node2.y ) + } + if ( node1.y == node2.y ) { return ( node1.x < node2.x ); + } return false; } bool compare_X_Y( const CheckerboardPartitioner::NodeInt& node1, const CheckerboardPartitioner::NodeInt& node2 ) { // comparison of two locations; X1 < X2 if it's to the east, then to the // south. - if ( node1.x < node2.x ) + if ( node1.x < node2.x ) { return true; - if ( node1.x == node2.x ) + } + if ( node1.x == node2.x ) { return ( node1.y < node2.y ); + } return false; } @@ -131,8 +140,9 @@ Number of procs per band remainder -= npartsb[iband]; } // distribute remaining procs over first bands - for ( size_t iband = 0; iband < remainder; iband++ ) + for ( size_t iband = 0; iband < remainder; iband++ ) { ++npartsb[iband]; + } /* Number of gridpoints per band @@ -146,8 +156,9 @@ Number of gridpoints per band remainder -= ngpb[iband]; } // distribute remaining gridpoints over first bands - for ( size_t iband = 0; iband < remainder; iband++ ) + for ( size_t iband = 0; iband < remainder; iband++ ) { ++ngpb[iband]; + } } else { remainder = ny; @@ -156,8 +167,9 @@ Number of gridpoints per band remainder -= ngpb[iband] / nx; } // distribute remaining rows over first bands - for ( size_t iband = 0; iband < remainder; iband++ ) + for ( size_t iband = 0; iband < remainder; iband++ ) { ngpb[iband] += nx; + } } // for (int iband=0;iband 0 ) { w = x - 1; - for ( k = 2; k <= n; ++k ) + for ( k = 2; k <= n; ++k ) { w = w * ( x - k ); + } } else { w = 1; - for ( k = 0; k <= -n - 1; ++k ) + for ( k = 0; k <= -n - 1; ++k ) { y = y * ( x + k ); + } } return w / y; } @@ -123,12 +125,15 @@ double polar_colat( int N ) { // Given N, determine the colatitude of the North polar spherical cap. // double polar_c( 0 ); - if ( N == 1 ) + if ( N == 1 ) { polar_c = M_PI; - if ( N == 2 ) + } + if ( N == 2 ) { polar_c = 0.5 * M_PI; - if ( N > 2 ) + } + if ( N > 2 ) { polar_c = sradius_of_cap( area_of_ideal_region( N ) ); + } return polar_c; } @@ -183,10 +188,12 @@ int num_collars( int N, const double& c_polar, const double& a_ideal ) { // determine n_collars, the number of collars between the polar caps. // bool enough = ( N > 2 ) && ( a_ideal > 0 ); - if ( enough ) + if ( enough ) { return std::max( 1, static_cast( round( ( M_PI - 2. * c_polar ) / a_ideal ) ) ); - else + } + else { return 0; + } } void round_to_naturals( int N, int ncollars, double r_regions[], int n_regions[] ) { @@ -416,8 +423,9 @@ EqualRegionsPartitioner::EqualRegionsPartitioner( int N ) : Partitioner( N ), N_ int EqualRegionsPartitioner::partition( const double& x, const double& y ) const { int b = band( y ); int p = 0; - for ( int n = 0; n < b; ++n ) + for ( int n = 0; n < b; ++n ) { p += sectors_[n]; + } return p + sector( b, x ); } @@ -427,10 +435,12 @@ int EqualRegionsPartitioner::band( const double& y ) const { int EqualRegionsPartitioner::sector( int band, const double& x ) const { double xreg = x; - if ( x < 0. ) + if ( x < 0. ) { xreg += 2. * M_PI; - else if ( x > 2. * M_PI ) + } + else if ( x > 2. * M_PI ) { xreg -= 2. * M_PI; + } return std::floor( xreg * sectors_[band] / ( 2. * M_PI + 1e-8 ) ); } @@ -449,18 +459,22 @@ void EqualRegionsPartitioner::where( int partition, int& band, int& sector ) con } bool compare_NS_WE( const EqualRegionsPartitioner::NodeInt& node1, const EqualRegionsPartitioner::NodeInt& node2 ) { - if ( node1.y > node2.y ) + if ( node1.y > node2.y ) { return true; - if ( node1.y == node2.y ) + } + if ( node1.y == node2.y ) { return ( node1.x < node2.x ); + } return false; } bool compare_WE_NS( const EqualRegionsPartitioner::NodeInt& node1, const EqualRegionsPartitioner::NodeInt& node2 ) { - if ( node1.x < node2.x ) + if ( node1.x < node2.x ) { return true; - if ( node1.x == node2.x ) + } + if ( node1.x == node2.x ) { return ( node1.y > node2.y ); + } return false; } @@ -537,8 +551,9 @@ void EqualRegionsPartitioner::partition( int nb_nodes, NodeInt nodes[], int part void EqualRegionsPartitioner::partition( const Grid& grid, int part[] ) const { if ( N_ == 1 ) { // trivial solution, so much faster - for ( idx_t j = 0; j < grid.size(); ++j ) + for ( idx_t j = 0; j < grid.size(); ++j ) { part[j] = 0; + } } else { ATLAS_TRACE( "EqualRegionsPartitioner::partition" ); @@ -586,8 +601,9 @@ void EqualRegionsPartitioner::partition( const Grid& grid, int part[] ) const { for ( int w = 0; w < nb_workers; ++w ) { int w_begin = w * grid.size() / N_; int w_end = ( w + 1 ) * grid.size() / N_; - if ( w == nb_workers - 1 ) + if ( w == nb_workers - 1 ) { w_end = grid.size(); + } size_t w_size = w_end - w_begin; int work_rank = std::min( w, mpi_size - 1 ); @@ -644,8 +660,9 @@ void EqualRegionsPartitioner::partition( const Grid& grid, int part[] ) const { for ( int w = 0; w < nb_workers; ++w ) { int w_begin = w * grid.size() / N_; int w_end = ( w + 1 ) * grid.size() / N_; - if ( w == nb_workers - 1 ) + if ( w == nb_workers - 1 ) { w_end = grid.size(); + } if ( w != 0 ) { std::inplace_merge( nodes.begin(), nodes.begin() + w_begin, nodes.begin() + w_end, compare_NS_WE ); diff --git a/src/atlas/grid/detail/partitioner/Partitioner.cc b/src/atlas/grid/detail/partitioner/Partitioner.cc index b12ec8297..5c5b1dc19 100644 --- a/src/atlas/grid/detail/partitioner/Partitioner.cc +++ b/src/atlas/grid/detail/partitioner/Partitioner.cc @@ -135,8 +135,9 @@ Partitioner* PartitionerFactory::build( const std::string& name ) { if ( j == m->end() ) { Log::error() << "No PartitionerFactory for [" << name << "]" << '\n'; Log::error() << "PartitionerFactories are:" << '\n'; - for ( j = m->begin(); j != m->end(); ++j ) + for ( j = m->begin(); j != m->end(); ++j ) { Log::error() << " " << ( *j ).first << '\n'; + } throw_Exception( std::string( "No PartitionerFactory called " ) + name ); } @@ -157,8 +158,9 @@ Partitioner* PartitionerFactory::build( const std::string& name, const idx_t nb_ if ( j == m->end() ) { Log::error() << "No PartitionerFactory for [" << name << "]" << '\n'; Log::error() << "PartitionerFactories are:" << '\n'; - for ( j = m->begin(); j != m->end(); ++j ) + for ( j = m->begin(); j != m->end(); ++j ) { Log::error() << " " << ( *j ).first << '\n'; + } throw_Exception( std::string( "No PartitionerFactory called " ) + name ); } diff --git a/src/atlas/grid/detail/pl/classic_gaussian/N.cc b/src/atlas/grid/detail/pl/classic_gaussian/N.cc index 5aaf77b66..3ac081014 100644 --- a/src/atlas/grid/detail/pl/classic_gaussian/N.cc +++ b/src/atlas/grid/detail/pl/classic_gaussian/N.cc @@ -23,14 +23,16 @@ namespace classic_gaussian { void PointsPerLatitude::assign( long nlon[], const size_t size ) const { ATLAS_ASSERT( size >= nlon_.size() ); - for ( size_t jlat = 0; jlat < nlon_.size(); ++jlat ) + for ( size_t jlat = 0; jlat < nlon_.size(); ++jlat ) { nlon[jlat] = nlon_[jlat]; + } } void PointsPerLatitude::assign( int nlon[], const size_t size ) const { ATLAS_ASSERT( size >= nlon_.size() ); - for ( size_t jlat = 0; jlat < nlon_.size(); ++jlat ) + for ( size_t jlat = 0; jlat < nlon_.size(); ++jlat ) { nlon[jlat] = nlon_[jlat]; + } } void PointsPerLatitude::assign( std::vector& nlon ) const { diff --git a/src/atlas/grid/detail/spacing/FocusSpacing.cc b/src/atlas/grid/detail/spacing/FocusSpacing.cc index f661dc8e3..2b500f44d 100644 --- a/src/atlas/grid/detail/spacing/FocusSpacing.cc +++ b/src/atlas/grid/detail/spacing/FocusSpacing.cc @@ -26,16 +26,20 @@ FocusSpacing::FocusSpacing( const eckit::Parametrisation& params ) { long N; // retrieve xmin, xmax and N from params - if ( !params.get( "start", xmin ) ) + if ( !params.get( "start", xmin ) ) { throw_Exception( "start missing in Params", Here() ); - if ( !params.get( "end", xmax ) ) + } + if ( !params.get( "end", xmax ) ) { throw_Exception( "end missing in Params", Here() ); - if ( !params.get( "N", N ) ) + } + if ( !params.get( "N", N ) ) { throw_Exception( "N missing in Params", Here() ); + } // additional parameters for focus spacing - if ( !params.get( "focus_factor", focus_factor_ ) ) + if ( !params.get( "focus_factor", focus_factor_ ) ) { throw_Exception( "focus_factor missing in Params", Here() ); + } x_.resize( N ); if ( N == 1 ) { diff --git a/src/atlas/grid/detail/spacing/GaussianSpacing.cc b/src/atlas/grid/detail/spacing/GaussianSpacing.cc index 13112ff06..35461eb40 100644 --- a/src/atlas/grid/detail/spacing/GaussianSpacing.cc +++ b/src/atlas/grid/detail/spacing/GaussianSpacing.cc @@ -34,8 +34,9 @@ GaussianSpacing::GaussianSpacing( long N ) { GaussianSpacing::GaussianSpacing( const eckit::Parametrisation& params ) { // retrieve N from params long N; - if ( !params.get( "N", N ) ) + if ( !params.get( "N", N ) ) { throw_Exception( "N missing in Params", Here() ); + } // perform checks ATLAS_ASSERT( N % 2 == 0 ); diff --git a/src/atlas/grid/detail/spacing/LinearSpacing.cc b/src/atlas/grid/detail/spacing/LinearSpacing.cc index 54641fb2e..67c33e1c5 100644 --- a/src/atlas/grid/detail/spacing/LinearSpacing.cc +++ b/src/atlas/grid/detail/spacing/LinearSpacing.cc @@ -62,10 +62,12 @@ LinearSpacing::Params::Params( const eckit::Parametrisation& params ) { } length = end - start; - if ( endpoint && N > 1 ) + if ( endpoint && N > 1 ) { step = length / double( N - 1 ); - else + } + else { step = length / double( N ); + } } LinearSpacing::LinearSpacing( const eckit::Parametrisation& params ) { @@ -94,10 +96,12 @@ void LinearSpacing::setup( double start, double end, long N, bool endpoint ) { x_.resize( N ); double step; - if ( endpoint && N > 1 ) + if ( endpoint && N > 1 ) { step = ( end - start ) / double( N - 1 ); - else + } + else { step = ( end - start ) / double( N ); + } for ( long i = 0; i < N; ++i ) { x_[i] = start + i * step; @@ -113,10 +117,12 @@ void LinearSpacing::setup( double start, double end, long N, bool endpoint ) { } double LinearSpacing::step() const { - if ( size() > 1 ) + if ( size() > 1 ) { return x_[1] - x_[0]; - else + } + else { return 0.; + } } bool LinearSpacing::endpoint() const { diff --git a/src/atlas/grid/detail/spacing/gaussian/Latitudes.cc b/src/atlas/grid/detail/spacing/gaussian/Latitudes.cc index 02b5ecdde..a7d670d18 100644 --- a/src/atlas/grid/detail/spacing/gaussian/Latitudes.cc +++ b/src/atlas/grid/detail/spacing/gaussian/Latitudes.cc @@ -113,8 +113,9 @@ void legpol_newton_iteration( int kn, const double pfn[], double px, double& pxn zdlx = px; zdlk = 0.; - if ( kodd == 0 ) + if ( kodd == 0 ) { zdlk = 0.5 * pfn[0]; + } zdlxn = 0.; zdlldn = 0.; ik = 1; @@ -215,8 +216,9 @@ void legpol_quadrature( const int kn, const double pfn[], double& pl, double& pw legpol_weight( kn, pfn, zx, zw ); break; } - if ( std::abs( pmod ) <= zeps * 1000. ) + if ( std::abs( pmod ) <= zeps * 1000. ) { iflag = 1; + } } if ( iflag != 1 ) { std::stringstream s; diff --git a/src/atlas/grid/detail/spacing/gaussian/N.cc b/src/atlas/grid/detail/spacing/gaussian/N.cc index db147506a..669ebaf9d 100644 --- a/src/atlas/grid/detail/spacing/gaussian/N.cc +++ b/src/atlas/grid/detail/spacing/gaussian/N.cc @@ -28,8 +28,9 @@ return "GaussianLatitudes"; void GaussianLatitudes::assign( double lats[], const size_t size ) const { ATLAS_ASSERT( size >= lats_.size() ); - for ( size_t jlat = 0; jlat < lats_.size(); ++jlat ) + for ( size_t jlat = 0; jlat < lats_.size(); ++jlat ) { lats[jlat] = lats_[jlat]; + } } void GaussianLatitudes::assign( std::vector& lats ) const { diff --git a/src/atlas/interpolation/element/Quad3D.cc b/src/atlas/interpolation/element/Quad3D.cc index 621db2d99..1f9140fee 100644 --- a/src/atlas/interpolation/element/Quad3D.cc +++ b/src/atlas/interpolation/element/Quad3D.cc @@ -27,8 +27,9 @@ method::Intersect Quad3D::intersects( const method::Ray& r, double edgeEpsilon, Triag3D T013( v00, v10, v01 ); isect = T013.intersects( r, edgeEpsilon, epsilon ); - if ( isect ) + if ( isect ) { return isect; + } Triag3D T231( v11, v01, v10 ); isect = T231.intersects( r, edgeEpsilon, epsilon ); diff --git a/src/atlas/interpolation/method/Method.cc b/src/atlas/interpolation/method/Method.cc index b5fe2c43d..d11709661 100644 --- a/src/atlas/interpolation/method/Method.cc +++ b/src/atlas/interpolation/method/Method.cc @@ -107,8 +107,9 @@ void Method::interpolate_field_rank2( const Field& src, Field& tgt ) const { for ( idx_t c = outer[r]; c < outer[r + 1]; ++c ) { idx_t n = index[c]; Value w = static_cast( weight[c] ); - for ( idx_t k = 0; k < Nk; ++k ) + for ( idx_t k = 0; k < Nk; ++k ) { v_tgt( r, k ) += w * v_src( n, k ); + } } } } @@ -136,9 +137,11 @@ void Method::interpolate_field_rank3( const Field& src, Field& tgt ) const { for ( idx_t c = outer[r]; c < outer[r + 1]; ++c ) { idx_t n = index[c]; Value w = static_cast( weight[c] ); - for ( idx_t k = 0; k < Nk; ++k ) - for ( idx_t l = 0; l < Nl; ++l ) + for ( idx_t k = 0; k < Nk; ++k ) { + for ( idx_t l = 0; l < Nl; ++l ) { v_tgt( r, k, l ) += w * v_src( n, k, l ); + } + } } } } @@ -206,8 +209,9 @@ void Method::haloExchange( const FieldSet& fields ) const { } } void Method::haloExchange( const Field& field ) const { - if ( field.dirty() ) + if ( field.dirty() ) { source().haloExchange( field ); + } } } // namespace interpolation diff --git a/src/atlas/interpolation/method/PointSet.cc b/src/atlas/interpolation/method/PointSet.cc index 22b814719..4076d86b7 100644 --- a/src/atlas/interpolation/method/PointSet.cc +++ b/src/atlas/interpolation/method/PointSet.cc @@ -48,16 +48,18 @@ PointSet::PointSet( Mesh& mesh ) { std::vector pidx; pidx.reserve( npts_ ); - for ( size_t ip = 0; ip < npts_; ++ip ) + for ( size_t ip = 0; ip < npts_; ++ip ) { pidx.push_back( PointIndex3::Value( PointIndex3::Point( coords( ip, 0 ), coords( ip, 1 ), coords( ip, 2 ) ), ip ) ); + } tree_->build( pidx.begin(), pidx.end() ); } else { - for ( size_t ip = 0; ip < npts_; ++ip ) + for ( size_t ip = 0; ip < npts_; ++ip ) { tree_->insert( PointIndex3::Value( PointIndex3::Point( coords( ip, 0 ), coords( ip, 1 ), coords( ip, 2 ) ), ip ) ); + } } } @@ -77,8 +79,9 @@ size_t PointSet::search_unique( const Point& p, size_t idx, uint32_t n ) { // std::cout << " EQUAL !!" << std::endl; equals.push_back( nidx ); } - else + else { break; + } } if ( equals.size() == nearest.size() ) /* need to increase the search to find @@ -90,11 +93,13 @@ size_t PointSet::search_unique( const Point& p, size_t idx, uint32_t n ) { { size_t ret = idx; /* if nothing found return same idx */ - if ( equals.size() >= 1 ) /* if an equal point was found return the first one */ + if ( equals.size() >= 1 ) { /* if an equal point was found return the first one */ ret = equals[0]; + } - for ( size_t n = 1; n < equals.size(); ++n ) + for ( size_t n = 1; n < equals.size(); ++n ) { duplicates_[equals[n]] = ret; + } return ret; } diff --git a/src/atlas/interpolation/method/fe/FiniteElement.cc b/src/atlas/interpolation/method/fe/FiniteElement.cc index 957396b35..95867759f 100644 --- a/src/atlas/interpolation/method/fe/FiniteElement.cc +++ b/src/atlas/interpolation/method/fe/FiniteElement.cc @@ -122,8 +122,9 @@ struct Stencil { void FiniteElement::print( std::ostream& out ) const { functionspace::NodeColumns src( source_ ); functionspace::NodeColumns tgt( target_ ); - if ( not tgt ) + if ( not tgt ) { ATLAS_NOTIMPLEMENTED; + } auto gidx_src = array::make_view( src.nodes().global_index() ); ATLAS_ASSERT( tgt.nodes().size() == idx_t( matrix_.rows() ) ); diff --git a/src/atlas/library/Library.cc b/src/atlas/library/Library.cc index 794d2e434..3fd46f702 100644 --- a/src/atlas/library/Library.cc +++ b/src/atlas/library/Library.cc @@ -130,12 +130,15 @@ void Library::initialise( const eckit::Parametrisation& config ) { config.get( "trace.report", trace_report_ ); } - if ( not debug_ ) + if ( not debug_ ) { debug_channel_.reset(); - if ( not trace_ ) + } + if ( not trace_ ) { trace_channel_.reset(); - if ( not info_ ) + } + if ( not info_ ) { info_channel_.reset(); + } // Summary if ( getEnv( "ATLAS_LOG_RANK", 0 ) == int( mpi::comm().rank() ) ) { @@ -195,8 +198,9 @@ eckit::Channel& Library::infoChannel() const { } eckit::Channel& Library::traceChannel() const { - if ( trace_channel_ ) + if ( trace_channel_ ) { return *trace_channel_; + } if ( trace_ ) { trace_channel_.reset( new eckit::Channel( new eckit::PrefixTarget( "ATLAS_TRACE", new eckit::OStreamTarget( eckit::Log::info() ) ) ) ); diff --git a/src/atlas/mesh/Connectivity.cc b/src/atlas/mesh/Connectivity.cc index b4b0720fd..b342eeda3 100644 --- a/src/atlas/mesh/Connectivity.cc +++ b/src/atlas/mesh/Connectivity.cc @@ -133,15 +133,17 @@ void IrregularConnectivityImpl::clear() { //------------------------------------------------------------------------------------------------------ void IrregularConnectivityImpl::on_delete() { - if ( ctxt_ && callback_delete_ ) + if ( ctxt_ && callback_delete_ ) { callback_delete_( ctxt_ ); + } } //------------------------------------------------------------------------------------------------------ void IrregularConnectivityImpl::on_update() { - if ( ctxt_ && callback_update_ ) + if ( ctxt_ && callback_update_ ) { callback_update_( ctxt_ ); + } } void IrregularConnectivityImpl::resize( idx_t old_size, idx_t new_size, bool initialize, const idx_t values[], @@ -166,8 +168,9 @@ void IrregularConnectivityImpl::add( idx_t rows, idx_t cols, const idx_t values[ ATLAS_ASSERT( owns_, "Connectivity must be owned to be resized directly" ); idx_t old_size = values_.size(); - if ( rows_ == 0 ) + if ( rows_ == 0 ) { old_size = 0; + } idx_t new_size = old_size + rows * cols; idx_t new_rows = rows_ + rows; @@ -209,8 +212,9 @@ void IrregularConnectivityImpl::add( idx_t rows, const idx_t cols[] ) { ATLAS_ASSERT( owns_, "Connectivity must be owned to be resized directly" ); idx_t old_size = values_.size(); idx_t new_size = old_size; - for ( idx_t j = 0; j < rows; ++j ) + for ( idx_t j = 0; j < rows; ++j ) { new_size += cols[j]; + } idx_t new_rows = rows_ + rows; displs_.resize( new_rows + 1 ); counts_.resize( new_rows ); @@ -233,8 +237,9 @@ void IrregularConnectivityImpl::add( idx_t rows, idx_t cols ) { ATLAS_ASSERT( owns_, "Connectivity must be owned to be resized directly" ); idx_t old_size = values_.size(); - if ( rows_ == 0 ) + if ( rows_ == 0 ) { old_size = 0; + } idx_t new_size = old_size + rows * cols; idx_t new_rows = rows_ + rows; @@ -331,8 +336,9 @@ void IrregularConnectivityImpl::insert( idx_t position, idx_t rows, const idx_t } idx_t insert_size( 0 ); - for ( idx_t j = 0; j < rows; ++j ) + for ( idx_t j = 0; j < rows; ++j ) { insert_size += cols[j]; + } values_.insert( position_displs, insert_size ); @@ -400,8 +406,9 @@ void IrregularConnectivityImpl::decode_( eckit::Stream& s ) { s >> rows_; s >> maxcols_; s >> mincols_; - if ( not name.empty() ) + if ( not name.empty() ) { rename( name ); + } ctxt_ = nullptr; owns_ = true; } @@ -542,8 +549,9 @@ void MultiBlockConnectivityImpl::insert( idx_t position, idx_t rows, idx_t cols, ATLAS_ASSERT( blk_idx >= 0l ); ATLAS_ASSERT( cols == block( blk_idx ).cols() ); - for ( idx_t jblk = blk_idx; jblk < blocks_; ++jblk ) + for ( idx_t jblk = blk_idx; jblk < blocks_; ++jblk ) { block_displs_[jblk + 1] += rows; + } IrregularConnectivityImpl::insert( position, rows, cols, values, fortran_array ); rebuild_block_connectivity(); @@ -563,8 +571,9 @@ void MultiBlockConnectivityImpl::insert( idx_t position, idx_t rows, idx_t cols IrregularConnectivityImpl::insert( position, rows, cols ); - for ( idx_t jblk = blk_idx; jblk < blocks_; ++jblk ) + for ( idx_t jblk = blk_idx; jblk < blocks_; ++jblk ) { block_displs_[jblk + 1] += rows; + } rebuild_block_connectivity(); } @@ -592,8 +601,9 @@ void MultiBlockConnectivityImpl::insert( idx_t position, idx_t rows, const idx_t IrregularConnectivityImpl::insert( position, rows, cols ); - for ( idx_t jblk = blk_idx; jblk < blocks_; ++jblk ) + for ( idx_t jblk = blk_idx; jblk < blocks_; ++jblk ) { block_displs_[jblk + 1] += rows; + } rebuild_block_connectivity(); } @@ -755,8 +765,9 @@ void BlockConnectivityImpl::decode( eckit::Stream& s ) { size_t BlockConnectivityImpl::footprint() const { size_t size = sizeof( *this ); - if ( owns() ) + if ( owns() ) { size += values_.footprint(); + } return size; } diff --git a/src/atlas/mesh/Elements.cc b/src/atlas/mesh/Elements.cc index 050d3f151..7306f0fd9 100644 --- a/src/atlas/mesh/Elements.cc +++ b/src/atlas/mesh/Elements.cc @@ -51,8 +51,9 @@ Elements::Elements( ElementType* element_type, idx_t nb_elements, const idx_t no } Elements::~Elements() { - if ( owns_ ) + if ( owns_ ) { delete hybrid_elements_; + } } const std::string& Elements::name() const { diff --git a/src/atlas/mesh/HybridElements.cc b/src/atlas/mesh/HybridElements.cc index 32393e029..1da6f5996 100644 --- a/src/atlas/mesh/HybridElements.cc +++ b/src/atlas/mesh/HybridElements.cc @@ -181,10 +181,12 @@ idx_t HybridElements::add( const ElementType* element_type, idx_t nb_elements, c element_types_.push_back( etype ); elements_.resize( element_types_.size() ); for ( idx_t t = 0; t < nb_types(); ++t ) { - if ( elements_[t] ) + if ( elements_[t] ) { elements_[t]->rebuild(); - else + } + else { elements_[t] = util::ObjectHandle( new Elements( *this, t ) ); + } } node_connectivity_->add( nb_elements, nb_nodes, connectivity, fortran_array ); @@ -241,8 +243,9 @@ idx_t HybridElements::elemtype_nb_edges( idx_t elem_idx ) const { void HybridElements::insert( idx_t type_idx, idx_t position, idx_t nb_elements ) { type_idx_.insert( type_idx_.begin() + position, nb_elements, type_idx ); elements_size_[type_idx] += nb_elements; - for ( idx_t jtype = type_idx + 1; jtype < nb_types() + 1; ++jtype ) + for ( idx_t jtype = type_idx + 1; jtype < nb_types() + 1; ++jtype ) { elements_begin_[jtype] += nb_elements; + } for ( idx_t t = 0; t < nb_types(); ++t ) { elements_[t]->rebuild(); } diff --git a/src/atlas/mesh/Nodes.cc b/src/atlas/mesh/Nodes.cc index fcfad654d..dff90b5aa 100644 --- a/src/atlas/mesh/Nodes.cc +++ b/src/atlas/mesh/Nodes.cc @@ -133,8 +133,9 @@ void Nodes::print( std::ostream& os ) const { os << "\t fields=\n"; for ( idx_t i = 0; i < nb_fields(); ++i ) { os << "\t\t" << field( i ); - if ( i != nb_fields() - 1 ) + if ( i != nb_fields() - 1 ) { os << ","; + } os << "\n"; } os << "]"; diff --git a/src/atlas/mesh/actions/BuildConvexHull3D.cc b/src/atlas/mesh/actions/BuildConvexHull3D.cc index 8cd6b114d..67cf37836 100644 --- a/src/atlas/mesh/actions/BuildConvexHull3D.cc +++ b/src/atlas/mesh/actions/BuildConvexHull3D.cc @@ -74,8 +74,9 @@ static Polyhedron_3* create_convex_hull_from_points( const std::vector& // insertion from a vector : std::vector vertices( pts.size() ); - for ( idx_t i = 0, size = vertices.size(); i < size; ++i ) + for ( idx_t i = 0, size = vertices.size(); i < size; ++i ) { vertices[i] = Point_3( pts[i]( XX ), pts[i]( YY ), pts[i]( ZZ ) ); + } // compute convex hull of non-collinear points @@ -142,8 +143,9 @@ static void cgal_polyhedron_to_atlas_mesh( Mesh& mesh, Polyhedron_3& poly, Point FT innerp = n * p0; - if ( innerp < 0 ) // need to swap an edge of the triag + if ( innerp < 0 ) { // need to swap an edge of the triag std::swap( vts[1], vts[2] ); + } } /* define the triag */ @@ -180,8 +182,9 @@ static void cgal_polyhedron_to_atlas_mesh( Mesh& mesh, Polyhedron_3& poly, Point void BuildConvexHull3D::operator()( Mesh& mesh ) const { // don't tesselate meshes already with triags or quads - if ( mesh.cells().size() ) + if ( mesh.cells().size() ) { return; + } ATLAS_TRACE(); diff --git a/src/atlas/mesh/actions/BuildDualMesh.cc b/src/atlas/mesh/actions/BuildDualMesh.cc index 2b56c48ca..b1d0900a4 100644 --- a/src/atlas/mesh/actions/BuildDualMesh.cc +++ b/src/atlas/mesh/actions/BuildDualMesh.cc @@ -96,11 +96,13 @@ void build_median_dual_mesh( Mesh& mesh ) { Field dual_volumes = nodes.add( Field( "dual_volumes", array::make_datatype(), array::make_shape( nodes.size() ) ) ); - if ( !mesh.cells().has_field( "centroids_xy" ) ) + if ( !mesh.cells().has_field( "centroids_xy" ) ) { mesh.cells().add( Field( "centroids_xy", build_centroids_xy( mesh.cells(), mesh.nodes().xy() ) ) ); + } - if ( !mesh.edges().has_field( "centroids_xy" ) ) + if ( !mesh.edges().has_field( "centroids_xy" ) ) { mesh.edges().add( Field( "centroids_xy", build_centroids_xy( mesh.edges(), mesh.nodes().xy() ) ) ); + } array::ArrayView v = array::make_view( dual_volumes ); @@ -173,15 +175,17 @@ void add_median_dual_volume_contribution_cells( const mesh::HybridElements& cell // special ordering for bit-identical results idx_t nb_cells = cells.size(); std::vector ordering( nb_cells ); - for ( idx_t jcell = 0; jcell < nb_cells; ++jcell ) + for ( idx_t jcell = 0; jcell < nb_cells; ++jcell ) { ordering[jcell] = Node( util::unique_lonlat( cell_centroids( jcell, XX ), cell_centroids( jcell, YY ) ), jcell ); + } std::sort( ordering.data(), ordering.data() + nb_cells ); for ( idx_t jcell = 0; jcell < nb_cells; ++jcell ) { idx_t icell = ordering[jcell].i; - if ( patch( icell ) ) + if ( patch( icell ) ) { continue; + } double x0 = cell_centroids( icell, XX ); double y0 = cell_centroids( icell, YY ); @@ -237,10 +241,12 @@ void add_median_dual_volume_contribution_poles( const mesh::HybridElements& edge y1 = edge_centroids( iedge, YY ); y2 = 0.; - if ( std::abs( y1 - max[YY] ) < tol ) + if ( std::abs( y1 - max[YY] ) < tol ) { y2 = 90.; - else if ( std::abs( y1 - min[YY] ) < tol ) + } + else if ( std::abs( y1 - min[YY] ) < tol ) { y2 = -90.; + } if ( y2 != 0 ) { const double quad_area = std::abs( ( x1 - x0 ) * ( y2 - y0 ) ); @@ -306,10 +312,12 @@ void build_dual_normals( Mesh& mesh ) { } if ( cnt == 2 ) { dual_normals( edge, XX ) = 0; - if ( node_xy( node, YY ) < 0. ) + if ( node_xy( node, YY ) < 0. ) { dual_normals( edge, YY ) = -std::abs( x[1] - x[0] ); - else if ( node_xy( node, YY ) > 0. ) + } + else if ( node_xy( node, YY ) > 0. ) { dual_normals( edge, YY ) = std::abs( x[1] - x[0] ); + } // std::cout << "pole dual_normal = " << dual_normals(YY,edge) << // std::endl; @@ -326,10 +334,12 @@ void build_dual_normals( Mesh& mesh ) { xr = edge_centroids( edge, XX ); yr = edge_centroids( edge, YY ); ; - if ( std::abs( yr - max[YY] ) < tol ) + if ( std::abs( yr - max[YY] ) < tol ) { yr = 90.; - else if ( std::abs( yr - min[YY] ) < tol ) + } + else if ( std::abs( yr - min[YY] ) < tol ) { yr = -90.; + } } else { xr = elem_centroids( right_elem, XX ); @@ -371,8 +381,9 @@ void make_dual_normals_outward( Mesh& mesh ) { void build_brick_dual_mesh( const Grid& grid, Mesh& mesh ) { auto g = StructuredGrid( grid ); if ( g ) { - if ( mpi::comm().size() != 1 ) + if ( mpi::comm().size() != 1 ) { throw_Exception( "Cannot build_brick_dual_mesh with more than 1 task", Here() ); + } mesh::Nodes& nodes = mesh.nodes(); array::ArrayView xy = array::make_view( nodes.xy() ); @@ -390,8 +401,9 @@ void build_brick_dual_mesh( const Grid& grid, Mesh& mesh ) { double dlon = 360. / static_cast( g.nx( jlat ) ); for ( idx_t jlon = 0; jlon < g.nx( jlat ); ++jlon ) { - while ( gidx( c ) != n + 1 ) + while ( gidx( c ) != n + 1 ) { c++; + } ATLAS_ASSERT( xy( c, XX ) == g.x( jlon, jlat ) ); ATLAS_ASSERT( xy( c, YY ) == lat ); dual_volumes( c ) = dlon * dlat; diff --git a/src/atlas/mesh/actions/BuildEdges.cc b/src/atlas/mesh/actions/BuildEdges.cc index 5299b8eb8..a0d93acb5 100644 --- a/src/atlas/mesh/actions/BuildEdges.cc +++ b/src/atlas/mesh/actions/BuildEdges.cc @@ -87,8 +87,9 @@ void build_element_to_edge_connectivity( Mesh& mesh ) { { UniqueLonLat compute_uid( mesh ); - for ( idx_t jedge = 0; jedge < nb_edges; ++jedge ) + for ( idx_t jedge = 0; jedge < nb_edges; ++jedge ) { edge_sort.emplace_back( Sort( compute_uid( edge_node_connectivity.row( jedge ) ), jedge ) ); + } std::sort( edge_sort.data(), edge_sort.data() + nb_edges ); } @@ -129,8 +130,9 @@ void build_element_to_edge_connectivity( Mesh& mesh ) { }; for ( idx_t jcell = 0; jcell < mesh.cells().size(); ++jcell ) { - if ( patch( jcell ) ) + if ( patch( jcell ) ) { continue; + } for ( idx_t jcol = 0; jcol < cell_edge_connectivity.cols( jcell ); ++jcol ) { if ( cell_edge_connectivity( jcell, jcol ) == cell_edge_connectivity.missing_value() ) { const array::ArrayView gidx = array::make_view( mesh.nodes().global_index() ); @@ -165,13 +167,15 @@ void build_node_to_edge_connectivity( Mesh& mesh ) { node_to_edge.add( nodes.size(), to_edge_size.data() ); - for ( idx_t jnode = 0; jnode < nodes.size(); ++jnode ) + for ( idx_t jnode = 0; jnode < nodes.size(); ++jnode ) { to_edge_size[jnode] = 0; + } UniqueLonLat compute_uid( mesh ); std::vector edge_sort( nb_edges ); - for ( idx_t jedge = 0; jedge < nb_edges; ++jedge ) + for ( idx_t jedge = 0; jedge < nb_edges; ++jedge ) { edge_sort[jedge] = Sort( compute_uid( edge_node_connectivity.row( jedge ) ), jedge ); + } std::stable_sort( edge_sort.data(), edge_sort.data() + nb_edges ); for ( idx_t jedge = 0; jedge < nb_edges; ++jedge ) { @@ -240,8 +244,9 @@ class AccumulatePoleEdges { int npart = -1; for ( std::set::iterator it = pole_nodes[NS].begin(); it != pole_nodes[NS].end(); ++it ) { int node = *it; - if ( npart == -1 ) + if ( npart == -1 ) { npart = part( node ); + } else if ( part( node ) != npart ) { // Not implemented yet, when pole-lattitude is split. std::stringstream msg; @@ -327,8 +332,9 @@ void accumulate_pole_edges( mesh::Nodes& nodes, std::vector& pole_edge_no int npart = -1; for ( std::set::iterator it = pole_nodes[NS].begin(); it != pole_nodes[NS].end(); ++it ) { int node = *it; - if ( npart == -1 ) + if ( npart == -1 ) { npart = part( node ); + } else if ( part( node ) != npart ) { // Not implemented yet, when pole-lattitude is split. std::stringstream msg; @@ -377,10 +383,12 @@ struct ComputeUniquePoleEdgeIndex { } centroid[XX] /= 2.; centroid[YY] /= 2.; - if ( centroid[YY] > 0 ) + if ( centroid[YY] > 0 ) { centroid[YY] = 90.; - else + } + else { centroid[YY] = -90.; + } /// FIXME make this into `util::unique_lonlat(centroid)` but this causes /// weird parallel behavior return util::detail::unique32( microdeg( centroid[XX] ), microdeg( centroid[YY] ) ); @@ -567,14 +575,16 @@ void build_edges( Mesh& mesh, const eckit::Configuration& config ) { int nb_edges = mesh.edges().size(); for ( int jedge = 0; jedge < nb_edges; ++jedge ) { nb_edges_including_halo[edge_halo( jedge )] = jedge + 1; - if ( jedge > 0 ) + if ( jedge > 0 ) { ATLAS_ASSERT( edge_halo( jedge ) >= edge_halo( jedge - 1 ) ); + } } } for ( int i = 0; i <= max_halo; ++i ) { - if ( i > 0 ) + if ( i > 0 ) { ATLAS_ASSERT( nb_edges_including_halo[i] > nb_edges_including_halo[i - 1] ); + } std::stringstream ss; ss << "nb_edges_including_halo[" << i << "]"; mesh.metadata().set( ss.str(), nb_edges_including_halo[i] ); diff --git a/src/atlas/mesh/actions/BuildHalo.cc b/src/atlas/mesh/actions/BuildHalo.cc index f7d74c235..ce58bdcd7 100644 --- a/src/atlas/mesh/actions/BuildHalo.cc +++ b/src/atlas/mesh/actions/BuildHalo.cc @@ -92,20 +92,23 @@ void make_nodes_global_index_human_readable( const mesh::actions::BuildHalo& bui if ( do_all ) { points_to_edit.resize( nodes_glb_idx.size() ); - for ( idx_t i = 0; i < nodes_glb_idx.size(); ++i ) + for ( idx_t i = 0; i < nodes_glb_idx.size(); ++i ) { points_to_edit[i] = i; + } } else { glb_idx_max = nodes.global_index().metadata().getLong( "max", 0 ); points_to_edit.resize( build_halo.periodic_points_local_index_.size() ); - for ( size_t i = 0; i < points_to_edit.size(); ++i ) + for ( size_t i = 0; i < points_to_edit.size(); ++i ) { points_to_edit[i] = build_halo.periodic_points_local_index_[i]; + } } std::vector glb_idx( points_to_edit.size() ); idx_t nb_nodes = static_cast( glb_idx.size() ); - for ( idx_t i = 0; i < nb_nodes; ++i ) + for ( idx_t i = 0; i < nb_nodes; ++i ) { glb_idx[i] = nodes_glb_idx( points_to_edit[i] ); + } // ATLAS_DEBUG_VAR( points_to_edit ); // ATLAS_DEBUG_VAR( points_to_edit.size() ); @@ -223,8 +226,9 @@ void make_cells_global_index_human_readable( const mesh::actions::BuildHalo& bui std::vector glb_idx( cells_to_edit.size() ); const idx_t nb_cells = static_cast( glb_idx.size() ); - for ( idx_t i = 0; i < nb_cells; ++i ) + for ( idx_t i = 0; i < nb_cells; ++i ) { glb_idx[i] = cells_glb_idx( cells_to_edit[i] ); + } // 1) Gather all global indices, together with location @@ -384,8 +388,9 @@ std::vector filter_nodes( std::vector nodes, const Predicate& predicat std::vector filtered; filtered.reserve( nodes.size() ); for ( int inode : nodes ) { - if ( predicate( inode ) ) + if ( predicate( inode ) ) { filtered.push_back( inode ); + } } return filtered; } @@ -403,8 +408,9 @@ class Notification { std::string str() const { std::stringstream stream; for ( size_t jnote = 0; jnote < notes.size(); ++jnote ) { - if ( jnote > 0 ) + if ( jnote > 0 ) { stream << "\n"; + } stream << notes[jnote]; } return stream.str(); @@ -446,8 +452,9 @@ void build_lookup_uid2node( Mesh& mesh, Uid2Node& uid2node ) { notes.add_error( msg.str() ); } } - if ( notes.error() ) + if ( notes.error() ) { throw_Exception( notes.str(), Here() ); + } } void accumulate_elements( const Mesh& mesh, const mpi::BufferView& request_node_uid, const Uid2Node& uid2node, @@ -714,8 +721,9 @@ class BuildHaloHelper { buf.elem_part[p][jelem] = elem_part( ielem ); Topology::set( buf.elem_flags[p][jelem], elem_flags( ielem ) ); buf.elem_type[p][jelem] = mesh.cells().type_idx( ielem ); - for ( idx_t jnode = 0; jnode < elem_nodes->cols( ielem ); ++jnode ) + for ( idx_t jnode = 0; jnode < elem_nodes->cols( ielem ); ++jnode ) { buf.elem_nodes_id[p][jelemnode++] = compute_uid( ( *elem_nodes )( ielem, jnode ) ); + } } } @@ -928,8 +936,9 @@ class BuildHaloHelper { } }; - if ( not status.new_periodic_ghost_cells.size() ) + if ( not status.new_periodic_ghost_cells.size() ) { status.new_periodic_ghost_cells.resize( mesh.cells().nb_types() ); + } std::vector> received_new_elems( mpi_size ); for ( idx_t jpart = 0; jpart < mpi_size; ++jpart ) { @@ -964,8 +973,9 @@ class BuildHaloHelper { // Add new elements BlockConnectivity& node_connectivity = elements.node_connectivity(); - if ( nb_elements_of_type[t] == 0 ) + if ( nb_elements_of_type[t] == 0 ) { continue; + } idx_t old_size = elements.size(); idx_t new_elems_pos = elements.add( nb_elements_of_type[t] ); @@ -1087,11 +1097,13 @@ void gather_bdry_nodes( const BuildHaloHelper& helper, const std::vector& void increase_halo_interior( BuildHaloHelper& helper ) { helper.update(); - if ( helper.node_to_elem.size() == 0 ) + if ( helper.node_to_elem.size() == 0 ) { build_lookup_node2elem( helper.mesh, helper.node_to_elem ); + } - if ( helper.uid2node.size() == 0 ) + if ( helper.uid2node.size() == 0 ) { build_lookup_uid2node( helper.mesh, helper.uid2node ); + } // All buffers needed to move elements and nodes BuildHaloHelper::Buffers sendmesh( helper.mesh ); @@ -1106,8 +1118,9 @@ void increase_halo_interior( BuildHaloHelper& helper ) { // 2) Communicate uid of these boundary nodes to other partitions std::vector send_bdry_nodes_uid( bdry_nodes.size() ); - for ( idx_t jnode = 0; jnode < nb_bdry_nodes; ++jnode ) + for ( idx_t jnode = 0; jnode < nb_bdry_nodes; ++jnode ) { send_bdry_nodes_uid[jnode] = helper.compute_uid( bdry_nodes[jnode] ); + } idx_t mpi_size = static_cast( mpi::comm().size() ); atlas::mpi::Buffer recv_bdry_nodes_uid_from_parts( mpi_size ); @@ -1156,10 +1169,12 @@ class PeriodicPoints { } bool operator()( int j ) const { - if ( j >= N_ ) + if ( j >= N_ ) { return false; - if ( Topology::check( flags_( j ), flag_ ) ) + } + if ( Topology::check( flags_( j ), flag_ ) ) { return true; + } return false; } @@ -1171,8 +1186,9 @@ class PeriodicPoints { friend std::ostream& operator<<( std::ostream& os, const PeriodicPoints& periodic_points ) { os << "["; for ( idx_t j = 0; j < periodic_points.flags_.shape( 0 ); ++j ) { - if ( periodic_points( j ) ) + if ( periodic_points( j ) ) { os << " " << j + 1; + } } os << " ]"; return os; @@ -1196,8 +1212,9 @@ void increase_halo_periodic( BuildHaloHelper& helper, const PeriodicPoints& peri // 1) Find boundary nodes of this partition: - if ( !helper.bdry_nodes.size() ) + if ( !helper.bdry_nodes.size() ) { accumulate_partition_bdry_nodes( helper.mesh, helper.halosize, helper.bdry_nodes ); + } std::vector bdry_nodes = filter_nodes( helper.bdry_nodes, periodic_points ); const idx_t nb_bdry_nodes = static_cast( bdry_nodes.size() ); @@ -1264,8 +1281,9 @@ void BuildHalo::operator()( int nb_elems ) { int halo = 0; mesh_.metadata().get( "halo", halo ); - if ( halo == nb_elems ) + if ( halo == nb_elems ) { return; + } ATLAS_TRACE( "Increasing mesh halo" ); diff --git a/src/atlas/mesh/actions/BuildNode2CellConnectivity.cc b/src/atlas/mesh/actions/BuildNode2CellConnectivity.cc index 6049e468a..72019c3ec 100644 --- a/src/atlas/mesh/actions/BuildNode2CellConnectivity.cc +++ b/src/atlas/mesh/actions/BuildNode2CellConnectivity.cc @@ -81,8 +81,9 @@ void BuildNode2CellConnectivity::operator()() { node_to_cell.add( nodes.size(), to_cell_size.data() ); - for ( idx_t jnode = 0; jnode < nodes.size(); ++jnode ) + for ( idx_t jnode = 0; jnode < nodes.size(); ++jnode ) { to_cell_size[jnode] = 0; + } UniqueLonLat compute_uid( mesh_ ); std::vector cell_sort( nb_cells ); diff --git a/src/atlas/mesh/actions/BuildParallelFields.cc b/src/atlas/mesh/actions/BuildParallelFields.cc index 8a2eceff5..1f6a814b5 100644 --- a/src/atlas/mesh/actions/BuildParallelFields.cc +++ b/src/atlas/mesh/actions/BuildParallelFields.cc @@ -250,8 +250,9 @@ Field& build_nodes_remote_idx( mesh::Nodes& nodes ) { // This piece should be somewhere central ... could be NPROMA ? // ----------> std::vector proc( nparts ); - for ( idx_t jpart = 0; jpart < nparts; ++jpart ) + for ( idx_t jpart = 0; jpart < nparts; ++jpart ) { proc[jpart] = jpart; + } // <--------- auto ridx = array::make_indexview( nodes.remote_index() ); @@ -708,8 +709,9 @@ Field& build_edges_partition( Mesh& mesh ) { } } mpi::comm().allReduceInPlace( insane, eckit::mpi::max() ); - if ( insane && eckit::mpi::comm().rank() == 0 ) + if ( insane && eckit::mpi::comm().rank() == 0 ) { throw_Exception( "Sanity check failed", Here() ); + } //#ifdef DEBUGGING_PARFIELDS // if( OWNED_EDGE(jedge) ) @@ -785,10 +787,12 @@ Field& build_edges_remote_idx( Mesh& mesh ) { Topology::check( flags( ip2 ), Topology::PERIODIC ) && !Topology::check( flags( ip2 ), Topology::BC | Topology::WEST ) ) ) { needed = true; - if ( Topology::check( flags( ip1 ), Topology::EAST ) ) + if ( Topology::check( flags( ip1 ), Topology::EAST ) ) { transform( centroid, -1 ); - else + } + else { transform( centroid, +1 ); + } } uid_t uid = util::unique_lonlat( centroid ); diff --git a/src/atlas/mesh/actions/BuildStatistics.cc b/src/atlas/mesh/actions/BuildStatistics.cc index a34d0b042..cdd93d16d 100644 --- a/src/atlas/mesh/actions/BuildStatistics.cc +++ b/src/atlas/mesh/actions/BuildStatistics.cc @@ -117,9 +117,10 @@ void build_statistics( Mesh& mesh ) { array::ArrayView lonlat = array::make_view( nodes.lonlat() ); if ( mesh.edges().size() ) { - if ( !mesh.edges().has_field( "arc_length" ) ) + if ( !mesh.edges().has_field( "arc_length" ) ) { mesh.edges().add( Field( "arc_length", array::make_datatype(), array::make_shape( mesh.edges().size() ) ) ); + } array::ArrayView dist = array::make_view( mesh.edges().field( "arc_length" ) ); const mesh::HybridElements::Connectivity& edge_nodes = mesh.edges().node_connectivity(); @@ -147,8 +148,9 @@ void build_statistics( Mesh& mesh ) { // Cell statistics { - if ( mpi::comm().size() == 1 ) + if ( mpi::comm().size() == 1 ) { ofs.open( stats_path.localPath(), std::ofstream::app ); + } array::ArrayView rho = array::make_view( mesh.cells().add( Field( "stats_rho", array::make_datatype(), array::make_shape( mesh.cells().size() ) ) ) ); @@ -198,8 +200,9 @@ void build_statistics( Mesh& mesh ) { } } } - if ( mpi::comm().size() == 1 ) + if ( mpi::comm().size() == 1 ) { ofs.close(); + } } eckit::PathName dual_stats_path( "dual_stats.txt" ); @@ -228,8 +231,9 @@ void build_statistics( Mesh& mesh ) { } } } - if ( mpi::comm().size() == 1 ) + if ( mpi::comm().size() == 1 ) { ofs.close(); + } } // ------------------------------------------------------------------ diff --git a/src/atlas/mesh/actions/ExtendNodesGlobal.cc b/src/atlas/mesh/actions/ExtendNodesGlobal.cc index 80bdc5e1d..d4cbf2107 100644 --- a/src/atlas/mesh/actions/ExtendNodesGlobal.cc +++ b/src/atlas/mesh/actions/ExtendNodesGlobal.cc @@ -27,8 +27,9 @@ namespace actions { ExtendNodesGlobal::ExtendNodesGlobal( const std::string& gridname ) : gridname_( gridname ) {} void ExtendNodesGlobal::operator()( const Grid& grid, Mesh& mesh ) const { - if ( grid.domain().global() ) + if ( grid.domain().global() ) { return; // don't add virtual points to global domains + } Grid O16( "O16" ); diff --git a/src/atlas/mesh/actions/WriteLoadBalanceReport.cc b/src/atlas/mesh/actions/WriteLoadBalanceReport.cc index 7c3497a92..94d0fe5ca 100644 --- a/src/atlas/mesh/actions/WriteLoadBalanceReport.cc +++ b/src/atlas/mesh/actions/WriteLoadBalanceReport.cc @@ -63,10 +63,12 @@ void write_load_balance_report( const Mesh& mesh, std::ostream& ofs ) { idx_t nowned( 0 ); idx_t nghost( 0 ); for ( idx_t n = 0; n < nb_nodes; ++n ) { - if ( is_ghost( n ) ) + if ( is_ghost( n ) ) { ++nghost; - else + } + else { ++nowned; + } } /// @note this could be improved by packing the 3 integers in a vector, and @@ -99,10 +101,12 @@ void write_load_balance_report( const Mesh& mesh, std::ostream& ofs ) { idx_t nowned( 0 ); idx_t nghost( 0 ); for ( idx_t j = 0; j < nb_edges; ++j ) { - if ( is_ghost( edge_nodes( j, 0 ) ) ) + if ( is_ghost( edge_nodes( j, 0 ) ) ) { ++nghost; - else + } + else { ++nowned; + } } /// @note this could be improved by packing the 3 integers in a vector, and diff --git a/src/atlas/mesh/detail/AccumulateFacets.cc b/src/atlas/mesh/detail/AccumulateFacets.cc index 3d488047f..1b5bf9b2c 100644 --- a/src/atlas/mesh/detail/AccumulateFacets.cc +++ b/src/atlas/mesh/detail/AccumulateFacets.cc @@ -81,8 +81,9 @@ void accumulate_facets( const mesh::HybridElements& cells, const mesh::Nodes& no std::vector facet_nodes( nb_nodes_in_facet ); for ( idx_t e = 0; e < nb_elems; ++e ) { - if ( patch( e ) ) + if ( patch( e ) ) { continue; + } for ( idx_t f = 0; f < nb_facets_in_elem; ++f ) { bool found_face = false; @@ -187,8 +188,9 @@ void accumulate_facets_in_range( std::vector& range, const mesh::H const idx_t e_end = range[t].end(); for ( idx_t e = e_start; e < e_end; ++e ) { - if ( patch( e ) ) + if ( patch( e ) ) { continue; + } for ( idx_t f = 0; f < nb_facets_in_elem; ++f ) { bool found_face = false; diff --git a/src/atlas/mesh/detail/MeshImpl.cc b/src/atlas/mesh/detail/MeshImpl.cc index 0dc9ea6f0..de0ff08db 100644 --- a/src/atlas/mesh/detail/MeshImpl.cc +++ b/src/atlas/mesh/detail/MeshImpl.cc @@ -54,21 +54,28 @@ size_t MeshImpl::footprint() const { size_t size = sizeof( *this ); size += metadata_.footprint(); - if ( nodes_ ) + if ( nodes_ ) { size += nodes_->footprint(); - if ( cells_ ) + } + if ( cells_ ) { size += cells_->footprint(); - if ( facets_ ) + } + if ( facets_ ) { size += facets_->footprint(); - if ( ridges_ ) + } + if ( ridges_ ) { size += ridges_->footprint(); - if ( peaks_ ) + } + if ( peaks_ ) { size += peaks_->footprint(); - if ( partition_graph_ ) + } + if ( partition_graph_ ) { size += partition_graph_->footprint(); + } for ( const auto& polygon : polygons_ ) { - if ( polygon ) + if ( polygon ) { size += polygon->footprint(); + } } return size; @@ -79,12 +86,15 @@ void MeshImpl::createElements() { facets_.reset( new HybridElements() ); ridges_.reset( new HybridElements() ); peaks_.reset( new HybridElements() ); - if ( dimensionality_ == 2 ) + if ( dimensionality_ == 2 ) { edges_ = facets_; - else if ( dimensionality_ == 3 ) + } + else if ( dimensionality_ == 3 ) { edges_ = ridges_; - else + } + else { throw_Exception( "Invalid Mesh dimensionality", Here() ); + } ATLAS_ASSERT( edges_.owners() == 2 ); } @@ -99,8 +109,9 @@ void MeshImpl::setProjection( const Projection& projection ) { void MeshImpl::setGrid( const Grid& grid ) { grid_.reset( new Grid( grid ) ); - if ( not projection_ ) + if ( not projection_ ) { projection_ = grid_->projection(); + } } idx_t MeshImpl::nb_partitions() const { @@ -112,42 +123,57 @@ idx_t MeshImpl::partition() const { } void MeshImpl::cloneToDevice() const { - if ( nodes_ ) + if ( nodes_ ) { nodes_->cloneToDevice(); - if ( cells_ ) + } + if ( cells_ ) { cells_->cloneToDevice(); - if ( facets_ ) + } + if ( facets_ ) { facets_->cloneToDevice(); - if ( ridges_ ) + } + if ( ridges_ ) { ridges_->cloneToDevice(); - if ( peaks_ ) + } + if ( peaks_ ) { peaks_->cloneToDevice(); + } } void MeshImpl::cloneFromDevice() const { - if ( nodes_ ) + if ( nodes_ ) { nodes_->cloneFromDevice(); - if ( cells_ ) + } + if ( cells_ ) { cells_->cloneFromDevice(); - if ( facets_ ) + } + if ( facets_ ) { facets_->cloneFromDevice(); - if ( ridges_ ) + } + if ( ridges_ ) { ridges_->cloneFromDevice(); - if ( peaks_ ) + } + if ( peaks_ ) { peaks_->cloneFromDevice(); + } } void MeshImpl::syncHostDevice() const { - if ( nodes_ ) + if ( nodes_ ) { nodes_->syncHostDevice(); - if ( cells_ ) + } + if ( cells_ ) { cells_->syncHostDevice(); - if ( facets_ ) + } + if ( facets_ ) { facets_->syncHostDevice(); - if ( ridges_ ) + } + if ( ridges_ ) { ridges_->syncHostDevice(); - if ( peaks_ ) + } + if ( peaks_ ) { peaks_->syncHostDevice(); + } } const PartitionGraph& MeshImpl::partitionGraph() const { diff --git a/src/atlas/mesh/detail/PartitionGraph.cc b/src/atlas/mesh/detail/PartitionGraph.cc index aed76a67f..7037a5a8d 100644 --- a/src/atlas/mesh/detail/PartitionGraph.cc +++ b/src/atlas/mesh/detail/PartitionGraph.cc @@ -132,8 +132,9 @@ PartitionGraph::PartitionGraph( idx_t values[], idx_t rows, idx_t displs[], idx_ for ( idx_t neighbour : nearestNeighbours( jpart ) ) { bool found( false ); for ( idx_t nextneighbour : nearestNeighbours( neighbour ) ) { - if ( nextneighbour == jpart ) + if ( nextneighbour == jpart ) { found = true; + } } if ( not found ) { values_.insert( values_.begin() + displs_[neighbour] + counts_[neighbour], jpart ); diff --git a/src/atlas/meshgenerator/detail/RegularMeshGenerator.cc b/src/atlas/meshgenerator/detail/RegularMeshGenerator.cc index 2e947d5ea..3dc18de62 100644 --- a/src/atlas/meshgenerator/detail/RegularMeshGenerator.cc +++ b/src/atlas/meshgenerator/detail/RegularMeshGenerator.cc @@ -49,12 +49,14 @@ RegularMeshGenerator::RegularMeshGenerator( const eckit::Parametrisation& p ) { // options copied from Structured MeshGenerator size_t nb_parts; - if ( p.get( "nb_parts", nb_parts ) ) + if ( p.get( "nb_parts", nb_parts ) ) { options.set( "nb_parts", nb_parts ); + } size_t part; - if ( p.get( "part", part ) ) + if ( p.get( "part", part ) ) { options.set( "part", part ); + } std::string partitioner; if ( p.get( "partitioner", partitioner ) ) { @@ -68,12 +70,14 @@ RegularMeshGenerator::RegularMeshGenerator( const eckit::Parametrisation& p ) { // options specifically for this MeshGenerator bool periodic_x; - if ( p.get( "periodic_x", periodic_x ) ) + if ( p.get( "periodic_x", periodic_x ) ) { options.set( "periodic_x", periodic_x ); + } bool periodic_y; - if ( p.get( "periodic_y", periodic_y ) ) + if ( p.get( "periodic_y", periodic_y ) ) { options.set( "periodic_y", periodic_y ); + } bool biperiodic; if ( p.get( "biperiodic", biperiodic ) ) { @@ -91,10 +95,12 @@ void RegularMeshGenerator::configure_defaults() { // This options sets the default partitioner std::string partitioner; - if ( grid::Partitioner::exists( "trans" ) && mpi::comm().size() > 1 ) + if ( grid::Partitioner::exists( "trans" ) && mpi::comm().size() > 1 ) { partitioner = "trans"; - else + } + else { partitioner = "checkerboard"; + } options.set( "partitioner", partitioner ); // Options for for periodic grids @@ -106,8 +112,9 @@ void RegularMeshGenerator::generate( const Grid& grid, Mesh& mesh ) const { ATLAS_ASSERT( !mesh.generated() ); const RegularGrid rg = RegularGrid( grid ); - if ( !rg ) + if ( !rg ) { throw_Exception( "RegularMeshGenerator can only work with a Regular grid", Here() ); + } size_t nb_parts = options.get( "nb_parts" ); @@ -131,8 +138,9 @@ void RegularMeshGenerator::hash( eckit::Hash& h ) const { void RegularMeshGenerator::generate( const Grid& grid, const grid::Distribution& distribution, Mesh& mesh ) const { const auto rg = RegularGrid( grid ); - if ( !rg ) + if ( !rg ) { throw_Exception( "Grid could not be cast to a Regular", Here() ); + } ATLAS_ASSERT( !mesh.generated() ); diff --git a/src/atlas/meshgenerator/detail/StructuredMeshGenerator.cc b/src/atlas/meshgenerator/detail/StructuredMeshGenerator.cc index c4f95b0ce..bb859a932 100644 --- a/src/atlas/meshgenerator/detail/StructuredMeshGenerator.cc +++ b/src/atlas/meshgenerator/detail/StructuredMeshGenerator.cc @@ -68,52 +68,65 @@ StructuredMeshGenerator::StructuredMeshGenerator( const eckit::Parametrisation& configure_defaults(); bool include_pole; - if ( p.get( "include_pole", include_pole ) ) + if ( p.get( "include_pole", include_pole ) ) { options.set( "include_pole", include_pole ); + } bool patch_pole; - if ( p.get( "patch_pole", patch_pole ) ) + if ( p.get( "patch_pole", patch_pole ) ) { options.set( "patch_pole", patch_pole ); + } bool unique_pole; - if ( p.get( "unique_pole", unique_pole ) ) + if ( p.get( "unique_pole", unique_pole ) ) { options.set( "unique_pole", unique_pole ); + } bool force_include_pole; - if ( p.get( "force_include_north_pole", force_include_pole ) ) + if ( p.get( "force_include_north_pole", force_include_pole ) ) { options.set( "force_include_north_pole", force_include_pole ); - if ( p.get( "force_include_south_pole", force_include_pole ) ) + } + if ( p.get( "force_include_south_pole", force_include_pole ) ) { options.set( "force_include_south_pole", force_include_pole ); + } bool three_dimensional; - if ( p.get( "three_dimensional", three_dimensional ) || p.get( "3d", three_dimensional ) ) + if ( p.get( "three_dimensional", three_dimensional ) || p.get( "3d", three_dimensional ) ) { options.set( "3d", three_dimensional ); + } size_t nb_parts; - if ( p.get( "nb_parts", nb_parts ) ) + if ( p.get( "nb_parts", nb_parts ) ) { options.set( "nb_parts", nb_parts ); + } size_t part; - if ( p.get( "part", part ) ) + if ( p.get( "part", part ) ) { options.set( "part", part ); + } double angle; - if ( p.get( "angle", angle ) ) + if ( p.get( "angle", angle ) ) { options.set( "angle", angle ); + } bool triangulate; - if ( p.get( "triangulate", triangulate ) ) + if ( p.get( "triangulate", triangulate ) ) { options.set( "triangulate", triangulate ); + } bool ghost_at_end; - if ( p.get( "ghost_at_end", ghost_at_end ) ) + if ( p.get( "ghost_at_end", ghost_at_end ) ) { options.set( "ghost_at_end", ghost_at_end ); + } std::string partitioner; - if ( grid::Partitioner::exists( "trans" ) ) + if ( grid::Partitioner::exists( "trans" ) ) { partitioner = "trans"; - else + } + else { partitioner = "equal_regions"; + } options.set( "partitioner", partitioner ); if ( p.get( "partitioner", partitioner ) ) { @@ -170,18 +183,21 @@ void StructuredMeshGenerator::generate( const Grid& grid, Mesh& mesh ) const { ATLAS_ASSERT( !mesh.generated() ); const StructuredGrid rg = StructuredGrid( grid ); - if ( !rg ) + if ( !rg ) { throw_Exception( "Structured can only work with a Structured", Here() ); + } idx_t nb_parts = options.get( "nb_parts" ); std::string partitioner_type = "equal_regions"; options.get( "partitioner", partitioner_type ); - if ( partitioner_type == "trans" && rg.ny() % 2 == 1 ) + if ( partitioner_type == "trans" && rg.ny() % 2 == 1 ) { partitioner_type = "equal_regions"; // Odd number of latitudes - if ( nb_parts == 1 || mpi::comm().size() == 1 ) + } + if ( nb_parts == 1 || mpi::comm().size() == 1 ) { partitioner_type = "equal_regions"; // Only one part --> Trans is slower + } grid::Partitioner partitioner( partitioner_type, nb_parts ); grid::Distribution distribution( partitioner.partition( grid ) ); @@ -197,8 +213,9 @@ void StructuredMeshGenerator::generate( const Grid& grid, const grid::Distributi ATLAS_TRACE(); const StructuredGrid rg = StructuredGrid( grid ); - if ( !rg ) + if ( !rg ) { throw_Exception( "Grid could not be cast to a Structured", Here() ); + } ATLAS_ASSERT( !mesh.generated() ); @@ -289,10 +306,12 @@ Find min and max latitudes used by this part. /* We need to connect to next region */ - if ( lat_north - 1 >= 0 && rg.nx( lat_north - 1 ) > 0 ) + if ( lat_north - 1 >= 0 && rg.nx( lat_north - 1 ) > 0 ) { --lat_north; - if ( idx_t( lat_south + 1 ) <= rg.ny() - 1 && rg.nx( lat_south + 1 ) > 0 ) + } + if ( idx_t( lat_south + 1 ) <= rg.ny() - 1 && rg.nx( lat_south + 1 ) > 0 ) { ++lat_south; + } region.lat_begin.resize( rg.ny(), -1 ); region.lat_end.resize( rg.ny(), -1 ); region.nb_lat_elems.resize( rg.ny(), 0 ); @@ -334,13 +353,15 @@ We need to connect to next region beginN = 0; endN = rg.nx( latN ) - ( periodic_east_west ? 0 : 1 ); - if ( eckit::types::is_approximately_equal( yN, 90. ) && unique_pole ) + if ( eckit::types::is_approximately_equal( yN, 90. ) && unique_pole ) { endN = beginN; + } beginS = 0; endS = rg.nx( latS ) - ( periodic_east_west ? 0 : 1 ); - if ( eckit::types::is_approximately_equal( yS, -90. ) && unique_pole ) + if ( eckit::types::is_approximately_equal( yS, -90. ) && unique_pole ) { endS = beginS; + } ipN1 = beginN; ipS1 = beginS; @@ -356,8 +377,9 @@ We need to connect to next region #endif while ( true ) { - if ( ipN1 == endN && ipS1 == endS ) + if ( ipN1 == endN && ipS1 == endS ) { break; + } #if DEBUG_OUTPUT Log::info() << "-------\n"; @@ -367,26 +389,34 @@ We need to connect to next region // ATLAS_ASSERT(offset.at(latS)+ipS1 < parts.size()); int pN1, pS1, pN2, pS2; - if ( ipN1 != rg.nx( latN ) ) + if ( ipN1 != rg.nx( latN ) ) { pN1 = parts.at( offset.at( latN ) + ipN1 ); - else + } + else { pN1 = parts.at( offset.at( latN ) ); - if ( ipS1 != rg.nx( latS ) ) + } + if ( ipS1 != rg.nx( latS ) ) { pS1 = parts.at( offset.at( latS ) + ipS1 ); - else + } + else { pS1 = parts.at( offset.at( latS ) ); + } - if ( ipN2 == rg.nx( latN ) ) + if ( ipN2 == rg.nx( latN ) ) { pN2 = parts.at( offset.at( latN ) ); - else + } + else { pN2 = parts.at( offset.at( latN ) + ipN2 ); - if ( ipS2 == rg.nx( latS ) ) + } + if ( ipS2 == rg.nx( latS ) ) { pS2 = parts.at( offset.at( latS ) ); - else + } + else { pS2 = parts.at( offset.at( latS ) + ipS2 ); + } - // Log::info() << ipN1 << "("<( rg.nx( latN ) ); - if ( stagger && ( latN + 1 ) % 2 == 0 ) + } + if ( stagger && ( latN + 1 ) % 2 == 0 ) { xN2 += M_PI / static_cast( rg.nx( latN ) ); - if ( stagger && ( latS + 1 ) % 2 == 0 ) + } + if ( stagger && ( latS + 1 ) % 2 == 0 ) { xS1 += M_PI / static_cast( rg.nx( latS ) ); - if ( stagger && ( latS + 1 ) % 2 == 0 ) + } + if ( stagger && ( latS + 1 ) % 2 == 0 ) { xS2 += M_PI / static_cast( rg.nx( latS ) ); + } #if DEBUG_OUTPUT Log::info() << "-------\n"; @@ -469,12 +503,15 @@ We need to connect to next region } } else { - if ( ipN1 == ipN2 ) + if ( ipN1 == ipN2 ) { try_make_triangle_up = true; - else if ( ipS1 == ipS2 ) + } + else if ( ipS1 == ipS2 ) { try_make_triangle_down = true; - else + } + else { try_make_quad = true; + } // try_make_quad = true; } @@ -491,8 +528,9 @@ We need to connect to next region else if ( ( dN1S2 >= dS1N2 ) && ( ipN1 != ipN2 ) ) { try_make_triangle_down = true; } - else + else { throw_Exception( "Should not try to make a quadrilateral!", Here() ); + } } // ------------------------------------------------ // END RULES @@ -517,17 +555,20 @@ We need to connect to next region add_quad = false; std::array np{pN1, pN2, pS1, pS2}; std::array pcnts; - for ( int j = 0; j < 4; ++j ) + for ( int j = 0; j < 4; ++j ) { pcnts[j] = std::count( np.begin(), np.end(), np[j] ); + } if ( pcnts[0] > 2 ) { // 3 or more of pN1 pE = pN1; - if ( latS == rg.ny() - 1 ) + if ( latS == rg.ny() - 1 ) { pE = pS1; + } } else if ( pcnts[2] > 2 ) { // 3 or more of pS1 pE = pS1; - if ( latN == 0 ) + if ( latN == 0 ) { pE = pN1; + } } else { std::array::iterator p_max = std::max_element( pcnts.begin(), pcnts.end() ); @@ -536,8 +577,9 @@ We need to connect to next region } else { // 3 or 4 points don't belong to mypart pE = pN1; - if ( latS == rg.ny() - 1 ) + if ( latS == rg.ny() - 1 ) { pE = pS1; + } } } add_quad = ( pE == mypart ); @@ -546,10 +588,12 @@ We need to connect to next region ++jelem; ++nelems; - if ( region.lat_begin.at( latN ) == -1 ) + if ( region.lat_begin.at( latN ) == -1 ) { region.lat_begin.at( latN ) = ipN1; - if ( region.lat_begin.at( latS ) == -1 ) + } + if ( region.lat_begin.at( latS ) == -1 ) { region.lat_begin.at( latS ) = ipS1; + } region.lat_begin.at( latN ) = std::min( region.lat_begin.at( latN ), ipN1 ); region.lat_begin.at( latS ) = std::min( region.lat_begin.at( latS ), ipS1 ); region.lat_end.at( latN ) = std::max( region.lat_end.at( latN ), ipN2 ); @@ -576,8 +620,9 @@ We need to connect to next region elem( 3 ) = ipN2; pE = pN1; - if ( latS == rg.ny() - 1 ) + if ( latS == rg.ny() - 1 ) { pE = pS1; + } add_triag = ( mypart == pE ); if ( add_triag ) { @@ -585,10 +630,12 @@ We need to connect to next region ++jelem; ++nelems; - if ( region.lat_begin.at( latN ) == -1 ) + if ( region.lat_begin.at( latN ) == -1 ) { region.lat_begin.at( latN ) = ipN1; - if ( region.lat_begin.at( latS ) == -1 ) + } + if ( region.lat_begin.at( latS ) == -1 ) { region.lat_begin.at( latS ) = ipS1; + } region.lat_begin.at( latN ) = std::min( region.lat_begin.at( latN ), ipN1 ); region.lat_begin.at( latS ) = std::min( region.lat_begin.at( latS ), ipS1 ); region.lat_end.at( latN ) = std::max( region.lat_end.at( latN ), ipN2 ); @@ -623,10 +670,12 @@ We need to connect to next region else { pE = pN1; } - if ( ipN1 == rg.nx( latN ) ) + if ( ipN1 == rg.nx( latN ) ) { pE = pS1; - if ( latS == rg.ny() - 1 ) + } + if ( latS == rg.ny() - 1 ) { pE = pS1; + } add_triag = ( mypart == pE ); @@ -635,10 +684,12 @@ We need to connect to next region ++jelem; ++nelems; - if ( region.lat_begin.at( latN ) == -1 ) + if ( region.lat_begin.at( latN ) == -1 ) { region.lat_begin.at( latN ) = ipN1; - if ( region.lat_begin.at( latS ) == -1 ) + } + if ( region.lat_begin.at( latS ) == -1 ) { region.lat_begin.at( latS ) = ipS1; + } region.lat_begin.at( latN ) = std::min( region.lat_begin.at( latN ), ipN1 ); region.lat_begin.at( latS ) = std::min( region.lat_begin.at( latS ), ipS1 ); region.lat_end.at( latN ) = std::max( region.lat_end.at( latN ), ipN1 ); @@ -672,10 +723,12 @@ We need to connect to next region // int(rg.nx(latN)-1)); // region.lat_end.at(latS) = std::min(region.lat_end.at(latS), // int(rg.nx(latS)-1)); - if ( yN == 90 && unique_pole ) + if ( yN == 90 && unique_pole ) { region.lat_end.at( latN ) = rg.nx( latN ) - 1; - if ( yS == -90 && unique_pole ) + } + if ( yS == -90 && unique_pole ) { region.lat_end.at( latS ) = rg.nx( latS ) - 1; + } if ( region.nb_lat_elems.at( jlat ) > 0 ) { region.lat_end.at( latN ) = std::max( region.lat_end.at( latN ), region.lat_begin.at( latN ) ); @@ -765,8 +818,9 @@ void StructuredMeshGenerator::generate_mesh( const StructuredGrid& rg, const std int nnewnodes = ( !has_point_at_north_pole && include_north_pole ? 1 : 0 ) + ( !has_point_at_south_pole && include_south_pole ? 1 : 0 ); - if ( three_dimensional && nparts != 1 ) + if ( three_dimensional && nparts != 1 ) { throw_Exception( "Cannot generate three_dimensional mesh in parallel", Here() ); + } int nnodes = region.nnodes; int ntriags = region.ntriags; int nquads = region.nquads; @@ -789,8 +843,9 @@ void StructuredMeshGenerator::generate_mesh( const StructuredGrid& rg, const std size_t node_numbering_size = nnodes; if ( remove_periodic_ghost_points ) { for ( idx_t jlat = 0; jlat < rg.ny(); ++jlat ) { - if ( region.lat_end[jlat] >= rg.nx( jlat ) ) + if ( region.lat_end[jlat] >= rg.nx( jlat ) ) { --nnodes; + } } } ATLAS_ASSERT( nnodes >= nnewnodes ); @@ -911,8 +966,9 @@ void StructuredMeshGenerator::generate_mesh( const StructuredGrid& rg, const std } else // No renumbering { - for ( idx_t jnode = 0; jnode < nnodes; ++jnode ) + for ( idx_t jnode = 0; jnode < nnodes; ++jnode ) { node_numbering.at( jnode ) = jnode; + } } idx_t jnode = 0; @@ -931,8 +987,9 @@ void StructuredMeshGenerator::generate_mesh( const StructuredGrid& rg, const std double x = rg.x( jlon, jlat ); // std::cout << "jlat = " << jlat << "; jlon = " << jlon << "; x = " << // x << std::endl; - if ( stagger && ( jlat + 1 ) % 2 == 0 ) + if ( stagger && ( jlat + 1 ) % 2 == 0 ) { x += 180. / static_cast( rg.nx( jlat ) ); + } xy( inode, XX ) = x; xy( inode, YY ) = y; @@ -968,8 +1025,9 @@ void StructuredMeshGenerator::generate_mesh( const StructuredGrid& rg, const std idx_t inode = node_numbering.at( jnode ); // int inode_left = node_numbering.at(jnode-1); double x = rg.x( rg.nx( jlat ), jlat ); - if ( stagger && ( jlat + 1 ) % 2 == 0 ) + if ( stagger && ( jlat + 1 ) % 2 == 0 ) { x += 180. / static_cast( rg.nx( jlat ) ); + } xy( inode, XX ) = x; xy( inode, YY ) = y; @@ -1096,10 +1154,12 @@ void StructuredMeshGenerator::generate_mesh( const StructuredGrid& rg, const std quad_nodes[3] = node_numbering.at( offset_loc.at( ilatN ) + elem( 3 ) - region.lat_begin.at( jlatN ) ); if ( three_dimensional && periodic_east_west ) { - if ( elem( 2 ) == rg.nx( jlatS ) ) + if ( elem( 2 ) == rg.nx( jlatS ) ) { quad_nodes[2] = node_numbering.at( offset_loc.at( ilatS ) ); - if ( elem( 3 ) == rg.nx( jlatN ) ) + } + if ( elem( 3 ) == rg.nx( jlatN ) ) { quad_nodes[3] = node_numbering.at( offset_loc.at( ilatN ) ); + } } jcell = quad_begin + jquad++; @@ -1118,10 +1178,12 @@ void StructuredMeshGenerator::generate_mesh( const StructuredGrid& rg, const std triag_nodes[2] = node_numbering.at( offset_loc.at( ilatS ) + elem( 2 ) - region.lat_begin.at( jlatS ) ); if ( three_dimensional && periodic_east_west ) { - if ( elem( 0 ) == rg.nx( jlatN ) ) + if ( elem( 0 ) == rg.nx( jlatN ) ) { triag_nodes[0] = node_numbering.at( offset_loc.at( ilatN ) ); - if ( elem( 2 ) == rg.nx( jlatS ) ) + } + if ( elem( 2 ) == rg.nx( jlatS ) ) { triag_nodes[2] = node_numbering.at( offset_loc.at( ilatS ) ); + } } } else // This is a triangle pointing down @@ -1133,10 +1195,12 @@ void StructuredMeshGenerator::generate_mesh( const StructuredGrid& rg, const std triag_nodes[2] = node_numbering.at( offset_loc.at( ilatN ) + elem( 3 ) - region.lat_begin.at( jlatN ) ); if ( three_dimensional && periodic_east_west ) { - if ( elem( 1 ) == rg.nx( jlatS ) ) + if ( elem( 1 ) == rg.nx( jlatS ) ) { triag_nodes[1] = node_numbering.at( offset_loc.at( ilatS ) ); - if ( elem( 3 ) == rg.nx( jlatN ) ) + } + if ( elem( 3 ) == rg.nx( jlatN ) ) { triag_nodes[2] = node_numbering.at( offset_loc.at( ilatN ) ); + } } } jcell = triag_begin + jtriag++; @@ -1154,8 +1218,9 @@ void StructuredMeshGenerator::generate_mesh( const StructuredGrid& rg, const std for ( idx_t ip2 = 0; ip2 < nlon; ++ip2 ) { jcell = triag_begin + jtriag++; idx_t ip3 = ip2 + 1; - if ( three_dimensional && ip3 == rg.nx( 0 ) ) + if ( three_dimensional && ip3 == rg.nx( 0 ) ) { ip3 = 0; + } triag_nodes[0] = node_numbering.at( jnorth + ip1 ); triag_nodes[1] = node_numbering.at( offset_loc.at( ilat ) + ip2 ); triag_nodes[2] = node_numbering.at( offset_loc.at( ilat ) + ip3 ); @@ -1196,8 +1261,9 @@ void StructuredMeshGenerator::generate_mesh( const StructuredGrid& rg, const std cells_part( jcell ) = mypart; Topology::set( cells_flags( jcell ), Topology::PATCH ); - if ( jbackward == jforward + 2 ) + if ( jbackward == jforward + 2 ) { break; + } if ( forward ) { ++jforward; @@ -1221,8 +1287,9 @@ void StructuredMeshGenerator::generate_mesh( const StructuredGrid& rg, const std triag_nodes[0] = node_numbering.at( jsouth + ip1 ); triag_nodes[1] = node_numbering.at( offset_loc.at( ilat ) + ip2 ); triag_nodes[2] = node_numbering.at( offset_loc.at( ilat ) + ip3 ); - if ( three_dimensional && ip2 == rg.nx( jlat ) ) + if ( three_dimensional && ip2 == rg.nx( jlat ) ) { triag_nodes[1] = node_numbering.at( offset_loc.at( ilat ) + 0 ); + } node_connectivity.set( jcell, triag_nodes ); cells_glb_idx( jcell ) = jcell + 1; cells_part( jcell ) = mypart; @@ -1260,8 +1327,9 @@ void StructuredMeshGenerator::generate_mesh( const StructuredGrid& rg, const std cells_part( jcell ) = mypart; Topology::set( cells_flags( jcell ), Topology::PATCH ); - if ( jbackward == jforward + 2 ) + if ( jbackward == jforward + 2 ) { break; + } if ( forward ) { ++jforward; diff --git a/src/atlas/numerics/Nabla.cc b/src/atlas/numerics/Nabla.cc index 9622c2aae..4423d351f 100644 --- a/src/atlas/numerics/Nabla.cc +++ b/src/atlas/numerics/Nabla.cc @@ -127,8 +127,9 @@ const NablaImpl* NablaFactory::build( const Method& method, const eckit::Paramet if ( j == m->end() ) { Log::error() << "No NablaFactory for [" << method.name() << "]" << '\n'; Log::error() << "NablaFactories are:" << '\n'; - for ( j = m->begin(); j != m->end(); ++j ) + for ( j = m->begin(); j != m->end(); ++j ) { Log::error() << " " << ( *j ).first << '\n'; + } throw_Exception( std::string( "No NablaFactory called " ) + method.name() ); } diff --git a/src/atlas/numerics/fvm/Method.cc b/src/atlas/numerics/fvm/Method.cc index 2e8dfb156..91f15dd0e 100644 --- a/src/atlas/numerics/fvm/Method.cc +++ b/src/atlas/numerics/fvm/Method.cc @@ -75,8 +75,9 @@ void Method::setup() { ATLAS_TRACE( "fvm::Method::setup " ); util::Config config; config.set( "halo", halo_.size() ); - if ( levels_ ) + if ( levels_ ) { config.set( "levels", levels_ ); + } node_columns_ = functionspace::NodeColumns( mesh(), config ); edge_columns_ = functionspace::EdgeColumns( mesh(), config ); @@ -105,12 +106,14 @@ void Method::setup() { for ( idx_t jedge = 0; jedge < node_edge_connectivity.cols( jnode ); ++jedge ) { idx_t iedge = node_edge_connectivity( jnode, jedge ); idx_t ip1 = edge_node_connectivity( iedge, 0 ); - if ( jnode == ip1 ) + if ( jnode == ip1 ) { node2edge_sign( jnode, jedge ) = 1.; + } else { node2edge_sign( jnode, jedge ) = -1.; - if ( is_pole_edge( iedge ) ) + if ( is_pole_edge( iedge ) ) { node2edge_sign( jnode, jedge ) = 1.; + } } } } diff --git a/src/atlas/numerics/fvm/Nabla.cc b/src/atlas/numerics/fvm/Nabla.cc index e77f0d8b2..98c883882 100644 --- a/src/atlas/numerics/fvm/Nabla.cc +++ b/src/atlas/numerics/fvm/Nabla.cc @@ -39,8 +39,9 @@ static NablaBuilder __fvm_nabla( "fvm" ); Nabla::Nabla( const numerics::Method& method, const eckit::Parametrisation& p ) : atlas::numerics::NablaImpl( method, p ) { fvm_ = dynamic_cast( &method ); - if ( !fvm_ ) + if ( !fvm_ ) { throw_Exception( "atlas::numerics::fvm::Nabla needs a atlas::numerics::fvm::Method", Here() ); + } Log::debug() << "Nabla constructed for method " << fvm_->name() << " with " << fvm_->node_columns().nb_nodes_global() << " nodes total" << std::endl; fvm_->attach(); @@ -61,13 +62,15 @@ void Nabla::setup() { std::vector tmp( nedges ); idx_t c( 0 ); for ( idx_t jedge = 0; jedge < nedges; ++jedge ) { - if ( is_pole_edge( jedge ) ) + if ( is_pole_edge( jedge ) ) { tmp[c++] = jedge; + } } pole_edges_.clear(); pole_edges_.reserve( c ); - for ( idx_t jedge = 0; jedge < c; ++jedge ) + for ( idx_t jedge = 0; jedge < c; ++jedge ) { pole_edges_.push_back( tmp[jedge] ); + } } void Nabla::gradient( const Field& field, Field& grad_field ) const { @@ -90,8 +93,9 @@ void Nabla::gradient_of_scalar( const Field& scalar_field, Field& grad_field ) c const idx_t nnodes = fvm_->node_columns().nb_nodes(); const idx_t nedges = fvm_->edge_columns().nb_edges(); const idx_t nlev = scalar_field.levels() ? scalar_field.levels() : 1; - if ( ( grad_field.levels() ? grad_field.levels() : 1 ) != nlev ) + if ( ( grad_field.levels() ? grad_field.levels() : 1 ) != nlev ) { throw_AssertionFailed( "gradient field should have same number of levels", Here() ); + } const auto scalar = scalar_field.levels() ? array::make_view( scalar_field ).slice( Range::all(), Range::all() ) @@ -164,8 +168,9 @@ void Nabla::gradient_of_vector( const Field& vector_field, Field& grad_field ) c const idx_t nnodes = fvm_->node_columns().nb_nodes(); const idx_t nedges = fvm_->edge_columns().nb_edges(); const idx_t nlev = vector_field.levels(); - if ( vector_field.levels() != nlev ) + if ( vector_field.levels() != nlev ) { throw_AssertionFailed( "gradient field should have same number of levels", Here() ); + } const auto vector = vector_field.levels() @@ -270,8 +275,9 @@ void Nabla::divergence( const Field& vector_field, Field& div_field ) const { const idx_t nnodes = fvm_->node_columns().nb_nodes(); const idx_t nedges = fvm_->edge_columns().nb_edges(); const idx_t nlev = vector_field.levels(); - if ( div_field.levels() != nlev ) + if ( div_field.levels() != nlev ) { throw_AssertionFailed( "divergence field should have same number of levels", Here() ); + } const auto vector = vector_field.levels() @@ -354,8 +360,9 @@ void Nabla::curl( const Field& vector_field, Field& curl_field ) const { const idx_t nnodes = fvm_->node_columns().nb_nodes(); const idx_t nedges = fvm_->edge_columns().nb_edges(); const idx_t nlev = vector_field.levels(); - if ( curl_field.levels() != nlev ) + if ( curl_field.levels() != nlev ) { throw_AssertionFailed( "curl field should have same number of levels", Here() ); + } const auto vector = vector_field.levels() @@ -430,8 +437,9 @@ void Nabla::laplacian( const Field& scalar, Field& lapl ) const { Field grad( fvm_->node_columns().createField( option::name( "grad" ) | option::levels( scalar.levels() ) | option::variables( 2 ) ) ); gradient( scalar, grad ); - if ( fvm_->node_columns().halo().size() < 2 ) + if ( fvm_->node_columns().halo().size() < 2 ) { fvm_->node_columns().haloExchange( grad ); + } divergence( grad, lapl ); } diff --git a/src/atlas/output/Gmsh.cc b/src/atlas/output/Gmsh.cc index 5e56bab83..f33fe4c4d 100644 --- a/src/atlas/output/Gmsh.cc +++ b/src/atlas/output/Gmsh.cc @@ -46,10 +46,12 @@ std::string GmshFileStream::parallelPathName( const PathName& path, int part ) { GmshFileStream::GmshFileStream( const PathName& file_path, const char* mode, int part ) { PathName par_path( file_path ); std::ios_base::openmode omode = std::ios_base::out; - if ( std::string( mode ) == "w" ) + if ( std::string( mode ) == "w" ) { omode = std::ios_base::out; - else if ( std::string( mode ) == "a" ) + } + else if ( std::string( mode ) == "a" ) { omode = std::ios_base::app; + } if ( part < 0 || mpi::comm().size() == 1 ) { std::ofstream::open( file_path.localPath(), omode ); @@ -120,12 +122,15 @@ detail::GmshIO writer( const Gmsh::Configuration& c ) { std::ios_base::openmode openmode( const Gmsh::Configuration& c ) { std::ios_base::openmode omode( std::ios_base::out ); - if ( std::string( c.openmode ) == "w" ) + if ( std::string( c.openmode ) == "w" ) { omode = std::ios_base::out; - else if ( std::string( c.openmode ) == "a" ) + } + else if ( std::string( c.openmode ) == "a" ) { omode = std::ios_base::app; - if ( c.binary ) + } + if ( c.binary ) { omode |= std::ios::binary; + } return omode; } diff --git a/src/atlas/output/Output.cc b/src/atlas/output/Output.cc index c9d5e7f6a..2b3ee0e27 100644 --- a/src/atlas/output/Output.cc +++ b/src/atlas/output/Output.cc @@ -113,8 +113,9 @@ const OutputImpl* OutputFactory::build( const std::string& name, Stream& stream if ( j == m->end() ) { Log::error() << "No OutputFactory for [" << name << "]" << std::endl; Log::error() << "OutputFactories are:" << std::endl; - for ( j = m->begin(); j != m->end(); ++j ) + for ( j = m->begin(); j != m->end(); ++j ) { Log::error() << " " << ( *j ).first << std::endl; + } throw_Exception( std::string( "No OutputFactory called " ) + name ); } @@ -132,8 +133,9 @@ const OutputImpl* OutputFactory::build( const std::string& name, Stream& stream, if ( j == m->end() ) { Log::error() << "No OutputFactory for [" << name << "]" << std::endl; Log::error() << "OutputFactories are:" << std::endl; - for ( j = m->begin(); j != m->end(); ++j ) + for ( j = m->begin(); j != m->end(); ++j ) { Log::error() << " " << ( *j ).first << std::endl; + } throw_Exception( std::string( "No OutputFactory called " ) + name ); } diff --git a/src/atlas/output/detail/GmshIO.cc b/src/atlas/output/detail/GmshIO.cc index 45bdedf32..70dc8ec4b 100644 --- a/src/atlas/output/detail/GmshIO.cc +++ b/src/atlas/output/detail/GmshIO.cc @@ -141,10 +141,12 @@ void write_level( std::ostream& out, const array::ArrayView gidx, std::vector data_vec( 3, 0. ); for ( idx_t n = 0; n < ndata; ++n ) { out << gidx( n ); - for ( idx_t v = 0; v < nvars; ++v ) + for ( idx_t v = 0; v < nvars; ++v ) { data_vec[v] = data( n, v ); - for ( int v = 0; v < 3; ++v ) + } + for ( int v = 0; v < 3; ++v ) { out << " " << data_vec[v]; + } out << "\n"; } } @@ -158,8 +160,9 @@ void write_level( std::ostream& out, const array::ArrayView gidx, } } out << gidx( n ); - for ( int v = 0; v < 9; ++v ) + for ( int v = 0; v < 9; ++v ) { out << " " << data_vec[v]; + } out << "\n"; } } @@ -171,8 +174,9 @@ void write_level( std::ostream& out, const array::ArrayView gidx, } } out << gidx( n ); - for ( int v = 0; v < 9; ++v ) + for ( int v = 0; v < 9; ++v ) { out << " " << data_vec[v]; + } out << "\n"; } } @@ -191,8 +195,9 @@ std::vector get_levels( int nlev, const Metadata& gmsh_options ) { gmsh_options.get( "levels", gmsh_levels ); if ( gmsh_levels.empty() || nlev == 1 ) { lev.resize( nlev ); - for ( int ilev = 0; ilev < nlev; ++ilev ) + for ( int ilev = 0; ilev < nlev; ++ilev ) { lev[ilev] = ilev; + } } else { lev = gmsh_levels; @@ -220,14 +225,18 @@ int field_step( const Field& field ) { } int field_vars( int nvars ) { - if ( nvars == 1 ) + if ( nvars == 1 ) { return nvars; - else if ( nvars <= 3 ) + } + else if ( nvars <= 3 ) { return 3; - else if ( nvars <= 9 ) + } + else if ( nvars <= 9 ) { return 9; - else + } + else { return nvars; + } } } // namespace @@ -518,12 +527,15 @@ Mesh GmshIO::read( const PathName& file_path ) const { namespace { mesh::ElementType* make_element_type( int type ) { - if ( type == QUAD ) + if ( type == QUAD ) { return new mesh::temporary::Quadrilateral(); - if ( type == TRIAG ) + } + if ( type == TRIAG ) { return new mesh::temporary::Triangle(); - if ( type == LINE ) + } + if ( type == LINE ) { return new mesh::temporary::Line(); + } throw_Exception( "Element type not supported", Here() ); } } // namespace @@ -531,20 +543,23 @@ mesh::ElementType* make_element_type( int type ) { void GmshIO::read( const PathName& file_path, Mesh& mesh ) const { std::ifstream file; file.open( file_path.localPath(), std::ios::in | std::ios::binary ); - if ( !file.is_open() ) + if ( !file.is_open() ) { throw_CantOpenFile( file_path ); + } std::string line; - while ( line != "$MeshFormat" ) + while ( line != "$MeshFormat" ) { std::getline( file, line ); + } double version; int binary; int size_of_real; file >> version >> binary >> size_of_real; - while ( line != "$Nodes" ) + while ( line != "$Nodes" ) { std::getline( file, line ); + } // Create nodes idx_t nb_nodes; @@ -567,8 +582,9 @@ void GmshIO::read( const PathName& file_path, Mesh& mesh ) const { double xmax = -std::numeric_limits::max(); double zmax = -std::numeric_limits::max(); gidx_t max_glb_idx = 0; - while ( binary && file.peek() == '\n' ) + while ( binary && file.peek() == '\n' ) { file.get(); + } for ( idx_t n = 0; n < nb_nodes; ++n ) { if ( binary ) { file.read( reinterpret_cast( &g ), sizeof( int ) ); @@ -596,19 +612,22 @@ void GmshIO::read( const PathName& file_path, Mesh& mesh ) const { coords( n, YY ) *= rad2deg; } } - for ( int i = 0; i < 3; ++i ) + for ( int i = 0; i < 3; ++i ) { std::getline( file, line ); + } int nb_elements = 0; - while ( line != "$Elements" ) + while ( line != "$Elements" ) { std::getline( file, line ); + } file >> nb_elements; if ( binary ) { - while ( file.peek() == '\n' ) + while ( file.peek() == '\n' ) { file.get(); + } int accounted_elems = 0; while ( accounted_elems < nb_elements ) { int header[3]; @@ -641,8 +660,9 @@ void GmshIO::read( const PathName& file_path, Mesh& mesh ) const { part = 0; egidx( e ) = data[0]; epart( e ) = part; - for ( size_t n = 0; n < nnodes_per_elem; ++n ) + for ( size_t n = 0; n < nnodes_per_elem; ++n ) { conn.set( e, n, glb_to_loc[data[1 + ntags + n]] ); + } } } } @@ -689,12 +709,14 @@ void GmshIO::read( const PathName& file_path, Mesh& mesh ) const { int ntags, tags[100]; for ( int e = 0; e < nb_elements; ++e ) { file >> g >> etype >> ntags; - for ( int t = 0; t < ntags; ++t ) + for ( int t = 0; t < ntags; ++t ) { file >> tags[t]; + } int part = 0; - if ( ntags > 3 ) + if ( ntags > 3 ) { part = std::max( part, *std::max_element( tags + 3, tags + ntags - 1 ) ); // one positive, others negative + } idx_t enodes[4]; @@ -764,15 +786,18 @@ void GmshIO::write( const Mesh& mesh, const PathName& file_path ) const { bool binary = !options.get( "ascii" ); openmode mode = std::ios::out; - if ( binary ) + if ( binary ) { mode = std::ios::out | std::ios::binary; + } GmshFile file( file_path, mode, part ); // Header - if ( binary ) + if ( binary ) { write_header_binary( file ); - else + } + else { write_header_ascii( file ); + } // Nodes const idx_t nb_nodes = nodes.size(); @@ -782,8 +807,9 @@ void GmshIO::write( const Mesh& mesh, const PathName& file_path ) const { for ( idx_t n = 0; n < nb_nodes; ++n ) { gidx_t g = glb_idx( n ); - for ( idx_t d = 0; d < surfdim; ++d ) + for ( idx_t d = 0; d < surfdim; ++d ) { xyz[d] = coords( n, d ); + } if ( binary ) { file.write( reinterpret_cast( &g ), sizeof( gidx_t ) ); @@ -793,18 +819,21 @@ void GmshIO::write( const Mesh& mesh, const PathName& file_path ) const { file << g << " " << xyz[XX] << " " << xyz[YY] << " " << xyz[ZZ] << "\n"; } } - if ( binary ) + if ( binary ) { file << "\n"; + } file << "$EndNodes\n"; // Elements file << "$Elements\n"; { std::vector grouped_elements; - if ( options.get( "elements" ) ) + if ( options.get( "elements" ) ) { grouped_elements.push_back( &mesh.cells() ); - if ( options.get( "edges" ) ) + } + if ( options.get( "edges" ) ) { grouped_elements.push_back( &mesh.edges() ); + } idx_t nb_elements( 0 ); for ( const mesh::HybridElements* hybrid : grouped_elements ) { @@ -815,10 +844,12 @@ void GmshIO::write( const Mesh& mesh, const PathName& file_path ) const { return mesh::Nodes::Topology::check( hybrid_flags( e ), mesh::Nodes::Topology::PATCH ); }; auto exclude = [&]( idx_t e ) { - if ( !include_ghost && hybrid_halo( e ) ) + if ( !include_ghost && hybrid_halo( e ) ) { return true; - if ( !include_patch && hybrid_patch( e ) ) + } + if ( !include_patch && hybrid_patch( e ) ) { return true; + } return false; }; for ( idx_t e = 0; e < hybrid->size(); ++e ) { @@ -835,14 +866,18 @@ void GmshIO::write( const Mesh& mesh, const PathName& file_path ) const { const mesh::Elements& elements = hybrid->elements( etype ); const mesh::ElementType& element_type = elements.element_type(); int gmsh_elem_type; - if ( element_type.name() == "Line" ) + if ( element_type.name() == "Line" ) { gmsh_elem_type = 1; - else if ( element_type.name() == "Triangle" ) + } + else if ( element_type.name() == "Triangle" ) { gmsh_elem_type = 2; - else if ( element_type.name() == "Quadrilateral" ) + } + else if ( element_type.name() == "Quadrilateral" ) { gmsh_elem_type = 3; - else + } + else { ATLAS_NOTIMPLEMENTED; + } const mesh::BlockConnectivity& node_connectivity = elements.node_connectivity(); @@ -854,8 +889,9 @@ void GmshIO::write( const Mesh& mesh, const PathName& file_path ) const { idx_t nb_elems = elements.size(); if ( !include_ghost ) { for ( idx_t elem = 0; elem < elements.size(); ++elem ) { - if ( elems_halo( elem ) ) + if ( elems_halo( elem ) ) { --nb_elems; + } } } @@ -873,8 +909,9 @@ void GmshIO::write( const Mesh& mesh, const PathName& file_path ) const { if ( include_ghost || !elems_halo( elem ) ) { data[0] = elems_glb_idx( elem ); data[4] = elems_partition( elem ); - for ( idx_t n = 0; n < node_connectivity.cols(); ++n ) + for ( idx_t n = 0; n < node_connectivity.cols(); ++n ) { data[5 + n] = glb_idx( node_connectivity( elem, n ) ); + } file.write( reinterpret_cast( &data ), datasize ); } } @@ -896,8 +933,9 @@ void GmshIO::write( const Mesh& mesh, const PathName& file_path ) const { } } } - if ( binary ) + if ( binary ) { file << "\n"; + } file << "$EndElements\n"; file << std::flush; @@ -995,8 +1033,9 @@ void GmshIO::write_delegate( const FieldSet& fieldset, const functionspace::Node const PathName& file_path, openmode mode ) const { bool is_new_file = ( mode != std::ios_base::app || !file_path.exists() ); bool binary( !options.get( "ascii" ) ); - if ( binary ) + if ( binary ) { mode |= std::ios_base::binary; + } bool gather = options.has( "gather" ) ? options.get( "gather" ) : false; GmshFile file( file_path, mode, gather ? -1 : int( atlas::mpi::comm().rank() ) ); @@ -1035,16 +1074,18 @@ void GmshIO::write_delegate( const FieldSet& fieldset, const functionspace::Stru bool is_new_file = ( mode != std::ios_base::app || !file_path.exists() ); bool binary( !options.get( "ascii" ) ); - if ( binary ) + if ( binary ) { mode |= std::ios_base::binary; + } bool gather = options.has( "gather" ) ? options.get( "gather" ) : false; GmshFile file( file_path, mode, gather ? -1 : int( atlas::mpi::comm().rank() ) ); // Header - if ( is_new_file ) + if ( is_new_file ) { write_header_ascii( file ); + } // field::Fields for ( idx_t field_idx = 0; field_idx < fieldset.size(); ++field_idx ) { @@ -1074,24 +1115,30 @@ void GmshIO::write_delegate( const FieldSet& fieldset, const functionspace::Stru // ---------------------------------------------------------------------------- void GmshIO::write( const FieldSet& fieldset, const FunctionSpace& funcspace, const eckit::PathName& file_path, openmode mode ) const { - if ( functionspace::NodeColumns( funcspace ) ) + if ( functionspace::NodeColumns( funcspace ) ) { write_delegate( fieldset, functionspace::NodeColumns( funcspace ), file_path, mode ); - else if ( functionspace::StructuredColumns( funcspace ) ) + } + else if ( functionspace::StructuredColumns( funcspace ) ) { write_delegate( fieldset, functionspace::StructuredColumns( funcspace ), file_path, mode ); - else + } + else { ATLAS_NOTIMPLEMENTED; + } } // ---------------------------------------------------------------------------- // ---------------------------------------------------------------------------- void GmshIO::write( const Field& field, const FunctionSpace& funcspace, const eckit::PathName& file_path, openmode mode ) const { - if ( functionspace::NodeColumns( funcspace ) ) + if ( functionspace::NodeColumns( funcspace ) ) { write_delegate( field, functionspace::NodeColumns( funcspace ), file_path, mode ); - else if ( functionspace::StructuredColumns( funcspace ) ) + } + else if ( functionspace::StructuredColumns( funcspace ) ) { write_delegate( field, functionspace::StructuredColumns( funcspace ), file_path, mode ); - else + } + else { ATLAS_NOTIMPLEMENTED; + } } // ---------------------------------------------------------------------------- diff --git a/src/atlas/output/detail/PointCloudIO.cc b/src/atlas/output/detail/PointCloudIO.cc index 9653a819e..8ae11289c 100644 --- a/src/atlas/output/detail/PointCloudIO.cc +++ b/src/atlas/output/detail/PointCloudIO.cc @@ -43,8 +43,9 @@ std::string sanitize_field_name( const std::string& s ) { std::replace_if( r.begin(), r.end(), ::isspace, '_' ); r.erase( r.find_last_not_of( '_' ) + 1 ); r.erase( 0, r.find_first_not_of( '_' ) ); - if ( !r.length() ) + if ( !r.length() ) { r = "_"; + } return r; } @@ -71,8 +72,9 @@ Mesh PointCloudIO::read( const eckit::PathName& path, std::vector& // open file and read all of header & data std::ifstream f( path.asString().c_str() ); - if ( !f.is_open() ) + if ( !f.is_open() ) { throw_CantOpenFile( path.asString() ); + } // header, part 1: // determine number of rows/columns @@ -87,10 +89,12 @@ Mesh PointCloudIO::read( const eckit::PathName& path, std::vector& << ")"; throw_Exception( errmsg.str(), Here() ); } - if ( nb_pts == 0 ) + if ( nb_pts == 0 ) { throw_AssertionFailed( msg + " invalid number of points (failed: nb_pts>0)" ); - if ( nb_columns < 2 ) + } + if ( nb_columns < 2 ) { throw_AssertionFailed( msg + " invalid number of columns (failed: nb_columns>=2)" ); + } mesh.nodes().resize( static_cast( nb_pts ) ); @@ -141,8 +145,9 @@ Mesh PointCloudIO::read( const eckit::PathName& path, std::vector& lonlat( i, LAT ) = pxy.y(); glb_idx( i ) = i + 1; - for ( j = 0; iss && j < nb_fld; ++j ) + for ( j = 0; iss && j < nb_fld; ++j ) { iss >> fields[j]( i ); + } if ( j < nb_fld ) { oss << " Invalid number of fields in data section, on line " << ( i + 1 ) << ", read " << j << " fields, expected " << nb_fld << "."; @@ -176,8 +181,9 @@ void PointCloudIO::write( const eckit::PathName& path, const Mesh& mesh ) { const mesh::Nodes& nodes = mesh.nodes(); const array::ArrayView lonlat = array::make_view( nodes.lonlat() ); - if ( !lonlat.size() ) + if ( !lonlat.size() ) { throw_Exception( msg + "invalid number of points (failed: nb_pts>0)" ); + } // get the fields (sanitized) names and values // (bypasses fields ("lonlat"|"lonlat") as shape(1)!=1) @@ -195,23 +201,26 @@ void PointCloudIO::write( const eckit::PathName& path, const Mesh& mesh ) { } std::ofstream f( path.asString().c_str() ); - if ( !f.is_open() ) + if ( !f.is_open() ) { throw_CantOpenFile( path.asString() ); + } const size_t Npts = lonlat.shape( 0 ); const size_t Nfld = vfvalues.size(); // header f << "PointCloudIO\t" << Npts << '\t' << ( 2 + Nfld ) << "\tlon\tlat"; - for ( size_t j = 0; j < Nfld; ++j ) + for ( size_t j = 0; j < Nfld; ++j ) { f << '\t' << vfnames[j]; + } f << '\n'; // data for ( size_t i = 0; i < Npts; ++i ) { f << lonlat( i, 0 ) << '\t' << lonlat( i, 1 ); - for ( size_t j = 0; j < Nfld; ++j ) + for ( size_t j = 0; j < Nfld; ++j ) { f << '\t' << vfvalues[j]( i ); + } f << '\n'; } @@ -231,8 +240,9 @@ void PointCloudIO::write( const eckit::PathName& path, const FieldSet& fieldset, ATLAS_ASSERT( fieldset.size() ); array::ArrayView lonlat = array::make_view( function_space.nodes().xy() ); - if ( !lonlat.size() ) + if ( !lonlat.size() ) { throw_Exception( msg + "invalid number of points (failed: nb_pts>0)" ); + } // get the fields (sanitized) names and values // (bypasses fields ("lonlat"|"lonlat") as shape(1)!=1) @@ -249,14 +259,16 @@ void PointCloudIO::write( const eckit::PathName& path, const FieldSet& fieldset, } std::ofstream f( path.asString().c_str() ); - if ( !f.is_open() ) + if ( !f.is_open() ) { throw_CantOpenFile( path.asString() ); + } const size_t Npts = lonlat.shape( 0 ), Nfld = vfvalues.size(); // header f << "PointCloudIO\t" << Npts << '\t' << ( 2 + Nfld ) << "\tlon\tlat"; - for ( size_t j = 0; j < Nfld; ++j ) + for ( size_t j = 0; j < Nfld; ++j ) { f << '\t' << vfnames[j]; + } f << '\n'; f.precision( std::numeric_limits::digits10 ); @@ -264,8 +276,9 @@ void PointCloudIO::write( const eckit::PathName& path, const FieldSet& fieldset, // data for ( size_t i = 0; i < Npts; ++i ) { f << lonlat( i, 0 ) << '\t' << lonlat( i, 1 ); - for ( size_t j = 0; j < Nfld; ++j ) + for ( size_t j = 0; j < Nfld; ++j ) { f << '\t' << vfvalues[j]( i ); + } f << '\n'; } @@ -276,15 +289,17 @@ void PointCloudIO::write( const eckit::PathName& path, const std::vector const std::string msg( "PointCloudIO::write: " ); const size_t Npts( lon.size() ), Nfld( vfvalues.size() ); - if ( Npts != lat.size() ) + if ( Npts != lat.size() ) { throw_Exception( msg + "number of points inconsistent (failed: #lon == #lat)" ); - if ( Nfld != vfnames.size() ) + } + if ( Nfld != vfnames.size() ) { throw_Exception( msg + "number of fields inconsistent (failed: #vfvalues == #vfnames)" ); - for ( size_t j = 0; j < Nfld; ++j ) - if ( Npts != vfvalues[j]->size() ) + } + for ( size_t j = 0; j < Nfld; ++j ) { + if ( Npts != vfvalues[j]->size() ) { throw_Exception( msg + "number of points inconsistent (failed: " "#lon == #lat == #*vfvalues[])" ); + } + } std::ofstream f( path.asString().c_str() ); - if ( !f.is_open() ) + if ( !f.is_open() ) { throw_CantOpenFile( path.asString() ); + } // header f << "PointCloudIO\t" << Npts << '\t' << ( 2 + Nfld ) << "\tlon\tlat"; - for ( size_t j = 0; j < Nfld; ++j ) + for ( size_t j = 0; j < Nfld; ++j ) { f << '\t' << sanitize_field_name( vfnames[j] ); + } f << '\n'; // data for ( size_t i = 0; i < Npts; ++i ) { f << lon[i] << '\t' << lat[i]; - for ( size_t j = 0; j < Nfld; ++j ) + for ( size_t j = 0; j < Nfld; ++j ) { f << '\t' << vfvalues[j]->operator[]( i ); + } f << '\n'; } @@ -334,28 +356,34 @@ void PointCloudIO::write( const eckit::PathName& path, const int& nb_pts, const const std::string msg( "PointCloudIO::write: " ); const size_t Npts( nb_pts > 0 ? nb_pts : 0 ), Nfld( nb_fld > 0 && afvalues && afnames ? nb_fld : 0 ); - if ( !Npts ) + if ( !Npts ) { throw_Exception( msg + "invalid number of points (nb_nodes)" ); - if ( !lon ) + } + if ( !lon ) { throw_Exception( msg + "invalid array describing longitude (lon)" ); - if ( !lat ) + } + if ( !lat ) { throw_Exception( msg + "invalid array describing latitude (lat)" ); + } std::ofstream f( path.asString().c_str() ); - if ( !f.is_open() ) + if ( !f.is_open() ) { throw_CantOpenFile( path.asString() ); + } // header f << "PointCloudIO\t" << Npts << '\t' << ( 2 + Nfld ) << "\tlon\tlat"; - for ( size_t j = 0; j < Nfld; ++j ) + for ( size_t j = 0; j < Nfld; ++j ) { f << '\t' << sanitize_field_name( afnames[j] ); + } f << '\n'; // data for ( size_t i = 0; i < Npts; ++i ) { f << lon[i] << '\t' << lat[i]; - for ( size_t j = 0; j < Nfld; ++j ) + for ( size_t j = 0; j < Nfld; ++j ) { f << '\t' << afvalues[j][i]; + } f << '\n'; } diff --git a/src/atlas/parallel/GatherScatter.cc b/src/atlas/parallel/GatherScatter.cc index d3d46a76a..a3016ac49 100644 --- a/src/atlas/parallel/GatherScatter.cc +++ b/src/atlas/parallel/GatherScatter.cc @@ -34,10 +34,12 @@ struct IsGhostPoint { } bool operator()( idx_t idx ) { - if ( part_[idx] != mypart_ ) + if ( part_[idx] != mypart_ ) { return true; - if ( ridx_[idx] != base_ + idx ) + } + if ( ridx_[idx] != base_ + idx ) { return true; + } return false; } int mypart_; @@ -155,8 +157,9 @@ void GatherScatter::setup( const int part[], const idx_t remote_idx[], const int idx_t jproc = node.p; glbmap_[glbdispls_[jproc] + idx[jproc]] = n++; - if ( jproc == myproc ) + if ( jproc == myproc ) { locmap_[idx[jproc]] = node.i; + } ++idx[jproc]; } diff --git a/src/atlas/parallel/HaloExchange.cc b/src/atlas/parallel/HaloExchange.cc index 9766b6ef0..f22f0ea89 100644 --- a/src/atlas/parallel/HaloExchange.cc +++ b/src/atlas/parallel/HaloExchange.cc @@ -33,10 +33,12 @@ struct IsGhostPoint { } bool operator()( idx_t idx ) { - if ( part_[idx] != mypart_ ) + if ( part_[idx] != mypart_ ) { return true; - if ( ridx_[idx] != base_ + idx ) + } + if ( ridx_[idx] != base_ + idx ) { return true; + } return false; } int mypart_; @@ -76,8 +78,9 @@ void HaloExchange::setup( const int part[], const idx_t remote_idx[], const int IsGhostPoint is_ghost( part, remote_idx, base, parsize_ ); for ( int jj = 0; jj < parsize_; ++jj ) { - if ( is_ghost( jj ) ) + if ( is_ghost( jj ) ) { ++recvcounts_[part[jj]]; + } } recvcnt_ = std::accumulate( recvcounts_.begin(), recvcounts_.end(), 0 ); @@ -130,8 +133,9 @@ void HaloExchange::setup( const int part[], const idx_t remote_idx[], const int here */ sendmap_.resize( sendcnt_ ); - for ( int jj = 0; jj < sendcnt_; ++jj ) + for ( int jj = 0; jj < sendcnt_; ++jj ) { sendmap_[jj] = recv_requests[jj]; + } is_setup_ = true; backdoor.parsize = parsize_; @@ -147,12 +151,14 @@ void execute_halo_exchange( HaloExchange* This, Value field[], int var_strides[] // slowest moving array::ArrayShape shape{This->backdoor.parsize}; - for ( int j = 0; j < var_rank; ++j ) + for ( int j = 0; j < var_rank; ++j ) { shape.push_back( var_extents[j] ); + } array::ArrayStrides strides{var_extents[0] * var_strides[0]}; - for ( int j = 0; j < var_rank; ++j ) + for ( int j = 0; j < var_rank; ++j ) { strides.push_back( var_strides[j] ); + } std::unique_ptr arr( array::Array::wrap( field, array::ArraySpec{shape, strides} ) ); diff --git a/src/atlas/parallel/omp/omp.cc b/src/atlas/parallel/omp/omp.cc index f00db559d..3b3f83368 100644 --- a/src/atlas/parallel/omp/omp.cc +++ b/src/atlas/parallel/omp/omp.cc @@ -42,77 +42,87 @@ extern "C" { void atlas_omp_set_num_threads( int num_threads ) { #if ATLAS_HAVE_OMP - if ( omp_set_num_threads ) + if ( omp_set_num_threads ) { omp_set_num_threads( num_threads ); + } #endif } int atlas_omp_get_num_threads( void ) { #if ATLAS_HAVE_OMP - if ( omp_get_num_threads ) + if ( omp_get_num_threads ) { return omp_get_num_threads(); + } #endif return 1; } int atlas_omp_get_max_threads( void ) { #if ATLAS_HAVE_OMP - if ( omp_get_max_threads ) + if ( omp_get_max_threads ) { return omp_get_max_threads(); + } #endif return 1; } int atlas_omp_get_thread_num( void ) { #if ATLAS_HAVE_OMP - if ( omp_get_thread_num ) + if ( omp_get_thread_num ) { return omp_get_thread_num(); + } #endif return 0; } int atlas_omp_get_num_procs( void ) { #if ATLAS_HAVE_OMP - if ( omp_get_num_procs ) + if ( omp_get_num_procs ) { return omp_get_num_procs(); + } #endif return 1; } int atlas_omp_in_parallel( void ) { #if ATLAS_HAVE_OMP - if ( omp_in_parallel ) + if ( omp_in_parallel ) { return omp_in_parallel(); + } #endif return 0; } void atlas_omp_set_dynamic( int dynamic_threads ) { #if ATLAS_HAVE_OMP - if ( omp_set_dynamic ) + if ( omp_set_dynamic ) { omp_set_dynamic( dynamic_threads ); + } #endif } int atlas_omp_get_dynamic( void ) { #if ATLAS_HAVE_OMP - if ( omp_get_dynamic ) + if ( omp_get_dynamic ) { return omp_get_dynamic(); + } #endif return 0; } void atlas_omp_set_nested( int nested ) { #if ATLAS_HAVE_OMP - if ( omp_set_nested ) + if ( omp_set_nested ) { omp_set_nested( nested ); + } #endif } int atlas_omp_get_nested( void ) { #if ATLAS_HAVE_OMP - if ( omp_get_nested ) + if ( omp_get_nested ) { return omp_get_nested(); + } #endif return 0; } diff --git a/src/atlas/projection/detail/LambertProjection.cc b/src/atlas/projection/detail/LambertProjection.cc index 744819f87..9f892eda5 100644 --- a/src/atlas/projection/detail/LambertProjection.cc +++ b/src/atlas/projection/detail/LambertProjection.cc @@ -44,16 +44,20 @@ namespace detail { // constructors LambertProjection::LambertProjection( const eckit::Parametrisation& params ) { // check presence of radius - if ( !params.get( "radius", radius_ ) ) + if ( !params.get( "radius", radius_ ) ) { radius_ = util::Earth::radius(); + } // check presence of lat1 and lat2 - if ( !params.get( "latitude1", lat1_ ) ) + if ( !params.get( "latitude1", lat1_ ) ) { throw_Exception( "latitude1 missing in Params", Here() ); - if ( !params.get( "latitude2", lat2_ ) ) + } + if ( !params.get( "latitude2", lat2_ ) ) { lat2_ = lat1_; + } // check presence of lon0 - if ( !params.get( "longitude0", lon0_ ) ) + if ( !params.get( "longitude0", lon0_ ) ) { throw_Exception( "longitude0 missing in Params", Here() ); + } setup(); } @@ -109,8 +113,9 @@ LambertProjection::Spec LambertProjection::spec() const { proj_spec.set( "latitude1", lat1_ ); proj_spec.set( "latitude2", lat2_ ); proj_spec.set( "longitude0", lon0_ ); - if ( std::not_equal_to()( radius_, util::Earth::radius() ) ) + if ( std::not_equal_to()( radius_, util::Earth::radius() ) ) { proj_spec.set( "radius", radius_ ); + } return proj_spec; } diff --git a/src/atlas/projection/detail/MercatorProjection.cc b/src/atlas/projection/detail/MercatorProjection.cc index 37a821d92..ba95815a8 100644 --- a/src/atlas/projection/detail/MercatorProjection.cc +++ b/src/atlas/projection/detail/MercatorProjection.cc @@ -47,11 +47,13 @@ MercatorProjectionT::MercatorProjectionT( const eckit::Parametrisation ProjectionImpl(), rotation_( params ) { // check presence of radius - if ( !params.get( "radius", radius_ ) ) + if ( !params.get( "radius", radius_ ) ) { radius_ = util::Earth::radius(); + } // check presence of lon0 - if ( !params.get( "longitude0", lon0_ ) ) + if ( !params.get( "longitude0", lon0_ ) ) { lon0_ = 0.0; + } inv_radius_ = 1. / radius_; } diff --git a/src/atlas/projection/detail/SchmidtProjection.cc b/src/atlas/projection/detail/SchmidtProjection.cc index 8b9240063..ed5d782cd 100644 --- a/src/atlas/projection/detail/SchmidtProjection.cc +++ b/src/atlas/projection/detail/SchmidtProjection.cc @@ -37,8 +37,9 @@ template SchmidtProjectionT::SchmidtProjectionT( const eckit::Parametrisation& params ) : ProjectionImpl(), rotation_( params ) { - if ( !params.get( "stretching_factor", c_ ) ) + if ( !params.get( "stretching_factor", c_ ) ) { throw_Exception( "stretching_factor missing in Params", Here() ); + } } // constructor diff --git a/src/atlas/runtime/AtlasTool.cc b/src/atlas/runtime/AtlasTool.cc index a63bbebed..6958acc7b 100644 --- a/src/atlas/runtime/AtlasTool.cc +++ b/src/atlas/runtime/AtlasTool.cc @@ -51,8 +51,9 @@ void debug_addTarget( eckit::LogTarget* target ) { lib.debugChannel().addTarget( new eckit::PrefixTarget( debug_prefix( libname ), target ) ); } } - if ( eckit::Log::debug() ) + if ( eckit::Log::debug() ) { eckit::Log::debug().addTarget( target ); + } } void debug_setTarget( eckit::LogTarget* target ) { @@ -62,8 +63,9 @@ void debug_setTarget( eckit::LogTarget* target ) { lib.debugChannel().setTarget( new eckit::PrefixTarget( debug_prefix( libname ), target ) ); } } - if ( eckit::Log::debug() ) + if ( eckit::Log::debug() ) { eckit::Log::debug().setTarget( target ); + } } void debug_reset() { @@ -73,8 +75,9 @@ void debug_reset() { lib.debugChannel().reset(); } } - if ( eckit::Log::debug() ) + if ( eckit::Log::debug() ) { eckit::Log::debug().reset(); + } } bool getEnv( const std::string& env, bool default_value ) { @@ -134,9 +137,10 @@ static std::string workdir; << "[" << mpi::comm().rank() << "] Aborting " << eckit::Main::instance().displayName() << "\n" << "-----------------------------------------\n" << exception.what() << "\n"; - if ( exception.location() ) + if ( exception.location() ) { out << "-----------------------------------------\n" << "LOCATION: " << exception.location() << "\n"; + } out << "-----------------------------------------\n" << "BACKTRACE\n" << "-----------------------------------------\n" @@ -155,9 +159,10 @@ static std::string workdir; << exception.what() << "\n" << "-----------------------------------------\n"; - if ( exception.location() ) + if ( exception.location() ) { out << "LOCATION: " << exception.location() << "\n" << "-----------------------------------------\n"; + } out << "BACKTRACE\n" << "-----------------------------------------\n" @@ -216,8 +221,9 @@ void atlas::AtlasTool::add_option( eckit::option::Option* option ) { void atlas::AtlasTool::help( std::ostream& out ) { out << "NAME\n" << indent() << name(); std::string brief = briefDescription(); - if ( brief.size() ) + if ( brief.size() ) { out << " - " << brief << '\n'; + } std::string usg = usage(); if ( usg.size() ) { @@ -240,8 +246,9 @@ void atlas::AtlasTool::help( std::ostream& out ) { bool atlas::AtlasTool::handle_help() { for ( int i = 1; i < argc(); ++i ) { if ( argv( i ) == "--help" || argv( i ) == "-h" ) { - if ( taskID() == 0 ) + if ( taskID() == 0 ) { help( std::cout ); + } return true; } } @@ -272,12 +279,14 @@ atlas::AtlasTool::AtlasTool( int argc, char** argv ) : eckit::Tool( argc, argv ) int atlas::AtlasTool::start() { try { - if ( handle_help() ) + if ( handle_help() ) { return success(); + } if ( argc() - 1 < minimumPositionalArguments() ) { - if ( taskID() == 0 ) + if ( taskID() == 0 ) { std::cout << "Usage: " << usage() << std::endl; + } return failed(); } Options opts = options_; @@ -322,8 +331,9 @@ void atlas::AtlasTool::setupLogging() { int d = digits( mpi::comm().size() ); std::string rankstr = std::to_string( taskID() ); - for ( int i = rankstr.size(); i < d; ++i ) + for ( int i = rankstr.size(); i < d; ++i ) { rankstr = "0" + rankstr; + } logfile_name = workdir + "/" + displayName() + ".log.p" + rankstr; @@ -331,32 +341,41 @@ void atlas::AtlasTool::setupLogging() { eckit::LogTarget* logfile = new eckit::FileTarget( logfile_name ); if ( int( mpi::comm().rank() ) == log_rank ) { - if ( Log::info() ) + if ( Log::info() ) { Log::info().addTarget( logfile ); - if ( Log::warning() ) + } + if ( Log::warning() ) { Log::warning().addTarget( logfile ); - if ( Log::error() ) + } + if ( Log::error() ) { Log::error().addTarget( logfile ); + } debug_addTarget( logfile ); } else { - if ( Log::info() ) + if ( Log::info() ) { Log::info().setTarget( logfile ); - if ( Log::warning() ) + } + if ( Log::warning() ) { Log::warning().setTarget( logfile ); - if ( Log::error() ) + } + if ( Log::error() ) { Log::error().setTarget( logfile ); + } debug_setTarget( logfile ); } } else { if ( int( mpi::comm().rank() ) != log_rank ) { - if ( Log::info() ) + if ( Log::info() ) { Log::info().reset(); - if ( Log::warning() ) + } + if ( Log::warning() ) { Log::warning().reset(); - if ( Log::error() ) + } + if ( Log::error() ) { Log::error().reset(); + } debug_reset(); } } diff --git a/src/atlas/runtime/trace/CallStack.cc b/src/atlas/runtime/trace/CallStack.cc index e06b6c965..6341c6dec 100644 --- a/src/atlas/runtime/trace/CallStack.cc +++ b/src/atlas/runtime/trace/CallStack.cc @@ -27,8 +27,9 @@ void CallStack::pop_front() { } size_t CallStack::hash() const { - if ( hash_ ) + if ( hash_ ) { return hash_; + } for ( auto h : stack_ ) { hash_ ^= ( h << 1 ); } diff --git a/src/atlas/runtime/trace/Logging.cc b/src/atlas/runtime/trace/Logging.cc index 3d4d3baf4..bfc9a6109 100644 --- a/src/atlas/runtime/trace/Logging.cc +++ b/src/atlas/runtime/trace/Logging.cc @@ -51,8 +51,9 @@ class LoggingState { void set( std::ostream& channel ) { channel_ = &channel; } void set( bool state ) { - if ( state == false ) + if ( state == false ) { channel_ = &empty_channel(); + } } }; @@ -79,13 +80,15 @@ bool Logging::enabled() { } void Logging::start( const std::string& title ) { - if ( enabled() ) + if ( enabled() ) { channel() << title << " ..." << std::endl; + } } void Logging::stop( const std::string& title, double seconds ) { - if ( enabled() ) + if ( enabled() ) { channel() << title << " ... done : " << seconds << "s" << std::endl; + } } //----------------------------------------------------------------------------------------------------------- @@ -96,8 +99,9 @@ std::ostream& NoLogging::channel() { //----------------------------------------------------------------------------------------------------------- void LoggingResult::stop( const std::string& title, double seconds ) { - if ( enabled() ) + if ( enabled() ) { channel() << title << " : " << seconds << "s" << std::endl; + } } //----------------------------------------------------------------------------------------------------------- diff --git a/src/atlas/runtime/trace/Timings.cc b/src/atlas/runtime/trace/Timings.cc index 8d8588bcc..9d7778a0b 100644 --- a/src/atlas/runtime/trace/Timings.cc +++ b/src/atlas/runtime/trace/Timings.cc @@ -116,8 +116,9 @@ void TimingsRegistry::report( std::ostream& out, const eckit::Configuration& con auto box_horizontal = []( int n ) { std::string s; s.reserve( 2 * n ); - for ( int i = 0; i < n; ++i ) + for ( int i = 0; i < n; ++i ) { s += "\u2500"; + } return s; }; std::string box_corner_tl( "\u250c" ); @@ -166,8 +167,9 @@ void TimingsRegistry::report( std::ostream& out, const eckit::Configuration& con std::set excluded_timers( excluded_timers_vector.begin(), excluded_timers_vector.end() ); auto excluded = [&]( size_t i ) -> bool { - if ( depth and nest_[i] > depth ) + if ( depth and nest_[i] > depth ) { return true; + } return excluded_timers.count( i ); }; @@ -188,8 +190,9 @@ void TimingsRegistry::report( std::ostream& out, const eckit::Configuration& con for ( auto& label : include_back ) { auto timers = labels_[label]; for ( size_t j : timers ) { - if ( nest_[j] == excluded_nest_stored[j] ) + if ( nest_[j] == excluded_nest_stored[j] ) { excluded_timers.erase( j ); + } } } @@ -281,19 +284,25 @@ void TimingsRegistry::report( std::ostream& out, const eckit::Configuration& con std::stringstream out; for ( long i = 0; i < nest - 1; ++i ) { - if ( active[i] ) + if ( active[i] ) { out << box_vertical; - else + } + else { out << " "; - for ( long j = 1; j < indent; ++j ) + } + for ( long j = 1; j < indent; ++j ) { out << " "; + } } - if ( active[nest - 1] ) + if ( active[nest - 1] ) { out << box_T_right; - else + } + else { out << box_corner_bl; - for ( long j = 1; j < indent; ++j ) + } + for ( long j = 1; j < indent; ++j ) { out << box_horizontal( 1 ); + } prefix_[k] = out.str(); } diff --git a/src/atlas/trans/LegendreCacheCreator.cc b/src/atlas/trans/LegendreCacheCreator.cc index 8b5a2cda7..4f13a3b33 100644 --- a/src/atlas/trans/LegendreCacheCreator.cc +++ b/src/atlas/trans/LegendreCacheCreator.cc @@ -58,8 +58,9 @@ LegendreCacheCreatorFactory& factory( const std::string& name ) { if ( j == m->end() ) { Log::error() << "No LegendreCacheCreatorFactory for [" << name << "]" << std::endl; Log::error() << "TransFactories are:" << std::endl; - for ( j = m->begin(); j != m->end(); ++j ) + for ( j = m->begin(); j != m->end(); ++j ) { Log::error() << " " << ( *j ).first << std::endl; + } throw_Exception( std::string( "No LegendreCacheCreatorFactory called " ) + name ); } return *j->second; diff --git a/src/atlas/trans/VorDivToUV.cc b/src/atlas/trans/VorDivToUV.cc index de85938a0..009cd2422 100644 --- a/src/atlas/trans/VorDivToUV.cc +++ b/src/atlas/trans/VorDivToUV.cc @@ -63,8 +63,9 @@ VorDivToUVFactory& factory( const std::string& name ) { if ( j == m->end() ) { Log::error() << "No VorDivToUVFactory for [" << name << "]" << std::endl; Log::error() << "VorDivToUVFactory are:" << std::endl; - for ( j = m->begin(); j != m->end(); ++j ) + for ( j = m->begin(); j != m->end(); ++j ) { Log::error() << " " << ( *j ).first << std::endl; + } throw_Exception( std::string( "No VorDivToUVFactory called " ) + name ); } return *j->second; diff --git a/src/atlas/trans/local/LegendreCacheCreatorLocal.cc b/src/atlas/trans/local/LegendreCacheCreatorLocal.cc index 57ee617d8..5cec303e2 100644 --- a/src/atlas/trans/local/LegendreCacheCreatorLocal.cc +++ b/src/atlas/trans/local/LegendreCacheCreatorLocal.cc @@ -120,10 +120,12 @@ LegendreCacheCreatorLocal::LegendreCacheCreatorLocal( const Grid& grid, int trun config_( config ) {} bool LegendreCacheCreatorLocal::supported() const { - if ( not StructuredGrid( grid_ ) ) + if ( not StructuredGrid( grid_ ) ) { return false; - if ( grid_.projection() ) + } + if ( grid_.projection() ) { return false; + } return true; } diff --git a/src/atlas/trans/local/LegendrePolynomials.cc b/src/atlas/trans/local/LegendrePolynomials.cc index 3b3d9fb76..8e2a986c7 100644 --- a/src/atlas/trans/local/LegendrePolynomials.cc +++ b/src/atlas/trans/local/LegendrePolynomials.cc @@ -124,8 +124,9 @@ void compute_legendre_polynomials_lat( const int trc, // truncation (in) double sq = std::sqrt( ( 2. * jn + 1. ) / ( 2. * jn ) ); legpol[idxmn( jn, jn )] = legpol[idxmn( jn - 1, jn - 1 )] * zdlsita * sq; - if ( std::abs( legpol[idxmn( jn, jn )] ) < zdls ) + if ( std::abs( legpol[idxmn( jn, jn )] ) < zdls ) { legpol[idxmn( jn, jn )] = 0.0; + } } // --------------------------------------------- diff --git a/src/atlas/util/Config.cc b/src/atlas/util/Config.cc index 6d3b9e8af..d0d6b74e9 100644 --- a/src/atlas/util/Config.cc +++ b/src/atlas/util/Config.cc @@ -76,8 +76,9 @@ Config& Config::set( const eckit::LocalConfiguration& other ) { Config& Config::set( const std::string& name, const std::vector& values ) { std::vector metadatavalues( values.size() ); - for ( size_t i = 0; i < metadatavalues.size(); ++i ) + for ( size_t i = 0; i < metadatavalues.size(); ++i ) { metadatavalues[i] = values[i]; + } set( name, metadatavalues ); return *this; } @@ -179,8 +180,9 @@ void atlas__Config__set_array_double( Config* This, const char* name, double val int atlas__Config__get_config( Config* This, const char* name, Config* value ) { ATLAS_ASSERT( This != nullptr, "Cannot access uninitialised atlas_Config" ); - if ( !This->get( std::string( name ), *value ) ) + if ( !This->get( std::string( name ), *value ) ) { return false; + } return true; } @@ -188,8 +190,9 @@ int atlas__Config__get_config_list( Config* This, const char* name, Config**& va ATLAS_ASSERT( This != nullptr, "Cannot access uninitialised atlas_Config" ); value = nullptr; std::vector vector; - if ( !This->get( std::string( name ), vector ) ) + if ( !This->get( std::string( name ), vector ) ) { return false; + } size = vector.size(); value = new Config*[size]; allocated = true; @@ -202,30 +205,34 @@ int atlas__Config__get_config_list( Config* This, const char* name, Config**& va int atlas__Config__get_int( Config* This, const char* name, int& value ) { ATLAS_ASSERT( This != nullptr, "Cannot access uninitialised atlas_Config" ); long long_value = value; - if ( !This->get( std::string( name ), long_value ) ) + if ( !This->get( std::string( name ), long_value ) ) { return false; + } ATLAS_ASSERT( int( long_value ) == long_value ); value = long_value; return true; } int atlas__Config__get_long( Config* This, const char* name, long& value ) { ATLAS_ASSERT( This != nullptr, "Cannot access uninitialised atlas_Config" ); - if ( !This->get( std::string( name ), value ) ) + if ( !This->get( std::string( name ), value ) ) { return false; + } return true; } int atlas__Config__get_float( Config* This, const char* name, float& value ) { ATLAS_ASSERT( This != nullptr, "Cannot access uninitialised atlas_Config" ); double double_value; - if ( !This->get( std::string( name ), double_value ) ) + if ( !This->get( std::string( name ), double_value ) ) { return false; + } value = static_cast( double_value ); return true; } int atlas__Config__get_double( Config* This, const char* name, double& value ) { ATLAS_ASSERT( This != nullptr, "Cannot access uninitialised atlas_Config" ); - if ( !This->get( std::string( name ), value ) ) + if ( !This->get( std::string( name ), value ) ) { return false; + } return true; } int atlas__Config__get_string( Config* This, const char* name, char*& value, int& size, int& allocated ) { @@ -244,8 +251,9 @@ int atlas__Config__get_string( Config* This, const char* name, char*& value, int int atlas__Config__get_array_int( Config* This, const char* name, int*& value, int& size, int& allocated ) { ATLAS_ASSERT( This != nullptr, "Cannot access uninitialised atlas_Config" ); std::vector v; - if ( !This->get( std::string( name ), v ) ) + if ( !This->get( std::string( name ), v ) ) { return false; + } size = v.size(); value = new int[size]; for ( size_t j = 0; j < v.size(); ++j ) { @@ -258,20 +266,23 @@ int atlas__Config__get_array_int( Config* This, const char* name, int*& value, i int atlas__Config__get_array_long( Config* This, const char* name, long*& value, int& size, int& allocated ) { ATLAS_ASSERT( This != nullptr, "Cannot access uninitialised atlas_Config" ); std::vector v; - if ( !This->get( std::string( name ), v ) ) + if ( !This->get( std::string( name ), v ) ) { return false; + } size = v.size(); value = new long[size]; - for ( size_t j = 0; j < v.size(); ++j ) + for ( size_t j = 0; j < v.size(); ++j ) { value[j] = v[j]; + } allocated = true; return true; } int atlas__Config__get_array_float( Config* This, const char* name, float*& value, int& size, int& allocated ) { ATLAS_ASSERT( This != nullptr, "Cannot access uninitialised atlas_Config" ); std::vector v; - if ( !This->get( std::string( name ), v ) ) + if ( !This->get( std::string( name ), v ) ) { return false; + } size = v.size(); value = new float[size]; for ( size_t j = 0; j < v.size(); ++j ) { @@ -283,12 +294,14 @@ int atlas__Config__get_array_float( Config* This, const char* name, float*& valu int atlas__Config__get_array_double( Config* This, const char* name, double*& value, int& size, int& allocated ) { ATLAS_ASSERT( This != nullptr, "Cannot access uninitialised atlas_Config" ); std::vector v; - if ( !This->get( std::string( name ), v ) ) + if ( !This->get( std::string( name ), v ) ) { return false; + } size = v.size(); value = new double[size]; - for ( size_t j = 0; j < v.size(); ++j ) + for ( size_t j = 0; j < v.size(); ++j ) { value[j] = v[j]; + } allocated = true; return true; } diff --git a/src/atlas/util/Metadata.cc b/src/atlas/util/Metadata.cc index 36a628fec..055935555 100644 --- a/src/atlas/util/Metadata.cc +++ b/src/atlas/util/Metadata.cc @@ -210,8 +210,9 @@ void atlas__Metadata__get_array_int( Metadata* This, const char* name, int*& val std::vector v = This->get>( std::string( name ) ); size = v.size(); value = new int[size]; - for ( size_t j = 0; j < v.size(); ++j ) + for ( size_t j = 0; j < v.size(); ++j ) { value[j] = v[j]; + } allocated = true; } void atlas__Metadata__get_array_long( Metadata* This, const char* name, long*& value, int& size, int& allocated ) { @@ -219,8 +220,9 @@ void atlas__Metadata__get_array_long( Metadata* This, const char* name, long*& v std::vector v = This->get>( std::string( name ) ); size = v.size(); value = new long[size]; - for ( size_t j = 0; j < v.size(); ++j ) + for ( size_t j = 0; j < v.size(); ++j ) { value[j] = v[j]; + } allocated = true; } void atlas__Metadata__get_array_float( Metadata* This, const char* name, float*& value, int& size, int& allocated ) { @@ -228,8 +230,9 @@ void atlas__Metadata__get_array_float( Metadata* This, const char* name, float*& std::vector v = This->get>( std::string( name ) ); size = v.size(); value = new float[size]; - for ( size_t j = 0; j < v.size(); ++j ) + for ( size_t j = 0; j < v.size(); ++j ) { value[j] = v[j]; + } allocated = true; } void atlas__Metadata__get_array_double( Metadata* This, const char* name, double*& value, int& size, int& allocated ) { diff --git a/src/atlas/util/ObjectHandle.cc b/src/atlas/util/ObjectHandle.cc index 2ef7e418f..add7aa9fe 100644 --- a/src/atlas/util/ObjectHandle.cc +++ b/src/atlas/util/ObjectHandle.cc @@ -54,8 +54,9 @@ void ObjectHandleBase::assign( const Object* other ) { void ObjectHandleBase::attach() { - if ( !null() ) + if ( !null() ) { object_->attach(); + } } // ------------------------------------------------------------------ diff --git a/src/atlas/util/Rotation.cc b/src/atlas/util/Rotation.cc index b8b630594..71ff2a7a5 100644 --- a/src/atlas/util/Rotation.cc +++ b/src/atlas/util/Rotation.cc @@ -126,8 +126,9 @@ void Rotation::precompute() { Rotation::Rotation( const PointLonLat& south_pole, double rotation_angle ) { spole_ = south_pole; npole_ = PointLonLat( spole_.lon() - 180., spole_.lat() + 180. ); - if ( npole_.lat() > 90 ) + if ( npole_.lat() > 90 ) { npole_.lon() += 180.; + } angle_ = wrap_angle( rotation_angle ); precompute(); @@ -143,14 +144,16 @@ Rotation::Rotation( const eckit::Parametrisation& p ) { if ( p.get( "north_pole", pole ) ) { npole_ = PointLonLat( pole.data() ); spole_ = PointLonLat( npole_.lon() + 180., npole_.lat() - 180. ); - if ( spole_.lat() < -90 ) + if ( spole_.lat() < -90 ) { spole_.lon() -= 180.; + } } else if ( p.get( "south_pole", pole ) ) { spole_ = PointLonLat( pole.data() ); npole_ = PointLonLat( spole_.lon() - 180., spole_.lat() + 180. ); - if ( npole_.lat() > 90 ) + if ( npole_.lat() > 90 ) { npole_.lon() += 180.; + } } precompute(); diff --git a/src/atlas_f/internals/Library.cc b/src/atlas_f/internals/Library.cc index 5d174f743..6857bc055 100644 --- a/src/atlas_f/internals/Library.cc +++ b/src/atlas_f/internals/Library.cc @@ -34,10 +34,12 @@ const char* atlas__eckit_git_sha1() { const char* atlas__eckit_git_sha1_abbrev( int length ) { static std::string git_sha1( eckit_git_sha1() ); - if ( git_sha1.empty() ) + if ( git_sha1.empty() ) { git_sha1 = "not available"; - else + } + else { git_sha1 = git_sha1.substr( 0, std::min( length, 40 ) ); + } return git_sha1.c_str(); } diff --git a/src/sandbox/benchmark_ifs_setup/atlas-benchmark-ifs-setup.cc b/src/sandbox/benchmark_ifs_setup/atlas-benchmark-ifs-setup.cc index e8c45e06c..c0f46bc61 100644 --- a/src/sandbox/benchmark_ifs_setup/atlas-benchmark-ifs-setup.cc +++ b/src/sandbox/benchmark_ifs_setup/atlas-benchmark-ifs-setup.cc @@ -81,8 +81,9 @@ int Tool::execute( const Args& args ) { args.get( "grid", key ); std::string path_in_str = ""; - if ( args.get( "grid", path_in_str ) ) + if ( args.get( "grid", path_in_str ) ) { path_in = path_in_str; + } StructuredGrid grid; if ( key.size() ) { @@ -96,8 +97,9 @@ int Tool::execute( const Args& args ) { Log::error() << "No grid specified." << std::endl; } - if ( !grid ) + if ( !grid ) { return failed(); + } size_t halo = args.getLong( "halo", halo_default() ); diff --git a/src/sandbox/benchmark_sorting/atlas-benchmark-sorting.cc b/src/sandbox/benchmark_sorting/atlas-benchmark-sorting.cc index 9ead95443..b526b2bd9 100644 --- a/src/sandbox/benchmark_sorting/atlas-benchmark-sorting.cc +++ b/src/sandbox/benchmark_sorting/atlas-benchmark-sorting.cc @@ -90,19 +90,22 @@ void make_nodes_global_index_human_readable( const mesh::actions::BuildHalo& bui if ( do_all ) { points_to_edit.resize( nodes_glb_idx.size() ); - for ( idx_t i = 0; i < nodes_glb_idx.size(); ++i ) + for ( idx_t i = 0; i < nodes_glb_idx.size(); ++i ) { points_to_edit[i] = i; + } } else { glb_idx_max = nodes.global_index().metadata().getLong( "max", 0 ); points_to_edit.resize( build_halo.periodic_points_local_index_.size() ); - for ( size_t i = 0; i < points_to_edit.size(); ++i ) + for ( size_t i = 0; i < points_to_edit.size(); ++i ) { points_to_edit[i] = build_halo.periodic_points_local_index_[i]; + } } std::vector glb_idx( points_to_edit.size() ); - for ( size_t i = 0; i < points_to_edit.size(); ++i ) + for ( size_t i = 0; i < points_to_edit.size(); ++i ) { glb_idx[i] = nodes_glb_idx( i ); + } ATLAS_DEBUG_VAR( points_to_edit ); ATLAS_DEBUG_VAR( points_to_edit.size() ); @@ -210,8 +213,9 @@ int Tool::execute( const Args& args ) { args.get( "grid", key ); std::string path_in_str = ""; - if ( args.get( "grid", path_in_str ) ) + if ( args.get( "grid", path_in_str ) ) { path_in = path_in_str; + } StructuredGrid grid; if ( key.size() ) { @@ -225,8 +229,9 @@ int Tool::execute( const Args& args ) { Log::error() << "No grid specified." << std::endl; } - if ( !grid ) + if ( !grid ) { return failed(); + } Log::debug() << "Domain: " << grid.domain() << std::endl; Log::debug() << "Periodic: " << grid.periodic() << std::endl; diff --git a/src/sandbox/grid_distribution/atlas-grid-distribution.cc b/src/sandbox/grid_distribution/atlas-grid-distribution.cc index 072a7c44b..fffe13b6a 100644 --- a/src/sandbox/grid_distribution/atlas-grid-distribution.cc +++ b/src/sandbox/grid_distribution/atlas-grid-distribution.cc @@ -73,8 +73,9 @@ int Tool::execute( const Args& args ) { args.get( "grid.name", key ); std::string path_in_str = ""; - if ( args.get( "grid.json", path_in_str ) ) + if ( args.get( "grid.json", path_in_str ) ) { path_in = path_in_str; + } StructuredGrid grid; if ( key.size() ) { @@ -97,15 +98,17 @@ int Tool::execute( const Args& args ) { Log::error() << "No grid specified." << std::endl; } - if ( !grid ) + if ( !grid ) { return failed(); + } Log::debug() << "Domain: " << grid.domain() << std::endl; Log::debug() << "Periodic: " << grid.periodic() << std::endl; std::string partitioner_type; - if ( not args.get( "partitioner", partitioner_type ) ) + if ( not args.get( "partitioner", partitioner_type ) ) { partitioner_type = "equal_regions"; + } long N = mpi::comm().size(); args.get( "partitions", N ); diff --git a/src/tests/array/test_array.cc b/src/tests/array/test_array.cc index c8b1c91d2..6423c2e9e 100644 --- a/src/tests/array/test_array.cc +++ b/src/tests/array/test_array.cc @@ -543,8 +543,9 @@ CASE( "test_valid" ) { CASE( "test_wrap" ) { array::ArrayT arr_t( 3, 2 ); EXPECT( arr_t.shape( 0 ) == 3 ); - if ( NOT_PADDED ) + if ( NOT_PADDED ) { EXPECT( arr_t.stride( 0 ) == 2 ); + } EXPECT( arr_t.shape( 1 ) == 2 ); EXPECT( arr_t.stride( 1 ) == 1 ); EXPECT( arr_t.rank() == 2 ); diff --git a/src/tests/functionspace/test_functionspace.cc b/src/tests/functionspace/test_functionspace.cc index 35354db05..6356d73cb 100644 --- a/src/tests/functionspace/test_functionspace.cc +++ b/src/tests/functionspace/test_functionspace.cc @@ -180,8 +180,9 @@ CASE( "test_functionspace_NodeColumns" ) { // glb_field->dump( Log::info() ); - if ( mpi::comm().rank() == root ) + if ( mpi::comm().rank() == root ) { glb_field.metadata().set( "test_broadcast", 123 ); + } arr.assign( -1 ); nodes_fs.scatter( glb_field, field ); diff --git a/src/tests/grid/test_grid_ptr.cc b/src/tests/grid/test_grid_ptr.cc index 902b7d732..067ba013c 100644 --- a/src/tests/grid/test_grid_ptr.cc +++ b/src/tests/grid/test_grid_ptr.cc @@ -187,8 +187,9 @@ CASE( "test_iterator_with_predicate" ) { auto filter = []( long n ) { bool b = ( n >= 5 && n < 10 ); - if ( b ) + if ( b ) { Log::debug() << "n = " << n << std::endl; + } return b; }; diff --git a/src/tests/interpolation/test_interpolation_cubic_prototype.cc b/src/tests/interpolation/test_interpolation_cubic_prototype.cc index 0109304c9..37a27b965 100644 --- a/src/tests/interpolation/test_interpolation_cubic_prototype.cc +++ b/src/tests/interpolation/test_interpolation_cubic_prototype.cc @@ -135,12 +135,15 @@ CASE( "test horizontal cubic interpolation" ) { //----------------------------------------------------------------------------- bool operator==( const eckit::linalg::Triplet& t1, const eckit::linalg::Triplet& t2 ) { - if ( t1.row() != t2.row() ) + if ( t1.row() != t2.row() ) { return false; - if ( t1.col() != t2.col() ) + } + if ( t1.col() != t2.col() ) { return false; - if ( !is_approximately_equal( t1.value(), t2.value() ) ) + } + if ( !is_approximately_equal( t1.value(), t2.value() ) ) { return false; + } return true; } @@ -148,11 +151,13 @@ bool operator!=( const eckit::linalg::Triplet& t1, const eckit::linalg::Triplet& return !( t1 == t2 ); } bool operator==( const std::vector& t1, const std::vector& t2 ) { - if ( t1.size() != t2.size() ) + if ( t1.size() != t2.size() ) { return false; + } for ( size_t i = 0; i < t1.size(); ++i ) { - if ( t1[i] != t2[i] ) + if ( t1[i] != t2[i] ) { return false; + } } return true; } diff --git a/src/tests/io/test_pointcloud_io.cc b/src/tests/io/test_pointcloud_io.cc index 110a70d6d..1ff2cf963 100644 --- a/src/tests/io/test_pointcloud_io.cc +++ b/src/tests/io/test_pointcloud_io.cc @@ -69,8 +69,9 @@ const std::vector fnames( test_arrays::fnames, test_arrays::fnames } // namespace test_vectors bool test_write_file( const std::string& file_path, const size_t& nb_pts, const size_t& nb_columns ) { - if ( !nb_pts ) + if ( !nb_pts ) { return false; + } std::ofstream f( file_path.c_str() ); return ( f && f << "PointCloudIO " << nb_pts << " " << nb_columns << " lon lat f_1 " diff --git a/src/tests/mesh/test_parfields.cc b/src/tests/mesh/test_parfields.cc index 95b7631ae..68756dfae 100644 --- a/src/tests/mesh/test_parfields.cc +++ b/src/tests/mesh/test_parfields.cc @@ -49,10 +49,12 @@ class IsGhost { mypart_( mpi::comm().rank() ) {} bool operator()( idx_t idx ) const { - if ( part_( idx ) != mypart_ ) + if ( part_( idx ) != mypart_ ) { return true; - if ( ridx_( idx ) != idx ) + } + if ( ridx_( idx ) != idx ) { return true; + } return false; } @@ -204,31 +206,37 @@ CASE( "test2" ) { idx_t nb_ghost = 0; for ( idx_t jnode = 0; jnode < nodes.size(); ++jnode ) { - if ( is_ghost( jnode ) ) + if ( is_ghost( jnode ) ) { ++nb_ghost; + } } ATLAS_DEBUG_VAR( nb_ghost ); - if ( mpi::comm().rank() == 0 ) + if ( mpi::comm().rank() == 0 ) { EXPECT( nb_ghost == 128 ); // South boundary of Northern hemisphere - if ( mpi::comm().rank() == 1 ) + } + if ( mpi::comm().rank() == 1 ) { EXPECT( nb_ghost == 0 ); // Southern hemisphere has no ghosts + } mesh::actions::build_periodic_boundaries( m ); int nb_periodic = -nb_ghost; for ( idx_t jnode = 0; jnode < nodes.size(); ++jnode ) { - if ( is_ghost( jnode ) ) + if ( is_ghost( jnode ) ) { ++nb_periodic; + } } ATLAS_DEBUG_VAR( nb_periodic ); - if ( mpi::comm().rank() == 0 ) + if ( mpi::comm().rank() == 0 ) { EXPECT( nb_periodic == 33 ); // Periodic East boundary of Northern hemisphere - // (plus one point south) - if ( mpi::comm().rank() == 1 ) + } + // (plus one point south) + if ( mpi::comm().rank() == 1 ) { EXPECT( nb_periodic == 32 ); // Periodic East boundary of Southern hemisphere + } Gmsh( "periodic.msh", util::Config( "info", true ) ).write( m ); } diff --git a/src/tests/mesh/test_rgg.cc b/src/tests/mesh/test_rgg.cc index b383980e3..a5567b0cd 100644 --- a/src/tests/mesh/test_rgg.cc +++ b/src/tests/mesh/test_rgg.cc @@ -373,8 +373,9 @@ ASSERT(0); const mesh::HybridElements::Connectivity& cell_node_connectivity = m.cells().node_connectivity(); for ( idx_t jelem = 0; jelem < static_cast( m.cells().size() ); ++jelem ) { - for ( idx_t jnode = 0; jnode < cell_node_connectivity.cols( jelem ); ++jnode ) + for ( idx_t jnode = 0; jnode < cell_node_connectivity.cols( jelem ); ++jnode ) { node_elem_connections[cell_node_connectivity( jelem, jnode )]++; + } } for ( idx_t jnode = 0; jnode < nb_nodes; ++jnode ) { if ( node_elem_connections[jnode] == 0 ) { @@ -390,9 +391,10 @@ ASSERT(0); if ( gidx( n ) <= grid.size() ) { if ( part( n ) == p ) { ++nb_owned; - if ( all_owned[gidx( n ) - 1] != -1 ) + if ( all_owned[gidx( n ) - 1] != -1 ) { std::cout << "node " << gidx( n ) << " already visited by " << all_owned[gidx( n ) - 1] << std::endl; + } EXPECT( all_owned[gidx( n ) - 1] == -1 ); all_owned[gidx( n ) - 1] = part( n ); } diff --git a/src/tests/numerics/test_fvm_nabla.cc b/src/tests/numerics/test_fvm_nabla.cc index 7b568a2e7..dd55679d8 100644 --- a/src/tests/numerics/test_fvm_nabla.cc +++ b/src/tests/numerics/test_fvm_nabla.cc @@ -103,8 +103,9 @@ void rotated_flow_magnitude( const fvm::Method& fvm, Field& field, const double& double Ux = pvel * ( std::cos( beta ) + std::tan( y ) * std::cos( x ) * std::sin( beta ) ) * radius * std::cos( y ); double Uy = -pvel * std::sin( x ) * std::sin( beta ) * radius; - for ( idx_t jlev = 0; jlev < field.levels(); ++jlev ) + for ( idx_t jlev = 0; jlev < field.levels(); ++jlev ) { var( jnode, jlev ) = std::sqrt( Ux * Ux + Uy * Uy ); + } } } diff --git a/src/tests/projection/test_rotation.cc b/src/tests/projection/test_rotation.cc index 407fcc3a7..1dc42feb8 100644 --- a/src/tests/projection/test_rotation.cc +++ b/src/tests/projection/test_rotation.cc @@ -88,8 +88,9 @@ class MagicsRotation { double PXROT = std::acos( ZCXROT ) * r2d; - if ( ZSXROT < 0.0 ) + if ( ZSXROT < 0.0 ) { PXROT = -PXROT; + } return PointLonLat( PXROT, PYROT ); } @@ -111,8 +112,9 @@ class MagicsRotation { ZCXMXC = std::max( std::min( ZCXMXC, +1.0 ), -1.0 ); double ZSXMXC = cos_lat * sin_lat / ZCYREG; double ZXMXC = std::acos( ZCXMXC ) * r2d; - if ( ZSXMXC < 0.0 ) + if ( ZSXMXC < 0.0 ) { ZXMXC = -ZXMXC; + } double PXREG = ZXMXC + south_pole_.lon(); return PointLonLat( PXREG, PYREG ); diff --git a/src/tests/trans/test_trans_localcache.cc b/src/tests/trans/test_trans_localcache.cc index 699177c7e..65be88cb7 100644 --- a/src/tests/trans/test_trans_localcache.cc +++ b/src/tests/trans/test_trans_localcache.cc @@ -46,8 +46,9 @@ using LinearSpacing = grid::LinearSpacing; eckit::PathName CacheFile( const std::string& path ) { eckit::PathName cachefile( path ); - if ( cachefile.exists() ) + if ( cachefile.exists() ) { cachefile.unlink(); + } return cachefile; } diff --git a/src/tests/trans/test_transgeneral.cc b/src/tests/trans/test_transgeneral.cc index 9bb5e076d..f8db91c13 100644 --- a/src/tests/trans/test_transgeneral.cc +++ b/src/tests/trans/test_transgeneral.cc @@ -87,8 +87,9 @@ double sphericalharmonics_analytic_point( double a = util::Earth::radius(); // Fourier part of the spherical harmonics: double rft = 1.; - if ( m > 0 ) + if ( m > 0 ) { rft *= 2.; // the famous factor 2 that noone really understands + } if ( imag == 0 ) { rft *= loncos; } @@ -108,112 +109,164 @@ double sphericalharmonics_analytic_point( // scalar: if ( ivar_in == 2 ) { if ( ivar_out == 2 ) { - if ( m == 0 && n == 0 ) + if ( m == 0 && n == 0 ) { return rft; - if ( m == 0 && n == 1 ) + } + if ( m == 0 && n == 1 ) { return std::sqrt( 3. ) * latsin * rft; - if ( m == 0 && n == 2 ) + } + if ( m == 0 && n == 2 ) { return std::sqrt( 5. ) / 2. * ( 3. * latsin * latsin - 1. ) * rft; // sign? - if ( m == 0 && n == 3 ) + } + if ( m == 0 && n == 3 ) { return std::sqrt( 7. ) / 2. * ( 5. * latsin * latsin - 3. ) * latsin * rft; // sign? - if ( m == 1 && n == 1 ) + } + if ( m == 1 && n == 1 ) { return std::sqrt( 3. / 2. ) * latcos * rft; // sign? - if ( m == 1 && n == 2 ) + } + if ( m == 1 && n == 2 ) { return std::sqrt( 15. / 2. ) * latsin * latcos * rft; // sign? - if ( m == 1 && n == 3 ) + } + if ( m == 1 && n == 3 ) { return std::sqrt( 21. ) / 4. * latcos * ( 5. * latsin * latsin - 1. ) * rft; // sign? - if ( m == 2 && n == 2 ) + } + if ( m == 2 && n == 2 ) { return std::sqrt( 15. / 2. ) / 2. * latcos * latcos * rft; - if ( m == 2 && n == 3 ) + } + if ( m == 2 && n == 3 ) { return std::sqrt( 105. / 2. ) / 2. * latcos * latcos * latsin * rft; - if ( m == 3 && n == 3 ) + } + if ( m == 3 && n == 3 ) { return std::sqrt( 35. ) / 4. * latcos * latcos * latcos * rft; // sign? - if ( m == 4 && n == 4 ) + } + if ( m == 4 && n == 4 ) { return ( 3 * std::sqrt( 17.5 ) * std::pow( latcos, 4 ) ) / 8. * rft; - if ( m == 5 && n == 5 ) + } + if ( m == 5 && n == 5 ) { return ( 3 * std::sqrt( 77 ) * std::pow( latcos, 5 ) ) / 16. * rft; - if ( m == 6 && n == 6 ) + } + if ( m == 6 && n == 6 ) { return ( std::sqrt( 3003 ) * std::pow( latcos, 6 ) ) / 32. * rft; - if ( m == 7 && n == 7 ) + } + if ( m == 7 && n == 7 ) { return ( 3 * std::sqrt( 357.5 ) * std::pow( latcos, 7 ) ) / 32. * rft; - if ( m == 8 && n == 8 ) + } + if ( m == 8 && n == 8 ) { return ( 3 * std::sqrt( 6077.5 ) * std::pow( latcos, 8 ) ) / 128. * rft; - if ( m == 9 && n == 9 ) + } + if ( m == 9 && n == 9 ) { return ( std::sqrt( 230945 ) * std::pow( latcos, 9 ) ) / 256. * rft; - if ( m == 10 && n == 10 ) + } + if ( m == 10 && n == 10 ) { return ( std::sqrt( 969969 ) * std::pow( latcos, 10 ) ) / 512. * rft; - if ( m == 11 && n == 11 ) + } + if ( m == 11 && n == 11 ) { return ( std::sqrt( 1.0140585e6 ) * std::pow( latcos, 11 ) ) / 512. * rft; - if ( m == 12 && n == 12 ) + } + if ( m == 12 && n == 12 ) { return ( 5 * std::sqrt( 676039 ) * std::pow( latcos, 12 ) ) / 2048. * rft; - if ( m == 13 && n == 13 ) + } + if ( m == 13 && n == 13 ) { return ( 15 * std::sqrt( 78004.5 ) * std::pow( latcos, 13 ) ) / 2048. * rft; - if ( m == 14 && n == 14 ) + } + if ( m == 14 && n == 14 ) { return ( 15 * std::sqrt( 323161.5 ) * std::pow( latcos, 14 ) ) / 4096. * rft; - if ( m == 15 && n == 15 ) + } + if ( m == 15 && n == 15 ) { return ( 3 * std::sqrt( 33393355 ) * std::pow( latcos, 15 ) ) / 8192. * rft; - if ( m == 16 && n == 16 ) + } + if ( m == 16 && n == 16 ) { return ( 3 * std::sqrt( 5.509903575e8 ) * std::pow( latcos, 16 ) ) / 32768. * rft; - if ( m == 17 && n == 17 ) + } + if ( m == 17 && n == 17 ) { return ( 15 * std::sqrt( 90751353 ) * std::pow( latcos, 17 ) ) / 65536. * rft; - if ( m == 18 && n == 18 ) + } + if ( m == 18 && n == 18 ) { return ( 5 * std::sqrt( 3357800061 ) * std::pow( latcos, 18 ) ) / 131072. * rft; - if ( m == 19 && n == 19 ) + } + if ( m == 19 && n == 19 ) { return ( 15 * std::sqrt( 3.829070245e8 ) * std::pow( latcos, 19 ) ) / 131072. * rft; - if ( m == 20 && n == 20 ) + } + if ( m == 20 && n == 20 ) { return ( 3 * std::sqrt( 156991880045 ) * std::pow( latcos, 20 ) ) / 524288. * rft; - if ( m == 21 && n == 21 ) + } + if ( m == 21 && n == 21 ) { return ( std::sqrt( 1.4465680375575e12 ) * std::pow( latcos, 21 ) ) / 524288. * rft; - if ( m == 22 && n == 22 ) + } + if ( m == 22 && n == 22 ) { return ( 15 * std::sqrt( 2.63012370465e10 ) * std::pow( latcos, 22 ) ) / 1.048576e6 * rft; - if ( m == 23 && n == 23 ) + } + if ( m == 23 && n == 23 ) { return ( 15 * std::sqrt( 107492012277 ) * std::pow( latcos, 23 ) ) / 2.097152e6 * rft; - if ( m == 24 && n == 24 ) + } + if ( m == 24 && n == 24 ) { return ( 105 * std::sqrt( 35830670759 ) * std::pow( latcos, 24 ) ) / 8.388608e6 * rft; - if ( m == 25 && n == 25 ) + } + if ( m == 25 && n == 25 ) { return ( 21 * std::sqrt( 9.136821043545e11 ) * std::pow( latcos, 25 ) ) / 8.388608e6 * rft; - if ( m == 26 && n == 26 ) + } + if ( m == 26 && n == 26 ) { return ( 21 * std::sqrt( 3.7250116562145e12 ) * std::pow( latcos, 26 ) ) / 1.6777216e7 * rft; - if ( m == 27 && n == 27 ) + } + if ( m == 27 && n == 27 ) { return ( 7 * std::sqrt( 136583760727865. ) * std::pow( latcos, 27 ) ) / 3.3554432e7 * rft; - if ( m == 28 && n == 28 ) + } + if ( m == 28 && n == 28 ) { return ( std::sqrt( 2.7248460265209068e16 ) * std::pow( latcos, 28 ) ) / 6.7108864e7 * rft; - if ( m == 29 && n == 29 ) + } + if ( m == 29 && n == 29 ) { return ( std::sqrt( 110873045217057585. ) * std::pow( latcos, 29 ) ) / 1.34217728e8 * rft; - if ( m == 30 && n == 30 ) + } + if ( m == 30 && n == 30 ) { return ( std::sqrt( 450883717216034179. ) * std::pow( latcos, 30 ) ) / 2.68435456e8 * rft; - if ( m == 31 && n == 31 ) + } + if ( m == 31 && n == 31 ) { return ( 21 * std::sqrt( 1.0389025742304935e15 ) * std::pow( latcos, 31 ) ) / 2.68435456e8 * rft; - if ( m == 32 && n == 32 ) + } + if ( m == 32 && n == 32 ) { return ( 21 * std::sqrt( 6.752866732498208e16 ) * std::pow( latcos, 32 ) ) / 2.147483648e9 * rft; - if ( m == 33 && n == 33 ) + } + if ( m == 33 && n == 33 ) { return ( 7 * std::sqrt( 2467865842240254105. ) * std::pow( latcos, 33 ) ) / 4.294967296e9 * rft; - if ( m == 34 && n == 34 ) + } + if ( m == 34 && n == 34 ) { return ( 21 * std::sqrt( 1112959105324036165. ) * std::pow( latcos, 34 ) ) / 8.589934592e9 * rft; - if ( m == 35 && n == 35 ) + } + if ( m == 35 && n == 35 ) { return ( 3 * std::sqrt( 5.53140675346046e19 ) * std::pow( latcos, 35 ) ) / 8.589934592e9 * rft; - if ( m == 36 && n == 36 ) + } + if ( m == 36 && n == 36 ) { return ( std::sqrt( 8075853860052271220473. ) * std::pow( latcos, 36 ) ) / 3.4359738368e10 * rft; - if ( m == 37 && n == 37 ) + } + if ( m == 37 && n == 37 ) { return ( 5 * std::sqrt( 3.2739948081292994e20 ) * std::pow( latcos, 37 ) ) / 3.4359738368e10 * rft; - if ( m == 38 && n == 38 ) + } + if ( m == 38 && n == 38 ) { return ( 35 * std::sqrt( 2.707815254843781e19 ) * std::pow( latcos, 38 ) ) / 6.8719476736e10 * rft; - if ( m == 39 && n == 39 ) + } + if ( m == 39 && n == 39 ) { return ( 35 * std::sqrt( 109701233401363445369. ) * std::pow( latcos, 39 ) ) / 1.37438953472e11 * rft; - if ( m == 40 && n == 40 ) + } + if ( m == 40 && n == 40 ) { return ( 63 * std::sqrt( 548506167006817226845. ) * std::pow( latcos, 40 ) ) / 5.49755813888e11 * rft; - if ( m == 41 && n == 41 ) + } + if ( m == 41 && n == 41 ) { return ( 63 * std::sqrt( 5.551952666044613e20 ) * std::pow( latcos, 41 ) ) / 5.49755813888e11 * rft; - if ( m == 42 && n == 42 ) + } + if ( m == 42 && n == 42 ) { return ( 15 * std::sqrt( 3.964094203555854e22 ) * std::pow( latcos, 42 ) ) / 1.099511627776e12 * rft; - if ( m == 43 && n == 43 ) + } + if ( m == 43 && n == 43 ) { return ( 45 * std::sqrt( 17823059209786010066579. ) * std::pow( latcos, 43 ) ) / 2.199023255552e12 * rft; - if ( m == 44 && n == 44 ) + } + if ( m == 44 && n == 44 ) { return ( 45 * std::sqrt( 7.210237589413431e22 ) * std::pow( latcos, 44 ) ) / 4.398046511104e12 * rft; - if ( m == 45 && n == 45 ) + } + if ( m == 45 && n == 45 ) { return ( 21 * std::sqrt( 1339044123748208678378695. ) * std::pow( latcos, 45 ) ) / 8.796093022208e12 * rft; + } // return // std::pow(latcos,45)*rft*21.*std::sqrt(1339044123748208678378695.)/8796093022208.; // // sign? @@ -229,8 +282,9 @@ double sphericalharmonics_analytic_point( // vorticity: if ( ivar_in == 0 ) { if ( ivar_out == 0 ) { // u: - if ( m == 0 && n == 0 ) + if ( m == 0 && n == 0 ) { return 0.; + } if ( m == 0 && n == 1 ) { if ( imag == 0 ) { return std::sqrt( 3. ) * a / 2. * latcos; @@ -249,10 +303,12 @@ double sphericalharmonics_analytic_point( } } else if ( ivar_out == 1 ) { // v: - if ( m == 0 && n == 0 ) + if ( m == 0 && n == 0 ) { return 0.; - if ( m == 0 && n == 1 ) + } + if ( m == 0 && n == 1 ) { return 0.; + } if ( m == 1 && n == 1 ) { if ( imag == 0 ) { return a * std::sqrt( 3. / 2. ) * lonsin; @@ -270,10 +326,12 @@ double sphericalharmonics_analytic_point( // divergence: if ( ivar_in == 1 ) { if ( ivar_out == 0 ) { // u: - if ( m == 0 && n == 0 ) + if ( m == 0 && n == 0 ) { return 0.; - if ( m == 0 && n == 1 ) + } + if ( m == 0 && n == 1 ) { return 0.; + } if ( m == 1 && n == 1 ) { if ( imag == 0 ) { return a * std::sqrt( 3. / 2. ) * lonsin; @@ -284,8 +342,9 @@ double sphericalharmonics_analytic_point( } } else if ( ivar_out == 1 ) { // v: - if ( m == 0 && n == 0 ) + if ( m == 0 && n == 0 ) { return 0.; + } if ( m == 0 && n == 1 ) { if ( imag == 0 ) { return -std::sqrt( 3. ) * a / 2. * latcos; @@ -332,8 +391,9 @@ void spectral_transform_grid_analytic( const int ivar_out ) // variable returned by this function. 0: u, 1: v, 2: scalar { int N = ( trc + 2 ) * ( trc + 1 ) / 2; - for ( int jm = 0; jm < 2 * N; jm++ ) + for ( int jm = 0; jm < 2 * N; jm++ ) { rspecg[jm] = 0.; + } int k = 0; for ( int jm = 0; jm <= trc; jm++ ) { for ( int jn = jm; jn <= trc; jn++ ) { @@ -345,8 +405,9 @@ void spectral_transform_grid_analytic( } } - for ( int jm = 0; jm < grid.size(); jm++ ) + for ( int jm = 0; jm < grid.size(); jm++ ) { rgp[jm] = 0.; + } if ( StructuredGrid( grid ) ) { StructuredGrid g( grid ); @@ -489,12 +550,15 @@ CASE( "test_trans_vordiv_with_translib" ) { vor[j] = 0.; div[j] = 0.; } - if ( ivar_in == 0 ) + if ( ivar_in == 0 ) { vor[k * nb_vordiv + jfld] = 1.; - if ( ivar_in == 1 ) + } + if ( ivar_in == 1 ) { div[k * nb_vordiv + jfld] = 1.; - if ( ivar_in == 2 ) + } + if ( ivar_in == 2 ) { sp[k * nb_scalar + jfld] = 1.; + } for ( int j = 0; j < nb_all * g.size(); j++ ) { gp[j] = 0.; @@ -694,8 +758,9 @@ CASE( "test_trans_domain" ) { int trc = 63; //Log::info() << "rgp1:" << std::endl; - if ( eckit::PathName( "legcache.bin" ).exists() ) + if ( eckit::PathName( "legcache.bin" ).exists() ) { eckit::PathName( "legcache.bin" ).unlink(); + } Trace t1( Here(), "translocal1 construction" ); trans::Trans transLocal1( global_grid, g1.domain(), trc, option::type( "local" ) | option::write_legendre( "legcache.bin" ) ); @@ -760,12 +825,15 @@ CASE( "test_trans_domain" ) { vor[j] = 0.; div[j] = 0.; } - if ( ivar_in == 0 ) + if ( ivar_in == 0 ) { vor[k * nb_vordiv + jfld] = 1.; - if ( ivar_in == 1 ) + } + if ( ivar_in == 1 ) { div[k * nb_vordiv + jfld] = 1.; - if ( ivar_in == 2 ) + } + if ( ivar_in == 2 ) { sp[k * nb_scalar + jfld] = 1.; + } for ( int j = 0; j < nb_all * g1.size(); j++ ) { rgp1[j] = 0.; @@ -943,12 +1011,15 @@ CASE( "test_trans_pole" ) { vor[j] = 0.; div[j] = 0.; } - if ( ivar_in == 0 ) + if ( ivar_in == 0 ) { vor[k * nb_vordiv + jfld] = 1.; - if ( ivar_in == 1 ) + } + if ( ivar_in == 1 ) { div[k * nb_vordiv + jfld] = 1.; - if ( ivar_in == 2 ) + } + if ( ivar_in == 2 ) { sp[k * nb_scalar + jfld] = 1.; + } for ( int j = 0; j < nb_all * g1.size(); j++ ) { rgp1[j] = 0.; @@ -1131,12 +1202,15 @@ CASE( "test_trans_southpole" ) { vor[j] = 0.; div[j] = 0.; } - if ( ivar_in == 0 ) + if ( ivar_in == 0 ) { vor[k * nb_vordiv + jfld] = 1.; - if ( ivar_in == 1 ) + } + if ( ivar_in == 1 ) { div[k * nb_vordiv + jfld] = 1.; - if ( ivar_in == 2 ) + } + if ( ivar_in == 2 ) { sp[k * nb_scalar + jfld] = 1.; + } for ( int j = 0; j < nb_all * g1.size(); j++ ) { rgp1[j] = 0.; @@ -1305,12 +1379,15 @@ CASE( "test_trans_unstructured" ) { vor[j] = 0.; div[j] = 0.; } - if ( ivar_in == 0 ) + if ( ivar_in == 0 ) { vor[k * nb_vordiv + jfld] = 1.; - if ( ivar_in == 1 ) + } + if ( ivar_in == 1 ) { div[k * nb_vordiv + jfld] = 1.; - if ( ivar_in == 2 ) + } + if ( ivar_in == 2 ) { sp[k * nb_scalar + jfld] = 1.; + } for ( int j = 0; j < nb_all * g.size(); j++ ) { gp[j] = 0.; diff --git a/src/tests/util/test_indexview.cc b/src/tests/util/test_indexview.cc index dcd7ebb20..6aece5631 100644 --- a/src/tests/util/test_indexview.cc +++ b/src/tests/util/test_indexview.cc @@ -33,8 +33,9 @@ namespace test { template std::string pos( Iterator& it ) { std::stringstream ss; - for ( size_t i = 0; i < it.pos().size(); ++i ) + for ( size_t i = 0; i < it.pos().size(); ++i ) { ss << it.pos()[i] << " "; + } return ss.str(); } diff --git a/src/tests/util/test_metadata.cc b/src/tests/util/test_metadata.cc index 88df0f974..b617f6caf 100644 --- a/src/tests/util/test_metadata.cc +++ b/src/tests/util/test_metadata.cc @@ -33,8 +33,9 @@ CASE( "test_broadcast_to_self" ) { metadata.broadcast(); EXPECT( metadata.has( "paramID" ) ); - if ( metadata.has( "paramID" ) ) + if ( metadata.has( "paramID" ) ) { EXPECT( metadata.get( "paramID" ) == 128 ); + } } // ----------------------------------------------------------------------------- @@ -52,11 +53,13 @@ CASE( "test_broadcast_to_other" ) { global.broadcast( local ); EXPECT( local.has( "paramID" ) ); - if ( local.has( "paramID" ) ) + if ( local.has( "paramID" ) ) { EXPECT( local.get( "paramID" ) == 128 ); + } - if ( mpi::comm().rank() != root ) + if ( mpi::comm().rank() != root ) { EXPECT( !global.has( "paramID" ) ); + } } //----------------------------------------------------------------------------- From 92b86b39a986138aa103ebab7dc46f05f0f519a2 Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Fri, 12 Jul 2019 16:59:37 +0000 Subject: [PATCH 82/86] Fix floating-point exception in Projection::lonlatBoundingBox The problem was that poles are not allowed to be projected for e.g. the Lambert Conformal projection. A tangent of 90 degrees is attempted which results in a FPE. Workaround discussed with Pedro Maciel is to remove the check. --- src/atlas/projection/detail/ProjectionImpl.cc | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/src/atlas/projection/detail/ProjectionImpl.cc b/src/atlas/projection/detail/ProjectionImpl.cc index bfee72f2b..76a463806 100644 --- a/src/atlas/projection/detail/ProjectionImpl.cc +++ b/src/atlas/projection/detail/ProjectionImpl.cc @@ -191,24 +191,6 @@ RectangularLonLatDomain ProjectionImpl::lonlatBoundingBox( const Domain& domain // 2. locate latitude extrema by checking if poles are included (in the un-projected frame) and if not, find extrema // not at the corners by refining iteratively - { - auto xyz = [=]( const PointXY& p ) -> PointXYZ { - PointXYZ r; - util::Earth::convertSphericalToCartesian( this->lonlat( p ), r ); - return r; - }; - - using interpolation::element::Quad3D; - using interpolation::method::Ray; - const Quad3D quad( xyz( corners[0] ), xyz( corners[1] ), xyz( corners[2] ), xyz( corners[3] ) ); - - PointXY NP{xy( {0., 90.} )}; - PointXY SP{xy( {0., -90.} )}; - - bounds.includesNorthPole( quad.intersects( Ray( xyz( NP ) ) ) ); - bounds.includesSouthPole( quad.intersects( Ray( xyz( SP ) ) ) ); - } - for ( size_t i = 0; i < corners.size(); ++i ) { if ( !bounds.includesNorthPole() || !bounds.includesSouthPole() ) { PointXY A = corners[i]; From 42f24e1eab5c8ca6867ad2cb6bcd7453e5b2422f Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Fri, 12 Jul 2019 18:15:24 +0100 Subject: [PATCH 83/86] Fix missing return --- src/sandbox/interpolation/atlas-parallel-interpolation.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/src/sandbox/interpolation/atlas-parallel-interpolation.cc b/src/sandbox/interpolation/atlas-parallel-interpolation.cc index a79df2f5f..71a12b6a3 100644 --- a/src/sandbox/interpolation/atlas-parallel-interpolation.cc +++ b/src/sandbox/interpolation/atlas-parallel-interpolation.cc @@ -300,6 +300,7 @@ int AtlasParallelInterpolation::execute( const AtlasTool::Args& args ) { Log::info() << "Writing backward interpolation results to src-back.msh" << std::endl; src.writeGmsh( "src-back.msh", src_fields ); } + return success(); } int main( int argc, char* argv[] ) { From 83ee7c86522c122b63e2acf97e3a2b15b91026f2 Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Mon, 15 Jul 2019 10:00:14 +0100 Subject: [PATCH 84/86] Remove spuriouis includes --- CMakeLists.txt | 12 ++++++++++++ src/atlas/projection/detail/ProjectionImpl.cc | 11 +++++------ src/atlas/projection/detail/ProjectionImpl.h | 1 - 3 files changed, 17 insertions(+), 7 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4461d3e34..12e00d637 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -270,6 +270,18 @@ if (HAVE_CLANG_TIDY) set(CMAKE_CXX_CLANG_TIDY "${CLANG_TIDY_EXE};-checks=${CLANG_TIDY_CHECKS};-header-filter='${CMAKE_SOURCE_DIR}/*'") endif() +find_program (INCLUDE_WHAT_YOU_USE_EXE NAMES "include-what-you-use" ) +if( INCLUDE_WHAT_YOU_USE_EXE ) + message(STATUS "Found include-what-you-use: ${INCLUDE_WHAT_YOU_USE_EXE}" ) +endif() +ecbuild_add_option( FEATURE INCLUDE_WHAT_YOU_USE + DEFAULT OFF # Need clang compiler? + DESCRIPTION "Use include-what-you-use clang-tool" + CONDITION INCLUDE_WHAT_YOU_USE_EXE ) +if( HAVE_INCLUDE_WHAT_YOU_USE ) + set(CMAKE_CXX_INCLUDE_WHAT_YOU_USE ${INCLUDE_WHAT_YOU_USE_EXE}) +endif() + add_subdirectory( src ) ################################################################################ diff --git a/src/atlas/projection/detail/ProjectionImpl.cc b/src/atlas/projection/detail/ProjectionImpl.cc index 76a463806..60b5cb5d5 100644 --- a/src/atlas/projection/detail/ProjectionImpl.cc +++ b/src/atlas/projection/detail/ProjectionImpl.cc @@ -8,20 +8,19 @@ * nor does it submit to any jurisdiction. */ +#include +#include #include +#include #include "eckit/types/FloatCompare.h" #include "eckit/utils/Hash.h" -#include "atlas/interpolation/element/Quad3D.h" -#include "atlas/interpolation/method/Ray.h" -#include "atlas/projection/detail/LonLatProjection.h" +#include "ProjectionImpl.h" + #include "atlas/projection/detail/ProjectionFactory.h" -#include "atlas/projection/detail/ProjectionImpl.h" #include "atlas/runtime/Exception.h" -#include "atlas/runtime/Log.h" #include "atlas/util/Config.h" -#include "atlas/util/Earth.h" namespace atlas { namespace projection { diff --git a/src/atlas/projection/detail/ProjectionImpl.h b/src/atlas/projection/detail/ProjectionImpl.h index d9f7c58a4..d967a0f58 100644 --- a/src/atlas/projection/detail/ProjectionImpl.h +++ b/src/atlas/projection/detail/ProjectionImpl.h @@ -10,7 +10,6 @@ #pragma once -#include #include #include "atlas/util/Factory.h" From 757f1f7d8bc55f8c76bcf529869a2bad8c7a5870 Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Thu, 11 Jul 2019 17:53:45 +0100 Subject: [PATCH 85/86] Version 0.18.0 --- VERSION.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION.cmake b/VERSION.cmake index f146c319a..fca3a7539 100644 --- a/VERSION.cmake +++ b/VERSION.cmake @@ -6,5 +6,5 @@ # granted to it by virtue of its status as an intergovernmental organisation nor # does it submit to any jurisdiction. -set ( ${PROJECT_NAME}_VERSION_STR "0.17.2" ) +set ( ${PROJECT_NAME}_VERSION_STR "0.18.0" ) From d24eb7265fb16af23befd1e6b98730f5f23af5c4 Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Mon, 15 Jul 2019 11:35:24 +0100 Subject: [PATCH 86/86] Update changelog --- CHANGELOG.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 994fad0a9..4751d64f9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,21 @@ This project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html ## [Unreleased] +## [0.18.0] - 2019-07-15 +### Changed +- Make grid hashes crossplatform + +### Added +- Fortran: Can now use TransLocal +- Fortran: Can now create unstructured grids +- LonLat Bounding box computations for grids using its projection +- Serialisation of Mesh Connectivity tables to/from eckit::Stream + +### Fixed +- Structured interpolation bugs +- StructuredColumns bug with iSend +- Memory corruption in Spectral functionspace with GT CUDA backend + ## [0.17.2] - 2019-06-04 ### Fixed - Compilation with PGI 19.4 @@ -113,6 +128,7 @@ This project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html ## 0.13.0 - 2018-02-16 [Unreleased]: https://github.com/ecmwf/atlas/compare/master...develop +[0.18.0]: https://github.com/ecmwf/atlas/compare/0.17.2...0.18.0 [0.17.2]: https://github.com/ecmwf/atlas/compare/0.17.1...0.17.2 [0.17.1]: https://github.com/ecmwf/atlas/compare/0.17.0...0.17.1 [0.17.0]: https://github.com/ecmwf/atlas/compare/0.16.0...0.17.0